BOOL WINAPI DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) { NTSTATUS Status; BASESRV_API_CONNECTINFO ConnectInfo; ULONG ConnectInfoSize = sizeof(ConnectInfo); WCHAR SessionDir[256]; DPRINT("DllMain(hInst %p, dwReason %lu)\n", hDll, dwReason); Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString; /* Cache the PEB and Session ID */ Peb = NtCurrentPeb(); SessionId = Peb->SessionId; switch (dwReason) { case DLL_PROCESS_ATTACH: { /* Set no filter initially */ GlobalTopLevelExceptionFilter = RtlEncodePointer(NULL); /* Enable the Rtl thread pool and timer queue to use proper Win32 thread */ RtlSetThreadPoolStartFunc(BaseCreateThreadPoolThread, BaseExitThreadPoolThread); /* Register the manifest prober routine */ LdrSetDllManifestProber(BasepProbeForDllManifest); /* Don't bother us for each thread */ LdrDisableThreadCalloutsForDll((PVOID)hDll); /* Initialize default path to NULL */ RtlInitUnicodeString(&BaseDefaultPath, NULL); /* Setup the 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(SessionDir, BASESRV_SERVERDLL_INDEX, &ConnectInfo, &ConnectInfoSize, &BaseRunningInServerProcess); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to connect to CSR (Status %lx)\n", Status); NtTerminateProcess(NtCurrentProcess(), Status); return FALSE; } /* Get the server data */ ASSERT(Peb->ReadOnlyStaticServerData); BaseStaticServerData = Peb->ReadOnlyStaticServerData[BASESRV_SERVERDLL_INDEX]; ASSERT(BaseStaticServerData); /* Check if we are running a CSR Server */ if (!BaseRunningInServerProcess) { /* Set the termination port for the thread */ DPRINT("Creating new thread for CSR\n"); CsrNewThread(); } /* Initialize heap handle table */ BaseDllInitializeMemoryManager(); /* Set HMODULE for our DLL */ kernel32_handle = hCurrentModule = hDll; /* Set the directories */ BaseWindowsDirectory = BaseStaticServerData->WindowsDirectory; BaseWindowsSystemDirectory = BaseStaticServerData->WindowsSystemDirectory; /* Construct the default path (using the static buffer) */ _snwprintf(BaseDefaultPathBuffer, sizeof(BaseDefaultPathBuffer) / sizeof(WCHAR), L".;%wZ;%wZ\\system;%wZ;", &BaseWindowsSystemDirectory, &BaseWindowsDirectory, &BaseWindowsDirectory); BaseDefaultPath.Buffer = BaseDefaultPathBuffer; BaseDefaultPath.Length = wcslen(BaseDefaultPathBuffer) * sizeof(WCHAR); BaseDefaultPath.MaximumLength = sizeof(BaseDefaultPathBuffer); /* Use remaining part of the default path buffer for the append path */ BaseDefaultPathAppend.Buffer = (PWSTR)((ULONG_PTR)BaseDefaultPathBuffer + BaseDefaultPath.Length); BaseDefaultPathAppend.Length = 0; BaseDefaultPathAppend.MaximumLength = BaseDefaultPath.MaximumLength - BaseDefaultPath.Length; /* Initialize command line */ InitCommandLines(); /* Initialize the DLL critical section */ RtlInitializeCriticalSection(&BaseDllDirectoryLock); /* Initialize the National Language Support routines */ if (!NlsInit()) { DPRINT1("NLS Init failed\n"); return FALSE; } /* Initialize Console Support */ if (!ConDllInitialize(dwReason, SessionDir)) { DPRINT1("Failed to set up console\n"); return FALSE; } /* Initialize application certification globals */ InitializeListHead(&BasepAppCertDllsList); RtlInitializeCriticalSection(&gcsAppCert); /* Insert more dll attach stuff here! */ DllInitialized = TRUE; break; } case DLL_PROCESS_DETACH: { if (DllInitialized != FALSE) { /* Uninitialize console support */ ConDllInitialize(dwReason, NULL); /* Insert more dll detach stuff here! */ NlsUninit(); /* Delete DLL critical section */ RtlDeleteCriticalSection(&BaseDllDirectoryLock); } break; } case DLL_THREAD_ATTACH: { /* ConDllInitialize sets the current console locale for the new thread */ return ConDllInitialize(dwReason, NULL); } default: break; } return TRUE; }
BOOL WINAPI BasepInitConsole(VOID) { NTSTATUS Status; PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters; WCHAR SessionDir[256]; ULONG SessionId = NtCurrentPeb()->SessionId; BOOLEAN InServer; CONSOLE_CONNECTION_INFO ConnectInfo; ULONG ConnectInfoSize = sizeof(ConnectInfo); DPRINT("BasepInitConsole for : %wZ\n", &Parameters->ImagePathName); DPRINT("Our current console handles are: %lx, %lx, %lx %lx\n", Parameters->ConsoleHandle, Parameters->StandardInput, Parameters->StandardOutput, Parameters->StandardError); /* Initialize our global console DLL lock */ Status = RtlInitializeCriticalSection(&ConsoleLock); if (!NT_SUCCESS(Status)) return FALSE; ConsoleInitialized = TRUE; /* Do nothing if this isn't a console app... */ if (RtlImageNtHeader(GetModuleHandle(NULL))->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI) { DPRINT("Image is not a console application\n"); Parameters->ConsoleHandle = NULL; ConnectInfo.ConsoleNeeded = FALSE; // ConsoleNeeded is used for knowing whether or not this is a CUI app. ConnectInfo.ConsoleStartInfo.ConsoleTitle[0] = L'\0'; ConnectInfo.ConsoleStartInfo.AppPath[0] = L'\0'; } else { LPCWSTR ExeName; InitConsoleInfo(&ConnectInfo.ConsoleStartInfo, &Parameters->ImagePathName); /* Initialize Input EXE name */ ExeName = wcsrchr(Parameters->ImagePathName.Buffer, L'\\'); if (ExeName) SetConsoleInputExeNameW(ExeName + 1); /* Assume one is needed */ ConnectInfo.ConsoleNeeded = TRUE; /* Handle the special flags given to us by BasePushProcessParameters */ if (Parameters->ConsoleHandle == HANDLE_DETACHED_PROCESS) { /* No console to create */ DPRINT("No console to create\n"); Parameters->ConsoleHandle = NULL; ConnectInfo.ConsoleNeeded = FALSE; } else if (Parameters->ConsoleHandle == HANDLE_CREATE_NEW_CONSOLE) { /* We'll get the real one soon */ DPRINT("Creating new console\n"); Parameters->ConsoleHandle = NULL; } else if (Parameters->ConsoleHandle == HANDLE_CREATE_NO_WINDOW) { /* We'll get the real one soon */ DPRINT("Creating new invisible console\n"); Parameters->ConsoleHandle = NULL; ConnectInfo.ConsoleStartInfo.ShowWindow = SW_HIDE; } else { if (Parameters->ConsoleHandle == INVALID_HANDLE_VALUE) { Parameters->ConsoleHandle = NULL; } DPRINT("Using existing console: %x\n", Parameters->ConsoleHandle); } } /* Now use the proper console handle */ ConnectInfo.Console = Parameters->ConsoleHandle; /* Initialize the Console Ctrl Handler */ InitConsoleCtrlHandling(); ConnectInfo.CtrlDispatcher = ConsoleControlDispatcher; /* Initialize the Property Dialog Handler */ ConnectInfo.PropDispatcher = PropDialogHandler; /* 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 Console Server */ DPRINT("Connecting to the Console Server in BasepInitConsole...\n"); Status = CsrClientConnectToServer(SessionDir, CONSRV_SERVERDLL_INDEX, &ConnectInfo, &ConnectInfoSize, &InServer); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to connect to the Console Server (Status %lx)\n", Status); return FALSE; } /* Nothing to do for server-to-server */ if (InServer) return TRUE; /* Nothing to do if not a console app */ if (!ConnectInfo.ConsoleNeeded) return TRUE; /* We got the handles, let's set them */ if ((Parameters->ConsoleHandle = ConnectInfo.Console)) { /* If we already had some, don't use the new ones */ if (!Parameters->StandardInput) { Parameters->StandardInput = ConnectInfo.InputHandle; } if (!Parameters->StandardOutput) { Parameters->StandardOutput = ConnectInfo.OutputHandle; } if (!Parameters->StandardError) { Parameters->StandardError = ConnectInfo.ErrorHandle; } } InputWaitHandle = ConnectInfo.InputWaitHandle; DPRINT("Console setup: %lx, %lx, %lx, %lx\n", Parameters->ConsoleHandle, Parameters->StandardInput, Parameters->StandardOutput, Parameters->StandardError); return TRUE; }
INT WINAPI DllMain( IN PVOID hInstanceDll, IN ULONG dwReason, IN PVOID reserved) { switch (dwReason) { case DLL_PROCESS_ATTACH: { #define WIN_OBJ_DIR L"\\Windows" #define SESSION_DIR L"\\Sessions" USERSRV_API_CONNECTINFO ConnectInfo; // USERCONNECT #if 0 // Disabling this code is a BIG HACK!! NTSTATUS Status; ULONG ConnectInfoSize = sizeof(ConnectInfo); WCHAR SessionDir[256]; /* Cache the PEB and Session ID */ PPEB Peb = NtCurrentPeb(); ULONG SessionId = Peb->SessionId; // gSessionId TRACE("user32::DllMain\n"); /* Don't bother us for each thread */ DisableThreadLibraryCalls(hInstanceDll); RtlZeroMemory(&ConnectInfo, sizeof(ConnectInfo)); /* Minimal setup of the connect info structure */ ConnectInfo.ulVersion = USER_VERSION; /* Setup the 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); } TRACE("Checkpoint (call CSR)\n"); /* Connect to the USER Server */ Status = CsrClientConnectToServer(SessionDir, USERSRV_SERVERDLL_INDEX, &ConnectInfo, &ConnectInfoSize, &gfServerProcess); if (!NT_SUCCESS(Status)) { ERR("Failed to connect to CSR (Status %lx)\n", Status); return FALSE; } TRACE("Checkpoint (CSR called)\n"); #endif User32Instance = hInstanceDll; /* Finish initialization */ TRACE("Checkpoint (call Init)\n"); if (!Init(&ConnectInfo)) return FALSE; if (!gfServerProcess) { #if WIN32K_ISNT_BROKEN InitializeImmEntryTable(); #else /* imm32 takes a refcount and prevents us from unloading */ LoadLibraryW(L"user32"); #endif // // Wine is stub and throws an exception so save this for real Imm32.dll testing!!!! // //gImmApiEntries.pImmRegisterClient(&gSharedInfo, ghImm32); } break; } case DLL_PROCESS_DETACH: { if (ghImm32) FreeLibrary(ghImm32); Cleanup(); break; } } /* Finally, initialize GDI */ return GdiDllInitialize(hInstanceDll, dwReason, reserved); }