/* * @implemented */ BOOL WINAPI GdiDllInitialize ( HANDLE hDll, DWORD dwReason, LPVOID lpReserved) { switch (dwReason) { case DLL_PROCESS_ATTACH: GdiProcessSetup (); break; case DLL_THREAD_ATTACH: NtCurrentTeb()->GdiTebBatch.Offset = 0; NtCurrentTeb()->GdiBatchCount = 0; break; default: return FALSE; } // Very simple, the list will fill itself as it is needed. if(!SetStockObjects) { RtlZeroMemory( &stock_objects, NB_STOCK_OBJECTS); //Assume Ros is dirty. SetStockObjects = TRUE; } return TRUE; }
BOOLEAN GdiDllInitialize( PVOID pvDllHandle, ULONG ulReason, PCONTEXT pcontext) { NTSTATUS status = 0; INT i; BOOLEAN fServer; PTEB pteb = NtCurrentTeb(); BOOL bRet = TRUE; switch (ulReason) { case DLL_PROCESS_ATTACH: // // force the kernel to initialize. This should be done last // since ClientThreadSetup is going to get called before this returns. // if (NtGdiInit() != TRUE) { return(FALSE); } bRet = GdiProcessSetup(); case DLL_THREAD_ATTACH: pteb->GdiTebBatch.Offset = 0; pteb->GdiBatchCount = 0; break; case DLL_PROCESS_DETACH: case DLL_THREAD_DETACH: break; } return(bRet); pvDllHandle; pcontext; }
BOOL WINAPI ClientThreadSetupHelper(BOOL IsCallback) { /* * Normally we are called by win32k so the win32 thread pointers * should be valid as they are set in win32k::InitThreadCallback. */ PCLIENTINFO ClientInfo = GetWin32ClientInfo(); BOOLEAN IsFirstThread = _InterlockedExchange8((PCHAR)&gfFirstThread, FALSE); TRACE("In ClientThreadSetup(IsCallback == %s, gfServerProcess = %s, IsFirstThread = %s)\n", IsCallback ? "TRUE" : "FALSE", gfServerProcess ? "TRUE" : "FALSE", IsFirstThread ? "TRUE" : "FALSE"); if (IsFirstThread) GdiProcessSetup(); /* Check for already initialized thread, and bail out if so */ if (ClientInfo->CI_flags & CI_INITTHREAD) { ERR("ClientThreadSetup: Thread already initialized.\n"); return FALSE; } /* * CSRSS couldn't use user32::DllMain CSR server-to-server call to connect * to win32k. So it is delayed to a manually-call to ClientThreadSetup. * Also this needs to be done only for the first thread (since the connection * is per-process). */ if (gfServerProcess && IsFirstThread) { NTSTATUS Status; USERCONNECT UserCon; RtlZeroMemory(&UserCon, sizeof(UserCon)); /* Minimal setup of the connect info structure */ UserCon.ulVersion = USER_VERSION; /* Connect to win32k */ Status = NtUserProcessConnect(NtCurrentProcess(), &UserCon, sizeof(UserCon)); if (!NT_SUCCESS(Status)) return FALSE; /* Retrieve data */ g_ppi = ClientInfo->ppi; // Snapshot PI, used as pointer only! g_ulSharedDelta = UserCon.siClient.ulSharedDelta; gpsi = SharedPtrToUser(UserCon.siClient.psi); gHandleTable = SharedPtrToUser(UserCon.siClient.aheList); gHandleEntries = SharedPtrToUser(gHandleTable->handles); gSharedInfo = UserCon.siClient; // ERR("1 SI 0x%x : HT 0x%x : D 0x%x\n", UserCon.siClient.psi, UserCon.siClient.aheList, g_ulSharedDelta); } TRACE("Checkpoint (register PFN)\n"); if (!RegisterClientPFN()) { ERR("RegisterClientPFN failed\n"); return FALSE; } /* Mark this thread as initialized */ ClientInfo->CI_flags |= CI_INITTHREAD; /* Initialization that should be done once per process */ if (IsFirstThread) { TRACE("Checkpoint (Allocating TLS)\n"); /* Allocate an index for user32 thread local data */ User32TlsIndex = TlsAlloc(); if (User32TlsIndex == TLS_OUT_OF_INDEXES) return FALSE; // HAAAAAAAAAACK!!!!!! // ASSERT(gpsi); if (!gpsi) ERR("AAAAAAAAAAAHHHHHHHHHHHHHH!!!!!!!! gpsi == NULL !!!!\n"); if (gpsi) { TRACE("Checkpoint (MessageInit)\n"); if (MessageInit()) { TRACE("Checkpoint (MenuInit)\n"); if (MenuInit()) { TRACE("Checkpoint initialization done OK\n"); InitializeCriticalSection(&U32AccelCacheLock); LoadAppInitDlls(); return TRUE; } MessageCleanup(); } TlsFree(User32TlsIndex); return FALSE; } } return TRUE; }