Клиент сообщает об ошибке из нашего приложения во время установки, которая указывает, что код в «IsWindowsAdministrator» ниже возвращает FALSE, когда установка выполняется администратором домена.Вы вошли как локальный админ, все работает нормально.Установщик (Innosetup) вызывает exe-файл, который выполняет некоторые операции диспетчера управления службами (см. Ниже), но после вызова нижеприведенного IsWindowsAdministrator для проверки статуса пользователя.
Моя причина для проверки статуса администратора заключается в следующем:перед вызовом задач диспетчера служб для работы с драйвером передайте изящную ошибку (см. ниже КОД УСТАНОВКИ ДРАЙВЕРА).Это задачи, которые я не могу легко выполнить в Innosetup, и я решил обернуть их в небольшой исполняемый файл, вызываемый установщиком.
Допустим ли код в CHECK ADMIN CODE для этой задачи?Или я должен просто отказаться от него и обернуть вызов в диспетчер управления службами в попытке-за исключением с более хорошим сообщением об ошибке?
Спасибо
===================== КОД УСТАНОВКИ ДРАЙВЕРА ========================
procedure ArtIODriver_Install( AShowSummary : boolean );
var
hServiceControlManager : THandle;
hService : SC_HANDLE;
ServiceStatus : TServiceStatus;
ServiceArgVectors : PAnsiString;
begin
If not IsWindowsAdministrator then
Raise EArtIODriver.Create(
'Error IODR4 - You must be a windows administrator to perform this action' );
If not FileExists( ArtIODriver_FilePath ) then
Raise EArtIODriver.CreateFmt(
'Error IODR7 - Unable to locate the driver file "%s"',
[ArtIODriver_FilePath] );
hService := 0;
hServiceControlManager := 0;
try
hServiceControlManager := OpenSCManager(
nil,
nil,
SC_MANAGER_ALL_ACCESS);
If hServiceControlManager = 0 then
Raise EArtIODriver.CreateFmt(
'Error IOD1 - Unable to open service control manager - %s',
[GetWinLastErrorStr] );
// can we see the service?
hService := OpenService(
hServiceControlManager,
JustDriverName,
SERVICE_ALL_ACCESS);
etc
etc
========= ПРОВЕРЬТЕ АДМИНИСТРАТНЫЙ КОД ================
function IsWindowsAdministrator: Boolean;
// Returns TRUE if the user has administrator priveleges
// Returns a boolean indicating whether or not user has admin
// privileges. Call only when running under NT. Win9.x will return false!
var
hAccessToken : tHandle;
ptgGroups : pTokenGroups;
dwInfoBufferSize : DWORD;
psidAdministrators : PSID;
int : integer; // counter
blnResult : boolean; // return flag
const
SECURITY_NT_AUTHORITY: SID_IDENTIFIER_AUTHORITY =
(Value: (0,0,0,0,0,5)); // ntifs
SECURITY_BUILTIN_DOMAIN_RID: DWORD = $00000020;
DOMAIN_ALIAS_RID_ADMINS: DWORD = $00000220;
DOMAIN_ALIAS_RID_USERS : DWORD = $00000221;
DOMAIN_ALIAS_RID_GUESTS: DWORD = $00000222;
DOMAIN_ALIAS_RID_POWER_: DWORD = $00000223;
begin
Result := False;
blnResult := OpenThreadToken( GetCurrentThread, TOKEN_QUERY,
True, hAccessToken );
if ( not blnResult ) then
begin
if GetLastError = ERROR_NO_TOKEN then
blnResult := OpenProcessToken( GetCurrentProcess,
TOKEN_QUERY, hAccessToken );
end;
ptgGroups := nil;
if ( blnResult ) then
try
GetMem(ptgGroups, 1024);
blnResult := GetTokenInformation( hAccessToken, TokenGroups,
ptgGroups, 1024,
dwInfoBufferSize );
CloseHandle( hAccessToken );
if ( blnResult ) then
begin
AllocateAndInitializeSid( SECURITY_NT_AUTHORITY, 2,
SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS,
0, 0, 0, 0, 0, 0,
psidAdministrators );
{$IFOPT R+}
{$DEFINE RMINUS}
{$R-}
{$ENDIF}
for int := 0 to ptgGroups.GroupCount - 1 do
if EqualSid( psidAdministrators,
ptgGroups.Groups[ int ].Sid ) then
begin
Result := True;
Break;
end;
{$IFDEF IMINUS}
{$R-}
{$UNDEF IMINUS}
{$ENDIF}
FreeSid( psidAdministrators );
end;
finally
If ptgGroups <> nil then
FreeMem( ptgGroups );
end;
end;