Author: gadamopoulos
Date: Mon Sep 19 08:32:38 2011
New Revision: 53745
URL:
http://svn.reactos.org/svn/reactos?rev=53745&view=rev
Log:
[win32k]
- Merge changes from the themes branch. These changes will introduce test regressions for
class functions and for TrackMouseEvent. The changes in the class functions are needed in
order to let comctl32 register its own versions of built in controls. This is a hack and
will be removed when we properly support class versions. The second change that causes
test regressions is in TrackMouseEvent and it is needed in order to fix WM_MOUSELEAVE
messages that were completely broken and not tested at all by wine's test suite.
Modified:
trunk/reactos/subsystems/win32/win32k/include/callback.h
trunk/reactos/subsystems/win32/win32k/include/hook.h
trunk/reactos/subsystems/win32/win32k/include/msgqueue.h
trunk/reactos/subsystems/win32/win32k/include/win32.h
trunk/reactos/subsystems/win32/win32k/main/dllmain.c
trunk/reactos/subsystems/win32/win32k/ntuser/callback.c
trunk/reactos/subsystems/win32/win32k/ntuser/class.c
trunk/reactos/subsystems/win32/win32k/ntuser/hook.c
trunk/reactos/subsystems/win32/win32k/ntuser/input.c
trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c
trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c
trunk/reactos/subsystems/win32/win32k/ntuser/timer.c
trunk/reactos/subsystems/win32/win32k/objects/bitblt.c
Modified: trunk/reactos/subsystems/win32/win32k/include/callback.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/callback.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/callback.h [iso-8859-1] Mon Sep 19
08:32:38 2011
@@ -54,3 +54,10 @@
HMENU APIENTRY co_IntCallLoadMenu(HINSTANCE,PUNICODE_STRING);
NTSTATUS APIENTRY co_IntClientThreadSetup(VOID);
+
+HMODULE
+co_IntClientLoadLibrary(PUNICODE_STRING strLibName,
+ PUNICODE_STRING strInitFunc,
+ BOOL Unload,
+ BOOL ApiHook);
+
Modified: trunk/reactos/subsystems/win32/win32k/include/hook.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/hook.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/hook.h [iso-8859-1] Mon Sep 19 08:32:38
2011
@@ -4,6 +4,13 @@
#define HOOKID_TO_INDEX(HookId) (HookId - WH_MINHOOK)
#define HOOKID_TO_FLAG(HookId) (1 << ((HookId) + 1))
#define ISITHOOKED(HookId) (((PTHREADINFO)PsGetCurrentThreadWin32Thread())->fsHooks
& HOOKID_TO_FLAG(HookId))
+
+/* NOTE: the following definition is not a real hook but
+ a pseudo-id that will be used only for
+ injecting user api hook module to all processes.
+ It is used internally in win32k */
+#define WH_APIHOOK WH_MAX + 1
+
typedef struct tagEVENTHOOK
{
@@ -43,4 +50,10 @@
LRESULT FASTCALL UserCallNextHookEx( PHOOK pHook, int Code, WPARAM wParam, LPARAM lParam,
BOOL Ansi);
BOOL FASTCALL IntUnhookWindowsHook(int,HOOKPROC);
+BOOL FASTCALL UserLoadApiHook();
+BOOL IntLoadHookModule(int iHookID, HHOOK hHook, BOOL Unload);
+BOOL FASTCALL UserUnregisterUserApiHook();
+
+extern PPROCESSINFO ppiUahServer;
+
/* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/include/msgqueue.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/msgqueue.h [iso-8859-1] Mon Sep 19
08:32:38 2011
@@ -4,6 +4,7 @@
#define MSQ_NORMAL 0
#define MSQ_ISHOOK 1
#define MSQ_ISEVENT 2
+#define MSQ_INJECTMODULE 3
#define QSIDCOUNTS 6
@@ -206,6 +207,16 @@
SENDASYNCPROC CompletionCallback,
ULONG_PTR CompletionCallbackContext,
ULONG_PTR *uResult);
+BOOL FASTCALL
+co_MsqSendMessageAsync(PTHREADINFO ptiReceiver,
+ HWND hwnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ SENDASYNCPROC CompletionCallback,
+ ULONG_PTR CompletionCallbackContext,
+ BOOL HasPackedLParam,
+ INT HookMessage);
LRESULT FASTCALL IntDispatchMessage(MSG* Msg);
BOOL FASTCALL IntTranslateKbdMessage(LPMSG lpMsg, UINT flags);
Modified: trunk/reactos/subsystems/win32/win32k/include/win32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/win32.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/win32.h [iso-8859-1] Mon Sep 19 08:32:38
2011
@@ -30,6 +30,7 @@
#define W32PF_NOWINDOWGHOSTING (0x01000000)
#define W32PF_MANUALGUICHECK (0x02000000)
#define W32PF_CREATEDWINORDC (0x04000000)
+#define W32PF_APIHOOKLOADED (0x08000000)
extern BOOL ClientPfnInit;
extern HINSTANCE hModClient;
Modified: trunk/reactos/subsystems/win32/win32k/main/dllmain.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ma…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] Mon Sep 19 08:32:38
2011
@@ -393,6 +393,22 @@
/* Remove it from the list */
*ppti = ptiCurrent->ptiSibling;
+ /* Decrement thread count and check if its 0 */
+ ppiCurrent->cThreads--;
+
+ /* Do now some process cleanup that requires a valid win32 thread */
+ if(ptiCurrent->ppi->cThreads == 0)
+ {
+ UserSetCursor(NULL, TRUE);
+
+ /* Check if we have registered the user api hook */
+ if(ptiCurrent->ppi == ppiUahServer)
+ {
+ /* Unregister the api hook without blocking */
+ UserUnregisterUserApiHook();
+ }
+ }
+
DceFreeThreadDCE(ptiCurrent);
HOOK_DestroyThreadHooks(Thread);
EVENT_DestroyThreadEvents(Thread);
@@ -421,14 +437,6 @@
IntSetThreadDesktop(NULL, TRUE);
- /* Decrement thread count and check if its 0 */
- ppiCurrent->cThreads--;
- if (ppiCurrent->cThreads == 0)
- {
- /* UGLY: Prevent this function from being called later
- when we don't have a THREADINFO anymore. */
- UserSetCursor(NULL, TRUE);
- }
/* Free the THREADINFO */
PsSetThreadWin32Thread(Thread, NULL);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/callback.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/callback.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/callback.c [iso-8859-1] Mon Sep 19
08:32:38 2011
@@ -115,6 +115,114 @@
}
/* FUNCTIONS *****************************************************************/
+
+/* calls ClientLoadLibrary in user32 */
+HMODULE
+co_IntClientLoadLibrary(PUNICODE_STRING pstrLibName,
+ PUNICODE_STRING pstrInitFunc,
+ BOOL Unload,
+ BOOL ApiHook)
+{
+ PVOID ResultPointer;
+ ULONG ResultLength;
+ ULONG ArgumentLength;
+ PCLIENT_LOAD_LIBRARY_ARGUMENTS pArguments;
+ NTSTATUS Status;
+ HMODULE Result;
+ ULONG_PTR pLibNameBuffer = 0, pInitFuncBuffer = 0;
+
+ TRACE("co_IntClientLoadLibrary: %S, %S, %d, %d\n", pstrLibName->Buffer,
pstrLibName->Buffer, Unload, ApiHook);
+
+ /* Calculate the size of the argument */
+ ArgumentLength = sizeof(CLIENT_LOAD_LIBRARY_ARGUMENTS);
+ if(pstrLibName)
+ {
+ pLibNameBuffer = ArgumentLength;
+ ArgumentLength += pstrLibName->Length + sizeof(WCHAR);
+ }
+ if(pstrInitFunc)
+ {
+ pInitFuncBuffer = ArgumentLength;
+ ArgumentLength += pstrInitFunc->Length + sizeof(WCHAR);
+ }
+
+ /* Allocate the argument*/
+ pArguments = IntCbAllocateMemory(ArgumentLength);
+ if(pArguments == NULL)
+ {
+ return FALSE;
+ }
+
+ /* Fill the argument */
+ pArguments->Unload = Unload;
+ pArguments->ApiHook = ApiHook;
+ if(pstrLibName)
+ {
+ /* Copy the string to the callback memory */
+ pLibNameBuffer += (ULONG_PTR)pArguments;
+ pArguments->strLibraryName.Buffer = (PWCHAR)pLibNameBuffer;
+ pArguments->strLibraryName.MaximumLength = pstrLibName->Length +
sizeof(WCHAR);
+ RtlCopyUnicodeString(&pArguments->strLibraryName, pstrLibName);
+
+ /* Fix argument pointer to be relative to the argument */
+ pLibNameBuffer -= (ULONG_PTR)pArguments;
+ pArguments->strLibraryName.Buffer = (PWCHAR)(pLibNameBuffer);
+ }
+ else
+ {
+ RtlZeroMemory(&pArguments->strLibraryName, sizeof(UNICODE_STRING));
+ }
+
+ if(pstrInitFunc)
+ {
+ /* Copy the strings to the callback memory */
+ pInitFuncBuffer += (ULONG_PTR)pArguments;
+ pArguments->strInitFuncName.Buffer = (PWCHAR)pInitFuncBuffer;
+ pArguments->strInitFuncName.MaximumLength = pstrInitFunc->Length +
sizeof(WCHAR);
+ RtlCopyUnicodeString(&pArguments->strInitFuncName, pstrInitFunc);
+
+ /* Fix argument pointers to be relative to the argument */
+ pInitFuncBuffer -= (ULONG_PTR)pArguments;
+ pArguments->strInitFuncName.Buffer = (PWCHAR)(pInitFuncBuffer);
+ }
+ else
+ {
+ RtlZeroMemory(&pArguments->strInitFuncName, sizeof(UNICODE_STRING));
+ }
+
+ /* Do the callback */
+ UserLeaveCo();
+
+ Status = KeUserModeCallback(USER32_CALLBACK_CLIENTLOADLIBRARY,
+ pArguments,
+ ArgumentLength,
+ &ResultPointer,
+ &ResultLength);
+
+ UserEnterCo();
+
+ /* Free the argument */
+ IntCbFreeMemory(pArguments);
+
+ if(!NT_SUCCESS(Status))
+ {
+ return FALSE;
+ }
+
+ _SEH2_TRY
+ {
+ ProbeForRead(ResultPointer, sizeof(HMODULE), 1);
+ /* Simulate old behaviour: copy into our local buffer */
+ Result = *(HMODULE*)ResultPointer;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Result = 0;
+ }
+ _SEH2_END;
+
+ return Result;
+}
VOID APIENTRY
co_IntCallSentMessageCallback(SENDASYNCPROC CompletionCallback,
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/class.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/class.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/class.c [iso-8859-1] Mon Sep 19 08:32:38
2011
@@ -1295,8 +1295,9 @@
if (lpwcx->style & CS_GLOBALCLASS)
{
+ /* HACK: allow global classes to be re-registered*/
Class = IntFindClass( ClassAtom,
- NULL,
+ lpwcx->hInstance,
&pi->pclsPublicList,
NULL);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/hook.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/hook.c [iso-8859-1] Mon Sep 19 08:32:38
2011
@@ -24,7 +24,221 @@
PVOID pHookStructs;
} HOOKPACK, *PHOOKPACK;
+UNICODE_STRING strUahModule;
+UNICODE_STRING strUahInitFunc;
+PPROCESSINFO ppiUahServer;
+
/* PRIVATE FUNCTIONS *********************************************************/
+
+/* Calls ClientLoadLibrary in user32 in order to load or unload a module */
+BOOL
+IntLoadHookModule(int iHookID, HHOOK hHook, BOOL Unload)
+{
+ PPROCESSINFO ppi;
+ HMODULE hmod;
+
+ ppi = PsGetCurrentProcessWin32Process();
+
+ ERR("IntLoadHookModule. Client PID: %d\n",
PsGetProcessId(ppi->peProcess));
+
+ /* Check if this is the api hook */
+ if(iHookID == WH_APIHOOK)
+ {
+ if(!Unload && !(ppi->W32PF_flags & W32PF_APIHOOKLOADED))
+ {
+ /* A callback in user mode can trigger UserLoadApiHook to be called and
+ as a result IntLoadHookModule will be called recursively.
+ To solve this we set the flag that means that the appliaction has
+ loaded the api hook before the callback and in case of error we remove it
*/
+ ppi->W32PF_flags |= W32PF_APIHOOKLOADED;
+
+ /* Call ClientLoadLibrary in user32 */
+ hmod = co_IntClientLoadLibrary(&strUahModule, &strUahInitFunc,
Unload, TRUE);
+ TRACE("co_IntClientLoadLibrary returned %d\n", hmod );
+ if(hmod == 0)
+ {
+ /* Remove the flag we set before */
+ ppi->W32PF_flags &= ~W32PF_APIHOOKLOADED;
+ return FALSE;
+ }
+ return TRUE;
+ }
+ else if(Unload && (ppi->W32PF_flags & W32PF_APIHOOKLOADED))
+ {
+ /* Call ClientLoadLibrary in user32 */
+ hmod = co_IntClientLoadLibrary(NULL, NULL, Unload, TRUE);
+ if(hmod != 0)
+ {
+ ppi->W32PF_flags &= ~W32PF_APIHOOKLOADED;
+ return TRUE;
+ }
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ STUB;
+
+ return FALSE;
+}
+
+/*
+IntHookModuleUnloaded:
+Sends a internal message to all threads of the requested desktop
+and notifies them that a global hook was destroyed
+and an injected module must be unloaded.
+As a result, IntLoadHookModule will be called for all the threads that
+will receive the special purpose internal message.
+*/
+BOOL
+IntHookModuleUnloaded(PDESKTOP pdesk, int iHookID, HHOOK hHook)
+{
+ PTHREADINFO ptiCurrent;
+ PLIST_ENTRY ListEntry;
+ PPROCESSINFO ppiCsr;
+
+ ERR("IntHookModuleUnloaded: iHookID=%d\n", iHookID);
+
+ ppiCsr = PsGetProcessWin32Process(CsrProcess);
+
+ ListEntry = pdesk->PtiList.Flink;
+ while(ListEntry != &pdesk->PtiList)
+ {
+ ptiCurrent = CONTAINING_RECORD(ListEntry, THREADINFO, PtiLink);
+
+ /* FIXME: do some more security checks here */
+
+ /* FIXME: the first check is a reactos specific hack for system threads */
+ if(!PsIsSystemProcess(ptiCurrent->ppi->peProcess) &&
+ ptiCurrent->ppi != ppiCsr)
+ {
+ if(ptiCurrent->ppi->W32PF_flags & W32PF_APIHOOKLOADED)
+ {
+ TRACE("IntHookModuleUnloaded: sending message to PID %d,
ppi=0x%x\n", PsGetProcessId(ptiCurrent->ppi->peProcess), ptiCurrent->ppi);
+ co_MsqSendMessageAsync( ptiCurrent,
+ 0,
+ iHookID,
+ TRUE,
+ (LPARAM)hHook,
+ NULL,
+ 0,
+ FALSE,
+ MSQ_INJECTMODULE);
+ }
+ }
+ ListEntry = ListEntry->Flink;
+ }
+
+ return TRUE;
+}
+
+BOOL
+FASTCALL
+UserLoadApiHook()
+{
+ return IntLoadHookModule(WH_APIHOOK, 0, FALSE);
+}
+
+BOOL
+FASTCALL
+UserRegisterUserApiHook(
+ PUNICODE_STRING pstrDllName,
+ PUNICODE_STRING pstrFuncName)
+{
+ PTHREADINFO pti, ptiCurrent;
+ HWND *List;
+ PWND DesktopWindow, pwndCurrent;
+ ULONG i;
+ PPROCESSINFO ppiCsr;
+
+ pti = PsGetCurrentThreadWin32Thread();
+ ppiCsr = PsGetProcessWin32Process(CsrProcess);
+
+ /* Fail if the api hook is already registered */
+ if(gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
+ {
+ return FALSE;
+ }
+
+ ERR("UserRegisterUserApiHook. Server PID: %d\n",
PsGetProcessId(pti->ppi->peProcess));
+
+ /* Register the api hook */
+ gpsi->dwSRVIFlags |= SRVINFO_APIHOOK;
+
+ strUahModule = *pstrDllName;
+ strUahInitFunc = *pstrFuncName;
+ ppiUahServer = pti->ppi;
+
+ /* Broadcast an internal message to every top level window */
+ DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+ List = IntWinListChildren(DesktopWindow);
+
+ if (List != NULL)
+ {
+ for (i = 0; List[i]; i++)
+ {
+ pwndCurrent = UserGetWindowObject(List[i]);
+ if(pwndCurrent == NULL)
+ {
+ continue;
+ }
+ ptiCurrent = pwndCurrent->head.pti;
+
+ /* FIXME: the first check is a reactos specific hack for system threads */
+ if(PsIsSystemProcess(ptiCurrent->ppi->peProcess) ||
+ ptiCurrent->ppi == ppiCsr)
+ {
+ continue;
+ }
+
+ co_MsqSendMessageAsync( ptiCurrent,
+ 0,
+ WH_APIHOOK,
+ FALSE, /* load the module */
+ 0,
+ NULL,
+ 0,
+ FALSE,
+ MSQ_INJECTMODULE);
+ }
+ ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+ }
+
+ return TRUE;
+}
+
+BOOL
+FASTCALL
+UserUnregisterUserApiHook()
+{
+ PTHREADINFO pti;
+
+ pti = PsGetCurrentThreadWin32Thread();
+
+ /* Fail if the api hook is not registered */
+ if(!(gpsi->dwSRVIFlags & SRVINFO_APIHOOK))
+ {
+ return FALSE;
+ }
+
+ /* Only the process that registered the api hook can uregister it */
+ if(ppiUahServer != PsGetCurrentProcessWin32Process())
+ {
+ return FALSE;
+ }
+
+ ERR("UserUnregisterUserApiHook. Server PID: %d\n",
PsGetProcessId(pti->ppi->peProcess));
+
+ /* Unregister the api hook */
+ gpsi->dwSRVIFlags &= ~SRVINFO_APIHOOK;
+ ppiUahServer = NULL;
+ ReleaseCapturedUnicodeString(&strUahModule, UserMode);
+ ReleaseCapturedUnicodeString(&strUahInitFunc, UserMode);
+
+ /* Notify all applications that the api hook module must be unloaded */
+ return IntHookModuleUnloaded(pti->rpdesk, WH_APIHOOK, 0);
+}
static
LRESULT
@@ -1510,4 +1724,64 @@
END_CLEANUP;
}
+BOOL
+APIENTRY
+NtUserRegisterUserApiHook(
+ PUNICODE_STRING m_dllname1,
+ PUNICODE_STRING m_funname1,
+ DWORD dwUnknown3,
+ DWORD dwUnknown4)
+{
+ BOOL ret;
+ UNICODE_STRING strDllNameSafe;
+ UNICODE_STRING strFuncNameSafe;
+ NTSTATUS Status;
+
+ /* Probe and capture parameters */
+ Status = ProbeAndCaptureUnicodeString(&strDllNameSafe, UserMode, m_dllname1);
+ if(!NT_SUCCESS(Status))
+ {
+ EngSetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ Status = ProbeAndCaptureUnicodeString(&strFuncNameSafe, UserMode, m_funname1);
+ if(!NT_SUCCESS(Status))
+ {
+ ReleaseCapturedUnicodeString(&strDllNameSafe, UserMode);
+ EngSetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ UserEnterExclusive();
+
+ /* Call internal function */
+ ret = UserRegisterUserApiHook(&strDllNameSafe, &strFuncNameSafe);
+
+ UserLeave();
+
+ /* Cleanup only in case of failure */
+ if(ret == FALSE)
+ {
+ ReleaseCapturedUnicodeString(&strDllNameSafe, UserMode);
+ ReleaseCapturedUnicodeString(&strFuncNameSafe, UserMode);
+ }
+
+ return ret;
+}
+
+BOOL
+APIENTRY
+NtUserUnregisterUserApiHook(VOID)
+{
+ BOOL ret;
+
+ UserEnterExclusive();
+ ret = UserUnregisterUserApiHook();
+ UserLeave();
+
+ return ret;
+}
+
+
/* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/input.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/input.c [iso-8859-1] Mon Sep 19 08:32:38
2011
@@ -1611,19 +1611,6 @@
if (!(pWnd = UserGetWindowObject(lpEventTrack->hwndTrack)))
return FALSE;
- if ( pDesk->spwndTrack != pWnd ||
- (pDesk->htEx != HTCLIENT) ^ !!(lpEventTrack->dwFlags &
TME_NONCLIENT) )
- {
- if ( lpEventTrack->dwFlags & TME_LEAVE &&
!(lpEventTrack->dwFlags & TME_CANCEL) )
- {
- UserPostMessage( lpEventTrack->hwndTrack,
- lpEventTrack->dwFlags & TME_NONCLIENT ?
WM_NCMOUSELEAVE : WM_MOUSELEAVE,
- 0, 0);
- }
- TRACE("IntTrackMouseEvent spwndTrack 0x%x pwnd 0x%x\n",
pDesk->spwndTrack, pWnd);
- return TRUE;
- }
-
/* Tracking spwndTrack same as pWnd */
if ( lpEventTrack->dwFlags & TME_CANCEL ) // Canceled mode.
{
@@ -1641,6 +1628,7 @@
}
else // Not Canceled.
{
+ pDesk->spwndTrack = pWnd;
if ( lpEventTrack->dwFlags & TME_LEAVE )
pDesk->dwDTFlags |= DF_TME_LEAVE;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] Mon Sep 19
08:32:38 2011
@@ -539,22 +539,35 @@
if (pwnd)
{
- PWND pwndTrack = IntChildrenWindowFromPoint(pwnd, Msg->pt.x, Msg->pt.y);
-
- if ( pDesk->spwndTrack != pwndTrack && pDesk->dwDTFlags &
(DF_TME_LEAVE|DF_TME_HOVER) )
- {
- if ( pDesk->dwDTFlags & DF_TME_LEAVE )
- UserPostMessage( UserHMGetHandle(pDesk->spwndTrack),
- (pDesk->htEx != HTCLIENT) ? WM_NCMOUSELEAVE :
WM_MOUSELEAVE,
- 0, 0);
-
- if ( pDesk->dwDTFlags & DF_TME_HOVER )
- IntKillTimer(UserHMGetHandle(pDesk->spwndTrack),
ID_EVENT_SYSTIMER_MOUSEHOVER, TRUE);
-
- pDesk->dwDTFlags &= ~(DF_TME_LEAVE|DF_TME_HOVER);
- }
- pDesk->spwndTrack = pwndTrack;
- pDesk->htEx = GetNCHitEx(pDesk->spwndTrack, Msg->pt);
+ /* If we a re tracking the mouse and it moves to another top level window */
+ if(pDesk->spwndTrack &&
+ UserGetAncestor(pDesk->spwndTrack, GA_ROOT) != pwnd)
+ {
+ /* Generate a WM_MOUSELEAVE message */
+ if ( pDesk->dwDTFlags & DF_TME_LEAVE )
+ {
+ MSG msgMouseLeave;
+
+ TRACE("co_MsqInsertMouseMessage: generating WM_MOUSELEAVE\n");
+
+ msgMouseLeave.hwnd = UserHMGetHandle(pDesk->spwndTrack);
+ msgMouseLeave.message = WM_MOUSELEAVE;
+ msgMouseLeave.pt = Msg->pt;
+ msgMouseLeave.time = Msg->time;
+ msgMouseLeave.lParam = msgMouseLeave.wParam = 0;
+
+ MsqPostMessage(pwnd->head.pti->MessageQueue, Msg, TRUE, QS_MOUSE);
+ }
+
+ /* Stop tracking */
+ if ( pDesk->dwDTFlags & DF_TME_HOVER )
+ {
+ IntKillTimer(pDesk->spwndTrack, ID_EVENT_SYSTIMER_MOUSEHOVER, TRUE);
+ }
+
+ pDesk->spwndTrack = NULL;
+ pDesk->htEx = 0;
+ }
}
hdcScreen = IntGetScreenDC();
@@ -811,6 +824,12 @@
Message->Msg.wParam,
Message->Msg.lParam);
}
+ else if(Message->HookMessage == MSQ_INJECTMODULE)
+ {
+ Result = IntLoadHookModule(Message->Msg.message,
+ (HHOOK)Message->Msg.lParam,
+ Message->Msg.wParam);
+ }
else if ((Message->CompletionCallback)
&& (Message->CallBackSenderQueue == MessageQueue))
{ /* Call the callback routine */
@@ -1004,6 +1023,58 @@
CurrentEntry = CurrentEntry->Flink;
}
}
+}
+
+BOOL FASTCALL
+co_MsqSendMessageAsync(PTHREADINFO ptiReceiver,
+ HWND hwnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ SENDASYNCPROC CompletionCallback,
+ ULONG_PTR CompletionCallbackContext,
+ BOOL HasPackedLParam,
+ INT HookMessage)
+{
+
+ PTHREADINFO ptiSender;
+ PUSER_SENT_MESSAGE Message;
+
+ if(!(Message = ExAllocatePoolWithTag(NonPagedPool, sizeof(USER_SENT_MESSAGE),
TAG_USRMSG)))
+ {
+ ERR("MsqSendMessage(): Not enough memory to allocate a message");
+ return FALSE;
+ }
+
+ ptiSender = PsGetCurrentThreadWin32Thread();
+
+ IntReferenceMessageQueue(ptiReceiver->MessageQueue);
+ /* Take reference on this MessageQueue if its a callback. It will be released
+ when message is processed or removed from target hwnd MessageQueue */
+ if (CompletionCallback)
+ IntReferenceMessageQueue(ptiSender->MessageQueue);
+
+ Message->Msg.hwnd = hwnd;
+ Message->Msg.message = Msg;
+ Message->Msg.wParam = wParam;
+ Message->Msg.lParam = lParam;
+ Message->CompletionEvent = NULL;
+ Message->Result = 0;
+ Message->lResult = 0;
+ Message->SenderQueue = NULL;
+ Message->CallBackSenderQueue = ptiSender->MessageQueue;
+ Message->DispatchingListEntry.Flink = NULL;
+ Message->CompletionCallback = CompletionCallback;
+ Message->CompletionCallbackContext = CompletionCallbackContext;
+ Message->HookMessage = HookMessage;
+ Message->HasPackedLParam = HasPackedLParam;
+ Message->QS_Flags = QS_SENDMESSAGE;
+
+ InsertTailList(&ptiReceiver->MessageQueue->SentMessagesListHead,
&Message->ListEntry);
+ MsqWakeQueue(ptiReceiver->MessageQueue, QS_SENDMESSAGE, TRUE);
+ IntDereferenceMessageQueue(ptiReceiver->MessageQueue);
+
+ return TRUE;
}
NTSTATUS FASTCALL
@@ -1281,6 +1352,7 @@
PUSER_MESSAGE_QUEUE MessageQueue;
PTHREADINFO pti;
PSYSTEM_CURSORINFO CurInfo;
+ PDESKTOP pDesk;
DECLARE_RETURN(BOOL);
pti = PsGetCurrentThreadWin32Thread();
@@ -1289,6 +1361,7 @@
CurInfo = IntGetSysCursorInfo();
pwndMsg = UserGetWindowObject(msg->hwnd);
clk_msg = MessageQueue->msgDblClk;
+ pDesk = pwndDesktop->head.rpdesk;
/* find the window to dispatch this mouse message to */
if (MessageQueue->CaptureWindow)
@@ -1308,6 +1381,45 @@
/* Remove and ignore the message */
*RemoveMessages = TRUE;
RETURN(FALSE);
+ }
+
+ /* If we a re tracking the mouse and it moves to another window */
+ if(pDesk->spwndTrack &&
+ pDesk->spwndTrack != pwndMsg &&
+ msg->message != WM_MOUSELEAVE)
+ {
+ /* Generate a WM_MOUSELEAVE message */
+ if ( pDesk->dwDTFlags & DF_TME_LEAVE )
+ {
+ MSG msgMouseLeave;
+
+ TRACE("co_IntProcessMouseMessage: generating WM_MOUSELEAVE\n");
+
+ msgMouseLeave.hwnd = UserHMGetHandle(pDesk->spwndTrack);
+ msgMouseLeave.message = WM_MOUSELEAVE;
+ msgMouseLeave.pt = msg->pt;
+ msgMouseLeave.time = msg->time;
+ msgMouseLeave.lParam = msgMouseLeave.wParam = 0;
+
+ MsqPostMessage(pwndMsg->head.pti->MessageQueue,
+ &msgMouseLeave,
+ TRUE,
+ QS_MOUSE);
+ }
+
+ /* Stop tracking */
+ if ( pDesk->dwDTFlags & DF_TME_HOVER )
+ {
+ IntKillTimer(pDesk->spwndTrack, ID_EVENT_SYSTIMER_MOUSEHOVER, TRUE);
+ }
+
+ pDesk->spwndTrack = NULL;
+ pDesk->htEx = 0;
+ }
+
+ if(pDesk->spwndTrack)
+ {
+ pDesk->htEx = hittest;
}
msg->hwnd = UserHMGetHandle(pwndMsg);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c [iso-8859-1] Mon Sep 19
08:32:38 2011
@@ -818,20 +818,6 @@
BOOL
APIENTRY
-NtUserRegisterUserApiHook(
- PUNICODE_STRING m_dllname1,
- PUNICODE_STRING m_funname1,
- DWORD dwUnknown3,
- DWORD dwUnknown4)
-{
- UserEnterExclusive();
- STUB;
- UserLeave();
- return 0;
-}
-
-BOOL
-APIENTRY
NtUserRegisterRawInputDevices(
IN PCRAWINPUTDEVICE pRawInputDevices,
IN UINT uiNumDevices,
@@ -965,14 +951,6 @@
BOOL
APIENTRY
-NtUserUnregisterUserApiHook(VOID)
-{
- STUB;
- return 0;
-}
-
-BOOL
-APIENTRY
NtUserGetLayeredWindowAttributes(
HWND hwnd,
COLORREF *pcrKey,
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/simplecall.c [iso-8859-1] Mon Sep 19
08:32:38 2011
@@ -119,6 +119,9 @@
case NOPARAM_ROUTINE_RELEASECAPTURE:
RETURN( (DWORD_PTR)IntReleaseCapture());
+
+ case NOPARAM_ROUTINE_LOADUSERAPIHOOK:
+ RETURN(UserLoadApiHook());
default:
ERR("Calling invalid routine number 0x%x in NtUserCallNoParam\n",
Routine);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/timer.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/timer.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/timer.c [iso-8859-1] Mon Sep 19 08:32:38
2011
@@ -324,7 +324,7 @@
if ( pDesk->dwDTFlags & DF_TME_HOVER &&
pWnd == pDesk->spwndTrack )
{
- Point = gpsi->ptCursor;
+ Point = pWnd->head.pti->MessageQueue->MouseMoveMsg.pt;
if ( RECTL_bPointInRect(&pDesk->rcMouseHover, Point.x, Point.y) )
{
if (pDesk->htEx == HTCLIENT) // In a client area.
@@ -345,9 +345,18 @@
wParam = pDesk->htEx; // Need to support all HTXYZ hits.
Msg = WM_NCMOUSEHOVER;
}
+ TRACE("Generating WM_NCMOUSEHOVER\n");
UserPostMessage(hwnd, Msg, wParam, MAKELPARAM(Point.x, Point.y));
pDesk->dwDTFlags &= ~DF_TME_HOVER;
break; // Kill this timer.
+ }
+ else
+ {
+ RECTL_vSetRect(&pDesk->rcMouseHover,
+ Point.x - gspv.iMouseHoverWidth / 2,
+ Point.y - gspv.iMouseHoverHeight / 2,
+ Point.x + gspv.iMouseHoverWidth / 2,
+ Point.y + gspv.iMouseHoverHeight / 2);
}
}
}
Modified: trunk/reactos/subsystems/win32/win32k/objects/bitblt.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/bitblt.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/bitblt.c [iso-8859-1] Mon Sep 19
08:32:38 2011
@@ -549,7 +549,7 @@
if (0 == WidthDest || 0 == HeightDest || 0 == WidthSrc || 0 == HeightSrc)
{
EngSetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
+ return TRUE;
}
if (!hDCDest || (UsesSource && !hDCSrc) || (UsesMask && !hDCMask))