📄 message.c
字号:
/*
* @implemented
*/
BOOL STDCALL
TranslateMessage(CONST MSG *lpMsg)
{
return(TranslateMessageEx((LPMSG)lpMsg, 0));
}
/*
* @implemented
*/
BOOL
STDCALL
WaitMessage(VOID)
{
return NtUserWaitMessage();
}
/*
* @implemented
*/
UINT STDCALL
RegisterWindowMessageA(LPCSTR lpString)
{
UNICODE_STRING String;
BOOLEAN Result;
UINT Atom;
Result = RtlCreateUnicodeStringFromAsciiz(&String, (PCSZ)lpString);
if (!Result)
{
return(0);
}
Atom = NtUserRegisterWindowMessage(&String);
RtlFreeUnicodeString(&String);
return(Atom);
}
/*
* @implemented
*/
UINT STDCALL
RegisterWindowMessageW(LPCWSTR lpString)
{
UNICODE_STRING String;
RtlInitUnicodeString(&String, lpString);
return(NtUserRegisterWindowMessage(&String));
}
/*
* @implemented
*/
HWND STDCALL
SetCapture(HWND hWnd)
{
return(NtUserSetCapture(hWnd));
}
/*
* @implemented
*/
HWND STDCALL
GetCapture(VOID)
{
return(NtUserGetCapture());
}
/*
* @implemented
*/
BOOL STDCALL
ReleaseCapture(VOID)
{
NtUserSetCapture(NULL);
return(TRUE);
}
/*
* @unimplemented
*/
DWORD
STDCALL
RealGetQueueStatus(UINT flags)
{
DWORD ret;
WORD changed_bits, wake_bits;
#if 0 /* wine stuff. don't know what it does... */
/* check for pending X events */
if (USER_Driver.pMsgWaitForMultipleObjectsEx)
USER_Driver.pMsgWaitForMultipleObjectsEx( 0, NULL, 0, 0, 0 );
#endif
ret = NtUserGetQueueStatus(TRUE /*ClearChanges*/);
changed_bits = LOWORD(ret);
wake_bits = HIWORD(ret);
return MAKELONG(changed_bits & flags, wake_bits & flags);
}
/*
* @unimplemented
*/
BOOL STDCALL GetInputState(VOID)
{
DWORD ret;
WORD wake_bits;
#if 0 /* wine stuff. don't know what it does... */
/* check for pending X events */
if (USER_Driver.pMsgWaitForMultipleObjectsEx)
USER_Driver.pMsgWaitForMultipleObjectsEx( 0, NULL, 0, 0, 0 );
#endif
ret = NtUserGetQueueStatus(FALSE /*ClearChanges*/);
wake_bits = HIWORD(ret);
return wake_bits & (QS_KEY | QS_MOUSEBUTTON);
}
NTSTATUS STDCALL
User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength)
{
PWINDOWPROC_CALLBACK_ARGUMENTS CallbackArgs;
MSG KMMsg, UMMsg;
/* Make sure we don't try to access mem beyond what we were given */
if (ArgumentLength < sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
{
return STATUS_INFO_LENGTH_MISMATCH;
}
CallbackArgs = (PWINDOWPROC_CALLBACK_ARGUMENTS) Arguments;
KMMsg.hwnd = CallbackArgs->Wnd;
KMMsg.message = CallbackArgs->Msg;
KMMsg.wParam = CallbackArgs->wParam;
/* Check if lParam is really a pointer and adjust it if it is */
if (0 <= CallbackArgs->lParamBufferSize)
{
if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS)
+ CallbackArgs->lParamBufferSize)
{
return STATUS_INFO_LENGTH_MISMATCH;
}
KMMsg.lParam = (LPARAM) ((char *) CallbackArgs + sizeof(WINDOWPROC_CALLBACK_ARGUMENTS));
}
else
{
if (ArgumentLength != sizeof(WINDOWPROC_CALLBACK_ARGUMENTS))
{
return STATUS_INFO_LENGTH_MISMATCH;
}
KMMsg.lParam = CallbackArgs->lParam;
}
if (WM_NCCALCSIZE == CallbackArgs->Msg && CallbackArgs->wParam)
{
NCCALCSIZE_PARAMS *Params = (NCCALCSIZE_PARAMS *) KMMsg.lParam;
Params->lppos = (PWINDOWPOS) (Params + 1);
}
if (! MsgiKMToUMMessage(&KMMsg, &UMMsg))
{
}
CallbackArgs->Result = IntCallWindowProcW(CallbackArgs->IsAnsiProc, CallbackArgs->Proc,
UMMsg.hwnd, UMMsg.message,
UMMsg.wParam, UMMsg.lParam);
if (! MsgiKMToUMReply(&KMMsg, &UMMsg, &CallbackArgs->Result))
{
}
return ZwCallbackReturn(CallbackArgs, ArgumentLength, STATUS_SUCCESS);
}
/*
* @implemented
*/
BOOL STDCALL SetMessageQueue(int cMessagesMax)
{
/* Function does nothing on 32 bit windows */
return TRUE;
}
typedef DWORD (WINAPI * RealGetQueueStatusProc)(UINT flags);
typedef DWORD (WINAPI * RealMsgWaitForMultipleObjectsExProc)(DWORD nCount, CONST HANDLE *lpHandles, DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags);
typedef struct _USER_MESSAGE_PUMP_ADDRESSES {
DWORD cbSize;
//NtUserRealInternalGetMessageProc NtUserRealInternalGetMessage;
//NtUserRealWaitMessageExProc NtUserRealWaitMessageEx;
RealGetQueueStatusProc RealGetQueueStatus;
RealMsgWaitForMultipleObjectsExProc RealMsgWaitForMultipleObjectsEx;
} USER_MESSAGE_PUMP_ADDRESSES, * PUSER_MESSAGE_PUMP_ADDRESSES;
DWORD
STDCALL
RealMsgWaitForMultipleObjectsEx(
DWORD nCount,
CONST HANDLE *pHandles,
DWORD dwMilliseconds,
DWORD dwWakeMask,
DWORD dwFlags);
typedef BOOL (WINAPI * MESSAGEPUMPHOOKPROC)(BOOL Unregistering,PUSER_MESSAGE_PUMP_ADDRESSES MessagePumpAddresses);
CRITICAL_SECTION gcsMPH;
MESSAGEPUMPHOOKPROC gpfnInitMPH;
DWORD gcLoadMPH = 0;
USER_MESSAGE_PUMP_ADDRESSES gmph = {sizeof(USER_MESSAGE_PUMP_ADDRESSES),
//NtUserRealInternalGetMessage,
//NtUserRealInternalWaitMessageEx,
RealGetQueueStatus,
RealMsgWaitForMultipleObjectsEx
};
DWORD gfMessagePumpHook = 0;
BOOL WINAPI IsInsideMessagePumpHook()
{
if(!gfMessagePumpHook)
return FALSE;
/* This code checks if we're inside SendMessage. */
#if 0
/* Since our TEB doesnt match that of real windows, testing this value is useless until we know what it does
PUCHAR NtTeb = (PUCHAR)NtCurrentTeb();
if(!*(PLONG*)&NtTeb[0x708])
return FALSE;
if(**(PLONG*)&NtTeb[0x708] <= 0)
return FALSE;*/
#endif
return TRUE;
}
void WINAPI ResetMessagePumpHook(PUSER_MESSAGE_PUMP_ADDRESSES Addresses)
{
Addresses->cbSize = sizeof(USER_MESSAGE_PUMP_ADDRESSES);
//Addresses->NtUserRealInternalGetMessage = (NtUserRealInternalGetMessageProc)NtUserRealInternalGetMessage;
//Addresses->NtUserRealWaitMessageEx = (NtUserRealWaitMessageExProc)NtUserRealInternalWaitMessageEx;
Addresses->RealGetQueueStatus = RealGetQueueStatus;
Addresses->RealMsgWaitForMultipleObjectsEx = RealMsgWaitForMultipleObjectsEx;
}
BOOL WINAPI RegisterMessagePumpHook(MESSAGEPUMPHOOKPROC Hook)
{
EnterCriticalSection(&gcsMPH);
if(!Hook) {
SetLastError(ERROR_INVALID_PARAMETER);
LeaveCriticalSection(&gcsMPH);
return FALSE;
}
if(!gcLoadMPH) {
USER_MESSAGE_PUMP_ADDRESSES Addresses;
gpfnInitMPH = Hook;
ResetMessagePumpHook(&Addresses);
if(!Hook(FALSE, &Addresses) || !Addresses.cbSize) {
LeaveCriticalSection(&gcsMPH);
return FALSE;
}
memcpy(&gmph, &Addresses, Addresses.cbSize);
} else {
if(gpfnInitMPH != Hook) {
LeaveCriticalSection(&gcsMPH);
return FALSE;
}
}
if(NtUserCallNoParam(NOPARAM_ROUTINE_INIT_MESSAGE_PUMP)) {
LeaveCriticalSection(&gcsMPH);
return FALSE;
}
if (!gcLoadMPH++) {
InterlockedExchange((PLONG)&gfMessagePumpHook, 1);
}
LeaveCriticalSection(&gcsMPH);
return TRUE;
}
BOOL WINAPI UnregisterMessagePumpHook(VOID)
{
EnterCriticalSection(&gcsMPH);
if(gcLoadMPH > 0) {
if(NtUserCallNoParam(NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP)) {
gcLoadMPH--;
if(!gcLoadMPH) {
InterlockedExchange((PLONG)&gfMessagePumpHook, 0);
gpfnInitMPH(TRUE, NULL);
ResetMessagePumpHook(&gmph);
gpfnInitMPH = 0;
}
LeaveCriticalSection(&gcsMPH);
return TRUE;
}
}
LeaveCriticalSection(&gcsMPH);
return FALSE;
}
DWORD WINAPI GetQueueStatus(UINT flags)
{
return IsInsideMessagePumpHook() ? gmph.RealGetQueueStatus(flags) : RealGetQueueStatus(flags);
}
/**
* @name RealMsgWaitForMultipleObjectsEx
*
* Wait either for either message arrival or for one of the passed events
* to be signalled.
*
* @param nCount
* Number of handles in the pHandles array.
* @param pHandles
* Handles of events to wait for.
* @param dwMilliseconds
* Timeout interval.
* @param dwWakeMask
* Mask specifying on which message events we should wakeup.
* @param dwFlags
* Wait type (see MWMO_* constants).
*
* @implemented
*/
DWORD STDCALL
RealMsgWaitForMultipleObjectsEx(
DWORD nCount,
const HANDLE *pHandles,
DWORD dwMilliseconds,
DWORD dwWakeMask,
DWORD dwFlags)
{
LPHANDLE RealHandles;
HANDLE MessageQueueHandle;
DWORD Result;
if (dwFlags & ~(MWMO_WAITALL | MWMO_ALERTABLE | MWMO_INPUTAVAILABLE))
{
SetLastError(ERROR_INVALID_PARAMETER);
return WAIT_FAILED;
}
/*
if (dwFlags & MWMO_INPUTAVAILABLE)
{
RealGetQueueStatus(dwWakeMask);
}
*/
MessageQueueHandle = NtUserMsqSetWakeMask(dwWakeMask);
if (MessageQueueHandle == NULL)
{
SetLastError(0); /* ? */
return WAIT_FAILED;
}
RealHandles = HeapAlloc(GetProcessHeap(), 0, (nCount + 1) * sizeof(HANDLE));
if (RealHandles == NULL)
{
NtUserMsqClearWakeMask();
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return WAIT_FAILED;
}
RtlCopyMemory(RealHandles, pHandles, nCount * sizeof(HANDLE));
RealHandles[nCount] = MessageQueueHandle;
Result = WaitForMultipleObjectsEx(nCount + 1, RealHandles,
dwFlags & MWMO_WAITALL,
dwMilliseconds, dwFlags & MWMO_ALERTABLE);
HeapFree(GetProcessHeap(), 0, RealHandles);
NtUserMsqClearWakeMask();
return Result;
}
/*
* @implemented
*/
DWORD WINAPI
MsgWaitForMultipleObjectsEx(
DWORD nCount,
CONST HANDLE *lpHandles,
DWORD dwMilliseconds,
DWORD dwWakeMask,
DWORD dwFlags)
{
return IsInsideMessagePumpHook() ? gmph.RealMsgWaitForMultipleObjectsEx(nCount, lpHandles, dwMilliseconds, dwWakeMask, dwFlags) : RealMsgWaitForMultipleObjectsEx(nCount, lpHandles,dwMilliseconds, dwWakeMask, dwFlags);
}
/*
* @implemented
*/
DWORD STDCALL
MsgWaitForMultipleObjects(
DWORD nCount,
CONST HANDLE *lpHandles,
BOOL fWaitAll,
DWORD dwMilliseconds,
DWORD dwWakeMask)
{
return MsgWaitForMultipleObjectsEx(nCount, lpHandles, dwMilliseconds,
dwWakeMask, fWaitAll ? MWMO_WAITALL : 0);
}
BOOL FASTCALL MessageInit(VOID)
{
InitializeCriticalSection(&DdeCrst);
InitializeCriticalSection(&MsgConversionCrst);
InitializeCriticalSection(&gcsMPH);
return TRUE;
}
VOID FASTCALL MessageCleanup(VOID)
{
DeleteCriticalSection(&DdeCrst);
DeleteCriticalSection(&MsgConversionCrst);
DeleteCriticalSection(&gcsMPH);
}
/***********************************************************************
* map_wparam_AtoW
*
* Convert the wparam of an ASCII message to Unicode.
*/
static WPARAM
map_wparam_AtoW( UINT message, WPARAM wparam )
{
switch(message)
{
case WM_CHARTOITEM:
case EM_SETPASSWORDCHAR:
case WM_CHAR:
case WM_DEADCHAR:
case WM_SYSCHAR:
case WM_SYSDEADCHAR:
case WM_MENUCHAR:
{
char ch[2];
WCHAR wch[2];
ch[0] = (wparam & 0xff);
ch[1] = (wparam >> 8);
MultiByteToWideChar(CP_ACP, 0, ch, 2, wch, 2);
wparam = MAKEWPARAM(wch[0], wch[1]);
}
break;
case WM_IME_CHAR:
{
char ch[2];
WCHAR wch;
ch[0] = (wparam >> 8);
ch[1] = (wparam & 0xff);
if (ch[0]) MultiByteToWideChar(CP_ACP, 0, ch, 2, &wch, 1);
else MultiByteToWideChar(CP_ACP, 0, &ch[1], 1, &wch, 1);
wparam = MAKEWPARAM( wch, HIWORD(wparam) );
}
break;
}
return wparam;
}
/*
* @implemented
*/
BOOL WINAPI
IsDialogMessageA( HWND hwndDlg, LPMSG pmsg )
{
MSG msg = *pmsg;
msg.wParam = map_wparam_AtoW( msg.message, msg.wParam );
return IsDialogMessageW( hwndDlg, &msg );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -