From 3438f985708e0ca261fc17f56cc94d69a1d409d3 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Mon, 26 Sep 2005 18:03:17 +0000 Subject: [PATCH] Open BNO directory with correct privileges, open CSR connection with correct path. Add InWindows boolean to use the right CSR ServerID in windows and add a hack to get kernel32 to be loadable if used with .local to force an application to use our kernel and not the system one. The result of this is that our kernel32 can now load in Windows XP (not 2000). svn path=/trunk/; revision=18097 --- reactos/include/ndk/obtypes.h | 2 +- reactos/lib/kernel32/kernel32.def | 3 +- reactos/lib/kernel32/misc/dllmain.c | 288 ++++++++++++++++++---------- 3 files changed, 193 insertions(+), 100 deletions(-) diff --git a/reactos/include/ndk/obtypes.h b/reactos/include/ndk/obtypes.h index 56b58b9dfe4..9aa9dd0f781 100644 --- a/reactos/include/ndk/obtypes.h +++ b/reactos/include/ndk/obtypes.h @@ -36,7 +36,7 @@ #define DIRECTORY_TRAVERSE 0x0002 #define DIRECTORY_CREATE_OBJECT 0x0004 #define DIRECTORY_CREATE_SUBDIRECTORY 0x0008 -#define DIRECTORY_ALL_ACCESS STANDARD_RIGHTS_REQUIRED | 0xF +#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF) #endif /* Duplication Flags */ diff --git a/reactos/lib/kernel32/kernel32.def b/reactos/lib/kernel32/kernel32.def index 39e611b4be9..1d427a7e3f4 100644 --- a/reactos/lib/kernel32/kernel32.def +++ b/reactos/lib/kernel32/kernel32.def @@ -55,7 +55,8 @@ BaseDumpAppcompatCache@0 BaseFlushAppcompatCache@0 ;BaseInitAppcompatCache ;BaseInitAppcompatCacheSupport -;BaseProcessInitPostImport +BaseProcessInitPostImport@0 +BaseQueryModuleData@20 BaseUpdateAppcompatCache@12 Beep@8 BeginUpdateResourceA@8 diff --git a/reactos/lib/kernel32/misc/dllmain.c b/reactos/lib/kernel32/misc/dllmain.c index 03033b761b2..7684ebe10b0 100644 --- a/reactos/lib/kernel32/misc/dllmain.c +++ b/reactos/lib/kernel32/misc/dllmain.c @@ -13,11 +13,9 @@ #include -#define NDEBUG +//#define NDEBUG #include "../include/debug.h" -#define CSR_BASE_DLL 0 // <- This should be 1 when CSR gets committed - /* GLOBALS *******************************************************************/ extern UNICODE_STRING SystemDirectory; @@ -26,6 +24,8 @@ extern UNICODE_STRING WindowsDirectory; HANDLE hProcessHeap = NULL; HMODULE hCurrentModule = NULL; HANDLE hBaseDir = NULL; +PPEB Peb; +ULONG SessionId; static BOOL DllInitialized = FALSE; static BOOL ConsoleInitialized = FALSE; @@ -44,6 +44,7 @@ extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAnd extern BOOL FASTCALL NlsInit(); extern VOID FASTCALL NlsUninit(); +BOOLEAN InWindows = FALSE; HANDLE STDCALL @@ -52,38 +53,74 @@ DuplicateConsoleHandle(HANDLE hConsole, BOOL bInheritHandle, DWORD dwOptions); +#define WIN_OBJ_DIR L"\\Windows" +#define SESSION_DIR L"\\Sessions" + /* FUNCTIONS *****************************************************************/ -static NTSTATUS +NTSTATUS +WINAPI OpenBaseDirectory(PHANDLE DirHandle) { - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\BaseNamedObjects"); - NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING Name = RTL_CONSTANT_STRING(L"\\BaseNamedObjects"); + NTSTATUS Status; - InitializeObjectAttributes(&ObjectAttributes, - &Name, - OBJ_CASE_INSENSITIVE|OBJ_PERMANENT, - NULL, - NULL); + InitializeObjectAttributes(&ObjectAttributes, + &Name, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); - Status = NtOpenDirectoryObject(DirHandle, - DIRECTORY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) + Status = NtOpenDirectoryObject(DirHandle, + DIRECTORY_ALL_ACCESS & + ~(DELETE | WRITE_DAC | WRITE_OWNER), + &ObjectAttributes); + if (!NT_SUCCESS(Status)) { - Status = NtCreateDirectoryObject(DirHandle, - DIRECTORY_ALL_ACCESS, - &ObjectAttributes); - if (!NT_SUCCESS(Status)) - { - DbgPrint("NtCreateDirectoryObject() failed\n"); - } - - return Status; + /* FIXME: It's not our job to create the BNO directory, csr does it */ + Status = NtCreateDirectoryObject(DirHandle, + DIRECTORY_ALL_ACCESS, + &ObjectAttributes); + if (!NT_SUCCESS(Status)) + { + DPRINT1("NtCreateDirectoryObject() failed\n"); + } } - return STATUS_SUCCESS; + DPRINT("Opened BNO: %lx\n", *DirHandle); + return Status; +} + +/* + * @unimplemented + */ +BOOL +WINAPI +BaseQueryModuleData(IN LPSTR ModuleName, + IN LPSTR Unknown, + IN PVOID Unknown2, + IN PVOID Unknown3, + IN PVOID Unknown4) +{ + DPRINT1("BaseQueryModuleData called: %s %s %x %x %x\n", + ModuleName, + Unknown, + Unknown2, + Unknown3, + Unknown4); + return FALSE; +} + +/* + * @unimplemented + */ +NTSTATUS +WINAPI +BaseProcessInitPostImport(VOID) +{ + /* FIXME: Initialize TS pointers */ + return STATUS_SUCCESS; } BOOL @@ -210,20 +247,75 @@ DllMain(HANDLE hDll, BOOLEAN IsServer; ULONG Dummy; ULONG DummySize = sizeof(Dummy); + WCHAR SessionDir[256]; DPRINT("DllMain(hInst %lx, dwReason %lu)\n", hDll, dwReason); + /* Cache the PEB and Session ID */ + Peb = NtCurrentPeb(); + SessionId = Peb->SessionId; + switch (dwReason) { case DLL_PROCESS_ATTACH: + /* OK, yes, this is really retarded but it works for now */ + InWindows = NtCurrentPeb()->BeingDebugged; + + /* + * CreateProcess will run in the real kernel32 and it will write + * its own BaseProcessStartThunk EIP in the CONTEXT that ZwContinue + * will get. We'll be first called by Ldr while initializing, and we'll + * be wrapped in 3 layers of SEH, followed by two frames, finally + * followed by our CONTEXT on the stack. We'll modify the EIP in it + * to match the correct one (our own) and then everything works. + * Tested on XP and 2K3, probably doesn't work in 2K. + */ + if (InWindows) + { + /* + * Due to yet another bug in how Windows handles .local, LDR will + * actually end up loading us twice. The second time will be the + * "official" load, at a totally different address. It will be, + * it will be at -that- address that all the APIs will be called. + * However, that address is dynamic while this one will be static, + * so we'll do initilization with this one. Plus, at this one, + * we know exactly that we're within 3 SEH layers. + */ + if (hDll == (HANDLE)0x7c800000) + { + PULONG Eip; + Eip = (PULONG)*(PULONG)*(PULONG)NtCurrentTeb()->Tib.ExceptionList + + 0x9 + + FIELD_OFFSET(CONTEXT, Eip) / sizeof(ULONG); + *Eip = (ULONG)BaseProcessStartThunk; + } + } + /* Don't bother us for each thread */ LdrDisableThreadCalloutsForDll((PVOID)hDll); + /* Setup the right Object Directory path */ + if (!SessionId) + { + /* Use the raw path */ + wcscpy(SessionDir, WIN_OBJ_DIR); + } + else + { + /* Use the session path */ + swprintf(SessionDir, + L"%ws\\%ld%ws", + SESSION_DIR, + SessionId, + WIN_OBJ_DIR); + } + /* Connect to the base server */ - Status = CsrClientConnectToServer(L"\\Windows", // <- FIXME: SessionDir - CSR_BASE_DLL, + DPRINT("Connecting to CSR...\n"); + Status = CsrClientConnectToServer(SessionDir, + InWindows ? 1 : 0, &Dummy, &DummySize, &IsServer); @@ -238,85 +330,85 @@ DllMain(HANDLE hDll, if (!IsServer) { /* Set the termination port for the thread */ + DPRINT("Creating new thread for CSR\n"); CsrNewThread(); } - hProcessHeap = RtlGetProcessHeap(); - hCurrentModule = hDll; + hProcessHeap = RtlGetProcessHeap(); + hCurrentModule = hDll; + DPRINT("Heap: %p\n", hProcessHeap); - /* - * Initialize WindowsDirectory and SystemDirectory - */ - DPRINT("NtSystemRoot: %S\n", - SharedUserData->NtSystemRoot); - RtlCreateUnicodeString (&WindowsDirectory, - SharedUserData->NtSystemRoot); - SystemDirectory.MaximumLength = WindowsDirectory.MaximumLength + 18; - SystemDirectory.Length = WindowsDirectory.Length + 18; - SystemDirectory.Buffer = RtlAllocateHeap (hProcessHeap, - 0, - SystemDirectory.MaximumLength); - wcscpy (SystemDirectory.Buffer, WindowsDirectory.Buffer); - wcscat (SystemDirectory.Buffer, L"\\System32"); + /* + * Initialize WindowsDirectory and SystemDirectory + */ + DPRINT("NtSystemRoot: %S\n", SharedUserData->NtSystemRoot); + RtlCreateUnicodeString (&WindowsDirectory, SharedUserData->NtSystemRoot); + SystemDirectory.MaximumLength = WindowsDirectory.MaximumLength + 18; + SystemDirectory.Length = WindowsDirectory.Length + 18; + SystemDirectory.Buffer = RtlAllocateHeap(hProcessHeap, + 0, + SystemDirectory.MaximumLength); + wcscpy(SystemDirectory.Buffer, WindowsDirectory.Buffer); + wcscat(SystemDirectory.Buffer, L"\\System32"); - /* Open object base directory */ - Status = OpenBaseDirectory(&hBaseDir); - if (!NT_SUCCESS(Status)) - { - DbgPrint("Failed to open object base directory (Status %lx)\n", - Status); - return FALSE; - } - - /* Initialize the DLL critical section */ - RtlInitializeCriticalSection(&DllLock); - - /* Initialize the National Language Support routines */ - if (! NlsInit()) - { + /* Open object base directory */ + Status = OpenBaseDirectory(&hBaseDir); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open object base directory (Status %lx)\n", Status); return FALSE; - } + } - /* Initialize Console Support */ - if (!BasepInitConsole()) - { - DPRINT1("Failure to set up console\n"); - return FALSE; + /* Initialize the DLL critical section */ + RtlInitializeCriticalSection(&DllLock); + + /* Initialize the National Language Support routines */ + if (!NlsInit()) + { + DPRINT1("NLS Init failed\n"); + return FALSE; + } + + /* Initialize Console Support */ + if (!BasepInitConsole()) + { + DPRINT1("Failure to set up console\n"); + return FALSE; + } + + /* Insert more dll attach stuff here! */ + DllInitialized = TRUE; + DPRINT1("Initialization complete\n"); + break; + + case DLL_PROCESS_DETACH: + + DPRINT("DLL_PROCESS_DETACH\n"); + if (DllInitialized == TRUE) + { + /* Insert more dll detach stuff here! */ + NlsUninit(); + + /* Delete DLL critical section */ + if (ConsoleInitialized == TRUE) + { + RtlDeleteCriticalSection (&ConsoleLock); + } + RtlDeleteCriticalSection (&DllLock); + + /* Close object base directory */ + NtClose(hBaseDir); + + RtlFreeUnicodeString (&SystemDirectory); + RtlFreeUnicodeString (&WindowsDirectory); + } + break; + + default: + break; } - /* Insert more dll attach stuff here! */ - - DllInitialized = TRUE; - break; - - case DLL_PROCESS_DETACH: - DPRINT("DLL_PROCESS_DETACH\n"); - if (DllInitialized == TRUE) - { - /* Insert more dll detach stuff here! */ - - NlsUninit(); - - /* Delete DLL critical section */ - if (ConsoleInitialized == TRUE) - { - RtlDeleteCriticalSection (&ConsoleLock); - } - RtlDeleteCriticalSection (&DllLock); - - /* Close object base directory */ - NtClose(hBaseDir); - - RtlFreeUnicodeString (&SystemDirectory); - RtlFreeUnicodeString (&WindowsDirectory); - } - break; - - default: - break; - } - - return TRUE; + return TRUE; } /* EOF */