Несколько лет назад мы столкнулись с проблемами, когда администратор устанавливал наше приложение на компьютере пользователя. Наше приложение создавало записи реестра во время установки, но затем отказывало из-за прав реестра, когда отличается пользователь запустил наше приложение.
Код ниже был написан предшественником. Похоже, исправлена вышеуказанная проблема. Но недавно код ниже сам по себе начал изящно проваливаться, сообщая об ошибке Windows: «Ошибка ключа» при вызове SetSecurityDescriptorDacl
.
Это, кажется, происходит на сетевых машинах, которые имеют корпоративную групповую политику. Мы подозреваем, что звонок на SetSecurityDescriptorDacl
с nil может быть не разрешен на этих машинах, даже если у пользователя есть права администратора.
Это не та область, в которой мы имеем какой-либо опыт, поэтому я надеюсь, что у кого-нибудь будут какие-то идеи или альтернативный фрагмент кода, который позволит нам обойти эту проблему ...
class function TQPWindowsRegistry.GiveEveryoneFullAccessToRegistryKey( const RootKey: HKey;
const RegPath : string;
out ErrorMsg : string): boolean;
var
Access : LongWord;
WinResult : LongWord;
SD : PSecurity_Descriptor;
LastError : DWORD;
Reg : TRegistry;
begin
Result := TRUE;
ErrorMsg := '';
if (Win32Platform = VER_PLATFORM_WIN32_NT) then
begin
if TOOLS.UserHasAdminToken then
Access := KEY_ALL_ACCESS
else
Access := KEY_READ OR KEY_WRITE;
Reg := TRegistry.Create(Access);
try
Reg.RootKey := RootKey;
if NOT Reg.OpenKey(RegPath, TRUE) then
Exit;
GetMem(SD, SECURITY_DESCRIPTOR_MIN_LENGTH);
try
Result := InitializeSecurityDescriptor(SD, SECURITY_DESCRIPTOR_REVISION);
if Result then
Result := SetSecurityDescriptorDacl(SD, TRUE, NIL, FALSE); // Fails here!
if NOT Result then
begin
LastError := WINDOWS.GetLastError;
if NOT Result then
ErrorMsg := SYSUTILS.SysErrorMessage(LastError);
end
else
begin
WinResult := RegSetKeySecurity(Reg.CurrentKey, DACL_SECURITY_INFORMATION, SD);
Result := (WinResult = ERROR_SUCCESS);
ErrorMsg := SYSUTILS.SysErrorMessage(WinResult);
end;
finally
FreeMem(SD);
end;
Reg.CloseKey;
finally
FreeAndNIL(Reg);
end;
end;
end; {GiveEveryoneFullAccessToRegistryKey}