新闻
2010年,@ChristianWimmer 批评了我的编码风格。现在,两年后,我不得不再次在我的程序中使用这个函数。因此,我决定改进这个函数的编码风格。
概述
我为您提供了我私人库中的一小部分内容以方便测试。要测试访问令牌的用户帐户是否是本地管理员组的成员,请将 JwaWinNT
的 eWellKnownSidType 参数设置为 WinBuiltinAdministratorsSid
。请注意,它需要JEDI API Libray,因为 Delphi 的 Windows.pas
单元没有定义 CreateWellKnownSid()
。
实施
function Inu_IsMemberOfWellKnownGroup(const hToken: Windows.THandle;
const eWellKnownSidType: JwaWinNT.WELL_KNOWN_SID_TYPE;
const pDomainSid: JwaWinNT.PSID=nil;
peElevType: PTokenElevationType=nil): Boolean;
var
hAccessToken: Windows.THandle;
rOSVerInfo: Windows.OSVERSIONINFO;
eTET: Windows.TTokenElevationType;
iReturnLen: Windows.DWORD;
hTokenToCheck: Windows.THandle;
iSidLen: Windows.DWORD;
pGroupSid: JwaWinNT.PSID;
bMemberOfWellKnownGroup: Windows.BOOL;
begin
Result := False;
hAccessToken := 0;
hTokenToCheck := 0;
pGroupSid := nil;
try
if hToken = 0 then begin
if not Windows.OpenThreadToken(Windows.GetCurrentThread(),
Windows.TOKEN_QUERY or Windows.TOKEN_DUPLICATE,
True, hAccessToken) then begin
if Windows.GetLastError() <> Windows.ERROR_NO_TOKEN then
Exit();
if not Windows.OpenProcessToken(Windows.GetCurrentProcess(),
Windows.TOKEN_QUERY or Windows.TOKEN_DUPLICATE, hAccessToken) then
Exit();
end;
end
else
hAccessToken := hToken;
rOSVerInfo.dwOSVersionInfoSize := SizeOf(Windows.OSVERSIONINFO);
if not Windows.GetVersionEx(rOSVerInfo) then
Exit();
if rOSVerInfo.dwMajorVersion >= 6 then begin
if not Windows.GetTokenInformation(hAccessToken,
Windows.TokenElevationType, @eTET,
SizeOf(Windows.TTokenElevationType), iReturnLen) then
Exit();
if eTET = Windows.TokenElevationTypeLimited then begin
if not Windows.GetTokenInformation(hAccessToken,
Windows.TokenLinkedToken, @hTokenToCheck,
SizeOf(Windows.TTokenLinkedToken), iReturnLen) then
Exit();
end;
if Assigned(peElevType) then
peElevType^ := eTET;
end
else begin
if Assigned(peElevType) then
peElevType^ := Windows.TokenElevationTypeDefault;
end;
if (hTokenToCheck = 0) and (not Windows.DuplicateToken(hAccessToken,
Windows.SecurityIdentification, @hTokenToCheck)) then
Exit();
iSidLen := JwaWinNT.SECURITY_MAX_SID_SIZE;
pGroupSid := JwaWinNT.PSid(Windows.LocalAlloc(Windows.LMEM_FIXED, iSidLen));
if not Assigned(pGroupSid) then
Exit();
if not JwaWinBase.CreateWellKnownSid(eWellKnownSidType, pDomainSid,
pGroupSid, iSidLen) then
Exit();
if not JwaWinBase.CheckTokenMembership(hTokenToCheck, pGroupSid,
bMemberOfWellKnownGroup) then
Exit();
Result := bMemberOfWellKnownGroup;
finally
if hAccessToken <> 0 then
Windows.CloseHandle(hAccessToken);
if (hTokenToCheck <> 0) then
Windows.CloseHandle(hTokenToCheck);
if Assigned(pGroupSid) then
Windows.LocalFree(Windows.HLOCAL(pGroupSid));
end;
end;