繁体   English   中英

如何在Delphi中使用SID设置Windows文件夹的权限

[英]How to set a Windows folder's permissions using SID's in Delphi

刚才,我正在研究使用安装在软件包安装过程中的小型应用程序修复本地化错误。 小型应用程序本质上是蛮横地强制对应用程序数据内我们自己的文件夹设置权限,以将所有人设置为完全访问权限。

问题是每个人都没有被本地化。 我知道我需要使用SID,对于每个人来说,它都是S-1-1-0 我找不到用于使用SID设置权限的WinAPI函数。

该函数现在使用BuildExplicitAccessWithNameSetNamedSecurityInfo ,如下所示

function setfullaccess(foldername:string):boolean;    //B2415 MDE
var
 pDACL: PACL;
 pEA: PEXPLICIT_ACCESS_A;
 R: DWORD;
begin
 result := true;
 pEA := AllocMem(SizeOf(EXPLICIT_ACCESS));
 BuildExplicitAccessWithName(pEA, 'EVERYONE', GENERIC_ALL{GENERIC_READ},GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT{NO_INHERITANCE});
 R := SetEntriesInAcl(1, pEA, nil, pDACL);
 if R = ERROR_SUCCESS then
 begin
  if SetNamedSecurityInfo(pchar(foldername), SE_FILE_OBJECT,DACL_SECURITY_INFORMATION, nil, nil, pDACL, nil) <> ERROR_SUCCESS then result := false;
  LocalFree(Cardinal(pDACL));
 end
 else result := false;//ShowMessage('SetEntriesInAcl failed: ' + SysErrorMessage(R));
end;

我应该改用哪些功能?

在搜索WinAPI文档后,我找到了下面的解决方案。 本质上,我使用SID查找“可读”名称,然后使用该名称。 这不是最优雅的解决方案,但对我有用。

procedure TTestform.Button4Click(Sender: TObject);
var
 Sid: PSID;
 peUse: DWORD;
 cchDomain: DWORD;
 cchName: DWORD;
 Name: array of Char;
 Domain: array of Char;
 pDACL: PACL;
 pEA: PEXPLICIT_ACCESS_A;
 R: DWORD;
 foldername: String; //Temp to hardcode
begin
 foldername := 'C:\TEMP'; //Temp to hardcode
 Sid := nil;
 Win32Check(ConvertStringSidToSidA(PChar('S-1-1-0'), Sid));
 cchName := 0;
 cchDomain := 0;
 //Get Length
 if (not LookupAccountSid(nil, Sid, nil, cchName, nil, cchDomain, peUse)) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
 begin
  SetLength(Name, cchName);
  SetLength(Domain, cchDomain);
  if LookupAccountSid(nil, Sid, @Name[0], cchName, @Domain[0], cchDomain, peUse) then
  begin
   pEA := AllocMem(SizeOf(EXPLICIT_ACCESS));
   BuildExplicitAccessWithName(pEA, PChar(Name), GENERIC_ALL{GENERIC_READ},GRANT_ACCESS, SUB_CONTAINERS_AND_OBJECTS_INHERIT{NO_INHERITANCE});
   R := SetEntriesInAcl(1, pEA, nil, pDACL);
   if R = ERROR_SUCCESS then
   begin
    if SetNamedSecurityInfo(pchar(foldername), SE_FILE_OBJECT,DACL_SECURITY_INFORMATION, nil, nil, pDACL, nil) <> ERROR_SUCCESS then ShowMessage('SetNamedSecurityInfo failed: ' + SysErrorMessage(GetLastError));
    LocalFree(Cardinal(pDACL));
   end
   else ShowMessage('SetEntriesInAcl failed: ' + SysErrorMessage(R));
  end;
 end;
end;

避免同时使用lookupbuild替代方法

var SID: JwaWinNT.PSid; // JWA clashes with Delphi XE2 Windows.Windows.PSID type
    pDACL: PACL;
    EA: EXPLICIT_ACCESS;
    SID_DATA: array[1..SECURITY_MAX_SID_SIZE] of byte;
    SID_DATA_SIZE: DWORD;

   SID_DATA_SIZE := Length(SID_DATA);
   Pointer(SID) := @SID_DATA; // @SID_DATA[Low(SID_DATA)]  for non-static arrays 

    pDACL := nil;
//   if ConvertStringSidToSid(Auth_Users_SID, SID) then
   if CreateWellKnownSid(WinAuthenticatedUserSid, nil, SID, SID_DATA_SIZE) then
   try
      EA.grfInheritance := SUB_CONTAINERS_AND_OBJECTS_INHERIT; // NO_INHERITANCE; // 0
      EA.grfAccessMode :=  GRANT_ACCESS;
      EA.grfAccessPermissions := GENERIC_ALL;

      EA.Trustee.MultipleTrusteeOperation := NO_MULTIPLE_TRUSTEE;
      EA.Trustee.pMultipleTrustee := nil;
      EA.Trustee.TrusteeType := TRUSTEE_IS_WELL_KNOWN_GROUP;
      EA.Trustee.TrusteeForm := TRUSTEE_IS_SID;
      EA.Trustee.ptstrName   := pointer(SID); 

      if ERROR_SUCCESS = SetEntriesInAcl(1, @EA, nil, pDACL) then begin

       // optional creation of PATH and 0-bytes dummy file skipped 

        SetNamedSecurityInfo(pchar(foldername), SE_FILE_OBJECT, ....  {see the author's answer above }
      end;

   finally
     LocalFree(pDACL); // SID is not allocated on heap - no need to free it
   end;

您也可以在http://forum.vingrad.ru/forum/topic-374131/0.html#st_15_view_0上第 2页的单元上检查此代码段

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM