From 991be350f79da58b4fb02f22d6eb020e4417de5a Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Tue, 5 Sep 2000 23:03:09 +0000 Subject: [PATCH] Registry fixes (not usable yet) Loader improvements svn path=/trunk/; revision=1335 --- reactos/lib/advapi32/misc/dllmain.c | 32 ++++- reactos/lib/advapi32/reg/reg.c | 202 ++++++++++++++++++++++++++- reactos/lib/kernel32/thread/thread.c | 56 +++++++- reactos/ntoskrnl/cm/registry.c | 41 +++++- 4 files changed, 312 insertions(+), 19 deletions(-) diff --git a/reactos/lib/advapi32/misc/dllmain.c b/reactos/lib/advapi32/misc/dllmain.c index 7d00df9b02b..e5353b7ed91 100644 --- a/reactos/lib/advapi32/misc/dllmain.c +++ b/reactos/lib/advapi32/misc/dllmain.c @@ -1,4 +1,21 @@ +/* $Id: dllmain.c,v 1.2 2000/09/05 22:59:58 ekohl Exp $ + * + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS system libraries + * FILE: lib/advapi32/misc/dllmain.c + * PURPOSE: Library main function + * PROGRAMMER: ??? + * UPDATE HISTORY: + * Created ??? + */ + +#include #include + +//#define NDEBUG +#include + + INT STDCALL DllMain( @@ -7,17 +24,22 @@ DllMain( PVOID reserved ) { +DPRINT1("ADVAPI32: DllMain() called\n"); switch (dwReason) { case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls (hinstDll); + RegInitialize (); break; - case DLL_THREAD_ATTACH: - break; - case DLL_THREAD_DETACH: - break; + case DLL_PROCESS_DETACH: + RegCleanup (); break; } - return(1); + +DPRINT1("ADVAPI32: DllMain() done\n"); + + return TRUE; } +/* EOF */ diff --git a/reactos/lib/advapi32/reg/reg.c b/reactos/lib/advapi32/reg/reg.c index 77ef32766fc..70d8eb21d92 100644 --- a/reactos/lib/advapi32/reg/reg.c +++ b/reactos/lib/advapi32/reg/reg.c @@ -1,4 +1,5 @@ -/* +/* $Id: reg.c,v 1.8 2000/09/05 23:00:27 ekohl Exp $ + * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries * FILE: lib/advapi32/reg/reg.c @@ -8,10 +9,157 @@ * Created 01/11/98 * 19990309 EA Stubs */ -#include #include +#include +#include #include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +#define MAX_DEFAULT_HANDLES 7 + +static CRITICAL_SECTION HandleTableCS; +static HANDLE DefaultHandleTable[MAX_DEFAULT_HANDLES]; + + +/* PROTOTYPES ****************************************************************/ + +static NTSTATUS MapDefaultKey (PHKEY ParentKey, HKEY Key); +static VOID CloseDefaultHandles(VOID); + +static NTSTATUS OpenLocalMachineKey (PHANDLE KeyHandle); + + +/* FUNCTIONS *****************************************************************/ + +/************************************************************************ + * RegInitDefaultHandles + */ + +BOOL +RegInitialize (VOID) +{ + DPRINT1("RegInitialize()\n"); + + RtlZeroMemory (DefaultHandleTable, + MAX_DEFAULT_HANDLES * sizeof(HANDLE)); + + RtlInitializeCriticalSection(&HandleTableCS); + return TRUE; +} + + +/************************************************************************ + * RegInit + */ +BOOL +RegCleanup(VOID) +{ + DPRINT1("RegCleanup()\n"); + + CloseDefaultHandles(); + RtlDeleteCriticalSection(&HandleTableCS); + return TRUE; +} + + +static NTSTATUS +MapDefaultKey (PHKEY ParentKey, + HKEY Key) +{ + PHANDLE Handle; + ULONG Index; + NTSTATUS Status = STATUS_SUCCESS; + + DPRINT1("MapDefaultKey (Key %x)\n", Key); + + if (((ULONG)Key & 0xF0000000) != 0x80000000) + { + *ParentKey = Key; + return STATUS_SUCCESS; + } + + /* Handle special cases here */ + Index = (ULONG)Key & 0x0FFFFFFF; +DPRINT1("Index %x\n", Index); + + 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 2: /*HKEY_LOCAL_MACHINE */ + Status = OpenLocalMachineKey(Handle); + break; + + default: + DPRINT1("MapDefaultHandle() no handle creator\n"); + Status = STATUS_INVALID_PARAMETER; + } + } + + RtlLeaveCriticalSection(&HandleTableCS); + +DPRINT1("Status %x\n", Status); + + if (NT_SUCCESS(Status)) + { + *ParentKey = (HKEY)*Handle; + } + + return Status; +} + + +static VOID CloseDefaultHandles(VOID) +{ + ULONG i; + + RtlEnterCriticalSection(&HandleTableCS); + + for (i = 0; i < MAX_DEFAULT_HANDLES; i++) + { + if (DefaultHandleTable[i] != NULL) + { +// NtClose (DefaultHandleTable[i]); + DefaultHandleTable[i] = NULL; + } + } + + RtlLeaveCriticalSection(&HandleTableCS); +} + + +static NTSTATUS +OpenLocalMachineKey (PHANDLE KeyHandle) +{ + OBJECT_ATTRIBUTES Attributes; + UNICODE_STRING KeyName; + + DPRINT1("OpenLocalMachineKey()\n"); + + RtlInitUnicodeString(&KeyName, + L"\\Registry\\Machine"); + + InitializeObjectAttributes(&Attributes, + &KeyName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + return (NtOpenKey (KeyHandle, 0x200000, &Attributes)); +} + + /************************************************************************ * RegCloseKey */ @@ -61,7 +209,7 @@ RegCreateKeyA( 0, NULL, 0, - MAXIMUM_ALLOWED, + KEY_ALL_ACCESS, NULL, phkResult, NULL); @@ -84,7 +232,7 @@ RegCreateKeyW( 0, NULL, 0, - MAXIMUM_ALLOWED, + KEY_ALL_ACCESS, NULL, phkResult, NULL); @@ -130,8 +278,49 @@ RegCreateKeyExW( LPDWORD lpdwDisposition ) { - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return ERROR_CALL_NOT_IMPLEMENTED; + UNICODE_STRING SubKeyString; + UNICODE_STRING ClassString; + OBJECT_ATTRIBUTES Attributes; + NTSTATUS Status; + HKEY ParentKey; + + DPRINT1("RegCreateKeyExW() called\n"); + + /* get the real parent key */ + Status = MapDefaultKey (&ParentKey, hKey); + if (!NT_SUCCESS(Status)) + { + SetLastError (RtlNtStatusToDosError(Status)); + return (RtlNtStatusToDosError(Status)); + } + + DPRINT1("ParentKey %x\n", (ULONG)ParentKey); + + RtlInitUnicodeString (&ClassString, lpClass); + RtlInitUnicodeString (&SubKeyString, lpSubKey); + + InitializeObjectAttributes (&Attributes, + &SubKeyString, + OBJ_CASE_INSENSITIVE, + (HANDLE)ParentKey, + (PSECURITY_DESCRIPTOR)lpSecurityAttributes); + + Status = NtCreateKey (phkResult, + samDesired, + &Attributes, + 0, + (lpClass == NULL)? NULL : &ClassString, + dwOptions, + (PULONG)lpdwDisposition); + DPRINT1("Status %x\n", Status); + if (!NT_SUCCESS(Status)) + { + SetLastError (RtlNtStatusToDosError(Status)); + return (RtlNtStatusToDosError(Status)); + } + DPRINT1("Returned handle %x\n", (ULONG)*phkResult); + + return ERROR_SUCCESS; } @@ -656,5 +845,4 @@ RegUnLoadKeyA( return ERROR_CALL_NOT_IMPLEMENTED; } - /* EOF */ diff --git a/reactos/lib/kernel32/thread/thread.c b/reactos/lib/kernel32/thread/thread.c index 9b2b4afbc10..95913b2e1da 100644 --- a/reactos/lib/kernel32/thread/thread.c +++ b/reactos/lib/kernel32/thread/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.19 2000/09/05 13:52:44 ekohl Exp $ +/* $Id: thread.c,v 1.20 2000/09/05 23:01:07 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS system libraries @@ -24,6 +24,18 @@ #include +static VOID ThreadAttachDlls (VOID); + +/* Type for a DLL's entry point */ +typedef +WINBOOL +STDCALL +(* PDLLMAIN_FUNC) ( + HANDLE hInst, + ULONG ul_reason_for_call, + LPVOID lpReserved + ); + /* FUNCTIONS *****************************************************************/ static VOID STDCALL @@ -32,12 +44,50 @@ ThreadStartup (LPTHREAD_START_ROUTINE lpStartAddress, { UINT uExitCode; + ThreadAttachDlls (); + + /* FIXME: notify csrss of thread creation ?? */ + uExitCode = (lpStartAddress)(lpParameter); - NtTerminateThread(NtCurrentThread(), - uExitCode); + ExitThread(uExitCode); } +static VOID +ThreadAttachDlls (VOID) +{ + PLIST_ENTRY ModuleListHead; + PLIST_ENTRY Entry; + PLDR_MODULE Module; + + DPRINT("ThreadAttachDlls() called\n"); + + RtlEnterCriticalSection (NtCurrentPeb()->LoaderLock); + + ModuleListHead = &NtCurrentPeb()->Ldr->InInitializationOrderModuleList; + Entry = ModuleListHead->Blink; + + while (Entry != ModuleListHead) + { + Module = CONTAINING_RECORD(Entry, LDR_MODULE, InInitializationOrderModuleList); + + if (Module->EntryPoint != 0) + { + PDLLMAIN_FUNC Entrypoint = (PDLLMAIN_FUNC)Module->EntryPoint; + + DPRINT("Calling entry point at 0x%08x\n", Entrypoint); + Entrypoint (Module->BaseAddress, + DLL_THREAD_ATTACH, + NULL); + } + + Entry = Entry->Blink; + } + + RtlLeaveCriticalSection (NtCurrentPeb()->LoaderLock); + + DPRINT("ThreadAttachDlls() done\n"); +} HANDLE STDCALL CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, diff --git a/reactos/ntoskrnl/cm/registry.c b/reactos/ntoskrnl/cm/registry.c index eda0bafebb0..eb3624b1f4e 100644 --- a/reactos/ntoskrnl/cm/registry.c +++ b/reactos/ntoskrnl/cm/registry.c @@ -1,4 +1,4 @@ -/* $Id: registry.c,v 1.26 2000/09/03 14:46:49 ekohl Exp $ +/* $Id: registry.c,v 1.27 2000/09/05 23:03:09 ekohl Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -408,6 +408,7 @@ NtCreateKey ( Status = CmiBuildKeyPath(&KeyNameBuf, ObjectAttributes); if (!NT_SUCCESS(Status)) { +CHECKPOINT1; return Status; } @@ -429,6 +430,7 @@ NtCreateKey ( KeyHandle); ExFreePool(KeyNameBuf); +CHECKPOINT1; return Status; } @@ -445,6 +447,7 @@ NtCreateKey ( { ExFreePool(KeyNameBuf); +CHECKPOINT1; return Status; } @@ -455,6 +458,7 @@ NtCreateKey ( CmiKeyType); if (NewKey == NULL) { +CHECKPOINT1; return STATUS_UNSUCCESSFUL; } NewKey->Flags = 0; @@ -468,6 +472,7 @@ NtCreateKey ( FALSE, KeyHandle); +CHECKPOINT1; return Status; #else UNIMPLEMENTED; @@ -698,10 +703,10 @@ NtFlushKey ( } -NTSTATUS +NTSTATUS STDCALL NtOpenKey ( - OUT PHANDLE KeyHandle, + OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes ) @@ -744,6 +749,7 @@ NtOpenKey ( } /* Open the key in the registry file */ +CHECKPOINT1; FileToUse = CmiSystemFile; Status = CmiFindKey(FileToUse, KeyNameBuf, @@ -751,8 +757,10 @@ NtOpenKey ( DesiredAccess, 0, NULL); +CHECKPOINT1; if (!NT_SUCCESS(Status)) { +CHECKPOINT1; FileToUse = CmiVolatileFile; Status = CmiFindKey(FileToUse, KeyNameBuf, @@ -760,13 +768,16 @@ NtOpenKey ( DesiredAccess, 0, NULL); +CHECKPOINT1; if (!NT_SUCCESS(Status)) { +CHECKPOINT1; ExFreePool(KeyNameBuf); return Status; } } +CHECKPOINT1; /* Create new key object and put into linked list */ NewKey = ObCreateObject(KeyHandle, @@ -1498,6 +1509,8 @@ CmiBuildKeyPath(PWSTR *KeyPath, POBJECT_ATTRIBUTES ObjectAttributes) ObjectHeader = 0; if (ObjectAttributes->RootDirectory != NULL) { +DbgPrint ("RootDirectory %x\n", ObjectAttributes->RootDirectory); +DbgPrint ("KeyName %wZ\n", ObjectAttributes->ObjectName); /* FIXME: determine type of object for RootDirectory */ Status = ObReferenceObjectByHandle(ObjectAttributes->RootDirectory, KEY_READ, @@ -1507,6 +1520,7 @@ CmiBuildKeyPath(PWSTR *KeyPath, POBJECT_ATTRIBUTES ObjectAttributes) NULL); if (!NT_SUCCESS(Status)) { +CHECKPOINT1; return Status; } ObjectHeader = BODY_TO_HEADER(ObjectBody); @@ -1853,6 +1867,13 @@ CmiFindKey(IN PREGISTRY_FILE RegistryFile, PWSTR Remainder, NextSlash; PKEY_BLOCK CurKeyBlock, SubKeyBlock; +DbgPrint("KeyNameBuf %S\n", KeyNameBuf); + +CHECKPOINT1; + if (RegistryFile == NULL) + return STATUS_UNSUCCESSFUL; +CHECKPOINT1; + /* FIXME: Should handle search by Class/TitleIndex */ /* Loop through each key level and find the needed subkey */ @@ -1860,12 +1881,14 @@ CmiFindKey(IN PREGISTRY_FILE RegistryFile, /* FIXME: this access of RootKeyBlock should be guarded by spinlock */ CurKeyBlock = CmiGetKeyBlock(RegistryFile, RegistryFile->HeaderBlock->RootKeyBlock); Remainder = KeyNameBuf; + wcscpy(CurKeyName, Remainder); while (NT_SUCCESS(Status) && (NextSlash = wcschr(Remainder, L'\\')) != NULL) { /* Copy just the current subkey name to a buffer */ wcsncpy(CurKeyName, Remainder, NextSlash - Remainder); CurKeyName[NextSlash - Remainder] = 0; +DbgPrint("CurKeyName %S\n", CurKeyName); /* Verify existance of CurKeyName */ Status = CmiScanForSubKey(RegistryFile, @@ -1879,6 +1902,7 @@ CmiFindKey(IN PREGISTRY_FILE RegistryFile, } if (SubKeyBlock == NULL) { +CHECKPOINT1; Status = STATUS_UNSUCCESSFUL; continue; } @@ -1889,6 +1913,7 @@ CmiFindKey(IN PREGISTRY_FILE RegistryFile, } if (NT_SUCCESS(Status)) { +DbgPrint("CurKeyName %S\n", CurKeyName); Status = CmiScanForSubKey(RegistryFile, CurKeyBlock, &SubKeyBlock, @@ -1898,6 +1923,7 @@ CmiFindKey(IN PREGISTRY_FILE RegistryFile, { if (SubKeyBlock == NULL) { +CHECKPOINT1; Status = STATUS_UNSUCCESSFUL; } else @@ -1907,6 +1933,7 @@ CmiFindKey(IN PREGISTRY_FILE RegistryFile, } } CmiReleaseBlock(RegistryFile, CurKeyBlock); +CHECKPOINT1; return Status; } @@ -2052,21 +2079,27 @@ CmiScanForSubKey(IN PREGISTRY_FILE RegistryFile, PHASH_TABLE_BLOCK HashBlock; PKEY_BLOCK CurSubKeyBlock; +CHECKPOINT1; HashBlock = CmiGetHashTableBlock(RegistryFile, KeyBlock->HashTableOffset); *SubKeyBlock = NULL; if (HashBlock == 0) { +CHECKPOINT1; return STATUS_SUCCESS; } +CHECKPOINT1; for (Idx = 0; Idx < HashBlock->HashTableSize; Idx++) { +DbgPrint ("KeyName %S HashValue %x\n", KeyName, HashBlock->Table[Idx].HashValue); if (HashBlock->Table[Idx].KeyOffset != 0 && - !wcsncmp(KeyName, (PWSTR) &HashBlock->Table[Idx].HashValue, 4)) + !wcsncmp(KeyName, (PWSTR) &HashBlock->Table[Idx].HashValue, 2)) +// !wcsncmp(KeyName, (PWSTR) &HashBlock->Table[Idx].HashValue, 4)) { CurSubKeyBlock = CmiGetKeyBlock(RegistryFile, HashBlock->Table[Idx].KeyOffset); if (!wcscmp(KeyName, CurSubKeyBlock->Name)) { +CHECKPOINT1; *SubKeyBlock = CurSubKeyBlock; break; }