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 */