mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Implemented RegLoadKey[A/W]() and RegUnLoadKey[A/W]().
svn path=/trunk/; revision=4421
This commit is contained in:
parent
e93115c5a2
commit
d64b0c501f
1 changed files with 418 additions and 301 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: reg.c,v 1.23 2003/02/02 22:40:36 gvg Exp $
|
||||
/* $Id: reg.c,v 1.24 2003/03/24 13:44:15 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS system libraries
|
||||
|
@ -9,7 +9,8 @@
|
|||
* Created 01/11/98
|
||||
* 19990309 EA Stubs
|
||||
*/
|
||||
#ifndef WIN32_REGDBG
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#define NTOS_MODE_USER
|
||||
#include <ntos.h>
|
||||
|
@ -21,70 +22,8 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#else /*WIN32_REGDBG*/
|
||||
#include "cm_win32.h"
|
||||
#ifdef __GNUC__
|
||||
#define WINAPI __stdcall
|
||||
#define WINAPIV __cdecl
|
||||
#define APIENTRY __stdcall
|
||||
#define DECLSPEC_IMPORT __declspec(dllimport)
|
||||
#define DECLSPEC_EXPORT __declspec(dllexport)
|
||||
#define DECLARE_HANDLE(n) typedef HANDLE n
|
||||
#define HKEY_PERFORMANCE_DATA ((HKEY)0x80000004)
|
||||
#define ERROR_SUCCESS 0L
|
||||
#define ERROR_INVALID_HANDLE 6L
|
||||
#define ERROR_OUTOFMEMORY 14L
|
||||
#define ERROR_INVALID_PARAMETER 87L
|
||||
#define ERROR_CALL_NOT_IMPLEMENTED 120L
|
||||
#define ERROR_MORE_DATA 234L
|
||||
|
||||
void WINAPI SetLastError(DWORD);
|
||||
BOOLEAN STDCALL RtlDosPathNameToNtPathName_U(PWSTR dosname, PUNICODE_STRING ntname, PWSTR* shortname, PCURDIR nah);
|
||||
NTSTATUS STDCALL RtlInitializeCriticalSection(LPCRITICAL_SECTION lpcs);
|
||||
NTSTATUS STDCALL RtlDeleteCriticalSection(LPCRITICAL_SECTION lpcs);
|
||||
NTSTATUS STDCALL RtlLeaveCriticalSection(LPCRITICAL_SECTION lpcs);
|
||||
NTSTATUS STDCALL RtlEnterCriticalSection(LPCRITICAL_SECTION lpcs);
|
||||
|
||||
DECLARE_HANDLE(HKEY);
|
||||
typedef HKEY *PHKEY;
|
||||
typedef ACCESS_MASK REGSAM;
|
||||
|
||||
typedef struct value_entA {
|
||||
LPSTR ve_valuename;
|
||||
DWORD ve_valuelen;
|
||||
DWORD ve_valueptr;
|
||||
DWORD ve_type;
|
||||
} VALENTA,*PVALENTA;
|
||||
typedef struct value_entW {
|
||||
LPWSTR ve_valuename;
|
||||
DWORD ve_valuelen;
|
||||
DWORD ve_valueptr;
|
||||
DWORD ve_type;
|
||||
} VALENTW,*PVALENTW;
|
||||
#endif
|
||||
#undef STDCALL
|
||||
#define STDCALL _stdcall
|
||||
#undef RegSetValueEx
|
||||
#undef RegCreateKeyEx
|
||||
#undef RegQueryInfoKey
|
||||
#undef RegDeleteKey
|
||||
#undef RegOpenKey
|
||||
#undef RegOpenKeyEx
|
||||
#undef RegEnumKeyEx
|
||||
#undef RegEnumValue
|
||||
#endif /*WIN32_REGDBG*/
|
||||
|
||||
#define CHECK_STATUS \
|
||||
{ \
|
||||
if (!NT_SUCCESS(Status)) \
|
||||
{ \
|
||||
LONG _ErrorCode = RtlNtStatusToDosError(Status); \
|
||||
SetLastError(_ErrorCode); \
|
||||
return _ErrorCode; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
#define MAX_DEFAULT_HANDLES 6
|
||||
|
||||
|
@ -92,7 +31,7 @@ static CRITICAL_SECTION HandleTableCS;
|
|||
static HANDLE DefaultHandleTable[MAX_DEFAULT_HANDLES];
|
||||
|
||||
|
||||
/* PROTOTYPES ****************************************************************/
|
||||
/* PROTOTYPES ***************************************************************/
|
||||
|
||||
static NTSTATUS MapDefaultKey (PHKEY ParentKey, HKEY Key);
|
||||
static VOID CloseDefaultKeys(VOID);
|
||||
|
@ -103,27 +42,20 @@ static NTSTATUS OpenUsersKey (PHANDLE KeyHandle);
|
|||
static NTSTATUS OpenCurrentConfigKey(PHANDLE KeyHandle);
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
inline void RegiTerminateWideString(LPWSTR String, DWORD Length)
|
||||
{
|
||||
LPWSTR AfterString = String + Length;
|
||||
*AfterString = 0;
|
||||
}
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/************************************************************************
|
||||
* RegInitDefaultHandles
|
||||
*/
|
||||
|
||||
BOOL
|
||||
RegInitialize(VOID)
|
||||
{
|
||||
DPRINT("RegInitialize()\n");
|
||||
DPRINT("RegInitialize()\n");
|
||||
|
||||
RtlZeroMemory (DefaultHandleTable,
|
||||
MAX_DEFAULT_HANDLES * sizeof(HANDLE));
|
||||
RtlInitializeCriticalSection(&HandleTableCS);
|
||||
return TRUE;
|
||||
RtlZeroMemory(DefaultHandleTable,
|
||||
MAX_DEFAULT_HANDLES * sizeof(HANDLE));
|
||||
RtlInitializeCriticalSection(&HandleTableCS);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -133,83 +65,101 @@ RegInitialize(VOID)
|
|||
BOOL
|
||||
RegCleanup(VOID)
|
||||
{
|
||||
DPRINT("RegCleanup()\n");
|
||||
DPRINT("RegCleanup()\n");
|
||||
|
||||
CloseDefaultKeys();
|
||||
RtlDeleteCriticalSection(&HandleTableCS);
|
||||
return TRUE;
|
||||
CloseDefaultKeys();
|
||||
RtlDeleteCriticalSection(&HandleTableCS);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
MapDefaultKey(PHKEY RealKey,
|
||||
HKEY Key)
|
||||
HKEY Key)
|
||||
{
|
||||
PHANDLE Handle;
|
||||
ULONG Index;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PHANDLE Handle;
|
||||
ULONG Index;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("MapDefaultKey (Key %x)\n", Key);
|
||||
DPRINT("MapDefaultKey (Key %x)\n", Key);
|
||||
|
||||
if (((ULONG)Key & 0xF0000000) != 0x80000000) {
|
||||
*RealKey = Key;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/* Handle special cases here */
|
||||
Index = (ULONG)Key & 0x0FFFFFFF;
|
||||
if (Index >= MAX_DEFAULT_HANDLES)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
RtlEnterCriticalSection(&HandleTableCS);
|
||||
Handle = &DefaultHandleTable[Index];
|
||||
if (*Handle == NULL) {
|
||||
/* create/open the default handle */
|
||||
switch (Index) {
|
||||
case 0: /* HKEY_CLASSES_ROOT */
|
||||
Status = OpenClassesRootKey(Handle);
|
||||
break;
|
||||
case 1: /* HKEY_CURRENT_USER */
|
||||
Status = RtlOpenCurrentUser(KEY_ALL_ACCESS, Handle);
|
||||
break;
|
||||
case 2: /* HKEY_LOCAL_MACHINE */
|
||||
Status = OpenLocalMachineKey(Handle);
|
||||
break;
|
||||
case 3: /* HKEY_USERS */
|
||||
Status = OpenUsersKey(Handle);
|
||||
break;
|
||||
if (((ULONG)Key & 0xF0000000) != 0x80000000)
|
||||
{
|
||||
*RealKey = Key;
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
/* Handle special cases here */
|
||||
Index = (ULONG)Key & 0x0FFFFFFF;
|
||||
if (Index >= MAX_DEFAULT_HANDLES)
|
||||
return(STATUS_INVALID_PARAMETER);
|
||||
|
||||
RtlEnterCriticalSection(&HandleTableCS);
|
||||
Handle = &DefaultHandleTable[Index];
|
||||
if (*Handle == NULL)
|
||||
{
|
||||
/* create/open the default handle */
|
||||
switch (Index)
|
||||
{
|
||||
case 0: /* HKEY_CLASSES_ROOT */
|
||||
Status = OpenClassesRootKey(Handle);
|
||||
break;
|
||||
|
||||
case 1: /* HKEY_CURRENT_USER */
|
||||
Status = RtlOpenCurrentUser(KEY_ALL_ACCESS, Handle);
|
||||
break;
|
||||
|
||||
case 2: /* HKEY_LOCAL_MACHINE */
|
||||
Status = OpenLocalMachineKey(Handle);
|
||||
break;
|
||||
|
||||
case 3: /* HKEY_USERS */
|
||||
Status = OpenUsersKey(Handle);
|
||||
break;
|
||||
#if 0
|
||||
case 4: /* HKEY_PERFORMANCE_DATA */
|
||||
Status = OpenPerformanceDataKey(Handle);
|
||||
break;
|
||||
case 4: /* HKEY_PERFORMANCE_DATA */
|
||||
Status = OpenPerformanceDataKey(Handle);
|
||||
break;
|
||||
#endif
|
||||
case 5: /* HKEY_CURRENT_CONFIG */
|
||||
Status = OpenCurrentConfigKey(Handle);
|
||||
break;
|
||||
default:
|
||||
DPRINT("MapDefaultHandle() no handle creator\n");
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
RtlLeaveCriticalSection(&HandleTableCS);
|
||||
if (NT_SUCCESS(Status)) {
|
||||
*RealKey = (HKEY)*Handle;
|
||||
}
|
||||
return Status;
|
||||
case 5: /* HKEY_CURRENT_CONFIG */
|
||||
Status = OpenCurrentConfigKey(Handle);
|
||||
break;
|
||||
|
||||
case 6: /* HKEY_DYN_DATA */
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT("MapDefaultHandle() no handle creator\n");
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
RtlLeaveCriticalSection(&HandleTableCS);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
*RealKey = (HKEY)*Handle;
|
||||
}
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
CloseDefaultKeys(VOID)
|
||||
{
|
||||
ULONG i;
|
||||
ULONG i;
|
||||
|
||||
RtlEnterCriticalSection(&HandleTableCS);
|
||||
for (i = 0; i < MAX_DEFAULT_HANDLES; i++) {
|
||||
if (DefaultHandleTable[i] != NULL) {
|
||||
NtClose (DefaultHandleTable[i]);
|
||||
DefaultHandleTable[i] = NULL;
|
||||
}
|
||||
}
|
||||
RtlLeaveCriticalSection(&HandleTableCS);
|
||||
RtlEnterCriticalSection(&HandleTableCS);
|
||||
for (i = 0; i < MAX_DEFAULT_HANDLES; i++)
|
||||
{
|
||||
if (DefaultHandleTable[i] != NULL)
|
||||
{
|
||||
NtClose(DefaultHandleTable[i]);
|
||||
DefaultHandleTable[i] = NULL;
|
||||
}
|
||||
}
|
||||
RtlLeaveCriticalSection(&HandleTableCS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -222,13 +172,13 @@ OpenClassesRootKey(PHANDLE KeyHandle)
|
|||
DPRINT("OpenClassesRootKey()\n");
|
||||
|
||||
InitializeObjectAttributes(&Attributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
return(NtOpenKey(KeyHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&Attributes));
|
||||
KEY_ALL_ACCESS,
|
||||
&Attributes));
|
||||
}
|
||||
|
||||
|
||||
|
@ -299,14 +249,16 @@ RegCloseKey(HKEY hKey)
|
|||
|
||||
/* don't close null handle or a pseudo handle */
|
||||
if ((!hKey) || (((ULONG)hKey & 0xF0000000) == 0x80000000))
|
||||
return ERROR_INVALID_HANDLE;
|
||||
Status = NtClose (hKey);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
LONG ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError (ErrorCode);
|
||||
return ErrorCode;
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
return(ERROR_INVALID_HANDLE);
|
||||
|
||||
Status = NtClose(hKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
LONG ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError (ErrorCode);
|
||||
return ErrorCode;
|
||||
}
|
||||
return(ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -360,11 +312,12 @@ RegCreateKeyExA(HKEY hKey,
|
|||
|
||||
/* get the real parent key */
|
||||
Status = MapDefaultKey(&ParentKey, hKey);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
LONG ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError(ErrorCode);
|
||||
return(ErrorCode);
|
||||
}
|
||||
}
|
||||
DPRINT("ParentKey %x\n", (ULONG)ParentKey);
|
||||
|
||||
if (lpClass != NULL)
|
||||
|
@ -386,11 +339,13 @@ RegCreateKeyExA(HKEY hKey,
|
|||
if (lpClass != NULL)
|
||||
RtlFreeUnicodeString(&ClassString);
|
||||
DPRINT("Status %x\n", Status);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
LONG ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError (ErrorCode);
|
||||
return ErrorCode;
|
||||
}
|
||||
}
|
||||
|
||||
return(ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -508,32 +463,39 @@ RegDeleteKeyA(
|
|||
LONG ErrorCode;
|
||||
|
||||
Status = MapDefaultKey(&ParentKey, hKey);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError (ErrorCode);
|
||||
return ErrorCode;
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError(ErrorCode);
|
||||
return(ErrorCode);
|
||||
}
|
||||
|
||||
RtlInitAnsiString(&SubKeyStringA, (LPSTR)lpSubKey);
|
||||
RtlAnsiStringToUnicodeString(&SubKeyStringW, &SubKeyStringA, TRUE);
|
||||
InitializeObjectAttributes (&ObjectAttributes,
|
||||
&SubKeyStringW,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
(HANDLE)ParentKey,
|
||||
NULL);
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&SubKeyStringW,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
(HANDLE)ParentKey,
|
||||
NULL);
|
||||
|
||||
Status = NtOpenKey(&TargetKey, DELETE, &ObjectAttributes);
|
||||
RtlFreeUnicodeString(&SubKeyStringW);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError(ErrorCode);
|
||||
return ErrorCode;
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError(ErrorCode);
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
Status = NtDeleteKey(TargetKey);
|
||||
NtClose(TargetKey);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError(ErrorCode);
|
||||
return ErrorCode;
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError(ErrorCode);
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -726,7 +688,7 @@ RegEnumKeyExW(
|
|||
}
|
||||
RtlMoveMemory(lpName, KeyInfo->Name, KeyInfo->NameLength);
|
||||
*lpcbName = (DWORD)(KeyInfo->NameLength / sizeof(WCHAR));
|
||||
RegiTerminateWideString(lpName, *lpcbName);
|
||||
lpName[KeyInfo->NameLength / sizeof(WCHAR)] = 0;
|
||||
if (lpClass) {
|
||||
RtlMoveMemory(lpClass,
|
||||
(PVOID)((ULONG_PTR)KeyInfo->Name + KeyInfo->ClassOffset),
|
||||
|
@ -939,13 +901,13 @@ RegEnumValueW(
|
|||
SetLastError(dwError);
|
||||
break;
|
||||
}
|
||||
memcpy(lpValueName, ValueInfo->Name, ValueInfo->NameLength);
|
||||
RtlCopyMemory(lpValueName, ValueInfo->Name, ValueInfo->NameLength);
|
||||
*lpcbValueName = (DWORD)(ValueInfo->NameLength / sizeof(WCHAR));
|
||||
RegiTerminateWideString(lpValueName, *lpcbValueName);
|
||||
lpValueName[ValueInfo->NameLength / sizeof(WCHAR)] = 0;
|
||||
if (lpType)
|
||||
*lpType = ValueInfo->Type;
|
||||
if (lpData) {
|
||||
memcpy(lpData,
|
||||
RtlCopyMemory(lpData,
|
||||
//(PVOID)((ULONG_PTR)ValueInfo->Name + ValueInfo->DataOffset),
|
||||
(PVOID)((ULONG_PTR)ValueInfo + ValueInfo->DataOffset),
|
||||
ValueInfo->DataLength);
|
||||
|
@ -1054,21 +1016,26 @@ RegFlushKey(HKEY hKey)
|
|||
HKEY KeyHandle;
|
||||
NTSTATUS Status;
|
||||
LONG ErrorCode;
|
||||
|
||||
|
||||
if (hKey == HKEY_PERFORMANCE_DATA)
|
||||
return(ERROR_SUCCESS);
|
||||
|
||||
Status = MapDefaultKey(&KeyHandle, hKey);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError(ErrorCode);
|
||||
return(ErrorCode);
|
||||
}
|
||||
}
|
||||
|
||||
Status = NtFlushKey(KeyHandle);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError(ErrorCode);
|
||||
return(ErrorCode);
|
||||
}
|
||||
}
|
||||
|
||||
return(ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -1076,13 +1043,11 @@ RegFlushKey(HKEY hKey)
|
|||
/************************************************************************
|
||||
* RegGetKeySecurity
|
||||
*/
|
||||
LONG
|
||||
STDCALL
|
||||
RegGetKeySecurity(
|
||||
HKEY hKey,
|
||||
SECURITY_INFORMATION SecurityInformation,
|
||||
PSECURITY_DESCRIPTOR pSecurityDescriptor,
|
||||
LPDWORD lpcbSecurityDescriptor)
|
||||
LONG STDCALL
|
||||
RegGetKeySecurity (HKEY hKey,
|
||||
SECURITY_INFORMATION SecurityInformation,
|
||||
PSECURITY_DESCRIPTOR pSecurityDescriptor,
|
||||
LPDWORD lpcbSecurityDescriptor)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
|
@ -1093,49 +1058,147 @@ RegGetKeySecurity(
|
|||
/************************************************************************
|
||||
* RegLoadKeyA
|
||||
*/
|
||||
LONG
|
||||
STDCALL
|
||||
RegLoadKeyA(
|
||||
HKEY hKey,
|
||||
LPCSTR lpSubKey,
|
||||
LPCSTR lpFile)
|
||||
LONG STDCALL
|
||||
RegLoadKeyA (HKEY hKey,
|
||||
LPCSTR lpSubKey,
|
||||
LPCSTR lpFile)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
UNICODE_STRING FileName;
|
||||
UNICODE_STRING KeyName;
|
||||
DWORD ErrorCode;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz (&KeyName,
|
||||
(LPSTR)lpSubKey);
|
||||
RtlCreateUnicodeStringFromAsciiz (&FileName,
|
||||
(LPSTR)lpFile);
|
||||
|
||||
ErrorCode = RegLoadKeyW (hKey,
|
||||
KeyName.Buffer,
|
||||
FileName.Buffer);
|
||||
|
||||
RtlFreeUnicodeString (&FileName);
|
||||
RtlFreeUnicodeString (&KeyName);
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* RegLoadKeyW
|
||||
*/
|
||||
LONG
|
||||
STDCALL
|
||||
RegLoadKeyW(
|
||||
HKEY hKey,
|
||||
LPCWSTR lpSubKey,
|
||||
LPCWSTR lpFile)
|
||||
LONG STDCALL
|
||||
RegLoadKeyW (HKEY hKey,
|
||||
LPCWSTR lpSubKey,
|
||||
LPCWSTR lpFile)
|
||||
{
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
OBJECT_ATTRIBUTES FileObjectAttributes;
|
||||
OBJECT_ATTRIBUTES KeyObjectAttributes;
|
||||
UNICODE_STRING FileName;
|
||||
UNICODE_STRING KeyName;
|
||||
HANDLE KeyHandle;
|
||||
DWORD ErrorCode;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (hKey == HKEY_PERFORMANCE_DATA)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
|
||||
Status = MapDefaultKey (&KeyHandle, hKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError (Status);
|
||||
SetLastError (ErrorCode);
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFile,
|
||||
&FileName,
|
||||
NULL,
|
||||
NULL))
|
||||
{
|
||||
SetLastError (ERROR_BAD_PATHNAME);
|
||||
return ERROR_BAD_PATHNAME;
|
||||
}
|
||||
|
||||
InitializeObjectAttributes (&FileObjectAttributes,
|
||||
&FileName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
RtlInitUnicodeString (&KeyName,
|
||||
(LPWSTR)lpSubKey);
|
||||
|
||||
InitializeObjectAttributes (&KeyObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
KeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtLoadKey (&KeyObjectAttributes,
|
||||
&FileObjectAttributes);
|
||||
|
||||
RtlFreeUnicodeString (&FileName);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError (Status);
|
||||
SetLastError (ErrorCode);
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* RegNotifyChangeKeyValue
|
||||
*/
|
||||
LONG
|
||||
STDCALL
|
||||
RegNotifyChangeKeyValue(
|
||||
HKEY hKey,
|
||||
BOOL bWatchSubtree,
|
||||
DWORD dwNotifyFilter,
|
||||
HANDLE hEvent,
|
||||
BOOL fAsynchronous)
|
||||
LONG STDCALL
|
||||
RegNotifyChangeKeyValue(HKEY hKey,
|
||||
BOOL bWatchSubtree,
|
||||
DWORD dwNotifyFilter,
|
||||
HANDLE hEvent,
|
||||
BOOL fAsynchronous)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
HANDLE KeyHandle;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (hKey == HKEY_PERFORMANCE_DATA)
|
||||
{
|
||||
return (ERROR_INVALID_HANDLE);
|
||||
}
|
||||
|
||||
if (fAsynchronous && hEvent == NULL)
|
||||
{
|
||||
return (ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
Status = MapDefaultKey (&KeyHandle,
|
||||
hKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return (RtlNtStatusToDosError (Status));
|
||||
}
|
||||
|
||||
/* FIXME: Remote key handles must fail */
|
||||
|
||||
Status = NtNotifyChangeKey (KeyHandle,
|
||||
hEvent,
|
||||
0,
|
||||
0,
|
||||
&IoStatusBlock,
|
||||
dwNotifyFilter,
|
||||
bWatchSubtree,
|
||||
0,
|
||||
0,
|
||||
fAsynchronous);
|
||||
if (!NT_SUCCESS(Status) && Status != STATUS_TIMEOUT)
|
||||
{
|
||||
return (RtlNtStatusToDosError (Status));
|
||||
}
|
||||
|
||||
return (ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1326,13 +1389,19 @@ RegQueryInfoKeyW(
|
|||
LONG ErrorCode;
|
||||
ULONG Length;
|
||||
|
||||
if ((lpClass) && (!lpcbClass)) {
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
if ((lpClass) && (!lpcbClass))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
Status = MapDefaultKey(&KeyHandle, hKey);
|
||||
CHECK_STATUS;
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError(ErrorCode);
|
||||
return(ErrorCode);
|
||||
}
|
||||
|
||||
if (lpClass) {
|
||||
FullInfoSize = sizeof(KEY_FULL_INFORMATION) + *lpcbClass;
|
||||
|
@ -1831,6 +1900,24 @@ RegRestoreKeyW(
|
|||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* RegSaveKeyA
|
||||
*/
|
||||
LONG STDCALL
|
||||
RegSaveKeyA(HKEY hKey,
|
||||
LPCSTR lpFile,
|
||||
LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
||||
{
|
||||
UNICODE_STRING FileName;
|
||||
LONG ErrorCode;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz(&FileName, (LPSTR)lpFile);
|
||||
ErrorCode = RegSaveKeyW(hKey, FileName.Buffer, lpSecurityAttributes);
|
||||
RtlFreeUnicodeString(&FileName);
|
||||
return(ErrorCode);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* RegSaveKeyW
|
||||
*/
|
||||
|
@ -1848,80 +1935,74 @@ RegSaveKeyW(HKEY hKey,
|
|||
NTSTATUS Status;
|
||||
LONG ErrorCode;
|
||||
|
||||
Status = MapDefaultKey(&KeyHandle, hKey);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
Status = MapDefaultKey (&KeyHandle,
|
||||
hKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError(ErrorCode);
|
||||
return(ErrorCode);
|
||||
}
|
||||
if (!RtlDosPathNameToNtPathName_U((LPWSTR)lpFile,
|
||||
&NtName, NULL, NULL)) {
|
||||
}
|
||||
|
||||
if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFile,
|
||||
&NtName,
|
||||
NULL,
|
||||
NULL))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return(ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
}
|
||||
|
||||
if (lpSecurityAttributes != NULL)
|
||||
{
|
||||
SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&NtName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
SecurityDescriptor);
|
||||
Status = NtCreateFile(&FileHandle,
|
||||
GENERIC_WRITE | SYNCHRONIZE,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
FILE_SHARE_READ,
|
||||
FILE_CREATE,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
|
||||
InitializeObjectAttributes (&ObjectAttributes,
|
||||
&NtName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
SecurityDescriptor);
|
||||
Status = NtCreateFile (&FileHandle,
|
||||
GENERIC_WRITE | SYNCHRONIZE,
|
||||
&ObjectAttributes,
|
||||
&IoStatusBlock,
|
||||
NULL,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
FILE_SHARE_READ,
|
||||
FILE_CREATE,
|
||||
FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
|
||||
NULL,
|
||||
0);
|
||||
RtlFreeUnicodeString(&NtName);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError(ErrorCode);
|
||||
return(ErrorCode);
|
||||
}
|
||||
Status = NtSaveKey(KeyHandle, FileHandle);
|
||||
}
|
||||
|
||||
Status = NtSaveKey(KeyHandle,
|
||||
FileHandle);
|
||||
NtClose(FileHandle);
|
||||
if (!NT_SUCCESS(Status)) {
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError(Status);
|
||||
SetLastError(ErrorCode);
|
||||
return(ErrorCode);
|
||||
}
|
||||
}
|
||||
|
||||
return(ERROR_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* RegSaveKeyA
|
||||
*/
|
||||
LONG STDCALL
|
||||
RegSaveKeyA(HKEY hKey,
|
||||
LPCSTR lpFile,
|
||||
LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
||||
{
|
||||
UNICODE_STRING FileName;
|
||||
LONG ErrorCode;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz(&FileName, (LPSTR)lpFile);
|
||||
ErrorCode = RegSaveKeyW(hKey, FileName.Buffer, lpSecurityAttributes);
|
||||
RtlFreeUnicodeString(&FileName);
|
||||
return(ErrorCode);
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* RegSetKeySecurity
|
||||
*/
|
||||
LONG
|
||||
STDCALL
|
||||
RegSetKeySecurity(
|
||||
HKEY hKey,
|
||||
SECURITY_INFORMATION SecurityInformation, /* FIXME: ULONG? */
|
||||
PSECURITY_DESCRIPTOR pSecurityDescriptor
|
||||
)
|
||||
LONG STDCALL
|
||||
RegSetKeySecurity(HKEY hKey,
|
||||
SECURITY_INFORMATION SecurityInformation,
|
||||
PSECURITY_DESCRIPTOR pSecurityDescriptor)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
|
@ -2098,14 +2179,12 @@ RegSetValueW(
|
|||
/************************************************************************
|
||||
* RegSetValueA
|
||||
*/
|
||||
LONG
|
||||
STDCALL
|
||||
RegSetValueA(
|
||||
HKEY hKey,
|
||||
LPCSTR lpSubKey,
|
||||
DWORD dwType,
|
||||
LPCSTR lpData,
|
||||
DWORD cbData)
|
||||
LONG STDCALL
|
||||
RegSetValueA(HKEY hKey,
|
||||
LPCSTR lpSubKey,
|
||||
DWORD dwType,
|
||||
LPCSTR lpData,
|
||||
DWORD cbData)
|
||||
{
|
||||
WCHAR SubKeyNameBuffer[MAX_PATH+1];
|
||||
UNICODE_STRING SubKeyName;
|
||||
|
@ -2147,30 +2226,68 @@ RegSetValueA(
|
|||
/************************************************************************
|
||||
* RegUnLoadKeyA
|
||||
*/
|
||||
LONG
|
||||
STDCALL
|
||||
RegUnLoadKeyA(
|
||||
HKEY hKey,
|
||||
LPCSTR lpSubKey)
|
||||
LONG STDCALL
|
||||
RegUnLoadKeyA (HKEY hKey,
|
||||
LPCSTR lpSubKey)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
UNICODE_STRING KeyName;
|
||||
DWORD ErrorCode;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz (&KeyName,
|
||||
(LPSTR)lpSubKey);
|
||||
|
||||
ErrorCode = RegUnLoadKeyW (hKey,
|
||||
KeyName.Buffer);
|
||||
|
||||
RtlFreeUnicodeString (&KeyName);
|
||||
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* RegUnLoadKeyW
|
||||
*/
|
||||
LONG
|
||||
STDCALL
|
||||
RegUnLoadKeyW(
|
||||
HKEY hKey,
|
||||
LPCWSTR lpSubKey)
|
||||
LONG STDCALL
|
||||
RegUnLoadKeyW (HKEY hKey,
|
||||
LPCWSTR lpSubKey)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
UNICODE_STRING KeyName;
|
||||
HANDLE KeyHandle;
|
||||
DWORD ErrorCode;
|
||||
NTSTATUS Status;
|
||||
|
||||
if (hKey == HKEY_PERFORMANCE_DATA)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
|
||||
Status = MapDefaultKey (&KeyHandle, hKey);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError (Status);
|
||||
SetLastError (ErrorCode);
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString (&KeyName,
|
||||
(LPWSTR)lpSubKey);
|
||||
|
||||
InitializeObjectAttributes (&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
KeyHandle,
|
||||
NULL);
|
||||
|
||||
Status = NtUnloadKey (&ObjectAttributes);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ErrorCode = RtlNtStatusToDosError (Status);
|
||||
SetLastError (ErrorCode);
|
||||
return ErrorCode;
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue