线程为窗口维护一个threadinfo结构,
threadinfo数据结构:
------------------
|登记消息队列指针|
------------------
|虚拟输入队列指针|
------------------
|发送消息队列指针|
------------------
|应答消息队列指针|
------------------
| nExitCode |
------------------
| 唤醒标志 |
------------------
|局部输入状态变量|
------------------
具体表现为每个线程有一个:gptiCurrent的全局变量。
threadinfo结构体是:
typedef struct tagTHREADINFO {
W32THREAD;
//***************************************** begin: USER specific fields
LIST_ENTRY PtiLink; // Link to other threads on desktop
PTL ptl; // Listhead for thread lock list
PTL ptlOb; // Listhead for kernel object thread lock list
PTL ptlPool; // Listhead for temp pool usage
int cEnterCount;
struct tagPROCESSINFO *ppi; // process info struct for this thread
struct tagQ *pq; // keyboard and mouse input queue
PKL spklActive; // active keyboard layout for this thread
MLIST mlPost; // posted message list.
USHORT fsChangeBitsRemoved;// Bits removed during PeekMessage
USHORT cDeskClient; // Ref count for CSRSS desktop
PCLIENTTHREADINFO pcti; // Info that must be visible from client
CLIENTTHREADINFO cti; // Use this when no desktop is available
HANDLE hEventQueueClient;
PKEVENT pEventQueueServer;
PKEVENT *apEvent; // Wait array for xxxPollAndWaitForSingleObject
PDESKTOP rpdesk;
HDESK hdesk; // Desktop handle
ACCESS_MASK amdesk; // Granted desktop access
PDESKTOPINFO pDeskInfo; // Desktop info visible to client
PCLIENTINFO pClientInfo; // Client info stored in TEB
DWORD TIF_flags; // TIF_ flags go here.
PUNICODE_STRING pstrAppName; // Application module name.
struct tagSMS *psmsSent; // Most recent SMS this thread has sent
struct tagSMS *psmsCurrent; // Received SMS this thread is currently processing
struct tagSMS *psmsReceiveList; // SMSs to be processed
LONG timeLast; // Time, position, and ID of last message
POINT ptLast;
DWORD idLast;
int cQuit;
int exitCode;
int cPaintsReady;
UINT cTimersReady;
PMENUSTATE pMenuState;
union {
PTDB ptdb; // Win16Task Schedule data for WOW thread
PWINDOWSTATION pwinsta; // Window station for SYSTEM thread
PDESKTOP pdeskClient; // Desktop for CSRSS thread
};
PSVR_INSTANCE_INFO psiiList; // thread DDEML instance list
DWORD dwExpWinVer;
DWORD dwCompatFlags; // The Win 3.1 Compat flags
UINT cWindows; // Number of windows owned by this thread
UINT cVisWindows; // Number of visible windows on this thread
struct tagQ *pqAttach; // calculation variabled used in
// AttachThreadInput()
int iCursorLevel; // keep track of each thread's level
DWORD fsReserveKeys; // Keys that must be sent to the active
// active console window.
struct tagTHREADINFO *ptiSibling; // pointer to sibling thread info
PMOVESIZEDATA pmsd;
DWORD fsHooks; // WHF_ Flags for which hooks are installed
PHOOK asphkStart[CWINHOOKS]; // Hooks registered for this thread
PHOOK sphkCurrent; // Hook this thread is currently processing
PSBTRACK pSBTrack;
#ifdef FE_IME
PWND spwndDefaultIme; // Default IME Window for this thread
PIMC spDefaultImc; // Default input context for this thread
HKL hklPrev; // Previous active keyboard layout
#endif
} THREADINFO;
__int16 __stdcall RegisterClassExWOWW(PWNDCLASSEXW lpWndClass, int pdwWOWstuff, PROC lpfnWorker, int fnid)
{
PWNDCLASSEXW lpWndClass_; // ebx@1
HINSTANCE v5; // eax@6
UINT v6; // eax@7
bool State; // esi@14
LPCWSTR v8; // eax@15
int v9; // ecx@16
HINSTANCE hInstance; // ebx@19
HMODULE v11; // eax@20
void *v13; // eax@14
int Flags2; // eax@47
int v15; // [sp+27Ch] [bp-4h]@1
LPDWORD pdwWOWstuff_; // [sp+48h] [bp-238h]@1
int v17; // [sp+58h] [bp-228h]@1
int v18; // [sp+68h] [bp-218h]@1
int v19; // [sp+44h] [bp-23Ch]@1
signed int MinorSubsystemVersion; // [sp+78h] [bp-208h]@7
HLOCAL fnWorker; // [sp+6Ch] [bp-214h]@9
char v22; // [sp+38h] [bp-248h]@9
WNDCLASSEX WndClass; // [sp+8h] [bp-278h]@10
int v24; // [sp+7Ch] [bp-204h]@14
__int16 v25; // [sp+4Ch] [bp-234h]@15
CHAR *pstrClassName; // [sp+54h] [bp-22Ch]@15
__int16 v27; // [sp+5Ch] [bp-224h]@17
int pcmn; // [sp+64h] [bp-21Ch]@17
void *v29; // [sp+70h] [bp-210h]@26
__int16 v30; // [sp+4Eh] [bp-232h]@35
LPCWSTR v31; // [sp+50h] [bp-230h]@35
__int16 v32; // [sp+5Eh] [bp-222h]@36
signed int v33; // [sp+60h] [bp-220h]@36
lpWndClass_ = lpWndClass;
v15 = _security_cookie_77D701B8;
pdwWOWstuff_ = (LPDWORD)pdwWOWstuff;
v17 = 0;
v18 = 0;
v19 = 0;
if ( (_WORD)lpfnWorker )
{
if ( (_WORD)lpfnWorker == 8192 )
lpfnWorker = 0;
MinorSubsystemVersion = 1024;
}
else
{
if ( lpWndClass->cbClsExtra < 0
|| lpWndClass->cbWndExtra < 0
|| lpWndClass->hInstance == hInstance && *(_DWORD *)(*MK_FP(__FS__, 24) + 1748) >= 0x400u )
goto LABEL_32;
if ( !lpWndClass->hInstance )
lpWndClass->hInstance = GetModuleHandleW(0);
v5 = lpWndClass_->hInstance;
if ( !v5 )
v5 = GetModuleHandleW(0);
MinorSubsystemVersion = pfnGetExpWinVer_77D70268(v5);
v6 = lpWndClass_->style;
if ( v6 & 0xF7FC0114 )
{
if ( (unsigned int)MinorSubsystemVersion > 0x30A )
goto LABEL_32;
lpWndClass_->style = v6 & 0x803FEEB;
}
if ( lpWndClass_->hbrBackground > (HBRUSH)0x1F && !GdiValidateHandle(lpWndClass_->hbrBackground) )
{
if ( (unsigned int)MinorSubsystemVersion <= 0x300 )
{
lpWndClass_->hbrBackground = 0;
goto LABEL_9;
}
LABEL_32:
UserSetLastError_77D1EBE3(87);
return 0;
}
}
LABEL_9:
if ( InitClsMenuNameW_77D1A344(&fnWorker, lpWndClass_->lpszMenuName, &v22) )
{
memcpy(&WndClass, lpWndClass_, sizeof(WndClass));
if ( (unsigned int)MinorSubsystemVersion > 0x30A )
LOBYTE(fnid) = (_BYTE)fnid | 0x80;
if ( *(_BYTE *)(*MK_FP(__FS__, 24) + 1760) & 2 )
{
Flags2 = GetAppCompatFlags2(0xFFFF9900u);
if ( !(Flags2 & 0x800000) )
BYTE3(fnid) &= 0xBFu;
}
if ( BYTE1(fnid) & 1 )
{
LOWORD(State) = 0;
v13 = ClassNameToVersion_77D198A0((wchar_t *)lpWndClass_->lpszClassName, (int)&v24, 0, 0);
MinorSubsystemVersion = (signed int)v13;
if ( !v13 )
{
LABEL_25:
if ( (unsigned int)fnWorker & 0xFFFF0000 )
LocalFree(fnWorker);
if ( (unsigned int)v29 & 0xFFFF0000 )
LocalFree(v29);
return State;
}
}
else
{
MinorSubsystemVersion = (signed int)lpWndClass_->lpszClassName;
}
v17 = 0;
pstrClassName = (CHAR *)&v25;
v8 = lpWndClass_->lpszClassName;
if ( (unsigned int)v8 & 0xFFFF0000 )
{
RtlInitUnicodeString(&v25, lpWndClass_->lpszClassName);
v9 = 0;
}
else
{
v9 = 0;
v30 = 0;
v25 = 0;
v31 = v8;
}
pcmn = (int)&v27;
v18 = v9;
if ( MinorSubsystemVersion & 0xFFFF0000 )
{
RtlInitUnicodeString(&v27, MinorSubsystemVersion);
}
else
{
v32 = v9;
v27 = v9;
v33 = MinorSubsystemVersion;
}
hInstance = lpWndClass_->hInstance;
State = (unsigned __int16)NtUserRegisterClassExWOW_77D19A29(
&WndClass,
(PUNICODE_STRING)pstrClassName,
(PVOID)pcmn,
(int (__stdcall *)())&fnWorker,
(WORD)lpfnWorker,
fnid,
pdwWOWstuff_);
if ( hInstance )
v11 = hInstance;
else
v11 = GetModuleHandleW(0);
if ( (unsigned int)pfnGetExpWinVer_77D70268(v11) < 0x30A )
State = State != 0;
if ( State )
return State;
goto LABEL_25;
}
return 0;
}