VOID FASTCALL GetConnected(VOID) { USERCONNECT UserCon; // ERR("GetConnected\n"); if ((PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo == NULL) NtUserGetThreadState(THREADSTATE_GETTHREADINFO); if (gpsi && g_ppi) return; // FIXME HAX: Due to the "Dll Initialization Bug" we have to call this too. GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL); NtUserProcessConnect( NtCurrentProcess(), &UserCon, sizeof(USERCONNECT)); g_ppi = GetWin32ClientInfo()->ppi; g_ulSharedDelta = UserCon.siClient.ulSharedDelta; gpsi = SharedPtrToUser(UserCon.siClient.psi); gHandleTable = SharedPtrToUser(UserCon.siClient.aheList); gHandleEntries = SharedPtrToUser(gHandleTable->handles); }
/* * @implemented */ DWORD WINAPI GetAppCompatFlags2(HTASK hTask) { PCLIENTINFO pci = GetWin32ClientInfo(); return pci->dwCompatFlags2; }
static VOID IntRestoreTebWndCallback (HWND hWnd, PWND pWnd, PVOID pActCtx) { PCLIENTINFO ClientInfo = GetWin32ClientInfo(); ClientInfo->CallbackWnd.hWnd = hWnd; ClientInfo->CallbackWnd.pWnd = pWnd; ClientInfo->CallbackWnd.pActCtx = pActCtx; }
// // Pass the Current Window handle and pointer to the Client Callback. // This will help user space programs speed up read access with the window object. // static VOID IntSetTebWndCallback (HWND * hWnd, PWND * pWnd, PVOID * pActCtx) { HWND hWndS = *hWnd; PWND Window = UserGetWindowObject(*hWnd); PCLIENTINFO ClientInfo = GetWin32ClientInfo(); *hWnd = ClientInfo->CallbackWnd.hWnd; *pWnd = ClientInfo->CallbackWnd.pWnd; *pActCtx = ClientInfo->CallbackWnd.pActCtx; ClientInfo->CallbackWnd.hWnd = hWndS; ClientInfo->CallbackWnd.pWnd = DesktopHeapAddressToUser(Window); ClientInfo->CallbackWnd.pActCtx = Window->pActCtx; }
void UserDbgAssertThreadInfo(BOOL showCaller) { PTEB Teb; PPROCESSINFO ppi; PCLIENTINFO pci; PTHREADINFO pti; ppi = PsGetCurrentProcessWin32Process(); pti = PsGetCurrentThreadWin32Thread(); Teb = NtCurrentTeb(); pci = GetWin32ClientInfo(); ASSERT(Teb); ASSERT(pti); ASSERT(pti->ppi == ppi); ASSERT(pti->pClientInfo == pci); ASSERT(Teb->Win32ThreadInfo == pti); ASSERT(pci->ppi == ppi); ASSERT(pci->fsHooks == pti->fsHooks); ASSERT(pci->ulClientDelta == DesktopHeapGetUserDelta()); if (pti->pcti && pci->pDeskInfo) ASSERT(pci->pClientThreadInfo == (PVOID)((ULONG_PTR)pti->pcti - pci->ulClientDelta)); if (pti->pcti && IsListEmpty(&pti->SentMessagesListHead)) ASSERT((pti->pcti->fsChangeBits & QS_SENDMESSAGE) == 0); if (pti->KeyboardLayout) ASSERT(pci->hKL == pti->KeyboardLayout->hkl); if(pti->rpdesk != NULL) ASSERT(pti->pDeskInfo == pti->rpdesk->pDeskInfo); /*too bad we still get this assertion*/ // Why? Not all flags are passed to the user and doing so could crash the system........ /* ASSERT(pci->dwTIFlags == pti->TIF_flags); */ /* if(pci->dwTIFlags != pti->TIF_flags) { ERR("pci->dwTIFlags(0x%x) doesn't match pti->TIF_flags(0x%x)\n", pci->dwTIFlags, pti->TIF_flags); if(showCaller) { DbgPrint("Caller:\n"); KeRosDumpStackFrames(NULL, 10); } pci->dwTIFlags = pti->TIF_flags; } */ }
BOOL Init(VOID) { USERCONNECT UserCon; /* Set PEB data */ NtCurrentPeb()->KernelCallbackTable = apfnDispatch; NtCurrentPeb()->PostProcessInitRoutine = NULL; NtUserProcessConnect( NtCurrentProcess(), &UserCon, sizeof(USERCONNECT)); g_ppi = GetWin32ClientInfo()->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); RtlInitializeCriticalSection(&gcsUserApiHook); gfServerProcess = FALSE; // FIXME HAX! Used in CsrClientConnectToServer(,,,,&gfServerProcess); //CsrClientConnectToServer(L"\\Windows", 0, NULL, 0, &gfServerProcess); //ERR("1 SI 0x%x : HT 0x%x : D 0x%x\n", UserCon.siClient.psi, UserCon.siClient.aheList, g_ulSharedDelta); /* Allocate an index for user32 thread local data. */ User32TlsIndex = TlsAlloc(); if (User32TlsIndex != TLS_OUT_OF_INDEXES) { if (MessageInit()) { if (MenuInit()) { InitializeCriticalSection(&U32AccelCacheLock); GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL); LoadAppInitDlls(); return TRUE; } MessageCleanup(); } TlsFree(User32TlsIndex); } return FALSE; }
// // Pass the Current Window handle and pointer to the Client Callback. // This will help user space programs speed up read access with the window object. // static VOID IntSetTebWndCallback (HWND * hWnd, PWND * pWnd, PVOID * pActCtx) { HWND hWndS = *hWnd; PWND Window = UserGetWindowObject(*hWnd); PCLIENTINFO ClientInfo = GetWin32ClientInfo(); *hWnd = ClientInfo->CallbackWnd.hWnd; *pWnd = ClientInfo->CallbackWnd.pWnd; *pActCtx = ClientInfo->CallbackWnd.pActCtx; if (Window) { ClientInfo->CallbackWnd.hWnd = hWndS; ClientInfo->CallbackWnd.pWnd = DesktopHeapAddressToUser(Window); ClientInfo->CallbackWnd.pActCtx = Window->pActCtx; } else //// What if Dispatching WM_SYS/TIMER with NULL window? Fix AbiWord Crash when sizing. { ClientInfo->CallbackWnd.hWnd = hWndS; ClientInfo->CallbackWnd.pWnd = Window; ClientInfo->CallbackWnd.pActCtx = 0; } }
/* * @implemented */ LRESULT WINAPI CallNextHookEx( HHOOK Hook, // Windows NT/XP/2003: Ignored. int Code, WPARAM wParam, LPARAM lParam) { PCLIENTINFO ClientInfo; DWORD Flags, Save; PHOOK pHook, phkNext; LRESULT lResult = 0; GetConnected(); ClientInfo = GetWin32ClientInfo(); if (!ClientInfo->phkCurrent) return 0; pHook = DesktopPtrToUser(ClientInfo->phkCurrent); if (!pHook->phkNext) return 0; // Nothing to do.... phkNext = DesktopPtrToUser(pHook->phkNext); if ( phkNext->HookId == WH_CALLWNDPROC || phkNext->HookId == WH_CALLWNDPROCRET) { Save = ClientInfo->dwHookData; Flags = ClientInfo->CI_flags & CI_CURTHPRHOOK; // wParam: If the message was sent by the current thread/process, it is // nonzero; otherwise, it is zero. if (wParam) ClientInfo->CI_flags |= CI_CURTHPRHOOK; else ClientInfo->CI_flags &= ~CI_CURTHPRHOOK; if (phkNext->HookId == WH_CALLWNDPROC) { PCWPSTRUCT pCWP = (PCWPSTRUCT)lParam; NtUserMessageCall( pCWP->hwnd, pCWP->message, pCWP->wParam, pCWP->lParam, (ULONG_PTR)&lResult, FNID_CALLWNDPROC, phkNext->Ansi); } else { PCWPRETSTRUCT pCWPR = (PCWPRETSTRUCT)lParam; ClientInfo->dwHookData = pCWPR->lResult; NtUserMessageCall( pCWPR->hwnd, pCWPR->message, pCWPR->wParam, pCWPR->lParam, (ULONG_PTR)&lResult, FNID_CALLWNDPROCRET, phkNext->Ansi); } ClientInfo->CI_flags ^= ((ClientInfo->CI_flags ^ Flags) & CI_CURTHPRHOOK); ClientInfo->dwHookData = Save; } else lResult = NtUserCallNextHookEx(Code, wParam, lParam, pHook->Ansi); return lResult; }
BOOL Init(PUSERCONNECT UserCon /*PUSERSRV_API_CONNECTINFO*/) { NTSTATUS Status = STATUS_SUCCESS; TRACE("user32::Init(0x%p) -->\n", UserCon); RtlInitializeCriticalSection(&gcsUserApiHook); /* Initialize callback table in PEB data */ NtCurrentPeb()->KernelCallbackTable = apfnDispatch; NtCurrentPeb()->PostProcessInitRoutine = NULL; // This is a HACK!! // gfServerProcess = FALSE; gfFirstThread = TRUE; //// End of HACK!! /// /* * Retrieve data from the connect info structure if the initializing * process is not CSRSS. In case it is, this will be done from inside * ClientThreadSetup. */ if (!gfServerProcess) { // FIXME: HACK!! We should fixup for the NtUserProcessConnect fixups // because it was made in the context of CSRSS process and not ours!! // So... as long as we don't fix that, we need to redo again a call // to NtUserProcessConnect... How perverse is that?! // // HACK(2): This call is necessary since we disabled // the CSR call in DllMain... { RtlZeroMemory(UserCon, sizeof(*UserCon)); /* Minimal setup of the connect info structure */ UserCon->ulVersion = USER_VERSION; TRACE("HACK: Hackish NtUserProcessConnect call!!\n"); /* Connect to win32k */ Status = NtUserProcessConnect(NtCurrentProcess(), UserCon, sizeof(*UserCon)); if (!NT_SUCCESS(Status)) return FALSE; } // // We continue as we should do normally... // /* Retrieve data */ g_ppi = GetWin32ClientInfo()->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; } // FIXME: Yet another hack... This call should normally not be done here, but // instead in ClientThreadSetup, and in User32CallClientThreadSetupFromKernel as well. TRACE("HACK: Using Init-ClientThreadSetupHelper hack!!\n"); if (!ClientThreadSetupHelper(FALSE)) { TRACE("Init-ClientThreadSetupHelper hack failed!\n"); return FALSE; } TRACE("<-- user32::Init()\n"); return NT_SUCCESS(Status); }
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; }
BOOL Init(VOID) { USERCONNECT UserCon; PVOID *KernelCallbackTable; /* Set up the kernel callbacks. */ KernelCallbackTable = NtCurrentPeb()->KernelCallbackTable; KernelCallbackTable[USER32_CALLBACK_WINDOWPROC] = (PVOID)User32CallWindowProcFromKernel; KernelCallbackTable[USER32_CALLBACK_SENDASYNCPROC] = (PVOID)User32CallSendAsyncProcForKernel; KernelCallbackTable[USER32_CALLBACK_LOADSYSMENUTEMPLATE] = (PVOID)User32LoadSysMenuTemplateForKernel; KernelCallbackTable[USER32_CALLBACK_LOADDEFAULTCURSORS] = (PVOID)User32SetupDefaultCursors; KernelCallbackTable[USER32_CALLBACK_HOOKPROC] = (PVOID)User32CallHookProcFromKernel; KernelCallbackTable[USER32_CALLBACK_EVENTPROC] = (PVOID)User32CallEventProcFromKernel; KernelCallbackTable[USER32_CALLBACK_LOADMENU] = (PVOID)User32CallLoadMenuFromKernel; KernelCallbackTable[USER32_CALLBACK_CLIENTTHREADSTARTUP] = (PVOID)User32CallClientThreadSetupFromKernel; KernelCallbackTable[USER32_CALLBACK_CLIENTLOADLIBRARY] = (PVOID)User32CallClientLoadLibraryFromKernel; KernelCallbackTable[USER32_CALLBACK_GETCHARSETINFO] = (PVOID)User32CallGetCharsetInfo; NtUserProcessConnect( NtCurrentProcess(), &UserCon, sizeof(USERCONNECT)); g_ppi = GetWin32ClientInfo()->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); RtlInitializeCriticalSection(&gcsUserApiHook); gfServerProcess = FALSE; // FIXME HAX! Used in CsrClientConnectToServer(,,,,&gfServerProcess); //CsrClientConnectToServer(L"\\Windows", 0, NULL, 0, &gfServerProcess); //ERR("1 SI 0x%x : HT 0x%x : D 0x%x\n", UserCon.siClient.psi, UserCon.siClient.aheList, g_ulSharedDelta); /* Allocate an index for user32 thread local data. */ User32TlsIndex = TlsAlloc(); if (User32TlsIndex != TLS_OUT_OF_INDEXES) { if (MessageInit()) { if (MenuInit()) { InitializeCriticalSection(&U32AccelCacheLock); GdiDllInitialize(NULL, DLL_PROCESS_ATTACH, NULL); LoadAppInitDlls(); return TRUE; } MessageCleanup(); } TlsFree(User32TlsIndex); } return FALSE; }