2010-12-19 224 views
3

我的Delphi 2010應用程序需要將Windows用戶添加到本地管理員組。我使用NetLocalGroupAddMembers得到了這部分工作。將SID轉換爲名稱

現在應用程序需要使用其他語言的本地化版本的Windows。爲此,我使用帶LsaLookupSids函數的SID來獲取組的已翻譯名稱,但無法執行此操作,因爲我不知道如何進行API調用。

我將不勝感激有人可以請教我如何使用LsaLookupSids函數從SID獲取組名('Administrators'的英文版美國版Windows)。

以下是我的代碼:

function AddUser(const username, password: PChar; resetpassword: boolean): boolean; stdcall; 
var 
    NetApiStatus: NET_API_STATUS; 
    UserInfo1003: USER_INFO_1003; 
    UserInfo1005: USER_INFO_1005; 
    ui: USER_INFO_1; 
    grp: String; 
    sid: PSID; 
    snu: SID_NAME_USE; 
    sidsize: LongWord; 
    refdomain: PLsaReferencedDomainList; //array [0..MAX_PATH - 1] of char; 
    refdomainsize: LongWord; 
    sidstring: PChar; 
    lgmi3: _LOCALGROUP_MEMBERS_INFO_3; 
    reftranname: PLsaTranslatedName; 
begin 
    if UserExists(username) then begin 


    sidstring := PChar('S-1-5-32-544'); //Local Administrators group 

    refdomain := AllocMem(SizeOf(refdomain)); 
    FillChar(refdomain, SizeOf(refdomain), 0); 

    reftranname := AllocMem(SizeOf(reftranname)); 

    sidsize := 0; 
    sid := nil; 
    sid := AllocMem(Length(sidstring)); 
    sid := PChar(sidstring); 
    try 
     LsaLookupSids(GetPolicyHandle, 1, sid, refdomain, reftranname); 
     grp := reftranname^.Name.Buffer; 
     showmessage('messg ' + grp); 
    finally 
     FreeMem(sid, sidsize); 
    end; 
    end; 

回答

4

簡單的例子。你也可以使用http://blog.delphi-jedi.net/security-library/(如TJwSecurityId)。

此代碼不使用LsaLookupSids,但內部LookupAccountSid(但對於本地組我不認爲它確實很重要)。

uses 
    JclSecurity, JclWin32; 

// Raises exception in case of invalid ASID or if SID is not found 
function GetNameFromSid(ASID: String): String; 
var 
    lSidLen: DWORD; 
    lSid: PSID; 
    lName, lDomain: WideString; 
begin 
    lSidLen := SECURITY_MAX_SID_SIZE; 

    lSid := AllocMem(lSidLen); 
    try 
    StringToSID(ASID, lSid, lSidLen); 
    LookupAccountBySid(lSid, lName, lDomain); 
    Result := lName; 
    finally 
    FreeMem(lSid); 
    end; 
end; 
6

你不需要LsaLookupSids,這意味着用於查找或SID的數組。 查找單個SID通常使用LookupAccountSid完成。例如:

uses JwaWindows; // or JwaSddl, JwaWinBase; 
    var 
     Sid: PSID; 
     peUse: DWORD; 
     cchDomain: DWORD; 
     cchName: DWORD; 
     Name: array of Char; 
     Domain: array of Char; 
    begin 
     Sid := nil; 
     // First convert String SID to SID 
     Win32Check(ConvertStringSidToSid(PChar('S-1-5-32-544'), 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 
      // note: cast to PChar because LookupAccountSid returns zero terminated string 
      ShowMessageFmt('%s\%s', [PChar(Domain), PChar(Name)]); 
     end; 
     end; 

     if Assigned(Sid) then 
     LocalFree(DWORD(Sid)); 
使用Jwscl

或更容易:使用JCL

uses JwsclSid; 

    var 
     Sid: TJwSecurityId; 
    begin 
     Sid := TJwSecurityId.Create('S-1-5-32-544'); 
     try 
     ShowMessage(Sid.GetAccountName); 
     finally 
     Sid.Free; 
     end;