我的Delphi 2010应用程序需要将Windows用户添加到本地Administrators组。我使用NetLocalGroupAddMembers使这部分工作。
现在,应用程序需要在其他语言的Windows本地化版本中运行。为此,我使用带有LsaLookupSids函数的SID来获取组的已翻译名称,但由于我不知道如何进行API调用而无法执行此操作。
如果有人能告诉我如何使用LsaLookupSids函数从SID获取组名(英文版美国版Windows中的“Administrators”),我将不胜感激。
以下是我的代码:
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;
答案 0 :(得分:6)
您不需要LsaLookupSids,这适用于查找或SID数组。 通常使用LookupAccountSid查找单个SID。例如:
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:
uses JwsclSid;
var
Sid: TJwSecurityId;
begin
Sid := TJwSecurityId.Create('S-1-5-32-544');
try
ShowMessage(Sid.GetAccountName);
finally
Sid.Free;
end;
答案 1 :(得分:4)
使用JCL的简单示例。您也可以使用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;