Simplified root key handling now that the server supports a real root

key. Fixed a few prototypes. Implemented NtDeleteKey/NtDeleteValueKey.
This commit is contained in:
Alexandre Julliard 2000-08-26 21:17:42 +00:00
parent 46487282dd
commit f9087e2bfa
2 changed files with 94 additions and 165 deletions

View File

@ -18,195 +18,138 @@
DEFAULT_DEBUG_CHANNEL(ntdll); DEFAULT_DEBUG_CHANNEL(ntdll);
static const WCHAR root_name[] = { '\\','R','e','g','i','s','t','r','y','\\',0 };
static const UNICODE_STRING root_path =
{
sizeof(root_name)-sizeof(WCHAR), /* Length */
sizeof(root_name), /* MaximumLength */
(LPWSTR)root_name /* Buffer */
};
/* copy a key name into the request buffer */ /* copy a key name into the request buffer */
static inline NTSTATUS copy_nameU( LPWSTR Dest, PUNICODE_STRING Name, UINT Offset ) static NTSTATUS copy_key_name( LPWSTR dest, const UNICODE_STRING *name )
{ {
if (Name->Buffer) int len = name->Length, pos = 0;
if (len >= MAX_PATH) return STATUS_BUFFER_OVERFLOW;
if (RtlPrefixUnicodeString( &root_path, name, TRUE ))
{ {
if ((Name->Length-Offset) > MAX_PATH) return STATUS_BUFFER_OVERFLOW; pos += root_path.Length / sizeof(WCHAR);
strcpyW( Dest, Name->Buffer+Offset ); len -= root_path.Length;
} }
else Dest[0] = 0; if (len) memcpy( dest, name->Buffer + pos, len );
dest[len / sizeof(WCHAR)] = 0;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
/* translates predefined paths to HKEY_ constants */
static BOOLEAN _NtKeyToWinKey(
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT UINT * Offset, /* offset within ObjectName */
OUT HKEY * KeyHandle) /* translated handle */
{
static const WCHAR KeyPath_HKLM[] = {
'\\','R','E','G','I','S','T','R','Y',
'\\','M','A','C','H','I','N','E',0};
static const WCHAR KeyPath_HKU [] = {
'\\','R','E','G','I','S','T','R','Y',
'\\','U','S','E','R',0};
static const WCHAR KeyPath_HCC [] = {
'\\','R','E','G','I','S','T','R','Y',
'\\','M','A','C','H','I','N','E',
'\\','S','Y','S','T','E','M',
'\\','C','U','R','R','E','N','T','C','O','N','T','R','O','L','S','E','T',
'\\','H','A','R','D','W','A','R','E','P','R','O','F','I','L','E','S',
'\\','C','U','R','R','E','N','T',0};
static const WCHAR KeyPath_HCR [] = {
'\\','R','E','G','I','S','T','R','Y',
'\\','M','A','C','H','I','N','E',
'\\','S','O','F','T','W','A','R','E',
'\\','C','L','A','S','S','E','S',0};
int len;
PUNICODE_STRING ObjectName = ObjectAttributes->ObjectName;
if(ObjectAttributes->RootDirectory) /* copy a key name into the request buffer */
static inline NTSTATUS copy_nameU( LPWSTR Dest, const UNICODE_STRING *name, UINT max )
{ {
len = 0; if (name->Length >= max) return STATUS_BUFFER_OVERFLOW;
*KeyHandle = ObjectAttributes->RootDirectory; if (name->Length) memcpy( Dest, name->Buffer, name->Length );
} Dest[name->Length / sizeof(WCHAR)] = 0;
else if((ObjectName->Length > (len=strlenW(KeyPath_HKLM))) return STATUS_SUCCESS;
&& (0==strncmpiW(ObjectName->Buffer,KeyPath_HKLM,len)))
{ *KeyHandle = HKEY_LOCAL_MACHINE;
}
else if((ObjectName->Length > (len=strlenW(KeyPath_HKU)))
&& (0==strncmpiW(ObjectName->Buffer,KeyPath_HKU,len)))
{ *KeyHandle = HKEY_USERS;
}
else if((ObjectName->Length > (len=strlenW(KeyPath_HCR)))
&& (0==strncmpiW(ObjectName->Buffer,KeyPath_HCR,len)))
{ *KeyHandle = HKEY_CLASSES_ROOT;
}
else if((ObjectName->Length > (len=strlenW(KeyPath_HCC)))
&& (0==strncmpiW(ObjectName->Buffer,KeyPath_HCC,len)))
{ *KeyHandle = HKEY_CURRENT_CONFIG;
}
else
{
*KeyHandle = 0;
*Offset = 0;
return FALSE;
} }
if (len > 0 && ObjectName->Buffer[len] == (WCHAR)'\\') len++;
*Offset = len;
TRACE("off=%u hkey=0x%08x\n", *Offset, *KeyHandle);
return TRUE;
}
/****************************************************************************** /******************************************************************************
* NtCreateKey [NTDLL] * NtCreateKey [NTDLL]
* ZwCreateKey * ZwCreateKey
*/ */
NTSTATUS WINAPI NtCreateKey( NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
PHANDLE KeyHandle, ULONG TitleIndex, const UNICODE_STRING *class, ULONG options,
ACCESS_MASK DesiredAccess, PULONG dispos )
POBJECT_ATTRIBUTES ObjectAttributes,
ULONG TitleIndex,
PUNICODE_STRING Class,
ULONG CreateOptions,
PULONG Disposition)
{ {
struct create_key_request *req = get_req_buffer(); struct create_key_request *req = get_req_buffer();
UINT ObjectNameOffset;
HKEY RootDirectory;
NTSTATUS ret; NTSTATUS ret;
TRACE("(%p,0x%08lx,0x%08lx,%p(%s),0x%08lx,%p)\n", TRACE( "(0x%x,%s,%s,%lx,%lx,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
KeyHandle, DesiredAccess, TitleIndex, Class, debugstr_us(Class), CreateOptions, Disposition); debugstr_us(class), options, access, retkey );
dump_ObjectAttributes(ObjectAttributes);
if (!KeyHandle) if (!retkey) return STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
_NtKeyToWinKey(ObjectAttributes, &ObjectNameOffset, &RootDirectory); req->parent = attr->RootDirectory;
req->access = access;
req->options = options;
req->modif = 0;
req->parent = RootDirectory; if ((ret = copy_key_name( req->name, attr->ObjectName ))) return ret;
req->access = DesiredAccess; req->class[0] = 0;
req->options = CreateOptions; if (class)
req->modif = time(NULL);
if (copy_nameU( req->name, ObjectAttributes->ObjectName, ObjectNameOffset ) != STATUS_SUCCESS)
return STATUS_INVALID_PARAMETER;
if (Class)
{ {
int ClassLen = Class->Length+1; if ((ret = copy_nameU( req->class, class, server_remaining(req->class) ))) return ret;
if ( ClassLen*sizeof(WCHAR) > server_remaining(req->class)) return STATUS_BUFFER_OVERFLOW;
memcpy( req->class, Class->Buffer, ClassLen );
req->class[ClassLen] = 0;
} }
else
req->class[0] = 0x0000;
if (!(ret = server_call_noerr( REQ_CREATE_KEY ))) if (!(ret = server_call_noerr( REQ_CREATE_KEY )))
{ {
*KeyHandle = req->hkey; *retkey = req->hkey;
if (Disposition) *Disposition = req->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY; if (dispos) *dispos = req->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
} }
return ret; return ret;
} }
/****************************************************************************** /******************************************************************************
* NtOpenKey [NTDLL.129] * NtOpenKey [NTDLL.129]
* ZwOpenKey * ZwOpenKey
* OUT PHANDLE KeyHandle (returns 0 when failure) * OUT PHANDLE retkey (returns 0 when failure)
* IN ACCESS_MASK DesiredAccess * IN ACCESS_MASK access
* IN POBJECT_ATTRIBUTES ObjectAttributes * IN POBJECT_ATTRIBUTES attr
*/ */
NTSTATUS WINAPI NtOpenKey( NTSTATUS WINAPI NtOpenKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
PHANDLE KeyHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes)
{ {
struct open_key_request *req = get_req_buffer(); struct open_key_request *req = get_req_buffer();
UINT ObjectNameOffset;
HKEY RootDirectory;
NTSTATUS ret; NTSTATUS ret;
TRACE("(%p,0x%08lx)\n", KeyHandle, DesiredAccess); TRACE( "(0x%x,%s,%lx,%p)\n", attr->RootDirectory,
dump_ObjectAttributes(ObjectAttributes); debugstr_us(attr->ObjectName), access, retkey );
if (!KeyHandle) return STATUS_INVALID_PARAMETER; if (!retkey) return STATUS_INVALID_PARAMETER;
*KeyHandle = 0; *retkey = 0;
_NtKeyToWinKey(ObjectAttributes, &ObjectNameOffset, &RootDirectory); req->parent = attr->RootDirectory;
req->access = access;
req->parent = RootDirectory; if ((ret = copy_key_name( req->name, attr->ObjectName ))) return ret;
req->access = DesiredAccess; if (!(ret = server_call_noerr( REQ_OPEN_KEY ))) *retkey = req->hkey;
if (copy_nameU( req->name, ObjectAttributes->ObjectName, ObjectNameOffset ) != STATUS_SUCCESS)
return STATUS_INVALID_PARAMETER;
if (!(ret = server_call_noerr(REQ_OPEN_KEY)))
{
*KeyHandle = req->hkey;
}
return ret; return ret;
} }
/****************************************************************************** /******************************************************************************
* NtDeleteKey [NTDLL] * NtDeleteKey [NTDLL]
* ZwDeleteKey * ZwDeleteKey
*/ */
NTSTATUS WINAPI NtDeleteKey(HANDLE KeyHandle) NTSTATUS WINAPI NtDeleteKey( HANDLE hkey )
{ {
FIXME("(0x%08x) stub!\n", struct delete_key_request *req = get_req_buffer();
KeyHandle);
return STATUS_SUCCESS; TRACE( "(%x)\n", hkey );
req->hkey = hkey;
req->name[0] = 0;
return server_call_noerr( REQ_DELETE_KEY );
} }
/****************************************************************************** /******************************************************************************
* NtDeleteValueKey [NTDLL] * NtDeleteValueKey [NTDLL]
* ZwDeleteValueKey * ZwDeleteValueKey
*/ */
NTSTATUS WINAPI NtDeleteValueKey( NTSTATUS WINAPI NtDeleteValueKey( HANDLE hkey, const UNICODE_STRING *name )
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName)
{ {
FIXME("(0x%08x,%p(%s)) stub!\n", NTSTATUS ret;
KeyHandle, ValueName,debugstr_us(ValueName)); struct delete_key_value_request *req = get_req_buffer();
return STATUS_SUCCESS;
TRACE( "(0x%x,%s)\n", hkey, debugstr_us(name) );
req->hkey = hkey;
if (!(ret = copy_nameU( req->name, name, MAX_PATH )))
ret = server_call_noerr( REQ_DELETE_KEY_VALUE );
return ret;
} }
/****************************************************************************** /******************************************************************************
* NtEnumerateKey [NTDLL] * NtEnumerateKey [NTDLL]
* ZwEnumerateKey * ZwEnumerateKey
@ -540,7 +483,7 @@ NTSTATUS WINAPI NtQueryValueKey(
KeyHandle, debugstr_us(ValueName), KeyValueInformationClass, KeyValueInformation, Length, ResultLength); KeyHandle, debugstr_us(ValueName), KeyValueInformationClass, KeyValueInformation, Length, ResultLength);
req->hkey = KeyHandle; req->hkey = KeyHandle;
if (copy_nameU(req->name, ValueName, 0) != STATUS_SUCCESS) return STATUS_BUFFER_OVERFLOW; if (copy_nameU(req->name, ValueName, MAX_PATH) != STATUS_SUCCESS) return STATUS_BUFFER_OVERFLOW;
if ((ret = server_call_noerr(REQ_GET_KEY_VALUE)) != STATUS_SUCCESS) return ret; if ((ret = server_call_noerr(REQ_GET_KEY_VALUE)) != STATUS_SUCCESS) return ret;
switch(KeyValueInformationClass) switch(KeyValueInformationClass)

View File

@ -812,25 +812,11 @@ NtSetSecurityObject(
/* registry functions */ /* registry functions */
NTSTATUS WINAPI NtCreateKey( NTSTATUS WINAPI NtCreateKey(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*,ULONG,
PHANDLE KeyHandle, const UNICODE_STRING*,ULONG,PULONG);
ACCESS_MASK DesiredAccess, NTSTATUS WINAPI NtDeleteKey(HANDLE);
POBJECT_ATTRIBUTES ObjectAttributes, NTSTATUS WINAPI NtDeleteValueKey(HANDLE,const UNICODE_STRING*);
ULONG TitleIndex, NTSTATUS WINAPI NtOpenKey(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*);
PUNICODE_STRING Class,
ULONG CreateOptions,
PULONG Disposition);
NTSTATUS WINAPI NtOpenKey(
PHANDLE KeyHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes);
NTSTATUS WINAPI NtDeleteKey(HANDLE KeyHandle);
NTSTATUS WINAPI NtDeleteValueKey(
IN HANDLE KeyHandle,
IN PUNICODE_STRING ValueName);
NTSTATUS WINAPI NtEnumerateKey( NTSTATUS WINAPI NtEnumerateKey(
HANDLE KeyHandle, HANDLE KeyHandle,