Newsgroups : Borland : borland.public.delphi.rtl.win32 : 2006 Jan : EditSecurity(), RegGetKeySecurity() woes!

www.cryer.info
Managed Newsgroup Archive

EditSecurity(), RegGetKeySecurity() woes!

Subject:EditSecurity(), RegGetKeySecurity() woes!
Posted by:"Lloyd Kinsella" (lloydkinsel..@gmail.com)
Date:21 Jan 2006 09:27:31

Hi,

I'm using EditSecurity() in the hopes of being able to edit the
security descriptor returned by RegGetKeySecurity().

However I'm having some issues:

1. I get a dialog telling me I don't have permission, even though I'm
logged in as Administrator.
2. There seems to be no default users/groups set for the descriptor.
3. The permissions are screwed up with odd values that look like random
memory?

Below is the code I'm using. I use the JwaAclUi.pas from the JEDI Win32
API conversion.

Any insights into this would be most appreciated.

- Lloyd K

//----------------------------------------------------------------------

unit Unit2;

interface

uses Windows, SysUtils, Classes, JwaAccCtrl, JwaWinNT, JwaWinUser,
JwaWinType, JwaAclUI;

type
  TSecurityInformation = class(TInterfacedObject, ISecurityInformation)
    private
      FKey: THandle;
    protected
      function GetObjectInformation(out pObjectInfo: SI_OBJECT_INFO):
HRESULT; stdcall;
      function GetSecurity(RequestedInformation: SECURITY_INFORMATION;
        out ppSecurityDescriptor: PSECURITY_DESCRIPTOR; fDefault:
BOOL): HRESULT; stdcall;
      function SetSecurity(SecurityInformation: SECURITY_INFORMATION;
        pSecurityDescriptor: PSECURITY_DESCRIPTOR): HRESULT; stdcall;
      function GetAccessRights(pguidObjectType: LPGUID; dwFlags: DWORD;
        out ppAccess: PSI_ACCESS; out pcAccesses, piDefaultAccess:
ULONG): HRESULT; stdcall;
      function MapGeneric(pguidObjectType: LPGUID; pAceFlags: PUCHAR;
        pMask: PACCESS_MASK): HRESULT; stdcall;
      function GetInheritTypes(out ppInheritTypes: PSI_INHERIT_TYPE;
        out pcInheritTypes: ULONG): HRESULT; stdcall;
      function PropertySheetPageCallback(hwnd: HWND; uMsg: UINT;
        uPage: SI_PAGE_TYPE): HRESULT; stdcall;
    public
      constructor Create(AKey: THandle);
    end;

implementation

const
  GUID_NULL: TGUID = '{00000000-0000-0000-0000-000000000000}';

  IDS_ACCESS_FULLCONTROL      = 'Full Control';
  IDS_ACCESS_READ             = 'Read';
  IDS_ACCESS_QUERYVALUE       = 'Query Value';
  IDS_ACCESS_SETVALUE         = 'Set Value';
  IDS_ACCESS_CREATESUBKEY     = 'Create Subkey';
  IDS_ACCESS_ENUMERATESUBKEYS = 'Enumerate Subkeys';
  IDS_ACCESS_NOTIFY           = 'Notify';
  IDS_ACCESS_CREATELINK       = 'Create Link';
  IDS_ACCESS_DELETE           = 'Delete';
  IDS_ACCESS_WRITEDAC         = 'Write DAC';
  IDS_ACCESS_WRITEOWNER       = 'Write Owner';
  IDS_ACCESS_READCONTROL      = 'Read Control';

  IDS_INHERIT_THISKEYONLY       = 'This key only';
  IDS_INHERIT_THISKEYANDSUBKEYS = 'This key and subkeys';
  IDS_INHERIT_SUBKEYSONLY       = 'Subkeys only';

{
var
  RegAccess: array of SI_ACCESS;
}
const
  RegAccess: array [0..11] of SI_ACCESS = (
                                          (
                                           pguid: @GUID_NULL;
                                           mask: KEY_ALL_ACCESS;
                                           pszName:
IDS_ACCESS_FULLCONTROL;
                                           dwFlags: SI_ACCESS_GENERAL
or SI_ACCESS_SPECIFIC
                                          ),
                                          (
                                           pguid: @GUID_NULL;
                                           mask: KEY_READ;
                                           pszName: IDS_ACCESS_READ;
                                           dwFlags: SI_ACCESS_GENERAL
                                          ),
                                          (
                                           pguid: @GUID_NULL;
                                           mask: KEY_QUERY_VALUE;
                                           pszName:
IDS_ACCESS_QUERYVALUE;
                                           dwFlags: SI_ACCESS_SPECIFIC
                                          ),
                                          (
                                           pguid: @GUID_NULL;
                                           mask: KEY_SET_VALUE;
                                           pszName: IDS_ACCESS_SETVALUE;
                                           dwFlags: SI_ACCESS_SPECIFIC
                                          ),
                                          (
                                           pguid: @GUID_NULL;
                                           mask: KEY_CREATE_SUB_KEY;
                                           pszName:
IDS_ACCESS_CREATESUBKEY;
                                           dwFlags: SI_ACCESS_SPECIFIC
                                          ),
                                          (
                                           pguid: @GUID_NULL;
                                           mask: KEY_ENUMERATE_SUB_KEYS;
                                           pszName:
IDS_ACCESS_ENUMERATESUBKEYS;
                                           dwFlags: SI_ACCESS_SPECIFIC
                                          ),
                                          (
                                           pguid: @GUID_NULL;
                                           mask: KEY_NOTIFY;
                                           pszName: IDS_ACCESS_NOTIFY;
                                           dwFlags: SI_ACCESS_SPECIFIC
                                          ),
                                          (
                                           pguid: @GUID_NULL;
                                           mask: KEY_CREATE_LINK;
                                           pszName:
IDS_ACCESS_CREATELINK;
                                           dwFlags: SI_ACCESS_SPECIFIC
                                          ),
                                          (
                                           pguid: @GUID_NULL;
                                           mask: DELETE;
                                           pszName: IDS_ACCESS_DELETE;
                                           dwFlags: SI_ACCESS_SPECIFIC
                                          ),
                                          (
                                           pguid: @GUID_NULL;
                                           mask: WRITE_DAC;
                                           pszName: IDS_ACCESS_WRITEDAC;
                                           dwFlags: SI_ACCESS_SPECIFIC
                                          ),
                                          (
                                           pguid: @GUID_NULL;
                                           mask: WRITE_OWNER;
                                           pszName:
IDS_ACCESS_WRITEOWNER;
                                           dwFlags: SI_ACCESS_SPECIFIC
                                          ),
                                          (
                                           pguid: @GUID_NULL;
                                           mask: READ_CONTROL;
                                           pszName:
IDS_ACCESS_READCONTROL;
                                           dwFlags: SI_ACCESS_SPECIFIC
                                          )
                                          );

  RegDefaultAccess: DWORD = 1; // KEY_READ

  RegAccessMasks: Windows.GENERIC_MAPPING = (
                                             GenericRead: KEY_READ;
                                             GenericWrite: KEY_WRITE;
                                             GenericExecute:
KEY_EXECUTE;
                                             GenericAll: KEY_ALL_ACCESS
                                            );

  RegInheritTypes: array [0..2] of SI_INHERIT_TYPE = (
                                                      (
                                                       pguid:
@GUID_NULL;
                                                       dwFlags: 0;
                                                       pszName:
IDS_INHERIT_THISKEYONLY;
                                                      ),
                                                      (
                                                       pguid:
@GUID_NULL;
                                                       dwFlags:
CONTAINER_INHERIT_ACE;
                                                       pszName:
IDS_INHERIT_THISKEYANDSUBKEYS;
                                                      ),
                                                      (
                                                       pguid:
@GUID_NULL;
                                                       dwFlags:
INHERIT_ONLY_ACE or CONTAINER_INHERIT_ACE;
                                                       pszName:
IDS_INHERIT_SUBKEYSONLY;
                                                      )
                                                     );


constructor TSecurityInformation.Create(AKey: THandle);
begin
  inherited Create;

  FKey := AKey;
end;

function TSecurityInformation.GetObjectInformation(out pObjectInfo:
SI_OBJECT_INFO): HRESULT;
begin
  ZeroMemory(@pObjectInfo,SizeOf(SI_OBJECT_INFO));
  pObjectInfo.dwFlags := SI_EDIT_ALL or SI_ADVANCED or SI_CONTAINER;
  pObjectInfo.hInstance := SysInit.HInstance;

  Result := S_OK;
end;

function TSecurityInformation.GetSecurity(RequestedInformation:
SECURITY_INFORMATION;
  out ppSecurityDescriptor: PSECURITY_DESCRIPTOR; fDefault: BOOL):
HRESULT;
var
  DescriptorSize: DWORD;
  SecurityDescriptor: Windows.PSecurityDescriptor;
  ErrorCode: LongInt;
begin
  Result := E_ACCESSDENIED;

  ErrorCode :=
RegGetKeySecurity(FKey,RequestedInformation,nil,DescriptorSize);

  if ErrorCode = ERROR_INSUFFICIENT_BUFFER then
    begin
      SecurityDescriptor :=
Windows.PSecurityDescriptor(LocalAlloc(LMEM_FIXED,DescriptorSize));

      if Assigned(SecurityDescriptor) then
        begin
          if
RegGetKeySecurity(FKey,RequestedInformation,SecurityDescriptor,Descripto
rSize) = ERROR_SUCCESS then
            begin
              ppSecurityDescriptor :=
PSECURITY_DESCRIPTOR(SecurityDescriptor);
              Result := S_OK;
            end
          else
            LocalFree(THandle(SecurityDescriptor));
        end
      else
        Result := E_OUTOFMEMORY;
    end;
end;

function TSecurityInformation.SetSecurity(SecurityInformation:
SECURITY_INFORMATION;
  pSecurityDescriptor: PSECURITY_DESCRIPTOR): HRESULT;
begin
  Result := E_NOTIMPL;
end;

function TSecurityInformation.GetAccessRights(pguidObjectType: LPGUID;
dwFlags: DWORD;
  out ppAccess: PSI_ACCESS; out pcAccesses, piDefaultAccess: ULONG):
HRESULT;
begin
  ppAccess := @RegAccess[0];
  pcAccesses := SizeOf(RegAccess);
  piDefaultAccess := RegDefaultAccess;

  Result := S_OK;
end;

function TSecurityInformation.MapGeneric(pguidObjectType: LPGUID;
pAceFlags: PUCHAR;
  pMask: PACCESS_MASK): HRESULT;
begin
  MapGenericMask(pMask^,RegAccessMasks);
  pMask^ := pMask^ and (not SYNCHRONIZE);

  Result := S_OK;
end;

function TSecurityInformation.GetInheritTypes(out ppInheritTypes:
PSI_INHERIT_TYPE;
  out pcInheritTypes: ULONG): HRESULT;
begin
  ppInheritTypes := @RegInheritTypes;
  pcInheritTypes := SizeOf(RegInheritTypes);

  Result := S_OK;
end;

function TSecurityInformation.PropertySheetPageCallback(hwnd: HWND;
uMsg: UINT;
  uPage: SI_PAGE_TYPE): HRESULT;
begin
  Result := E_NOTIMPL;
end;

{
function IDSToStrW(IDS: WideString): PWideChar;
begin
  GetMem(Result,(Length(IDS) + 1) * SizeOf(WideChar));
  Move(IDS[1],Result^,Length(IDS) * SizeOf(WideChar));
end;

procedure Init;
begin
  SetLength(RegAccess,12);

  RegAccess[0].pguid := @GUID_NULL;
  RegAccess[0].mask:= KEY_ALL_ACCESS;
  RegAccess[0].pszName:= IDSToStrW(IDS_ACCESS_FULLCONTROL);
  RegAccess[0].dwFlags:= SI_ACCESS_GENERAL or SI_ACCESS_SPECIFIC;

  RegAccess[1].pguid:= @GUID_NULL;
  RegAccess[1].mask:= KEY_READ;
  RegAccess[1].pszName:= IDSToStrW(IDS_ACCESS_READ);
  RegAccess[1].dwFlags:= SI_ACCESS_GENERAL;

  RegAccess[2].pguid:= @GUID_NULL;
  RegAccess[2].mask:= KEY_QUERY_VALUE;
  RegAccess[2].pszName:= IDSToStrW(IDS_ACCESS_QUERYVALUE);
  RegAccess[2].dwFlags:= SI_ACCESS_SPECIFIC;

  RegAccess[3].pguid:= @GUID_NULL;
  RegAccess[3].mask:= KEY_SET_VALUE;
  RegAccess[3].pszName:= IDSToStrW(IDS_ACCESS_SETVALUE);
  RegAccess[3].dwFlags:= SI_ACCESS_SPECIFIC;

  RegAccess[4].pguid:= @GUID_NULL;
  RegAccess[4].mask:= KEY_CREATE_SUB_KEY;
  RegAccess[4].pszName:= IDSToStrW(IDS_ACCESS_CREATESUBKEY);
  RegAccess[4].dwFlags:= SI_ACCESS_SPECIFIC;

  RegAccess[5].pguid:= @GUID_NULL;
  RegAccess[5].mask:= KEY_ENUMERATE_SUB_KEYS;
  RegAccess[5].pszName:= IDSToStrW(IDS_ACCESS_ENUMERATESUBKEYS);
  RegAccess[5].dwFlags:= SI_ACCESS_SPECIFIC;

  RegAccess[6].pguid:= @GUID_NULL;
  RegAccess[6].mask:= KEY_NOTIFY;
  RegAccess[6].pszName:= IDSToStrW(IDS_ACCESS_NOTIFY);
  RegAccess[6].dwFlags:= SI_ACCESS_SPECIFIC;

  RegAccess[7].pguid:= @GUID_NULL;
  RegAccess[7].mask:= KEY_CREATE_LINK;
  RegAccess[7].pszName:= IDSToStrW(IDS_ACCESS_CREATELINK);
  RegAccess[7].dwFlags:= SI_ACCESS_SPECIFIC;

  RegAccess[8].pguid:= @GUID_NULL;
  RegAccess[8].mask:= DELETE;
  RegAccess[8].pszName:= IDSToStrW(IDS_ACCESS_DELETE);
  RegAccess[8].dwFlags:= SI_ACCESS_SPECIFIC;

  RegAccess[9].pguid:= @GUID_NULL;
  RegAccess[9].mask:= WRITE_DAC;
  RegAccess[9].pszName:= IDSToStrW(IDS_ACCESS_WRITEDAC);
  RegAccess[9].dwFlags:= SI_ACCESS_SPECIFIC;

  RegAccess[10].pguid:= @GUID_NULL;
  RegAccess[10].mask:= WRITE_OWNER;
  RegAccess[10].pszName:= IDSToStrW(IDS_ACCESS_WRITEOWNER);
  RegAccess[10].dwFlags:= SI_ACCESS_SPECIFIC;

  RegAccess[11].pguid:= @GUID_NULL;
  RegAccess[11].mask:= READ_CONTROL;
  RegAccess[11].pszName:= IDSToStrW(IDS_ACCESS_READCONTROL);
  RegAccess[11].dwFlags:= SI_ACCESS_SPECIFIC;
end;

initialization

  Init;
}

end.

//----------------------------------------------------------------------

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    btnGo: TButton;
    procedure btnGoClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses Unit2, JwaAclUI;

const
  RegRoot = HKEY_LOCAL_MACHINE;
  RegPath = 'SOFTWARE\Workshell\ClipShare\1.0\CipherProviders';

procedure TForm1.btnGoClick(Sender: TObject);
var
  Key: HKEY;
  SI: ISecurityInformation;
begin
  if RegOpenKeyEx(RegRoot,RegPath,0,KEY_ALL_ACCESS,Key) <>
ERROR_SUCCESS then
    begin
      ShowMessage('Cannot open Registry key.');
      Exit;
    end;

  try
    SI := TSecurityInformation.Create(Key);
      try
        if not EditSecurity(Handle,SI) then
          begin
            ShowMessage('Could not edit security information.');
            Exit;
          end;
      finally
        SI := nil;
      end;
  finally
    RegCloseKey(Key);
  end;
end;

end.

Replies:

www.cryer.info
Managed Newsgroup Archive