首页 > 代码库 > 很久以前写的一个 ShareRestrictedSD 类

很久以前写的一个 ShareRestrictedSD 类

代码中一开始的 几个 USES 单元,可能是多余的。

 

unit ShareRestrictedSD;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Shlobj, ActiveX, Dialogs,Shellapi;

///////////////////
//如果这家伙起作用,那么它的作者是jiangsheng(C++);
//如果这家伙一点用没有,那我不知道它的作者
//以上为 jiangsheng 的声明.
//使用方法.
//var
//  SharedSD:TShareRestrictedSD; //创建一个工具类.
//  try
//    SharedSD:=TShareRestrictedSD.Create;
//    FMappingHandle :=
//       CreateFileMapping(
//         $FFFFFFFF, {to virtual memory}
//         SharedSD.GetSA, //获得一个超级用户安全对象.
//         page_readwrite,
//         0,
//         FSize,
//         pchar(FNameToCreate));
//  finally
//    if Assigned(SharedSD) then
//    begin
//      FreeAndNil(SharedSD); //一定要记得释放
//    end;
//  end;
//修改:Flying Wang 和 爱吃猪头肉
///////////////////

const
  SECURITY_NULL_SID_AUTHORITY    = $0;
  SECURITY_WORLD_SID_AUTHORITY   = $1;
  SECURITY_LOCAL_SID_AUTHORITY   = $2;
  SECURITY_CREATOR_SID_AUTHORITY = $3;
  SECURITY_NT_AUTHORITY          = $5;

  ACL_REVISION                   = $2;

  SECURITY_NULL_RID              = $0;
  SECURITY_LOCAL_RID             = $0;
  SECURITY_WORLD_RID             = $0;
  SECURITY_CREATOR_OWNER_RID     = $0;
  SECURITY_DIALUP_RID            = $1;
  SECURITY_CREATOR_GROUP_RID     = $1;
  SECURITY_NETWORK_RID           = $2;
  SECURITY_BATCH_RID             = $3;
  SECURITY_INTERACTIVE_RID       = $4;
  SECURITY_LOGON_IDS_RID         = $5;
  SECURITY_SERVICE_RID           = $6;
  SECURITY_LOCAL_SYSTEM_RID      =$12;
  SECURITY_BUILTIN_DOMAIN_RID    =$20;

  HEAP_NO_SERIALIZE              = $1;
  HEAP_GROWABLE                  = $2;
  HEAP_GENERATE_EXCEPTIONS       = $4;
  HEAP_ZERO_MEMORY               = $8;
  HEAP_REALLOC_IN_PLACE_ONLY     =$10;
  HEAP_TAG_SHIFT                 =$12;
  HEAP_TAIL_CHECKING_ENABLED     =$20;
  HEAP_FREE_CHECKING_ENABLED     =$40;
  HEAP_DISABLE_COALESCE_ON_FREE  =$80;
  HEAP_MAXIMUM_TAG               =$0FFF;
  HEAP_PSEUDO_TAG_FLAG           =$8000;
  HEAP_CREATE_ALIGN_16           =$00010000;
  HEAP_CREATE_ENABLE_TRACING     =$00020000;

type

  PACE_HEADER = ^TACE_HEADER;
  _ACE_HEADER = record
    AceType:Byte;
    AceFlags:Byte;
    AceSize:Word;
  end;
  TACE_HEADER = _ACE_HEADER;
  ACE_HEADER = _ACE_HEADER;

//  ACCESS_MASK = DWORD;

  PACCESS_ALLOWED_ACE = ^TACCESS_ALLOWED_ACE;
  _ACCESS_ALLOWED_ACE = record
    Header:TACE_HEADER;
    Mask:ACCESS_MASK;
    SidStart:DWORD;
  end;
  TACCESS_ALLOWED_ACE = _ACCESS_ALLOWED_ACE;
  ACCESS_ALLOWED_ACE = _ACCESS_ALLOWED_ACE;
 

  TShareRestrictedSD =class(TObject)
  private
    { Private-Deklarationen }
    ptr:Pointer;
    sa:TSecurityAttributes;
    sd:TSecurityDescriptor;
  protected
    { Protected-Deklarationen }
  public
    { Public-Deklarationen }
    Constructor Create;
    Destructor Destroy; override;
    function GetSA:PSecurityAttributes;
  published
    { Published-Deklarationen }
  end;

implementation

Const
  DefSubAuthorityCount = 1;

Function BuildRestrictedSD(pSD:PSecurityDescriptor):Pointer;
var
  dwAclLength:DWORD;
  psideveryone:PSID;
  pDACL:PACL;
  bResult:Boolean;
  pACE:PACCESS_ALLOWED_ACE;
  siaWorld:TSIDIdentifierAuthority;
  si:SECURITY_INFORMATION;
begin
  Result:=nil;
  psideveryone:=nil;
  pDACL:=nil;
  bResult:=False;
  pACE:=nil;
  FillMemory(@siaWorld,Sizeof(siaWorld),SECURITY_NULL_SID_AUTHORITY);
  siaWorld.Value[5]:=SECURITY_WORLD_SID_AUTHORITY;
  si:=DACL_SECURITY_INFORMATION;
  try
    // initialize the security descriptor
    if (not InitializeSecurityDescriptor(pSD,
      SECURITY_DESCRIPTOR_REVISION)) then
    begin
      //InitializeSecurityDescriptor() failed;
      exit;
    end;
    // obtain a sid for the Authenticated Users Group
    if (not AllocateAndInitializeSid(siaWorld,
            DefSubAuthorityCount,
            SECURITY_WORLD_RID,
            SECURITY_NULL_RID,
            SECURITY_NULL_RID,
            SECURITY_NULL_RID,
            SECURITY_NULL_RID,
            SECURITY_NULL_RID,
            SECURITY_NULL_RID,
            SECURITY_NULL_RID,
            psidEveryone)) then
    begin
      //AllocateAndInitializeSid() failed;
      exit;
    end;
    // NOTE:
    //
    // The Authenticated Users group includes all user accounts that
    // have been successfully authenticated by the system. If access
    // must be restricted to a specific user or group other than
    // Authenticated Users, the SID can be constructed using the
    // LookupAccountSid() API based on a user or group name.

    // calculate the DACL length
    dwAclLength:= sizeof(ACL)
            // add space for Authenticated Users group ACE
            + sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)
            + GetLengthSid(psidEveryone);
    // allocate memory for the DACL
    pDACL:=PACL(HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY,
            dwAclLength));
    if (pDACL=nil) then
    begin
      //HeapAlloc() failed;
      exit;
    end;
    // initialize the DACL
    if (not InitializeAcl(pDACL^, dwAclLength, ACL_REVISION)) then
    begin
      //InitializeAcl() failed
      exit;
    end;
    // add the Authenticated Users group ACE to the DACL with
    // GENERIC_READ, GENERIC_WRITE, and GENERIC_EXECUTE access
    if (not AddAccessAllowedAce(pDACL^, ACL_REVISION,
            GENERIC_ALL,
            psidEveryone)) then
    begin
      //AddAccessAllowedAce() failed;
      exit;
    end;
    // set the DACL in the security descriptor
    if (not SetSecurityDescriptorDacl(pSD, TRUE, pDACL, FALSE)) then
    begin
      //SetSecurityDescriptorDacl() failed;
      exit;
    end;
    bResult:=True;    
  finally
    if (psidEveryone<>nil) then
    begin
      FreeSid(psidEveryone);
    end;
    if (not bResult) then
    begin
      if (pDACL<>nil) then
      begin
        HeapFree(GetProcessHeap, 0, pDACL);
      end;
      pDACL:=nil;
    end;
  end;
  Result:=pDACL;
end;

//The following function frees memory allocated in the
// BuildRestrictedSD() function
procedure FreeRestrictedSD(ptr:Pointer);
begin
  if (ptr<>nil) then
  begin
    HeapFree(GetProcessHeap, 0, ptr);
  end;
end;

Constructor TShareRestrictedSD.Create;
begin
  ptr:=nil;
  sa.nLength:=Sizeof(sa);
  sa.lpSecurityDescriptor:= @Sd;
  sa.bInheritHandle:=False;
  // build a restricted security descriptor
  if Win32Platform = VER_PLATFORM_WIN32_NT then
  begin
    ptr:=BuildRestrictedSD(@sd);
    if (ptr=nil) then
    begin
      Raise Exception.Create(BuildRestrictedSD failed);
    end;
  end;
end;

Destructor TShareRestrictedSD.Destroy;
begin
  if (ptr<>nil) then
  begin
    FreeRestrictedSD(ptr);
  end;
end;

function TShareRestrictedSD.GetSA:PSecurityAttributes;
begin
  if (ptr<>nil) then
  begin
    Result:=@Sa;
  end
  else
  begin
    Result:=nil;
  end;
end;

end.