You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
8716 lines
286 KiB
8716 lines
286 KiB
/****************************** Module Header ******************************\
|
|
* Module Name: userk.h
|
|
*
|
|
* Copyright (c) 1985 - 2001, Microsoft Corporation
|
|
*
|
|
* Typedefs, defines, and prototypes that are used exclusively by the User
|
|
* kernel-mode code.
|
|
*
|
|
* History:
|
|
* 04-28-91 DarrinM Created from PROTO.H, MACRO.H, and STRTABLE.H
|
|
* 01-25-95 JimA Prepped for kernel-mode
|
|
\***************************************************************************/
|
|
|
|
#ifndef _USERK_
|
|
#define _USERK_
|
|
|
|
#ifndef _WINBASE_
|
|
#include <wbasek.h>
|
|
#endif // _WINBASE_
|
|
|
|
#include <csrmsg.h>
|
|
#include <heap.h>
|
|
|
|
/*
|
|
* BltColor() flags.
|
|
*/
|
|
#define BC_INVERT 0x00000001
|
|
#define BC_NOMIRROR 0x00000002
|
|
|
|
#define MIRRORED_HDC(hdc) (GreGetLayout(hdc) & LAYOUT_RTL)
|
|
|
|
#define OEMRESOURCE 1
|
|
|
|
#define CCACHEDCAPTIONS 5
|
|
|
|
#define GETMOUSETRAILS() (IsRemoteConnection() ? 0 : gMouseTrails)
|
|
#define MOUSE_TRAILS_FREQ 50
|
|
|
|
#include <winnls.h>
|
|
#include <wincon.h>
|
|
|
|
#include <winuser.h>
|
|
#include <winuserp.h>
|
|
#include <wowuserp.h>
|
|
#include "ntddvdeo.h"
|
|
|
|
#ifdef GENERIC_INPUT
|
|
#include <hidpddi.h>
|
|
#include <hidpi.h>
|
|
#include <hidclass.h>
|
|
#endif
|
|
|
|
#include <user.h>
|
|
|
|
PTHREADINFO _ptiCrit(VOID);
|
|
PTHREADINFO _ptiCritShared(VOID);
|
|
extern PTHREADINFO gptiCurrent;
|
|
|
|
#if DBG
|
|
#define PtiCurrent() _ptiCrit()
|
|
#define PtiCurrentShared() _ptiCritShared()
|
|
#else // DBG
|
|
#define PtiCurrent() (gptiCurrent)
|
|
#define PtiCurrentShared() ((PTHREADINFO)(W32GetCurrentThread()))
|
|
#endif // DBG
|
|
|
|
extern HANDLE CsrApiPort;
|
|
|
|
#if DBG
|
|
VOID CheckPtiSysPeek(int where, PQ pq, ULONG_PTR newIdSysPeek);
|
|
VOID CheckSysLock(int where, PQ pq, PTHREADINFO pti);
|
|
#else
|
|
#define CheckPtiSysPeek(where, pq, newIdSysPeek)
|
|
#define CheckSysLock(where, pq, pti)
|
|
#endif
|
|
|
|
/*
|
|
* ShutdownProcessRoutine return values
|
|
*/
|
|
#define SHUTDOWN_KNOWN_PROCESS 1
|
|
#define SHUTDOWN_UNKNOWN_PROCESS 2
|
|
#define SHUTDOWN_CANCEL 3
|
|
|
|
/*
|
|
* Macros to get address of current thread and process information.
|
|
*/
|
|
|
|
#define PpiCurrent() ((PPROCESSINFO)(W32GetCurrentProcess()))
|
|
|
|
#define PtiFromThread(Thread) ((PTHREADINFO)(PsGetThreadWin32Thread(Thread)))
|
|
|
|
#if DBG
|
|
#define GetNestedCallsCounter() (PtiCurrentShared()->cNestedCalls)
|
|
#else
|
|
#define GetNestedCallsCounter()
|
|
#endif
|
|
|
|
#define PpiFromProcess(Process) \
|
|
((PPROCESSINFO)(PsGetProcessWin32Process(Process)))
|
|
|
|
#define ISCSRSS() (PsGetCurrentProcess() == gpepCSRSS)
|
|
|
|
BOOL CSTPush(UINT uThreadID, PVOID pParam, HANDLE UniqueProcessId, BOOL bRemoteThreadStack);
|
|
|
|
VOID CSTCleanupStack(BOOL bRemoteThreadStack);
|
|
|
|
__inline BOOL InitCreateSystemThreadsMsg(
|
|
PUSER_API_MSG pMsg,
|
|
UINT ThreadID,
|
|
PVOID pVoid,
|
|
HANDLE UniqueProcessId,
|
|
BOOL bRemoteThread)
|
|
{
|
|
UserAssert(CsrApiPort != NULL);
|
|
|
|
if (!CSTPush(ThreadID, pVoid, UniqueProcessId, bRemoteThread)) {
|
|
return FALSE;
|
|
}
|
|
|
|
pMsg->h.u1.s1.DataLength = (USHORT)(sizeof(USER_API_MSG) - sizeof(PORT_MESSAGE));
|
|
pMsg->h.u1.s1.TotalLength = (USHORT)sizeof(USER_API_MSG);
|
|
pMsg->h.u2.ZeroInit = 0;
|
|
pMsg->CaptureBuffer = NULL;
|
|
pMsg->ApiNumber = CSR_MAKE_API_NUMBER(USERSRV_SERVERDLL_INDEX, UserpCreateSystemThreads);
|
|
pMsg->u.CreateSystemThreads.bRemoteThread = bRemoteThread;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
NTSTATUS OpenEffectiveToken(
|
|
PHANDLE phToken);
|
|
|
|
NTSTATUS GetProcessLuid(
|
|
PETHREAD Thread OPTIONAL,
|
|
PLUID LuidProcess);
|
|
|
|
BOOLEAN IsRestricted(
|
|
PETHREAD Thread);
|
|
|
|
NTSTATUS InitSystemThread(
|
|
PUNICODE_STRING pstrThreadName);
|
|
|
|
#define INITCLIENTINFO(pti) \
|
|
{ \
|
|
try { \
|
|
pti->pClientInfo->dwExpWinVer = pti->dwExpWinVer; \
|
|
pti->pClientInfo->dwTIFlags = pti->TIF_flags; \
|
|
\
|
|
pti->pClientInfo->lpClassesRegistered = NULL; \
|
|
\
|
|
if (pti->spklActive) { \
|
|
pti->pClientInfo->CodePage = pti->spklActive->CodePage; \
|
|
pti->pClientInfo->hKL = pti->spklActive->hkl; \
|
|
} else { \
|
|
pti->pClientInfo->CodePage = CP_ACP; \
|
|
pti->pClientInfo->hKL = 0; \
|
|
} \
|
|
} except (W32ExceptionHandler(TRUE, RIP_WARNING)) { \
|
|
Status = GetExceptionCode(); \
|
|
goto Error; \
|
|
} \
|
|
}
|
|
|
|
PKEVENT CreateKernelEvent(
|
|
IN EVENT_TYPE Type,
|
|
IN BOOLEAN State);
|
|
|
|
NTSTATUS ProtectHandle(
|
|
IN HANDLE Handle,
|
|
IN POBJECT_TYPE pObjectType,
|
|
IN BOOLEAN Protect);
|
|
|
|
__inline VOID FreeKernelEvent(PVOID* pp)
|
|
{
|
|
UserFreePool(*pp);
|
|
*pp = NULL;
|
|
}
|
|
|
|
|
|
extern BOOL gfSwitchInProgress;
|
|
extern PKEVENT gpevtVideoportCallout;
|
|
|
|
__inline VOID SetConsoleSwitchInProgress(BOOL fSwitchInProgress)
|
|
{
|
|
gfSwitchInProgress = fSwitchInProgress;
|
|
if (fSwitchInProgress) {
|
|
KeResetEvent(gpevtVideoportCallout);
|
|
} else {
|
|
KeSetEvent(gpevtVideoportCallout, EVENT_INCREMENT, FALSE);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Object types exported from the kernel.
|
|
*/
|
|
extern POBJECT_TYPE *ExWindowStationObjectType;
|
|
extern POBJECT_TYPE *ExDesktopObjectType;
|
|
extern POBJECT_TYPE *ExEventObjectType;
|
|
extern POBJECT_TYPE *IoDriverObjectType;
|
|
|
|
#ifndef DWORD_ALIGN
|
|
#define DWORD_ALIGN(x) ( ((x) + 3) & ~3)
|
|
#endif // !DWORD_ALIGN
|
|
|
|
/*
|
|
* Private probing macros
|
|
*/
|
|
|
|
#if defined(_X86_)
|
|
#define DATAALIGN sizeof(BYTE)
|
|
#define CHARALIGN sizeof(BYTE)
|
|
#else
|
|
#define DATAALIGN sizeof(DWORD)
|
|
#define CHARALIGN sizeof(WCHAR)
|
|
#endif
|
|
|
|
#define ProbeForReadBuffer(Address, Count, Alignment) { \
|
|
if ((ULONG)(Count) > (ULONG)(MAXULONG / sizeof(*(Address)))) { \
|
|
ExRaiseAccessViolation(); \
|
|
} \
|
|
ProbeForRead(Address, (ULONG)(Count) * sizeof(*(Address)), Alignment); \
|
|
}
|
|
|
|
#define ProbeForWriteBuffer(Address, Count, Alignment) { \
|
|
if ((ULONG)(Count) > (ULONG)(MAXULONG / sizeof(*(Address)))) { \
|
|
ExRaiseAccessViolation(); \
|
|
} \
|
|
ProbeForWrite(Address, (ULONG)(Count) * sizeof(*(Address)), Alignment); \
|
|
}
|
|
|
|
#define ProbeAndReadSize(Address) \
|
|
(((Address) >= (SIZE * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile SIZE * const)MM_USER_PROBE_ADDRESS) : (*(volatile SIZE *)(Address)))
|
|
|
|
|
|
#define ProbeAndReadBlendfunction(Address) \
|
|
(((Address) >= (BLENDFUNCTION * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile BLENDFUNCTION * const)MM_USER_PROBE_ADDRESS) : (*(volatile BLENDFUNCTION *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadPoint(
|
|
// IN PPOINT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbePoint(Address) \
|
|
(((Address) >= (POINT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile DWORD * const)MM_USER_PROBE_ADDRESS) : (*(volatile DWORD *)(Address)))
|
|
|
|
#define ProbeAndReadPoint(Address) \
|
|
(((Address) >= (POINT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile POINT * const)MM_USER_PROBE_ADDRESS) : (*(volatile POINT *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadRect(
|
|
// IN PRECT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeRect(Address) \
|
|
(((Address) >= (RECT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile DWORD * const)MM_USER_PROBE_ADDRESS) : (*(volatile DWORD *)(Address)))
|
|
|
|
#define ProbeAndReadRect(Address) \
|
|
(((Address) >= (RECT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile RECT * const)MM_USER_PROBE_ADDRESS) : (*(volatile RECT *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadMessage(
|
|
// IN PMSG Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeMessage(Address) \
|
|
(((Address) >= (MSG * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile DWORD * const)MM_USER_PROBE_ADDRESS) : (*(volatile DWORD *)(Address)))
|
|
|
|
#define ProbeAndReadMessage(Address) \
|
|
(((Address) >= (MSG * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile MSG * const)MM_USER_PROBE_ADDRESS) : (*(volatile MSG *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadLargeString(
|
|
// IN PLARGE_STRING Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadLargeString(Address) \
|
|
(((Address) >= (LARGE_STRING * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile LARGE_STRING * const)MM_USER_PROBE_ADDRESS) : (*(volatile LARGE_STRING *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadWindowPlacement(
|
|
// IN PWINDOWPLACEMENT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadWindowPlacement(Address) \
|
|
(((Address) >= (WINDOWPLACEMENT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile WINDOWPLACEMENT * const)MM_USER_PROBE_ADDRESS) : (*(volatile WINDOWPLACEMENT *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadMenuItem(
|
|
// IN PMENUITEMINFO Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadMenuItem(Address) \
|
|
(((Address) >= (MENUITEMINFO * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile MENUITEMINFO * const)MM_USER_PROBE_ADDRESS) : (*(volatile MENUITEMINFO *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadMenuInfo(
|
|
// IN PMENUINFO Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadMenuInfo(Address) \
|
|
(((Address) >= (MENUINFO * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile MENUINFO * const)MM_USER_PROBE_ADDRESS) : (*(volatile MENUINFO *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadScrollInfo(
|
|
// IN PSCROLLINFO Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadScrollInfo(Address) \
|
|
(((Address) >= (SCROLLINFO * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile SCROLLINFO * const)MM_USER_PROBE_ADDRESS) : (*(volatile SCROLLINFO *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadPopupParams(
|
|
// IN PTPMPARAMS Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadPopupParams(Address) \
|
|
(((Address) >= (TPMPARAMS * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile TPMPARAMS * const)MM_USER_PROBE_ADDRESS) : (*(volatile TPMPARAMS *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadPaintStruct(
|
|
// IN PPAINTSTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadPaintStruct(Address) \
|
|
(((Address) >= (PAINTSTRUCT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile PAINTSTRUCT * const)MM_USER_PROBE_ADDRESS) : (*(volatile PAINTSTRUCT *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadCreateStruct(
|
|
// IN PCREATESTRUCTW Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadCreateStruct(Address) \
|
|
(((Address) >= (CREATESTRUCTW * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile CREATESTRUCTW * const)MM_USER_PROBE_ADDRESS) : (*(volatile CREATESTRUCTW *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadMDICreateStruct(
|
|
// IN PMDICREATESTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadMDICreateStruct(Address) \
|
|
(((Address) >= (MDICREATESTRUCT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile MDICREATESTRUCT * const)MM_USER_PROBE_ADDRESS) : (*(volatile MDICREATESTRUCT *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadCopyDataStruct(
|
|
// IN PCOPYDATASTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadCopyDataStruct(Address) \
|
|
(((Address) >= (COPYDATASTRUCT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile COPYDATASTRUCT * const)MM_USER_PROBE_ADDRESS) : (*(volatile COPYDATASTRUCT *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadCompareItemStruct(
|
|
// IN PCOMPAREITEMSTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadCompareItemStruct(Address) \
|
|
(((Address) >= (COMPAREITEMSTRUCT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile COMPAREITEMSTRUCT * const)MM_USER_PROBE_ADDRESS) : (*(volatile COMPAREITEMSTRUCT *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadDeleteItemStruct(
|
|
// IN PDELETEITEMSTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadDeleteItemStruct(Address) \
|
|
(((Address) >= (DELETEITEMSTRUCT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile DELETEITEMSTRUCT * const)MM_USER_PROBE_ADDRESS) : (*(volatile DELETEITEMSTRUCT *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadHelp(
|
|
// IN PHLP Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadHelp(Address) \
|
|
(((Address) >= (HLP * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile HLP * const)MM_USER_PROBE_ADDRESS) : (*(volatile HLP *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadHelpInfo(
|
|
// IN PHELPINFO Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadHelpInfo(Address) \
|
|
(((Address) >= (HELPINFO * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile HELPINFO * const)MM_USER_PROBE_ADDRESS) : (*(volatile HELPINFO *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadDrawItemStruct(
|
|
// IN PDRAWITEMSTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadDrawItemStruct(Address) \
|
|
(((Address) >= (DRAWITEMSTRUCT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile DRAWITEMSTRUCT * const)MM_USER_PROBE_ADDRESS) : (*(volatile DRAWITEMSTRUCT *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadHookInfo(
|
|
// IN PDEBUGHOOKINFO Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadHookInfo(Address) \
|
|
(((Address) >= (DEBUGHOOKINFO * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile DEBUGHOOKINFO * const)MM_USER_PROBE_ADDRESS) : (*(volatile DEBUGHOOKINFO *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadCBTActivateStruct(
|
|
// IN PCBTACTIVATESTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadCBTActivateStruct(Address) \
|
|
(((Address) >= (CBTACTIVATESTRUCT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile CBTACTIVATESTRUCT * const)MM_USER_PROBE_ADDRESS) : (*(volatile CBTACTIVATESTRUCT *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadKbdHook(
|
|
// IN PKBDHOOKSTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadKbdHook(Address) \
|
|
(((Address) >= (KBDLLHOOKSTRUCT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile KBDLLHOOKSTRUCT * const)MM_USER_PROBE_ADDRESS) : (*(volatile KBDLLHOOKSTRUCT *)(Address)))
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadMsllHook(
|
|
// IN PMSLLHOOKSTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadMsllHook(Address) \
|
|
(((Address) >= (MSLLHOOKSTRUCT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile MSLLHOOKSTRUCT * const)MM_USER_PROBE_ADDRESS) : (*(volatile MSLLHOOKSTRUCT *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadMouseHook(
|
|
// IN PMOUSEHOOKSTRUCTEX Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadMouseHook(Address) \
|
|
(((Address) >= (MOUSEHOOKSTRUCTEX * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile MOUSEHOOKSTRUCTEX * const)MM_USER_PROBE_ADDRESS) : (*(volatile MOUSEHOOKSTRUCTEX *)(Address)))
|
|
|
|
|
|
#ifdef REDIRECTION
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadHTHook(
|
|
// IN PHTHOOKSTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadHTHook(Address) \
|
|
(((Address) >= (HTHOOKSTRUCT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile HTHOOKSTRUCT * const)MM_USER_PROBE_ADDRESS) : (*(volatile HTHOOKSTRUCT *)(Address)))
|
|
|
|
#endif // REDIRECTION
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadCBTCreateStruct(
|
|
// IN PCBT_CREATEWND Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadCBTCreateStruct(Address) \
|
|
(((Address) >= (CBT_CREATEWND * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile CBT_CREATEWND * const)MM_USER_PROBE_ADDRESS) : (*(volatile CBT_CREATEWND *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadTrackMouseEvent(
|
|
// IN LPTRACKMOUSEEVENT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadTrackMouseEvent(Address) \
|
|
(((Address) >= (TRACKMOUSEEVENT * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile TRACKMOUSEEVENT * const)MM_USER_PROBE_ADDRESS) : (*(volatile TRACKMOUSEEVENT *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadWindowPos(
|
|
// IN PWINDOWPOS Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadWindowPos(Address) \
|
|
(((Address) >= (WINDOWPOS * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile WINDOWPOS * const)MM_USER_PROBE_ADDRESS) : (*(volatile WINDOWPOS *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadCursorFind(
|
|
// IN PCURSORFIND Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadCursorFind(Address) \
|
|
(((Address) >= (CURSORFIND * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile CURSORFIND * const)MM_USER_PROBE_ADDRESS) : (*(volatile CURSORFIND *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadSetClipBData(
|
|
// IN PSETCLIPBDATA Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadSetClipBData(Address) \
|
|
(((Address) >= (SETCLIPBDATA * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile SETCLIPBDATA * const)MM_USER_PROBE_ADDRESS) : (*(volatile SETCLIPBDATA *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadBroadcastSystemMsgParams(
|
|
// IN LPBROADCASTSYSTEMMSGPARAMS Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadBroadcastSystemMsgParams(Address) \
|
|
(((Address) >= (BROADCASTSYSTEMMSGPARAMS * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile BROADCASTSYSTEMMSGPARAMS * const)MM_USER_PROBE_ADDRESS) : (*(volatile BROADCASTSYSTEMMSGPARAMS *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadCursorData(
|
|
// IN PCURSORDATA Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadCursorData(Address) \
|
|
(((Address) >= (CURSORDATA * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile CURSORDATA * const)MM_USER_PROBE_ADDRESS) : (*(volatile CURSORDATA *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeForReadUnicodeStringBuffer(
|
|
// IN UNICODE_STRING String
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#if defined(_X86_)
|
|
#define ProbeForReadUnicodeStringBuffer(String) \
|
|
if (((ULONG_PTR)((String).Buffer) & (sizeof(BYTE) - 1)) != 0) { \
|
|
ExRaiseDatatypeMisalignment(); \
|
|
} else if ((((ULONG_PTR)((String).Buffer) + ((String).Length) + sizeof(UNICODE_NULL)) < (ULONG_PTR)((String).Buffer)) || \
|
|
(((ULONG_PTR)((String).Buffer) + ((String).Length) + sizeof(UNICODE_NULL)) > (ULONG_PTR)MM_USER_PROBE_ADDRESS)) { \
|
|
ExRaiseAccessViolation(); \
|
|
} else if (((String).Length) > ((String).MaximumLength)) { \
|
|
ExRaiseAccessViolation(); \
|
|
}
|
|
#else
|
|
#define ProbeForReadUnicodeStringBuffer(String) \
|
|
if (((ULONG_PTR)((String).Buffer) & (sizeof(WCHAR) - 1)) != 0) { \
|
|
ExRaiseDatatypeMisalignment(); \
|
|
} else if ((((ULONG_PTR)((String).Buffer) + ((String).Length) + sizeof(UNICODE_NULL)) < (ULONG_PTR)((String).Buffer)) || \
|
|
(((ULONG_PTR)((String).Buffer) + ((String).Length) + sizeof(UNICODE_NULL)) > (ULONG_PTR)MM_USER_PROBE_ADDRESS)) { \
|
|
ExRaiseAccessViolation(); \
|
|
} else if (((String).Length) > ((String).MaximumLength)) { \
|
|
ExRaiseAccessViolation(); \
|
|
}
|
|
#endif
|
|
|
|
#if defined(_X86_)
|
|
#define ProbeForReadUnicodeStringFullBuffer(String) \
|
|
if (((ULONG_PTR)((String).Buffer) & (sizeof(BYTE) - 1)) != 0) { \
|
|
ExRaiseDatatypeMisalignment(); \
|
|
} else if ((((ULONG_PTR)((String).Buffer) + ((String).MaximumLength)) < (ULONG_PTR)((String).Buffer)) || \
|
|
(((ULONG_PTR)((String).Buffer) + ((String).MaximumLength)) > (ULONG_PTR)MM_USER_PROBE_ADDRESS)) { \
|
|
ExRaiseAccessViolation(); \
|
|
} else if (((String).Length) > ((String).MaximumLength)) { \
|
|
ExRaiseAccessViolation(); \
|
|
}
|
|
#else
|
|
#define ProbeForReadUnicodeStringFullBuffer(String) \
|
|
if (((ULONG_PTR)((String).Buffer) & (sizeof(WCHAR) - 1)) != 0) { \
|
|
ExRaiseDatatypeMisalignment(); \
|
|
} else if ((((ULONG_PTR)((String).Buffer) + ((String).MaximumLength)) < (ULONG_PTR)((String).Buffer)) || \
|
|
(((ULONG_PTR)((String).Buffer) + ((String).MaximumLength)) > (ULONG_PTR)MM_USER_PROBE_ADDRESS)) { \
|
|
ExRaiseAccessViolation(); \
|
|
} else if (((String).Length) > ((String).MaximumLength)) { \
|
|
ExRaiseAccessViolation(); \
|
|
}
|
|
#endif
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeForReadUnicodeStringBufferOrId(
|
|
// IN UNICODE_STRING String
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForReadUnicodeStringBufferOrId(String) \
|
|
if (IS_PTR((String).Buffer)) { \
|
|
ProbeForReadUnicodeStringBuffer(String); \
|
|
}
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadCandidateForm(
|
|
// IN PCANDIDATEFORM Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadCandidateForm(Address) \
|
|
(((Address) >= (CANDIDATEFORM * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile CANDIDATEFORM * const)MM_USER_PROBE_ADDRESS) : (*(volatile CANDIDATEFORM *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadCompositionForm(
|
|
// IN PCANDIDATEFORM Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadCompositionForm(Address) \
|
|
(((Address) >= (COMPOSITIONFORM * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile COMPOSITIONFORM * const)MM_USER_PROBE_ADDRESS) : (*(volatile COMPOSITIONFORM *)(Address)))
|
|
|
|
//++
|
|
//
|
|
// BOOLEAN
|
|
// ProbeAndReadLogFontW(
|
|
// IN PLOGFONTA Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadLogFontW(Address) \
|
|
(((Address) >= (LOGFONTW * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile LOGFONTW * const)MM_USER_PROBE_ADDRESS) : (*(volatile LOGFONTW *)(Address)))
|
|
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWritePoint(
|
|
// IN PPOINT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWritePoint(Address) { \
|
|
if ((Address) >= (POINT * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile POINT *)(Address) = *(volatile POINT *)(Address); \
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteRect(
|
|
// IN PRECT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteRect(Address) { \
|
|
if ((Address) >= (RECT * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile RECT *)(Address) = *(volatile RECT *)(Address); \
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteMessage(
|
|
// IN PMSG Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteMessage(Address) { \
|
|
if ((Address) >= (MSG * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile MSG *)(Address) = *(volatile MSG *)(Address); \
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWritePaintStruct(
|
|
// IN PPAINTSTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWritePaintStruct(Address) { \
|
|
if ((Address) >= (PAINTSTRUCT * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile PAINTSTRUCT *)(Address) = *(volatile PAINTSTRUCT *)(Address); \
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteDropStruct(
|
|
// IN PDROPSTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteDropStruct(Address) { \
|
|
if ((Address) >= (DROPSTRUCT * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile DROPSTRUCT *)(Address) = *(volatile DROPSTRUCT *)(Address); \
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteScrollInfo(
|
|
// IN PSCROLLINFO Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteScrollInfo(Address) { \
|
|
if ((Address) >= (SCROLLINFO * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile SCROLLINFO *)(Address) = *(volatile SCROLLINFO *)(Address); \
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteStyleStruct(
|
|
// IN PSTYLESTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteStyleStruct(Address) { \
|
|
if ((Address) >= (STYLESTRUCT * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile STYLESTRUCT *)(Address) = *(volatile STYLESTRUCT *)(Address); \
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteMeasureItemStruct(
|
|
// IN PMEASUREITEMSTRUCT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteMeasureItemStruct(Address) { \
|
|
if ((Address) >= (MEASUREITEMSTRUCT * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile MEASUREITEMSTRUCT *)(Address) = *(volatile MEASUREITEMSTRUCT *)(Address);\
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteCreateStruct(
|
|
// IN PCREATESTRUCTW Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteCreateStruct(Address) { \
|
|
if ((Address) >= (CREATESTRUCTW * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile CREATESTRUCTW *)(Address) = *(volatile CREATESTRUCTW *)(Address);\
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteEvent(
|
|
// IN PEVENTMSGMSG Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteEvent(Address) { \
|
|
if ((Address) >= (EVENTMSG * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile EVENTMSG *)(Address) = *(volatile EVENTMSG *)(Address); \
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteWindowPlacement(
|
|
// IN PWINDOWPLACEMENT Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteWindowPlacement(Address) { \
|
|
if ((Address) >= (WINDOWPLACEMENT * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile WINDOWPLACEMENT *)(Address) = *(volatile WINDOWPLACEMENT *)(Address);\
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteGetClipData(
|
|
// IN PGETCLIPBDATA Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteGetClipData(Address) { \
|
|
if ((Address) >= (GETCLIPBDATA * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile GETCLIPBDATA *)(Address) = *(volatile GETCLIPBDATA *)(Address);\
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOUD
|
|
// ProbeForWriteBroadcastSystemMsgParams(
|
|
// IN LPBROADCASTSYSTEMMSGPARAMS Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteBroadcastSystemMsgParams(Address) { \
|
|
if ((Address) >= (BROADCASTSYSTEMMSGPARAMS * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile BROADCASTSYSTEMMSGPARAMS *)(Address) = *(volatile BROADCASTSYSTEMMSGPARAMS *)(Address); \
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteMDINextMenu(
|
|
// IN PMDINEXTMENU Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteMDINextMenu(Address) { \
|
|
if ((Address) >= (MDINEXTMENU * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile MDINEXTMENU *)(Address) = *(volatile MDINEXTMENU *)(Address); \
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWritePoint5(
|
|
// IN PPOINT5 Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWritePoint5(Address) { \
|
|
if ((Address) >= (POINT5 * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile POINT5 *)(Address) = *(volatile POINT5 *)(Address);\
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteNCCalcSize(
|
|
// IN PNCCALCSIZE_PARAMS Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteNCCalcSize(Address) { \
|
|
if ((Address) >= (NCCALCSIZE_PARAMS * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile NCCALCSIZE_PARAMS *)(Address) = *(volatile NCCALCSIZE_PARAMS *)(Address);\
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteWindowPos(
|
|
// IN PWINDOWPOS Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteWindowPos(Address) { \
|
|
if ((Address) >= (WINDOWPOS * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile WINDOWPOS *)(Address) = *(volatile WINDOWPOS *)(Address);\
|
|
}
|
|
|
|
#define ProbeForWriteComboBoxInfo(Address) { \
|
|
if ((Address) >= (COMBOBOXINFO * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile COMBOBOXINFO *)(Address) = *(volatile COMBOBOXINFO *)(Address); \
|
|
}
|
|
|
|
#define ProbeForWriteScrollBarInfo(Address) { \
|
|
if ((Address) >= (SCROLLBARINFO * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile SCROLLBARINFO *)(Address) = *(volatile SCROLLBARINFO *)(Address); \
|
|
}
|
|
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteCandidateForm(
|
|
// IN PCANDIDATEFORM Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteCandidateForm(Address) { \
|
|
if ((Address) >= (CANDIDATEFORM * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile CANDIDATEFORM *)(Address) = *(volatile CANDIDATEFORM *)(Address); \
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteCompositionForm(
|
|
// IN PCOMPOSITIONFORM Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteCompositionForm(Address) { \
|
|
if ((Address) >= (COMPOSITIONFORM * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile COMPOSITIONFORM *)(Address) = *(volatile COMPOSITIONFORM *)(Address);\
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteLogFontW(
|
|
// IN PLOGFONTW Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteLogFontW(Address) { \
|
|
if ((Address) >= (LOGFONTW * const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG * const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile LOGFONTW *)(Address) = *(volatile LOGFONTW *)(Address); \
|
|
}
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteReconvertString(IN PRECONVERTSTRING Address)
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteReconvertString(Address) { \
|
|
if ((Address) >= (RECONVERTSTRING* const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG* const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile RECONVERTSTRING*)(Address) = *(volatile RECONVERTSTRING*)(Address); \
|
|
*((volatile BYTE*)(Address) + (Address)->dwSize) = *((volatile BYTE*)(Address) + (Address)->dwSize); \
|
|
}
|
|
|
|
#define ProbeForReadReconvertString(pReconv) \
|
|
ProbeForRead((pReconv), (pReconv)->dwSize, 1)
|
|
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeForWriteImeCharPosition(IN LPPrivateIMECHARPOSITION Address)
|
|
//
|
|
//--
|
|
|
|
#define ProbeForWriteImeCharPosition(Address) { \
|
|
if ((Address) >= (PrivateIMECHARPOSITION* const)MM_USER_PROBE_ADDRESS) { \
|
|
*(volatile ULONG* const)MM_USER_PROBE_ADDRESS = 0; \
|
|
} \
|
|
\
|
|
*(volatile PrivateIMECHARPOSITION*)(Address) = *(volatile PrivateIMECHARPOSITION*)(Address); \
|
|
}
|
|
|
|
|
|
|
|
//++
|
|
//
|
|
// VOID
|
|
// ProbeAndReadMenuGetObjectInfo(
|
|
// IN PMENUGETOBJECTINFO Address
|
|
// )
|
|
//
|
|
//--
|
|
|
|
#define ProbeAndReadMenuGetObjectInfo(Address) \
|
|
(((Address) >= (MENUGETOBJECTINFO * const)MM_USER_PROBE_ADDRESS) ? \
|
|
(*(volatile MENUGETOBJECTINFO * const)MM_USER_PROBE_ADDRESS) : (*(volatile MENUGETOBJECTINFO *)(Address)))
|
|
|
|
|
|
/*
|
|
* This macro makes sure an object is thread locked. DEBUG only.
|
|
*/
|
|
#if DBG
|
|
VOID CheckLock(PVOID pobj);
|
|
#else // DBG
|
|
#define CheckLock(p)
|
|
#endif // DBG
|
|
|
|
/*
|
|
* Debug macros
|
|
*/
|
|
#if DBG
|
|
|
|
#define TRACE_INIT(str) { if (TraceInitialization > 0) { KdPrint(str); }}
|
|
#define TRACE_SWITCH(str) { if (TraceFullscreenSwitch > 0) { KdPrint(str); }}
|
|
|
|
extern PCSZ apszSimpleCallNames[];
|
|
|
|
#define TRACE(s) TAGMSG2(DBGTAG_StubReturn, "%s, retval = %x", (s), retval)
|
|
#define TRACEVOID(s) TAGMSG1(DBGTAG_StubReturn, "%s", (s))
|
|
|
|
#define TRACETHUNK(t) \
|
|
TAGMSG3(DBGTAG_StubThunk, \
|
|
"Thunk %s, %s(%s)", \
|
|
(t), \
|
|
(xpfnProc >= FNID_START && xpfnProc <= FNID_END ? \
|
|
gapszFNID[xpfnProc - FNID_START] : "Unknown"), \
|
|
(msg >= WM_USER ? "WM_USER" : gapszMessage[msg]))
|
|
|
|
#define TRACECALLBACK(s) TAGMSG2(DBGTAG_StubCallback, "%s, retval = %x", (s), retval)
|
|
|
|
#define TRACECALLBACKMSG(s) \
|
|
TAGMSG4(DBGTAG_StubCallback, \
|
|
"Callback %s, %s(%s), retval = %x", \
|
|
(s), \
|
|
(xpfnProc >= (PROC)FNID_START && xpfnProc <= (PROC)FNID_END ? \
|
|
gapszFNID[(ULONG_PTR)xpfnProc - FNID_START] : "Unknown"), \
|
|
(msg >= WM_USER ? "WM_USER" : gapszMessage[msg]), \
|
|
retval)
|
|
#else // DBG
|
|
|
|
#define TRACE_INIT(str) {}
|
|
#define TRACE_SWITCH(str) {}
|
|
#define TRACE(s)
|
|
#define TRACEVOID(s)
|
|
#define TRACETHUNK(t)
|
|
#define TRACECALLBACK(t)
|
|
#define TRACECALLBACKMSG(t)
|
|
|
|
#endif // DBG
|
|
|
|
/*
|
|
* Statistics for performance counter
|
|
*/
|
|
|
|
typedef struct tagPERFINFO {
|
|
LONG lCount;
|
|
LONG lMaxCount;
|
|
LONG lTotalCount;
|
|
SIZE_T lSize;
|
|
} PERFHANDLEINFO, *PPERFHANDLEINFO;
|
|
|
|
typedef struct _HANDLEPAGE {
|
|
ULONG_PTR iheLimit; /* first handle index past the end of the page */
|
|
ULONG_PTR iheFreeEven; /* first even free handle in the page -- window objects */
|
|
ULONG_PTR iheFreeOdd; /* first even odd handle in the page */
|
|
} HANDLEPAGE, *PHANDLEPAGE;
|
|
|
|
|
|
#if DBG || FRE_LOCK_RECORD
|
|
VOID HMCleanUpHandleTable(VOID);
|
|
DWORD DbgDumpHandleTable(VOID);
|
|
#endif
|
|
|
|
BOOL HMInitHandleTable(PVOID pBase);
|
|
PVOID HMAllocObject(PTHREADINFO pti, PDESKTOP pdesk, BYTE btype, DWORD size);
|
|
BOOL HMFreeObject(PVOID pobj);
|
|
BOOL HMMarkObjectDestroy(PVOID pobj);
|
|
BOOL HMDestroyObject(PVOID pobj);
|
|
PVOID FASTCALL HMAssignmentLock(PVOID *ppobj, PVOID pobj);
|
|
PVOID FASTCALL HMAssignmentUnlock(PVOID *ppobj);
|
|
void HMDestroyUnlockedObject(PHE phe);
|
|
|
|
void HMCleanupGrantedHandle(HANDLE h);
|
|
|
|
/*
|
|
* Validation, handle mapping, etc.
|
|
*/
|
|
#define RevalidateHwnd(hwnd) HMValidateHandleNoSecure(hwnd, TYPE_WINDOW)
|
|
#define RevalidateCatHwnd(hwnd) HMValidateCatHandleNoSecure(hwnd, TYPE_WINDOW)
|
|
|
|
#define HtoPq(h) ((PVOID)HMObjectFromHandle(h))
|
|
#define HtoPqCat(h) ((PVOID)HMCatObjectFromHandle(h))
|
|
#define HtoP(h) ((PVOID)HMObjectFromHandle(h))
|
|
#define HtoPCat(h) ((PVOID)HMCatObjectFromHandle(h))
|
|
#define PW(hwnd) ((PWND)HtoP(hwnd))
|
|
#define PWCat(hwnd) ((PWND)HtoPCat(hwnd))
|
|
#define TID(pti) HandleToUlong((pti) == NULL ? NULL : (PsGetThreadId((pti)->pEThread)))
|
|
#define TIDq(pti) HandleToUlong(PsGetThreadId((pti)->pEThread))
|
|
|
|
/*
|
|
* Assignment lock macro -> used for locking objects embedded in structures
|
|
* and globals. Threadlocks used for locking objects across callbacks.
|
|
*/
|
|
#define Lock(ppobj, pobj) HMAssignmentLock((PVOID *)ppobj, (PVOID)pobj)
|
|
#define Unlock(ppobj) HMAssignmentUnlock((PVOID *)ppobj)
|
|
|
|
PVOID HMUnlockObjectInternal(PVOID pobj);
|
|
|
|
#define HMUnlockObject(pobj) \
|
|
( (--((PHEAD)pobj)->cLockObj == 0) ? HMUnlockObjectInternal(pobj) : pobj )
|
|
|
|
VOID HMChangeOwnerThread(PVOID pobj, PTHREADINFO pti);
|
|
VOID HMChangeOwnerPheProcess(PHE phe, PTHREADINFO pti);
|
|
#define HMChangeOwnerProcess(pobj, pti) HMChangeOwnerPheProcess(HMPheFromObject(pobj), pti)
|
|
|
|
#if DBG
|
|
VOID HMLockObject(PVOID pobj);
|
|
BOOL HMRelocateLockRecord(PVOID ppobjOld, LONG_PTR cbDelta);
|
|
#else // DBG
|
|
#define HMLockObject(p) (((PHEAD)p)->cLockObj++)
|
|
#endif // DBG
|
|
|
|
#if DBG
|
|
VOID ThreadLock(PVOID pobj, PTL ptl);
|
|
#else // DBG
|
|
#define ThreadLock(_pobj_, _ptl_) \
|
|
{ \
|
|
PTHREADINFO _pti_; \
|
|
PVOID __pobj_ = (_pobj_); \
|
|
\
|
|
_pti_ = PtiCurrent(); \
|
|
(_ptl_)->next = _pti_->ptl; \
|
|
_pti_->ptl = (_ptl_); \
|
|
(_ptl_)->pobj = __pobj_; \
|
|
if (__pobj_ != NULL) { \
|
|
HMLockObject(__pobj_); \
|
|
} \
|
|
}
|
|
#endif // DBG
|
|
|
|
#if DBG
|
|
#define ThreadLockAlways(_pobj_, _ptl_) \
|
|
{ \
|
|
PVOID __pobj_ = (_pobj_); \
|
|
UserAssert(__pobj_ != NULL); \
|
|
ThreadLock(__pobj_, _ptl_); \
|
|
}
|
|
#else // DBG
|
|
#define ThreadLockAlways(_pobj_, _ptl_) \
|
|
{ \
|
|
PTHREADINFO _pti_; \
|
|
PVOID __pobj_ = (_pobj_); \
|
|
\
|
|
_pti_ = PtiCurrent(); \
|
|
(_ptl_)->next = _pti_->ptl; \
|
|
_pti_->ptl = (_ptl_); \
|
|
(_ptl_)->pobj = __pobj_; \
|
|
HMLockObject(__pobj_); \
|
|
}
|
|
#endif // DBG
|
|
|
|
#if DBG
|
|
#define ThreadLockNever(_ptl_) \
|
|
{ \
|
|
ThreadLock(NULL, _ptl_); \
|
|
}
|
|
#else // DBG
|
|
#define ThreadLockNever(_ptl_) \
|
|
{ \
|
|
PTHREADINFO _pti_; \
|
|
\
|
|
_pti_ = PtiCurrent(); \
|
|
(_ptl_)->next = _pti_->ptl; \
|
|
_pti_->ptl = (_ptl_); \
|
|
(_ptl_)->pobj = NULL; \
|
|
}
|
|
#endif // DBG
|
|
|
|
#if DBG
|
|
#define ThreadLockAlwaysWithPti(_pti_, _pobj_, _ptl_) \
|
|
{ \
|
|
PVOID __pobj_ = (_pobj_); \
|
|
UserAssert(_pti_ == PtiCurrentShared()); \
|
|
UserAssert(__pobj_ != NULL); \
|
|
ThreadLock(__pobj_, _ptl_); \
|
|
}
|
|
#else // DBG
|
|
#define ThreadLockAlwaysWithPti(_pti_, _pobj_, _ptl_) \
|
|
{ \
|
|
PVOID __pobj_ = (_pobj_); \
|
|
(_ptl_)->next = _pti_->ptl; \
|
|
_pti_->ptl = (_ptl_); \
|
|
(_ptl_)->pobj = __pobj_; \
|
|
HMLockObject(__pobj_); \
|
|
}
|
|
#endif // DBG
|
|
|
|
#if DBG
|
|
#define ThreadLockNeverWithPti(_pti_, _ptl_) \
|
|
{ \
|
|
UserAssert(_pti_ == PtiCurrentShared()); \
|
|
ThreadLock(NULL, _ptl_); \
|
|
}
|
|
#else // DBG
|
|
#define ThreadLockNeverWithPti(_pti_, _ptl_) \
|
|
{ \
|
|
(_ptl_)->next = _pti_->ptl; \
|
|
_pti_->ptl = (_ptl_); \
|
|
(_ptl_)->pobj = NULL; \
|
|
}
|
|
#endif // DBG
|
|
|
|
#if DBG
|
|
#define ThreadLockWithPti(_pti_, _pobj_, _ptl_) \
|
|
{ \
|
|
PVOID __pobj_ = (_pobj_); \
|
|
UserAssert(_pti_ == PtiCurrentShared()); \
|
|
ThreadLock(__pobj_, _ptl_); \
|
|
}
|
|
#else // DBG
|
|
#define ThreadLockWithPti(_pti_, _pobj_, _ptl_) \
|
|
{ \
|
|
PVOID __pobj_ = (_pobj_); \
|
|
(_ptl_)->next = _pti_->ptl; \
|
|
_pti_->ptl = (_ptl_); \
|
|
(_ptl_)->pobj = __pobj_; \
|
|
if (__pobj_ != NULL) { \
|
|
HMLockObject(__pobj_); \
|
|
} \
|
|
}
|
|
#endif // DBG
|
|
|
|
#if DBG
|
|
PVOID ThreadLockExchange(PVOID pobj, PTL ptl);
|
|
#else // DBG
|
|
__inline PVOID ThreadLockExchange(PVOID pobj, PTL ptl)
|
|
{
|
|
PVOID pobjOld;
|
|
|
|
pobjOld = ptl->pobj;
|
|
ptl->pobj = pobj;
|
|
if (pobj) {
|
|
HMLockObject(pobj);
|
|
}
|
|
|
|
if (pobjOld) {
|
|
pobjOld = HMUnlockObject((PHEAD)pobjOld);
|
|
}
|
|
|
|
return pobjOld;
|
|
}
|
|
#endif // DBG
|
|
|
|
#if DBG
|
|
#define ThreadLockExchangeAlways(_pobj_, _ptl_) \
|
|
{ \
|
|
PVOID __pobj_ = (_pobj_); \
|
|
UserAssert(__pobj_ != NULL); \
|
|
ThreadLockExchange(__pobj_, _ptl_); \
|
|
}
|
|
#else // DBG
|
|
__inline PVOID ThreadLockExchangeAlways(PVOID pobj, PTL ptl)
|
|
{
|
|
PVOID pobjOld;
|
|
|
|
pobjOld = ptl->pobj;
|
|
ptl->pobj = pobj;
|
|
HMLockObject(pobj);
|
|
if (pobjOld) {
|
|
pobjOld = HMUnlockObject((PHEAD)pobjOld);
|
|
}
|
|
|
|
return pobjOld;
|
|
}
|
|
#endif // DBG
|
|
|
|
#if DBG
|
|
PVOID ThreadUnlock1(PTL ptl);
|
|
#define ThreadUnlock(ptl) ThreadUnlock1(ptl)
|
|
#else // DBG
|
|
PVOID ThreadUnlock1(VOID);
|
|
#define ThreadUnlock(ptl) ThreadUnlock1()
|
|
#endif // DBG
|
|
|
|
/*
|
|
* Define this only if you want to track down lock/unlock mismatches
|
|
* for desktop objects.
|
|
*/
|
|
#ifdef LOGDESKTOPLOCKS
|
|
|
|
/*
|
|
* This is the structure used by the desktop logging stuff.
|
|
*/
|
|
typedef struct tagLogD {
|
|
WORD tag; // tag
|
|
WORD type; // lock | unlock
|
|
ULONG_PTR extra; // extra information to identify the lock/unlock
|
|
PVOID trace[6]; // stack trace
|
|
} LogD, *PLogD;
|
|
|
|
/*
|
|
* Tags for LOCK/UNLOCK REFERENCE/DEREFERENCE calls for desktop objects.
|
|
*/
|
|
|
|
#define LDU_CLS_DESKPARENT1 1
|
|
#define LDL_CLS_DESKPARENT1 2
|
|
|
|
#define LDU_CLS_DESKPARENT2 3
|
|
#define LDL_CLS_DESKPARENT2 5
|
|
|
|
#define LDU_FN_DESTROYCLASS 6
|
|
#define LDL_FN_DESTROYCLASS 7
|
|
|
|
#define LDU_FN_DESTROYMENU 8
|
|
#define LDL_FN_DESTROYMENU 9
|
|
|
|
#define LDU_FN_DESTROYTHREADINFO 10
|
|
#define LDL_FN_DESTROYTHREADINFO 11
|
|
|
|
#define LDU_FN_DESTROYWINDOWSTATION 12
|
|
#define LDL_FN_DESTROYWINDOWSTATION 13
|
|
|
|
#define LDU_DESKDISCONNECT 14
|
|
#define LDL_DESKDISCONNECT 15
|
|
|
|
#define LDU_DESK_DESKNEXT 16
|
|
#define LDL_DESK_DESKNEXT1 17
|
|
|
|
#define LDU_OBJ_DESK 18
|
|
#define LDL_OBJ_DESK 19
|
|
#define LDL_MOTHERDESK_DESK1 20
|
|
|
|
#define LDL_PTI_DESK 21
|
|
#define LDL_DT_DESK 23
|
|
|
|
#define LDU_PTI_DESK 24
|
|
|
|
#define LDU_PPI_DESKSTARTUP1 26
|
|
#define LDU_PPI_DESKSTARTUP2 27
|
|
#define LDU_PPI_DESKSTARTUP3 28
|
|
#define LDL_PPI_DESKSTARTUP1 29
|
|
#define LDL_PPI_DESKSTARTUP2 30
|
|
|
|
#define LDU_DESKLOGON 31
|
|
#define LDL_DESKLOGON 32
|
|
|
|
#define LDUT_FN_FREEWINDOW 33
|
|
#define LDLT_FN_FREEWINDOW 34
|
|
|
|
#define LDUT_FN_DESKTOPTHREAD_DESK 35
|
|
#define LDLT_FN_DESKTOPTHREAD_DESK 36
|
|
|
|
#define LDUT_FN_DESKTOPTHREAD_DESKTEMP 37
|
|
#define LDLT_FN_DESKTOPTHREAD_DESKTEMP 38
|
|
|
|
#define LDUT_FN_SETDESKTOP 39
|
|
#define LDLT_FN_SETDESKTOP 40
|
|
|
|
#define LDUT_FN_NTUSERSWITCHDESKTOP 41
|
|
#define LDLT_FN_NTUSERSWITCHDESKTOP 42
|
|
|
|
#define LDUT_FN_SENDMESSAGEBSM1 43
|
|
#define LDUT_FN_SENDMESSAGEBSM2 44
|
|
#define LDLT_FN_SENDMESSAGEBSM 45
|
|
|
|
#define LDUT_FN_SYSTEMBROADCASTMESSAGE 46
|
|
#define LDLT_FN_SYSTEMBROADCASTMESSAGE 47
|
|
|
|
#define LDUT_FN_CTXREDRAWSCREEN 48
|
|
#define LDLT_FN_CTXREDRAWSCREEN 49
|
|
|
|
#define LDUT_FN_CTXDISABLESCREEN 50
|
|
#define LDLT_FN_CTXDISABLESCREEN 51
|
|
|
|
#define LD_DEREF_FN_CREATEDESKTOP1 52
|
|
#define LD_DEREF_FN_CREATEDESKTOP2 53
|
|
#define LD_DEREF_FN_CREATEDESKTOP3 54
|
|
#define LD_REF_FN_CREATEDESKTOP 55
|
|
|
|
#define LD_DEREF_FN_OPENDESKTOP 56
|
|
#define LD_REF_FN_OPENDESKTOP 57
|
|
|
|
#define LD_DEREF_FN_SETDESKTOP 58
|
|
#define LD_REF_FN_SETDESKTOP 59
|
|
|
|
#define LD_DEREF_FN_GETTHREADDESKTOP 60
|
|
#define LD_REF_FN_GETTHREADDESKTOP 61
|
|
|
|
#define LD_DEREF_FN_CLOSEDESKTOP1 62
|
|
#define LD_DEREF_FN_CLOSEDESKTOP2 63
|
|
#define LD_REF_FN_CLOSEDESKTOP 64
|
|
|
|
#define LD_DEREF_FN_RESOLVEDESKTOP 65
|
|
#define LD_REF_FN_RESOLVEDESKTOP 66
|
|
|
|
#define LD_DEREF_VALIDATE_HDESK1 67
|
|
#define LD_DEREF_VALIDATE_HDESK2 68
|
|
#define LD_DEREF_VALIDATE_HDESK3 69
|
|
#define LD_DEREF_VALIDATE_HDESK4 70
|
|
#define LDL_VALIDATE_HDESK 71
|
|
|
|
#define LDUT_FN_CREATETHREADINFO1 72
|
|
#define LDUT_FN_CREATETHREADINFO2 73
|
|
#define LDLT_FN_CREATETHREADINFO 74
|
|
|
|
#define LD_DEREF_FN_SETCSRSSTHREADDESKTOP1 75
|
|
#define LD_DEREF_FN_SETCSRSSTHREADDESKTOP2 76
|
|
#define LD_REF_FN_SETCSRSSTHREADDESKTOP 77
|
|
|
|
#define LD_DEREF_FN_CONSOLECONTROL1 78
|
|
#define LD_REF_FN_CONSOLECONTROL1 79
|
|
|
|
#define LD_DEREF_FN_CONSOLECONTROL2 80
|
|
#define LD_REF_FN_CONSOLECONTROL2 81
|
|
|
|
#define LD_DEREF_FN_GETUSEROBJECTINFORMATION 82
|
|
#define LD_REF_FN_GETUSEROBJECTINFORMATION 83
|
|
|
|
#define LD_DEREF_FN_SETUSEROBJECTINFORMATION 84
|
|
#define LD_REF_FN_SETUSEROBJECTINFORMATION 85
|
|
|
|
#define LD_DEREF_FN_CREATEWINDOWSTATION 86
|
|
#define LD_REF_FN_CREATEWINDOWSTATION 87
|
|
|
|
#define LDL_TERM_DESKDESTROY1 88
|
|
#define LDL_TERM_DESKDESTROY2 89
|
|
|
|
#define LDL_MOTHERDESK_DESK2 92
|
|
|
|
#define LDL_WINSTA_DESKLIST2 93
|
|
#define LDL_WINSTA_DESKLIST1 94
|
|
|
|
#define LDL_DESKRITINPUT 95
|
|
#define LDU_DESKRITINPUT 96
|
|
|
|
#define LD_DEREF_FN_2CREATEDESKTOP 97
|
|
|
|
#define LDL_DESK_DESKNEXT2 98
|
|
|
|
#define LDL_DESKSHOULDBEFOREGROUND1 99
|
|
#define LDL_DESKSHOULDBEFOREGROUND2 100
|
|
#define LDL_DESKSHOULDBEFOREGROUND3 101
|
|
|
|
#define LDL_HOOK_DESK 102
|
|
#define LDU_HOOK_DESK 103
|
|
|
|
#define LDU_DESKSHOULDBEFOREGROUND 105
|
|
|
|
#define LDU_MOTHERDESK_DESK 106
|
|
|
|
void LogDesktop(PDESKTOP pdesk, DWORD tag, BOOL bLock, ULONG_PTR extra);
|
|
|
|
#else
|
|
#define LogDesktop(pdesk, tag, bLock, extra)
|
|
#endif // LOGDESKTOPLOCKS
|
|
|
|
/*
|
|
* Routines for referencing and assigning kernel objects.
|
|
*/
|
|
#ifdef LOGDESKTOPLOCKS
|
|
VOID LockObjectAssignment(PVOID*, PVOID, DWORD, ULONG_PTR);
|
|
VOID UnlockObjectAssignment(PVOID*, DWORD, ULONG_PTR);
|
|
#else
|
|
VOID LockObjectAssignment(PVOID*, PVOID);
|
|
VOID UnlockObjectAssignment(PVOID*);
|
|
#endif
|
|
|
|
VOID UserDereferenceObject(PVOID pobj);
|
|
|
|
#define ThreadLockObject(pobj, ptl) \
|
|
{ \
|
|
UserAssert(!(PpiCurrent()->W32PF_Flags & W32PF_TERMINATED)); \
|
|
UserAssert(pobj == NULL || OBJECT_TO_OBJECT_HEADER(pobj)->PointerCount != 0); \
|
|
PushW32ThreadLock(pobj, ptl, UserDereferenceObject); \
|
|
if (pobj != NULL) { \
|
|
ObReferenceObject(pobj); \
|
|
} \
|
|
}
|
|
|
|
#define ThreadLockExchangeObject(pobj, ptl) \
|
|
{ \
|
|
UserAssert(!(PpiCurrent()->W32PF_Flags & W32PF_TERMINATED)); \
|
|
UserAssert(pobj == NULL || OBJECT_TO_OBJECT_HEADER(pobj)->PointerCount != 0); \
|
|
if (pobj != NULL) { \
|
|
ObReferenceObject(pobj); \
|
|
} \
|
|
ExchangeW32ThreadLock(pobj, ptl); \
|
|
}
|
|
|
|
#define ThreadUnlockObject(ptl) \
|
|
{ \
|
|
PopAndFreeW32ThreadLock(ptl); \
|
|
} \
|
|
|
|
#ifdef LOGDESKTOPLOCKS
|
|
|
|
#define UnlockWinSta(ppwinsta) \
|
|
UnlockObjectAssignment(ppwinsta, 0, 0)
|
|
|
|
#define LockWinSta(ppwinsta, pwinsta) \
|
|
{ \
|
|
if (pwinsta != NULL) \
|
|
{ \
|
|
UserAssert(OBJECT_TO_OBJECT_HEADER(pwinsta)->Type == *ExWindowStationObjectType); \
|
|
} \
|
|
LockObjectAssignment(ppwinsta, pwinsta, 0, 0); \
|
|
}
|
|
|
|
#define LockDesktop(ppdesk, pdesk, tag, extra) \
|
|
{ \
|
|
if (pdesk != NULL) \
|
|
{ \
|
|
UserAssert(OBJECT_TO_OBJECT_HEADER(pdesk)->Type == *ExDesktopObjectType); \
|
|
} \
|
|
LockObjectAssignment(ppdesk, pdesk, tag, extra); \
|
|
}
|
|
|
|
#define UnlockDesktop(ppdesk, tag, extra) \
|
|
UnlockObjectAssignment(ppdesk, tag, extra)
|
|
|
|
#define ThreadLockDesktop(pti, pdesk, ptl, tag) \
|
|
{ \
|
|
UserAssert(pdesk == NULL || OBJECT_TO_OBJECT_HEADER(pdesk)->Type == *ExDesktopObjectType);\
|
|
ThreadLockObject(pdesk, ptl); \
|
|
LogDesktop(pdesk, tag, TRUE, (ULONG_PTR)PtiCurrent()); \
|
|
}
|
|
|
|
#define ThreadLockExchangeDesktop(pti, pdesk, ptl, tag) \
|
|
{ \
|
|
UserAssert(pdesk == NULL || OBJECT_TO_OBJECT_HEADER(pdesk)->Type == *ExDesktopObjectType);\
|
|
ThreadLockExchangeObject(pdesk, ptl); \
|
|
LogDesktop(pdesk, tag, TRUE, (ULONG_PTR)PtiCurrent()); \
|
|
}
|
|
|
|
#define ThreadUnlockDesktop(pti, ptl, tag) \
|
|
{ \
|
|
LogDesktop((PDESKTOP)(((PTL)ptl)->pobj), tag, FALSE, (ULONG_PTR)PtiCurrent()); \
|
|
ThreadUnlockObject(ptl); \
|
|
}
|
|
|
|
#else
|
|
|
|
#define UnlockWinSta(ppwinsta) \
|
|
UnlockObjectAssignment(ppwinsta)
|
|
|
|
#define LockWinSta(ppwinsta, pwinsta) \
|
|
{ \
|
|
if (pwinsta != NULL) \
|
|
{ \
|
|
UserAssert(OBJECT_TO_OBJECT_HEADER(pwinsta)->Type == *ExWindowStationObjectType); \
|
|
} \
|
|
LockObjectAssignment(ppwinsta, pwinsta); \
|
|
}
|
|
|
|
#define LockDesktop(ppdesk, pdesk, tag, extra) \
|
|
{ \
|
|
if (pdesk != NULL) \
|
|
{ \
|
|
UserAssert(OBJECT_TO_OBJECT_HEADER(pdesk)->Type == *ExDesktopObjectType); \
|
|
} \
|
|
LockObjectAssignment(ppdesk, pdesk); \
|
|
}
|
|
|
|
#define UnlockDesktop(ppdesk, tag, extra) \
|
|
UnlockObjectAssignment(ppdesk)
|
|
|
|
#define ThreadLockDesktop(pti, pdesk, ptl, tag) \
|
|
{ \
|
|
UserAssert(pdesk == NULL || OBJECT_TO_OBJECT_HEADER(pdesk)->Type == *ExDesktopObjectType);\
|
|
ThreadLockObject(pdesk, ptl); \
|
|
}
|
|
|
|
#define ThreadLockExchangeDesktop(pti, pdesk, ptl, tag) \
|
|
{ \
|
|
UserAssert(pdesk == NULL || OBJECT_TO_OBJECT_HEADER(pdesk)->Type == *ExDesktopObjectType);\
|
|
ThreadLockExchangeObject(pdesk, ptl); \
|
|
}
|
|
|
|
#define ThreadUnlockDesktop(pti, ptl, tag) ThreadUnlockObject(ptl)
|
|
|
|
#endif // LOGDESKTOPLOCKS
|
|
|
|
#define ThreadLockWinSta(pti, pwinsta, ptl) \
|
|
{ \
|
|
UserAssert(pwinsta == NULL || OBJECT_TO_OBJECT_HEADER(pwinsta)->Type == *ExWindowStationObjectType);\
|
|
ThreadLockObject(pwinsta, ptl); \
|
|
}
|
|
|
|
#define ThreadLockExchangeWinSta(pti, pwinsta, ptl) \
|
|
{ \
|
|
UserAssert(pwinsta == NULL || OBJECT_TO_OBJECT_HEADER(pwinsta)->Type == *ExWindowStationObjectType);\
|
|
ThreadLockExchangeObject(pwinsta, ptl); \
|
|
}
|
|
|
|
#define _ThreadLockPti(pti, pobj, ptl) LockW32Thread((PW32THREAD)pobj, ptl)
|
|
#if DBG
|
|
#define ThreadLockPti(pti, pobj, ptl) \
|
|
{ \
|
|
if ((pobj != NULL) \
|
|
&& (pobj->TIF_flags & TIF_INCLEANUP) \
|
|
&& (pobj != PtiCurrent())) { \
|
|
RIPMSG1(RIP_ERROR, "ThreadLockPti: dead thread %#p", pobj); \
|
|
} \
|
|
_ThreadLockPti(pti, pobj, ptl); \
|
|
}
|
|
#else
|
|
#define ThreadLockPti(pti, pobj, ptl) \
|
|
{ \
|
|
_ThreadLockPti(pti, pobj, ptl); \
|
|
}
|
|
#endif
|
|
|
|
#define ThreadLockExchangePti(pobj, ptl) LockExchangeW32Thread((PW32THREAD)pobj, ptl)
|
|
|
|
#define ThreadUnlockWinSta(pti, ptl) ThreadUnlockObject(ptl)
|
|
#define ThreadUnlockPti(pti, ptl) UnlockW32Thread(ptl)
|
|
|
|
/*
|
|
* Macros for locking pool allocations
|
|
*/
|
|
#define ThreadLockPool(_pti_, _ppool_, _ptl_) \
|
|
PushW32ThreadLock(_ppool_, _ptl_, UserFreePool)
|
|
|
|
#define ThreadUnlockPool(_pti_, _ptl_) \
|
|
PopW32ThreadLock(_ptl_)
|
|
|
|
#define ThreadUnlockAndFreePool(_pti_, _ptl_) \
|
|
PopAndFreeAlwaysW32ThreadLock(_ptl_)
|
|
|
|
#define ThreadLockPoolCleanup(_pti_, _ppool_, _ptl_, _pfn_) \
|
|
PushW32ThreadLock(_ppool_, _ptl_, _pfn_)
|
|
|
|
#define ThreadUnlockPoolCleanup(_pti_, _ptl_) \
|
|
PopW32ThreadLock(_ptl_)
|
|
|
|
#define ThreadUnlockAndCleanupPool(_pti_, _ptl_) \
|
|
PopAndFreeAlwaysW32ThreadLock(_ptl_)
|
|
|
|
#define ThreadLockDesktopHandle(_pti, _ptl_, _hdesk_) \
|
|
PushW32ThreadLock(_hdesk_, _ptl_, CloseProtectedHandle)
|
|
|
|
#define ThreadUnlockDesktopHandle(_ptl_) \
|
|
PopAndFreeAlwaysW32ThreadLock(_ptl_)
|
|
|
|
void CleanupDecSFWLockCount(PVOID pIgnore);
|
|
#define ThreadLockSFWLockCount(_ptl_) \
|
|
{ \
|
|
IncSFWLockCount(); \
|
|
/* Pass a fake pObj or the cleanup function won't be called */ \
|
|
PushW32ThreadLock(&guSFWLockCount, _ptl_, CleanupDecSFWLockCount); \
|
|
}
|
|
|
|
#define ThreadUnlockSFWLockCount(_ptl_) \
|
|
{ \
|
|
DecSFWLockCount(); \
|
|
PopW32ThreadLock(_ptl_); \
|
|
}
|
|
|
|
/*
|
|
* special handle that signifies we have a rle bitmap for the wallpaper
|
|
*/
|
|
#define HBITMAP_RLE ((HBITMAP)0xffffffff)
|
|
|
|
typedef struct tagWPINFO {
|
|
int xsize, ysize;
|
|
PBITMAPINFO pbmi;
|
|
PBYTE pdata;
|
|
PBYTE pbmfh;
|
|
} WPINFO;
|
|
|
|
/*
|
|
* Defines used by GetMouseMovePointsEx API
|
|
*/
|
|
|
|
#define MAX_MOUSEPOINTS 64
|
|
|
|
#define PREVPOINT(i) \
|
|
((i == 0) ? (MAX_MOUSEPOINTS - 1) : ((i - 1) % MAX_MOUSEPOINTS))
|
|
|
|
#define NEXTPOINT(i) \
|
|
((i + 1) % MAX_MOUSEPOINTS)
|
|
|
|
#define SAVEPOINT(xc, yc, _resX, _resY, t, e) \
|
|
{ \
|
|
/* \
|
|
* (xc, yc) is the point and (resX, resY) is the resolution \
|
|
*/ \
|
|
gaptMouse[gptInd].x = MAKELONG(LOWORD(xc), LOWORD(_resX)); \
|
|
gaptMouse[gptInd].y = MAKELONG(LOWORD(yc), LOWORD(_resY)); \
|
|
gaptMouse[gptInd].time = t; \
|
|
gaptMouse[gptInd].dwExtraInfo = e; \
|
|
\
|
|
gptInd = NEXTPOINT(gptInd); \
|
|
}
|
|
|
|
|
|
/*
|
|
* Structure used for getting the stack traces for user critical section.
|
|
*/
|
|
#define MAX_STACK_CALLS 8
|
|
|
|
typedef struct tagCRITSTACK {
|
|
struct tagCRITSTACK* pNext;
|
|
PETHREAD thread;
|
|
int nFrames;
|
|
PVOID trace[MAX_STACK_CALLS];
|
|
} CRITSTACK, *PCRITSTACK;
|
|
|
|
|
|
/*
|
|
* Macros for User Server and Raw Input Thread critical sections.
|
|
*/
|
|
#if DBG
|
|
#define KeUserModeCallback(api, pIn, cb, pOut, pcb) _KeUserModeCallback(api, pIn, cb, pOut, pcb);
|
|
#define CheckCritIn() _AssertCritIn()
|
|
#define CheckDeviceInfoListCritIn() _AssertDeviceInfoListCritIn()
|
|
#define CheckCritInShared() _AssertCritInShared()
|
|
#define CheckCritOut() _AssertCritOut()
|
|
#define CheckDeviceInfoListCritOut() _AssertDeviceInfoListCritOut()
|
|
|
|
void BeginAtomicCheck();
|
|
void BeginAtomicDeviceInfoListCheck();
|
|
void EndAtomicCheck();
|
|
void EndAtomicDeviceInfoListCheck();
|
|
#define BEGINATOMICCHECK() BeginAtomicCheck(); \
|
|
{ DWORD dwCritSecUseSave = gdwCritSecUseCount;
|
|
|
|
#define ENDATOMICCHECK() UserAssert(dwCritSecUseSave == gdwCritSecUseCount); \
|
|
} EndAtomicCheck();
|
|
#define BEGINATOMICDEVICEINFOLISTCHECK() \
|
|
BeginAtomicDeviceInfoListCheck(); \
|
|
{ DWORD dwDeviceInfoListCritSecUseSave = gdwDeviceInfoListCritSecUseCount;
|
|
|
|
#define ENDATOMICDEVICEINFOLISTCHECK() \
|
|
UserAssert(dwDeviceInfoListCritSecUseSave == gdwDeviceInfoListCritSecUseCount); \
|
|
} EndAtomicDeviceInfoListCheck();
|
|
|
|
// Use this to jump/return out of scope of dwCritSecUseSave (eg: error handling)
|
|
#define EXITATOMICCHECK() UserAssert(dwCritSecUseSave == gdwCritSecUseCount); \
|
|
EndAtomicCheck();
|
|
#define ISATOMICCHECK() (gdwInAtomicOperation != 0)
|
|
#define ISATOMICDEVICEINFOLISTCHECK() (gdwInAtomicDeviceInfoListOperation != 0)
|
|
|
|
#else // DBG
|
|
#define CheckCritIn()
|
|
#define CheckDeviceInfoListCritIn()
|
|
#define CheckCritInShared()
|
|
#define CheckCritOut()
|
|
#define CheckDeviceInfoListCritOut()
|
|
#define BEGINATOMICCHECK()
|
|
#define BEGINATOMICDEVICEINFOLISTCHECK()
|
|
#define BeginAtomicCheck()
|
|
#define BeginAtomicDeviceInfoListCheck()
|
|
#define ENDATOMICCHECK()
|
|
#define ENDATOMICDEVICEINFOLISTCHECK()
|
|
#define EndAtomicCheck()
|
|
#define EndAtomicDeviceInfoListCheck()
|
|
#define EXITATOMICCHECK()
|
|
#define ISATOMICCHECK()
|
|
#define ISATOMICDEVICEINFOLISTCHECK()
|
|
#endif // DBG
|
|
|
|
|
|
#define DIAGNOSE_IO 1
|
|
#ifdef DIAGNOSE_IO
|
|
ULONG MonotonicTick();
|
|
#define LOGTIME(gt) gt = MonotonicTick();
|
|
#else
|
|
#define LOGTIME(gt)
|
|
#endif
|
|
|
|
/*
|
|
* #defines used for mouse/keyboard read buffer
|
|
*/
|
|
#define MAXIMUM_ITEMS_READ 10
|
|
#define NELEM_BUTTONQUEUE 16
|
|
|
|
/*
|
|
* Number of times to retry reading a device after a read attempt fails
|
|
*/
|
|
#define MAXIMUM_READ_RETRIES 5
|
|
|
|
typedef struct tagGENERIC_DEVICE_INFO {
|
|
#ifdef GENERIC_INPUT
|
|
HEAD head;
|
|
#endif
|
|
struct tagDEVICEINFO *pNext;
|
|
BYTE type;
|
|
BYTE bFlags;
|
|
USHORT usActions;
|
|
BYTE nRetryRead;
|
|
UNICODE_STRING ustrName;
|
|
HANDLE handle;
|
|
PVOID NotificationEntry;
|
|
PKEVENT pkeHidChangeCompleted; // wake RequestDeviceChange()
|
|
IO_STATUS_BLOCK iosb;
|
|
NTSTATUS ReadStatus;
|
|
|
|
#ifdef DIAGNOSE_IO
|
|
HANDLE OpenerProcess;
|
|
NTSTATUS OpenStatus;
|
|
NTSTATUS AttrStatus;
|
|
ULONG timeStartRead; // tick before ZwReadFile
|
|
ULONG timeEndRead; // tick after ZwReadFile
|
|
int nReadsOutstanding; // ZwReadFile ++, consume data --
|
|
#endif
|
|
|
|
#ifdef PRERELEASE
|
|
UINT fForcedDetach : 1; // Set if the device is forced detached from TS
|
|
#endif
|
|
} GENERIC_DEVICE_INFO, *PGENERIC_DEVICE_INFO;
|
|
|
|
// valuse for GENERIC_DEVICE_INFO.type
|
|
#define DEVICE_TYPE_MOUSE 0
|
|
#define DEVICE_TYPE_KEYBOARD 1
|
|
#ifdef GENERIC_INPUT
|
|
#define DEVICE_TYPE_HID 2
|
|
#define DEVICE_TYPE_MAX 2
|
|
#else
|
|
#define DEVICE_TYPE_MAX 1
|
|
#endif
|
|
|
|
// values for GENERIC_DEVICE_INFO.usActions and SignalDeviceChange()
|
|
#define GDIAF_ARRIVED (USHORT)0x0001 // open & start reading
|
|
#define GDIAF_QUERYREMOVE (USHORT)0x0002 // close the device
|
|
#define GDIAF_REMOVECANCELLED (USHORT)0x0004 // reopen the device
|
|
#define GDIAF_DEPARTED (USHORT)0x0008 // close and free the device
|
|
#define GDIAF_IME_STATUS (USHORT)0x0010 // ???
|
|
#define GDIAF_REFRESH_MOUSE (USHORT)0x0020 // ???
|
|
#define GDIAF_FREEME (USHORT)0x0080 // Request to Free the DeviceInfo
|
|
#define GDIAF_PNPWAITING (USHORT)0x0100 // a PnP thread is waiting
|
|
#define GDIAF_RETRYREAD (USHORT)0x0200 // Retry the read
|
|
#define GDIAF_RECONNECT (USHORT)0x0400 // The session reconnected
|
|
#ifdef GENERIC_INPUT
|
|
#define GDIAF_STARTREAD (USHORT)0x0800 // The device needs to be started
|
|
#define GDIAF_STOPREAD (USHORT)0x1000 // The device needs to be stopped
|
|
#endif
|
|
|
|
// values for GENERIC_DEVICE_INFO.bFlags;
|
|
#define GDIF_NOTPNP 0x01 // Not a PnP device (eg: PS/2)
|
|
#define GDIF_READING 0x02 // Read may be pending (don't free DeviceInfo).
|
|
#if DIAGNOSE_IO
|
|
#define GDIF_READERMUSTFREE 0x04 // "Free Device" while read pending
|
|
#define GDIF_PNPMUSTFREE 0x08 // "Free Device" while PnP notification pending
|
|
#endif
|
|
#define GDIF_DBGREAD 0x10 // Verbose dbg output about this device
|
|
|
|
typedef struct tagMOUSE_DEVICE_INFO { // DEVICE_TYPE_MOUSE
|
|
MOUSE_ATTRIBUTES Attr;
|
|
MOUSE_INPUT_DATA Data[MAXIMUM_ITEMS_READ];
|
|
} MOUSE_DEVICE_INFO, *PMOUSE_DEVICE_INFO;
|
|
|
|
#ifdef GENERIC_INPUT
|
|
#define INVALID_UNIT_ID ((USHORT)0xffff)
|
|
#define INJECTED_UNIT_ID ((USHORT)0xfffe)
|
|
#endif
|
|
|
|
|
|
typedef struct tagKEYBOARD_DEVICE_INFO { // DEVICE_TYPE_KEYBOARD
|
|
KEYBOARD_ATTRIBUTES Attr;
|
|
KEYBOARD_ID_EX IdEx;
|
|
KEYBOARD_INPUT_DATA Data[MAXIMUM_ITEMS_READ];
|
|
} KEYBOARD_DEVICE_INFO, *PKEYBOARD_DEVICE_INFO;
|
|
|
|
#define GET_KEYBOARD_DEVINFO_ID(pDeviceInfo) ((pDeviceInfo)->keyboard.IdEx)
|
|
#define GET_KEYBOARD_DEVINFO_TYPE(pDeviceInfo) ((pDeviceInfo)->keyboard.IdEx.Type)
|
|
#define GET_KEYBOARD_DEVINFO_SUBTYPE(pDeviceInfo) ((pDeviceInfo)->keyboard.IdEx.Subtype)
|
|
|
|
|
|
#ifdef GENERIC_INPUT
|
|
/*
|
|
* HID Descriptor
|
|
* allocated as a handle, type == TAG_HIDDESC
|
|
*/
|
|
typedef struct tagHIDDESC {
|
|
IO_STATUS_BLOCK iob;
|
|
|
|
PVOID pPreparsedData; // the size is in hidCollectionInfo.DescriptorSize
|
|
PVOID pInputBuffer; // the size is in hidpCaps.
|
|
|
|
HIDP_CAPS hidpCaps;
|
|
HID_COLLECTION_INFORMATION hidCollectionInfo;
|
|
} HIDDESC, *PHIDDESC;
|
|
|
|
/*
|
|
* HID Top Level Collection Information
|
|
*/
|
|
typedef struct tagHID_TLC_INFO {
|
|
LIST_ENTRY link;
|
|
// Toplevel collection
|
|
USHORT usUsagePage;
|
|
USHORT usUsage;
|
|
/*
|
|
* Reference counters
|
|
*/
|
|
UINT cDevices; // # of devices currently attached
|
|
UINT cDirectRequest; // Reference count of direct request to this device type (# of processes)
|
|
UINT cUsagePageRequest; // Reference count of UsagePage only request
|
|
UINT cExcludeRequest; // Reference count of Exclude request
|
|
UINT cExcludeOrphaned; // Orphaned count of Exclude request
|
|
#if defined(GI_SINK) && defined(LATER)
|
|
UINT cSinkable; // LATER...
|
|
#endif
|
|
} HID_TLC_INFO, *PHID_TLC_INFO;
|
|
|
|
/*
|
|
* HID global PageOnly request
|
|
*/
|
|
typedef struct tagHID_PAGEONLY_REQUEST {
|
|
LIST_ENTRY link;
|
|
USHORT usUsagePage;
|
|
UINT cRefCount;
|
|
#if defined(GI_SINK) && defined(LATER)
|
|
UINT cSinkable;
|
|
#endif
|
|
} HID_PAGEONLY_REQUEST, *PHID_PAGEONLY_REQUEST;
|
|
|
|
/*
|
|
* Global HID Request
|
|
*/
|
|
typedef struct tagHID_REQUEST_TABLE {
|
|
/*
|
|
* HID_TLC_INFO
|
|
*/
|
|
LIST_ENTRY TLCInfoList;
|
|
/*
|
|
* HID_PAGEONLY_REQUEST
|
|
*/
|
|
LIST_ENTRY UsagePageList;
|
|
|
|
#ifdef GI_SINK
|
|
/*
|
|
* PROCESS_HID_TABLE
|
|
*/
|
|
LIST_ENTRY ProcessRequestList;
|
|
#endif
|
|
} HID_REQUEST_TABLE, *PHID_REQUEST_TABLE;
|
|
|
|
extern HID_REQUEST_TABLE gHidRequestTable;
|
|
extern int gnHidProcess;
|
|
|
|
/*
|
|
* Per process hid device request list
|
|
*/
|
|
typedef struct tagPROCESS_HID_REQUEST {
|
|
LIST_ENTRY link;
|
|
// Toplevel collection
|
|
USHORT usUsagePage;
|
|
USHORT usUsage;
|
|
#ifdef GI_SINK
|
|
BOOL fSinkable : 1;
|
|
#endif
|
|
BOOL fExclusiveOrphaned : 1;
|
|
union {
|
|
PHID_TLC_INFO pTLCInfo;
|
|
PHID_PAGEONLY_REQUEST pPORequest;
|
|
LPVOID ptr;
|
|
};
|
|
PWND spwndTarget;
|
|
} PROCESS_HID_REQUEST, *PPROCESS_HID_REQUEST;
|
|
|
|
/*
|
|
* Per-process HID request table
|
|
*/
|
|
typedef struct tagPROCESS_HID_TABLE {
|
|
/*
|
|
* Link to the next process HID table.
|
|
*/
|
|
LIST_ENTRY link;
|
|
|
|
/*
|
|
* Those LIST_ENTRYs point PROCESS_HID_REQUEST
|
|
*/
|
|
LIST_ENTRY InclusionList;
|
|
LIST_ENTRY UsagePageList;
|
|
LIST_ENTRY ExclusionList;
|
|
|
|
/*
|
|
* Target windows for the legacy devices
|
|
*/
|
|
PWND spwndTargetMouse;
|
|
PWND spwndTargetKbd;
|
|
|
|
#ifdef GI_SINK
|
|
/*
|
|
* Number of Sinks in this process.
|
|
* N.b. this does not include the legacy device sinks to
|
|
* save clocks walking through the list, if sink requests
|
|
* are only for the legacy devices.
|
|
*/
|
|
int nSinks;
|
|
#endif
|
|
|
|
/*
|
|
* Cache of the last matching request.
|
|
*/
|
|
PPROCESS_HID_REQUEST pLastRequest;
|
|
USAGE UsagePageLast;
|
|
USAGE UsageLast;
|
|
|
|
/*
|
|
* Legacy Mode flags
|
|
*/
|
|
BOOL fRawMouse : 1;
|
|
BOOL fNoLegacyMouse : 1;
|
|
#ifdef GI_SINK
|
|
BOOL fRawMouseSink : 1;
|
|
#endif
|
|
BOOL fRawKeyboard : 1;
|
|
BOOL fNoLegacyKeyboard : 1;
|
|
#ifdef GI_SINK
|
|
BOOL fRawKeyboardSink : 1;
|
|
#endif
|
|
BOOL fCaptureMouse : 1; // "Own" a mouse...
|
|
BOOL fNoHotKeys : 1;
|
|
BOOL fAppKeys: 1;
|
|
} PROCESS_HID_TABLE, *PPROCESS_HID_TABLE;
|
|
|
|
#define TestRawInputMode(pti, mode) \
|
|
((pti) && (pti)->ppi && (pti)->ppi->pHidTable && (pti)->ppi->pHidTable->f##mode)
|
|
|
|
#define TestRawInputModeNoCheck(pti, mode) \
|
|
((pti)->ppi->pHidTable->f##mode)
|
|
|
|
#ifdef GI_SINK
|
|
typedef struct tagHID_COUNTERS {
|
|
DWORD cKbdSinks;
|
|
DWORD cMouseSinks;
|
|
DWORD cHidSinks;
|
|
} HID_COUNTERS;
|
|
|
|
extern HID_COUNTERS gHidCounters;
|
|
|
|
#define IsKeyboardSinkPresent() (gHidCounters.cKbdSinks > 0)
|
|
#define IsMouseSinkPresent() (gHidCounters.cMouseSinks > 0)
|
|
#endif
|
|
|
|
|
|
#define HID_INCLUDE 0x01
|
|
#define HID_PAGEONLY 0x02
|
|
#define HID_EXCLUDE 0x03
|
|
|
|
/*
|
|
* HID Device info
|
|
*/
|
|
typedef struct tagHID_DEVICE_INFO {
|
|
PHIDDESC pHidDesc;
|
|
PHID_TLC_INFO pTLCInfo;
|
|
} HID_DEVICE_INFO, *PHID_DEVICE_INFO;
|
|
|
|
#endif // GENERIC_INPUT
|
|
|
|
typedef struct tagDEVICEINFO {
|
|
GENERIC_DEVICE_INFO;
|
|
union {
|
|
MOUSE_DEVICE_INFO mouse;
|
|
KEYBOARD_DEVICE_INFO keyboard;
|
|
#ifdef GENERIC_INPUT
|
|
HID_DEVICE_INFO hid;
|
|
#endif
|
|
};
|
|
} DEVICEINFO, *PDEVICEINFO;
|
|
|
|
typedef struct tagDEVICE_TEMPLATE {
|
|
SIZE_T cbDeviceInfo; // bytes to allocate for DEVICEINFO
|
|
const GUID *pClassGUID; // GUID of the class
|
|
UINT uiRegistrySection; // Parameters for class (HKLM\SYSTEM\CurrentControlSet\Services\*\Parameters)
|
|
LPWSTR pwszClassName; // Class name (eg: L"mouclass")
|
|
LPWSTR pwszDefDevName; // Default Device Name
|
|
LPWSTR pwszLegacyDevName; // Legacy Device Name (eg: "PointerClassLegacy0")
|
|
ULONG IOCTL_Attr; // IOCTL_*_QUERY_ATTRIBUTES
|
|
UINT offAttr; // offset of *_ATTRIBUTES struct within DEVICEINFO
|
|
ULONG cbAttr; // sizeof *_ATTRIBUTES struct
|
|
UINT offData; // offset of *_INPUT_DATA buffer within DEVICEINFO
|
|
ULONG cbData; // sizeof *_INPUT_DATA buffer
|
|
VOID (*DeviceRead)(PDEVICEINFO); // routine to read the device
|
|
PKEVENT pkeHidChange; // event to signal changes to this sort of device
|
|
|
|
#ifdef GENERIC_INPUT
|
|
DWORD dwFlags; // Flags...
|
|
#endif
|
|
} DEVICE_TEMPLATE, *PDEVICE_TEMPLATE;
|
|
|
|
|
|
#ifdef GENERIC_INPUT
|
|
#define DT_HID 0x00000001
|
|
#endif
|
|
|
|
extern DEVICE_TEMPLATE aDeviceTemplate[]; // in pnp.c
|
|
|
|
typedef struct tagMOUSEEVENT {
|
|
USHORT ButtonFlags;
|
|
USHORT ButtonData;
|
|
ULONG_PTR ExtraInfo;
|
|
POINT ptPointer;
|
|
LONG time;
|
|
BOOL bInjected;
|
|
#ifdef GENERIC_INPUT
|
|
HANDLE hDevice;
|
|
|
|
/*
|
|
* The raw mouse information comes here.
|
|
*/
|
|
MOUSE_INPUT_DATA rawData;
|
|
#endif
|
|
} MOUSEEVENT, *PMOUSEEVENT;
|
|
|
|
|
|
#ifdef GENERIC_INPUT
|
|
/*
|
|
* RawInput
|
|
*/
|
|
typedef struct tagHIDDATA {
|
|
THROBJHEAD head;
|
|
PWND spwndTarget;
|
|
RAWINPUT rid; // raw input data, variable length
|
|
// rid needs to be the last member in HIDDATA
|
|
} HIDDATA, *PHIDDATA;
|
|
|
|
/*
|
|
* Global request list manipulation.
|
|
*/
|
|
void InitializeHidRequestList();
|
|
void CleanupHidRequestList();
|
|
|
|
/*
|
|
* DeviceType request
|
|
*/
|
|
VOID FreeHidTLCInfo(
|
|
PHID_TLC_INFO pHidRequest);
|
|
|
|
/*
|
|
* HID specific device info
|
|
*/
|
|
PHIDDESC HidCreateDeviceInfo(PDEVICEINFO pDeviceInfo);
|
|
|
|
/*
|
|
* HID specific information (managed by HM),
|
|
* linked from DEVICEINFO
|
|
*/
|
|
/* N.b. AllocateHidDesc is only called within hidevice.c */
|
|
void FreeHidDesc(PHIDDESC);
|
|
|
|
/*
|
|
* The handle in WM_INPUT
|
|
*/
|
|
PHIDDATA AllocateHidData(HANDLE hDevice, DWORD dwType, DWORD dwSize, WPARAM wParam, PWND pwnd);
|
|
void FreeHidData(PHIDDATA pData);
|
|
|
|
#ifdef GI_SINK
|
|
#define GI_SINK_PARAM(x) ,x
|
|
#else
|
|
#define GI_SINK_PARAM(x)
|
|
#endif
|
|
|
|
void FreeHidProcessRequest(
|
|
PPROCESS_HID_REQUEST pHid,
|
|
DWORD dwFlags,
|
|
PPROCESS_HID_TABLE pHidTable);
|
|
|
|
|
|
/*
|
|
* HID specific read call back (called from InputApc)
|
|
*/
|
|
VOID ProcessHidInput(PDEVICEINFO pDeviceInfo);
|
|
|
|
/*
|
|
* API helper
|
|
*/
|
|
BOOL _RegisterRawInputDevices(PCRAWINPUTDEVICE, UINT uiNumDevices);
|
|
UINT _GetRegisteredRawInputDevices(PRAWINPUTDEVICE, PUINT puiNumDevices);
|
|
|
|
/*
|
|
* UserCriticalSection...
|
|
*/
|
|
#define BESURE_IN_USERCRIT(cond) \
|
|
{ \
|
|
BOOLEAN fHasToLeaveUserCrit = FALSE; \
|
|
if ((cond) && !ExIsResourceAcquiredExclusiveLite(gpresUser)) { \
|
|
CheckDeviceInfoListCritOut(); \
|
|
fHasToLeaveUserCrit = TRUE; \
|
|
EnterCrit(); \
|
|
TAGMSG0(DBGTAG_PNP, "BESURE_IN_USERCRIT: entering the user crit"); \
|
|
}
|
|
|
|
#define END_IN_USERCRIT() \
|
|
if (fHasToLeaveUserCrit) { \
|
|
CheckDeviceInfoListCritOut(); \
|
|
TAGMSG0(DBGTAG_PNP, "END_IN_USERCRIT: leaving the user crit"); \
|
|
LeaveCrit(); \
|
|
}\
|
|
}
|
|
|
|
/*
|
|
* Acquire input device lock while making sure there is no pending PnP callout
|
|
* requesting to process a device change.
|
|
*/
|
|
#define PNP_SAFE_DEVICECRIT_IN() \
|
|
{\
|
|
CheckCritIn();\
|
|
CheckDeviceInfoListCritIn();\
|
|
while (TRUE) {\
|
|
if (gbPnPWaiting) {\
|
|
LeaveDeviceInfoListCrit();\
|
|
LeaveCrit(); \
|
|
Status = KeWaitForSingleObject(gpEventPnPWainting, Executive, KernelMode, FALSE, NULL); \
|
|
EnterCrit();\
|
|
EnterDeviceInfoListCrit();\
|
|
UserAssert(Status == STATUS_SUCCESS);\
|
|
continue;\
|
|
} else { \
|
|
break; \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
|
|
/*
|
|
* Check if this device type is active to read
|
|
*/
|
|
__inline DWORD HidValidExclusive(PHID_TLC_INFO pTLCInfo)
|
|
{
|
|
UserAssert(pTLCInfo);
|
|
UserAssert(pTLCInfo->cExcludeRequest >= pTLCInfo->cExcludeOrphaned);
|
|
return pTLCInfo->cExcludeRequest - pTLCInfo->cExcludeOrphaned;
|
|
}
|
|
|
|
__inline BOOL HidTLCActive(PHID_TLC_INFO pTLCInfo)
|
|
{
|
|
UserAssert(pTLCInfo);
|
|
return pTLCInfo->cDirectRequest > 0 || pTLCInfo->cUsagePageRequest > HidValidExclusive(pTLCInfo);
|
|
}
|
|
|
|
/*
|
|
* Allocate and free process device type request table.
|
|
*/
|
|
PPROCESS_HID_TABLE AllocateProcessHidTable(void);
|
|
void FreeProcessHidTable(PPROCESS_HID_TABLE pHidTable);
|
|
|
|
void DestroyProcessHidRequests(PPROCESSINFO ppi);
|
|
void DestroyThreadHidObjects(PTHREADINFO pti);
|
|
|
|
#if DBG
|
|
void CheckupHidLeak(void);
|
|
#endif
|
|
|
|
#endif // GENERIC_INPUT
|
|
|
|
|
|
VOID ProcessKeyboardInput(PDEVICEINFO pDeviceInfo);
|
|
VOID ProcessMouseInput(PDEVICEINFO pDeviceInfo);
|
|
VOID RequestDeviceChange(
|
|
PDEVICEINFO pDeviceInfo,
|
|
USHORT usAction,
|
|
BOOL fInDeviceInfoListCrit);
|
|
|
|
VOID NTAPI InputApc(
|
|
IN PVOID ApcContext,
|
|
IN PIO_STATUS_BLOCK IoStatusBlock,
|
|
IN ULONG Reserved);
|
|
|
|
ULONG xxxGetDeviceChangeInfo(VOID);
|
|
NTSTATUS InitializeMediaChange(HANDLE hMediaRequestEvent);
|
|
VOID CleanupMediaChange(VOID);
|
|
|
|
/*
|
|
* Hard error information
|
|
*/
|
|
typedef struct tagHARDERRORHANDLER {
|
|
PTHREADINFO pti;
|
|
PQ pqAttach;
|
|
} HARDERRORHANDLER, *PHARDERRORHANDLER;
|
|
|
|
/*
|
|
* Terminal Structure.
|
|
*
|
|
* This structure is only viewable from the kernel.
|
|
*/
|
|
|
|
#define TEST_GTERMF(f) TEST_FLAG(gdwGTERMFlags, f)
|
|
#define TEST_BOOL_GTERMF(f) TEST_BOOL_FLAG(gdwGTERMFlags, f)
|
|
#define SET_GTERMF(f) SET_FLAG(gdwGTERMFlags, f)
|
|
#define CLEAR_GTERMF(f) CLEAR_FLAG(gdwGTERMFlags, f)
|
|
#define SET_OR_CLEAR_GTERMF(f, fSet) SET_OR_CLEAR_FLAG(gdwGTERMFlags, f, fSet)
|
|
#define TOGGLE_GTERMF(f) TOGGLE_FLAG(gdwGTERMFlags, f)
|
|
|
|
#define GTERMF_MOUSE 0x00000001
|
|
|
|
|
|
#define TERMF_INITIALIZED 0x00000001
|
|
#define TERMF_NOIO 0x00000002
|
|
#define TERMF_STOPINPUT 0x00000004
|
|
#define TERMF_DTINITSUCCESS 0x00000008
|
|
#define TERMF_DTINITFAILED 0x00000010
|
|
#define TERMF_DTDESTROYED 0x00000020
|
|
#define TERMF_MOTHERWND_CREATED 0x00000040
|
|
#define TERMF_MOTHERWND_DESTROYED 0x00000080
|
|
|
|
typedef struct tagTERMINAL {
|
|
|
|
DWORD dwTERMF_Flags; // terminal flags
|
|
|
|
/*
|
|
* System Information
|
|
*/
|
|
PWND spwndDesktopOwner; // mother desktop
|
|
|
|
|
|
PTHREADINFO ptiDesktop;
|
|
PQ pqDesktop;
|
|
|
|
PKEVENT pEventTermInit;
|
|
PKEVENT pEventDestroyDesktop; // Used for destroying desktops
|
|
|
|
PDESKTOP rpdeskDestroy; // Desktop destroy list.
|
|
|
|
PKEVENT pEventInputReady; // input ready event. This is created in
|
|
// CreateTerminal. RIT and the desktop thread
|
|
// will wait for it. It will be set when the
|
|
// first desktop in that terminal will be created.
|
|
} TERMINAL, *PTERMINAL;
|
|
|
|
/*
|
|
* Pool allocation tags and macros
|
|
*/
|
|
|
|
/*
|
|
* Define tags. To add tags, add them to ntuser\kernel\ptag.lst
|
|
*/
|
|
#define DEFINE_POOLTAG(value, index) value
|
|
|
|
#define DECLARE_POOLTAG(name, value, index)
|
|
|
|
#include "ptag.h"
|
|
|
|
NTSTATUS UserCommitDesktopMemory(
|
|
PVOID pBase,
|
|
PVOID *ppCommit,
|
|
PSIZE_T pCommitSize);
|
|
|
|
NTSTATUS UserCommitSharedMemory(
|
|
PVOID pBase,
|
|
PVOID *ppCommit,
|
|
PSIZE_T pCommitSize);
|
|
|
|
PWIN32HEAP UserCreateHeap(
|
|
HANDLE hSection,
|
|
ULONG ulViewOffset,
|
|
PVOID pvBaseAddress,
|
|
DWORD dwSize,
|
|
PRTL_HEAP_COMMIT_ROUTINE pfnCommit);
|
|
|
|
#define RECORD_STACK_TRACE_SIZE 6
|
|
|
|
/*
|
|
* Pool allocation flags
|
|
*/
|
|
|
|
#define POOL_HEAVY_ALLOCS 0x00000001 // use HeavyAllocPool
|
|
#define POOL_CAPTURE_STACK 0x00000002 // stack traces are captured
|
|
#define POOL_FAIL_ALLOCS 0x00000004 // fail pool allocations
|
|
#define POOL_FAIL_BY_INDEX 0x00000008 // fail allocations by index
|
|
#define POOL_TAIL_CHECK 0x00000010 // append tail string
|
|
#define POOL_KEEP_FREE_RECORD 0x00000020 // keep a list with last x frees
|
|
#define POOL_KEEP_FAIL_RECORD 0x00000040 // keep a list with last x failed allocations
|
|
#define POOL_BREAK_FOR_LEAKS 0x00000080 // break on pool leaks (remote sessions)
|
|
|
|
typedef struct tagWin32AllocStats {
|
|
SIZE_T dwMaxMem; // max pool memory allocated
|
|
SIZE_T dwCrtMem; // current pool memory used
|
|
DWORD dwMaxAlloc; // max number of pool allocations made
|
|
DWORD dwCrtAlloc; // current pool allocations
|
|
|
|
PWin32PoolHead pHead; // pointer to the link list with the allocations
|
|
|
|
} Win32AllocStats, *PWin32AllocStats;
|
|
|
|
typedef struct tagPOOLRECORD {
|
|
PVOID ExtraData; // the tag
|
|
SIZE_T size;
|
|
PVOID trace[RECORD_STACK_TRACE_SIZE];
|
|
} POOLRECORD, *PPOOLRECORD;
|
|
|
|
#ifdef POOL_INSTR_API
|
|
|
|
BOOL _Win32PoolAllocationStats(
|
|
LPDWORD parrTags,
|
|
SIZE_T tagsCount,
|
|
SIZE_T* lpdwMaxMem,
|
|
SIZE_T* lpdwCrtMem,
|
|
LPDWORD lpdwMaxAlloc,
|
|
LPDWORD lpdwCrtAlloc);
|
|
|
|
#endif // POOL_INSTR_API
|
|
|
|
#ifdef POOL_INSTR
|
|
|
|
VOID CleanupPoolAllocations(VOID);
|
|
NTSTATUS InitPoolLimitations(VOID);
|
|
VOID CleanUpPoolLimitations(VOID);
|
|
#else
|
|
#define CleanupPoolAllocations()
|
|
#define InitPoolLimitations() STATUS_SUCCESS
|
|
#define CleanUpPoolLimitations()
|
|
|
|
#endif // POOL_INSTR
|
|
|
|
#ifndef TRACE_MAP_VIEWS
|
|
#define InitSectionTrace() STATUS_SUCCESS
|
|
#define CleanUpSections()
|
|
#else
|
|
NTSTATUS InitSectionTrace(VOID);
|
|
VOID CleanUpSections(VOID);
|
|
#endif // TRACE_MAP_VIEWS
|
|
|
|
extern PWIN32HEAP gpvSharedAlloc;
|
|
|
|
__inline PVOID
|
|
SharedAlloc(ULONG cb)
|
|
{
|
|
return Win32HeapAlloc(gpvSharedAlloc, cb, 0, 0);
|
|
}
|
|
|
|
__inline BOOL
|
|
SharedFree(PVOID pv)
|
|
{
|
|
return Win32HeapFree(gpvSharedAlloc, pv);
|
|
}
|
|
|
|
NTSTATUS CommitReadOnlyMemory(HANDLE hSection, PSIZE_T pulCommit,
|
|
DWORD dwCommitOffset, int* pdCommit);
|
|
|
|
/*
|
|
* Height and Width of the desktop pattern bitmap.
|
|
*/
|
|
#define CXYDESKPATTERN 8
|
|
|
|
/***************************************************************************\
|
|
* Typedefs and Macros
|
|
*
|
|
* Here are defined all types and macros that are shared across the User's
|
|
* server-side code modules. Types and macros that are unique to a single
|
|
* module should be defined at the head of that module, not in this file.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
|
|
// Window Proc Window Validation macro
|
|
|
|
#define VALIDATECLASSANDSIZE(pwnd, message, wParam, lParam, inFNID, initmessage) \
|
|
if ((pwnd)->fnid != (inFNID)) { \
|
|
switch ((pwnd)->fnid) { \
|
|
DWORD cb; \
|
|
case 0: \
|
|
\
|
|
if ((cb = pwnd->cbwndExtra + sizeof(WND)) < (DWORD)(CBFNID(inFNID))) { \
|
|
RIPMSG3(RIP_WARNING, \
|
|
"(%#p %lX) needs at least (%ld) window words for this proc", \
|
|
pwnd, cb - sizeof(WND), \
|
|
(DWORD)(CBFNID(inFNID)) - sizeof(WND)); \
|
|
return 0; \
|
|
} \
|
|
/* \
|
|
* If this is not the initialization message, we cannot set the fnid; \
|
|
* otherwise, we'll probably fault working on this pwnd's private \
|
|
* uninitialized data \
|
|
*/ \
|
|
if ((message) != (initmessage)) { \
|
|
if (((message) != WM_NCCREATE) && ((message) != WM_NCCALCSIZE) && ((message) != WM_GETMINMAXINFO)) { \
|
|
RIPMSG3(RIP_WARNING, \
|
|
"Default processing message %#lx for pwnd %#p. fnid %#lx not set",\
|
|
(message), (pwnd), (DWORD)(inFNID)); \
|
|
} \
|
|
return xxxDefWindowProc((pwnd), (message), (wParam), (lParam)); \
|
|
} \
|
|
\
|
|
/* \
|
|
* Remember what window class this window belongs to. Can't use \
|
|
* the real class because any app can call CallWindowProc() \
|
|
* directly no matter what the class is! \
|
|
*/ \
|
|
(pwnd)->fnid = (WORD)(inFNID); \
|
|
break; \
|
|
\
|
|
default: \
|
|
RIPMSG3(RIP_WARNING, "Window (%#p) not of correct class; fnid = %lX not %lX", \
|
|
(pwnd), (DWORD)((pwnd)->fnid), (DWORD)(inFNID)); \
|
|
\
|
|
/* Fall through */ \
|
|
\
|
|
case (inFNID | FNID_CLEANEDUP_BIT): \
|
|
case (inFNID | FNID_DELETED_BIT): \
|
|
case (inFNID | FNID_STATUS_BITS): \
|
|
return 0; \
|
|
} \
|
|
}
|
|
|
|
/*
|
|
* Handy Region helper macros
|
|
*/
|
|
#define CopyRgn(hrgnDst, hrgnSrc) \
|
|
GreCombineRgn(hrgnDst, hrgnSrc, NULL, RGN_COPY)
|
|
#define IntersectRgn(hrgnResult, hrgnA, hrgnB) \
|
|
GreCombineRgn(hrgnResult, hrgnA, hrgnB, RGN_AND)
|
|
#define SubtractRgn(hrgnResult, hrgnA, hrgnB) \
|
|
GreCombineRgn(hrgnResult, hrgnA, hrgnB, RGN_DIFF)
|
|
#define UnionRgn(hrgnResult, hrgnA, hrgnB) \
|
|
GreCombineRgn(hrgnResult, hrgnA, hrgnB, RGN_OR)
|
|
#define XorRgn(hrgnResult, hrgnA, hrgnB) \
|
|
GreCombineRgn(hrgnResult, hrgnA, hrgnB, RGN_XOR)
|
|
|
|
void DeleteMaybeSpecialRgn(HRGN hrgn);
|
|
|
|
BOOL zzzInvalidateDCCache(PWND pwndInvalid, DWORD flags);
|
|
|
|
#define IDC_DEFAULT 0x0001
|
|
#define IDC_CHILDRENONLY 0x0002
|
|
#define IDC_CLIENTONLY 0x0004
|
|
#define IDC_MOVEBLT 0x0008
|
|
#define IDC_NOMOUSE 0x0010
|
|
|
|
/*
|
|
* RestoreSpb return Flags
|
|
*/
|
|
|
|
#define RSPB_NO_INVALIDATE 0 // nothing invalidated by restore
|
|
#define RSPB_INVALIDATE 1 // restore invalidate some area
|
|
#define RSPB_INVALIDATE_SSB 2 // restore called SaveScreenBits which invalidated
|
|
|
|
// Calls Proc directly without doing any messages translation
|
|
|
|
#define SCMS_FLAGS_ANSI 0x0001
|
|
#define SCMS_FLAGS_INONLY 0x0002 // Message should be one way (hooks)
|
|
|
|
#define CallClientProcA(pwnd, msg, wParam, lParam, xpfn) \
|
|
SfnDWORD(pwnd, msg, wParam, lParam, xpfn, \
|
|
((PROC)(gpsi->apfnClientW.pfnDispatchMessage)), TRUE, NULL)
|
|
#define CallClientProcW(pwnd, msg, wParam, lParam, xpfn) \
|
|
SfnDWORD(pwnd, msg, wParam, lParam, xpfn, \
|
|
((PROC)(gpsi->apfnClientW.pfnDispatchMessage)), TRUE, NULL)
|
|
#define CallClientWorkerProc(pwnd, msg, wParam, lParam, xpfn) \
|
|
SfnDWORD(pwnd, msg, wParam, lParam, 0, xpfn, TRUE, NULL)
|
|
#define ScSendMessageSMS(pwnd, msg, wParam, lParam, xParam, xpfn, dwSCMSFlags, psms) \
|
|
(((msg) & ~MSGFLAG_MASK) >= WM_USER) ? \
|
|
SfnDWORD(pwnd, msg, wParam, lParam, xParam, xpfn, dwSCMSFlags, psms) : \
|
|
gapfnScSendMessage[MessageTable[msg & 0xffff].iFunction](pwnd, msg, wParam, lParam, xParam, xpfn, dwSCMSFlags, psms)
|
|
#define ScSendMessage(pwnd, msg, wParam, lParam, xParam, xpfn, dwSCMSFlags) \
|
|
ScSendMessageSMS(pwnd, msg, wParam, lParam, xParam, xpfn, dwSCMSFlags, NULL)
|
|
|
|
/*
|
|
* Server-side routines for loading cursors/icons/strings/menus from server.
|
|
*/
|
|
#define SERVERSTRINGMAXSIZE 40
|
|
void RtlInitUnicodeStringOrId(PUNICODE_STRING pstrName, LPWSTR lpstrName);
|
|
int RtlLoadStringOrError(UINT, LPTSTR, int, WORD);
|
|
#define ServerLoadString(hmod, id, p, cch)\
|
|
RtlLoadStringOrError(id, p, cch, 0)
|
|
#define ServerLoadStringEx(hmod, id, p, cch, wLang)\
|
|
RtlLoadStringOrError(id, p, cch, wLang)
|
|
|
|
/*
|
|
* Callback routines for loading resources from client.
|
|
*/
|
|
HANDLE xxxClientLoadImage(
|
|
PUNICODE_STRING pstrName,
|
|
ATOM atomModName,
|
|
WORD wImageType,
|
|
int cxSize,
|
|
int cySize,
|
|
UINT LR_flags,
|
|
BOOL fWallpaper);
|
|
|
|
HANDLE xxxClientCopyImage(
|
|
IN HANDLE hImage,
|
|
IN UINT uImageType,
|
|
IN int cxDesired,
|
|
IN int cyDesired,
|
|
IN UINT LR_flags);
|
|
|
|
PMENU xxxClientLoadMenu(
|
|
HANDLE hmod,
|
|
PUNICODE_STRING pstrName);
|
|
|
|
int xxxClientAddFontResourceW(PUNICODE_STRING, DWORD, DESIGNVECTOR*);
|
|
|
|
VOID ClientFontSweep(VOID);
|
|
VOID ClientLoadLocalT1Fonts();
|
|
VOID ClientLoadRemoteT1Fonts();
|
|
|
|
/*
|
|
* Server-side routine for thread initialization.
|
|
*/
|
|
NTSTATUS InitializeClientPfnArrays(
|
|
CONST PFNCLIENT *ppfnClientA,
|
|
CONST PFNCLIENT *ppfnClientW,
|
|
CONST PFNCLIENTWORKER *ppfnClientWorker,
|
|
HANDLE hModUser);
|
|
|
|
VOID SetRipFlags(DWORD);
|
|
VOID SetDbgTag(int, DWORD);
|
|
|
|
|
|
/*
|
|
* xxxActivateWindow() commands
|
|
*/
|
|
#define AW_USE 1
|
|
#define AW_TRY 2
|
|
#define AW_SKIP 3
|
|
#define AW_TRY2 4
|
|
#define AW_SKIP2 5 /* used internally in xxxActivateWindow() */
|
|
#define AW_USE2 6 /* nc mouse activation added by craigc */
|
|
|
|
/*
|
|
* Structure for WM_ACTIVATEAPP EnumWindows() callback.
|
|
*/
|
|
typedef struct tagAAS {
|
|
PTHREADINFO ptiNotify;
|
|
DWORD tidActDeact;
|
|
UINT fActivating : 1;
|
|
UINT fQueueNotify : 1;
|
|
} AAS;
|
|
|
|
/*
|
|
* Declaration for EnumWindows() callback function.
|
|
*/
|
|
BOOL xxxActivateApp(PWND pwnd, AAS *paas);
|
|
|
|
#define GETDESKINFO(pti) ((pti)->pDeskInfo)
|
|
|
|
#define SET_TIME_LAST_READ(pti) ((pti)->pcti->timeLastRead = NtGetTickCount())
|
|
#define GET_TIME_LAST_READ(pti) ((pti)->pcti->timeLastRead)
|
|
|
|
|
|
/*
|
|
* General purpose helper macros
|
|
*/
|
|
#define abs(A) (((A) < 0)? -(A) : (A))
|
|
|
|
#define N_ELEM(a) (sizeof(a)/sizeof(a[0]))
|
|
|
|
|
|
/*
|
|
* General purpose access check macro
|
|
*/
|
|
#define RETURN_IF_ACCESS_DENIED(amGranted, amRequested, r) \
|
|
if (!CheckGrantedAccess((amGranted), (amRequested))) return r
|
|
|
|
/*
|
|
* Lock record structure for tracking locks (debug only)
|
|
*/
|
|
|
|
#define LOCKRECORD_STACK 8
|
|
#define LOCKRECORD_MARKDESTROY IntToPtr( 0xFFFFFFFF )
|
|
|
|
typedef struct _LOCKRECORD {
|
|
PLR plrNext;
|
|
DWORD cLockObj;
|
|
PVOID ppobj;
|
|
PVOID trace[LOCKRECORD_STACK];
|
|
} LOCKRECORD;
|
|
|
|
/*
|
|
* We limit recursion until we have only this much stack left.
|
|
* We have to leave room for kernel interupts.
|
|
*/
|
|
#define KERNEL_STACK_MINIMUM_RESERVE (4*1024)
|
|
|
|
/*
|
|
* And this much of backing store in IA64.
|
|
*/
|
|
#if defined(_IA64_)
|
|
#define KERNEL_BSTORE_MINIMUM_RESERVE (4*1024)
|
|
#define GET_CURRENT_BSTORE() ((ULONG_PTR)PsGetCurrentThreadStackBase() + KERNEL_LARGE_BSTORE_SIZE - __getReg(CV_IA64_RsBSP))
|
|
#endif // _IA64_
|
|
|
|
#if DBG
|
|
#if defined(_IA64_)
|
|
#define GET_USED_BSTORE_SIZE() (__getReg(CV_IA64_RsBSP) - (ULONG_PTR)PsGetCurrentThreadStackBase())
|
|
#define ASSERT_BSTORE() UserAssert(GET_CURRENT_BSTORE() > KERNEL_BSTORE_MINIMUM_RESERVE)
|
|
#else // _IA64_
|
|
#define ASSERT_BSTORE()
|
|
#endif // _IA64_
|
|
|
|
#define ASSERT_STACK() \
|
|
UserAssert(IoGetRemainingStackSize() > KERNEL_STACK_MINIMUM_RESERVE); \
|
|
ASSERT_BSTORE()
|
|
|
|
__inline ULONG_PTR GET_USED_STACK_SIZE(
|
|
VOID)
|
|
{
|
|
ULONG_PTR uLocVer;
|
|
return ((ULONG_PTR)PsGetCurrentThreadStackBase() - (ULONG_PTR)&uLocVer);
|
|
}
|
|
#endif // DBG
|
|
|
|
/*
|
|
* The following is a LOCK structure. This structure is recorded for
|
|
* each threadlock so unlocks can occur at cleanup time.
|
|
*/
|
|
typedef struct _LOCK {
|
|
PTHREADINFO pti;
|
|
PVOID pobj;
|
|
PTL ptl;
|
|
#if DBG
|
|
PVOID pfn; // for debugging purposes only
|
|
int ilNext; // for debugging purposes only
|
|
int iilPrev; // for debugging purposes only
|
|
#endif // DBG
|
|
} LOCK, *PLOCK;
|
|
|
|
#define NEEDSSYNCPAINT(pwnd) TestWF(pwnd, WFSENDERASEBKGND | WFSENDNCPAINT)
|
|
|
|
typedef struct tagCVR // cvr
|
|
{
|
|
WINDOWPOS pos; // MUST be first field of CVR!
|
|
int xClientNew; // New client rectangle
|
|
int yClientNew;
|
|
int cxClientNew;
|
|
int cyClientNew;
|
|
RECT rcBlt;
|
|
int dxBlt; // Distance blt rectangle is moving
|
|
int dyBlt;
|
|
UINT fsRE; // RE_ flags: whether hrgnVisOld is empty or not
|
|
HRGN hrgnVisOld; // Previous visrgn
|
|
PTHREADINFO pti; // The thread this SWP should be processed on
|
|
HRGN hrgnClip; // Window clipping region
|
|
HRGN hrgnInterMonitor; // multimon support
|
|
} CVR, *PCVR;
|
|
|
|
/*
|
|
* CalcValidRects() "Region Empty" flag values
|
|
* A set bit indicates the corresponding region is empty.
|
|
*/
|
|
#define RE_VISNEW 0x0001 // CVR "Region Empty" flag values
|
|
#define RE_VISOLD 0x0002 // A set bit indicates the
|
|
#define RE_VALID 0x0004 // corresponding region is empty.
|
|
#define RE_INVALID 0x0008
|
|
#define RE_SPB 0x0010
|
|
#define RE_VALIDSUM 0x0020
|
|
#define RE_INVALIDSUM 0x0040
|
|
|
|
typedef struct tagSMWP { // smwp
|
|
HEAD head;
|
|
UINT bShellNotify:1; // The acvr list contains shell notify flags
|
|
UINT bHandle:1; // This is an HM object allocation -- See -BeginDeferWindowPos
|
|
/*
|
|
* All fields AFTER ccvr are preserved when reusing the global SMWP structure.
|
|
*/
|
|
int ccvr; // Number of CVRs in the SWMP
|
|
int ccvrAlloc; // Number of actual CVRs allocated in the SMWP
|
|
PCVR acvr; // Pointer to array of CVR structures
|
|
} SMWP, *PSMWP;
|
|
|
|
void DestroySMWP(PSMWP psmwp);
|
|
|
|
/*
|
|
* Clipboard data object definition
|
|
*/
|
|
typedef struct tagCLIPDATA {
|
|
HEAD head;
|
|
DWORD cbData;
|
|
BYTE abData[0];
|
|
} CLIPDATA, *PCLIPDATA;
|
|
|
|
/*
|
|
* Private User Startupinfo
|
|
*/
|
|
typedef struct tagUSERSTARTUPINFO {
|
|
DWORD cb;
|
|
DWORD dwX;
|
|
DWORD dwY;
|
|
DWORD dwXSize;
|
|
DWORD dwYSize;
|
|
DWORD dwFlags;
|
|
WORD wShowWindow;
|
|
WORD cbReserved2;
|
|
} USERSTARTUPINFO, *PUSERSTARTUPINFO;
|
|
|
|
/*
|
|
* TLBLOCK structure for multiple threads locking.
|
|
*/
|
|
#define THREADS_PER_TLBLOCK 16
|
|
|
|
typedef struct tagTLBLOCK {
|
|
struct tagTLBLOCK *ptlBlockPrev;
|
|
struct {
|
|
PTHREADINFO pti;
|
|
TL tlpti;
|
|
DWORD dwFlags;
|
|
#if DBG
|
|
DWORD dwUnlockedCount;
|
|
#endif
|
|
} list[THREADS_PER_TLBLOCK];
|
|
} TLBLOCK, *PTLBLOCK;
|
|
|
|
/*
|
|
* Keyboard File object.
|
|
*/
|
|
typedef struct tagKBDFILE {
|
|
HEAD head;
|
|
struct tagKBDFILE *pkfNext; // next keyboard file
|
|
HANDLE hBase; // base address of data
|
|
PKBDTABLES pKbdTbl; // pointer to kbd layout data.
|
|
ULONG Size; // Size of pKbdTbl
|
|
PKBDNLSTABLES pKbdNlsTbl; // pointer to kbd nls layout data.
|
|
WCHAR awchDllName[32];
|
|
#ifdef LATER
|
|
LANGID langId; // Default language ID of this layout
|
|
#endif
|
|
} KBDFILE, *PKBDFILE;
|
|
|
|
/*
|
|
* Keyboard Layout object.
|
|
*/
|
|
typedef struct tagKL { /* kl */
|
|
HEAD head;
|
|
struct tagKL *pklNext; // next in layout cycle
|
|
struct tagKL *pklPrev; // prev in layout cycle
|
|
DWORD dwKL_Flags; // KL_* flags
|
|
HKL hkl; // (Layout ID | Base Language ID)
|
|
KBDFILE *spkf; // Keyboard Layout File
|
|
KBDFILE *spkfPrimary; // Primary keyboard layout file
|
|
DWORD dwFontSigs; // mask of FS_xxx bits - fonts that layout is good for
|
|
UINT iBaseCharset;// Charset value (Win95 compat) eg: ANSI_CHARSET
|
|
WORD CodePage; // Windows Codepage of kbd layout, eg: 1252, 1250
|
|
WCHAR wchDiacritic;// Dead key saved here until next keystroke
|
|
PIMEINFOEX piiex; // Extended information for IME based layout
|
|
UINT uNumTbl; // number of tables in pKbdTbl
|
|
PKBDFILE *pspkfExtra; // extra layout file in this
|
|
DWORD dwLastKbdType;
|
|
DWORD dwLastKbdSubType;
|
|
DWORD dwKLID; // base keyboard layout ID
|
|
} KL, *PKL;
|
|
|
|
/*
|
|
* Flag values for KL dwFlags
|
|
*/
|
|
#define KL_UNLOADED 0x20000000
|
|
#define KL_RESET 0x40000000
|
|
|
|
|
|
PKL HKLtoPKL(PTHREADINFO pti, HKL hkl);
|
|
|
|
typedef struct tagKBDLANGTOGGLE
|
|
{
|
|
BYTE bVkey;
|
|
BYTE bScan;
|
|
int iBitPosition;
|
|
} KBDLANGTOGGLE;
|
|
|
|
/*
|
|
* These constants are derived from combinations of
|
|
* iBitPosition (refer to the LangToggle array defined
|
|
* in globals.c).
|
|
*/
|
|
|
|
/*
|
|
* This bit is used for both control and alt keys
|
|
*/
|
|
#define KLT_ALT 1
|
|
|
|
/*
|
|
* This bit is used for the left shift key
|
|
*/
|
|
#define KLT_LEFTSHIFT 2
|
|
|
|
/*
|
|
* This combination denotes ctrl/alt and the left shift key
|
|
*/
|
|
#define KLT_ALTLEFTSHIFT 3
|
|
|
|
/*
|
|
* This bit is used for the right shift key
|
|
*/
|
|
#define KLT_RIGHTSHIFT 4
|
|
|
|
/*
|
|
* This combination denotes ctrl/alt and the right shift key
|
|
*/
|
|
#define KLT_ALTRIGHTSHIFT 5
|
|
|
|
/*
|
|
* This combination denotes ctrl/alt and both the shift keys
|
|
*/
|
|
#define KLT_ALTBOTHSHIFTS 7
|
|
|
|
/*
|
|
* This value is used to mark invalid toggle key sequence
|
|
*/
|
|
#define KLT_NONE 8
|
|
|
|
|
|
/*
|
|
* Key Event (KE) structure
|
|
* Stores a Virtual Key event
|
|
*/
|
|
typedef struct tagKE {
|
|
union {
|
|
BYTE bScanCode; // Virtual Scan Code (Set 1)
|
|
WCHAR wchInjected; // Unicode char from SendInput()
|
|
};
|
|
USHORT usFlaggedVk; // Vk | Flags
|
|
DWORD dwTime; // time in milliseconds
|
|
#ifdef GENERIC_INPUT
|
|
HANDLE hDevice;
|
|
KEYBOARD_INPUT_DATA data;
|
|
#endif
|
|
} KE, *PKE;
|
|
|
|
/*
|
|
* Misc. keyboard stuff moved from oak/inc/kbd.h
|
|
*/
|
|
typedef BOOL (* KEPROC)(PKE pKe);
|
|
typedef BOOL (* NLSKEPROC)(PKE pKe, ULONG_PTR dwExtraInfo, ULONG dwParam);
|
|
typedef BOOL (* NLSVKFPROC)(PVK_F pVkToF, PKE pKe, ULONG_PTR dwExtraInfo);
|
|
|
|
/*
|
|
* OEM-specific special processing (keystroke simulators and filters)
|
|
*/
|
|
extern KEPROC aKEProcOEM[];
|
|
|
|
|
|
/*
|
|
* Key message lParam bits
|
|
*/
|
|
#define EXTENDED_BIT 0x01000000
|
|
#define DONTCARE_BIT 0x02000000
|
|
#define FAKE_KEYSTROKE 0x02000000
|
|
#define ALTNUMPAD_BIT 0x04000000 // copied from windows\inc\wincon.w
|
|
|
|
/*
|
|
* For handy diacritics
|
|
*/
|
|
#define IDS_FROM_SCANCODE(prefix, base) \
|
|
(0xc000 + ((0x ## prefix) >= 0xE0 ? 0x100 : 0) + (0x ## base))
|
|
|
|
//
|
|
// NLS Keyboard functions
|
|
//
|
|
VOID NlsKbdInitializePerSystem(VOID);
|
|
VOID NlsKbdSendIMENotification(DWORD dwImeOpen, DWORD dwImeConversion);
|
|
|
|
/*
|
|
* Desktop flags.
|
|
*/
|
|
#define DF_ACTIVEONDESTROY 0x00000001
|
|
#define DF_ZOMBIE 0x00000002
|
|
#define DF_NOTRITUNLOCK 0x00000004
|
|
#define DF_QUITUNLOCK 0x00000008
|
|
#define DF_USERMODE 0x00000010
|
|
#define DF_SKIPSWITCHDESKTOP 0x00000020
|
|
#define DF_DTNONEWDESKTOP 0x00000040
|
|
#define DF_REDIRECTED 0x00000080
|
|
#define DF_DESKCREATED 0x00000100
|
|
#define DF_NEWDISPLAYSETTINGS 0x00000200
|
|
#define DF_TRACKMOUSEHOVER 0x00000400
|
|
#define DF_TRACKMOUSELEAVE 0x00000800
|
|
#define DF_TOOLTIPACTIVE 0x00001000
|
|
#define DF_TOOLTIPSHOWING 0x00002000
|
|
#define DF_HOTTRACKING 0x00004000
|
|
#define DF_DESTROYED 0x00008000
|
|
#define DF_DESKWNDDESTROYED 0x00010000
|
|
#define DF_DYING 0x00020000
|
|
|
|
#define DF_TOOLTIP (DF_TOOLTIPACTIVE | DF_TOOLTIPSHOWING)
|
|
#define DF_TRACKMOUSEEVENT (DF_TRACKMOUSELEAVE | DF_TRACKMOUSEHOVER)
|
|
#define DF_MOUSEMOVETRK (DF_HOTTRACKING | DF_TOOLTIPACTIVE | DF_TRACKMOUSELEAVE | DF_TRACKMOUSEHOVER)
|
|
|
|
#define CAPTIONTOOLTIPLEN 100
|
|
|
|
/*
|
|
* Used to identify desktops uniquely for GDI
|
|
*/
|
|
|
|
#define GW_DESKTOP_ID 1
|
|
|
|
#define DESKTOP_ALLOC_TRACE_SIZE 6
|
|
|
|
#if DBG
|
|
typedef struct tagDbgAllocHead {
|
|
DWORD mark;
|
|
DWORD tag;
|
|
PDESKTOP pdesk;
|
|
SIZE_T size; // the size of the allocation (doesn't include
|
|
// this structure
|
|
|
|
struct tagDbgAllocHead* pPrev; // pointer to the previous allocation of this tag
|
|
struct tagDbgAllocHead* pNext; // pointer to the next allocation of this tag
|
|
|
|
#ifdef DESKTOP_ALLOC_TRACE
|
|
PVOID trace[DESKTOP_ALLOC_TRACE_SIZE];
|
|
#endif // DESKTOP_ALLOC_TRACE
|
|
|
|
} DbgAllocHead, *PDbgAllocHead;
|
|
#endif // DBG
|
|
|
|
#define DTAG_CLASS 0x0001
|
|
#define DTAG_DESKTOPINFO 0x0002
|
|
#define DTAG_CLIENTTHREADINFO 0x0003
|
|
#define DTAG_TEXT 0x0004
|
|
#define DTAG_HANDTABL 0x0005
|
|
#define DTAG_SBINFO 0x0006
|
|
#define DTAG_MENUITEM 0x0007
|
|
#define DTAG_MENUTEXT 0x0008
|
|
#define DTAG_IMETEXT 0x0009
|
|
#define DTAG_PROPLIST 0x000A
|
|
|
|
/*
|
|
* Desktop Structure.
|
|
*
|
|
* This structure is only viewable from the kernel. If any desktop
|
|
* information is needed in the client, then they should reference off
|
|
* the pDeskInfo field (i.e. pti->pDeskInfo).
|
|
*/
|
|
typedef struct tagDESKTOP {
|
|
|
|
DWORD dwSessionId; // Terminal Server SessionId. This has to be first field in the structure
|
|
PDESKTOPINFO pDeskInfo; // Desktop information
|
|
PDISPLAYINFO pDispInfo; //
|
|
|
|
PDESKTOP rpdeskNext; // Next desktop in list
|
|
PWINDOWSTATION rpwinstaParent; // Windowstation owner
|
|
|
|
DWORD dwDTFlags; // Desktop flags
|
|
ULONG dwDesktopId; // Needed by GDI to tag display devices
|
|
|
|
PMENU spmenuSys; //
|
|
PMENU spmenuDialogSys; //
|
|
PMENU spmenuHScroll;
|
|
PMENU spmenuVScroll;
|
|
PWND spwndForeground; //
|
|
PWND spwndTray;
|
|
PWND spwndMessage;
|
|
PWND spwndTooltip;
|
|
|
|
HANDLE hsectionDesktop; //
|
|
PWIN32HEAP pheapDesktop; //
|
|
DWORD dwConsoleThreadId; //
|
|
DWORD dwConsoleIMEThreadId;
|
|
CONSOLE_CARET_INFO cciConsole;
|
|
LIST_ENTRY PtiList; //
|
|
|
|
PWND spwndTrack; // xxxTrackMouseMove data
|
|
int htEx;
|
|
RECT rcMouseHover;
|
|
DWORD dwMouseHoverTime;
|
|
|
|
|
|
#ifdef LOGDESKTOPLOCKS
|
|
int nLockCount;
|
|
int nLogMax;
|
|
int nLogCrt;
|
|
PLogD pLog;
|
|
#endif // LOGDESKTOPLOCKS
|
|
|
|
} DESKTOP;
|
|
|
|
typedef struct tagDESKWND {
|
|
WND wnd;
|
|
DWORD idProcess;
|
|
DWORD idThread;
|
|
} DESKWND, *PDESKWND;
|
|
|
|
PVOID DesktopAlloc(PDESKTOP pdesk, UINT uSize,DWORD tag);
|
|
|
|
#define DesktopAllocAlways(pdesk, uSize, tag) \
|
|
Win32HeapAlloc(pdesk->pheapDesktop, uSize, tag, 0)
|
|
|
|
#define DesktopFree(pdesk, p) Win32HeapFree(pdesk->pheapDesktop, p)
|
|
|
|
/*
|
|
* Windowstation structure
|
|
*/
|
|
#define WSF_SWITCHLOCK 0x0001
|
|
#define WSF_OPENLOCK 0x0002
|
|
#define WSF_NOIO 0x0004
|
|
#define WSF_SHUTDOWN 0x0008
|
|
#define WSF_DYING 0x0010
|
|
#define WSF_REALSHUTDOWN 0x0020
|
|
#define WSF_CLIPBOARDCHANGED 0x0040
|
|
#define WSF_INDELAYEDRENDERING 0x0080
|
|
|
|
typedef struct tagWINDOWSTATION {
|
|
/*
|
|
* TS SessionId. This has to be the first field in the structure.
|
|
*/
|
|
DWORD dwSessionId;
|
|
PWINDOWSTATION rpwinstaNext;
|
|
PDESKTOP rpdeskList;
|
|
|
|
PTERMINAL pTerm;
|
|
|
|
DWORD dwWSF_Flags;
|
|
struct tagKL *spklList;
|
|
|
|
/*
|
|
* Clipboard variables.
|
|
*/
|
|
PTHREADINFO ptiClipLock;
|
|
PTHREADINFO ptiDrawingClipboard;
|
|
PWND spwndClipOpen;
|
|
PWND spwndClipViewer;
|
|
PWND spwndClipOwner;
|
|
struct tagCLIP *pClipBase;
|
|
int cNumClipFormats;
|
|
UINT iClipSerialNumber;
|
|
UINT iClipSequenceNumber;
|
|
|
|
/*
|
|
* Global Atom table.
|
|
*/
|
|
PVOID pGlobalAtomTable;
|
|
|
|
LUID luidEndSession;
|
|
LUID luidUser;
|
|
PSID psidUser;
|
|
|
|
/*
|
|
* Pointer to the currently active desktop for the window station.
|
|
*/
|
|
#if DBG
|
|
PDESKTOP pdeskCurrent;
|
|
#endif
|
|
} WINDOWSTATION;
|
|
|
|
typedef struct tagCAPTIONCACHE {
|
|
PCURSOR spcursor;
|
|
POEMBITMAPINFO pOem;
|
|
#if DBG
|
|
HICON hico;
|
|
#endif
|
|
} CAPTIONCACHE;
|
|
|
|
/*
|
|
* Configurable icon and cursor stuff
|
|
*/
|
|
typedef struct tagSYSCFGICO
|
|
{
|
|
WORD Id; // configurable id (OIC_ or OCR_ value)
|
|
WORD StrId; // String ID for registry key name
|
|
PCURSOR spcur; // perminant cursor/icon pointer
|
|
} SYSCFGICO;
|
|
|
|
#define SYSICO(name) (gasysico[OIC_##name##_DEFAULT - OIC_FIRST_DEFAULT].spcur)
|
|
#define SYSCUR(name) (gasyscur[OCR_##name##_DEFAULT - OCR_FIRST_DEFAULT].spcur)
|
|
|
|
|
|
/*
|
|
* Accelerator Table structure
|
|
*/
|
|
typedef struct tagACCELTABLE {
|
|
PROCOBJHEAD head;
|
|
UINT cAccel;
|
|
ACCEL accel[1];
|
|
} ACCELTABLE, *LPACCELTABLE;
|
|
|
|
/*
|
|
* Besides the desktop window used by the current thread, we also
|
|
* need to get the desktop window of a window and the input desktop
|
|
* window.
|
|
*/
|
|
#define PWNDDESKTOP(p) ((p)->head.rpdesk->pDeskInfo->spwnd)
|
|
#define PWNDMESSAGE(p) ((p)->head.rpdesk->spwndMessage)
|
|
#define PWNDTOOLTIP(p) ((p)->head.rpdesk->spwndTooltip)
|
|
|
|
/*
|
|
* During window destruction, even a locked window can have a
|
|
* NULL parent so use this macro where a NULL parent is a problem.
|
|
*/
|
|
#define PWNDPARENT(p) (p->spwndParent ? p->spwndParent : PWNDDESKTOP(p))
|
|
|
|
#define ISAMENU(pwwnd) \
|
|
(GETFNID(pwnd) == FNID_MENU)
|
|
|
|
|
|
/* NEW MENU STUFF */
|
|
typedef struct tagPOPUPMENU
|
|
{
|
|
|
|
DWORD fIsMenuBar:1; /* This is a hacked struct which refers to the
|
|
* menu bar associated with a app. Only true if
|
|
* in the root ppopupMenuStruct.
|
|
*/
|
|
DWORD fHasMenuBar:1; /* This popup is part of a series which has a
|
|
* menu bar (either a sys menu or top level menu
|
|
* bar)
|
|
*/
|
|
DWORD fIsSysMenu:1; /* The system menu is here. */
|
|
DWORD fIsTrackPopup:1; /* Is TrackPopup popup menu */
|
|
DWORD fDroppedLeft:1;
|
|
DWORD fHierarchyDropped:1;/* If true, a submenu has been dropped off this popup */
|
|
DWORD fRightButton:1; /* Allow right button in menu */
|
|
DWORD fToggle:1; /* If TRUE, button up cancels the popup */
|
|
DWORD fSynchronous:1; /* For synchronous return value of cmd chosen */
|
|
DWORD fFirstClick:1; /* Keep track if this was the first click on the
|
|
* top level menu bar item. If the user down/up
|
|
* clicks on a top level menu bar item twice, we
|
|
* want to cancel menu mode.
|
|
*/
|
|
DWORD fDropNextPopup:1; /* Should we drop hierarchy of next menu item w/ popup? */
|
|
DWORD fNoNotify:1; /* Don't send WM_ msgs to owner, except WM_COMMAND */
|
|
DWORD fAboutToHide:1; // Same purpose as fHideTimer?
|
|
DWORD fShowTimer:1; // TRUE if the IDSYS_MNSHOW timer is set
|
|
DWORD fHideTimer:1; // TRUE if the IDSYS_MNHIDE timer is set
|
|
|
|
DWORD fDestroyed:1; /* Set when the owner menu window has been destroyed
|
|
* so the popup can be freed once it's no longer needed
|
|
* Also set in root popupmenu when menu mode must end
|
|
*/
|
|
|
|
DWORD fDelayedFree:1; /* Avoid freeing the popup when the owner menu
|
|
* window is destroyed.
|
|
* If set, it must be a root popupmenu or must
|
|
* be linked in ppmDelayedFree
|
|
* This is eventually set for all hierarchical popups
|
|
*/
|
|
|
|
DWORD fFlushDelayedFree:1; /* Used in root popupmenus only.
|
|
* Set when a hierarchical popup marked as fDelayedFree
|
|
* has been destroyed.
|
|
*/
|
|
|
|
|
|
DWORD fFreed:1; /* Popup has been freed. Used for debug only */
|
|
|
|
DWORD fInCancel:1; /* Popup has been passed to xxxMNCancel */
|
|
|
|
DWORD fTrackMouseEvent:1; /* TrackMouseEvent has been called */
|
|
DWORD fSendUninit:1; /* Send WM_UNINITMENUPOPUP */
|
|
DWORD fRtoL:1; /* For going backwards with the keys */
|
|
DWORD iDropDir:5; /* Animation direction */
|
|
|
|
|
|
PWND spwndNotify;
|
|
/* Window who gets the notification messages. If this
|
|
* is a window with a menu bar, then this is the same
|
|
* as hwndPopupMenu.
|
|
*/
|
|
PWND spwndPopupMenu;
|
|
/* The window associated with this ppopupMenu struct.
|
|
* If this is a top level menubar, then hwndPopupMenu
|
|
* is the window the menu bar. ie. it isn't really a
|
|
* popup menu window.
|
|
*/
|
|
PWND spwndNextPopup;
|
|
/* The next popup in the hierarchy. Null if the last
|
|
* in chain
|
|
*/
|
|
PWND spwndPrevPopup;
|
|
/* The previous popup in the hierarchy. NULL if at top
|
|
*/
|
|
PMENU spmenu;/* The PMENU displayed in this window
|
|
*/
|
|
PMENU spmenuAlternate;
|
|
/* Alternate PMENU. If the system menu is displayed,
|
|
* and a menubar menu exists, this will contain the
|
|
* menubar menu. If menubar menu is displayed, this
|
|
* will contain the system menu. Use only on top level
|
|
* ppopupMenu structs so that we can handle windows
|
|
* with both a system menu and a menu bar menu. Only
|
|
* used in the root ppopupMenuStruct.
|
|
*/
|
|
|
|
PWND spwndActivePopup; /* This is the popup the mouse/"keyboard focus" is on */
|
|
|
|
PPOPUPMENU ppopupmenuRoot;
|
|
|
|
PPOPUPMENU ppmDelayedFree; /* List of hierarchical popups marked
|
|
* as fDelayedFree.
|
|
*/
|
|
|
|
UINT posSelectedItem; /* Position of the selected item in this menu */
|
|
UINT posDropped;
|
|
|
|
} POPUPMENU;
|
|
|
|
typedef struct tagMENUWND {
|
|
WND wnd;
|
|
PPOPUPMENU ppopupmenu;
|
|
} MENUWND, *PMENUWND;
|
|
|
|
/*
|
|
* CheckPoint structure
|
|
*/
|
|
typedef struct tagCHECKPOINT {
|
|
RECT rcNormal;
|
|
POINT ptMin;
|
|
POINT ptMax;
|
|
DWORD fDragged:1;
|
|
DWORD fWasMaximizedBeforeMinimized:1;
|
|
DWORD fWasMinimizedBeforeMaximized:1;
|
|
DWORD fMinInitialized:1;
|
|
DWORD fMaxInitialized:1;
|
|
} CHECKPOINT, *PCHECKPOINT;
|
|
|
|
typedef struct tagCLIP {
|
|
UINT fmt;
|
|
HANDLE hData;
|
|
BOOL fGlobalHandle;
|
|
} CLIP, *PCLIP;
|
|
|
|
/*
|
|
* DDEML instance structure
|
|
*/
|
|
typedef struct tagSVR_INSTANCE_INFO {
|
|
THROBJHEAD head;
|
|
struct tagSVR_INSTANCE_INFO *next;
|
|
struct tagSVR_INSTANCE_INFO *nextInThisThread;
|
|
DWORD afCmd;
|
|
PWND spwndEvent;
|
|
PVOID pcii;
|
|
} SVR_INSTANCE_INFO, *PSVR_INSTANCE_INFO;
|
|
|
|
typedef struct tagPUBOBJ {
|
|
struct tagPUBOBJ *next;
|
|
HANDLE hObj;
|
|
int count;
|
|
W32PID pid;
|
|
} PUBOBJ, *PPUBOBJ;
|
|
|
|
/*
|
|
* Defines for Menu focus
|
|
*/
|
|
#define FREEHOLD 0
|
|
#define MOUSEHOLD -1 /* Mouse button held down and dragging */
|
|
#define KEYBDHOLD 1
|
|
|
|
/*
|
|
* Structure definition for messages as they exist on a Q. Same as MSG
|
|
* structure except for the link-pointer and flags at the end.
|
|
*/
|
|
typedef struct tagQMSG {
|
|
PQMSG pqmsgNext;
|
|
PQMSG pqmsgPrev;
|
|
MSG msg;
|
|
LONG_PTR ExtraInfo;
|
|
DWORD dwQEvent;
|
|
PTHREADINFO pti;
|
|
} QMSG;
|
|
|
|
/*
|
|
* dwQEvent values for QMSG structure.
|
|
*/
|
|
#define QEVENT_SHOWWINDOW 0x0001
|
|
#define QEVENT_CANCELMODE 0x0002
|
|
#define QEVENT_SETWINDOWPOS 0x0003
|
|
#define QEVENT_UPDATEKEYSTATE 0x0004
|
|
#define QEVENT_DEACTIVATE 0x0005
|
|
#define QEVENT_ACTIVATE 0x0006
|
|
#define QEVENT_POSTMESSAGE 0x0007
|
|
#define QEVENT_DESTROYWINDOW 0x0008
|
|
#define QEVENT_ASYNCSENDMSG 0x0009
|
|
#define QEVENT_HUNGTHREAD 0x000A
|
|
#define QEVENT_CANCELMOUSEMOVETRK 0x000B
|
|
#define QEVENT_NOTIFYWINEVENT 0x000C
|
|
#define QEVENT_RITACCESSIBILITY 0x000D
|
|
#define QEVENT_RITSOUND 0x000E
|
|
#define QEVENT_APPCOMMAND 0x000F
|
|
|
|
#define RITSOUND_UPSIREN 0x0000
|
|
#define RITSOUND_DOWNSIREN 0x0001
|
|
#define RITSOUND_LOWBEEP 0x0002
|
|
#define RITSOUND_HIGHBEEP 0x0003
|
|
#define RITSOUND_KEYCLICK 0x0004
|
|
#define RITSOUND_DOBEEP 0x0005
|
|
|
|
/*
|
|
* xxxProcessEventMessage flags
|
|
*/
|
|
#define PEM_ACTIVATE_RESTORE 0x0001
|
|
#define PEM_ACTIVATE_NOZORDER 0x0002
|
|
|
|
typedef struct _MOVESIZEDATA {
|
|
PWND spwnd;
|
|
RECT rcDrag;
|
|
RECT rcDragCursor;
|
|
RECT rcParent;
|
|
POINT ptMinTrack;
|
|
POINT ptMaxTrack;
|
|
RECT rcWindow;
|
|
int dxMouse;
|
|
int dyMouse;
|
|
int cmd;
|
|
int impx;
|
|
int impy;
|
|
POINT ptRestore;
|
|
UINT fInitSize : 1; // should we initialize cursor pos
|
|
UINT fmsKbd : 1; // who knows
|
|
UINT fLockWindowUpdate : 1; // whether screen was locked ok
|
|
UINT fTrackCancelled : 1; // Set if tracking ended by other thread.
|
|
UINT fForeground : 1; // whether the tracking thread is foreground
|
|
// and if we should draw the drag-rect
|
|
UINT fDragFullWindows : 1;
|
|
UINT fOffScreen : 1;
|
|
} MOVESIZEDATA, *PMOVESIZEDATA;
|
|
|
|
/*
|
|
* DrawDragRect styles.
|
|
*/
|
|
#define DDR_START 0 // - start drag.
|
|
#define DDR_ENDACCEPT 1 // - end and accept
|
|
#define DDR_ENDCANCEL 2 // - end and cancel.
|
|
|
|
|
|
/*
|
|
* Pseudo Event stuff. (fManualReset := TRUE, fInitState := FALSE)
|
|
*/
|
|
|
|
DWORD WaitOnPseudoEvent(HANDLE *phE, DWORD dwMilliseconds);
|
|
|
|
#define PSEUDO_EVENT_ON ((HANDLE)IntToPtr( 0xFFFFFFFF ))
|
|
#define PSEUDO_EVENT_OFF ((HANDLE)IntToPtr( 0x00000000 ))
|
|
#define INIT_PSEUDO_EVENT(ph) *ph = PSEUDO_EVENT_OFF;
|
|
|
|
#define SET_PSEUDO_EVENT(phE) \
|
|
CheckCritIn(); \
|
|
if (*(phE) == PSEUDO_EVENT_OFF) *(phE) = PSEUDO_EVENT_ON; \
|
|
else if (*(phE) != PSEUDO_EVENT_ON) { \
|
|
KeSetEvent(*(phE), EVENT_INCREMENT, FALSE); \
|
|
ObDereferenceObject(*(phE)); \
|
|
*(phE) = PSEUDO_EVENT_ON; \
|
|
}
|
|
|
|
#define RESET_PSEUDO_EVENT(phE) \
|
|
CheckCritIn(); \
|
|
if (*(phE) == PSEUDO_EVENT_ON) *(phE) = PSEUDO_EVENT_OFF; \
|
|
else if (*(phE) != PSEUDO_EVENT_OFF) { \
|
|
KeClearEvent(*(phE)); \
|
|
}
|
|
|
|
#define CLOSE_PSEUDO_EVENT(phE) \
|
|
CheckCritIn(); \
|
|
if (*(phE) == PSEUDO_EVENT_ON) *(phE) = PSEUDO_EVENT_OFF; \
|
|
else if (*(phE) != PSEUDO_EVENT_OFF) { \
|
|
KeSetEvent(*(phE), EVENT_INCREMENT, FALSE); \
|
|
ObDereferenceObject(*(phE)); \
|
|
*(phE) = PSEUDO_EVENT_OFF; \
|
|
}
|
|
|
|
typedef struct tagMLIST {
|
|
PQMSG pqmsgRead; // next message to be read. This is a FIFO queue
|
|
PQMSG pqmsgWriteLast; // last message added to the queue. Used mainly for coalescing
|
|
DWORD cMsgs; // Count of messages. Used for optimizations and to enforce a max.
|
|
} MLIST, *PMLIST;
|
|
|
|
/*
|
|
* Message Queue structure.
|
|
*
|
|
* Note, if you need to add a WORD sized value,
|
|
* do so after xbtnDblClk.
|
|
*/
|
|
typedef struct tagQ {
|
|
MLIST mlInput; // raw mouse and key message list.
|
|
|
|
PTHREADINFO ptiSysLock; // Thread currently allowed to process input
|
|
ULONG_PTR idSysLock; // Last message removed or to be removed before unlocking
|
|
ULONG_PTR idSysPeek; // Last message peeked
|
|
|
|
PTHREADINFO ptiMouse; // Last thread to get mouse msg.
|
|
PTHREADINFO ptiKeyboard;
|
|
|
|
PWND spwndCapture;
|
|
PWND spwndFocus;
|
|
PWND spwndActive;
|
|
PWND spwndActivePrev;
|
|
|
|
UINT codeCapture; // type of captue. See *_CAP* defines in this file
|
|
UINT msgDblClk; // last mouse down message removed
|
|
WORD xbtnDblClk; // last xbutton down
|
|
DWORD timeDblClk; // max time for next button down to be taken as double click
|
|
HWND hwndDblClk; // window that got last button down
|
|
POINT ptDblClk; // last button down position. See SYSMET(C?DOUBLECLK)
|
|
|
|
BYTE afKeyRecentDown[CBKEYSTATERECENTDOWN];
|
|
BYTE afKeyState[CBKEYSTATE];
|
|
|
|
CARET caret;
|
|
|
|
PCURSOR spcurCurrent;
|
|
int iCursorLevel; // show/hide count. < 0 if the cursor is not visible
|
|
|
|
DWORD QF_flags; // QF_ flags go here
|
|
|
|
USHORT cThreads; // Count of threads using this queue
|
|
USHORT cLockCount; // Count of threads that don't want this queue freed
|
|
|
|
UINT msgJournal; // See SetJournalTimer. Journal message to be delivered when timer goes off
|
|
LONG_PTR ExtraInfo; // Extra info for last qmsg read. See GetMessageExtraInfo
|
|
} Q;
|
|
|
|
/*
|
|
* Used for zzzAttachThreadInput()
|
|
*/
|
|
typedef struct tagATTACHINFO {
|
|
struct tagATTACHINFO *paiNext;
|
|
PTHREADINFO pti1;
|
|
PTHREADINFO pti2;
|
|
} ATTACHINFO, *PATTACHINFO;
|
|
|
|
#define POLL_EVENT_CNT 5
|
|
|
|
#define IEV_IDLE 0
|
|
#define IEV_INPUT 1
|
|
#define IEV_EXEC 2
|
|
#define IEV_TASK 3
|
|
#define IEV_WOWEXEC 4
|
|
|
|
|
|
typedef struct tagWOWTHREADINFO {
|
|
struct tagWOWTHREADINFO *pwtiNext;
|
|
DWORD idTask; // WOW task id
|
|
ULONG_PTR idWaitObject; // pseudo handle returned to parent
|
|
DWORD idParentProcess; // process that called CreateProcess
|
|
PKEVENT pIdleEvent; // event that WaitForInputIdle will wait on
|
|
} WOWTHREADINFO, *PWOWTHREADINFO;
|
|
|
|
/*
|
|
* Task Data Block structure.
|
|
*/
|
|
typedef struct tagTDB {
|
|
PTDB ptdbNext;
|
|
int nEvents;
|
|
int nPriority;
|
|
PTHREADINFO pti;
|
|
PWOWTHREADINFO pwti; // per thread info for shared Wow
|
|
WORD hTaskWow; // Wow cookie to find apps during shutdown
|
|
WORD TDB_Flags; // bit 0 means setup app
|
|
} TDB;
|
|
|
|
#define TDBF_SETUP 1
|
|
|
|
|
|
/*
|
|
* Hack message for shell to tell them a setup app is exiting.
|
|
* This message is defined in \nt\private\shell\inc, but I really
|
|
* don't want to introduce that dependency in the build. DavidDS
|
|
* has put a check in that file to make sure that the value does not
|
|
* change and refers to this usage. FritzS
|
|
*/
|
|
#define DTM_SETUPAPPRAN (WM_USER+90)
|
|
|
|
/*
|
|
* Menu animation GDI objects.
|
|
*/
|
|
typedef struct tagMENUANIDC
|
|
{
|
|
HDC hdcAni; // Scratch dc for animation
|
|
} MENUANIDC;
|
|
|
|
/*
|
|
* Menu Control Structure
|
|
*/
|
|
typedef struct tagMENUSTATE {
|
|
PPOPUPMENU pGlobalPopupMenu;
|
|
DWORD fMenuStarted : 1;
|
|
DWORD fIsSysMenu : 1;
|
|
DWORD fInsideMenuLoop : 1;
|
|
DWORD fButtonDown:1;
|
|
DWORD fInEndMenu:1;
|
|
DWORD fUnderline:1; /* Shorcut key underlines are shown */
|
|
DWORD fButtonAlwaysDown:1; /* The mouse has always been down since the menu started */
|
|
DWORD fDragging:1; /* Dragging (in DoDragDrop) or about to */
|
|
DWORD fModelessMenu:1; /* No modal loop */
|
|
DWORD fInCallHandleMenuMessages:1;/* processing a msg from CallHandleMM */
|
|
DWORD fDragAndDrop:1; /* This menu can do drag and drop */
|
|
DWORD fAutoDismiss:1; /* This menu goes away on its own if mouse is off for certain time */
|
|
DWORD fAboutToAutoDismiss:1; /* Autodismiss will take place when timer goes off */
|
|
DWORD fIgnoreButtonUp:1; /* Eat next button up, i.e, cancel dragging */
|
|
DWORD fMouseOffMenu:1; /* Mouse is off the menu - modeless menus only */
|
|
DWORD fInDoDragDrop:1; /* in a WM_MENUDODRAGDROP callback */
|
|
DWORD fActiveNoForeground:1; /* A menu window is active but we're not in the foreground */
|
|
DWORD fNotifyByPos:1; /* Use WM_MENUCOMMAND */
|
|
DWORD fSetCapture:1; /* True if the menu mode set capture */
|
|
DWORD iAniDropDir:5; /* direction of animation */
|
|
|
|
POINT ptMouseLast;
|
|
int mnFocus;
|
|
int cmdLast;
|
|
PTHREADINFO ptiMenuStateOwner;
|
|
|
|
DWORD dwLockCount;
|
|
|
|
struct tagMENUSTATE *pmnsPrev; /* Previous menustate for nested/context menus */
|
|
|
|
POINT ptButtonDown; /* Mouse down position (begin drag position) */
|
|
ULONG_PTR uButtonDownHitArea; /* Return from xxxMNFindWindowFromPoint on button down */
|
|
UINT uButtonDownIndex; /* Index of the item being dragged */
|
|
|
|
int vkButtonDown; /* Mouse button being dragged */
|
|
|
|
ULONG_PTR uDraggingHitArea; /* Last hit area while InDoDragDrop */
|
|
UINT uDraggingIndex; /* Last index */
|
|
UINT uDraggingFlags; /* Gap flags */
|
|
|
|
HDC hdcWndAni; // window DC while animating
|
|
DWORD dwAniStartTime; // starting time of animation
|
|
int ixAni; // current x-step in animation
|
|
int iyAni; // current y-step in animation
|
|
int cxAni; // total x in animation
|
|
int cyAni; // total y in animation
|
|
HBITMAP hbmAni; // Scratch bmp for animation.
|
|
|
|
/*
|
|
* Important: The following structure must be the last
|
|
* thing in tagMENUSTATE. MNAllocMenuState doesn't NULL out
|
|
* this structure
|
|
*/
|
|
MENUANIDC;
|
|
|
|
} MENUSTATE, *PMENUSTATE;
|
|
|
|
typedef struct tagLASTINPUT { /* linp */
|
|
DWORD timeLastInputMessage;
|
|
DWORD dwFlags;
|
|
PTHREADINFO ptiLastWoken; /* Last thread woken by key or click */
|
|
/* It can be NULL */
|
|
POINT ptLastClick; /* point of the last mouse click */
|
|
} LASTINPUT, PLASTINPUT;
|
|
|
|
#define LINP_KEYBOARD 0x00000001
|
|
#define LINP_SCREENSAVER 0x00000002
|
|
#define LINP_LOWPOWER 0x00000004
|
|
#define LINP_POWEROFF 0x00000008
|
|
#define LINP_JOURNALLING 0x00000010
|
|
#define LINP_INPUTSOURCES (LINP_KEYBOARD | LINP_JOURNALLING)
|
|
#define LINP_POWERTIMEOUTS (LINP_LOWPOWER | LINP_POWEROFF)
|
|
#define LINP_INPUTTIMEOUTS (LINP_SCREENSAVER | LINP_LOWPOWER | LINP_POWEROFF)
|
|
|
|
/*
|
|
* Menu data to be passed to xxxRealDrawMenuItem from xxxDrawState
|
|
*/
|
|
typedef struct {
|
|
PMENU pMenu;
|
|
PITEM pItem;
|
|
} GRAYMENU, *PGRAYMENU;
|
|
|
|
#define IS_THREAD_RESTRICTED(pti, r) \
|
|
((pti->TIF_flags & TIF_RESTRICTED) ? \
|
|
(pti->ppi->pW32Job->restrictions & (r)) : \
|
|
FALSE)
|
|
|
|
#define IS_CURRENT_THREAD_RESTRICTED(r) \
|
|
((PtiCurrent()->TIF_flags & TIF_RESTRICTED) ? \
|
|
(PtiCurrent()->ppi->pW32Job->restrictions & (r)) : \
|
|
FALSE)
|
|
|
|
/*
|
|
* These types are needed before they are fully defined.
|
|
*/
|
|
typedef struct tagSMS * KPTR_MODIFIER PSMS;
|
|
|
|
/*
|
|
* Make sure this structure matches up with W32THREAD, since they're
|
|
* really the same thing.
|
|
*/
|
|
|
|
/*
|
|
* NOTE -- this structure has been sorted (roughly) in order of use
|
|
* of the fields. The x86 code set allows cheaper access to fields
|
|
* that are in the first 0x80 bytes of a structure. Please attempt
|
|
* to ensure that frequently-used fields are below this boundary.
|
|
* FritzS
|
|
*/
|
|
|
|
typedef struct tagTHREADINFO {
|
|
W32THREAD;
|
|
|
|
//***************************************** begin: USER specific fields
|
|
|
|
PTL ptl; // Listhead for thread lock list
|
|
|
|
PPROCESSINFO ppi; // process info struct for this thread
|
|
|
|
PQ pq; // keyboard and mouse input queue
|
|
|
|
PKL spklActive; // active keyboard layout for this thread
|
|
|
|
PCLIENTTHREADINFO pcti; // Info that must be visible from client
|
|
|
|
PDESKTOP rpdesk;
|
|
PDESKTOPINFO pDeskInfo; // Desktop info visible to client
|
|
ULONG_PTR ulClientDelta; // Desktop heap client delta
|
|
PCLIENTINFO pClientInfo; // Client info stored in TEB
|
|
|
|
DWORD TIF_flags; // TIF_ flags go here.
|
|
|
|
PUNICODE_STRING pstrAppName; // Application module name.
|
|
|
|
PSMS psmsSent; // Most recent SMS this thread has sent
|
|
PSMS psmsCurrent; // Received SMS this thread is currently processing
|
|
PSMS psmsReceiveList; // SMSs to be processed
|
|
|
|
LONG timeLast; // Time and ID of last message
|
|
ULONG_PTR idLast;
|
|
|
|
int exitCode;
|
|
|
|
HDESK hdesk; // Desktop handle
|
|
int cPaintsReady;
|
|
UINT cTimersReady;
|
|
|
|
PMENUSTATE pMenuState;
|
|
|
|
union {
|
|
PTDB ptdb; // Win16Task Schedule data for WOW thread
|
|
PWINDOWSTATION pwinsta; // Window station for SYSTEM thread
|
|
};
|
|
|
|
PSVR_INSTANCE_INFO psiiList; // thread DDEML instance list
|
|
DWORD dwExpWinVer;
|
|
DWORD dwCompatFlags; // The Win 3.1 Compat flags
|
|
DWORD dwCompatFlags2; // new DWORD to extend compat flags for NT5+ features
|
|
|
|
PQ pqAttach; // calculation variabled used in
|
|
// zzzAttachThreadInput()
|
|
|
|
PTHREADINFO ptiSibling; // pointer to sibling thread info
|
|
|
|
PMOVESIZEDATA pmsd;
|
|
|
|
DWORD fsHooks; // WHF_ Flags for which hooks are installed
|
|
PHOOK sphkCurrent; // Hook this thread is currently processing
|
|
|
|
PSBTRACK pSBTrack;
|
|
|
|
HANDLE hEventQueueClient;
|
|
PKEVENT pEventQueueServer;
|
|
LIST_ENTRY PtiLink; // Link to other threads on desktop
|
|
int iCursorLevel; // keep track of each thread's level
|
|
POINT ptLast; // Position of last message
|
|
|
|
PWND spwndDefaultIme; // Default IME Window for this thread
|
|
PIMC spDefaultImc; // Default input context for this thread
|
|
HKL hklPrev; // Previous active keyboard layout
|
|
int cEnterCount;
|
|
MLIST mlPost; // posted message list.
|
|
USHORT fsChangeBitsRemoved;// Bits removed during PeekMessage
|
|
WCHAR wchInjected; // character from last VK_PACKET
|
|
DWORD fsReserveKeys; // Keys that must be sent to the active
|
|
// active console window.
|
|
PKEVENT *apEvent; // Wait array for xxxPollAndWaitForSingleObject
|
|
ACCESS_MASK amdesk; // Granted desktop access
|
|
UINT cWindows; // Number of windows owned by this thread
|
|
UINT cVisWindows; // Number of visible windows on this thread
|
|
|
|
PHOOK aphkStart[CWINHOOKS]; // Hooks registered for this thread
|
|
CLIENTTHREADINFO cti; // Use this when no desktop is available
|
|
|
|
#ifdef GENERIC_INPUT
|
|
HANDLE hPrevHidData;
|
|
#endif
|
|
#if DBG
|
|
UINT cNestedCalls;
|
|
#endif
|
|
} THREADINFO;
|
|
|
|
#define PWNDTOPSBTRACK(pwnd) (((GETPTI(pwnd)->pSBTrack)))
|
|
|
|
/*
|
|
* The number of library module handles we can store in the dependency
|
|
* tables. If this exceeds 32, the load mask implementation must be
|
|
* changed.
|
|
*/
|
|
#define CLIBS 32
|
|
|
|
/*
|
|
* Process Info structure.
|
|
*/
|
|
typedef struct tagWOWPROCESSINFO {
|
|
struct tagWOWPROCESSINFO *pwpiNext; // List of WOW ppi's, gppiFirstWow is head
|
|
PTHREADINFO ptiScheduled; // current thread in nonpreemptive scheduler
|
|
PTDB ptdbHead; // list of this process's WOW tasks
|
|
PVOID lpfnWowExitTask; // func addr for wow exittask callback
|
|
PKEVENT pEventWowExec; // WowExec Virt HWint scheduler event
|
|
HANDLE hEventWowExecClient; // client handle value for wowexec
|
|
DWORD nSendLock; // Send Scheduler inter process Send count
|
|
DWORD nRecvLock; // Send Scheduler inter process Receive count
|
|
PTHREADINFO CSOwningThread; // Pseudo Wow CritSect ClientThreadId
|
|
LONG CSLockCount; // Pseudo Wow CritSect LockCount
|
|
} WOWPROCESSINFO, *PWOWPROCESSINFO;
|
|
|
|
typedef struct tagDESKTOPVIEW {
|
|
struct tagDESKTOPVIEW *pdvNext;
|
|
PDESKTOP pdesk;
|
|
ULONG_PTR ulClientDelta;
|
|
} DESKTOPVIEW, *PDESKTOPVIEW;
|
|
|
|
|
|
/*
|
|
* number of DWORDs in ppi->pgh
|
|
*/
|
|
#define GH_SIZE 8
|
|
|
|
/*
|
|
* The delta allocation for ppiTable array in W32JOB structure.
|
|
*/
|
|
#define JP_DELTA 4
|
|
|
|
/*
|
|
* W32JOB structure
|
|
*/
|
|
typedef struct tagW32JOB {
|
|
struct tagW32JOB* pNext; // next W32JOB structure
|
|
PEJOB Job; // pointer to the EJOB structure
|
|
PVOID pAtomTable; // the atom table for the job object
|
|
DWORD restrictions; // UI restrictions
|
|
UINT uProcessCount; // number of processes in ppiTable
|
|
UINT uMaxProcesses; // how much room is in ppiTable
|
|
PPROCESSINFO* ppiTable; // the array of processes contained in the job
|
|
UINT ughCrt; // crt number of handles in pgh
|
|
UINT ughMax; // number of handles pgh can store
|
|
PULONG_PTR pgh; // the granted handles table
|
|
} W32JOB, *PW32JOB;
|
|
|
|
#ifdef REDIRECTION
|
|
#define PF_REDIRECTED 0x00000001
|
|
#define PF_REDIRECTIONHOST 0x00000002
|
|
#endif // REDIRECTION
|
|
|
|
/*
|
|
* Make sure this structure matches up with W32PROCESS, since they're
|
|
* really the same thing.
|
|
*/
|
|
|
|
/*
|
|
* NOTE -- this structure has been sorted (roughly) in order of use
|
|
* of the fields. The x86 code set allows cheaper access to fields
|
|
* that are in the first 0x80 bytes of a structure. Please attempt
|
|
* to ensure that frequently-used fields are below this boundary.
|
|
*/
|
|
|
|
typedef struct tagPROCESSINFO {
|
|
W32PROCESS;
|
|
//***************************************** begin: USER specific fields
|
|
PTHREADINFO ptiList; // threads in this process
|
|
PTHREADINFO ptiMainThread; // pti of "main thread"
|
|
PDESKTOP rpdeskStartup; // initial desktop
|
|
PCLS pclsPrivateList; // this processes' private classes
|
|
PCLS pclsPublicList; // this processes' public classes
|
|
PWOWPROCESSINFO pwpi; // Wow PerProcess Info
|
|
|
|
PPROCESSINFO ppiNext; // next ppi structure in start list
|
|
PPROCESSINFO ppiNextRunning;
|
|
int cThreads; // count of threads using this process info
|
|
HDESK hdeskStartup; // initial desktop handle
|
|
UINT cSysExpunge; // sys expunge counter
|
|
DWORD dwhmodLibLoadedMask; // bits describing loaded hook dlls
|
|
HANDLE ahmodLibLoaded[CLIBS]; // process unique hmod array for hook dlls
|
|
struct tagWINDOWSTATION *rpwinsta; // process windowstation
|
|
HWINSTA hwinsta; // windowstation handle
|
|
ACCESS_MASK amwinsta; // windowstation accesses
|
|
|
|
DWORD dwHotkey; // hot key from progman
|
|
HMONITOR hMonitor; // monitor handle from CreateProcess
|
|
PDESKTOPVIEW pdvList; // list of desktop views
|
|
UINT iClipSerialNumber; // clipboard serial number
|
|
RTL_BITMAP bmHandleFlags; // per handle flags
|
|
PCURSOR pCursorCache; // process cursor/icon cache
|
|
PVOID pClientBase; // LEAVE THIS FOR HYDRA; offset to the shared section
|
|
DWORD dwLpkEntryPoints; // user mode language pack installed
|
|
|
|
PW32JOB pW32Job; // pointer to the W32JOB structure
|
|
|
|
DWORD dwImeCompatFlags; // per-process Ime Compatibility flags
|
|
LUID luidSession; // logon session id
|
|
USERSTARTUPINFO usi; // process startup info
|
|
|
|
#ifdef VALIDATEHANDLEQUOTA
|
|
LONG lHandles;
|
|
#endif
|
|
|
|
DWORD dwLayout; // the default Window orientation for this process
|
|
|
|
#ifdef GENERIC_INPUT
|
|
PPROCESS_HID_TABLE pHidTable; // per process device request list
|
|
#endif
|
|
|
|
#ifdef REDIRECTION
|
|
DWORD dwRedirection; // redirection mode for this process
|
|
#endif
|
|
} PROCESSINFO;
|
|
|
|
/*
|
|
* Bit definitions for dwLpkEntryPoints in the processinfo structure.
|
|
* These are passed from the client side when an lpk is registered.
|
|
* The kernel determines when to perform callbacks based on which
|
|
* entry points an lpk supports.
|
|
*/
|
|
#define LPK_TABBEDTEXTOUT 0x01
|
|
#define LPK_PSMTEXTOUT 0x02
|
|
#define LPK_DRAWTEXTEX 0x04
|
|
#define LPK_EDITCONTROL 0x08
|
|
#define LPK_INSTALLED 0x0f
|
|
|
|
#define CALL_LPK(ptiCurrent) ((PpiCurrent()->dwLpkEntryPoints & LPK_INSTALLED) && \
|
|
!((ptiCurrent)->TIF_flags & TIF_INCLEANUP))
|
|
|
|
/*
|
|
* This is used to send cool switch windows information
|
|
* to the lpk
|
|
*/
|
|
typedef struct _LPKDRAWSWITCHWND {
|
|
RECT rcRect;
|
|
LARGE_UNICODE_STRING strName;
|
|
} LPKDRAWSWITCHWND;
|
|
|
|
/*
|
|
* DC cache entry structure (DCE)
|
|
*
|
|
* This structure identifies an entry in the DCE cache. It is
|
|
* usually initialized at GetDCEx() and cleanded during RelaseCacheDC
|
|
* calls.
|
|
*
|
|
* Field
|
|
* -----
|
|
*
|
|
* pdceNext - Pointer to the next DCE entry.
|
|
*
|
|
*
|
|
* hdc - GDI DC handle for the dce entry. This will have
|
|
* the necessary clipping regions selected into it.
|
|
*
|
|
* pwndOrg - Identifies the window in the GetDCEx() call which owns
|
|
* the DCE Entry.
|
|
*
|
|
* pwndClip - Identifies the window by which the DC is clipped to.
|
|
* This is usually done for PARENTDC windows.
|
|
*
|
|
* hrgnClip - This region is set if the caller to GetDCEx() passes a
|
|
* clipping region in which to intersect with the visrgn.
|
|
* This is used when we need to recalc the visrgn for the
|
|
* DCE entry. This will be freed at ReleaseCacheDC()
|
|
* time if the flag doesn't have DCX_NODELETERGN set.
|
|
*
|
|
* hrgnClipPublic - This is a copy of the (hrgnClip) passed in above. We
|
|
* make a copy and set it as PUBLIC ownership so that
|
|
* we can use it in computations during the UserSetDCVisRgn
|
|
* call. This is necessary for Full-Hung-Draw where we
|
|
* are drawing from a different process then the one
|
|
* who created the (hrgnClip). This is always deleted
|
|
* in the ReleaseCacheDC() call.
|
|
*
|
|
* hrgnSavedVis - This is a copy of the saved visrgn for the DCE entry.
|
|
*
|
|
* flags - DCX_ flags.
|
|
*
|
|
* ptiOwner - Thread owner of the DCE entry.
|
|
*
|
|
*/
|
|
typedef struct tagDCE {
|
|
PDCE pdceNext;
|
|
HDC hdc;
|
|
PWND pwndOrg;
|
|
PWND pwndClip;
|
|
HRGN hrgnClip;
|
|
HRGN hrgnClipPublic;
|
|
HRGN hrgnSavedVis;
|
|
DWORD DCX_flags;
|
|
PTHREADINFO ptiOwner;
|
|
PMONITOR pMonitor;
|
|
} DCE;
|
|
|
|
#define DCE_SIZE_CACHEINIT 5 // Initial number of DCEs in the cache.
|
|
#define DCE_SIZE_CACHETHRESHOLD 32 // Number of dce's as a threshold.
|
|
|
|
#define DCE_RELEASED 0 // ReleaseDC released
|
|
#define DCE_FREED 1 // ReleaseDC freed
|
|
#define DCE_NORELEASE 2 // ReleaseDC in-use.
|
|
|
|
/*
|
|
* CalcVisRgn DC type bits
|
|
*/
|
|
#define DCUNUSED 0x00 /* Unused cache entry */
|
|
#define DCC 0x01 /* Client area */
|
|
#define DCW 0x02 /* Window area */
|
|
#define DCSAVEDVISRGN 0x04
|
|
#define DCCLIPRGN 0x08
|
|
#define DCNOCHILDCLIP 0x10 /* Nochildern clip */
|
|
#define DCSAVEVIS 0x20 /* Save visrgn before calculating */
|
|
#define DCCACHE 0x40
|
|
|
|
/*
|
|
* THREAD_CODEPAGE()
|
|
*
|
|
* Returns the CodePage based on the current keyboard layout.
|
|
*/
|
|
|
|
#define _THREAD_CODEPAGE() (GetClientInfo()->CodePage)
|
|
|
|
_inline WORD THREAD_CODEPAGE() {
|
|
WORD CodePage;
|
|
try {
|
|
CodePage = _THREAD_CODEPAGE();
|
|
} except (W32ExceptionHandler(FALSE, RIP_WARNING)) {
|
|
CodePage = PtiCurrent()->spklActive ? PtiCurrent()->spklActive->CodePage : CP_ACP;
|
|
}
|
|
return CodePage;
|
|
}
|
|
|
|
/*
|
|
* Window List Structure
|
|
*/
|
|
typedef struct tagBWL {
|
|
struct tagBWL *pbwlNext;
|
|
HWND *phwndNext;
|
|
HWND *phwndMax;
|
|
PTHREADINFO ptiOwner;
|
|
HWND rghwnd[1];
|
|
} BWL, *PBWL;
|
|
|
|
/*
|
|
* Numbers of HWND slots to to start with and to increase by.
|
|
*/
|
|
#define BWL_CHWNDINIT 32 /* initial # slots pre-allocated */
|
|
#define BWL_CHWNDMORE 8 /* # slots to obtain when required */
|
|
|
|
#define BWL_ENUMCHILDREN 1
|
|
#define BWL_ENUMLIST 2
|
|
#define BWL_ENUMOWNERLIST 4
|
|
|
|
#define BWL_ENUMIMELAST 0x08
|
|
#define BWL_REMOVEIMECHILD 0x10
|
|
|
|
/*
|
|
* Saved Popup Bits structure
|
|
*/
|
|
typedef struct tagSPB {
|
|
struct tagSPB *pspbNext;
|
|
PWND spwnd;
|
|
HBITMAP hbm;
|
|
RECT rc;
|
|
HRGN hrgn;
|
|
DWORD flags;
|
|
ULONG_PTR ulSaveId;
|
|
} SPB;
|
|
|
|
#define SPB_SAVESCREENBITS 0x0001 // GreSaveScreenBits() was called
|
|
#define SPB_LOCKUPDATE 0x0002 // LockWindowUpdate() SPB
|
|
#define SPB_DRAWBUFFER 0x0004 // BeginDrawBuffer() SPB
|
|
|
|
#define AnySpbs() (gpDispInfo->pspbFirst != NULL) // TRUE if there are any SPBs
|
|
|
|
/*
|
|
* Macro to check if the journal playback hook is installed.
|
|
*/
|
|
#define FJOURNALRECORD() (GETDESKINFO(PtiCurrent())->aphkStart[WH_JOURNALRECORD + 1] != NULL)
|
|
#define FJOURNALPLAYBACK() (GETDESKINFO(PtiCurrent())->aphkStart[WH_JOURNALPLAYBACK + 1] != NULL)
|
|
|
|
#define TESTHMODLOADED(pti, x) ((pti)->ppi->dwhmodLibLoadedMask & (1 << (x)))
|
|
#define SETHMODLOADED(pti, x, hmod) ((pti)->ppi->ahmodLibLoaded[x] = hmod, \
|
|
(pti)->ppi->dwhmodLibLoadedMask |= (1 << (x)))
|
|
#define CLEARHMODLOADED(pti, x) ((pti)->ppi->ahmodLibLoaded[x] = NULL, \
|
|
(pti)->ppi->dwhmodLibLoadedMask &= ~(1 << (x)))
|
|
#define PFNHOOK(phk) (phk->ihmod == -1 ? (PROC)phk->offPfn : \
|
|
(PROC)(((ULONG_PTR)(PtiCurrent()->ppi->ahmodLibLoaded[phk->ihmod])) + \
|
|
((ULONG_PTR)(phk->offPfn))))
|
|
|
|
/*
|
|
* Extended structures for message thunking.
|
|
*/
|
|
typedef struct _CREATESTRUCTEX {
|
|
CREATESTRUCT cs;
|
|
LARGE_STRING strName;
|
|
LARGE_STRING strClass;
|
|
} CREATESTRUCTEX, *PCREATESTRUCTEX;
|
|
|
|
typedef struct _MDICREATESTRUCTEX {
|
|
MDICREATESTRUCT mdics;
|
|
LARGE_STRING strTitle;
|
|
LARGE_STRING strClass;
|
|
} MDICREATESTRUCTEX, *PMDICREATESTRUCTEX;
|
|
|
|
typedef struct _CWPSTRUCTEX {
|
|
struct tagCWPSTRUCT;
|
|
PSMS psmsSender;
|
|
} CWPSTRUCTEX, *PCWPSTRUCTEX;
|
|
|
|
typedef struct _CWPRETSTRUCTEX {
|
|
LRESULT lResult;
|
|
struct tagCWPSTRUCT;
|
|
PSMS psmsSender;
|
|
} CWPRETSTRUCTEX, *PCWPRETSTRUCTEX;
|
|
|
|
/*
|
|
* SendMessage structure and defines.
|
|
*/
|
|
typedef struct tagSMS { /* sms */
|
|
PSMS psmsNext; // link in global psmsList
|
|
#if DBG
|
|
PSMS psmsSendList; // head of queue's SendMessage chain
|
|
PSMS psmsSendNext; // link in queue's SendMessage chain
|
|
#endif // DBG
|
|
PSMS psmsReceiveNext; // link in queue's ReceiveList
|
|
PTHREADINFO ptiSender; // sending thread
|
|
PTHREADINFO ptiReceiver; // receiving thread
|
|
|
|
SENDASYNCPROC lpResultCallBack; // function to receive the SendMessageCallback return value
|
|
ULONG_PTR dwData; // value to be passed back to the lpResultCallBack function
|
|
PTHREADINFO ptiCallBackSender; // sending thread
|
|
|
|
LRESULT lRet; // message return value
|
|
DWORD tSent; // time message was sent
|
|
UINT flags; // SMF_ flags
|
|
WPARAM wParam; // message fields...
|
|
LPARAM lParam;
|
|
UINT message;
|
|
PWND spwnd;
|
|
PVOID pvCapture; // captured argument data
|
|
} SMS;
|
|
|
|
#define SMF_REPLY 0x0001 // message has been replied to
|
|
#define SMF_RECEIVERDIED 0x0002 // receiver has died
|
|
#define SMF_SENDERDIED 0x0004 // sender has died
|
|
#define SMF_RECEIVERFREE 0x0008 // receiver should free sms when done
|
|
#define SMF_RECEIVEDMESSAGE 0x0010 // sms has been received
|
|
#define SMF_CB_REQUEST 0x0100 // SendMessageCallback requested
|
|
#define SMF_CB_REPLY 0x0200 // SendMessageCallback reply
|
|
#define SMF_CB_CLIENT 0x0400 // Client process request
|
|
#define SMF_CB_SERVER 0x0800 // Server process request
|
|
#define SMF_WOWRECEIVE 0x1000 // wow sched has incr recv count
|
|
#define SMF_WOWSEND 0x2000 // wow sched has incr send count
|
|
#define SMF_RECEIVERBUSY 0x4000 // reciver is processing this msg
|
|
|
|
/*
|
|
* InterSendMsgEx parameter used for SendMessageCallback and TimeOut
|
|
*/
|
|
typedef struct tagINTERSENDMSGEX { /* ism */
|
|
UINT fuCall; // callback or timeout call
|
|
|
|
SENDASYNCPROC lpResultCallBack; // function to receive the send message value
|
|
ULONG_PTR dwData; // Value to be passed back to the SendResult call back function
|
|
LRESULT lRet; // return value from the send message
|
|
|
|
UINT fuSend; // how to send the message, SMTO_BLOCK, SMTO_ABORTIFHUNG
|
|
UINT uTimeout; // time-out duration
|
|
PULONG_PTR lpdwResult; // the return value for a syncornis call
|
|
} INTRSENDMSGEX, *PINTRSENDMSGEX;
|
|
|
|
#define ISM_CALLBACK 0x0001 // callback function request
|
|
#define ISM_TIMEOUT 0x0002 // timeout function request
|
|
#define ISM_REQUEST 0x0010 // callback function request message
|
|
#define ISM_REPLY 0x0020 // callback function reply message
|
|
#define ISM_CB_CLIENT 0x0100 // client process callback function
|
|
|
|
/*
|
|
* Event structure to handle broadcasts of notification messages.
|
|
*/
|
|
typedef struct tagASYNCSENDMSG {
|
|
WPARAM wParam;
|
|
LPARAM lParam;
|
|
UINT message;
|
|
HWND hwnd;
|
|
} ASYNCSENDMSG, *PASYNCSENDMSG;
|
|
|
|
/*
|
|
* HkCallHook() structure
|
|
*/
|
|
#define IsHooked(pti, fsHook) \
|
|
((fsHook & (pti->fsHooks | pti->pDeskInfo->fsHooks)) != 0)
|
|
|
|
#define IsGlobalHooked(pti, fsHook) \
|
|
((fsHook & pti->pDeskInfo->fsHooks) != 0)
|
|
|
|
typedef struct tagHOOKMSGSTRUCT { /* hch */
|
|
PHOOK phk;
|
|
int nCode;
|
|
LPARAM lParam;
|
|
} HOOKMSGSTRUCT, *PHOOKMSGSTRUCT;
|
|
|
|
/*
|
|
* BroadcastMessage() commands.
|
|
*/
|
|
#define BMSG_SENDMSG 0x0000
|
|
#define BMSG_SENDNOTIFYMSG 0x0001
|
|
#define BMSG_POSTMSG 0x0002
|
|
#define BMSG_SENDMSGCALLBACK 0x0003
|
|
#define BMSG_SENDMSGTIMEOUT 0x0004
|
|
#define BMSG_SENDNOTIFYMSGPROCESS 0x0005
|
|
|
|
/*
|
|
* xxxBroadcastMessage parameter used for SendMessageCallback and TimeOut
|
|
*/
|
|
typedef union tagBROADCASTMSG { /* bcm */
|
|
struct { // for callback broadcast
|
|
SENDASYNCPROC lpResultCallBack; // function to receive the send message value
|
|
ULONG_PTR dwData; // Value to be passed back to the SendResult call back function
|
|
BOOL bClientRequest; // if a cliet or server callback request
|
|
} cb;
|
|
struct { // for timeout broadcast
|
|
UINT fuFlags; // timeout type flags
|
|
UINT uTimeout; // timeout length
|
|
PULONG_PTR lpdwResult; // where to put the return value
|
|
} to;
|
|
} BROADCASTMSG, *PBROADCASTMSG;
|
|
|
|
/*
|
|
* Internal hotkey structures and defines.
|
|
*/
|
|
typedef struct tagHOTKEY {
|
|
PTHREADINFO pti;
|
|
PWND spwnd;
|
|
WORD fsModifiers; // MOD_SHIFT, MOD_ALT, MOD_CONTROL, MOD_WIN
|
|
WORD wFlags; // MOD_SAS
|
|
UINT vk;
|
|
int id;
|
|
struct tagHOTKEY *phkNext;
|
|
} HOTKEY, *PHOTKEY;
|
|
|
|
#define PWND_INPUTOWNER (PWND)1 // Means send WM_HOTKEY to input owner.
|
|
#define PWND_FOCUS (PWND)NULL // Means send WM_HOTKEY to queue's pwndFocus.
|
|
#define PWND_TOP (PWND)0
|
|
#define PWND_BOTTOM (PWND)1
|
|
#define PWND_GROUPTOTOP ((PWND)-1)
|
|
#define PWND_TOPMOST ((PWND)-1)
|
|
#define PWND_NOTOPMOST ((PWND)-2)
|
|
#define PWND_BROADCAST ((PWND)-1)
|
|
|
|
#define IDHOT_DEBUG (-5)
|
|
#define IDHOT_DEBUGSERVER (-6)
|
|
#define IDHOT_WINDOWS (-7)
|
|
|
|
/*
|
|
* xPos, yPos for WM_CONTEXTMENU from keyboard
|
|
*/
|
|
#define KEYBOARD_MENU ((LPARAM)-1) // Keyboard generated menu
|
|
|
|
/*
|
|
* Capture codes
|
|
*/
|
|
#define NO_CAP_CLIENT 0 /* no capture; in client area */
|
|
#define NO_CAP_SYS 1 /* no capture; in sys area */
|
|
#define CLIENT_CAPTURE 2 /* client-relative capture */
|
|
#define WINDOW_CAPTURE 3 /* window-relative capture */
|
|
#define SCREEN_CAPTURE 4 /* screen-relative capture */
|
|
#define FULLSCREEN_CAPTURE 5 /* capture entire machine */
|
|
#define CLIENT_CAPTURE_INTERNAL 6 /* client-relative capture (Win 3.1 style; won't release) */
|
|
|
|
#define CH_HELPPREFIX 0x08
|
|
|
|
#ifdef KANJI
|
|
#define CH_KANJI1 0x1D
|
|
#define CH_KANJI2 0x1E
|
|
#define CH_KANJI3 0x1F
|
|
#endif // KANJI
|
|
|
|
#define xxxRedrawScreen() \
|
|
xxxInternalInvalidate(PtiCurrent()->rpdesk->pDeskInfo->spwnd, \
|
|
HRGN_FULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN)
|
|
|
|
/*
|
|
* Preallocated buffer for use during SetWindowPos to prevent memory
|
|
* allocation failures.
|
|
*/
|
|
#define CCVR_WORKSPACE 4
|
|
|
|
/*
|
|
* DrawIconCallBack data, global only for state data in tmswitch.c
|
|
*/
|
|
typedef struct tagDRAWICONCB { /* dicb */
|
|
PWND pwndTop; // Window being drawn
|
|
UINT cx; // x offset for icon
|
|
UINT cy; // y offset for icon
|
|
} DRAWICONCB, *PDRAWICONCB;
|
|
|
|
/*
|
|
* The following defines the components of nKeyboardSpeed
|
|
*/
|
|
#define KSPEED_MASK 0x001F // Defines the key repeat speed.
|
|
#define KDELAY_MASK 0x0060 // Defines the keyboard delay.
|
|
#define KDELAY_SHIFT 5
|
|
|
|
/*
|
|
* Property list checkpoint int
|
|
*/
|
|
#define PROP_CHECKPOINT MAKEINTATOM(atomCheckpointProp)
|
|
#define PROP_DDETRACK MAKEINTATOM(atomDDETrack)
|
|
#define PROP_QOS MAKEINTATOM(atomQOS)
|
|
#define PROP_DDEIMP MAKEINTATOM(atomDDEImp)
|
|
#define PROP_WNDOBJ MAKEINTATOM(atomWndObj)
|
|
#define PROP_IMELEVEL MAKEINTATOM(atomImeLevel)
|
|
#define PROP_LAYER MAKEINTATOM(atomLayer)
|
|
|
|
#define WinFlags ((WORD)(&__WinFlags))
|
|
|
|
/*
|
|
* ntinput.c
|
|
*/
|
|
BOOL xxxInternalKeyEventDirect(
|
|
BYTE bVk,
|
|
WORD wScan,
|
|
DWORD dwFlags,
|
|
DWORD dwTime,
|
|
ULONG_PTR dwExtraInfo);
|
|
|
|
UINT xxxSendInput(
|
|
UINT nInputs,
|
|
LPINPUT pInputs);
|
|
|
|
BOOL _BlockInput(
|
|
BOOL fBlockIt);
|
|
|
|
int _GetMouseMovePointsEx(
|
|
CONST MOUSEMOVEPOINT* ppt,
|
|
MOUSEMOVEPOINT* pptBuf,
|
|
UINT nPoints,
|
|
DWORD resolution);
|
|
|
|
|
|
VOID xxxProcessKeyEvent(
|
|
PKE pke,
|
|
ULONG_PTR ExtraInformation,
|
|
BOOL bInjected);
|
|
|
|
VOID xxxButtonEvent(
|
|
DWORD ButtonNumber,
|
|
POINT ptPointer,
|
|
BOOL fBreak,
|
|
DWORD time,
|
|
ULONG_PTR ExtraInfo,
|
|
#ifdef GENERIC_INPUT
|
|
HANDLE hDevice,
|
|
PMOUSE_INPUT_DATA pmei,
|
|
#endif
|
|
BOOL bInjected,
|
|
BOOL fDblClk);
|
|
|
|
VOID xxxMoveEvent(
|
|
LONG dx,
|
|
LONG dy,
|
|
DWORD dwFlags,
|
|
ULONG_PTR dwExtraInfo,
|
|
#ifdef GENERIC_INPUT
|
|
HANDLE hDevice,
|
|
PMOUSE_INPUT_DATA pmei,
|
|
#endif
|
|
DWORD time,
|
|
BOOL bInjected
|
|
);
|
|
|
|
typedef struct _RIT_INIT {
|
|
PTERMINAL pTerm;
|
|
PKEVENT pRitReadyEvent;
|
|
} RIT_INIT, *PRIT_INIT;
|
|
|
|
PDEVICEINFO StartDeviceRead(PDEVICEINFO pDeviceInfo);
|
|
|
|
NTSTATUS DeviceNotify(
|
|
IN PPLUGPLAY_NOTIFY_HDR pNotification,
|
|
IN PDEVICEINFO pDeviceInfo);
|
|
|
|
#define MOUSE_SENSITIVITY_MIN 1
|
|
#define MOUSE_SENSITIVITY_DEFAULT 10
|
|
#define MOUSE_SENSITIVITY_MAX 20
|
|
LONG CalculateMouseSensitivity(LONG lSens);
|
|
|
|
PDEVICEINFO FreeDeviceInfo(PDEVICEINFO pMouseInfo);
|
|
|
|
|
|
__inline PTHREADINFO PtiKbdFromQ(PQ pq)
|
|
{
|
|
if (pq->spwndActive) {
|
|
return GETPTI(pq->spwndActive);
|
|
}
|
|
UserAssert(pq->ptiKeyboard);
|
|
return pq->ptiKeyboard;
|
|
}
|
|
|
|
__inline PTHREADINFO ValidatePtiKbd(PQ pq)
|
|
{
|
|
if (pq == NULL) {
|
|
return NULL;
|
|
}
|
|
return PtiKbdFromQ(pq);
|
|
}
|
|
|
|
__inline PTHREADINFO PtiMouseFromQ(PQ pq)
|
|
{
|
|
if (pq->spwndCapture) {
|
|
return GETPTI(pq->spwndCapture);
|
|
}
|
|
UserAssert(pq->ptiMouse);
|
|
return pq->ptiMouse;
|
|
}
|
|
|
|
__inline PTHREADINFO ValidatePtiMouse(PQ pq)
|
|
{
|
|
if (pq == NULL) {
|
|
return NULL;
|
|
}
|
|
return PtiMouseFromQ(pq);
|
|
}
|
|
|
|
|
|
VOID QueueMouseEvent(
|
|
USHORT ButtonFlags,
|
|
USHORT ButtonData,
|
|
ULONG_PTR ExtraInfo,
|
|
POINT ptMouse,
|
|
LONG time,
|
|
#ifdef GENERIC_INPUT
|
|
HANDLE hDevice,
|
|
PMOUSE_INPUT_DATA pmei,
|
|
#endif
|
|
BOOL bInjected,
|
|
BOOL bWakeRIT
|
|
);
|
|
|
|
typedef struct {
|
|
DWORD dwVersion;
|
|
DWORD dwFlags;
|
|
DWORD dwMapCount;
|
|
DWORD dwMap[0];
|
|
} SCANCODEMAP, *PSCANCODEMAP;
|
|
|
|
|
|
#ifndef SCANCODE_NUMPAD_PLUS
|
|
#define SCANCODE_NUMPAD_PLUS (0x4e)
|
|
#endif
|
|
#ifndef SCANCODE_NUMPAD_DOT
|
|
#define SCANCODE_NUMPAD_DOT (0x53)
|
|
#endif
|
|
|
|
/*
|
|
* Flag (LowLevel and HighLevel) for
|
|
* hex Alt+Numpad mode.
|
|
* If you need to add a new flag for gfInNumpadHexInput,
|
|
* note the variable is BYTE.
|
|
*/
|
|
#define NUMPAD_HEXMODE_LL (1)
|
|
#define NUMPAD_HEXMODE_HL (2)
|
|
|
|
#define MODIFIER_FOR_ALT_NUMPAD(wModBit) \
|
|
(((wModBits) == KBDALT) || ((wModBits) == (KBDALT | KBDSHIFT)) || \
|
|
((wModBits) == (KBDKANA | KBDALT)) || ((wModBits) == (KBDKANA | KBDALT | KBDSHIFT)))
|
|
|
|
|
|
BOOL UnqueueMouseEvent(PMOUSEEVENT pme);
|
|
|
|
BYTE VKFromVSC(PKE pke, BYTE bPrefix, LPBYTE afKeyState);
|
|
BOOL KEOEMProcs(PKE pke);
|
|
BOOL xxxKELocaleProcs(PKE pke);
|
|
BOOL xxxKENLSProcs(PKE pke, ULONG_PTR dwExtraInformation);
|
|
|
|
VOID xxxKeyEvent(USHORT usVk, WORD wScanCode, DWORD time, ULONG_PTR ExtraInfo,
|
|
#ifdef GENERIC_INPUT
|
|
HANDLE hDevice,
|
|
PKEYBOARD_INPUT_DATA pkei,
|
|
#endif
|
|
BOOL bInjected);
|
|
|
|
typedef BITMAPINFOHEADER *PBMPHEADER, *LPBMPHEADER;
|
|
|
|
VOID xxxSimpleDoSyncPaint(PWND pwnd);
|
|
VOID xxxDoSyncPaint(PWND pwnd, DWORD flags);
|
|
VOID xxxInternalDoSyncPaint(PWND pwnd, DWORD flags);
|
|
|
|
/*
|
|
* NOTE: the first 4 values must be as defined for backward compatibility
|
|
* reasons. They are sent as parameters to the WM_SYNCPAINT message.
|
|
* They used to be hard-coded constants.
|
|
*
|
|
* Only ENUMCLIPPEDCHILDREN, ALLCHILDREN, and NOCHECKPARENTS are passed on
|
|
* during recursion. The other bits reflect the current window only.
|
|
*/
|
|
#define DSP_ERASE 0x0001 // Send WM_ERASEBKGND
|
|
#define DSP_FRAME 0x0002 // Send WM_NCPAINT
|
|
#define DSP_ENUMCLIPPEDCHILDREN 0x0004 // Enum children if WS_CLIPCHILDREN
|
|
#define DSP_WM_SYNCPAINT 0x0008 // Called from WM_SYNCPAINT handler
|
|
#define DSP_NOCHECKPARENTS 0x0010 // Don't check parents for update region
|
|
#define DSP_ALLCHILDREN 0x0020 // Enumerate all children.
|
|
|
|
BOOL xxxDrawAnimatedRects(
|
|
PWND pwndClip,
|
|
int idAnimation,
|
|
LPRECT lprcStart,
|
|
LPRECT lprcEnd);
|
|
|
|
typedef struct tagTIMER {
|
|
HEAD head;
|
|
struct tagTIMER *ptmrNext;
|
|
struct tagTIMER *ptmrPrev;
|
|
PTHREADINFO pti;
|
|
struct tagWND * spwnd;
|
|
UINT_PTR nID;
|
|
DWORD cmsCountdown;
|
|
DWORD cmsRate;
|
|
UINT flags;
|
|
TIMERPROC_PWND pfn;
|
|
PTHREADINFO ptiOptCreator; // Used for journal playback -- Will be NULL
|
|
// if timer was created by non-GUI thread.
|
|
} TIMER, *PTIMER;
|
|
|
|
UINT_PTR InternalSetTimer(PWND pwnd, UINT_PTR nIDEvent, UINT dwElapse,
|
|
TIMERPROC_PWND pTimerFunc, UINT flags);
|
|
|
|
VOID FreeTimer(PTIMER ptmr);
|
|
|
|
/*
|
|
* Call FindTimer() with fKill == TRUE and TMRF_RIT. This will basically
|
|
* delete the timer.
|
|
*/
|
|
#define KILLRITTIMER(pwnd, nID) FindTimer(pwnd, nID, TMRF_RIT, TRUE)
|
|
|
|
/*
|
|
* Raster Ops
|
|
*/
|
|
#define PATOR 0x00FA0089L /* destination, pattern, or */
|
|
|
|
/*
|
|
* Message thunks.
|
|
*/
|
|
typedef LRESULT (APIENTRY *SFNSCSENDMESSAGE)(PWND, UINT, WPARAM, LPARAM,
|
|
ULONG_PTR, PROC, DWORD, PSMS);
|
|
|
|
#define SMESSAGEPROTO(func) \
|
|
LRESULT CALLBACK Sfn ## func( \
|
|
PWND pwnd, UINT msg, WPARAM wParam, LPARAM lParam, \
|
|
ULONG_PTR xParam, PROC xpfnWndProc, DWORD dwSCMSFlags, PSMS psms)
|
|
|
|
SMESSAGEPROTO(SENTDDEMSG);
|
|
SMESSAGEPROTO(DDEINIT);
|
|
SMESSAGEPROTO(DWORD);
|
|
SMESSAGEPROTO(NCDESTROY);
|
|
SMESSAGEPROTO(INWPARAMCHAR);
|
|
SMESSAGEPROTO(INWPARAMDBCSCHAR);
|
|
|
|
SMESSAGEPROTO(GETTEXTLENGTHS);
|
|
|
|
SMESSAGEPROTO(GETDBCSTEXTLENGTHS);
|
|
SMESSAGEPROTO(INLPCREATESTRUCT);
|
|
SMESSAGEPROTO(INLPDROPSTRUCT);
|
|
SMESSAGEPROTO(INOUTLPPOINT5);
|
|
SMESSAGEPROTO(INOUTLPSCROLLINFO);
|
|
SMESSAGEPROTO(INOUTLPRECT);
|
|
SMESSAGEPROTO(INOUTNCCALCSIZE);
|
|
SMESSAGEPROTO(OUTLPRECT);
|
|
SMESSAGEPROTO(INLPMDICREATESTRUCT);
|
|
SMESSAGEPROTO(INLPCOMPAREITEMSTRUCT);
|
|
SMESSAGEPROTO(INLPDELETEITEMSTRUCT);
|
|
SMESSAGEPROTO(INLPHLPSTRUCT);
|
|
SMESSAGEPROTO(INLPHELPINFOSTRUCT); // WINHELP4
|
|
SMESSAGEPROTO(INLPDRAWITEMSTRUCT);
|
|
SMESSAGEPROTO(INOUTLPMEASUREITEMSTRUCT);
|
|
SMESSAGEPROTO(INSTRING);
|
|
SMESSAGEPROTO(INPOSTEDSTRING);
|
|
SMESSAGEPROTO(INSTRINGNULL);
|
|
SMESSAGEPROTO(OUTSTRING);
|
|
SMESSAGEPROTO(INCNTOUTSTRING);
|
|
SMESSAGEPROTO(POUTLPINT);
|
|
SMESSAGEPROTO(POPTINLPUINT);
|
|
SMESSAGEPROTO(INOUTLPWINDOWPOS);
|
|
SMESSAGEPROTO(INLPWINDOWPOS);
|
|
SMESSAGEPROTO(INLBOXSTRING);
|
|
SMESSAGEPROTO(OUTLBOXSTRING);
|
|
SMESSAGEPROTO(INCBOXSTRING);
|
|
SMESSAGEPROTO(OUTCBOXSTRING);
|
|
SMESSAGEPROTO(INCNTOUTSTRINGNULL);
|
|
SMESSAGEPROTO(INOUTDRAG);
|
|
SMESSAGEPROTO(FULLSCREEN);
|
|
SMESSAGEPROTO(INPAINTCLIPBRD);
|
|
SMESSAGEPROTO(INSIZECLIPBRD);
|
|
SMESSAGEPROTO(OUTDWORDDWORD);
|
|
SMESSAGEPROTO(OUTDWORDINDWORD);
|
|
SMESSAGEPROTO(OPTOUTLPDWORDOPTOUTLPDWORD);
|
|
SMESSAGEPROTO(DWORDOPTINLPMSG);
|
|
SMESSAGEPROTO(COPYGLOBALDATA);
|
|
SMESSAGEPROTO(COPYDATA);
|
|
SMESSAGEPROTO(INDESTROYCLIPBRD);
|
|
SMESSAGEPROTO(INOUTNEXTMENU);
|
|
SMESSAGEPROTO(INOUTSTYLECHANGE);
|
|
SMESSAGEPROTO(IMAGEIN);
|
|
SMESSAGEPROTO(IMAGEOUT);
|
|
SMESSAGEPROTO(INDEVICECHANGE);
|
|
SMESSAGEPROTO(INOUTMENUGETOBJECT);
|
|
SMESSAGEPROTO(POWERBROADCAST);
|
|
SMESSAGEPROTO(LOGONNOTIFY);
|
|
SMESSAGEPROTO(IMECONTROL);
|
|
SMESSAGEPROTO(IMEREQUEST);
|
|
SMESSAGEPROTO(INLPKDRAWSWITCHWND);
|
|
SMESSAGEPROTO(OUTLPCOMBOBOXINFO);
|
|
SMESSAGEPROTO(OUTLPSCROLLBARINFO);
|
|
|
|
/***************************************************************************\
|
|
* Function Prototypes
|
|
*
|
|
* NOTE: Only prototypes for GLOBAL (across module) functions should be put
|
|
* here. Prototypes for functions that are global to a single module should
|
|
* be put at the head of that module.
|
|
*
|
|
* LATER: There's still lots of bogus trash in here to be cleaned out.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
/*
|
|
* Random prototypes.
|
|
*/
|
|
DWORD _GetWindowContextHelpId(
|
|
PWND pwnd);
|
|
|
|
BOOL _SetWindowContextHelpId(
|
|
PWND pwnd,
|
|
DWORD dwContextId);
|
|
|
|
void xxxSendHelpMessage(
|
|
PWND pwnd,
|
|
int iType,
|
|
int iCtrlId,
|
|
HANDLE hItemHandle,
|
|
DWORD dwContextId);
|
|
|
|
HPALETTE _SelectPalette(
|
|
HDC hdc,
|
|
HPALETTE hpalette,
|
|
BOOL fForceBackground);
|
|
|
|
int xxxRealizePalette(
|
|
HDC hdc);
|
|
|
|
VOID xxxFlushPalette(
|
|
PWND pwnd);
|
|
|
|
VOID xxxBroadcastPaletteChanged(
|
|
PWND pwnd,
|
|
BOOL fForceDesktop);
|
|
|
|
PCURSOR SearchIconCache(
|
|
PCURSOR pCursorCache,
|
|
ATOM atomModName,
|
|
PUNICODE_STRING pstrResName,
|
|
PCURSOR pCursorSrc,
|
|
PCURSORFIND pcfSearch);
|
|
|
|
VOID ZombieCursor(PCURSOR pcur);
|
|
|
|
BOOL IsSmallerThanScreen(PWND pwnd);
|
|
|
|
BOOL zzzSetSystemCursor(
|
|
PCURSOR pcur,
|
|
DWORD id);
|
|
|
|
BOOL zzzSetSystemImage(
|
|
PCURSOR pcur,
|
|
PCURSOR pcurOld);
|
|
|
|
BOOL _InternalGetIconInfo(
|
|
IN PCURSOR pcur,
|
|
OUT PICONINFO piconinfo,
|
|
OUT OPTIONAL PUNICODE_STRING pstrModName,
|
|
OUT OPTIONAL PUNICODE_STRING pstrResName,
|
|
OUT OPTIONAL LPDWORD pbpp,
|
|
IN BOOL fInternalCursor);
|
|
|
|
VOID LinkCursor(
|
|
PCURSOR pcur);
|
|
|
|
BOOL _SetCursorIconData(
|
|
PCURSOR pcur,
|
|
PUNICODE_STRING pstrModName,
|
|
PUNICODE_STRING pstrResName,
|
|
PCURSORDATA pData,
|
|
DWORD cbData);
|
|
|
|
PCURSOR _GetCursorFrameInfo(
|
|
PCURSOR pcur,
|
|
int iFrame,
|
|
PJIF pjifRate,
|
|
LPINT pccur);
|
|
|
|
BOOL zzzSetSystemCursor(
|
|
PCURSOR pcur,
|
|
DWORD id);
|
|
|
|
PCURSOR _FindExistingCursorIcon(
|
|
ATOM atomModName,
|
|
PUNICODE_STRING pstrResName,
|
|
PCURSOR pcurSrc,
|
|
PCURSORFIND pcfSearch);
|
|
|
|
HCURSOR _CreateEmptyCursorObject(
|
|
BOOL fPublic);
|
|
|
|
BOOL _GetUserObjectInformation(HANDLE h,
|
|
int nIndex, PVOID pvInfo, DWORD nLength, LPDWORD lpnLengthNeeded);
|
|
BOOL _SetUserObjectInformation(HANDLE h,
|
|
int nIndex, PVOID pvInfo, DWORD nLength);
|
|
DWORD xxxWaitForInputIdle(ULONG_PTR idProcess, DWORD dwMilliseconds,
|
|
BOOL fSharedWow);
|
|
VOID StartScreenSaver(BOOL bOnlyIfSecure);
|
|
UINT InternalMapVirtualKeyEx(UINT wCode, UINT wType, PKBDTABLES pKbdTbl);
|
|
SHORT InternalVkKeyScanEx(WCHAR cChar, PKBDTABLES pKbdTbl);
|
|
|
|
|
|
|
|
PWND ParentNeedsPaint(PWND pwnd);
|
|
VOID SetHungFlag(PWND pwnd, WORD wFlag);
|
|
VOID ClearHungFlag(PWND pwnd, WORD wFlag);
|
|
|
|
BOOL _DdeSetQualityOfService(PWND pwndClient,
|
|
CONST PSECURITY_QUALITY_OF_SERVICE pqosNew,
|
|
PSECURITY_QUALITY_OF_SERVICE pqosOld);
|
|
BOOL _DdeGetQualityOfService(PWND pwndClient,
|
|
PWND pwndServer, PSECURITY_QUALITY_OF_SERVICE pqos);
|
|
|
|
BOOL QueryTrackMouseEvent(LPTRACKMOUSEEVENT lpTME);
|
|
void CancelMouseHover(PQ pq);
|
|
void ResetMouseTracking(PQ pq, PWND pwnd);
|
|
|
|
void _SetIMEShowStatus(BOOL fShow);
|
|
BOOL _GetIMEShowStatus(VOID);
|
|
|
|
/*
|
|
* Prototypes for internal version of APIs.
|
|
*/
|
|
PWND _FindWindowEx(PWND pwndParent, PWND pwndChild,
|
|
LPCWSTR pszClass, LPCWSTR pszName, DWORD dwType);
|
|
UINT APIENTRY GreSetTextAlign(HDC, UINT);
|
|
UINT APIENTRY GreGetTextAlign(HDC);
|
|
|
|
/*
|
|
* Prototypes for validation, RIP, error handling, etc functions.
|
|
*/
|
|
PWND FASTCALL ValidateHwnd(HWND hwnd);
|
|
|
|
NTSTATUS ValidateHwinsta(HWINSTA, KPROCESSOR_MODE, ACCESS_MASK, PWINDOWSTATION*);
|
|
NTSTATUS ValidateHdesk(HDESK, KPROCESSOR_MODE, ACCESS_MASK, PDESKTOP*);
|
|
|
|
PMENU ValidateHmenu(HMENU hmenu);
|
|
PMONITOR ValidateHmonitor(HMONITOR hmonitor);
|
|
HRGN UserValidateCopyRgn(HRGN);
|
|
|
|
BOOL ValidateHandleSecure(HANDLE h);
|
|
|
|
NTSTATUS UserJobCallout(PKWIN32_JOBCALLOUT_PARAMETERS Parm);
|
|
|
|
BOOL RemoveProcessFromJob(PPROCESSINFO ppi);
|
|
|
|
|
|
BOOL xxxActivateDebugger(UINT fsModifiers);
|
|
|
|
void ClientDied(void);
|
|
|
|
VOID SendMsgCleanup(PTHREADINFO ptiCurrent);
|
|
VOID ReceiverDied(PSMS psms, PSMS *ppsmsUnlink);
|
|
LRESULT xxxInterSendMsgEx(PWND, UINT, WPARAM, LPARAM, PTHREADINFO, PTHREADINFO, PINTRSENDMSGEX );
|
|
VOID ClearSendMessages(PWND pwnd);
|
|
PPCLS GetClassPtr(ATOM atom, PPROCESSINFO ppi, HANDLE hModule);
|
|
BOOL ReferenceClass(PCLS pcls, PWND pwnd);
|
|
VOID DereferenceClass(PWND pwnd);
|
|
ULONG_PTR MapClientToServerPfn(ULONG_PTR dw);
|
|
|
|
|
|
VOID xxxReceiveMessage(PTHREADINFO);
|
|
#define xxxReceiveMessages(pti) \
|
|
while ((pti)->pcti->fsWakeBits & QS_SENDMESSAGE) { xxxReceiveMessage((pti)); }
|
|
|
|
PBWL BuildHwndList(PWND pwnd, UINT flags, PTHREADINFO ptiOwner);
|
|
VOID FreeHwndList(PBWL pbwl);
|
|
|
|
#define MINMAX_KEEPHIDDEN 0x1
|
|
#define MINMAX_ANIMATE 0x10000
|
|
|
|
PWND xxxMinMaximize(PWND pwnd, UINT cmd, DWORD dwFlags);
|
|
void xxxMinimizeHungWindow(PWND pwnd);
|
|
VOID xxxInitSendValidateMinMaxInfo(PWND pwnd, LPMINMAXINFO lpmmi);
|
|
HRGN CreateEmptyRgn(void);
|
|
HRGN CreateEmptyRgnPublic(void);
|
|
HRGN SetOrCreateRectRgnIndirectPublic(HRGN * phrgn, LPCRECT lprc);
|
|
BOOL SetEmptyRgn(HRGN hrgn);
|
|
BOOL SetRectRgnIndirect(HRGN hrgn, LPCRECT lprc);
|
|
void RegisterCDROMNotify(void);
|
|
NTSTATUS xxxRegisterForDeviceClassNotifications();
|
|
VOID xxxUnregisterDeviceClassNotifications();
|
|
BOOL xxxInitInput(PTERMINAL);
|
|
VOID InitMice();
|
|
void UpdateMouseInfo(void);
|
|
BOOL OpenMouse(PDEVICEINFO pMouseInfo);
|
|
void ProcessDeviceChanges(DWORD DeviceType);
|
|
PDEVICEINFO CreateDeviceInfo(DWORD DeviceType, PUNICODE_STRING SymbolicLinkName, BYTE bFlags);
|
|
void InitKeyboard(void);
|
|
void InitKeyboardState(void);
|
|
UINT xxxHardErrorControl(DWORD, HANDLE, PDESKRESTOREDATA);
|
|
|
|
#define MAX_RETRIES_TO_OPEN 30
|
|
|
|
#define UPDATE_KBD_TYPEMATIC 1
|
|
#define UPDATE_KBD_LEDS 2
|
|
|
|
VOID SetKeyboardRate(UINT nKeySpeed);
|
|
VOID RecolorDeskPattern(VOID);
|
|
BOOL xxxInitWindowStation(VOID);
|
|
VOID zzzInternalSetCursorPos(int x, int y);
|
|
VOID UpdateKeyLights(BOOL bInjected);
|
|
VOID SetDebugHotKeys(VOID);
|
|
VOID BoundCursor(LPPOINT lppt);
|
|
|
|
void DestroyKF(PKBDFILE pkf);
|
|
VOID DestroyKL(PKL pkl);
|
|
VOID CleanupKeyboardLayouts(VOID);
|
|
|
|
BOOL xxxSetDeskPattern(PUNICODE_STRING pProfileUserName,LPWSTR lpPat, BOOL fCreation);
|
|
BOOL xxxSetDeskWallpaper(PUNICODE_STRING pProfileUserName,LPWSTR lpszFile);
|
|
HPALETTE CreateDIBPalette(LPBITMAPINFOHEADER pbmih, UINT colors);
|
|
BOOL CalcVisRgn(HRGN* hrgn, PWND pwndOrg, PWND pwndClip, DWORD flags);
|
|
|
|
NTSTATUS xxxCreateThreadInfo(PETHREAD pEThread);
|
|
|
|
BOOL DestroyProcessInfo(PW32PROCESS);
|
|
|
|
|
|
VOID RawInputThread(PVOID pVoid);
|
|
HANDLE GetRemoteProcessId(VOID);
|
|
VOID HandleSystemThreadCreationFailure(BOOL bRemoteThread);
|
|
VOID xxxCreateSystemThreads(BOOL bRemoteThread);
|
|
|
|
VOID xxxDesktopThread(PTERMINAL pTerm);
|
|
VOID ForceEmptyClipboard(PWINDOWSTATION);
|
|
|
|
NTSTATUS zzzInitTask(UINT dwExpWinVer, DWORD dwAppCompatFlags, DWORD dwUserWOWCompatFlags,
|
|
PUNICODE_STRING pstrModName, PUNICODE_STRING pstrBaseFileName,
|
|
DWORD hTaskWow, DWORD dwHotkey, DWORD idTask,
|
|
DWORD dwX, DWORD dwY, DWORD dwXSize, DWORD dwYSize);
|
|
VOID DestroyTask(PPROCESSINFO ppi, PTHREADINFO ptiToRemove);
|
|
BOOL PostInputMessage(PQ pq, PWND pwnd, UINT message, WPARAM wParam,
|
|
LPARAM lParam, DWORD time, ULONG_PTR dwExtraInfo);
|
|
PWND PwndForegroundCapture(VOID);
|
|
BOOL xxxSleepThread(UINT fsWakeMask, DWORD Timeout, BOOL fForegroundIdle);
|
|
VOID SetWakeBit(PTHREADINFO pti, UINT wWakeBit);
|
|
VOID WakeSomeone(PQ pq, UINT message, PQMSG pqmsg);
|
|
VOID ClearWakeBit(PTHREADINFO pti, UINT wWakeBit, BOOL fSysCheck);
|
|
NTSTATUS xxxInitProcessInfo(PW32PROCESS);
|
|
|
|
PTHREADINFO PtiFromThreadId(DWORD idThread);
|
|
BOOL zzzAttachThreadInput(PTHREADINFO ptiAttach, PTHREADINFO ptiAttachTo, BOOL fAttach);
|
|
BOOL zzzReattachThreads(BOOL fJournalAttach);
|
|
PQ AllocQueue(PTHREADINFO, PQ);
|
|
VOID FreeQueue(PQ pq);
|
|
|
|
|
|
VOID FreeCachedQueues(VOID);
|
|
VOID CleanupGDI(VOID);
|
|
VOID CleanupResources(VOID);
|
|
|
|
VOID zzzDestroyQueue(PQ pq, PTHREADINFO pti);
|
|
PQMSG AllocQEntry(PMLIST pml);
|
|
__inline VOID FreeQEntry(PQMSG pqmsg)
|
|
{
|
|
extern PPAGED_LOOKASIDE_LIST QEntryLookaside;
|
|
ExFreeToPagedLookasideList(QEntryLookaside, pqmsg);
|
|
}
|
|
|
|
VOID DelQEntry(PMLIST pml, PQMSG pqmsg);
|
|
VOID zzzAttachToQueue(PTHREADINFO pti, PQ pqAttach, PQ pqJournal,
|
|
BOOL fJoiningForeground);
|
|
VOID xxxProcessEventMessage(PTHREADINFO ptiCurrent, PQMSG pqmsg);
|
|
VOID xxxProcessSetWindowPosEvent(PSMWP psmwpT);
|
|
VOID xxxProcessAsyncSendMessage(PASYNCSENDMSG pmsg);
|
|
BOOL PostEventMessage(PTHREADINFO pti, PQ pq, DWORD dwQEvent, PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
|
|
BOOL xxxDoPaint(PWND pwndFilter, LPMSG lpMsg);
|
|
BOOL DoTimer(PWND pwndFilter);
|
|
BOOL CheckPwndFilter(PWND pwnd, PWND pwndFilter);
|
|
|
|
#define WHT_IGNOREDISABLED 0x00000001
|
|
|
|
#ifdef REDIRECTION
|
|
|
|
#define WHT_FAKESPEEDHITTEST 0x00000002
|
|
|
|
PWND xxxCallSpeedHitTestHook(POINT* ppt);
|
|
VOID PushMouseMove(PQ pq, POINT pt);
|
|
VOID PopMouseMove(PQ pq, POINT* ppt);
|
|
|
|
#endif // REDIRECTION
|
|
|
|
BOOL xxxGetCursorPos(LPPOINT lpPt);
|
|
HWND xxxWindowHitTest(PWND pwnd, POINT pt, int *pipos, DWORD dwHitTestFlags);
|
|
HWND xxxWindowHitTest2(PWND pwnd, POINT pt, int *pipos, DWORD dwHitTestFlags);
|
|
|
|
PWND SpeedHitTest(PWND pwndParent, POINT pt);
|
|
VOID xxxDeactivate(PTHREADINFO pti, DWORD tidSetForeground);
|
|
|
|
#define SFW_STARTUP 0x0001
|
|
#define SFW_SWITCH 0x0002
|
|
#define SFW_NOZORDER 0x0004
|
|
#define SFW_SETFOCUS 0x0008
|
|
#define SFW_ACTIVATERESTORE 0x0010
|
|
|
|
BOOL xxxSetForegroundWindow2(PWND pwnd, PTHREADINFO ptiCurrent, DWORD fFlags);
|
|
VOID SetForegroundThread(PTHREADINFO pti);
|
|
VOID xxxSendFocusMessages(PTHREADINFO pti, PWND pwndReceive);
|
|
|
|
#define ATW_MOUSE 0x0001
|
|
#define ATW_SETFOCUS 0x0002
|
|
#define ATW_ASYNC 0x0004
|
|
#define ATW_NOZORDER 0x0008
|
|
|
|
BOOL FBadWindow(PWND pwnd);
|
|
BOOL xxxActivateThisWindow(PWND pwnd, DWORD tidLoseForeground, DWORD fFlags);
|
|
BOOL xxxActivateWindow(PWND pwnd, UINT cmd);
|
|
|
|
#define NTW_PREVIOUS 1
|
|
#define NTW_IGNORETOOLWINDOW 2
|
|
PWND NextTopWindow(PTHREADINFO pti, PWND pwnd, PWND pwndSkip, DWORD flags);
|
|
|
|
int xxxMouseActivate(PTHREADINFO pti, PWND pwnd, UINT message, WPARAM wParam, LPPOINT lppt, int ht);
|
|
int UT_GetParentDCClipBox(PWND pwnd, HDC hdc, LPRECT lprc);
|
|
VOID UpdateAsyncKeyState(PQ pq, UINT wVK, BOOL fBreak);
|
|
void PostUpdateKeyStateEvent(PQ pq);
|
|
void ProcessUpdateKeyStateEvent(PQ pq, CONST PBYTE pbKeyState, CONST PBYTE pbRecentDown);
|
|
|
|
BOOL InternalSetProp(PWND pwnd, LPWSTR pszKey, HANDLE hData, DWORD dwFlags);
|
|
HANDLE InternalRemoveProp(PWND pwnd, LPWSTR pszKey, BOOL fInternal);
|
|
VOID DeleteProperties(PWND pwnd);
|
|
CHECKPOINT *CkptRestore(PWND pwnd, LPCRECT lprcWindow);
|
|
UINT_PTR _SetTimer(PWND pwnd, UINT_PTR nIDEvent, UINT dwElapse, TIMERPROC_PWND pTimerFunc);
|
|
BOOL KillTimer2(PWND pwnd, UINT_PTR nIDEvent, BOOL fSystemTimer);
|
|
VOID DestroyThreadsTimers(PTHREADINFO pti);
|
|
VOID DecTimerCount(PTHREADINFO pti);
|
|
VOID zzzInternalShowCaret();
|
|
VOID zzzInternalHideCaret();
|
|
VOID zzzInternalDestroyCaret();
|
|
VOID ChangeAcquireResourceType(VOID);
|
|
VOID EnterCrit(VOID);
|
|
VOID EnterSharedCrit(VOID);
|
|
VOID LeaveCrit(VOID);
|
|
VOID _AssertCritIn(VOID);
|
|
VOID _AssertDeviceInfoListCritIn(VOID);
|
|
VOID _AssertCritInShared(VOID);
|
|
VOID _AssertCritOut(VOID);
|
|
VOID _AssertDeviceInfoListCritOut(VOID);
|
|
NTSTATUS _KeUserModeCallback(
|
|
IN ULONG ApiNumber,
|
|
IN PVOID InputBuffer,
|
|
IN ULONG InputLength,
|
|
OUT PVOID *OutputBuffer,
|
|
OUT PULONG OutputLength);
|
|
|
|
|
|
#define UnlockProcess ObDereferenceObject
|
|
#define UnlockThread ObDereferenceObject
|
|
|
|
extern ULONG gSessionId;
|
|
|
|
#if DBG
|
|
#define ValidateProcessSessionId(pEProcess) \
|
|
UserAssert(PsGetProcessSessionId(pEProcess) == gSessionId)
|
|
|
|
#define ValidateThreadSessionId(pEThread) \
|
|
UserAssert(PsGetThreadSessionId(pEThread) == gSessionId)
|
|
#else
|
|
#define ValidateProcessSessionId(pEProcess)
|
|
#define ValidateThreadSessionId(pEThread)
|
|
#endif
|
|
|
|
|
|
__inline NTSTATUS LockProcessByClientId(
|
|
HANDLE dwProcessId,
|
|
PEPROCESS* ppEProcess)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
Status = PsLookupProcessByProcessId(dwProcessId, ppEProcess);
|
|
|
|
if (NT_SUCCESS(Status) && (PsGetProcessSessionId(*ppEProcess) != gSessionId)) {
|
|
UnlockProcess(*ppEProcess);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
__inline NTSTATUS LockThreadByClientId(
|
|
HANDLE dwThreadId,
|
|
PETHREAD* ppEThread)
|
|
{
|
|
NTSTATUS Status;
|
|
|
|
Status = PsLookupThreadByThreadId(dwThreadId, ppEThread);
|
|
|
|
if (NT_SUCCESS(Status) && (PsGetThreadSessionId(*ppEThread) != gSessionId)) {
|
|
UnlockThread(*ppEThread);
|
|
return STATUS_UNSUCCESSFUL;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
BOOL IsSAS(BYTE vk, UINT* pfsModifiers);
|
|
BOOL xxxDoHotKeyStuff(UINT vk, BOOL fBreak, DWORD fsReserveKeys);
|
|
PHOTKEY IsHotKey(UINT fsModifiers, UINT vk);
|
|
void ClearCachedHotkeyModifiers(void);
|
|
|
|
/*
|
|
* Server.c
|
|
*/
|
|
#define USER_WINDOWSECT_SIZE 512
|
|
#define USER_NOIOSECT_SIZE 128
|
|
#define USR_LOGONSECT_SIZE 128
|
|
#define USR_DISCONNECTSECT_SIZE 64
|
|
#define NOIO_DESKTOP_NUMBER 10
|
|
|
|
BOOL InitCreateUserCrit(VOID);
|
|
PMDEV InitVideo(
|
|
BOOL bReenumerationNeeded);
|
|
|
|
/*
|
|
* DRVSUP.C
|
|
*/
|
|
BOOL InitUserScreen();
|
|
|
|
VOID InitLoadResources();
|
|
|
|
typedef struct tagDISPLAYRESOURCE {
|
|
WORD cyThunb;
|
|
WORD cxThumb;
|
|
WORD xCompressIcon;
|
|
WORD yCompressIcon;
|
|
WORD xCompressCursor;
|
|
WORD yCompressCursor;
|
|
WORD yKanji;
|
|
WORD cxBorder;
|
|
WORD cyBorder;
|
|
} DISPLAYRESOURCE, *PDISPLAYRESOURCE;
|
|
|
|
|
|
|
|
VOID xxxUserResetDisplayDevice(VOID);
|
|
|
|
/*
|
|
* Object management and security
|
|
*/
|
|
#define DEFAULT_WINSTA L"\\Windows\\WindowStations\\WinSta0"
|
|
|
|
#define POBJECT_NAME(pobj) (OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(pobj)) ? \
|
|
&(OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(pobj))->Name) : NULL)
|
|
|
|
PSECURITY_DESCRIPTOR CreateSecurityDescriptor(PACCESS_ALLOWED_ACE paceList,
|
|
DWORD cbAce, BOOLEAN fDaclDefaulted);
|
|
PACCESS_ALLOWED_ACE AllocAce(PACCESS_ALLOWED_ACE pace, BYTE bType,
|
|
BYTE bFlags, ACCESS_MASK am, PSID psid, LPDWORD lpdwLength);
|
|
BOOL CheckGrantedAccess(ACCESS_MASK, ACCESS_MASK);
|
|
BOOL AccessCheckObject(PVOID, ACCESS_MASK, KPROCESSOR_MODE, CONST GENERIC_MAPPING *);
|
|
BOOL InitSecurity(VOID);
|
|
BOOL IsPrivileged(PPRIVILEGE_SET ppSet);
|
|
BOOL CheckWinstaWriteAttributesAccess(void);
|
|
|
|
HWINSTA xxxConnectService(PUNICODE_STRING, HDESK *);
|
|
NTSTATUS TestForInteractiveUser(PLUID pluidCaller);
|
|
NTSTATUS _UserTestForWinStaAccess( PUNICODE_STRING pstrWinSta, BOOL fInherit);
|
|
HDESK xxxResolveDesktop(HANDLE hProcess, PUNICODE_STRING pstrDesktop,
|
|
HWINSTA *phwinsta, BOOL fInherit, BOOL* pbShutDown);
|
|
|
|
NTSTATUS xxxResolveDesktopForWOW(
|
|
IN OUT PUNICODE_STRING pstrDesktop);
|
|
|
|
WORD xxxClientWOWGetProcModule(WNDPROC_PWND pfn);
|
|
DWORD xxxClientWOWTask16SchedNotify(DWORD NotifyParm,DWORD dwParam);
|
|
|
|
PVOID _MapDesktopObject(HANDLE h);
|
|
PDESKTOPVIEW GetDesktopView(PPROCESSINFO ppi, PDESKTOP pdesk);
|
|
VOID TerminateConsole(PDESKTOP);
|
|
|
|
|
|
/*
|
|
* Object manager callouts for windowstations
|
|
*/
|
|
NTSTATUS DestroyWindowStation(
|
|
PKWIN32_CLOSEMETHOD_PARAMETERS pCloseParams );
|
|
|
|
NTSTATUS FreeWindowStation(
|
|
PKWIN32_DELETEMETHOD_PARAMETERS pDeleteParams );
|
|
|
|
NTSTATUS ParseWindowStation(
|
|
PKWIN32_PARSEMETHOD_PARAMETERS pParseParams );
|
|
|
|
NTSTATUS OkayToCloseWindowStation(
|
|
PKWIN32_OKAYTOCLOSEMETHOD_PARAMETERS pOkCloseParams);
|
|
|
|
NTSTATUS WindowStationOpenProcedure(
|
|
PKWIN32_OPENMETHOD_PARAMETERS pOpenParams);
|
|
|
|
/*
|
|
* Object manager callouts for desktops
|
|
*/
|
|
NTSTATUS DesktopOpenProcedure(
|
|
PKWIN32_OPENMETHOD_PARAMETERS pOpenParams);
|
|
|
|
NTSTATUS MapDesktop(
|
|
PKWIN32_OPENMETHOD_PARAMETERS pOpenParams );
|
|
|
|
NTSTATUS UnmapDesktop(
|
|
PKWIN32_CLOSEMETHOD_PARAMETERS pCloseParams );
|
|
|
|
NTSTATUS FreeDesktop(
|
|
PKWIN32_DELETEMETHOD_PARAMETERS pDeleteParams );
|
|
|
|
NTSTATUS ParseDesktop(
|
|
IN PVOID ParseObject,
|
|
IN PVOID ObjectType,
|
|
IN OUT PACCESS_STATE AccessState,
|
|
IN KPROCESSOR_MODE AccessMode,
|
|
IN ULONG Attributes,
|
|
IN OUT PUNICODE_STRING CompleteName,
|
|
IN OUT PUNICODE_STRING RemainingName,
|
|
IN OUT PVOID Context OPTIONAL,
|
|
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
|
|
OUT PVOID *Object);
|
|
|
|
NTSTATUS OkayToCloseDesktop(
|
|
PKWIN32_OKAYTOCLOSEMETHOD_PARAMETERS pOkCloseParams);
|
|
|
|
/*
|
|
* Routines pilfered from kernel32
|
|
*/
|
|
VOID UserSleep(DWORD dwMilliseconds);
|
|
BOOL UserBeep(DWORD dwFreq, DWORD dwDuration);
|
|
NTSTATUS UserRtlCreateAtomTable(ULONG NumberOfBuckets);
|
|
ATOM UserAddAtom(LPCWSTR lpAtom, BOOL bPin);
|
|
ATOM UserFindAtom(LPCWSTR lpAtom);
|
|
ATOM UserDeleteAtom(ATOM atom);
|
|
UINT UserGetAtomName(ATOM atom, LPWSTR lpch, int cchMax);
|
|
|
|
#define FindClassAtom(lpszClassName) \
|
|
(IS_PTR(lpszClassName) ? UserFindAtom(lpszClassName) : PTR_TO_ID(lpszClassName))
|
|
|
|
/*
|
|
* Keyboard Layouts
|
|
*/
|
|
void SetGlobalKeyboardTableInfo(PKL pklNew);
|
|
VOID ChangeForegroundKeyboardTable(PKL pklOld, PKL pklNew);
|
|
HKL xxxLoadKeyboardLayoutEx(PWINDOWSTATION, HANDLE, HKL, UINT,
|
|
PKBDTABLE_MULTI_INTERNAL,
|
|
LPCWSTR, UINT, UINT);
|
|
HKL xxxActivateKeyboardLayout(PWINDOWSTATION pwinsta, HKL hkl, UINT Flags, PWND pwnd);
|
|
HKL xxxInternalActivateKeyboardLayout(PKL pkl, UINT Flags, PWND pwnd);
|
|
BOOL GetKbdLangSwitch(PUNICODE_STRING pProfileUserName);
|
|
|
|
BOOL xxxUnloadKeyboardLayout(PWINDOWSTATION, HKL);
|
|
VOID RemoveKeyboardLayoutFile(PKBDFILE pkf);
|
|
HKL _GetKeyboardLayout(DWORD idThread);
|
|
UINT _GetKeyboardLayoutList(PWINDOWSTATION pwinsta, UINT nItems, HKL *lpBuff);
|
|
VOID xxxFreeKeyboardLayouts(PWINDOWSTATION, BOOL bUnlock);
|
|
|
|
DWORD xxxDragObject(PWND pwndParent, PWND xhwndFrom, UINT wFmt,
|
|
ULONG_PTR dwData, PCURSOR xpcur);
|
|
BOOL xxxDragDetect(PWND pwnd, POINT pt);
|
|
BOOL xxxIsDragging(PWND pwnd, POINT ptScreen, UINT uMsg);
|
|
|
|
HKL GetActiveHKL();
|
|
|
|
#define DMI_INVERT 0x00000001
|
|
#define DMI_GRAYED 0x00000002
|
|
|
|
VOID xxxDrawMenuItem(HDC hdc, PMENU pMenu, PITEM pItem, DWORD dwFlags);
|
|
BOOL xxxRealDrawMenuItem(HDC hdc, PGRAYMENU lpGray, int cx, int cy);
|
|
VOID xxxDrawMenuBarUnderlines(PWND pwnd, BOOL fShow);
|
|
UINT MNItemHitTest(PMENU pMenu, PWND pwnd, POINT pt);
|
|
|
|
|
|
/*
|
|
* Menu macros
|
|
*/
|
|
__inline BOOL IsRootPopupMenu(PPOPUPMENU ppopupmenu)
|
|
{
|
|
return (ppopupmenu == ppopupmenu->ppopupmenuRoot);
|
|
}
|
|
__inline BOOL ExitMenuLoop (PMENUSTATE pMenuState, PPOPUPMENU ppopupmenu)
|
|
{
|
|
return (!pMenuState->fInsideMenuLoop || ppopupmenu->fDestroyed);
|
|
}
|
|
__inline PMENUSTATE GetpMenuState (PWND pwnd)
|
|
{
|
|
return (GETPTI(pwnd)->pMenuState);
|
|
}
|
|
__inline PPOPUPMENU GetpGlobalPopupMenu (PWND pwnd)
|
|
{
|
|
return (GetpMenuState(pwnd) ? GetpMenuState(pwnd)->pGlobalPopupMenu : NULL);
|
|
}
|
|
__inline BOOL IsInsideMenuLoop(PTHREADINFO pti)
|
|
{
|
|
return ((pti->pMenuState != NULL) && pti->pMenuState->fInsideMenuLoop);
|
|
}
|
|
__inline BOOL IsMenuStarted(PTHREADINFO pti)
|
|
{
|
|
return ((pti->pMenuState != NULL) && pti->pMenuState->fMenuStarted);
|
|
}
|
|
__inline PITEM MNGetToppItem(PMENU pMenu)
|
|
{
|
|
return pMenu->rgItems + pMenu->iTop;
|
|
}
|
|
__inline BOOL MNIsItemSelected(PPOPUPMENU ppopupmenu)
|
|
{
|
|
return ((int)ppopupmenu->posSelectedItem >= 0);
|
|
}
|
|
__inline PITEM MNGetSelectedpitem(PPOPUPMENU ppopupmenu)
|
|
{
|
|
return ppopupmenu->spmenu->rgItems + ppopupmenu->posSelectedItem;
|
|
}
|
|
__inline BOOL MNIsScrollArrowSelected(PPOPUPMENU ppopupmenu)
|
|
{
|
|
return ((ppopupmenu->posSelectedItem == MFMWFP_UPARROW)
|
|
|| (ppopupmenu->posSelectedItem == MFMWFP_DOWNARROW));
|
|
}
|
|
__inline BOOL IsModelessMenuNotificationWindow (PWND pwnd)
|
|
{
|
|
PMENUSTATE pMenuState;
|
|
return (((pMenuState = GetpMenuState(pwnd)) != NULL)
|
|
&& pMenuState->fModelessMenu
|
|
&& (pMenuState->pGlobalPopupMenu->spwndNotify == pwnd));
|
|
}
|
|
__inline BOOL IsRecursedMenuState(PMENUSTATE pMenuState, PPOPUPMENU ppopupmenu)
|
|
{
|
|
return (pMenuState->pGlobalPopupMenu != ppopupmenu->ppopupmenuRoot);
|
|
}
|
|
|
|
__inline BOOL IsMDIItem (PITEM pitem)
|
|
{
|
|
return (TestMFS(pitem, MFS_CACHEDBMP)
|
|
&& (pitem->hbmp != NULL)
|
|
&& (pitem->hbmp <= HBMMENU_MBARLAST));
|
|
}
|
|
|
|
/*
|
|
* This definition for CM_MODE_TRANSITION must match the one in ntcon\inc\server.h
|
|
*/
|
|
|
|
#define CM_MODE_TRANSITION (WM_USER+6)
|
|
|
|
#define MNXBORDER (SYSMET(CXBORDER) + SYSMET(CXEDGE))
|
|
#define MNYBORDER (SYSMET(CYBORDER) + SYSMET(CYEDGE))
|
|
#define MNXSPACE (SYSMET(CXEDGE))
|
|
#define MNLEFTMARGIN (SYSMET(CXEDGE))
|
|
|
|
/*
|
|
* xxxMNUpdateShownMenu flags
|
|
*/
|
|
#define MNUS_DEFAULT 0x00000001
|
|
#define MNUS_DELETE 0x00000002
|
|
#define MNUS_DRAWFRAME 0x00000004
|
|
|
|
/* This tells xxxMNItemSize that the bitamp size is not avilable */
|
|
#define MNIS_MEASUREBMP -1
|
|
|
|
|
|
/*
|
|
* MN_SIZEWINDOW wParam flag. xxxMNUpdateShownMenu sends this
|
|
* message, so keep MNSW_ and MNUS_ in sync.
|
|
*/
|
|
#define MNSW_RETURNSIZE 0
|
|
#define MNSW_SIZE MNUS_DEFAULT
|
|
#define MNSW_DRAWFRAME MNUS_DRAWFRAME
|
|
|
|
/*
|
|
* Animation flags (pMenuState->iAniDropDir)
|
|
*/
|
|
#define PAS_RIGHT (TPM_HORPOSANIMATION >> TPM_FIRSTANIBITPOS)
|
|
#define PAS_LEFT (TPM_HORNEGANIMATION >> TPM_FIRSTANIBITPOS)
|
|
#define PAS_DOWN (TPM_VERPOSANIMATION >> TPM_FIRSTANIBITPOS)
|
|
#define PAS_UP (TPM_VERNEGANIMATION >> TPM_FIRSTANIBITPOS)
|
|
#define PAS_OUT 0x10
|
|
#define PAS_HORZ (PAS_LEFT | PAS_RIGHT)
|
|
#define PAS_VERT (PAS_UP | PAS_DOWN)
|
|
|
|
#if (PAS_HORZ + PAS_VERT >= PAS_OUT)
|
|
#error PAS_ & TPM_*ANIMATION conflict.
|
|
#endif
|
|
|
|
#define CXMENU3DEDGE 1
|
|
#define CYMENU3DEDGE 1
|
|
|
|
/*
|
|
* Scrollbar initialization types
|
|
*/
|
|
#define SCROLL_NORMAL 0
|
|
#define SCROLL_DIRECT 1
|
|
#define SCROLL_MENU 2
|
|
|
|
/*
|
|
* movesize.c
|
|
*/
|
|
void xxxDrawDragRect(PMOVESIZEDATA pmsd, LPRECT lprc, UINT flags);
|
|
void GetMonitorMaxArea(PWND pwnd, PMONITOR pMonitor, LPRECT * pprc);
|
|
|
|
/*
|
|
* focusact.c
|
|
*/
|
|
VOID SetForegroundPriorityProcess(PPROCESSINFO ppi, PTHREADINFO pti, BOOL fSetForegound);
|
|
VOID SetForegroundPriority(PTHREADINFO pti, BOOL fSetForeground);
|
|
void xxxUpdateTray(PWND pwnd);
|
|
|
|
|
|
//
|
|
// mnchange.c
|
|
//
|
|
void xxxMNUpdateShownMenu(PPOPUPMENU ppopup, PITEM pItem, UINT uFlags);
|
|
|
|
//
|
|
// mnkey.c
|
|
//
|
|
UINT xxxMNFindChar(PMENU pMenu, UINT ch, INT idxC, INT *lpr);
|
|
UINT MNFindItemInColumn(PMENU pMenu, UINT idxB, int dir, BOOL fRoot);
|
|
|
|
//
|
|
// mndraw.c
|
|
//
|
|
void MNAnimate(PMENUSTATE pMenuState, BOOL fIterate);
|
|
void MNDrawFullNC(PWND pwnd, HDC hdcIn, PPOPUPMENU ppopup);
|
|
void MNDrawArrow(HDC hdcIn, PPOPUPMENU ppopup, UINT uArrow);
|
|
void MNEraseBackground (HDC hdc, PMENU pmenu, int x, int y, int cx, int cy);
|
|
void MNDrawEdge(PMENU pmenu, HDC hdc, RECT * prcDraw, UINT nFlags);
|
|
|
|
|
|
//
|
|
// mnstate.c
|
|
//
|
|
PMENUSTATE xxxMNAllocMenuState(PTHREADINFO ptiCurrent, PTHREADINFO ptiNotify, PPOPUPMENU ppopupmenuRoot);
|
|
void xxxMNEndMenuState(BOOL fFreePopup);
|
|
BOOL MNEndMenuStateNotify (PMENUSTATE pMenuState);
|
|
void MNFlushDestroyedPopups (PPOPUPMENU ppopupmenu, BOOL fUnlock);
|
|
BOOL MNSetupAnimationDC (PMENUSTATE pMenuState);
|
|
BOOL MNCreateAnimationBitmap(PMENUSTATE pMenuState, UINT cx, UINT cy);
|
|
void MNDestroyAnimationBitmap(PMENUSTATE pMenuState);
|
|
PMENUSTATE xxxMNStartMenuState(PWND pwnd, DWORD cmd, LPARAM lParam);
|
|
__inline VOID LockMenuState(
|
|
PMENUSTATE pMenuState)
|
|
{
|
|
(pMenuState->dwLockCount)++;
|
|
}
|
|
BOOL xxxUnlockMenuState (PMENUSTATE pMenuState);
|
|
|
|
//
|
|
// menu.c
|
|
//
|
|
#if DBG
|
|
VOID Validateppopupmenu(PPOPUPMENU ppopupmenu);
|
|
#else // DBG
|
|
#define Validateppopupmenu(ppopupmenu)
|
|
#endif // DBG
|
|
|
|
#if DBG
|
|
#define MNGetpItemIndex DBGMNGetpItemIndex
|
|
UINT DBGMNGetpItemIndex(PMENU pmenu, PITEM pitem);
|
|
#else // DBG
|
|
#define MNGetpItemIndex _MNGetpItemIndex
|
|
#endif // DBG
|
|
|
|
__inline UINT _MNGetpItemIndex(
|
|
PMENU pmenu,
|
|
PITEM pitem)
|
|
{
|
|
return (UINT)(((ULONG_PTR)pitem - (ULONG_PTR)pmenu->rgItems) / sizeof(ITEM));
|
|
}
|
|
|
|
VOID xxxMNDismiss(PMENUSTATE pMenuState);
|
|
PITEM MNGetpItem(PPOPUPMENU ppopup, UINT uIndex);
|
|
VOID xxxMNSetCapture(PPOPUPMENU ppopup);
|
|
VOID xxxMNReleaseCapture(VOID);
|
|
VOID MNCheckButtonDownState(PMENUSTATE pMenuState);
|
|
PWND GetMenuStateWindow(PMENUSTATE pMenuState);
|
|
PVOID LockPopupMenu(PPOPUPMENU ppopup, PMENU * pspmenu, PMENU pmenu);
|
|
PVOID UnlockPopupMenu(PPOPUPMENU ppopup, PMENU * pspmenu);
|
|
PVOID LockWndMenu(PWND pwnd, PMENU * pspmenu, PMENU pmenu);
|
|
PVOID UnlockWndMenu(PWND pwnd, PMENU * pspmenu);
|
|
UINT MNSetTimerToCloseHierarchy(PPOPUPMENU ppopup);
|
|
BOOL xxxMNSetTop(PPOPUPMENU ppopup, int iNewTop);
|
|
LRESULT xxxMenuWindowProc(PWND, UINT, WPARAM, LPARAM);
|
|
VOID xxxMNButtonUp(PPOPUPMENU ppopupMenu, PMENUSTATE pMenuState, UINT posItemHit, LPARAM lParam);
|
|
VOID xxxMNButtonDown(PPOPUPMENU ppopupMenu, PMENUSTATE pMenuState, UINT posItemHit, BOOL fClick);
|
|
PITEM xxxMNSelectItem(PPOPUPMENU ppopupMenu, PMENUSTATE pMenuState, UINT itemPos);
|
|
BOOL xxxMNSwitchToAlternateMenu(PPOPUPMENU ppopupMenu);
|
|
VOID xxxMNCancel(PMENUSTATE pMenuState, UINT uMsg, UINT cmd, LPARAM lParam);
|
|
VOID xxxMNKeyDown(PPOPUPMENU ppopupMenu, PMENUSTATE pMenuState, UINT key);
|
|
BOOL xxxMNDoubleClick(PMENUSTATE pMenuState, PPOPUPMENU ppopup, int idxItem);
|
|
VOID xxxMNCloseHierarchy(PPOPUPMENU ppopupMenu, PMENUSTATE pMenuState);
|
|
PWND xxxMNOpenHierarchy(PPOPUPMENU ppopupMenu, PMENUSTATE pMenuState);
|
|
VOID LockMFMWFPWindow (PULONG_PTR puHitArea, ULONG_PTR uNewHitArea);
|
|
VOID UnlockMFMWFPWindow (PULONG_PTR puHitArea);
|
|
BOOL IsMFMWFPWindow (ULONG_PTR uHitArea);
|
|
LONG_PTR xxxMNFindWindowFromPoint(PPOPUPMENU ppopupMenu, PUINT pIndex, POINTS screenPt);
|
|
VOID xxxMNMouseMove(PPOPUPMENU ppopupMenu, PMENUSTATE pMenuState, POINTS screenPt);
|
|
int xxxMNCompute(PMENU pMenu, PWND pwndNotify, DWORD yMenuTop,
|
|
DWORD xMenuLeft,DWORD cxMax, LPDWORD lpdwHeight);
|
|
VOID xxxMNRecomputeBarIfNeeded(PWND pwndNotify, PMENU pMenu);
|
|
VOID xxxMenuDraw(HDC hdc, PMENU pMenu);
|
|
UINT MNFindNextValidItem(PMENU pMenu, int i, int dir, UINT flags);
|
|
VOID MNFreeItem(PMENU pMenu, PITEM pItem, BOOL fFreeItemPopup);
|
|
BOOL xxxMNStartMenu(PPOPUPMENU ppopupMenu, int mn);
|
|
VOID MNPositionSysMenu(PWND pwnd, PMENU pSysMenu);
|
|
|
|
PITEM xxxMNInvertItem(PPOPUPMENU ppopupmenu, PMENU pMenu,int itemNumber,PWND pwndNotify, BOOL fOn);
|
|
|
|
VOID xxxSendMenuSelect(PWND pwndNotify, PWND pwndMenu, PMENU pMenu, int idx);
|
|
#define SMS_NOMENU (PMENU)(-1)
|
|
|
|
|
|
BOOL xxxSetSystemMenu(PWND pwnd, PMENU pMenu);
|
|
BOOL xxxSetDialogSystemMenu(PWND pwnd);
|
|
|
|
VOID xxxMNChar(PPOPUPMENU ppopupMenu, PMENUSTATE pMenuState, UINT character);
|
|
PPOPUPMENU MNAllocPopup(BOOL fForceAlloc);
|
|
VOID MNFreePopup(PPOPUPMENU ppopupmenu);
|
|
|
|
/*
|
|
* Menu entry points used by the rest of USER
|
|
*/
|
|
VOID xxxMNKeyFilter(PPOPUPMENU ppopupMenu, PMENUSTATE pMenuState, UINT ch);
|
|
int xxxMenuBarCompute(PMENU pMenu, PWND pwndNotify, DWORD yMenuTop,
|
|
DWORD xMenuLeft, int cxMax);
|
|
VOID xxxEndMenu(PMENUSTATE pMenuState);
|
|
BOOL xxxCallHandleMenuMessages(PMENUSTATE pMenuState, PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
BOOL xxxHandleMenuMessages(LPMSG lpmsg, PMENUSTATE pMenuState, PPOPUPMENU ppopupmenu);
|
|
void xxxEndMenuLoop (PMENUSTATE pMenuState, PPOPUPMENU ppopupmenu);
|
|
int xxxMNLoop(PPOPUPMENU ppopupMenu, PMENUSTATE pMenuState, LPARAM lParam, BOOL fDblClk);
|
|
VOID xxxSetSysMenu(PWND pwnd);
|
|
PMENU xxxGetSysMenuHandle(PWND pwnd);
|
|
PMENU xxxGetSysMenu(PWND pwnd, BOOL fSubMenu);
|
|
PMENU MakeMenuRtoL(PMENU pMenu, BOOL bRtoL);
|
|
HDC CreateCompatiblePublicDC(HDC hdc, HBITMAP *pbmDCGray);
|
|
void xxxPSMTextOut(HDC hdc, int xLeft, int yTop, LPWSTR lpsz, int cch, DWORD dwFlags);
|
|
BOOL xxxPSMGetTextExtent(HDC hdc, LPWSTR lpstr, int cch, PSIZE psize);
|
|
|
|
/*
|
|
* LPK callbacks
|
|
*/
|
|
void xxxClientPSMTextOut(HDC hdc, int xLeft, int yTop, PUNICODE_STRING lpsz, int cch, DWORD dwFlags);
|
|
int xxxClientLpkDrawTextEx(HDC hdc, int xLeft, int yTop, LPCWSTR lpsz, int nCount,
|
|
BOOL fDraw, UINT wFormat, LPDRAWTEXTDATA lpDrawInfo, UINT bAction, int iCharSet);
|
|
BOOL xxxClientExtTextOutW(HDC hdc, int x, int y, int flOpts, RECT *prcl,
|
|
LPCWSTR pwsz, UINT cwc, INT *pdx);
|
|
BOOL xxxClientGetTextExtentPointW(HDC hdc, LPCWSTR lpstr, int cch, PSIZE psize);
|
|
|
|
/*
|
|
* Menu Drag and Drop
|
|
*/
|
|
NTSTATUS xxxClientRegisterDragDrop (HWND hwnd);
|
|
NTSTATUS xxxClientRevokeDragDrop (HWND hwnd);
|
|
NTSTATUS xxxClientLoadOLE(VOID);
|
|
void xxxMNSetGapState (ULONG_PTR uHitArea, UINT uIndex, UINT uFlags, BOOL fSet);
|
|
BOOL xxxMNDragOver(POINT * ppt, PMNDRAGOVERINFO pmndoi);
|
|
BOOL xxxMNDragLeave(VOID);
|
|
void xxxMNUpdateDraggingInfo (PMENUSTATE pMenuState, ULONG_PTR uHitArea, UINT uIndex);
|
|
|
|
/*
|
|
* Scroll bar entry points
|
|
*/
|
|
VOID xxxSBTrackInit(PWND pwnd, LPARAM lParam, int curArea, UINT uType);
|
|
VOID SBCtlSetup(PSBWND psbwnd);
|
|
void CalcSBStuff(PWND pwnd, PSBCALC pSBCalc, BOOL fVert);
|
|
void CalcSBStuff2(PSBCALC pSBCalc, LPRECT lprc, CONST PSBDATA pw, BOOL fVert);
|
|
BOOL xxxEnableScrollBar(PWND pwnd, UINT wSBflags, UINT wArrows);
|
|
void DrawSize(PWND pwnd, HDC hdc, int cxFrame, int cyFrame);
|
|
int xxxScrollWindowEx(PWND pwnd, int dx, int dy, LPRECT prcScroll,
|
|
LPRECT prcClip, HRGN hrgnUpdate, LPRECT prcUpdate, DWORD flags);
|
|
void xxxDoScrollMenu(PWND pwndNotify, PWND pwndSB, BOOL fVert, LPARAM lParam);
|
|
|
|
/*
|
|
* ICONS.C
|
|
*/
|
|
BOOL xxxInternalEnumWindow(PWND pwndNext, WNDENUMPROC_PWND lpfn, LPARAM lParam, UINT fEnumChildren);
|
|
VOID ISV_InitMinMaxInfo(PWND pwnd, PPOINT aptMinMaxWnd);
|
|
VOID ISV_ValidateMinMaxInfo(PWND pwnd, PPOINT aptMinMaxWnd);
|
|
/*
|
|
* GETSET.C
|
|
*/
|
|
WORD _SetWindowWord(PWND pwnd, int index, WORD value);
|
|
DWORD xxxSetWindowLong(PWND pwnd, int index, DWORD value, BOOL bAnsi);
|
|
ULONG_PTR xxxSetWindowData(PWND pwnd, int index, ULONG_PTR dwData, BOOL bAnsi);
|
|
LONG xxxSetWindowStyle(PWND pwnd, int gwl, DWORD styleNew);
|
|
BOOL FCallerOk(PWND pwnd);
|
|
|
|
int IntersectVisRect(HDC, int, int, int, int); // Imported from GDI
|
|
PCURSOR xxxGetWindowSmIcon(PWND pwnd, BOOL fDontSendMsg);
|
|
VOID xxxDrawCaptionBar(PWND pwnd, HDC hdc, UINT fFlags);
|
|
VOID xxxDrawScrollBar(PWND pwnd, HDC hdc, BOOL fVert);
|
|
VOID xxxTrackBox(PWND, UINT, WPARAM, LPARAM, PSBCALC);
|
|
VOID xxxTrackThumb(PWND, UINT, WPARAM, LPARAM, PSBCALC);
|
|
VOID xxxEndScroll(PWND pwnd, BOOL fCancel);
|
|
VOID xxxDrawWindowFrame(PWND pwnd, HDC hdc, UINT wFlags);
|
|
BOOL xxxInternalPaintDesktop(PWND pwnd, HDC hdc, BOOL fPaint);
|
|
VOID xxxSysCommand(PWND pwnd, DWORD cmd, LPARAM lParam);
|
|
VOID xxxHandleNCMouseGuys(PWND pwnd, UINT message, int htArea, LPARAM lParam);
|
|
void xxxCreateClassSmIcon(PCLS pcls);
|
|
HICON xxxCreateWindowSmIcon(PWND pwnd, HICON hIconBig, BOOL fCopyFromRes);
|
|
BOOL DestroyWindowSmIcon(PWND pwnd);
|
|
BOOL DestroyClassSmIcon(PCLS pcls);
|
|
UINT DWP_GetHotKey(PWND);
|
|
UINT DWP_SetHotKey(PWND, DWORD);
|
|
PWND HotKeyToWindow(DWORD);
|
|
|
|
VOID xxxDWP_DoNCActivate(PWND pwnd, DWORD dwFlags, HRGN hrgnClip);
|
|
#define NCA_ACTIVE 0x00000001
|
|
#define NCA_FORCEFRAMEOFF 0x00000002
|
|
|
|
VOID xxxDWP_ProcessVirtKey(UINT key);
|
|
BOOL xxxDWP_EraseBkgnd(PWND pwnd, UINT msg, HDC hdc);
|
|
VOID SetTiledRect(PWND pwnd, LPRECT lprc, PMONITOR pMonitor);
|
|
VOID LinkWindow(PWND pwnd, PWND pwndInsert, PWND pwndParent);
|
|
VOID UnlinkWindow(PWND pwndUnlink, PWND pwndParent);
|
|
VOID xxxDW_DestroyOwnedWindows(PWND pwndParent);
|
|
VOID xxxDW_SendDestroyMessages(PWND pwnd);
|
|
VOID xxxFreeWindow(PWND pwnd, PTL ptlpwndFree);
|
|
VOID xxxFW_DestroyAllChildren(PWND pwnd);
|
|
|
|
PHOTKEY FindHotKey(PTHREADINFO pti, PWND pwnd, int id, UINT fsModifiers, UINT vk,
|
|
BOOL fUnregister, PBOOL pfKeysExist);
|
|
|
|
NTSTATUS _BuildNameList(
|
|
PWINDOWSTATION pwinsta,
|
|
PNAMELIST pNameList,
|
|
UINT cbNameList,
|
|
PUINT pcbNeeded);
|
|
|
|
VOID xxxHelpLoop(PWND pwnd);
|
|
|
|
NTSTATUS _BuildPropList(PWND pwnd, PROPSET aPropSet[], UINT cPropMax, PUINT pcPropReturned);
|
|
BOOL xxxSendEraseBkgnd(PWND pwnd, HDC hdcBeginPaint, HRGN hrgnUpdate);
|
|
LONG xxxSetScrollBar(PWND pwnd, int code, LPSCROLLINFO lpsi, BOOL fRedraw);
|
|
VOID IncPaintCount(PWND pwnd);
|
|
VOID DecPaintCount(PWND pwnd);
|
|
PPROP CreateProp(PWND pwnd);
|
|
|
|
/*
|
|
* METRICS.C
|
|
*/
|
|
VOID xxxRecreateSmallIcons(PWND pwnd);
|
|
|
|
VOID TransferWakeBit(PTHREADINFO pti, UINT message);
|
|
BOOL SysHasKanji(VOID);
|
|
LONG xxxBroadcastMessage(PWND, UINT, WPARAM, LPARAM, UINT, PBROADCASTMSG );
|
|
|
|
VOID zzzSetFMouseMoved();
|
|
|
|
VOID TimersProc(VOID);
|
|
|
|
VOID PostMove(PQ pq);
|
|
VOID DestroyWindowsTimers(PWND pwnd);
|
|
|
|
UINT_PTR StartTimers(VOID);
|
|
|
|
/*==========================================================================*/
|
|
/* */
|
|
/* Internal Function Declarations */
|
|
/* */
|
|
/*==========================================================================*/
|
|
|
|
LRESULT xxxTooltipWndProc(PWND, UINT, WPARAM, LPARAM);
|
|
LRESULT xxxSwitchWndProc(PWND, UINT, WPARAM, LPARAM);
|
|
LRESULT xxxDesktopWndProc(PWND, UINT, WPARAM, LPARAM);
|
|
|
|
LRESULT xxxSBWndProc(PSBWND, UINT, WPARAM, LPARAM);
|
|
|
|
VOID DrawThumb2(PWND, PSBCALC, HDC, HBRUSH, BOOL, UINT);
|
|
UINT GetWndSBDisableFlags(PWND, BOOL);
|
|
|
|
HANDLE _ConvertMemHandle(LPBYTE lpData, UINT cbData);
|
|
|
|
VOID zzzRegisterSystemThread (DWORD flags, DWORD reserved);
|
|
|
|
VOID zzzUpdateCursorImage();
|
|
void zzzCalcStartCursorHide(PW32PROCESS Process, DWORD timeAdd);
|
|
BOOL FinalUserInit();
|
|
BOOL LW_RegisterWindows(VOID);
|
|
|
|
BOOL xxxSystemParametersInfo(UINT wFlag, DWORD wParam, LPVOID lParam, UINT flags);
|
|
|
|
PWINDOWSTATION CheckClipboardAccess(VOID);
|
|
PCLIP FindClipFormat(PWINDOWSTATION pwinsta, UINT format);
|
|
BOOL InternalSetClipboardData(PWINDOWSTATION pwinsta, UINT format,
|
|
HANDLE hData, BOOL fGlobalHandle, BOOL fIncSerialNumber);
|
|
VOID xxxDisownClipboard(PWND pwndClipOwner);
|
|
|
|
VOID CaretBlinkProc(PWND pwnd, UINT message, UINT_PTR id, LPARAM lParam);
|
|
VOID xxxRedrawFrame(PWND pwnd);
|
|
VOID xxxRedrawFrameAndHook(PWND pwnd);
|
|
VOID BltColor(HDC, HBRUSH, HDC, int, int, int, int, int, int, UINT);
|
|
VOID StoreMessage(LPMSG pmsg, PWND pwnd, UINT message, WPARAM wParam,
|
|
LPARAM lParam, DWORD time);
|
|
VOID StoreQMessage(PQMSG pqmsg, PWND pwnd, UINT message, WPARAM wParam,
|
|
LPARAM lParam, DWORD time, DWORD dwQEvent, ULONG_PTR dwExtraInfo);
|
|
|
|
#ifdef REDIRECTION
|
|
__inline VOID StoreQMessagePti(
|
|
PQMSG pqmsg,
|
|
PTHREADINFO pti)
|
|
{
|
|
if (pqmsg->msg.message >= WM_MOUSEFIRST && pqmsg->msg.message <= WM_MOUSELAST) {
|
|
pqmsg->msg.pt.x = LOWORD(pqmsg->msg.lParam);
|
|
pqmsg->msg.pt.y = HIWORD(pqmsg->msg.lParam);
|
|
} else {
|
|
if (pti != NULL)
|
|
pqmsg->msg.pt = pti->ptLast;
|
|
}
|
|
pqmsg->pti = pti;
|
|
}
|
|
#else
|
|
__inline VOID StoreQMessagePti(
|
|
PQMSG pqmsg,
|
|
PTHREADINFO pti)
|
|
{
|
|
pqmsg->pti = pti;
|
|
}
|
|
#endif // REDIRECTION
|
|
|
|
VOID xxxSendSizeMessage(PWND pwnd, UINT cmdSize);
|
|
|
|
VOID xxxCheckFocus(PWND pwnd);
|
|
VOID OffsetChildren(PWND pwnd, int dx, int dy, LPRECT prcHitTest);
|
|
|
|
VOID xxxMoveSize(PWND pwnd, UINT cmdMove, DWORD wptStart);
|
|
VOID xxxShowOwnedWindows(PWND pwndOwner, UINT cmdShow, HRGN hrgnHung);
|
|
VOID xxxAdjustSize(PWND pwnd, LPINT lpcx, LPINT lpcy);
|
|
|
|
VOID xxxNextWindow(PQ pq, DWORD wParam);
|
|
VOID xxxOldNextWindow(UINT flags);
|
|
VOID xxxCancelCoolSwitch(void);
|
|
VOID RemoveThreadSwitchWindowInfo(PTHREADINFO pti);
|
|
|
|
VOID xxxCancelTracking(VOID);
|
|
VOID xxxCancelTrackingForThread(PTHREADINFO ptiCancel);
|
|
VOID xxxCapture(PTHREADINFO pti, PWND pwnd, UINT code);
|
|
UINT SystoChar(UINT message, LPARAM lParam);
|
|
|
|
PHOOK PhkFirstValid(PTHREADINFO pti, int nFilterType);
|
|
PHOOK PhkFirstGlobalValid(PTHREADINFO pti, int nFilterType);
|
|
VOID FreeHook(PHOOK phk);
|
|
int xxxCallHook(int, WPARAM, LPARAM, int);
|
|
LRESULT xxxCallHook2(PHOOK, int, WPARAM, LPARAM, LPBOOL);
|
|
BOOL xxxCallMouseHook(UINT message, PMOUSEHOOKSTRUCTEX pmhs, BOOL fRemove);
|
|
VOID xxxCallJournalRecordHook(PQMSG pqmsg);
|
|
DWORD xxxCallJournalPlaybackHook(PQMSG pqmsg);
|
|
VOID SetJournalTimer(DWORD dt, UINT msgJournal);
|
|
VOID FreeThreadsWindowHooks(VOID);
|
|
|
|
BOOL xxxSnapWindow(PWND pwnd);
|
|
|
|
BOOL DefSetText(PWND pwnd, PLARGE_STRING pstrText);
|
|
PWND DSW_GetTopLevelCreatorWindow(PWND pwnd);
|
|
VOID xxxCalcClientRect(PWND pwnd, LPRECT lprc, BOOL fHungRedraw);
|
|
VOID xxxUpdateClientRect(PWND pwnd);
|
|
|
|
BOOL AllocateUnicodeString(PUNICODE_STRING pstrDst, PUNICODE_STRING pstrSrc);
|
|
|
|
HANDLE CreateDesktopHeap(PWIN32HEAP* ppheapRet, ULONG ulHeapSize);
|
|
|
|
BOOL xxxSetInternalWindowPos(PWND pwnd, UINT cmdShow, LPRECT lprcWin,
|
|
LPPOINT lpptMin);
|
|
VOID xxxMetricsRecalc(UINT wFlags, int dx, int dy, int dyCaption, int dyMenu);
|
|
|
|
VOID xxxBroadcastDisplaySettingsChange(PDESKTOP, BOOL);
|
|
|
|
|
|
/*
|
|
* This is for SPI_GET/SETUSERPREFERENCE.
|
|
* Currently it's for DWORD values only. A type field will be added so all new
|
|
* settings will be mostly handled through common SystemParametersInfo code.
|
|
*/
|
|
typedef struct tagPROFILEVALUEINFO {
|
|
DWORD dwValue;
|
|
UINT uSection;
|
|
LPCWSTR pwszKeyName;
|
|
} PROFILEVALUEINFO, *PPROFILEVALUEINFO;
|
|
|
|
/*
|
|
* SystemParametersInfo UserPreferences manipulation macros.
|
|
* SPI_ values in the BOOL or DWORD ranges (see winuser.w) are stored in
|
|
* gpdwCPUserPreferencesMask (BOOL) and gpviCPUserPreferences (DOWRD) (see kernel\globals.c).
|
|
* The following macros use the actual SPI_ value to determine the
|
|
* location of a given bit (BOOL mask) or DWORD in those globals.
|
|
*
|
|
* Macros to access DWORDs stored in gpviCPUserPreferences.
|
|
*
|
|
*/
|
|
#define UPIsDWORDRange(uSetting) \
|
|
((uSetting) >= SPI_STARTDWORDRANGE && (uSetting) < SPI_MAXDWORDRANGE)
|
|
|
|
/*
|
|
* The first entry in gpviCPUserPreferences is reserved for the bitmask, so add 1.
|
|
* Each setting has SPI_GET and SPI_SET, so divide by 2 to get the index
|
|
*/
|
|
#define UPDWORDIndex(uSetting) \
|
|
(1 + (((uSetting) - SPI_STARTDWORDRANGE) / 2))
|
|
|
|
/*
|
|
* Macros to access BOOLs stored in gpdwCPUserPreferencesMask.
|
|
*/
|
|
#define UPIsBOOLRange(uSetting) \
|
|
((uSetting) >= SPI_STARTBOOLRANGE && (uSetting) < SPI_MAXBOOLRANGE)
|
|
|
|
/*
|
|
* Each setting has SPI_GET and SPI_SET, so divide by 2 to get the index
|
|
*/
|
|
#define UPBOOLIndex(uSetting) \
|
|
(((uSetting) - SPI_STARTBOOLRANGE) / 2)
|
|
|
|
/*
|
|
* Returns a pointer to the DWORD that contains the bit corresponding to uSetting
|
|
*/
|
|
#define UPBOOLPointer(pdw, uSetting) \
|
|
(pdw + (UPBOOLIndex(uSetting) / 32))
|
|
|
|
/*
|
|
* Returns the DWORD mask needed to test/set/clear the bit corresponding to uSetting
|
|
*/
|
|
#define UPBOOLMask(uSetting) \
|
|
(1 << (UPBOOLIndex(uSetting) - ((UPBOOLIndex(uSetting) / 32) * 32)))
|
|
|
|
#define TestUPBOOL(pdw, uSetting) \
|
|
(*UPBOOLPointer(pdw, uSetting) & UPBOOLMask(uSetting))
|
|
|
|
#define SetUPBOOL(pdw, uSetting) \
|
|
(*UPBOOLPointer(pdw, uSetting) |= UPBOOLMask(uSetting))
|
|
|
|
#define ClearUPBOOL(pdw, uSetting) \
|
|
{ \
|
|
UserAssert(UPIsBOOLRange(uSetting)); \
|
|
*UPBOOLPointer(pdw, uSetting) &= ~UPBOOLMask(uSetting); \
|
|
}
|
|
|
|
/*
|
|
* Use these macros ONLY if UPIsBOOLRange(SPI_GET ## uSetting) is TRUE
|
|
*/
|
|
#define TestUP(uSetting) TestUPBOOL(gpdwCPUserPreferencesMask, SPI_GET ## uSetting)
|
|
#define SetUP(uSetting) SetUPBOOL(gpdwCPUserPreferencesMask, SPI_GET ## uSetting)
|
|
#define ClearUP(uSetting) ClearUPBOOL(gpdwCPUserPreferencesMask, SPI_GET ## uSetting)
|
|
|
|
#define IndexUP(uSetting) \
|
|
(1 << (((uSetting) - SPI_STARTBOOLRANGE) / 2))
|
|
|
|
/*
|
|
* Some settings (ie, UI Effects) are disabled when TestUP(UISETTINGS) is FALSE.
|
|
*/
|
|
#define TestEffectUP(uSetting) \
|
|
((*gpdwCPUserPreferencesMask & \
|
|
(IndexUP(SPI_GET ## uSetting) | IndexUP(SPI_GETUIEFFECTS))) == \
|
|
(IndexUP(SPI_GET ## uSetting) | IndexUP(SPI_GETUIEFFECTS)))
|
|
|
|
/*
|
|
* Some UI effects have an "inverted" disabled value (ie, disabled is TRUE).
|
|
*/
|
|
#define TestEffectInvertUP(uSetting) (TestUP(uSetting) || !TestUP(UIEFFECTS))
|
|
|
|
/*
|
|
* Some of these BOOL values are needed in the client side. This macro
|
|
* propagates them to gpsi->PUSIFlags. Note that the SI_ value must match the
|
|
* UPBOOLMask value for this to work fine.
|
|
*/
|
|
#define PropagetUPBOOLTogpsi(uSetting) \
|
|
UserAssert((DWORD)(PUSIF_ ## uSetting) == (DWORD)UPBOOLMask(SPI_GET ## uSetting)); \
|
|
COPY_FLAG(gpsi->PUSIFlags, TestUP(## uSetting), PUSIF_ ## uSetting)
|
|
|
|
|
|
|
|
/*
|
|
* Test if a TS session is connected remotly or locally through the console
|
|
* terminal.
|
|
*/
|
|
#define IsRemoteConnection() (gProtocolType != PROTOCOL_CONSOLE)
|
|
#define IsMultimon() ((gpDispInfo != NULL) && (gpDispInfo->cMonitors > 1))
|
|
#define GETCONSOLEHDEV() (gfRemotingConsole?gConsoleShadowhDev:gpDispInfo->hDev)
|
|
|
|
#ifdef IMM_PER_LOGON
|
|
BOOL UpdatePerUserImmEnabling(VOID);
|
|
#endif
|
|
BOOL xxxUpdatePerUserSystemParameters(DWORD dwFlags);
|
|
VOID SaveVolatileUserSettings(VOID);
|
|
|
|
VOID MenuRecalc(VOID);
|
|
|
|
#define UNDERLINE_RECALC 0x7FFFFFFF // MAXINT; tells us to recalc underline position
|
|
|
|
|
|
/*
|
|
* Library management routines.
|
|
*/
|
|
int GetHmodTableIndex(PUNICODE_STRING pstrName);
|
|
VOID AddHmodDependency(int iatom);
|
|
VOID RemoveHmodDependency(int iatom);
|
|
HANDLE xxxLoadHmodIndex(int iatom);
|
|
VOID xxxDoSysExpunge(PTHREADINFO pti);
|
|
|
|
|
|
VOID DestroyThreadsObjects(VOID);
|
|
VOID MarkThreadsObjects(PTHREADINFO pti);
|
|
|
|
VOID FreeMessageList(PMLIST pml);
|
|
VOID DestroyThreadsHotKeys(VOID);
|
|
VOID DestroyWindowsHotKeys(PWND pwnd);
|
|
|
|
VOID DestroyClass(PPCLS ppcls);
|
|
VOID PatchThreadWindows(PTHREADINFO);
|
|
VOID DestroyCacheDCEntries(PTHREADINFO);
|
|
|
|
VOID DestroyProcessesClasses(PPROCESSINFO);
|
|
|
|
/*
|
|
* Win16 Task Apis Taskman.c
|
|
*/
|
|
|
|
VOID InsertTask(PPROCESSINFO ppi, PTDB ptdbNew);
|
|
|
|
BOOL xxxSleepTask(BOOL fInputIdle, HANDLE);
|
|
|
|
BOOL xxxUserYield(PTHREADINFO pti);
|
|
VOID xxxDirectedYield(DWORD dwThreadId);
|
|
VOID DirectedScheduleTask(PTHREADINFO ptiOld, PTHREADINFO ptiNew, BOOL bSendMsg, PSMS psms);
|
|
VOID WakeWowTask(PTHREADINFO Pti);
|
|
|
|
/*
|
|
* WowScheduler assertion for multiple wow tasks running simultaneously
|
|
*/
|
|
|
|
_inline
|
|
VOID
|
|
EnterWowCritSect(
|
|
PTHREADINFO pti,
|
|
PWOWPROCESSINFO pwpi
|
|
)
|
|
{
|
|
if (!++pwpi->CSLockCount) {
|
|
pwpi->CSOwningThread = pti;
|
|
} else {
|
|
RIPMSG2(RIP_ERROR,
|
|
"MultipleWowTasks running simultaneously %x %x\n",
|
|
pwpi->CSOwningThread,
|
|
pwpi->CSLockCount);
|
|
}
|
|
}
|
|
|
|
_inline
|
|
VOID
|
|
ExitWowCritSect(
|
|
PTHREADINFO pti,
|
|
PWOWPROCESSINFO pwpi
|
|
)
|
|
{
|
|
if (pti == pwpi->CSOwningThread) {
|
|
pwpi->CSOwningThread = NULL;
|
|
pwpi->CSLockCount--;
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// These are internal USER functions called from inside and outside the
|
|
// critical section (from server & client side). They are a private 'API'.
|
|
//
|
|
// The prototypes appear in pairs:
|
|
// as called from outside the critsect (from client-side)
|
|
// as called from inside the critsect (from server-side)
|
|
// there must be layer code for the 1st function of each pair which validates
|
|
// handles, enters the critsect, calls the 2nd of the pair of functions, and
|
|
// leaves the critsect again.
|
|
//
|
|
// Things may have to change when we go client server: InitPwSB() mustn't
|
|
// return a pointer to global (server) data! etc.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
BOOL xxxFillWindow(PWND pwndBrush, PWND pwndPaint, HDC hdc, HBRUSH hbr);
|
|
HBRUSH xxxGetControlBrush(PWND pwnd, HDC hdc, UINT msg);
|
|
HBRUSH xxxGetControlColor(PWND pwndParent, PWND pwndCtl, HDC hdc, UINT message);
|
|
PSBINFO _InitPwSB(PWND);
|
|
BOOL _KillSystemTimer(PWND pwnd, UINT_PTR nIDEvent);
|
|
BOOL xxxPaintRect(PWND, PWND, HDC, HBRUSH, LPRECT);
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// these are called from stubs.c in the client so will probably go away
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
/*
|
|
* From CLASS.C
|
|
*/
|
|
|
|
typedef struct tagWNDCLASSVEREX {
|
|
WNDCLASSEXW;
|
|
LPCWSTR lpszClassNameVer;
|
|
} WNDCLASSVEREX, *LPWNDCLASSVEREX;
|
|
|
|
|
|
PCLS InternalRegisterClassEx(
|
|
LPWNDCLASSVEREX lpwndcls,
|
|
WORD fnid,
|
|
DWORD flags
|
|
);
|
|
|
|
PCURSOR GetClassIcoCur(PWND pwnd, int index);
|
|
PCURSOR xxxSetClassIcon(PWND pwnd, PCLS pcls, PCURSOR pCursor, int gcw);
|
|
ULONG_PTR xxxSetClassData(PWND pwnd, int index, ULONG_PTR dwData, BOOL bAnsi);
|
|
|
|
/*
|
|
* CREATEW.C
|
|
*/
|
|
|
|
#define xxxNVCreateWindowEx(dwStyle, pstrClass, pstrName, style, \
|
|
x, y, cx, cy, pwndParent, pmenu, hModule, pCreateParams, \
|
|
dwExpWinVerAndFlags) \
|
|
xxxCreateWindowEx(dwStyle, pstrClass, pstrClass, pstrName, \
|
|
style, x, y, cx, cy, pwndParent, pmenu, hModule, pCreateParams, \
|
|
dwExpWinVerAndFlags, NULL)
|
|
|
|
PWND xxxCreateWindowEx(DWORD dwStyle, PLARGE_STRING pstrNVClass, PLARGE_STRING pstrClass,
|
|
PLARGE_STRING pstrName, DWORD style, int x, int y, int cx,
|
|
int cy, PWND pwndParent, PMENU pmenu, HANDLE hModule,
|
|
LPVOID pCreateParams, DWORD dwExpWinVerAndFlags, PACTIVATION_CONTEXT pActCtx);
|
|
BOOL xxxDestroyWindow(PWND pwnd);
|
|
|
|
/*
|
|
* SENDMSG.C
|
|
*/
|
|
LRESULT xxxSendMessageFF(PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, ULONG_PTR xParam);
|
|
LONG xxxSendMessageBSM(PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam,
|
|
LPBROADCASTSYSTEMMSGPARAMS pbsmParams);
|
|
LRESULT xxxSendMessageEx(PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam, ULONG_PTR xParam);
|
|
LRESULT xxxSendMessage(PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
LRESULT xxxSendMessageTimeout(PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam,
|
|
UINT fuFlags, UINT uTimeout, PLONG_PTR lpdwResult);
|
|
BOOL xxxSendNotifyMessage(PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
void QueueNotifyMessage(PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
BOOL xxxSendMessageCallback(PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam,
|
|
SENDASYNCPROC lpResultCallBack, ULONG_PTR dwData, BOOL bClientReqest );
|
|
BOOL _ReplyMessage(LRESULT lRet);
|
|
VOID UserLogError(
|
|
PCWSTR pwszError,
|
|
ULONG cbError,
|
|
NTSTATUS ErrorCode);
|
|
|
|
/*
|
|
* MN*.C
|
|
*/
|
|
int xxxTranslateAccelerator(PWND pwnd, LPACCELTABLE pat, LPMSG lpMsg);
|
|
BOOL xxxSetMenu(PWND pwnd, PMENU pmenu, BOOL fRedraw);
|
|
VOID ChangeMenuOwner(PMENU pMenu, PPROCESSINFO ppi);
|
|
int xxxMenuBarDraw(PWND pwnd, HDC hdc, int cxFrame, int cyFrame);
|
|
BOOL xxxDrawMenuBar(PWND pwnd);
|
|
|
|
UINT xxxPaintMenuBar(PWND pwnd, HDC hdc, int iLeftOffset, int iRightOffset, int iTopOffset, DWORD dwFlags);
|
|
UINT xxxCalcMenuBar(PWND pwnd, int iLeftOffset, int iRightOffset, int iTopOffset, LPCRECT prcWnd);
|
|
|
|
BOOL xxxSetMenuItemInfo(PMENU pMenu, UINT nPos, BOOL fByPosition,
|
|
LPMENUITEMINFOW lpmii, PUNICODE_STRING pstrItem);
|
|
BOOL _SetMenuContextHelpId(PMENU pMenu, DWORD dwContextHelpId);
|
|
BOOL _SetMenuFlagRtoL(PMENU pMenu);
|
|
BOOL xxxInsertMenuItem(PMENU pMenu, UINT wIndex, BOOL fByPosition,
|
|
LPMENUITEMINFOW lpmii, PUNICODE_STRING pstrItem);
|
|
BOOL xxxRemoveMenu(PMENU pMenu, UINT nPos, UINT dwFlags);
|
|
BOOL xxxDeleteMenu(PMENU pMenu, UINT nPos, UINT dwFlags);
|
|
BOOL xxxSetMenuInfo(PMENU pMenu, LPCMENUINFO lpmi);
|
|
BOOL xxxTrackPopupMenuEx(PMENU pmenu, UINT dwFlags, int x, int y,
|
|
PWND pwnd, CONST TPMPARAMS *pparams);
|
|
LONG FindBestPos(int x, int y, int cx, int cy, LPRECT prcExclude,
|
|
UINT wFlags, PPOPUPMENU ppopupmenu, PMONITOR pMonitor);
|
|
BOOL _SetMenuDefaultItem(PMENU pMenu, UINT wId, BOOL fByPosition);
|
|
int xxxMenuItemFromPoint(PWND pwnd, PMENU pMenu, POINT ptScreen);
|
|
BOOL xxxGetMenuItemRect(PWND pwnd, PMENU pMenu, UINT uIndex, LPRECT lprcScreen);
|
|
PPOPUPMENU MNGetPopupFromMenu(PMENU pMenu, PMENUSTATE *ppMenuState);
|
|
PVOID LockDesktopMenu(PMENU * ppmenu, PMENU pmenu);
|
|
PVOID UnlockDesktopMenu(PMENU * ppmenu);
|
|
#ifdef LAME_BUTTON
|
|
PMENU xxxLoadSysDesktopMenu (PMENU * ppmenu, UINT uMenuId, PWND pwnd);
|
|
#else
|
|
PMENU xxxLoadSysDesktopMenu (PMENU * ppmenu, UINT uMenuId);
|
|
#endif // LAME_BUTTON
|
|
__inline PVOID UnlockDesktopSysMenu(
|
|
PMENU * ppmenu)
|
|
{
|
|
ClearMF(*ppmenu, MFSYSMENU);
|
|
return UnlockDesktopMenu(ppmenu);
|
|
}
|
|
|
|
/*
|
|
* SHOWWIN.C
|
|
*/
|
|
BOOL xxxShowWindow(PWND pwnd, DWORD cmdShowAnimate);
|
|
BOOL _ShowWindowAsync(PWND pwnd, int cmdShow, UINT uWPFlags);
|
|
BOOL xxxShowOwnedPopups(PWND pwndOwner, BOOL fShow);
|
|
|
|
#define RDW_HASWINDOWRGN 0x8000
|
|
BOOL xxxSetWindowRgn(PWND pwnd, HRGN hrgn, BOOL fRedraw);
|
|
|
|
/*
|
|
* SWP.C
|
|
*/
|
|
void SelectWindowRgn(PWND pwnd, HRGN hrgnClip);
|
|
PWND GetTopMostInsertAfter (PWND pwnd);
|
|
|
|
#define GETTOPMOSTINSERTAFTER(pwnd) \
|
|
(gHardErrorHandler.pti == NULL ? NULL : GetTopMostInsertAfter(pwnd))
|
|
|
|
__inline BOOL FSwpTopmost(
|
|
PWND pwnd)
|
|
{
|
|
return (!!TestWF(pwnd, WEFTOPMOST) ^ !!TestWF(pwnd, WFTOGGLETOPMOST));
|
|
}
|
|
|
|
|
|
PWND PWInsertAfter(HWND hwnd);
|
|
PWND CalcForegroundInsertAfter(PWND pwnd);
|
|
BOOL xxxSetWindowPos(PWND pwnd, PWND pwndInsertAfter, int x, int y,
|
|
int cx, int cy, UINT flags);
|
|
PSMWP InternalBeginDeferWindowPos(int cwndGuess);
|
|
BOOL AllocateCvr (PSMWP psmwp, int cwndHint);
|
|
PSMWP _BeginDeferWindowPos(int cwndGuess);
|
|
PSMWP _DeferWindowPos(PSMWP psmwp, PWND pwnd, PWND pwndInsertAfter,
|
|
int x, int y, int cx, int cy, UINT rgf);
|
|
BOOL xxxEndDeferWindowPosEx(PSMWP psmwp, BOOL fAsync);
|
|
BOOL xxxMoveWindow(PWND pwnd, int x, int y, int cx, int cy, BOOL fRedraw);
|
|
PWND GetLastTopMostWindow(VOID);
|
|
VOID xxxHandleWindowPosChanged(PWND pwnd, PWINDOWPOS ppos);
|
|
VOID IncVisWindows(PWND pwnd);
|
|
VOID DecVisWindows(PWND pwnd);
|
|
BOOL FVisCountable(PWND pwnd);
|
|
VOID SetVisible(PWND pwnd, UINT flags);
|
|
VOID ClrFTrueVis(PWND pwnd);
|
|
|
|
VOID SetWindowState(PWND pwnd, DWORD flags);
|
|
VOID ClearWindowState(PWND pwnd, DWORD flags);
|
|
|
|
BOOL xxxUpdateWindows(PWND pwnd, HRGN hrgn);
|
|
|
|
VOID SetMinimize(PWND pwnd, UINT uFlags);
|
|
#define SMIN_CLEAR 0
|
|
#define SMIN_SET 1
|
|
|
|
PWND NextOwnedWindow(PWND pwnd, PWND pwndOwner, PWND pwndParent);
|
|
|
|
/*
|
|
* DWP.C
|
|
*/
|
|
LRESULT xxxDefWindowProc(PWND, UINT, WPARAM, LPARAM);
|
|
LRESULT xxxRealDefWindowProc(PWND, UINT, WPARAM, LPARAM);
|
|
PWND DWP_GetEnabledPopup(PWND pwndStart);
|
|
|
|
|
|
/*
|
|
* INPUT.C
|
|
*/
|
|
#ifdef MESSAGE_PUMP_HOOK
|
|
|
|
BOOL xxxWaitMessageEx(UINT fsWakeMask, DWORD Timeout);
|
|
__inline BOOL xxxWaitMessage(
|
|
VOID)
|
|
{
|
|
return xxxWaitMessageEx(QS_ALLINPUT | QS_EVENT, 0);
|
|
}
|
|
BOOL xxxRealWaitMessageEx(UINT fsWakeMask, DWORD Timeout);
|
|
|
|
#else
|
|
|
|
BOOL xxxWaitMessage(VOID);
|
|
|
|
#endif
|
|
|
|
VOID DBGValidateQueueStates(PDESKTOP pdesk);
|
|
VOID IdleTimerProc(VOID);
|
|
BOOL ValidateTimerCallback(PTHREADINFO, LPARAM);
|
|
VOID zzzWakeInputIdle(PTHREADINFO pti);
|
|
VOID SleepInputIdle(PTHREADINFO pti);
|
|
BOOL xxxInternalGetMessage(LPMSG lpmsg, HWND hwnd, UINT wMsgFilterMin,
|
|
UINT wMsgFilterMax, UINT wRemoveMsg, BOOL fGetMessage);
|
|
|
|
#ifdef MESSAGE_PUMP_HOOK
|
|
BOOL xxxRealInternalGetMessage(LPMSG lpMsg, HWND hwndFilter, UINT msgMin,
|
|
UINT msgMax, UINT flags, BOOL fGetMessage);
|
|
#endif
|
|
|
|
#define xxxPeekMessage(lpmsg, hwnd, wMsgMin, wMsgMax, wRemoveMsg) \
|
|
xxxInternalGetMessage(lpmsg, hwnd, wMsgMin, wMsgMax, wRemoveMsg, FALSE)
|
|
#define xxxGetMessage(lpmsg, hwnd, wMsgMin, wMsgMax) \
|
|
xxxInternalGetMessage(lpmsg, hwnd, wMsgMin, wMsgMax, PM_REMOVE, TRUE)
|
|
DWORD _GetMessagePos(VOID);
|
|
LRESULT xxxDispatchMessage(LPMSG lpmsg);
|
|
UINT GetMouseKeyFlags(PQ pq);
|
|
BOOL _PostMessage(PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
BOOL IPostQuitMessage(PTHREADINFO pti, int nExitCode);
|
|
BOOL _PostQuitMessage(int nExitCode);
|
|
BOOL _PostThreadMessage(PTHREADINFO pti, UINT message, WPARAM wParam, LPARAM lParam);
|
|
BOOL xxxTranslateMessage(LPMSG pmsg, UINT flags);
|
|
BOOL _GetInputState(VOID);
|
|
DWORD _GetQueueStatus(UINT);
|
|
typedef VOID (CALLBACK* MSGWAITCALLBACK)(DWORD DeviceType);
|
|
DWORD xxxMsgWaitForMultipleObjects(DWORD nCount, PVOID *apObjects, MSGWAITCALLBACK pfnNonMsg, PKWAIT_BLOCK WaitBlockArray);
|
|
|
|
BOOL FHungApp(PTHREADINFO pti, DWORD dwTimeFromLastRead);
|
|
VOID xxxRedrawHungWindow(PWND pwnd, HRGN hrgnFullDrag);
|
|
VOID xxxRedrawHungWindowFrame(PWND pwnd, BOOL fActive);
|
|
VOID zzzActiveCursorTracking (PWND pwnd);
|
|
PWND GetActiveTrackPwnd(PWND pwnd, Q **ppq);
|
|
int xxxActiveWindowTracking(PWND pwnd, UINT uMsg, int iHitTest);
|
|
VOID xxxHungAppDemon(PWND pwnd, UINT message, UINT_PTR nID, LPARAM lParam);
|
|
|
|
/*
|
|
* shadow.c
|
|
*/
|
|
BOOL WindowHasShadow(PWND pwnd);
|
|
BOOL xxxAddShadow(PWND pwnd);
|
|
VOID xxxRemoveShadow(PWND pwnd);
|
|
VOID CleanupShadow(PWND pwndShadow);
|
|
VOID MoveShadow(PWND pwnd);
|
|
VOID UpdateShadowShape(PWND pwnd);
|
|
VOID xxxUpdateShadowZorder(PWND pwnd);
|
|
BOOL FAnyShadows(VOID);
|
|
|
|
/*
|
|
* QUEUE.C
|
|
*/
|
|
__inline BOOL IsShellProcess(
|
|
PPROCESSINFO ppi)
|
|
{
|
|
return ((ppi->rpdeskStartup != NULL)
|
|
&& (ppi->rpdeskStartup->pDeskInfo->ppiShellProcess == ppi));
|
|
}
|
|
|
|
__inline DWORD GetAppCompatFlags2ForPti(
|
|
PTHREADINFO pti,
|
|
WORD wVer)
|
|
{
|
|
if (wVer < pti->dwExpWinVer) {
|
|
return 0;
|
|
}
|
|
|
|
return pti->dwCompatFlags2;
|
|
}
|
|
|
|
VOID ClearWakeMask(VOID);
|
|
VOID _AllowForegroundActivation(VOID);
|
|
|
|
ULONG GetTaskName(PTHREADINFO pti, PWSTR Buffer, ULONG BufferLength);
|
|
PQMSG FindQMsg(PTHREADINFO pti, PMLIST pml, PWND pwndFilter, UINT msgMin, UINT msgMax, BOOL bProcessAck);
|
|
VOID zzzShowStartGlass(DWORD dwTimeout);
|
|
DWORD _GetChangeBits(VOID);
|
|
NTSTATUS xxxSetCsrssThreadDesktop(PDESKTOP pdesk, PDESKRESTOREDATA pdrdRestore);
|
|
NTSTATUS xxxRestoreCsrssThreadDesktop(PDESKRESTOREDATA pdrdRestore);
|
|
|
|
PQ GetJournallingQueue(PTHREADINFO pti);
|
|
VOID ClearAppStarting (PPROCESSINFO ppi);
|
|
BOOL _GetProcessDefaultLayout(DWORD *pdwDefaultLayout);
|
|
BOOL _SetProcessDefaultLayout(DWORD dwDefaultLayout);
|
|
|
|
|
|
#ifdef HUNGAPP_GHOSTING
|
|
|
|
/*
|
|
* GHOST.C
|
|
*/
|
|
VOID _DisableProcessWindowsGhosting(VOID);
|
|
LRESULT xxxGhostWndProc(PWND, UINT, WPARAM, LPARAM);
|
|
VOID SignalGhost(PWND pwnd);
|
|
BOOL xxxCreateGhost(PWND pwnd);
|
|
VOID RemoveGhost(PWND pwnd);
|
|
PWND FindGhost(PWND pwnd);
|
|
BOOL GhostSizedOrMoved(PWND pwnd);
|
|
|
|
|
|
#define WM_HUNGTHREAD (WM_USER + 0)
|
|
#define WM_CREATETRAILTIMER (WM_USER + 1)
|
|
#define WM_SCANGHOST (WM_USER + 2)
|
|
|
|
VOID GhostThread(PDESKTOP pdesk);
|
|
|
|
__inline VOID SignalGhost(
|
|
PWND pwnd)
|
|
{
|
|
/*
|
|
* No ghosting for applications that are debugged, since it can
|
|
* make debugging confusing to developers.
|
|
*/
|
|
if (TestWF(pwnd, WFMINIMIZED) ||
|
|
(GETPTI(pwnd)->ppi->W32PF_Flags & W32PF_DISABLEWINDOWSGHOSTING) ||
|
|
(PsGetProcessDebugPort(GETPTI(pwnd)->ppi->Process) != NULL) ||
|
|
(GetAppCompatFlags2ForPti(GETPTI(pwnd), VERMAX) & GACF2_NOGHOST)) {
|
|
return;
|
|
}
|
|
|
|
_PostMessage(PWNDDESKTOP(pwnd), WM_HUNGTHREAD, 0, (LPARAM)HWq(pwnd));
|
|
}
|
|
|
|
#endif // HUNGAPP_GHOSTING
|
|
|
|
/*
|
|
* TMSWITCH.C
|
|
*/
|
|
VOID xxxSwitchToThisWindow(PWND pwnd, BOOL fAltTab);
|
|
|
|
/*
|
|
* TOUNICOD.C
|
|
*/
|
|
int xxxToUnicodeEx(UINT wVirtKey, UINT wScanCode, CONST BYTE *lpKeyState,
|
|
LPWSTR pwszBuff, int cchBuff, UINT wFlags, HKL hkl);
|
|
int xxxInternalToUnicode(UINT wVirtKey, UINT wScanCode, CONST IN PBYTE pfvk,
|
|
OUT PWCHAR awchChars, INT cChar, UINT uiTMFlags, OUT PDWORD pdwFlags, HKL hkl);
|
|
|
|
/*
|
|
* HOTKEYS.C
|
|
*/
|
|
BOOL _RegisterHotKey(PWND pwnd, int id, UINT fsModifiers, UINT vk);
|
|
BOOL _UnregisterHotKey(PWND pwnd, int id);
|
|
|
|
/*
|
|
* FOCUSACT.C
|
|
*/
|
|
PWND xxxSetFocus(PWND pwnd);
|
|
#ifdef FG_HOOKLOCK
|
|
#define FG_HOOKLOCK_PARAM(x) , x
|
|
#else
|
|
#define FG_HOOKLOCK_PARAM(x)
|
|
#endif
|
|
BOOL CanForceForeground(PPROCESSINFO ppi FG_HOOKLOCK_PARAM(PTHREADINFO pti));
|
|
BOOL xxxStubSetForegroundWindow(PWND pwnd);
|
|
BOOL xxxSetForegroundWindow(PWND pwnd, BOOL fFlash);
|
|
PWND xxxSetActiveWindow(PWND pwnd);
|
|
PWND _GetActiveWindow(VOID);
|
|
BOOL xxxAllowSetForegroundWindow(DWORD dwProcessId);
|
|
BOOL _LockSetForegroundWindow(UINT uLockCode);
|
|
|
|
/*
|
|
* UPDATE.C
|
|
*/
|
|
BOOL xxxInvalidateRect(PWND pwnd, LPRECT lprc, BOOL fErase);
|
|
BOOL xxxValidateRect(PWND pwnd, LPRECT lprc);
|
|
BOOL xxxInvalidateRgn(PWND pwnd, HRGN hrgn, BOOL fErase);
|
|
BOOL xxxValidateRgn(PWND pwnd, HRGN hrgn);
|
|
BOOL xxxUpdateWindow(PWND pwnd);
|
|
BOOL xxxGetUpdateRect(PWND pwnd, LPRECT lprc, BOOL fErase);
|
|
int xxxGetUpdateRgn(PWND pwnd, HRGN hrgn, BOOL fErase);
|
|
int _ExcludeUpdateRgn(HDC hdc, PWND pwnd);
|
|
int CalcWindowRgn(PWND pwnd, HRGN hrgn, BOOL fClient);
|
|
VOID DeleteUpdateRgn(PWND pwnd);
|
|
BOOL xxxRedrawWindow(PWND pwnd, LPRECT lprcUpdate, HRGN hrgnUpdate, DWORD flags);
|
|
BOOL IntersectWithParents(PWND pwnd, LPRECT lprc);
|
|
VOID xxxInternalInvalidate(PWND pwnd, HRGN hrgnUpdate, DWORD flags);
|
|
|
|
/*
|
|
* WINMGR.C
|
|
*/
|
|
BOOL xxxEnableWindow(PWND pwnd, BOOL fEnable);
|
|
int xxxGetWindowText(PWND pwnd, LPWSTR psz, int cchMax);
|
|
PWND xxxSetParent(PWND pwnd, PWND pwndNewParent);
|
|
BOOL xxxFlashWindow(PWND pwnd, DWORD dwFlags, DWORD dwTimeout);
|
|
extern ATOM gaFlashWState;
|
|
__inline DWORD GetFlashWindowState(
|
|
PWND pwnd)
|
|
{
|
|
return HandleToUlong(_GetProp(pwnd, MAKEINTATOM(gaFlashWState), PROPF_INTERNAL));
|
|
}
|
|
|
|
__inline VOID SetFlashWindowState(
|
|
PWND pwnd,
|
|
DWORD dwState)
|
|
{
|
|
InternalSetProp(pwnd, MAKEINTATOM(gaFlashWState),
|
|
(HANDLE)ULongToPtr(dwState), PROPF_INTERNAL | PROPF_NOPOOL);
|
|
}
|
|
__inline VOID RemoveFlashWindowState(
|
|
PWND pwnd)
|
|
{
|
|
InternalRemoveProp(pwnd, MAKEINTATOM(gaFlashWState), PROPF_INTERNAL);
|
|
}
|
|
BOOL _GetWindowPlacement(PWND pwnd, PWINDOWPLACEMENT pwp);
|
|
BOOL xxxSetWindowPlacement(PWND pwnd, PWINDOWPLACEMENT pwp);
|
|
BOOL ValidateParentDepth(PWND pwnd, PWND pwndParent);
|
|
BOOL ValidateOwnerDepth(PWND pwnd, PWND pwndOwner);
|
|
VOID WPUpdateCheckPointSettings (PWND pwnd, UINT uWPFlags);
|
|
|
|
/*
|
|
* DC.C
|
|
*/
|
|
HDC _GetDC(PWND pwnd);
|
|
HDC _GetDCEx(PWND pwnd, HRGN hrgnClip, DWORD flags);
|
|
HDC _GetWindowDC(PWND pwnd);
|
|
BOOL _ReleaseDC(HDC hdc);
|
|
UINT ReleaseCacheDC(HDC hdc, BOOL fEndPaint);
|
|
HDC CreateCacheDC(PWND, DWORD, PMONITOR);
|
|
BOOL DestroyCacheDC(PDCE *, HDC);
|
|
VOID InvalidateDce(PDCE pdce);
|
|
VOID DeleteHrgnClip(PDCE pdce);
|
|
PWND WindowFromCacheDC(HDC hdc);
|
|
PWND FastWindowFromDC(HDC hdc);
|
|
VOID DelayedDestroyCacheDC(VOID);
|
|
PDCE LookupDC(HDC hdc);
|
|
HDC GetMonitorDC(PDCE pdceOrig, PMONITOR pMonitor);
|
|
BOOL GetDCOrgOnScreen(HDC hdc, LPPOINT ppt);
|
|
__inline VOID MarkDCEInvalid(
|
|
PDCE pdce)
|
|
{
|
|
/*
|
|
* Clear all bits, but these.
|
|
*/
|
|
pdce->DCX_flags &= (DCX_CACHE | DCX_REDIRECTED);
|
|
|
|
/*
|
|
* Mark this cache entry as invalid
|
|
*/
|
|
pdce->DCX_flags |= DCX_INVALID;
|
|
}
|
|
|
|
BOOL MirrorRegion(PWND pwnd, HRGN hrgn, BOOL bUseClient);
|
|
|
|
/*
|
|
* PAINT.C
|
|
*/
|
|
HDC xxxBeginPaint(PWND pwnd, PAINTSTRUCT *lpps);
|
|
BOOL xxxEndPaint(PWND pwnd, PAINTSTRUCT *lpps);
|
|
|
|
/*
|
|
* CAPTURE.C
|
|
*/
|
|
PWND xxxSetCapture(PWND pwnd);
|
|
BOOL xxxReleaseCapture(VOID);
|
|
|
|
/*
|
|
* KEYBOARD.C
|
|
*/
|
|
SHORT _GetAsyncKeyState(int vk);
|
|
BOOL _SetKeyboardState(CONST BYTE *pKeyboard);
|
|
int _GetKeyboardType(int nTypeFlag);
|
|
VOID RegisterPerUserKeyboardIndicators(PUNICODE_STRING pProfileUserName);
|
|
VOID UpdatePerUserKeyboardIndicators(PUNICODE_STRING pProfileUserName);
|
|
VOID UpdatePerUserKeyboardMappings(PUNICODE_STRING pProfileUserName);
|
|
|
|
#define TestRawKeyDown(vk) TestKeyDownBit(gafRawKeyState, vk)
|
|
#define SetRawKeyDown(vk) SetKeyDownBit(gafRawKeyState, vk)
|
|
#define ClearRawKeyDown(vk) ClearKeyDownBit(gafRawKeyState, vk)
|
|
#define TestRawKeyToggle(vk) TestKeyToggleBit(gafRawKeyState, vk)
|
|
#define SetRawKeyToggle(vk) SetKeyToggleBit(gafRawKeyState, vk)
|
|
#define ClearRawKeyToggle(vk) ClearKeyToggleBit(gafRawKeyState, vk)
|
|
#define ToggleRawKeyToggle(vk) ToggleKeyToggleBit(gafRawKeyState, vk)
|
|
|
|
/*
|
|
* XLATE.C
|
|
*/
|
|
int _GetKeyNameText(LONG lParam, LPWSTR lpString, int nSize);
|
|
|
|
/*
|
|
* TIMERS.C
|
|
*/
|
|
BOOL _KillTimer(PWND pwnd, UINT_PTR nIDEvent);
|
|
PTIMER FindTimer(PWND pwnd, UINT_PTR nID, UINT flags, BOOL fKill);
|
|
VOID xxxSystemTimerProc(PWND pwnd, UINT msg, UINT_PTR id, LPARAM lParam);
|
|
|
|
|
|
/*
|
|
* CARET.C
|
|
*/
|
|
BOOL zzzDestroyCaret(VOID);
|
|
BOOL xxxCreateCaret(PWND, HBITMAP, int, int);
|
|
BOOL zzzShowCaret(PWND);
|
|
BOOL zzzHideCaret(PWND);
|
|
BOOL _SetCaretBlinkTime(UINT);
|
|
BOOL zzzSetCaretPos(int, int);
|
|
|
|
/*
|
|
* MSGBEEP.C
|
|
*/
|
|
BOOL xxxOldMessageBeep(VOID);
|
|
BOOL xxxMessageBeep(UINT wType);
|
|
VOID PlayEventSound(UINT idSound);
|
|
|
|
/*
|
|
* WINWHERE.C
|
|
*/
|
|
PWND _ChildWindowFromPointEx(PWND pwndParent, POINT pt, UINT i);
|
|
PWND xxxWindowFromPoint(POINT pt);
|
|
PWND SizeBoxHwnd(PWND pwnd);
|
|
|
|
/*
|
|
* GETSET.C
|
|
*/
|
|
WORD _SetWindowWord(PWND pwnd, int index, WORD value);
|
|
DWORD xxxSetWindowLong(PWND pwnd, int index, DWORD value, BOOL bAnsi);
|
|
#ifdef _WIN64
|
|
ULONG_PTR xxxSetWindowLongPtr(PWND pwnd, int index, ULONG_PTR value, BOOL bAnsi);
|
|
#else
|
|
#define xxxSetWindowLongPtr xxxSetWindowLong
|
|
#endif
|
|
#define __GetWindowLong(pwnd, index) ((LONG)(*(DWORD UNALIGNED *)((BYTE *)((pwnd) + 1) + (index))))
|
|
#define __GetWindowLongPtr(pwnd, index) ((LONG_PTR)(*(ULONG_PTR UNALIGNED *)((BYTE *)((pwnd) + 1) + (index))))
|
|
#if DBG
|
|
ULONG DBGGetWindowLong(PWND pwnd, int index);
|
|
#define _GetWindowLong DBGGetWindowLong
|
|
ULONG_PTR DBGGetWindowLongPtr(PWND pwnd, int index);
|
|
#define _GetWindowLongPtr DBGGetWindowLongPtr
|
|
#else
|
|
#define _GetWindowLong __GetWindowLong
|
|
#define _GetWindowLongPtr __GetWindowLongPtr
|
|
#endif
|
|
|
|
/*
|
|
* CLIPBRD.C
|
|
*/
|
|
BOOL _OpenClipboard(PWND pwnd, LPBOOL lpfEmptyClient);
|
|
BOOL xxxCloseClipboard(PWINDOWSTATION pwinsta);
|
|
UINT _EnumClipboardFormats(UINT fmt);
|
|
BOOL xxxEmptyClipboard(PWINDOWSTATION pwinsta);
|
|
HANDLE xxxGetClipboardData(PWINDOWSTATION pwinsta, UINT fmt, PGETCLIPBDATA gcd);
|
|
BOOL _IsClipboardFormatAvailable(UINT fmt);
|
|
int _GetPriorityClipboardFormat(UINT *lpPriorityList, int cfmts);
|
|
PWND xxxSetClipboardViewer(PWND pwndClipViewerNew);
|
|
BOOL xxxChangeClipboardChain(PWND pwndRemove, PWND pwndNewNext);
|
|
|
|
/*
|
|
* miscutil.c
|
|
*/
|
|
VOID SetDialogPointer(PWND pwnd, LONG_PTR lPtr);
|
|
VOID ZapActiveAndFocus(VOID);
|
|
BOOL xxxSetShellWindow(PWND pwnd, PWND pwndBkGnd);
|
|
BOOL _SetProgmanWindow(PWND pwnd);
|
|
BOOL _SetTaskmanWindow(PWND pwnd);
|
|
|
|
#define STW_SAME ((PWND) 1)
|
|
VOID xxxSetTrayWindow(PDESKTOP pdesk, PWND pwnd, PMONITOR pMonitor);
|
|
BOOL xxxAddFullScreen(PWND pwnd, PMONITOR pMonitor);
|
|
BOOL xxxRemoveFullScreen(PWND pwnd, PMONITOR pMonitor);
|
|
BOOL xxxCheckFullScreen(PWND pwnd, PSIZERECT psrc);
|
|
BOOL IsTrayWindow(PWND);
|
|
|
|
#define FDoTray() (SYSMET(ARRANGE) & ARW_HIDE)
|
|
#define FCallHookTray() (IsHooked(PtiCurrent(), WHF_SHELL))
|
|
#define FPostTray(p) (p->pDeskInfo->spwndTaskman)
|
|
#define FCallTray(p) (FDoTray() && ( FCallHookTray()|| FPostTray(p) ))
|
|
|
|
// ----------------------------------------------------------------------------
|
|
//
|
|
// FTopLevel() - TRUE if window is a top level window
|
|
//
|
|
// FHas31TrayStyles() - TRUE if window is either full screen or has
|
|
// both a system menu and a caption
|
|
// (NOTE: minimized windows always have captions)
|
|
//
|
|
// ----------------------------------------------------------------------------
|
|
#define FTopLevel(pwnd) (pwnd->spwndParent == PWNDDESKTOP(pwnd))
|
|
#define FHas31TrayStyles(pwnd) (TestWF(pwnd, WFFULLSCREEN) || \
|
|
(TestWF(pwnd, WFSYSMENU | WFMINBOX) && \
|
|
(TestWF(pwnd, WFCAPTION) || TestWF(pwnd, WFMINIMIZED))))
|
|
BOOL Is31TrayWindow(PWND pwnd);
|
|
|
|
/*
|
|
* fullscr.c
|
|
*/
|
|
|
|
#if DBG
|
|
|
|
__inline VOID VerifyVisibleMonitorCount(
|
|
VOID)
|
|
{
|
|
extern PDISPLAYINFO gpDispInfo;
|
|
PMONITOR pMonitor = gpDispInfo->pMonitorFirst;
|
|
ULONG cVisMon = 0;
|
|
|
|
while (pMonitor) {
|
|
if (pMonitor->dwMONFlags & MONF_VISIBLE) {
|
|
cVisMon++;
|
|
}
|
|
pMonitor = pMonitor->pMonitorNext;
|
|
}
|
|
|
|
UserAssert(cVisMon == gpDispInfo->cMonitors);
|
|
}
|
|
|
|
#else
|
|
#define VerifyVisibleMonitorCount()
|
|
#endif
|
|
|
|
BOOL xxxMakeWindowForegroundWithState(PWND, BYTE);
|
|
VOID FullScreenCleanup(VOID);
|
|
LONG xxxUserChangeDisplaySettings(
|
|
PUNICODE_STRING pstrDeviceName,
|
|
LPDEVMODEW pDevMode,
|
|
PDESKTOP pdesk,
|
|
DWORD dwFlags,
|
|
PVOID lParam,
|
|
MODE PreviousMode);
|
|
BOOL xxxbFullscreenSwitch(BOOL bFullscreenSwitch, HWND hwnd);
|
|
|
|
|
|
/*
|
|
* SBAPI.C
|
|
*/
|
|
BOOL xxxShowScrollBar(PWND, UINT, BOOL);
|
|
|
|
/*
|
|
* mngray.c
|
|
*/
|
|
BOOL xxxDrawState(HDC hdcDraw, HBRUSH hbrFore,
|
|
LPARAM lData, int x, int y, int cx, int cy, UINT uFlags);
|
|
|
|
/*
|
|
* SCROLLW.C
|
|
*/
|
|
BOOL _ScrollDC(HDC hdc, int dx, int dy, LPRECT prcSrc, LPRECT prcClip,
|
|
HRGN hrgnUpdate, LPRECT prcUpdate);
|
|
|
|
/*
|
|
* SPB.C
|
|
*/
|
|
VOID SpbCheckRect(PWND pwnd, LPRECT lprc, DWORD flags);
|
|
VOID SpbCheck(VOID);
|
|
PSPB FindSpb(PWND pwnd);
|
|
VOID FreeSpb(PSPB pspb);
|
|
VOID FreeAllSpbs(VOID);
|
|
VOID CreateSpb(PWND pwnd, UINT flags, HDC hdcScreen);
|
|
UINT RestoreSpb(PWND pwnd, HRGN hrgnUncovered, HDC *phdcScreen);
|
|
VOID SpbCheckPwnd(PWND pwnd);
|
|
VOID SpbCheckDce(PDCE pdce);
|
|
BOOL LockWindowUpdate2(PWND pwndLock, BOOL fThreadOverride);
|
|
|
|
/*
|
|
* DRAWFRM.C
|
|
*/
|
|
BOOL BitBltSysBmp(HDC hdc, int x, int y, UINT i);
|
|
|
|
/*
|
|
* SYSMET.c
|
|
*/
|
|
BOOL APIENTRY xxxSetSysColors(PUNICODE_STRING pProfileUserName,int count, PUINT pIndex, LPDWORD pClrVal, UINT uOptions);
|
|
VOID SetSysColor(UINT icol, DWORD rgb, UINT uOptions);
|
|
|
|
/*
|
|
* ICONS.C
|
|
*/
|
|
UINT xxxArrangeIconicWindows(PWND pwnd);
|
|
BOOL _SetSystemMenu(PWND pwnd, PMENU pMenu);
|
|
|
|
/*
|
|
* RMCREATE.C
|
|
*/
|
|
PICON _CreateIconIndirect(PICONINFO piconinfo);
|
|
PCURSOR _CreateCursor(HANDLE hModule, int iXhotspot, int iYhotspot,
|
|
int iWidth, int iHeight, LPBYTE lpANDplane, LPBYTE lpXORplane);
|
|
PICON _CreateIcon(HANDLE hModule, int iWidth, int iHeight,
|
|
BYTE bPlanes, BYTE bBitsPixel, LPBYTE lpANDplane, LPBYTE lpXORplane);
|
|
VOID DestroyUnlockedCursor(VOID *pv);
|
|
BOOL _DestroyCursor(PCURSOR pcur, DWORD cmdDestroy);
|
|
HANDLE _CreateAcceleratorTable(LPACCEL ccxpaccel, int cbAccel);
|
|
|
|
/*
|
|
* CURSOR.C
|
|
*/
|
|
#if DBG
|
|
PCURSOR DbgLockQCursor(PQ pq, PCURSOR pcur);
|
|
#define LockQCursor(pq, pcur) DbgLockQCursor(pq, pcur)
|
|
#else
|
|
#define LockQCursor(pq, pcur) Lock(&pq->spcurCurrent, pcur)
|
|
#endif // DBG
|
|
|
|
PCURSOR zzzSetCursor(PCURSOR pcur);
|
|
BOOL zzzSetCursorPos(int x, int y);
|
|
int zzzShowCursor(BOOL fShow);
|
|
BOOL zzzClipCursor(LPCRECT prcClip);
|
|
PCURSOR _GetCursor(VOID);
|
|
BOOL _SetCursorContents(PCURSOR pcur, PCURSOR pcurNew);
|
|
VOID SetPointer(BOOL fSet);
|
|
VOID zzzHideCursorNoCapture(VOID);
|
|
#define GETPCI(pcur) ((PCURSINFO)&(pcur->CI_FIRST))
|
|
|
|
/*
|
|
* WMICON.C
|
|
*/
|
|
BOOL _DrawIconEx(HDC hdc, int x, int y, PCURSOR pcur, int cx, int cy,
|
|
UINT istepIfAniCur, HBRUSH hbrush, UINT diFlags) ;
|
|
BOOL BltIcon(HDC hdc, int x, int y, int cx, int cy,
|
|
HDC hdcSrc, PCURSOR pcursor, UINT diFlag, LONG rop);
|
|
|
|
/*
|
|
* DESKTOP.C
|
|
*/
|
|
|
|
__inline VOID xxxCleanupMotherDesktopWindow(
|
|
PTERMINAL pTerm)
|
|
{
|
|
PWND pwnd = pTerm->spwndDesktopOwner;
|
|
|
|
/*
|
|
* Hide the window first.
|
|
*/
|
|
SetVisible(pwnd, SV_UNSET);
|
|
pTerm->dwTERMF_Flags |= TERMF_MOTHERWND_DESTROYED;
|
|
|
|
if(Unlock(&(pTerm->spwndDesktopOwner))) {
|
|
xxxDestroyWindow(pwnd);
|
|
}
|
|
}
|
|
|
|
HDESK xxxCreateDesktop(
|
|
POBJECT_ATTRIBUTES,
|
|
KPROCESSOR_MODE,
|
|
PUNICODE_STRING,
|
|
LPDEVMODEW,
|
|
DWORD,
|
|
DWORD);
|
|
|
|
#define CST_MAX_THREADS 30
|
|
|
|
/*
|
|
* Flags for xxxSwitchDesktop().
|
|
*/
|
|
#define SDF_CREATENEW 0x01 /* New desktop, don't send enable/disable */
|
|
#define SDF_SLOVERRIDE 0x02 /* Don't respect WSF_SWITCHLOCK on pwinsta */
|
|
|
|
HDESK _OpenDesktop(POBJECT_ATTRIBUTES ccxObja, KPROCESSOR_MODE AccessMode, DWORD dwFlags, DWORD dwDesiredAccess, BOOL *pbShutDown);
|
|
BOOL OpenDesktopCompletion(PDESKTOP pdesk, HDESK hdesk, DWORD dwFlags, BOOL *pbShutDown);
|
|
BOOL xxxSwitchDesktop(PWINDOWSTATION pwinsta, PDESKTOP pdesk, DWORD dwFlags);
|
|
BOOL zzzSetDesktop(PTHREADINFO pti, PDESKTOP pdesk, HDESK hdesk);
|
|
HDESK _GetInputDesktop(VOID);
|
|
BOOL xxxSetThreadDesktop(HDESK hdesk, PDESKTOP pdesk);
|
|
HDESK xxxGetThreadDesktop(DWORD dwThread, HDESK hdeskConsole, KPROCESSOR_MODE AccessMode);
|
|
BOOL xxxCloseDesktop(HDESK hdesk, KPROCESSOR_MODE AccessMode);
|
|
DWORD _SetDesktopConsoleThread(PDESKTOP pdesk, DWORD dwThreadId);
|
|
VOID xxxRealizeDesktop(PWND pwnd);
|
|
|
|
/*
|
|
* Flags for GetDesktopHeapSize().
|
|
*/
|
|
#define DHS_LOGON 0x1
|
|
#define DHS_DISCONNECT 0x2
|
|
#define DHS_NOIO 0x3
|
|
|
|
ULONG GetDesktopHeapSize(
|
|
USHORT usFlags);
|
|
|
|
/*
|
|
* WINSTA.C
|
|
*/
|
|
NTSTATUS CreateGlobalAtomTable(
|
|
PVOID* ppAtomTable);
|
|
|
|
HWINSTA xxxCreateWindowStation(
|
|
POBJECT_ATTRIBUTES ObjA,
|
|
KPROCESSOR_MODE OwnershipMode,
|
|
DWORD amRequest,
|
|
HANDLE hKbdLayoutFile,
|
|
DWORD offTable,
|
|
PKBDTABLE_MULTI_INTERNAL pKbdTableMulti,
|
|
PCWSTR pwszKLID,
|
|
UINT uKbdInputLocale);
|
|
|
|
HWINSTA _OpenWindowStation(
|
|
POBJECT_ATTRIBUTES pObjA,
|
|
DWORD dwDesiredAccess,
|
|
KPROCESSOR_MODE AccessMode);
|
|
|
|
BOOL _CloseWindowStation(
|
|
HWINSTA hwinsta);
|
|
|
|
NTSTATUS _SetProcessWindowStation(
|
|
HWINSTA hwinsta,
|
|
KPROCESSOR_MODE AccessMode);
|
|
|
|
PWINDOWSTATION _GetProcessWindowStation(
|
|
HWINSTA *phwinsta);
|
|
|
|
BOOL _LockWorkStation(
|
|
VOID);
|
|
|
|
NTSTATUS ReferenceWindowStation(
|
|
PETHREAD Thread,
|
|
HWINSTA hwinsta,
|
|
ACCESS_MASK amDesiredAccess,
|
|
PWINDOWSTATION *ppwinsta,
|
|
BOOL fUseDesktop);
|
|
|
|
/*
|
|
* HOOKS.C
|
|
*/
|
|
PROC zzzSetWindowsHookAW(int nFilterType, PROC pfnFilterProc, DWORD dwFlags);
|
|
BOOL zzzUnhookWindowsHookEx(PHOOK phk);
|
|
BOOL zzzUnhookWindowsHook(int nFilterType, PROC pfnFilterProc);
|
|
LRESULT xxxCallNextHookEx(int nCode, WPARAM wParam, LPARAM lParam);
|
|
BOOL _CallMsgFilter(LPMSG lpMsg, int nCode);
|
|
VOID zzzCancelJournalling(VOID);
|
|
#if DBG
|
|
VOID DbgValidateHooks(PHOOK phk, int iType);
|
|
#else
|
|
#define DbgValidateHooks(phk, iType)
|
|
#endif
|
|
BOOL _RegisterUserApiHook(PUNICODE_STRING pstrLib, ULONG_PTR offPfnInitDefWindowProc);
|
|
BOOL _UnregisterUserApiHook(VOID);
|
|
BOOL xxxLoadUserApiHook(VOID);
|
|
|
|
|
|
extern int gihmodUserApiHook;
|
|
|
|
__inline BOOL IsInsideUserApiHook(
|
|
VOID)
|
|
{
|
|
return gihmodUserApiHook >= 0;
|
|
}
|
|
|
|
#ifdef MESSAGE_PUMP_HOOK
|
|
|
|
BOOL _DoInitMessagePumpHook(VOID);
|
|
BOOL _DoUninitMessagePumpHook(VOID);
|
|
|
|
extern PTHREADINFO gptiCurrent;
|
|
|
|
__inline BOOL IsInsideMPH(
|
|
VOID)
|
|
{
|
|
PCLIENTTHREADINFO pcti = PtiCurrent()->pcti;
|
|
return pcti->cMessagePumpHooks > 0;
|
|
}
|
|
|
|
#endif // MESSAGE_PUMP_HOOK
|
|
|
|
|
|
/*
|
|
* SRVHOOK.C
|
|
*/
|
|
LRESULT fnHkINLPCWPEXSTRUCT(PWND pwnd, UINT message, WPARAM wParam,
|
|
LPARAM lParam, ULONG_PTR xParam);
|
|
LRESULT fnHkINLPCWPRETEXSTRUCT(PWND pwnd, UINT message, WPARAM wParam,
|
|
LPARAM lParam, ULONG_PTR xParam);
|
|
|
|
/*
|
|
* EXITWIN.C
|
|
*/
|
|
LONG xxxClientShutdown(PWND pwnd, WPARAM wParam);
|
|
BOOL xxxRegisterUserHungAppHandlers(PFNW32ET pfnW32EndTask, HANDLE hEventWowExec);
|
|
|
|
/*
|
|
* INIT.C
|
|
*/
|
|
BOOL CreateTerminalInput(PTERMINAL pTerm);
|
|
|
|
VOID LW_LoadProfileInitData(PUNICODE_STRING pProfileUserName);
|
|
VOID xxxODI_ColorInit(PUNICODE_STRING pProfileUserName);
|
|
HRGN InitCreateRgn(VOID);
|
|
VOID xxxUpdateSystemCursorsFromRegistry(PUNICODE_STRING pProfileUserName);
|
|
VOID xxxUpdateSystemIconsFromRegistry(PUNICODE_STRING pProfileUserName);
|
|
VOID RegisterLPK(DWORD dwLpkEntryPoints);
|
|
HBITMAP CreateCaptionStrip(VOID);
|
|
|
|
BOOL LW_BrushInit(VOID);
|
|
VOID xxxLW_LoadFonts(BOOL bRemote);
|
|
|
|
VOID _LoadCursorsAndIcons(VOID);
|
|
|
|
VOID UnloadCursorsAndIcons(VOID);
|
|
|
|
VOID IncrMBox(VOID);
|
|
VOID DecrMBox(VOID);
|
|
VOID InitAnsiOem(PCHAR pOemToAnsi, PCHAR pAnsiToOem);
|
|
int xxxAddFontResourceW(LPWSTR lpFile, FLONG flags, DESIGNVECTOR *pdv);
|
|
VOID EnforceColorDependentSettings(VOID);
|
|
|
|
|
|
/*
|
|
* ACCESS.C
|
|
*/
|
|
VOID xxxUpdatePerUserAccessPackSettings(PUNICODE_STRING pProfileUserName);
|
|
|
|
/*
|
|
* inctlpan.c
|
|
*/
|
|
VOID GetWindowNCMetrics(LPNONCLIENTMETRICS lpnc);
|
|
|
|
HFONT CreateFontFromWinIni(PUNICODE_STRING pProfileUserName,LPLOGFONT lplf, UINT idFont);
|
|
VOID SetMinMetrics(PUNICODE_STRING pProfileUserName,LPMINIMIZEDMETRICS lpmin);
|
|
BOOL xxxSetWindowNCMetrics(PUNICODE_STRING pProfileUserName,LPNONCLIENTMETRICS lpnc, BOOL fSizeChange, int clNewBorder);
|
|
BOOL SetIconMetrics(PUNICODE_STRING pProfileUserName,LPICONMETRICS lpicon);
|
|
BOOL xxxSetNCFonts(PUNICODE_STRING pProfileUserName, LPNONCLIENTMETRICS lpnc);
|
|
BOOL CreateBitmapStrip(VOID);
|
|
BOOL UpdateWinIniInt(PUNICODE_STRING pProfileUserName, UINT idSection, UINT wKeyNameId, int value);
|
|
|
|
/*
|
|
* rare.c
|
|
*/
|
|
VOID SetDesktopMetrics(VOID);
|
|
VOID SetMsgBox(PWND pwnd);
|
|
|
|
BOOL _RegisterShellHookWindow(PWND pwnd);
|
|
BOOL _DeregisterShellHookWindow(PWND pwnd);
|
|
BOOL xxxSendMinRectMessages(PWND pwnd, RECT *lpRect);
|
|
void PostShellHookMessages(UINT message, LPARAM lParam);
|
|
VOID _ResetDblClk(VOID);
|
|
VOID xxxSimulateShiftF10(VOID);
|
|
BOOL VWPLAdd(PVWPL *ppvwpl, PWND pwnd, DWORD dwThreshold);
|
|
BOOL VWPLRemove(PVWPL *ppvwpl, PWND pwnd);
|
|
PWND VWPLNext(PVWPL pvwpl, PWND pwndPrev, DWORD *pnPrev);
|
|
|
|
/*
|
|
* DDETRACK STUFF
|
|
*/
|
|
|
|
#if DBG
|
|
VOID ValidatePublicObjectList(VOID);
|
|
VOID TraceDdeMsg(UINT msg, HWND hwndFrom, HWND hwndTo, UINT code);
|
|
#define MSG_SENT 0
|
|
#define MSG_POST 1
|
|
#define MSG_RECV 2
|
|
#define MSG_PEEK 3
|
|
#else
|
|
#define ValidatePublicObjectList()
|
|
#define TraceDdeMsg(m, h1, h2, c)
|
|
#endif // DBG
|
|
|
|
typedef struct tagFREELIST {
|
|
struct tagFREELIST *next;
|
|
HANDLE h; // CSR client side GMEM_DDESHARE handle
|
|
DWORD flags; // XS_ flags describing data
|
|
} FREELIST, *PFREELIST;
|
|
|
|
typedef struct tagDDEIMP {
|
|
SECURITY_QUALITY_OF_SERVICE qos;
|
|
SECURITY_CLIENT_CONTEXT ClientContext;
|
|
short cRefInit;
|
|
short cRefConv;
|
|
} DDEIMP, *PDDEIMP;
|
|
|
|
typedef struct tagDDECONV {
|
|
THROBJHEAD head; // HM header
|
|
struct tagDDECONV *snext;
|
|
struct tagDDECONV *spartnerConv; // siamese twin
|
|
PWND spwnd; // associated pwnd
|
|
PWND spwndPartner; // associated partner pwnd
|
|
struct tagXSTATE *spxsOut; // transaction info queue - out point
|
|
struct tagXSTATE *spxsIn; // transaction info queue - in point
|
|
struct tagFREELIST *pfl; // free list
|
|
DWORD flags; // CXF_ flags
|
|
struct tagDDEIMP *pddei; // impersonation information
|
|
} DDECONV, *PDDECONV;
|
|
|
|
typedef DWORD (FNDDERESPONSE)(PDWORD pmsg, LPARAM *plParam, PDDECONV pDdeConv);
|
|
typedef FNDDERESPONSE *PFNDDERESPONSE;
|
|
|
|
typedef struct tagXSTATE {
|
|
THROBJHEAD head; // HM header
|
|
struct tagXSTATE *snext;
|
|
PFNDDERESPONSE fnResponse; // proc to handle next msg.
|
|
HANDLE hClient; // GMEM_DDESAHRE handle on client side
|
|
HANDLE hServer; // GMEM_DDESHARE handle on server side
|
|
PINTDDEINFO pIntDdeInfo; // DDE data being transfered
|
|
DWORD flags; // XS_ flags describing transaction/data
|
|
} XSTATE, *PXSTATE;
|
|
|
|
// values for flags field
|
|
|
|
#define CXF_IS_SERVER 0x0001
|
|
#define CXF_TERMINATE_POSTED 0x0002
|
|
#define CXF_PARTNER_WINDOW_DIED 0x0004
|
|
#define CXF_INTRA_PROCESS 0x8000
|
|
|
|
BOOL xxxDDETrackSendHook(PWND pwndTo, DWORD message, WPARAM wParam, LPARAM lParam);
|
|
DWORD xxxDDETrackPostHook(PUINT pmessage, PWND pwndTo, WPARAM wParam, LPARAM *plParam, BOOL fSent);
|
|
VOID FreeDdeXact(PXSTATE pxs);
|
|
|
|
VOID xxxDDETrackGetMessageHook(PMSG pmsg);
|
|
VOID xxxDDETrackWindowDying(PWND pwnd, PDDECONV pDdeConv);
|
|
VOID FreeDdeConv(PDDECONV pDdeConv);
|
|
BOOL _ImpersonateDdeClientWindow(PWND pwndClient, PWND pwndServer);
|
|
|
|
|
|
typedef struct tagMONITORPOS
|
|
{
|
|
RECT rcMonitor; /* where the monitor rect was */
|
|
RECT rcWork; /* where the work rect was */
|
|
PMONITOR pMonitor; /* what new monitor gets its windows */
|
|
} MONITORPOS, *PMONITORPOS;
|
|
|
|
typedef struct tagMONITORRECTS
|
|
{
|
|
int cMonitor; /* number of monitors */
|
|
MONITORPOS amp[1]; /* the monitor positions */
|
|
} MONITORRECTS, *PMONITORRECTS;
|
|
|
|
|
|
// stuctures for windows resize/ reposition on reconnect.
|
|
// when disconnecting from local console, these structures allow
|
|
// to memorize the monitors layout and windows size and positions
|
|
// on the monitors. When reconnecting back to local console, the snapshot
|
|
// is used to restore windows positions for windows that still exist.
|
|
|
|
|
|
typedef struct tagWPSNAPSHOT
|
|
{
|
|
RECT rcWindow; /* Windows rect */
|
|
HWND hwnd; /* hwnd */
|
|
} WPSNAPSHOT, *PWPSNAPSHOT;
|
|
|
|
typedef struct tagWMSNAPSHOT
|
|
{
|
|
PMONITORRECTS pmr; /* Monitors and their dimensions and positions */
|
|
PWPSNAPSHOT pwps; /* Windows and their dimensions and positions */
|
|
int cWindows; /* number of windows in pwps */
|
|
} WMSNAPSHOT, *PWMSNAPSHOT;
|
|
|
|
NTSTATUS RestoreMonitorsAndWindowsRects(VOID);
|
|
NTSTATUS SnapShotMonitorsAndWindowsRects(VOID);
|
|
VOID CleanupMonitorsAndWindowsSnapShot(VOID);
|
|
PWPSNAPSHOT SnapshotWindowRects(int *pnWindows);
|
|
|
|
PMONITORRECTS SnapshotMonitorRects(VOID);
|
|
VOID xxxDesktopRecalc(PMONITORRECTS pmrOld);
|
|
VOID UpdateMonitorRectsSnapShot(PMONITORRECTS pmr);
|
|
BOOL IsValidMonitor(PMONITOR pMonitor);
|
|
|
|
BOOL _SetDoubleClickTime(UINT dtTime);
|
|
BOOL _SwapMouseButton(BOOL fSwapButtons);
|
|
VOID xxxDestroyThreadInfo(VOID);
|
|
|
|
BOOL _GetWindowPlacement(PWND pwnd, PWINDOWPLACEMENT pwp);
|
|
|
|
PMENU xxxGetSystemMenu(PWND pWnd, BOOL bRevert);
|
|
PMENU _CreateMenu(VOID);
|
|
PMENU _CreatePopupMenu(VOID);
|
|
BOOL _DestroyMenu(PMENU pMenu);
|
|
DWORD _CheckMenuItem(PMENU pMenu, UINT wIDCheckItem, UINT wCheck);
|
|
DWORD xxxEnableMenuItem(PMENU pMenu, UINT wIDEnableItem, UINT wEnable);
|
|
|
|
PWND _GetNextQueueWindow(PWND pwnd, BOOL fDir, BOOL fAltEsc);
|
|
|
|
UINT_PTR _SetSystemTimer(PWND pwnd, UINT_PTR nIDEvent, DWORD dwElapse,
|
|
TIMERPROC_PWND pTimerFunc);
|
|
BOOL _SetClipboardData(UINT fmt, HANDLE hData, BOOL fGlobalHandle, BOOL fIncSerialNumber);
|
|
WORD _SetClassWord(PWND pwnd, int index, WORD value);
|
|
DWORD xxxSetClassLong(PWND pwnd, int index, DWORD value, BOOL bAnsi);
|
|
#ifdef _WIN64
|
|
ULONG_PTR xxxSetClassLongPtr(PWND pwnd, int index, ULONG_PTR value, BOOL bAnsi);
|
|
#else
|
|
#define xxxSetClassLongPtr xxxSetClassLong
|
|
#endif
|
|
ATOM _RegisterClassEx(LPWNDCLASSVEREX pwc,
|
|
PCLSMENUNAME pcmn,
|
|
WORD fnid,
|
|
DWORD dwFlags,
|
|
LPDWORD pdwWOW);
|
|
BOOL xxxHiliteMenuItem(PWND pwnd, PMENU pmenu, UINT cmd, UINT flags);
|
|
HANDLE _CreateAcceleratorTable(LPACCEL paccel, int cbAccel);
|
|
HANDLE xxxGetInputEvent(DWORD dwWakeMask);
|
|
BOOL _UnregisterClass(LPCWSTR lpszClassName, HANDLE hModule, PCLSMENUNAME pcmn);
|
|
ATOM _GetClassInfoEx(HANDLE hModule, LPCWSTR lpszClassName, LPWNDCLASSEX pwc, LPWSTR *ppszMenuName, BOOL bAnsi);
|
|
PWND _WindowFromDC(HDC hdc);
|
|
PCLS _GetWOWClass(HANDLE hModule, LPCWSTR lpszClassName);
|
|
LRESULT xxxHkCallHook(PHOOK phk, int nCode, WPARAM wParam, LPARAM lParam);
|
|
PHOOK zzzSetWindowsHookEx(HANDLE hmod, PUNICODE_STRING pstrLib,
|
|
PTHREADINFO ptiThread, int nFilterType, PROC pfnFilterProc, DWORD dwFlags);
|
|
DWORD GetDebugHookLParamSize(WPARAM wParam, PDEBUGHOOKINFO pdebughookstruct);
|
|
BOOL _RegisterLogonProcess(DWORD dwProcessId, BOOL fSecure);
|
|
UINT _LockWindowStation(PWINDOWSTATION pwinsta);
|
|
BOOL _UnlockWindowStation(PWINDOWSTATION pwinsta);
|
|
BOOL _SetWindowStationUser(PWINDOWSTATION pwinsta, PLUID pluidUser,
|
|
PSID psidUser, DWORD cbsidUser);
|
|
BOOL _SetDesktopBitmap(PDESKTOP pdesk, HBITMAP hbitmap, DWORD dwStyle);
|
|
|
|
BOOL _SetLogonNotifyWindow(PWND pwnd);
|
|
|
|
|
|
BOOL _RegisterTasklist(PWND pwndTasklist);
|
|
LONG_PTR _SetMessageExtraInfo(LONG_PTR);
|
|
VOID xxxRemoveEvents(PQ pq, int nQueue, DWORD flags);
|
|
|
|
PPCLS _InnerGetClassPtr(ATOM atom, PPCLS ppclsList, HANDLE hModule);
|
|
|
|
/*
|
|
* ntcb.h funtions.
|
|
*/
|
|
DWORD ClientGetListboxString(PWND hwnd, UINT msg,
|
|
WPARAM wParam, PVOID lParam,
|
|
ULONG_PTR xParam, PROC xpfn, DWORD dwSCMSFlags, BOOL bNotString, PSMS psms);
|
|
HANDLE ClientLoadLibrary(PUNICODE_STRING pstrLib, ULONG_PTR offPfnInitDefWindowProc);
|
|
BOOL ClientFreeLibrary(HANDLE hmod);
|
|
|
|
#ifdef MESSAGE_PUMP_HOOK
|
|
BOOL ClientGetMessageMPH(LPMSG msg, HWND hwndFilter, UINT msgMin, UINT msgMax, UINT flags, BOOL fGetMessage);
|
|
BOOL ClientWaitMessageExMPH(UINT fsWakeMask, DWORD Timeout);
|
|
#endif
|
|
|
|
BOOL xxxClientGetCharsetInfo(LCID lcid, PCHARSETINFO pcs);
|
|
BOOL ClientExitProcess(PFNW32ET pfn, DWORD dwExitCode);
|
|
BOOL ClientGrayString(GRAYSTRINGPROC pfnOutProc, HDC hdc,
|
|
DWORD lpData, int nCount);
|
|
BOOL CopyFromClient(LPBYTE lpByte, LPBYTE lpByteClient, DWORD cch,
|
|
BOOL fString, BOOL fAnsi);
|
|
BOOL CopyToClient(LPBYTE lpByte, LPBYTE lpByteClient,
|
|
DWORD cchMax, BOOL fAnsi);
|
|
VOID ClientNoMemoryPopup(VOID);
|
|
NTSTATUS xxxClientThreadSetup(VOID);
|
|
|
|
VOID ClientDeliverUserApc(VOID);
|
|
|
|
BOOL ClientImmLoadLayout(HKL, PIMEINFOEX);
|
|
DWORD ClientImmProcessKey(HWND, HKL, UINT, LPARAM, DWORD);
|
|
|
|
NTSTATUS xxxUserModeCallback (ULONG uApi, PVOID pIn, ULONG cbIn, PVOID pOut, ULONG cbOut);
|
|
int xxxClientLoadStringW(UINT StrID, LPWSTR szText, int cch);
|
|
|
|
PCURSOR ClassSetSmallIcon(
|
|
PCLS pcls,
|
|
PCURSOR pcursor,
|
|
BOOL fServerCreated);
|
|
|
|
BOOL _GetTextMetricsW(
|
|
HDC hdc,
|
|
LPTEXTMETRICW ptm);
|
|
|
|
int xxxDrawMenuBarTemp(
|
|
PWND pwnd,
|
|
HDC hdc,
|
|
LPRECT lprc,
|
|
PMENU pMenu,
|
|
HFONT hFont);
|
|
|
|
BOOL xxxDrawCaptionTemp(
|
|
PWND pwnd,
|
|
HDC hdc,
|
|
LPRECT lprc,
|
|
HFONT hFont,
|
|
PCURSOR pcursor,
|
|
PUNICODE_STRING pstrText OPTIONAL,
|
|
UINT flags);
|
|
|
|
WORD xxxTrackCaptionButton(
|
|
PWND pwnd,
|
|
UINT hit);
|
|
|
|
VOID GiveForegroundActivateRight(HANDLE hPid);
|
|
BOOL HasForegroundActivateRight(HANDLE hPid);
|
|
BOOL FRemoveForegroundActivate(PTHREADINFO pti);
|
|
VOID RestoreForegroundActivate(VOID);
|
|
VOID CancelForegroundActivate(VOID);
|
|
|
|
#define ACTIVATE_ARRAY_SIZE 5
|
|
extern HANDLE ghCanActivateForegroundPIDs[ACTIVATE_ARRAY_SIZE];
|
|
|
|
__inline VOID GiveForegroundActivateRight(
|
|
HANDLE hPid)
|
|
{
|
|
static int index = 0;
|
|
|
|
TAGMSG1(DBGTAG_FOREGROUND, "Giving 0x%x foreground activate right", hPid);
|
|
ghCanActivateForegroundPIDs[index++] = hPid;
|
|
if (index == ACTIVATE_ARRAY_SIZE) {
|
|
index = 0;
|
|
}
|
|
}
|
|
|
|
__inline BOOL HasForegroundActivateRight(
|
|
HANDLE hPid)
|
|
{
|
|
int i = 0;
|
|
|
|
for(; i < ACTIVATE_ARRAY_SIZE; ++i) {
|
|
if (ghCanActivateForegroundPIDs[i] == hPid) {
|
|
TAGMSG1(DBGTAG_FOREGROUND, "HasForegroundActivateRight: Found 0x%x", hPid);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
TAGMSG1(DBGTAG_FOREGROUND, "HasForegroundActivateRight: Did NOT find 0x%x", hPid);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
#define WHERE_NOONE_CAN_SEE_ME ((int) -32000)
|
|
BOOL MinToTray(PWND pwnd);
|
|
|
|
void xxxUpdateThreadsWindows(
|
|
PTHREADINFO pti,
|
|
PWND pwnd,
|
|
HRGN hrgnFullDrag);
|
|
|
|
NTSTATUS xxxQueryInformationThread(
|
|
IN HANDLE hThread,
|
|
IN USERTHREADINFOCLASS ThreadInfoClass,
|
|
OUT PVOID ThreadInformation,
|
|
IN ULONG ThreadInformationLength,
|
|
OUT PULONG ReturnLength OPTIONAL);
|
|
|
|
NTSTATUS xxxSetInformationThread(
|
|
IN HANDLE hThread,
|
|
IN USERTHREADINFOCLASS ThreadInfoClass,
|
|
IN PVOID ThreadInformation,
|
|
IN ULONG ThreadInformationLength);
|
|
|
|
NTSTATUS GetProcessDefaultWindowOrientation(
|
|
IN HANDLE hProcess,
|
|
OUT DWORD *pdwDefaultOrientation);
|
|
|
|
NTSTATUS SetProcessDefaultWindowOrientation(
|
|
IN HANDLE hProcess,
|
|
IN DWORD dwDefaultOrientation);
|
|
|
|
NTSTATUS SetInformationProcess(
|
|
IN HANDLE hProcess,
|
|
IN USERPROCESSINFOCLASS ProcessInfoClass,
|
|
IN PVOID ProcessInformation,
|
|
IN ULONG ProcessInformationLength);
|
|
|
|
|
|
NTSTATUS xxxConsoleControl(
|
|
IN CONSOLECONTROL ConsoleControl,
|
|
IN PVOID ConsoleInformation,
|
|
IN ULONG ConsoleInformationLength);
|
|
|
|
|
|
/***************************************************************************\
|
|
* String Table Defines
|
|
*
|
|
* KERNEL\STRID.MC has a nice big table of strings that are meant to be
|
|
* localized. Before use, the strings are pulled from the resource table
|
|
* with LoadString, passing it one of the following string ids.
|
|
*
|
|
* NOTE: Only strings that need to be localized should be added to the
|
|
* string table. Class name strings, etc are NOT localized.
|
|
*
|
|
* LATER: All string table entries should be reexamined to be sure they
|
|
* conform to the note above.
|
|
*
|
|
\***************************************************************************/
|
|
|
|
#define OCR_APPSTARTING 32650
|
|
|
|
/*
|
|
* Win Event Hook struct
|
|
*/
|
|
typedef struct tagEVENTHOOK {
|
|
THROBJHEAD head; //
|
|
struct tagEVENTHOOK *pehNext; // Next event hook
|
|
UINT eventMin; // Min event (>=) to hook
|
|
UINT eventMax; // Max event (<=) to hook
|
|
UINT fDestroyed:1; // If orphaned while in use
|
|
UINT fIgnoreOwnThread:1; // Ignore events for installer thread
|
|
UINT fIgnoreOwnProcess:1; // Ignore events for installer process
|
|
UINT fSync:1; // Sync event (inject DLL into each process)
|
|
HANDLE hEventProcess; // Process being hooked
|
|
DWORD idEventThread; // Thread being hooked
|
|
ULONG_PTR offPfn; // offset event proc
|
|
int ihmod; // index of module containing event proc
|
|
LPWSTR pwszModulePath; // Path of module library for global sync.
|
|
} EVENTHOOK, *PEVENTHOOK;
|
|
|
|
typedef struct tagNOTIFY {
|
|
struct tagNOTIFY *pNotifyNext; // Next notification
|
|
PEVENTHOOK spEventHook; // Event this refers to
|
|
DWORD event; // Event
|
|
HWND hwnd; // hwnd to ask about it
|
|
LONG idObject; // object ID
|
|
LONG idChild; // child id
|
|
DWORD idSenderThread; // Thread generating event
|
|
DWORD dwEventTime; // Event time
|
|
DWORD dwWEFlags; // WEF_DEFERNOTIFY etc.
|
|
PTHREADINFO ptiReceiver; // Thread receiving event
|
|
} NOTIFY, *PNOTIFY;
|
|
|
|
VOID xxxWindowEvent(DWORD event, PWND pwnd, LONG idObject, LONG idChild, DWORD dwFlags);
|
|
#define WEF_USEPWNDTHREAD 0x0001
|
|
#define WEF_DEFERNOTIFY 0x0002
|
|
#define WEF_ASYNC 0x0004
|
|
#define WEF_POSTED 0x0008
|
|
|
|
#define DeferWinEventNotify() CheckCritIn(); \
|
|
gdwDeferWinEvent++
|
|
#define IsWinEventNotifyDeferred() (gdwDeferWinEvent > 0)
|
|
#define IsWinEventNotifyDeferredOK() (!IsWinEventNotifyDeferred() || ISATOMICCHECK())
|
|
#define zzzEndDeferWinEventNotify() \
|
|
UserAssert(IsWinEventNotifyDeferred()); \
|
|
CheckCritIn(); \
|
|
if (--gdwDeferWinEvent == 0) { \
|
|
if (gpPendingNotifies != NULL) { \
|
|
xxxFlushDeferredWindowEvents(); \
|
|
} \
|
|
}
|
|
|
|
/*
|
|
* Only use this one for bookkeeping gdwDeferWinEvent,
|
|
* which may be required without leaving the critical section.
|
|
*/
|
|
#define EndDeferWinEventNotifyWithoutProcessing() \
|
|
UserAssert(IsWinEventNotifyDeferred()); \
|
|
CheckCritIn(); \
|
|
--gdwDeferWinEvent
|
|
|
|
#define zzzWindowEvent(event, pwnd, idObject, idChild, dwFlags) \
|
|
xxxWindowEvent(event, pwnd, idObject, idChild, \
|
|
IsWinEventNotifyDeferred() ? (dwFlags) | WEF_DEFERNOTIFY : (dwFlags))
|
|
|
|
VOID xxxFlushDeferredWindowEvents();
|
|
|
|
BOOL xxxClientCallWinEventProc(WINEVENTPROC pfn, PEVENTHOOK pEventHook, PNOTIFY pNotify);
|
|
void DestroyEventHook(PEVENTHOOK);
|
|
VOID FreeThreadsWinEvents(PTHREADINFO pti);
|
|
|
|
BOOL _UnhookWinEvent(PEVENTHOOK peh);
|
|
VOID DestroyNotify(PNOTIFY pNotify);
|
|
PEVENTHOOK xxxProcessNotifyWinEvent(PNOTIFY pNotify);
|
|
PEVENTHOOK _SetWinEventHook(DWORD eventMin, DWORD eventMax,
|
|
HMODULE hmodWinEventProc, PUNICODE_STRING pstrLib,
|
|
WINEVENTPROC pfnWinEventProc, HANDLE hEventProcess,
|
|
DWORD idEventThread, DWORD dwFlags);
|
|
BOOL _GetGUIThreadInfo(PTHREADINFO pti, PGUITHREADINFO pgui);
|
|
BOOL xxxGetTitleBarInfo(PWND pwnd, PTITLEBARINFO ptbi);
|
|
BOOL xxxGetComboBoxInfo(PWND pwnd, PCOMBOBOXINFO ptbi);
|
|
DWORD xxxGetListBoxInfo(PWND pwnd);
|
|
BOOL xxxGetScrollBarInfo(PWND pwnd, LONG idObject, PSCROLLBARINFO ptbi);
|
|
PWND _GetAncestor(PWND pwnd, UINT gaFlags);
|
|
PWND _RealChildWindowFromPoint(PWND pwndParent, POINT pt);
|
|
BOOL _GetAltTabInfo(int iItem, PALTTABINFO pati,
|
|
LPWSTR lpszItemText, UINT cchItemText, BOOL bAnsi);
|
|
BOOL xxxGetMenuBarInfo(PWND pwnd, long idObject, long idItem, PMENUBARINFO pmbi);
|
|
|
|
typedef HWND *PHWND;
|
|
typedef struct tagSwitchWndInfo *PSWINFO;
|
|
|
|
typedef struct tagSwitchWndInfo {
|
|
|
|
PSWINFO pswiNext; // Pointer to the next Switch Window Info.
|
|
PTHREADINFO pti; // pit that allocated the strucutre.
|
|
PBWL pbwl; // Pointer to the window list built.
|
|
PHWND phwndLast; // Pointer to the last window in the list.
|
|
PHWND phwndCurrent; // pointer to the current window.
|
|
|
|
INT iTotalTasks; // Total number of tasks.
|
|
INT iTasksShown; // Total tasks shown.
|
|
BOOL fScroll; // Is there a need to scroll?
|
|
|
|
INT iFirstTaskIndex; // Index to the first task shown.
|
|
|
|
INT iNoOfColumns; // Max Number of tasks per row.
|
|
INT iNoOfRows; // Max Number of rows of icons in the switch window.
|
|
INT iIconsInLastRow; // Icons in last row.
|
|
INT iCurCol; // Current column where hilite lies.
|
|
INT iCurRow; // Current row where hilite lies.
|
|
INT cxSwitch; // Switch Window dimensions.
|
|
INT cySwitch;
|
|
POINT ptFirstRowStart; // Top left corner of the first Icon Slot.
|
|
RECT rcTaskName; // Rect where Task name is displayed.
|
|
BOOL fJournaling; // Determins how we check the keyboard state
|
|
} SWITCHWNDINFO, *PSWINFO;
|
|
|
|
typedef struct tagSWITCHWND {
|
|
WND;
|
|
PSWINFO pswi;
|
|
} SWITCHWND, *PSWITCHWND;
|
|
|
|
typedef struct tagHOTKEYSTRUCT {
|
|
PWND spwnd;
|
|
DWORD key;
|
|
} HOTKEYSTRUCT, *PHOTKEYSTRUCT;
|
|
|
|
#define LANGTOGGLEKEYS_SIZE 3
|
|
|
|
/*
|
|
* ACCF_ and PUDF_ flags share the same field. ACCF fields
|
|
* are so named because they may later move to a differnt
|
|
* struct.
|
|
*/
|
|
#define ACCF_DEFAULTFILTERKEYSON 0x00000001
|
|
#define ACCF_DEFAULTSTICKYKEYSON 0x00000002
|
|
#define ACCF_DEFAULTMOUSEKEYSON 0x00000004
|
|
#define ACCF_DEFAULTTOGGLEKEYSON 0x00000008
|
|
#define ACCF_DEFAULTTIMEOUTON 0x00000010
|
|
#define ACCF_DEFAULTKEYBOARDPREF 0x00000020
|
|
#define ACCF_DEFAULTSCREENREADER 0x00000040
|
|
#define ACCF_DEFAULTHIGHCONTRASTON 0x00000080
|
|
#define ACCF_ACCESSENABLED 0x00000100
|
|
#define ACCF_IGNOREBREAKCODE 0x00000400
|
|
#define ACCF_FKMAKECODEPROCESSED 0x00000800
|
|
#define ACCF_MKVIRTUALMOUSE 0x00001000
|
|
#define ACCF_MKREPEATVK 0x00002000
|
|
#define ACCF_FIRSTTICK 0x00004000
|
|
#define ACCF_SHOWSOUNDSON 0x00008000
|
|
|
|
/*
|
|
* NOTE: PUDF_ANIMATE must have the same value as MINMAX_ANIMATE.
|
|
*/
|
|
#define PUDF_ANIMATE 0x00010000
|
|
|
|
#define ACCF_KEYBOARDPREF 0x00020000
|
|
#define ACCF_SCREENREADER 0x00040000
|
|
#define PUDF_BEEP 0x00080000 /* Warning beeps allowed? */
|
|
#define PUDF_DRAGFULLWINDOWS 0x00100000 /* Drag xor rect or full windows */
|
|
#define PUDF_ICONTITLEWRAP 0x00200000 /* Wrap icon titles or just use single line */
|
|
#define PUDF_FONTSARELOADED 0x00400000
|
|
#define PUDF_POPUPINUSE 0x00800000
|
|
#define PUDF_EXTENDEDSOUNDS 0x01000000
|
|
#define PUDF_MENUSTATEINUSE 0x02000000
|
|
#define PUDF_VDMBOUNDSACTIVE 0x04000000
|
|
#define PUDF_ALLOWFOREGROUNDACTIVATE 0x08000000
|
|
#define PUDF_DRAGGINGFULLWINDOW 0x10000000
|
|
#define PUDF_LOCKFULLSCREEN 0x20000000
|
|
#define PUDF_GSMWPINUSE 0x40000000
|
|
|
|
#define TEST_ACCF(f) TEST_FLAG(gdwPUDFlags, f)
|
|
#define TEST_BOOL_ACCF(f) TEST_BOOL_FLAG(gdwPUDFlags, f)
|
|
#define SET_ACCF(f) SET_FLAG(gdwPUDFlags, f)
|
|
#define CLEAR_ACCF(f) CLEAR_FLAG(gdwPUDFlags, f)
|
|
#define SET_OR_CLEAR_ACCF(f, fSet) SET_OR_CLEAR_FLAG(gdwPUDFlags, f, fSet)
|
|
#define TOGGLE_ACCF(f) TOGGLE_FLAG(gdwPUDFlags, f)
|
|
|
|
#define TEST_PUDF(f) TEST_FLAG(gdwPUDFlags, f)
|
|
#define TEST_BOOL_PUDF(f) TEST_BOOL_FLAG(gdwPUDFlags, f)
|
|
#define SET_PUDF(f) SET_FLAG(gdwPUDFlags, f)
|
|
#define CLEAR_PUDF(f) CLEAR_FLAG(gdwPUDFlags, f)
|
|
#define SET_OR_CLEAR_PUDF(f, fSet) SET_OR_CLEAR_FLAG(gdwPUDFlags, f, fSet)
|
|
#define TOGGLE_PUDF(f) TOGGLE_FLAG(gdwPUDFlags, f)
|
|
|
|
/*
|
|
* Power state stuff
|
|
*/
|
|
|
|
typedef struct tagPOWERSTATE {
|
|
volatile ULONG fInProgress:1;
|
|
volatile ULONG fCritical:1;
|
|
volatile ULONG fOverrideApps:1;
|
|
volatile ULONG fQueryAllowed:1;
|
|
volatile ULONG fUIAllowed:1;
|
|
PKEVENT pEvent;
|
|
BROADCASTSYSTEMMSGPARAMS bsmParams;
|
|
POWERSTATEPARAMS psParams;
|
|
ULONG PowerStateTask;
|
|
} POWERSTATE, *PPOWERSTATE;
|
|
|
|
typedef struct _POWER_INIT {
|
|
PVIDEO_WIN32K_CALLBACKS_PARAMS Params;
|
|
PKEVENT pPowerReadyEvent;
|
|
} POWER_INIT, *PPOWER_INIT;
|
|
|
|
#define POWERON_PHASE -1
|
|
#define LOWPOWER_PHASE 1
|
|
#define POWEROFF_PHASE 2
|
|
|
|
NTSTATUS InitializePowerRequestList(HANDLE hPowerRequestEvent);
|
|
VOID CleanupPowerRequestList(VOID);
|
|
VOID DeletePowerRequestList(VOID);
|
|
VOID xxxUserPowerCalloutWorker(VOID);
|
|
VOID VideoPortCalloutThread(PPOWER_INIT pInitData);
|
|
|
|
/*
|
|
* Fade-in / fade-out globals.
|
|
*/
|
|
|
|
typedef struct tagFADE {
|
|
HANDLE hsprite;
|
|
HDC hdc;
|
|
HBITMAP hbm;
|
|
POINT ptDst;
|
|
SIZE size;
|
|
DWORD dwTime;
|
|
DWORD dwStart;
|
|
DWORD dwFlags;
|
|
#ifdef MOUSE_IP
|
|
COLORREF crColorKey;
|
|
#endif
|
|
} FADE, *PFADE;
|
|
|
|
/*
|
|
* Globals are included last because they may require some of the types
|
|
* being defined above.
|
|
*/
|
|
#include "globals.h"
|
|
#include "ddemlsvr.h"
|
|
/*
|
|
* If you make a change that requires including strid.h when building
|
|
* ntuser\rtl, then you need to change the sources/makefil* files so this
|
|
* file will be built in ntuser\inc; make sure that the output of
|
|
* mc.exe still goes to the kernel directory; this is because there are
|
|
* other places (like ntuser\server) where we use the same file name.
|
|
*/
|
|
#ifndef _USERRTL_
|
|
#include "strid.h"
|
|
#endif
|
|
|
|
#include "ntuser.h"
|
|
|
|
#define TestALPHA(uSetting) (!gbDisableAlpha && TestEffectUP(uSetting))
|
|
|
|
/*
|
|
* tooltips/tracking prototypes from tooltips.c
|
|
*/
|
|
|
|
typedef struct tagTOOLTIP {
|
|
DWORD dwFlags;
|
|
UINT uTID;
|
|
DWORD dwAnimStart;
|
|
int iyAnim;
|
|
LPWSTR pstr;
|
|
} TOOLTIP;
|
|
|
|
typedef struct tagTOOLTIPWND {
|
|
WND;
|
|
|
|
DWORD dwShowDelay;
|
|
DWORD dwHideDelay;
|
|
HDC hdcMem;
|
|
HBITMAP hbmMem;
|
|
|
|
TOOLTIP; // this field must be last!
|
|
} TOOLTIPWND, *PTOOLTIPWND;
|
|
|
|
#define HTEXSCROLLFIRST 60
|
|
#define HTSCROLLUP 60
|
|
#define HTSCROLLDOWN 61
|
|
#define HTSCROLLUPPAGE 62
|
|
#define HTSCROLLDOWNPAGE 63
|
|
#define HTSCROLLTHUMB 64
|
|
#define HTEXSCROLLLAST 64
|
|
#define HTEXMENUFIRST 65
|
|
#define HTMDISYSMENU 65
|
|
#define HTMDIMAXBUTTON 66
|
|
#define HTMDIMINBUTTON 67
|
|
#define HTMDICLOSE 68
|
|
#define HTMENUITEM 69
|
|
#define HTEXMENULAST 69
|
|
|
|
int FindNCHitEx(PWND pwnd, int ht, POINT pt);
|
|
void xxxTrackMouseMove(PWND pwnd, int htEx, UINT message);
|
|
BOOL xxxHotTrack(PWND pwnd, int htEx, BOOL fDraw);
|
|
void xxxResetTooltip(PTOOLTIPWND pttwnd);
|
|
void xxxCancelMouseMoveTracking (DWORD dwDTFlags, PWND pwndTrack, int htEx, DWORD dwDTCancel);
|
|
|
|
/*
|
|
* String range IDs.
|
|
*
|
|
* These are defined here to avoid duplicate entries in strid.mc
|
|
*/
|
|
#define STR_COLORSTART STR_SCROLLBAR
|
|
#define STR_COLOREND STR_MENUBAR
|
|
|
|
/*
|
|
* Sprite and Fade related functions and defines.
|
|
*/
|
|
#define FADE_SHOW 0x00000001
|
|
#define FADE_COMPLETED 0x00000002
|
|
#define FADE_SHOWN 0x00000004
|
|
#define FADE_WINDOW 0x00000008
|
|
#define FADE_MENU 0x00000010
|
|
#define FADE_TOOLTIP 0x00000020
|
|
#ifdef MOUSE_IP
|
|
#define FADE_COLORKEY 0x00000040
|
|
#define FADE_SONAR 0x00000080
|
|
#endif
|
|
|
|
HDC CreateFade(PWND pwnd, RECT *prc, DWORD dwTime, DWORD dwFlags);
|
|
VOID StartFade(void);
|
|
VOID StopFade(void);
|
|
VOID ShowFade(void);
|
|
VOID AnimateFade(void);
|
|
__inline DWORD TestFadeFlags(
|
|
DWORD dwFlags)
|
|
{
|
|
return (gfade.dwFlags & dwFlags);
|
|
}
|
|
|
|
#ifdef MOUSE_IP
|
|
|
|
#define IS_SONAR_ACTIVE() (TestUP(MOUSESONAR) && TestFadeFlags(FADE_SONAR))
|
|
#define CLEAR_SONAR_LASTVK() (void)((TestUP(MOUSESONAR) && gbLastVkForSonar) ? (gbLastVkForSonar = 0) : 0)
|
|
|
|
BOOL StartSonar();
|
|
void StopSonar();
|
|
|
|
#endif
|
|
|
|
HANDLE xxxSetLayeredWindow(PWND pwnd, BOOL fRepaintBehind);
|
|
VOID UnsetLayeredWindow(PWND pwnd);
|
|
void TrackLayeredZorder(PWND pwnd);
|
|
VOID UpdateRedirectedDC(PDCE pdce);
|
|
BOOL _UpdateLayeredWindow(PWND pwnd, HDC hdcDst, POINT *pptDst, SIZE *psize, HDC hdcSrc,
|
|
POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags);
|
|
BOOL _GetLayeredWindowAttributes(PWND hwnd, COLORREF *pcrKey, BYTE *pbAlpha, DWORD *pdwFlags);
|
|
BOOL _SetLayeredWindowAttributes(PWND pwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
|
|
BOOL RecreateRedirectionBitmap(PWND pwnd);
|
|
VOID ResetRedirectedWindows(VOID);
|
|
|
|
PWND GetStyleWindow(PWND pwnd, DWORD dwStyle);
|
|
PWND GetLastChild(PWND pwnd);
|
|
|
|
BOOL SetRedirectedWindow(PWND pwnd, UINT uFlags);
|
|
VOID UnsetRedirectedWindow(PWND pwnd, UINT uFlags);
|
|
VOID ConvertRedirectionDCs(PWND pwnd, HBITMAP hbm);
|
|
VOID xxxCompositedPaint(PWND pwnd);
|
|
|
|
#define REDIRECT_LAYER 0x0001
|
|
#define REDIRECT_COMPOSITED 0x0002
|
|
#define REDIRECT_EXTREDIRECTED 0x0004
|
|
#define REDIRECT_PRINT 0x0008
|
|
|
|
typedef struct tagREDIRECT {
|
|
HBITMAP hbm;
|
|
RECT rcUpdate;
|
|
UINT uFlags;
|
|
HRGN hrgnComp;
|
|
|
|
#if DBG
|
|
PWND pwnd;
|
|
#endif // DBG
|
|
|
|
} REDIRECT, *PREDIRECT;
|
|
|
|
HBITMAP GetRedirectionBitmap(PWND pwnd);
|
|
BOOL SetRedirectionBitmap(PWND pwnd, HBITMAP hbm);
|
|
UINT GetRedirectionFlags(PWND pwnd);
|
|
BOOL xxxPrintWindow(PWND pwnd, HDC hdcBlt, UINT nFlags);
|
|
void xxxTurnOffCompositing(PWND pwndStart, BOOL fChild);
|
|
|
|
|
|
#ifdef REDIRECTION
|
|
BOOL xxxSetProcessRedirectionMode(BOOL fEnable, PPROCESSINFO ppi);
|
|
BOOL xxxSetDesktopRedirectionMode(BOOL fEnable, PDESKTOP pDesk, PPROCESSINFO ppi);
|
|
#endif // REDIRECTION
|
|
|
|
void InternalInvalidate3(
|
|
PWND pwnd,
|
|
HRGN hrgn,
|
|
DWORD flags);
|
|
|
|
BOOL UserSetFont(PUNICODE_STRING pProfileUserName,
|
|
LPLOGFONTW lplf,
|
|
UINT idFont,
|
|
HFONT* phfont
|
|
);
|
|
|
|
HICON DWP_GetIcon(
|
|
PWND pwnd,
|
|
UINT uType);
|
|
|
|
BOOL xxxRedrawTitle(
|
|
PWND pwnd, UINT wFlags);
|
|
|
|
DWORD GetContextHelpId(
|
|
PWND pwnd);
|
|
|
|
|
|
HANDLE xxxClientCopyImage(
|
|
HANDLE hImage,
|
|
UINT type,
|
|
int cxNew,
|
|
int cyNew,
|
|
UINT flags);
|
|
|
|
VOID _WOWCleanup(
|
|
HANDLE hInstance,
|
|
DWORD hTaskWow);
|
|
|
|
VOID _WOWModuleUnload(HANDLE hModule);
|
|
|
|
/*
|
|
* FastProfile APIs
|
|
*/
|
|
typedef struct tagPROFINTINFO {
|
|
UINT idSection;
|
|
LPWSTR lpKeyName;
|
|
DWORD nDefault;
|
|
PUINT puResult;
|
|
} PROFINTINFO, *PPROFINTINFO;
|
|
|
|
typedef struct {
|
|
UINT idSection;
|
|
UINT id;
|
|
UINT idRes;
|
|
UINT def;
|
|
} SPINFO, *PSPINFO;
|
|
|
|
|
|
#define DEFAULT_USER_HANDLE_QUOTA 10000
|
|
#define DEFAULT_POSTMESSAGE_LIMIT 10000
|
|
|
|
/*
|
|
* See aFastRegMap[] in ntuser\kernel\profile.c
|
|
*/
|
|
#define PMAP_COLORS 0
|
|
#define PMAP_CURSORS 1
|
|
#define PMAP_WINDOWSM 2
|
|
#define PMAP_WINDOWSU 3
|
|
#define PMAP_DESKTOP 4
|
|
#define PMAP_ICONS 5
|
|
#define PMAP_FONTS 6
|
|
#define PMAP_TRUETYPE 7
|
|
#define PMAP_KBDLAYOUT 8
|
|
#define PMAP_INPUT 9
|
|
#define PMAP_COMPAT 10
|
|
#define PMAP_SUBSYSTEMS 11
|
|
#define PMAP_BEEP 12
|
|
#define PMAP_MOUSE 13
|
|
#define PMAP_KEYBOARD 14
|
|
#define PMAP_STICKYKEYS 15
|
|
#define PMAP_KEYBOARDRESPONSE 16
|
|
#define PMAP_MOUSEKEYS 17
|
|
#define PMAP_TOGGLEKEYS 18
|
|
#define PMAP_TIMEOUT 19
|
|
#define PMAP_SOUNDSENTRY 20
|
|
#define PMAP_SHOWSOUNDS 21
|
|
#define PMAP_AEDEBUG 22
|
|
#define PMAP_NETWORK 23
|
|
#define PMAP_METRICS 24
|
|
#define PMAP_UKBDLAYOUT 25
|
|
#define PMAP_UKBDLAYOUTTOGGLE 26
|
|
#define PMAP_WINLOGON 27
|
|
#define PMAP_KEYBOARDPREF 28
|
|
#define PMAP_SCREENREADER 29
|
|
#define PMAP_HIGHCONTRAST 30
|
|
#define PMAP_IMECOMPAT 31
|
|
#define PMAP_IMM 32
|
|
#define PMAP_POOLLIMITS 33
|
|
#define PMAP_COMPAT32 34
|
|
#define PMAP_SETUPPROGRAMNAMES 35
|
|
#define PMAP_INPUTMETHOD 36
|
|
#define PMAP_COMPAT2 37
|
|
#define PMAP_MOUCLASS_PARAMS 38
|
|
#define PMAP_KBDCLASS_PARAMS 39
|
|
#define PMAP_COMPUTERNAME 40
|
|
#define PMAP_TS 41
|
|
#define PMAP_TABLETPC 42
|
|
#define PMAP_MEDIACENTER 43
|
|
#define PMAP_TS_EXCLUDE_DESKTOP_VERSION 44
|
|
#define PMAP_LAST 44
|
|
|
|
#define MAXPROFILEBUF 256
|
|
|
|
#define POLICY_NONE 0x0001
|
|
#define POLICY_USER 0x0002
|
|
#define POLICY_MACHINE 0x0004
|
|
#define POLICY_REMOTE 0x0008
|
|
#define POLICY_ONLY 0x0010
|
|
/*
|
|
* POLICY_REMOTE is not included in POLICY_ALL intentionally.
|
|
* Else, we will try to read the remote policy always.
|
|
*/
|
|
#define POLICY_ALL (POLICY_NONE | POLICY_USER | POLICY_MACHINE)
|
|
#define POLICY_VALID (POLICY_ALL | POLICY_ONLY | POLICY_REMOTE)
|
|
|
|
PUNICODE_STRING CreateProfileUserName(TL *ptl);
|
|
void FreeProfileUserName(PUNICODE_STRING pProfileUserName,TL *ptl);
|
|
HANDLE OpenCacheKeyEx(PUNICODE_STRING pProfileUserName OPTIONAL, UINT idSection, ACCESS_MASK amRequest, PDWORD pdwPolicyFlags);
|
|
BOOL CheckDesktopPolicy(PUNICODE_STRING pProfileUserName OPTIONAL, PCWSTR lpKeyName);
|
|
BOOL CheckDesktopPolicyChange(PUNICODE_STRING pProfileUserName OPTIONAL);
|
|
DWORD FastGetProfileKeysW(PUNICODE_STRING pProfileUserName OPTIONAL, UINT idSection, LPCWSTR pszDefault, LPWSTR *ppszKeys);
|
|
BOOL FastGetProfileDwordW(PUNICODE_STRING pProfileUserName OPTIONAL, UINT idSection, LPCWSTR lpKeyName, DWORD dwDefault, PDWORD pdwReturn, DWORD dwPolicyOnly);
|
|
DWORD FastGetProfileStringW(PUNICODE_STRING pProfileUserName OPTIONAL, UINT idSection, LPCWSTR lpKeyName, LPCWSTR lpDefault, LPWSTR lpReturnedString, DWORD nSize, DWORD dwPolicyOnly);
|
|
BOOL FastGetProfileIntW(PUNICODE_STRING pProfileUserName OPTIONAL, UINT idSection, LPCWSTR lpKeyName, UINT nDefault, PUINT puiReturn, DWORD dwPolicyOnly);
|
|
BOOL FastWriteProfileStringW(PUNICODE_STRING pProfileUserName OPTIONAL, UINT idSection, LPCWSTR lpKeyName, LPCWSTR lpString);
|
|
BOOL FastGetProfileIntFromID(PUNICODE_STRING pProfileUserName OPTIONAL, UINT idSection, UINT idKey, int def, PINT pResult, DWORD dwPolicyOnly);
|
|
DWORD FastGetProfileStringFromIDW(PUNICODE_STRING pProfileUserName OPTIONAL, UINT idSection, UINT idKey, LPCWSTR lpDefault, LPWSTR lpReturnedString, DWORD cch, DWORD dwPolicyOnly);
|
|
BOOL FastWriteProfileValue(PUNICODE_STRING pProfileUserName OPTIONAL, UINT idSection, LPCWSTR lpKeyName, UINT uType, LPBYTE lpStruct, UINT cbSizeStruct);
|
|
DWORD FastGetProfileValue(PUNICODE_STRING pProfileUserName OPTIONAL, UINT idSection, LPCWSTR lpKeyName,LPBYTE lpDefault, LPBYTE lpReturn, UINT cbSizeReturn, DWORD dwPolicyOnly);
|
|
BOOL FastGetProfileIntsW(PUNICODE_STRING pProfileUserName OPTIONAL, PPROFINTINFO ppii, DWORD dwPolicyOnly);
|
|
BOOL FastUpdateWinIni(PUNICODE_STRING pProfileUserName OPTIONAL, UINT idSection, UINT wKeyNameId, LPWSTR lpszValue);
|
|
|
|
/*
|
|
* # of pels added to border width. When a user requests a border width of 1
|
|
* that user actualy gets a border width of BORDER_EXTRA + 1 if the window
|
|
* has a sizing border.
|
|
*/
|
|
#define BORDER_EXTRA 3
|
|
|
|
/*
|
|
* tmswitch.c stuff
|
|
*/
|
|
|
|
__inline int GetCaptionHeight(
|
|
PWND pwnd)
|
|
{
|
|
if (!TestWF(pwnd, WFCPRESENT)) {
|
|
return 0;
|
|
} else {
|
|
return TestWF(pwnd, WEFTOOLWINDOW) ?
|
|
SYSMET(CYSMCAPTION) : SYSMET(CYCAPTION);
|
|
}
|
|
}
|
|
|
|
__inline VOID InitTooltipDelay(
|
|
PTOOLTIPWND pttwnd)
|
|
{
|
|
if (pttwnd != NULL) {
|
|
pttwnd->dwShowDelay = gdtDblClk * 3;
|
|
pttwnd->dwHideDelay = gdtDblClk * 8;
|
|
}
|
|
}
|
|
|
|
__inline PPROFILEVALUEINFO UPDWORDPointer(
|
|
UINT uSetting)
|
|
{
|
|
UserAssert(UPIsDWORDRange(uSetting));
|
|
return gpviCPUserPreferences + UPDWORDIndex(uSetting);
|
|
}
|
|
|
|
|
|
/*
|
|
* ComputeTickDelta
|
|
*
|
|
* ComputeTickDelta computes a time delta between two times. The
|
|
* delta is defined as a 31-bit, signed value. It is best to think of time as
|
|
* a clock that wraps around. The delta is the minimum distance on this circle
|
|
* between two different places on the circle. If the delta goes
|
|
* counter-clockwise, it is looking at a time in the PAST and is POSITIVE. If
|
|
* the delta goes clockwise, it is looking at a time in the FUTURE and is
|
|
* negative.
|
|
*
|
|
* It is IMPORTANT to realize that the (dwCurTime >= dwLastTime) comparison does
|
|
* not determine the delta's sign, but only determines the operation to compute
|
|
* the delta without an overflow occuring.
|
|
*/
|
|
__inline
|
|
int ComputeTickDelta(
|
|
IN DWORD dwCurTick,
|
|
IN DWORD dwLastTick)
|
|
{
|
|
return (int) dwCurTick - dwLastTick;
|
|
}
|
|
|
|
|
|
__inline
|
|
DWORD ComputePastTickDelta(
|
|
IN DWORD dwCurTick,
|
|
IN DWORD dwLastTick)
|
|
{
|
|
/*
|
|
* This handles a wrap-around.
|
|
*/
|
|
return dwCurTick - dwLastTick;
|
|
}
|
|
|
|
__inline BOOL IsTimeFromLastInput(
|
|
DWORD dwTimeout)
|
|
{
|
|
return ((NtGetTickCount() - glinp.timeLastInputMessage) > dwTimeout);
|
|
}
|
|
|
|
__inline BOOL IsTimeFromLastRITEvent(
|
|
DWORD dwTimeout)
|
|
{
|
|
return ((NtGetTickCount() - gpsi->dwLastRITEventTickCount) > dwTimeout);
|
|
}
|
|
|
|
#if DBG
|
|
__inline void DBGIncModalMenuCount(
|
|
VOID)
|
|
{
|
|
guModalMenuStateCount++;
|
|
}
|
|
|
|
__inline VOID DBGDecModalMenuCount(
|
|
VOID)
|
|
{
|
|
UserAssert(guModalMenuStateCount != 0);
|
|
guModalMenuStateCount--;
|
|
}
|
|
#else
|
|
#define DBGIncModalMenuCount()
|
|
#define DBGDecModalMenuCount()
|
|
#endif
|
|
|
|
__inline BOOL IsForegroundLocked(
|
|
VOID)
|
|
{
|
|
return (guSFWLockCount != 0 || gppiLockSFW != NULL);
|
|
}
|
|
|
|
|
|
/*
|
|
* Compatibility hack for foreground activation problems.
|
|
*/
|
|
__inline
|
|
BOOL GiveUpForeground(
|
|
VOID)
|
|
{
|
|
if (gptiForeground == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (GetAppCompatFlags2ForPti(gptiForeground, VER40) & GACF2_GIVEUPFOREGROUND) {
|
|
TAGMSG0(DBGTAG_FOREGROUND, "GiveUpForeground Hack Succeeded!");
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
__inline VOID IncSFWLockCount(
|
|
VOID)
|
|
{
|
|
guSFWLockCount++;
|
|
}
|
|
|
|
__inline VOID DecSFWLockCount(
|
|
VOID)
|
|
{
|
|
UserAssert(guSFWLockCount != 0);
|
|
guSFWLockCount--;
|
|
}
|
|
|
|
__inline DWORD UPDWORDValue(
|
|
UINT uSetting)
|
|
{
|
|
return UPDWORDPointer(uSetting)->dwValue;
|
|
}
|
|
/*
|
|
* Use this macro ONLY if UPIsDWORDRange(SPI_GET ## uSetting) is TRUE.
|
|
*/
|
|
#define UP(uSetting) UPDWORDValue(SPI_GET ## uSetting)
|
|
|
|
/*
|
|
* NTIMM.C
|
|
*/
|
|
|
|
#define IMESHOWSTATUS_NOTINITIALIZED ((BOOL)0xffff)
|
|
|
|
PIMC CreateInputContext(
|
|
IN ULONG_PTR dwClientImcData);
|
|
|
|
BOOL DestroyInputContext(
|
|
IN PIMC pImc);
|
|
|
|
VOID FreeInputContext(
|
|
IN PIMC pImc);
|
|
|
|
HIMC AssociateInputContext(
|
|
IN PWND pWnd,
|
|
IN PIMC pImc);
|
|
|
|
AIC_STATUS AssociateInputContextEx(
|
|
IN PWND pWnd,
|
|
IN PIMC pImc,
|
|
IN DWORD dwFlag);
|
|
|
|
BOOL UpdateInputContext(
|
|
IN PIMC pImc,
|
|
IN UPDATEINPUTCONTEXTCLASS UpdateType,
|
|
IN ULONG_PTR UpdateValue);
|
|
|
|
VOID xxxFocusSetInputContext(
|
|
IN PWND pwnd,
|
|
IN BOOL fActivate,
|
|
IN BOOL fQueueMsg);
|
|
|
|
UINT BuildHimcList(
|
|
PTHREADINFO pti,
|
|
UINT cHimcMax,
|
|
HIMC *phimcFirst);
|
|
|
|
PWND xxxCreateDefaultImeWindow(
|
|
IN PWND pwnd,
|
|
IN ATOM atomT,
|
|
IN HANDLE hInst);
|
|
|
|
BOOL xxxImmActivateThreadsLayout(
|
|
PTHREADINFO pti,
|
|
PTLBLOCK ptlBlockPrev,
|
|
PKL pkl);
|
|
|
|
VOID xxxImmActivateAndUnloadThreadsLayout(
|
|
IN PTHREADINFO *ptiList,
|
|
IN UINT nEntries,
|
|
IN PTLBLOCK ptlBlockPrev,
|
|
PKL pklCurrent,
|
|
DWORD dwHklReplace);
|
|
|
|
VOID xxxImmActivateLayout(
|
|
IN PTHREADINFO pti,
|
|
IN PKL pkl);
|
|
|
|
VOID xxxImmUnloadThreadsLayout(
|
|
IN PTHREADINFO *ptiList,
|
|
IN UINT nEntry,
|
|
IN PTLBLOCK ptlBlockPrev,
|
|
IN DWORD dwFlag);
|
|
|
|
VOID xxxImmUnloadLayout(
|
|
IN PTHREADINFO pti,
|
|
IN DWORD dwFlag);
|
|
|
|
PIMEINFOEX xxxImmLoadLayout(
|
|
IN HKL hKL);
|
|
|
|
VOID xxxImmActivateLayout(
|
|
IN PTHREADINFO pti,
|
|
IN PKL pkl);
|
|
|
|
BOOL GetImeInfoEx(
|
|
IN PWINDOWSTATION pwinsta,
|
|
IN PIMEINFOEX piiex,
|
|
IN IMEINFOEXCLASS SearchType);
|
|
|
|
BOOL SetImeInfoEx(
|
|
IN PWINDOWSTATION pwinsta,
|
|
IN PIMEINFOEX piiex);
|
|
|
|
DWORD xxxImmProcessKey(
|
|
IN PQ pq,
|
|
IN PWND pwnd,
|
|
IN UINT message,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam);
|
|
|
|
BOOL GetImeHotKey(
|
|
DWORD dwHotKeyID,
|
|
PUINT puModifiers,
|
|
PUINT puVKey,
|
|
HKL *phKL );
|
|
|
|
BOOL SetImeHotKey(
|
|
DWORD dwHotKeyID,
|
|
UINT uModifiers,
|
|
UINT uVKey,
|
|
HKL hKL,
|
|
DWORD dwAction );
|
|
|
|
PIMEHOTKEYOBJ CheckImeHotKey(
|
|
PQ pq,
|
|
UINT uVKey,
|
|
LPARAM lParam);
|
|
|
|
BOOL ImeCanDestroyDefIME(
|
|
IN PWND pwndDefaultIme,
|
|
IN PWND pwndDestroy);
|
|
|
|
BOOL IsChildSameThread(
|
|
IN PWND pwndParent,
|
|
IN PWND pwndChild);
|
|
|
|
BOOL ImeCanDestroyDefIMEforChild(
|
|
IN PWND pwndDefaultIme,
|
|
IN PWND pwndDestroy);
|
|
|
|
VOID ImeCheckTopmost(
|
|
IN PWND pwnd);
|
|
|
|
VOID ImeSetOwnerWindow(
|
|
IN PWND pwndIme,
|
|
IN PWND pwndNewOwner);
|
|
|
|
VOID ImeSetFutureOwner(
|
|
IN PWND pwndDefaultIme,
|
|
IN PWND pwndOrgOwner);
|
|
|
|
VOID ImeSetTopmostChild(
|
|
IN PWND pwndRoot,
|
|
IN BOOL fFlag);
|
|
|
|
VOID ImeSetTopmost(
|
|
IN PWND pwndRoot,
|
|
IN BOOL fFlag,
|
|
IN PWND pwndInsertBefore);
|
|
|
|
PSOFTKBDDATA ProbeAndCaptureSoftKbdData(
|
|
PSOFTKBDDATA Source);
|
|
|
|
VOID xxxNotifyIMEStatus(
|
|
IN PWND pwnd,
|
|
IN DWORD dwOpen,
|
|
IN DWORD dwConversion );
|
|
|
|
BOOL xxxSetIMEShowStatus(
|
|
IN BOOL fShow);
|
|
|
|
VOID xxxBroadcastImeShowStatusChange(
|
|
IN PWND pwndDefIme,
|
|
IN BOOL fShow);
|
|
|
|
VOID xxxCheckImeShowStatusInThread(
|
|
IN PWND pwndDefIme);
|
|
|
|
|
|
#define IsWndImeRelated(pwnd) \
|
|
(pwnd->pcls->atomClassName == gpsi->atomSysClass[ICLS_IME] || \
|
|
TestCF(pwnd, CFIME))
|
|
|
|
/*
|
|
* Critical section routines for processing mouse input
|
|
*/
|
|
__inline VOID EnterMouseCrit(
|
|
VOID)
|
|
{
|
|
|
|
KeEnterCriticalRegion();
|
|
ExAcquireResourceExclusiveLite(gpresMouseEventQueue, TRUE);
|
|
}
|
|
|
|
__inline VOID LeaveMouseCrit(
|
|
VOID)
|
|
{
|
|
|
|
ExReleaseResourceLite(gpresMouseEventQueue);
|
|
KeLeaveCriticalRegion();
|
|
}
|
|
|
|
#if DBG
|
|
#define EnterDeviceInfoListCrit _EnterDeviceInfoListCrit
|
|
#define LeaveDeviceInfoListCrit _LeaveDeviceInfoListCrit
|
|
VOID _EnterDeviceInfoListCrit();
|
|
VOID _LeaveDeviceInfoListCrit();
|
|
#else
|
|
/*
|
|
* Critical section routines for accessing the Device List (gpDeviceInfoList)
|
|
*/
|
|
__inline VOID EnterDeviceInfoListCrit(
|
|
VOID)
|
|
{
|
|
KeEnterCriticalRegion();
|
|
ExAcquireResourceExclusiveLite(gpresDeviceInfoList, TRUE);
|
|
}
|
|
__inline VOID LeaveDeviceInfoListCrit(
|
|
VOID)
|
|
{
|
|
ExReleaseResourceLite(gpresDeviceInfoList);
|
|
KeLeaveCriticalRegion();
|
|
}
|
|
#endif // DBG
|
|
|
|
#define BEGIN_REENTER_DEVICEINFOLISTCRIT() \
|
|
{ \
|
|
BOOL fAlreadyHadDeviceInfoCrit; \
|
|
\
|
|
/* \
|
|
* If we're not in the user crit then acquire it. \
|
|
*/ \
|
|
fAlreadyHadDeviceInfoCrit = ExIsResourceAcquiredExclusiveLite(gpresDeviceInfoList); \
|
|
if (fAlreadyHadDeviceInfoCrit == FALSE) { \
|
|
EnterDeviceInfoListCrit(); \
|
|
}
|
|
|
|
#define END_REENTER_DEVICEINFOLISTCRIT() \
|
|
if (fAlreadyHadDeviceInfoCrit == FALSE) { \
|
|
LeaveDeviceInfoListCrit(); \
|
|
} \
|
|
}
|
|
|
|
|
|
/*
|
|
* Request RIT to update the keyboard h/w settings
|
|
*/
|
|
__inline VOID RequestKeyboardRateUpdate(
|
|
VOID)
|
|
{
|
|
gdwUpdateKeyboard |= UPDATE_KBD_TYPEMATIC;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
* Keep some capture state visible from user-mode for performance.
|
|
*/
|
|
__inline VOID LockCaptureWindow(
|
|
PQ pq,
|
|
PWND pwnd)
|
|
{
|
|
if (pq->spwndCapture) {
|
|
UserAssert(gpsi->cCaptures > 0);
|
|
gpsi->cCaptures--;
|
|
}
|
|
|
|
if (pwnd) {
|
|
gpsi->cCaptures++;
|
|
}
|
|
|
|
Lock(&pq->spwndCapture, pwnd);
|
|
}
|
|
|
|
__inline VOID UnlockCaptureWindow(
|
|
PQ pq)
|
|
{
|
|
if (pq->spwndCapture) {
|
|
UserAssert(gpsi->cCaptures > 0);
|
|
gpsi->cCaptures--;
|
|
Unlock(&pq->spwndCapture);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Some routines for manipulating desktop and windowstation handles.
|
|
*/
|
|
#define HF_DESKTOPHOOK 0 // offset to desktop hook flag
|
|
#define HF_PROTECTED 1 // offset to protected flag
|
|
#define HF_LIMIT 2 // number of flags per handle
|
|
|
|
BOOL SetHandleFlag(HANDLE hObject, DWORD dwFlag, BOOL fSet);
|
|
BOOL CheckHandleFlag(PEPROCESS Process, DWORD dwSessionId, HANDLE hObject, DWORD dwFlag);
|
|
VOID SetHandleInUse(HANDLE hObject);
|
|
BOOL CheckHandleInUse(HANDLE hObject);
|
|
|
|
__inline NTSTATUS CloseProtectedHandle(
|
|
HANDLE handle)
|
|
{
|
|
if (handle != NULL) {
|
|
SetHandleFlag(handle, HF_PROTECTED, FALSE);
|
|
return ZwClose(handle);
|
|
}
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
__inline VOID EnterHandleFlagsCrit(
|
|
VOID)
|
|
{
|
|
KeEnterCriticalRegion();
|
|
ExAcquireFastMutexUnsafe(gpHandleFlagsMutex);
|
|
}
|
|
|
|
__inline VOID LeaveHandleFlagsCrit(
|
|
VOID)
|
|
{
|
|
ExReleaseFastMutexUnsafe(gpHandleFlagsMutex);
|
|
KeLeaveCriticalRegion();
|
|
}
|
|
|
|
// multimon apis
|
|
|
|
BOOL xxxEnumDisplayMonitors(
|
|
HDC hdc,
|
|
LPRECT lprcClip,
|
|
MONITORENUMPROC lpfnEnum,
|
|
LPARAM dwData,
|
|
BOOL fInternal);
|
|
|
|
BOOL xxxClientMonitorEnumProc(
|
|
HMONITOR hMonitor,
|
|
HDC hdcMonitor,
|
|
LPRECT lprc,
|
|
LPARAM dwData,
|
|
MONITORENUMPROC xpfnProc);
|
|
|
|
VOID ClipPointToDesktop(LPPOINT lppt);
|
|
VOID DestroyMonitor(PMONITOR pMonitor);
|
|
BOOL GetHDevName(HMONITOR hMon, PWCHAR pName);
|
|
ULONG HdevFromMonitor(PMONITOR pMonitor);
|
|
|
|
/*
|
|
* The global to assure the atomicness of
|
|
* the monitor update.
|
|
*/
|
|
extern DWORD gdwMonitorBusy;
|
|
|
|
/*
|
|
* Rebasing functions for shared memory.
|
|
*/
|
|
#define REBASESHAREDPTR(p) (p)
|
|
#define REBASESHAREDPTRALWAYS(p) (p)
|
|
|
|
#define PDEV_ENABLED() \
|
|
InterlockedExchange((LPLONG)&gbMDEVDisabled, FALSE);
|
|
|
|
#define PDEV_DISABLED() \
|
|
InterlockedExchange((LPLONG)&gbMDEVDisabled, TRUE);
|
|
|
|
__inline BOOL SafeEnableMDEV(
|
|
VOID)
|
|
{
|
|
if (gbMDEVDisabled) {
|
|
if (DrvEnableMDEV(gpDispInfo->pmdev, TRUE)) {
|
|
PDEV_ENABLED();
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
} else {
|
|
RIPMSGF0(RIP_WARNING, "Trying to enable an enabled MDEV");
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
__inline BOOL SafeDisableMDEV(
|
|
VOID)
|
|
{
|
|
if (!gbMDEVDisabled) {
|
|
if (DrvDisableMDEV(gpDispInfo->pmdev, TRUE)) {
|
|
PDEV_DISABLED();
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
} else {
|
|
RIPMSGF0(RIP_WARNING, "Trying to disable a disabled MDEV");
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Multimonitor macros used in RTL. There are similar definitions
|
|
* in client\usercli.h
|
|
*/
|
|
__inline PDISPLAYINFO
|
|
GetDispInfo(
|
|
VOID)
|
|
{
|
|
return gpDispInfo;
|
|
}
|
|
|
|
__inline PMONITOR
|
|
GetPrimaryMonitor(
|
|
VOID)
|
|
{
|
|
return REBASESHAREDPTRALWAYS(GetDispInfo()->pMonitorPrimary);
|
|
}
|
|
|
|
VOID _QueryUserHandles(
|
|
IN LPDWORD lpIn,
|
|
IN DWORD dwInLength,
|
|
OUT DWORD pdwResult[][TYPE_CTYPES]);
|
|
|
|
|
|
|
|
#define REMOVE_FROM_LIST(type, pstart, pitem, next) \
|
|
{ \
|
|
type** pp; \
|
|
\
|
|
for (pp = &pstart; *pp != NULL; pp = &(*pp)->next) { \
|
|
if (*pp == pitem) { \
|
|
*pp = pitem->next; \
|
|
break; \
|
|
} \
|
|
} \
|
|
} \
|
|
|
|
|
|
#define HH_DRIVERENTRY 0x00000001
|
|
#define HH_USERINITIALIZE 0x00000002
|
|
#define HH_INITVIDEO 0x00000004
|
|
#define HH_REMOTECONNECT 0x00000008
|
|
#define HH_REMOTEDISCONNECT 0x00000010
|
|
#define HH_REMOTERECONNECT 0x00000020
|
|
#define HH_REMOTELOGOFF 0x00000040
|
|
#define HH_DRIVERUNLOAD 0x00000080
|
|
#define HH_GRECLEANUP 0x00000100
|
|
#define HH_USERKCLEANUP 0x00000200
|
|
#define HH_INITIATEWIN32KCLEANUP 0x00000400
|
|
#define HH_ALLDTGONE 0x00000800
|
|
#define HH_RITGONE 0x00001000
|
|
#define HH_RITCREATED 0x00002000
|
|
#define HH_LOADCURSORS 0x00004000
|
|
#define HH_KBDLYOUTGLOBALCLEANUP 0x00008000
|
|
#define HH_KBDLYOUTFREEWINSTA 0x00010000
|
|
#define HH_CLEANUPRESOURCES 0x00020000
|
|
#define HH_DISCONNECTDESKTOP 0x00040000
|
|
#define HH_DTQUITPOSTED 0x00080000
|
|
#define HH_DTQUITRECEIVED 0x00100000
|
|
#define HH_DTWAITONHANDLES 0x00400000
|
|
|
|
#define HYDRA_HINT(ev) (gdwHydraHint |= ev)
|
|
|
|
#if DBG
|
|
VOID TrackAddDesktop(PVOID pDesktop);
|
|
VOID TrackRemoveDesktop(PVOID pDesktop);
|
|
VOID DumpTrackedDesktops(BOOL bBreak);
|
|
|
|
#define DbgTrackAddDesktop(pdesk) TrackAddDesktop(pdesk)
|
|
#define DbgTrackRemoveDesktop(pdesk) TrackRemoveDesktop(pdesk)
|
|
#define DbgDumpTrackedDesktops(b) DumpTrackedDesktops(b)
|
|
#else
|
|
#define DbgTrackAddDesktop(pdesk)
|
|
#define DbgTrackRemoveDesktop(pdesk)
|
|
#define DbgDumpTrackedDesktops(b)
|
|
#endif
|
|
|
|
#if DBG
|
|
#define TRACE_HYDAPI(m) \
|
|
if (gbTraceHydraApi) { \
|
|
KdPrint(("HYD-%d API: ", gSessionId)); \
|
|
KdPrint(m); \
|
|
}
|
|
#else
|
|
#define TRACE_HYDAPI(m)
|
|
#endif
|
|
|
|
#if DBG
|
|
#define TRACE_DESKTOP(m) \
|
|
if (gbTraceDesktop) { \
|
|
KdPrint(("HYD-%d DT ", gSessionId)); \
|
|
KdPrint(m); \
|
|
}
|
|
#else
|
|
#define TRACE_DESKTOP(m)
|
|
#endif
|
|
|
|
NTSTATUS
|
|
RemoteConnect(
|
|
IN PDOCONNECTDATA pDoConnectData,
|
|
IN ULONG DisplayDriverNameLength,
|
|
IN PWCHAR DisplayDriverName);
|
|
|
|
NTSTATUS
|
|
xxxRemoteDisconnect(
|
|
VOID);
|
|
|
|
NTSTATUS
|
|
xxxRemoteConsoleShadowStop(
|
|
VOID);
|
|
|
|
|
|
NTSTATUS
|
|
xxxRemoteReconnect(
|
|
IN PDORECONNECTDATA pDoReconnectData);
|
|
|
|
|
|
NTSTATUS
|
|
xxxRemoteNotify(
|
|
IN PDONOTIFYDATA pDoNotifyData);
|
|
|
|
NTSTATUS
|
|
RemoteLogoff(
|
|
VOID);
|
|
|
|
BOOL
|
|
PrepareForLogoff(
|
|
UINT uFlags);
|
|
|
|
NTSTATUS
|
|
xxxRemoteStopScreenUpdates(
|
|
VOID);
|
|
|
|
VOID xxxPushKeyEvent(
|
|
BYTE bVk,
|
|
BYTE bScan,
|
|
DWORD dwFlags,
|
|
DWORD dwExtraInfo);
|
|
|
|
NTSTATUS
|
|
RemoteThinwireStats(
|
|
OUT PVOID Stats);
|
|
|
|
NTSTATUS
|
|
RemoteNtSecurity(
|
|
VOID);
|
|
|
|
NTSTATUS
|
|
xxxRemoteShadowSetup(
|
|
VOID);
|
|
|
|
NTSTATUS
|
|
RemoteShadowStart(
|
|
IN PVOID pThinwireData,
|
|
ULONG ThinwireDataLength);
|
|
|
|
NTSTATUS
|
|
xxxRemoteShadowStop(
|
|
VOID);
|
|
|
|
NTSTATUS
|
|
RemoteShadowCleanup(
|
|
IN PVOID pThinwireData,
|
|
ULONG ThinwireDataLength);
|
|
|
|
NTSTATUS
|
|
xxxRemotePassthruEnable(
|
|
VOID);
|
|
|
|
NTSTATUS
|
|
RemotePassthruDisable(
|
|
VOID);
|
|
|
|
NTSTATUS
|
|
CtxDisplayIOCtl(
|
|
ULONG DisplayIOCtlFlags,
|
|
PUCHAR pDisplayIOCtlData,
|
|
ULONG cbDisplayIOCtlData);
|
|
|
|
DWORD
|
|
RemoteConnectState(
|
|
VOID);
|
|
|
|
BOOL
|
|
_GetWinStationInfo(
|
|
WSINFO* pWsInfo);
|
|
|
|
// from fullscr.c
|
|
|
|
NTSTATUS
|
|
RemoteRedrawRectangle(
|
|
WORD Left,
|
|
WORD Top,
|
|
WORD Right,
|
|
WORD Bottom);
|
|
|
|
NTSTATUS
|
|
RemoteRedrawScreen(
|
|
VOID);
|
|
|
|
NTSTATUS
|
|
RemoteDisableScreen(
|
|
VOID);
|
|
|
|
// from fekbd.c
|
|
VOID
|
|
NlsKbdSendIMEProc(
|
|
DWORD dwImeOpen,
|
|
DWORD dwImeConversion);
|
|
|
|
|
|
/*
|
|
* Additional menu functions (dependant on previous inline functions)
|
|
*/
|
|
__inline BOOL MNIsFlatMenu(
|
|
VOID)
|
|
{
|
|
return TestEffectUP(FLATMENU);
|
|
}
|
|
|
|
VOID SetMouseTrails(UINT n);
|
|
VOID HideMouseTrails(PWND pwnd, UINT message, UINT_PTR nID, LPARAM lParam);
|
|
|
|
|
|
#if DBG
|
|
#define CheckPublicDC(lpszStr, hdc) \
|
|
{ \
|
|
if (GreGetObjectOwner((HOBJ)hdc, DC_TYPE) == OBJECT_OWNER_PUBLIC) { \
|
|
RIPMSG1(RIP_ERROR, lpszStr, hdc); \
|
|
} \
|
|
}
|
|
#else
|
|
#define CheckPublicDC(lpszStr, hdc)
|
|
#endif
|
|
#define szMESSAGE L"Message"
|
|
|
|
#ifdef LAME_BUTTON
|
|
|
|
/*
|
|
* Lame button constants -- HKCU\Control Panel\Desktop\LameButtonEnabled.
|
|
*/
|
|
#define LBUTTON_DIALOG 0x4
|
|
#define LBUTTON_TOPLEVEL 0x8
|
|
|
|
__inline BOOL NeedsLameButton(
|
|
PWND pwnd,
|
|
PWND pwndParent)
|
|
{
|
|
/*
|
|
* Windows with the WS_EX_TOOLWINDOW style can't have a lame button (see
|
|
* Windows Bug #237648), nor can consoles.
|
|
*/
|
|
if (TestWF(pwnd, WEFTOOLWINDOW) || PsGetCurrentProcess() == gpepCSRSS) {
|
|
return FALSE;
|
|
} else if (pwndParent != NULL && GETFNID(pwndParent) == FNID_DESKTOP) {
|
|
return (gdwLameFlags & LBUTTON_TOPLEVEL) != 0;
|
|
} else if (GETFNID(pwnd) == FNID_DIALOG) {
|
|
return (gdwLameFlags & LBUTTON_DIALOG) != 0;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
#endif // LAME_BUTTON
|
|
|
|
#ifdef TRACK_PNP_NOTIFICATION
|
|
|
|
typedef enum tagPNP_NOTIFICATION_TYPE {
|
|
PNP_NTF_CLASSNOTIFY,
|
|
PNP_NTF_CREATEDEVICEINFO,
|
|
PNP_NTF_FREEDEVICEINFO,
|
|
PNP_NTF_PROCESSDEVICECHANGES,
|
|
PNP_NTF_REQUESTDEVICECHANGE,
|
|
PNP_NTF_DEVICENOTIFY,
|
|
PNP_NTF_FREEDEVICEINFO_DEFERRED,
|
|
PNP_NTF_CLOSEDEVICE,
|
|
PNP_NTF_DEVICENOTIFY_UNLISTED,
|
|
PNP_NTF_UNREGISTER_NOTIFICATION,
|
|
PNP_NTF_UNREGISTER_REMOTE_CANCELLED,
|
|
} PNP_NOTIFICATION_TYPE;
|
|
|
|
typedef struct tagPNP_NOTIFICATION_RECORD {
|
|
UINT iSeq;
|
|
PNP_NOTIFICATION_TYPE type;
|
|
PVOID pKThread;
|
|
PDEVICEINFO pDeviceInfo;
|
|
HANDLE hDeviceInfo;
|
|
UCHAR szPathName[80];
|
|
ULONG_PTR NotificationCode;
|
|
PVOID trace[LOCKRECORD_STACK];
|
|
} PNP_NOTIFICATION_RECORD, *PPNP_NOTIFICATION_RECORD;
|
|
|
|
VOID CleanupPnpNotificationRecord(
|
|
VOID);
|
|
|
|
VOID RecordPnpNotification(
|
|
PNP_NOTIFICATION_TYPE type,
|
|
PDEVICEINFO pDeviceInfo,
|
|
ULONG_PTR NotificationCode);
|
|
|
|
extern BOOL gfRecordPnpNotification;
|
|
|
|
#endif // TRACK_PNP_NOTIFICATION
|
|
|
|
#ifdef SUBPIXEL_MOUSE
|
|
VOID BuildMouseAccelerationCurve(
|
|
PMONITOR pMonitor);
|
|
|
|
VOID DoNewMouseAccel(
|
|
INT *dx,
|
|
INT *dw);
|
|
|
|
VOID ReadDefaultAccelerationCurves(
|
|
PUNICODE_STRING pProfileUserName);
|
|
|
|
VOID ResetMouseAccelerationCurves(
|
|
VOID);
|
|
#endif // SUBPIXEL_MOUSE
|
|
|
|
#ifdef AUTORUN_CURSOR
|
|
VOID ShowAutorunCursor(
|
|
ULONG ulTimeout);
|
|
|
|
VOID HideAutorunCursor(
|
|
PWND pwnd,
|
|
UINT message,
|
|
UINT_PTR nID,
|
|
LPARAM lParam);
|
|
#endif // AUTORUN_CURSOR
|
|
|
|
/*
|
|
* These must go after globals.h is #include'd, as they're inline functions and
|
|
* they use gptiCurrent (indirectly, by way of ThreadLock()).
|
|
*/
|
|
__inline VOID ThreadLockMenuNoModify(
|
|
PMENU pMenu,
|
|
PTL ptl)
|
|
{
|
|
UserAssert(!TestMF(pMenu, MFREADONLY));
|
|
SetMF(pMenu, MFREADONLY);
|
|
ThreadLock(pMenu, ptl);
|
|
}
|
|
|
|
__inline VOID ThreadLockMenuAlwaysNoModify(
|
|
PMENU pMenu,
|
|
PTL ptl)
|
|
{
|
|
UserAssert(!TestMF(pMenu, MFREADONLY));
|
|
SetMF(pMenu, MFREADONLY);
|
|
ThreadLockAlways(pMenu, ptl);
|
|
}
|
|
|
|
__inline VOID ThreadUnlockMenuNoModify(
|
|
PTL ptl)
|
|
{
|
|
UserAssert(TestMF((PMENU)ptl->pobj, MFREADONLY));
|
|
ClearMF((PMENU)ptl->pobj, MFREADONLY);
|
|
ThreadUnlock(ptl);
|
|
}
|
|
|
|
__inline int
|
|
SetBestStretchMode(
|
|
HDC hdc,
|
|
UINT bpp,
|
|
BOOL fHT)
|
|
{
|
|
return GreSetStretchBltMode(
|
|
hdc,
|
|
((fHT) ?
|
|
HALFTONE : ((bpp == 1) ? BLACKONWHITE : COLORONCOLOR)));
|
|
}
|
|
|
|
#endif
|