From 526f2d84e4f5e8aecead9f5e859c83dd6af762c2 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Sun, 3 Apr 2011 21:12:40 +0000 Subject: [PATCH 01/21] [Win32k] - Fix GetPeekMessage apitest that was broken when fixing the last two post quite message test. svn path=/trunk/; revision=51245 --- reactos/subsystems/win32/win32k/ntuser/message.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index e13b30352a3..4081267b8c3 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -1861,7 +1861,7 @@ NtUserGetMessage(PMSG pMsg, UserLeave(); - if (Ret) + if (Ret == TRUE) { _SEH2_TRY { @@ -1876,7 +1876,10 @@ NtUserGetMessage(PMSG pMsg, _SEH2_END; } - return Ret ? (WM_QUIT != pMsg->message) : FALSE; + if ((INT)Ret != -1) + Ret = Ret ? (WM_QUIT != pMsg->message) : FALSE; + + return Ret; } BOOL APIENTRY From 53af1b545ed044078ad09f1df3c122d355c9461f Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Sun, 3 Apr 2011 21:46:42 +0000 Subject: [PATCH 02/21] [KERNEL32] - Implement BasepMapModuleHandle and use it in GetModuleFileNameW. Later, it'll be used by other module and loader related functions in kernel32. - Wrap a call to RtlImageNtHeader into SEH, because winetest and for some reason FF installer call it with incorrect handle and expect it to not crash (Windows also has SEH, but inside RtlImageNtHeader). - Fix null-termination problems in GetModuleFileNameA, and incorrect calculation of characters returned in GetModuleFileNameW. - Various smaller improvements to the rewritten code (missing parenthesis, better variable names, use pretty LDR_ macros from http://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx ). - Thanks for your feedback! See issue #6079 for more details. svn path=/trunk/; revision=51246 --- reactos/dll/win32/kernel32/misc/ldr.c | 72 +++++++++++++++++++-------- reactos/include/ndk/ldrtypes.h | 7 +++ 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/reactos/dll/win32/kernel32/misc/ldr.c b/reactos/dll/win32/kernel32/misc/ldr.c index 50fdcc31049..8dd3d9994dc 100644 --- a/reactos/dll/win32/kernel32/misc/ldr.c +++ b/reactos/dll/win32/kernel32/misc/ldr.c @@ -41,8 +41,8 @@ BasepGetModuleHandleExParameterValidation(DWORD dwFlags, if (dwFlags & ~(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS) || - (dwFlags & GET_MODULE_HANDLE_EX_FLAG_PIN && - dwFlags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT) || + ((dwFlags & GET_MODULE_HANDLE_EX_FLAG_PIN) && + (dwFlags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)) || (!lpwModuleName && (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)) ) { @@ -69,6 +69,21 @@ BasepGetModuleHandleExParameterValidation(DWORD dwFlags, return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS; } +PVOID +WINAPI +BasepMapModuleHandle(HMODULE hModule, BOOLEAN AsDataFile) +{ + /* If no handle is provided - use current image base address */ + if (!hModule) return NtCurrentPeb()->ImageBaseAddress; + + /* Check if it's a normal or a datafile one */ + if (LDR_IS_DATAFILE(hModule) && !AsDataFile) + return NULL; + + /* It'a a normal DLL, just return its handle */ + return hModule; +} + /** * @name GetDllLoadPath * @@ -394,11 +409,22 @@ GetProcAddress( HMODULE hModule, LPCSTR lpProcName ) BOOL WINAPI FreeLibrary(HINSTANCE hLibModule) { NTSTATUS Status; + PIMAGE_NT_HEADERS NtHeaders; - if ((ULONG_PTR)hLibModule & 1) + if (LDR_IS_DATAFILE(hLibModule)) { - /* This is a LOAD_LIBRARY_AS_DATAFILE module */ - if (RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~1))) + // FIXME: This SEH should go inside RtlImageNtHeader instead + _SEH2_TRY + { + /* This is a LOAD_LIBRARY_AS_DATAFILE module, check if it's a valid one */ + NtHeaders = RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~1)); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + NtHeaders = NULL; + } _SEH2_END + + if (NtHeaders) { /* Unmap view */ Status = NtUnmapViewOfSection(NtCurrentProcess(), (PVOID)((ULONG_PTR)hLibModule & ~1)); @@ -440,7 +466,7 @@ FreeLibraryAndExitThread(HMODULE hLibModule, { NTSTATUS Status; - if ((ULONG_PTR)hLibModule & 1) + if (LDR_IS_DATAFILE(hLibModule)) { /* This is a LOAD_LIBRARY_AS_DATAFILE module */ if (RtlImageNtHeader((PVOID)((ULONG_PTR)hLibModule & ~1))) @@ -472,51 +498,53 @@ GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize) { - UNICODE_STRING filenameW; + UNICODE_STRING FilenameW; ANSI_STRING FilenameA; NTSTATUS Status; - DWORD Length = 0; + DWORD Length = 0, LengthToCopy; /* Allocate a unicode buffer */ - filenameW.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nSize * sizeof(WCHAR)); - if (!filenameW.Buffer) + FilenameW.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nSize * sizeof(WCHAR)); + if (!FilenameW.Buffer) { BaseSetLastNTError(STATUS_NO_MEMORY); return 0; } /* Call unicode API */ - filenameW.Length = GetModuleFileNameW(hModule, filenameW.Buffer, nSize) * sizeof(WCHAR); - filenameW.MaximumLength = filenameW.Length + sizeof(WCHAR); + FilenameW.Length = GetModuleFileNameW(hModule, FilenameW.Buffer, nSize) * sizeof(WCHAR); + FilenameW.MaximumLength = FilenameW.Length + sizeof(WCHAR); - if (filenameW.Length) + if (FilenameW.Length) { /* Convert to ansi string */ - Status = BasepUnicodeStringTo8BitString(&FilenameA, &filenameW, TRUE); + Status = BasepUnicodeStringTo8BitString(&FilenameA, &FilenameW, TRUE); if (!NT_SUCCESS(Status)) { /* Set last error, free string and retun failure */ BaseSetLastNTError(Status); - RtlFreeUnicodeString(&filenameW); + RtlFreeUnicodeString(&FilenameW); return 0; } /* Calculate size to copy */ Length = min(nSize, FilenameA.Length); - /* Remove terminating zero */ - if (Length == FilenameA.Length) - Length--; + /* Include terminating zero */ + if (nSize > Length) + LengthToCopy = Length + 1; + else + LengthToCopy = nSize; /* Now copy back to the caller amount he asked */ - RtlMoveMemory(lpFilename, FilenameA.Buffer, Length); + RtlMoveMemory(lpFilename, FilenameA.Buffer, LengthToCopy); /* Free ansi filename */ RtlFreeAnsiString(&FilenameA); } /* Free unicode filename */ - RtlFreeHeap(RtlGetProcessHeap(), 0, filenameW.Buffer); + RtlFreeHeap(RtlGetProcessHeap(), 0, FilenameW.Buffer); /* Return length copied */ return Length; @@ -537,6 +565,8 @@ GetModuleFileNameW(HINSTANCE hModule, ULONG Cookie; PPEB Peb; + hModule = BasepMapModuleHandle(hModule, FALSE); + /* Upscale nSize from chars to bytes */ nSize *= sizeof(WCHAR); @@ -587,7 +617,7 @@ GetModuleFileNameW(HINSTANCE hModule, /* Release the loader lock */ LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS, Cookie); - return Length; + return Length / sizeof(WCHAR); } HMODULE diff --git a/reactos/include/ndk/ldrtypes.h b/reactos/include/ndk/ldrtypes.h index aaf790ab6e5..4586f8325e5 100644 --- a/reactos/include/ndk/ldrtypes.h +++ b/reactos/include/ndk/ldrtypes.h @@ -79,6 +79,13 @@ Author: // #define IMAGE_SCN_TYPE_NOLOAD 0x00000002 +// +// Loader datafile/imagemapping macros +// +#define LDR_IS_DATAFILE(handle) (((ULONG_PTR)(handle)) & (ULONG_PTR)1) +#define LDR_IS_IMAGEMAPPING(handle) (((ULONG_PTR)(handle)) & (ULONG_PTR)2) +#define LDR_IS_RESOURCE(handle) (LDR_IS_IMAGEMAPPING(handle) || LDR_IS_DATAFILE(handle)) + // // Loader Data stored in the PEB // From 594dd8de49e5f05219ce28e1888ecdfb67079739 Mon Sep 17 00:00:00 2001 From: Sylvain Petreolle Date: Sun, 3 Apr 2011 22:09:07 +0000 Subject: [PATCH 03/21] [RBUILD] Use msvcrt as default crt for DLLs/OCX modules. svn path=/trunk/; revision=51247 --- reactos/tools/rbuild/module.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/tools/rbuild/module.cpp b/reactos/tools/rbuild/module.cpp index e0c9ff826df..f050640e68c 100644 --- a/reactos/tools/rbuild/module.cpp +++ b/reactos/tools/rbuild/module.cpp @@ -1226,7 +1226,7 @@ Module::GetDefaultModuleCRT () const return "static"; case Win32DLL: case Win32OCX: - return "ntdll"; + return "msvcrt"; case NativeDLL: case NativeCUI: return "ntdll"; From 7a18540a920ac8a3b7f8b50a68f6cbd085f833f5 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Mon, 4 Apr 2011 07:18:54 +0000 Subject: [PATCH 04/21] [User32|Win32k] - Working on wine win test_capture_4, pass all the tests in test_capture_4_proc but still waiting forever in MenuTrackMenu:WaitMessage! svn path=/trunk/; revision=51248 --- reactos/dll/win32/user32/windows/menu.c | 6 ++- reactos/dll/win32/user32/windows/message.c | 5 ++- .../subsystems/win32/win32k/ntuser/focus.c | 28 +++++++++---- reactos/subsystems/win32/win32k/ntuser/misc.c | 39 ++++++++++--------- 4 files changed, 48 insertions(+), 30 deletions(-) diff --git a/reactos/dll/win32/user32/windows/menu.c b/reactos/dll/win32/user32/windows/menu.c index 9b500dbd8a0..38294269bef 100644 --- a/reactos/dll/win32/user32/windows/menu.c +++ b/reactos/dll/win32/user32/windows/menu.c @@ -3207,8 +3207,10 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, fEndMenu = !fRemove; } - SetCapture(mt.OwnerWnd); - (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, mt.OwnerWnd); + /* owner may not be visible when tracking a popup, so use the menu itself */ + capture_win = (wFlags & TPM_POPUPMENU) ? MenuInfo.Wnd : mt.OwnerWnd; + (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, capture_win); // 1 + SetCapture(capture_win); // 2 FIXME("MenuTrackMenu 1\n"); while (! fEndMenu) diff --git a/reactos/dll/win32/user32/windows/message.c b/reactos/dll/win32/user32/windows/message.c index 5536d835cec..13d12147d09 100644 --- a/reactos/dll/win32/user32/windows/message.c +++ b/reactos/dll/win32/user32/windows/message.c @@ -2380,8 +2380,9 @@ GetCapture(VOID) BOOL WINAPI ReleaseCapture(VOID) { - NtUserSetCapture(NULL); - return(TRUE); + HWND hwndPrev = NtUserSetCapture(NULL); + return(hwndPrev ? TRUE : FALSE); +// return (BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_RELEASECAPTURE); } diff --git a/reactos/subsystems/win32/win32k/ntuser/focus.c b/reactos/subsystems/win32/win32k/ntuser/focus.c index 9989e880956..65750944072 100644 --- a/reactos/subsystems/win32/win32k/ntuser/focus.c +++ b/reactos/subsystems/win32/win32k/ntuser/focus.c @@ -546,6 +546,9 @@ co_UserSetCapture(HWND hWnd) pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; + if (ThreadQueue->QF_flags & QF_CAPTURELOCKED) + return NULL; + if ((Window = UserGetWindowObject(hWnd))) { if (Window->head.pti->MessageQueue != ThreadQueue) @@ -553,7 +556,7 @@ co_UserSetCapture(HWND hWnd) return NULL; } } - + hWndPrev = MsqSetStateWindow(ThreadQueue, MSQ_STATE_CAPTURE, hWnd); if (hWndPrev) @@ -563,19 +566,28 @@ co_UserSetCapture(HWND hWnd) IntNotifyWinEvent(EVENT_SYSTEM_CAPTUREEND, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); } + if (Window) + IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); + + if (hWndPrev && hWndPrev != hWnd) + { + if (ThreadQueue->MenuOwner && Window) ThreadQueue->QF_flags |= QF_CAPTURELOCKED; + + co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd); + + ThreadQueue->QF_flags &= ~QF_CAPTURELOCKED; + } + + ThreadQueue->CaptureWindow = hWnd; + + /// These are hacks! /* also remove other windows if not capturing anymore */ if (hWnd == NULL) { MsqSetStateWindow(ThreadQueue, MSQ_STATE_MENUOWNER, NULL); MsqSetStateWindow(ThreadQueue, MSQ_STATE_MOVESIZE, NULL); } - - if (Window) - IntNotifyWinEvent(EVENT_SYSTEM_CAPTURESTART, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); - - co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd); - ThreadQueue->CaptureWindow = hWnd; - + /// return hWndPrev; } diff --git a/reactos/subsystems/win32/win32k/ntuser/misc.c b/reactos/subsystems/win32/win32k/ntuser/misc.c index 3a6b0e3f9d3..a36403e49c1 100644 --- a/reactos/subsystems/win32/win32k/ntuser/misc.c +++ b/reactos/subsystems/win32/win32k/ntuser/misc.c @@ -179,7 +179,9 @@ NtUserGetGUIThreadInfo( GUITHREADINFO SafeGui; PDESKTOP Desktop; PUSER_MESSAGE_QUEUE MsgQueue; + PTHREADINFO W32Thread; PETHREAD Thread = NULL; + DECLARE_RETURN(BOOLEAN); DPRINT("Enter NtUserGetGUIThreadInfo\n"); @@ -198,7 +200,7 @@ NtUserGetGUIThreadInfo( RETURN( FALSE); } - if(idThread) + if (idThread) { Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)idThread, &Thread); if(!NT_SUCCESS(Status)) @@ -206,24 +208,17 @@ NtUserGetGUIThreadInfo( EngSetLastError(ERROR_ACCESS_DENIED); RETURN( FALSE); } - Desktop = ((PTHREADINFO)Thread->Tcb.Win32Thread)->rpdesk; + W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread; + Desktop = W32Thread->rpdesk; } else - { - /* get the foreground thread */ - PTHREADINFO W32Thread = (PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread; + { /* get the foreground thread */ + Thread = PsGetCurrentThread(); + W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread; Desktop = W32Thread->rpdesk; - if(Desktop) - { - MsgQueue = Desktop->ActiveMessageQueue; - if(MsgQueue) - { - Thread = MsgQueue->Thread; - } - } } - if(!Thread || !Desktop) + if (!Thread || !Desktop ) { if(idThread && Thread) ObDereferenceObject(Thread); @@ -231,13 +226,21 @@ NtUserGetGUIThreadInfo( RETURN( FALSE); } - MsgQueue = (PUSER_MESSAGE_QUEUE)Desktop->ActiveMessageQueue; + if ( W32Thread->MessageQueue ) + MsgQueue = W32Thread->MessageQueue; + else + { + if ( Desktop ) MsgQueue = Desktop->ActiveMessageQueue; + } + CaretInfo = MsgQueue->CaretInfo; SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0); - if(MsgQueue->MenuOwner) + + if (MsgQueue->MenuOwner) SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState; - if(MsgQueue->MoveSize) + + if (MsgQueue->MoveSize) SafeGui.flags |= GUI_INMOVESIZE; /* FIXME add flag GUI_16BITTASK */ @@ -254,7 +257,7 @@ NtUserGetGUIThreadInfo( SafeGui.rcCaret.right = SafeGui.rcCaret.left + CaretInfo->Size.cx; SafeGui.rcCaret.bottom = SafeGui.rcCaret.top + CaretInfo->Size.cy; - if(idThread) + if (idThread) ObDereferenceObject(Thread); Status = MmCopyToCaller(lpgui, &SafeGui, sizeof(GUITHREADINFO)); From 94b1cd39cdc7e3a501ff75f91bd4cbe4a99345a4 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Mon, 4 Apr 2011 07:22:41 +0000 Subject: [PATCH 05/21] - Fix build. svn path=/trunk/; revision=51249 --- reactos/dll/win32/user32/windows/menu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/reactos/dll/win32/user32/windows/menu.c b/reactos/dll/win32/user32/windows/menu.c index 38294269bef..92749931c8a 100644 --- a/reactos/dll/win32/user32/windows/menu.c +++ b/reactos/dll/win32/user32/windows/menu.c @@ -3174,6 +3174,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, BOOL fRemove; INT executedMenuId = -1; MTRACKER mt; + HWND capture_win; BOOL enterIdleSent = FALSE; mt.TrackFlags = 0; From 15474a66e9bfafa139073b02a535dba5e17a0914 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Mon, 4 Apr 2011 14:27:29 +0000 Subject: [PATCH 06/21] [SNDVOL32] - Set Control variable to null, which prevents that mixer controls being assigned to another line when the current line does not have any controls. Bug was highlighted when opening the property window. In that case sndvol32 frees the previous setting, so all mixer lines are also getting freed including their controls, which caused a double free in the case the line did not have any controls assigned. svn path=/trunk/; revision=51252 --- reactos/base/applications/sndvol32/mixer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reactos/base/applications/sndvol32/mixer.c b/reactos/base/applications/sndvol32/mixer.c index b085fe95fb3..f01496c7ed3 100644 --- a/reactos/base/applications/sndvol32/mixer.c +++ b/reactos/base/applications/sndvol32/mixer.c @@ -189,7 +189,7 @@ SndMixerQueryConnections(PSND_MIXER Mixer, MIXER_GETLINEINFOF_SOURCE); if (Result == MMSYSERR_NOERROR) { - LPMIXERCONTROL Controls; + LPMIXERCONTROL Controls = NULL; PSND_MIXER_CONNECTION Con; DPRINT("++ Source: %ws\n", LineInfo.szName); From 7fcd953546f81e00f680c0e8d5634f0549908c2c Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Mon, 4 Apr 2011 19:35:24 +0000 Subject: [PATCH 07/21] [KERNEL32] - Minor cleanup, better flag names (thanks to ProcessHacker team for the good names and values). - Return error in failure path of BasepGetModuleHandleExW. - Optimize GetModuleHandleExA so that it calls the internal routine directly, without going through GetModuleHandleExW first and thus validating parameters second time. svn path=/trunk/; revision=51253 --- reactos/dll/ntdll/ldr/ldrapi.c | 31 ++++++++--------- reactos/dll/win32/kernel32/misc/ldr.c | 50 ++++++++++++++++----------- reactos/include/ndk/ldrtypes.h | 8 +++-- 3 files changed, 49 insertions(+), 40 deletions(-) diff --git a/reactos/dll/ntdll/ldr/ldrapi.c b/reactos/dll/ntdll/ldr/ldrapi.c index 9b697ca9a0e..e08f4ca5ec8 100644 --- a/reactos/dll/ntdll/ldr/ldrapi.c +++ b/reactos/dll/ntdll/ldr/ldrapi.c @@ -15,9 +15,6 @@ /* GLOBALS *******************************************************************/ -#define LDR_LOCK_HELD 0x2 -#define LDR_LOCK_FREE 0x1 - LONG LdrpLoaderLockAcquisitonCount; /* FUNCTIONS *****************************************************************/ @@ -38,7 +35,7 @@ LdrUnlockLoaderLock(IN ULONG Flags, if (Flags & ~1) { /* Flags are invalid, check how to fail */ - if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS) { /* The caller wants us to raise status */ RtlRaiseStatus(STATUS_INVALID_PARAMETER_1); @@ -60,7 +57,7 @@ LdrUnlockLoaderLock(IN ULONG Flags, DPRINT1("LdrUnlockLoaderLock() called with an invalid cookie!\n"); /* Invalid cookie, check how to fail */ - if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS) { /* The caller wants us to raise status */ RtlRaiseStatus(STATUS_INVALID_PARAMETER_2); @@ -73,7 +70,7 @@ LdrUnlockLoaderLock(IN ULONG Flags, } /* Ready to release the lock */ - if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS) { /* Do a direct leave */ RtlLeaveCriticalSection(&LdrpLoaderLock); @@ -118,11 +115,11 @@ LdrLockLoaderLock(IN ULONG Flags, if (Cookie) *Cookie = 0; /* Validate the flags */ - if (Flags & ~(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS | + if (Flags & ~(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS | LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY)) { /* Flags are invalid, check how to fail */ - if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS) { /* The caller wants us to raise status */ RtlRaiseStatus(STATUS_INVALID_PARAMETER_1); @@ -136,7 +133,7 @@ LdrLockLoaderLock(IN ULONG Flags, if (!Cookie) { /* No cookie check how to fail */ - if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS) { /* The caller wants us to raise status */ RtlRaiseStatus(STATUS_INVALID_PARAMETER_3); @@ -150,7 +147,7 @@ LdrLockLoaderLock(IN ULONG Flags, if ((Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) && !(Result)) { /* No pointer to return the data to */ - if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS) { /* The caller wants us to raise status */ RtlRaiseStatus(STATUS_INVALID_PARAMETER_2); @@ -164,7 +161,7 @@ LdrLockLoaderLock(IN ULONG Flags, if (InInit) return STATUS_SUCCESS; /* Check what locking semantic to use */ - if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS) + if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS) { /* Check if we should enter or simply try */ if (Flags & LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY) @@ -173,13 +170,13 @@ LdrLockLoaderLock(IN ULONG Flags, if (!RtlTryEnterCriticalSection(&LdrpLoaderLock)) { /* It's locked */ - *Result = LDR_LOCK_HELD; + *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED; goto Quickie; } else { /* It worked */ - *Result = LDR_LOCK_FREE; + *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED; } } else @@ -188,7 +185,7 @@ LdrLockLoaderLock(IN ULONG Flags, RtlEnterCriticalSection(&LdrpLoaderLock); /* See if result was requested */ - if (Result) *Result = LDR_LOCK_FREE; + if (Result) *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED; } /* Increase the acquisition count */ @@ -209,13 +206,13 @@ LdrLockLoaderLock(IN ULONG Flags, if (!RtlTryEnterCriticalSection(&LdrpLoaderLock)) { /* It's locked */ - *Result = LDR_LOCK_HELD; + *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED; _SEH2_YIELD(return STATUS_SUCCESS); } else { /* It worked */ - *Result = LDR_LOCK_FREE; + *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED; } } else @@ -224,7 +221,7 @@ LdrLockLoaderLock(IN ULONG Flags, RtlEnterCriticalSection(&LdrpLoaderLock); /* See if result was requested */ - if (Result) *Result = LDR_LOCK_FREE; + if (Result) *Result = LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED; } /* Increase the acquisition count */ diff --git a/reactos/dll/win32/kernel32/misc/ldr.c b/reactos/dll/win32/kernel32/misc/ldr.c index 8dd3d9994dc..cbf00e56896 100644 --- a/reactos/dll/win32/kernel32/misc/ldr.c +++ b/reactos/dll/win32/kernel32/misc/ldr.c @@ -22,7 +22,7 @@ typedef struct tagLOADPARMS32 { extern BOOLEAN InWindows; extern WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle; -#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_FAIL 1 +#define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR 1 #define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS 2 #define BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_CONTINUE 3 @@ -47,14 +47,14 @@ BasepGetModuleHandleExParameterValidation(DWORD dwFlags, ) { BaseSetLastNTError(STATUS_INVALID_PARAMETER_1); - return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_FAIL; + return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR; } /* Check 2nd parameter */ if (!phModule) { BaseSetLastNTError(STATUS_INVALID_PARAMETER_2); - return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_FAIL; + return BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR; } /* Return what we have according to the module name */ @@ -578,7 +578,7 @@ GetModuleFileNameW(HINSTANCE hModule, Peb = NtCurrentPeb (); /* Acquire a loader lock */ - LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS, NULL, &Cookie); + LdrLockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, NULL, &Cookie); /* Traverse the module list */ ModuleListHead = &Peb->Ldr->InLoadOrderModuleList; @@ -615,7 +615,7 @@ GetModuleFileNameW(HINSTANCE hModule, } _SEH2_END /* Release the loader lock */ - LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS, Cookie); + LdrUnlockLoaderLock(LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS, Cookie); return Length / sizeof(WCHAR); } @@ -709,7 +709,8 @@ BasepGetModuleHandleExW(BOOLEAN NoLock, DWORD dwPublicFlags, LPCWSTR lpwModuleNa hModule = GetModuleHandleForUnicodeString(&ModuleNameU); if (!hModule) { - // FIXME: Status?! + /* Last error is already set, so just return failure by setting status */ + Status = STATUS_DLL_NOT_FOUND; goto quickie; } } @@ -737,6 +738,10 @@ BasepGetModuleHandleExW(BOOLEAN NoLock, DWORD dwPublicFlags, LPCWSTR lpwModuleNa hModule); } + /* Set last error in case of failure */ + if (!NT_SUCCESS(Status)) + SetLastErrorByStatus(Status); + quickie: /* Unlock loader lock if it was acquired */ if (!NoLock) @@ -745,10 +750,6 @@ quickie: ASSERT(NT_SUCCESS(Status2)); } - /* Set last error in case of failure */ - if (!NT_SUCCESS(Status)) - SetLastErrorByStatus(Status); - /* Set the module handle to the caller */ if (phModule) *phModule = hModule; @@ -827,7 +828,7 @@ GetModuleHandleExW(IN DWORD dwFlags, dwValid = BasepGetModuleHandleExParameterValidation(dwFlags, lpwModuleName, phModule); /* If result is invalid parameter - return failure */ - if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_FAIL) return FALSE; + if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR) return FALSE; /* If result is 2, there is no need to do anything - return success. */ if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS) return TRUE; @@ -855,13 +856,14 @@ GetModuleHandleExA(IN DWORD dwFlags, { PUNICODE_STRING lpModuleNameW; DWORD dwValid; - BOOL Ret; + BOOL Ret = FALSE; + NTSTATUS Status; /* Validate parameters */ dwValid = BasepGetModuleHandleExParameterValidation(dwFlags, (LPCWSTR)lpModuleName, phModule); /* If result is invalid parameter - return failure */ - if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_FAIL) return FALSE; + if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_ERROR) return FALSE; /* If result is 2, there is no need to do anything - return success. */ if (dwValid == BASEP_GET_MODULE_HANDLE_EX_PARAMETER_VALIDATION_SUCCESS) return TRUE; @@ -869,10 +871,11 @@ GetModuleHandleExA(IN DWORD dwFlags, /* Check if we don't need to convert the name */ if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS) { - /* Call the W version of the API without conversion */ - Ret = GetModuleHandleExW(dwFlags, - (LPCWSTR)lpModuleName, - phModule); + /* Call the extended version of the API without conversion */ + Status = BasepGetModuleHandleExW(FALSE, + dwFlags, + (LPCWSTR)lpModuleName, + phModule); } else { @@ -882,12 +885,17 @@ GetModuleHandleExA(IN DWORD dwFlags, /* Return FALSE if conversion failed */ if (!lpModuleNameW) return FALSE; - /* Call the W version of the API */ - Ret = GetModuleHandleExW(dwFlags, - lpModuleNameW->Buffer, - phModule); + /* Call the extended version of the API */ + Status = BasepGetModuleHandleExW(FALSE, + dwFlags, + lpModuleNameW->Buffer, + phModule); } + /* If result was successful - return true */ + if (NT_SUCCESS(Status)) + Ret = TRUE; + /* Return result */ return Ret; } diff --git a/reactos/include/ndk/ldrtypes.h b/reactos/include/ndk/ldrtypes.h index 4586f8325e5..8887a040b07 100644 --- a/reactos/include/ndk/ldrtypes.h +++ b/reactos/include/ndk/ldrtypes.h @@ -71,8 +71,12 @@ Author: // // LdrLockLoaderLock Flags // -#define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_STATUS 0x00000001 -#define LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY 0x00000002 +#define LDR_LOCK_LOADER_LOCK_FLAG_RAISE_ON_ERRORS 0x00000001 +#define LDR_LOCK_LOADER_LOCK_FLAG_TRY_ONLY 0x00000002 + +#define LDR_LOCK_LOADER_LOCK_DISPOSITION_INVALID 0 +#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_ACQUIRED 1 +#define LDR_LOCK_LOADER_LOCK_DISPOSITION_LOCK_NOT_ACQUIRED 2 // // FIXME: THIS SHOULD *NOT* BE USED! From 9990b69447eedb3e1ddce99e9d53299ccbafe249 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Mon, 4 Apr 2011 21:15:07 +0000 Subject: [PATCH 08/21] [Win32k] - Do not block calling thread when sending WM_PARENTNOTIFY messages. Fixes hang at end of user32 winetest for msg. svn path=/trunk/; revision=51254 --- reactos/subsystems/win32/win32k/ntuser/window.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index 21aecf32546..a64f48d5ba9 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -1529,10 +1529,10 @@ static void IntSendParentNotify( PWND pWindow, UINT msg ) { if (pWindow->spwndParent && pWindow->spwndParent != UserGetDesktopWindow()) { - co_IntSendMessage( pWindow->spwndParent->head.h, - WM_PARENTNOTIFY, - MAKEWPARAM( msg, pWindow->IDMenu), - (LPARAM)pWindow->head.h ); + co_IntSendMessageNoWait( pWindow->spwndParent->head.h, + WM_PARENTNOTIFY, + MAKEWPARAM( msg, pWindow->IDMenu), + (LPARAM)pWindow->head.h ); } } } From 771f834c4379ff488b4f72b6bc6ec2e753f17750 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Mon, 4 Apr 2011 21:50:24 +0000 Subject: [PATCH 09/21] [Win32k] - co_MsqDispatchOneSentMessage: After calling the windows procedure check if the message was a callback. If so place the message into the calling MessageQueue. Also check if the current MessageQueue is the calling MessageQueue in which case dont call the Windows procedure but call the callback routine. SendMessageCallback is now properly implemented. - Remove the use of MSQ_SENTNOWAIT and instead use the SenderQueue and CallBackSenderQueue members to determine if the MessageQueues need to be dereferenced. - Modify co_MsqSendMessage to accept more parameters so that it can handle Notification, Callback and Internal messages. These changes make this function more complex but removes duplicate code in messages.c and move the handling for all queued messages in one location. - co_IntSendMessageWithCallBack: If the callback is for the same Message Queue, call it vice queuing it. Insert the message into the MessageQueue before waking the thread to handle the message. Should fix bug 5580. svn path=/trunk/; revision=51255 --- .../subsystems/win32/win32k/ntuser/event.c | 10 +- reactos/subsystems/win32/win32k/ntuser/hook.c | 10 +- .../subsystems/win32/win32k/ntuser/message.c | 49 ++++-- .../subsystems/win32/win32k/ntuser/msgqueue.c | 152 +++++++++++++----- 4 files changed, 155 insertions(+), 66 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/event.c b/reactos/subsystems/win32/win32k/ntuser/event.c index 18bde4ca040..0af97a25449 100644 --- a/reactos/subsystems/win32/win32k/ntuser/event.c +++ b/reactos/subsystems/win32/win32k/ntuser/event.c @@ -115,15 +115,19 @@ IntCallLowLevelEvent( PEVENTHOOK pEH, /* FIXME should get timeout from * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */ - Status = co_MsqSendMessage( pEH->head.pti->MessageQueue, + Status = co_MsqSendMessage( ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue, + pEH->head.pti->MessageQueue, hwnd, event, 0, - (LPARAM)pEP, + (LPARAM)pEP, + FALSE, + NULL, + 0, 300, TRUE, MSQ_ISEVENT, - &uResult); + &uResult); if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(pEP, TAG_HOOK); diff --git a/reactos/subsystems/win32/win32k/ntuser/hook.c b/reactos/subsystems/win32/win32k/ntuser/hook.c index 40d847b12ae..d41e3218a9b 100644 --- a/reactos/subsystems/win32/win32k/ntuser/hook.c +++ b/reactos/subsystems/win32/win32k/ntuser/hook.c @@ -88,15 +88,19 @@ IntCallLowLevelHook( PHOOK Hook, /* FIXME should get timeout from * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */ - Status = co_MsqSendMessage( pti->MessageQueue, + Status = co_MsqSendMessage( ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue, + pti->MessageQueue, IntToPtr(Code), // hWnd Hook->HookId, // Msg wParam, - (LPARAM)pHP, + (LPARAM)pHP, + FALSE, + NULL, + 0, uTimeout, Block, MSQ_ISHOOK, - &uResult); + &uResult); if (!NT_SUCCESS(Status)) { DPRINT1("Error Hook Call SendMsg. %d Status: 0x%x\n", Hook->HookId, Status); diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index 4081267b8c3..922aa6d3197 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -1261,11 +1261,15 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, do { - Status = co_MsqSendMessage( Window->head.pti->MessageQueue, + Status = co_MsqSendMessage(((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue, + Window->head.pti->MessageQueue, hWnd, Msg, wParam, lParam, + FALSE, + NULL, + 0, uTimeout, (uFlags & SMTO_BLOCK), MSQ_NORMAL, @@ -1354,6 +1358,7 @@ co_IntSendMessageNoWait(HWND hWnd, LPARAM lParam) { ULONG_PTR Result = 0; + /* Piggyback off CallBack */ co_IntSendMessageWithCallBack(hWnd, Msg, wParam, @@ -1372,12 +1377,12 @@ co_IntSendMessageNoWait(HWND hWnd, */ LRESULT FASTCALL co_IntSendMessageWithCallBack( HWND hWnd, - UINT Msg, - WPARAM wParam, - LPARAM lParam, - SENDASYNCPROC CompletionCallback, - ULONG_PTR CompletionCallbackContext, - ULONG_PTR *uResult) + UINT Msg, + WPARAM wParam, + LPARAM lParam, + SENDASYNCPROC CompletionCallback, + ULONG_PTR CompletionCallbackContext, + ULONG_PTR *uResult) { ULONG_PTR Result; PWND Window = NULL; @@ -1437,7 +1442,7 @@ co_IntSendMessageWithCallBack( HWND hWnd, } /* If this is not a callback and it can be sent now, then send it. */ - if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL)) + if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue) { ObReferenceObject(Win32Thread->pEThread); Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc, @@ -1452,11 +1457,20 @@ co_IntSendMessageWithCallBack( HWND hWnd, *uResult = Result; } ObDereferenceObject(Win32Thread->pEThread); + + if (CompletionCallback) + { + co_IntCallSentMessageCallback(CompletionCallback, + hWnd, + Msg, + CompletionCallbackContext, + Result); + } } IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult); - if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL)) + if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue) { if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE))) { @@ -1480,18 +1494,21 @@ co_IntSendMessageWithCallBack( HWND hWnd, Message->lResult = 0; Message->QS_Flags = 0; Message->SenderQueue = NULL; // mjmartin, you are right! This is null. - Message->CallBackSenderQueue = Win32Thread->MessageQueue; - + if (CompletionCallback) + Message->CallBackSenderQueue = Win32Thread->MessageQueue; + else + Message->CallBackSenderQueue = NULL; IntReferenceMessageQueue(Window->head.pti->MessageQueue); Message->CompletionCallback = CompletionCallback; Message->CompletionCallbackContext = CompletionCallbackContext; - Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT; - Message->HasPackedLParam = (lParamBufferSize > 0); + Message->HookMessage = MSQ_NORMAL; + Message->HasPackedLParam = (lParamBufferSize > -1); Message->QS_Flags = QS_SENDMESSAGE; - MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, FALSE); - + if (CompletionCallback) + InsertTailList(&Win32Thread->MessageQueue->DispatchingMessagesHead, &Message->DispatchingListEntry); InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry); + MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, FALSE); IntDereferenceMessageQueue(Window->head.pti->MessageQueue); RETURN(TRUE); @@ -2112,7 +2129,7 @@ NtUserMessageCall( HWND hWnd, { co_IntSendMessageTimeout( HWND_BROADCAST, Msg, - wParam, + wParam, lParam, SMTO_NORMAL, 2000, diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index db8ca7c97b8..be62390ffa4 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -423,7 +423,7 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) PLIST_ENTRY Entry; LRESULT Result; PTHREADINFO pti; - + if (IsListEmpty(&MessageQueue->SentMessagesListHead)) { return(FALSE); @@ -466,6 +466,18 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) Message->Msg.wParam, Message->Msg.lParam); } + else if ((Message->CompletionCallback) + && (Message->CallBackSenderQueue == MessageQueue)) + { /* Call the callback routine */ + ASSERT(Message->QS_Flags & QS_SMRESULT); + co_IntCallSentMessageCallback(Message->CompletionCallback, + Message->Msg.hwnd, + Message->Msg.message, + Message->CompletionCallbackContext, + Message->lResult); + /* Set callback to NULL to prevent reentry */ + Message->CompletionCallback = NULL; + } else { /* Call the window procedure. */ Result = co_IntSendMessage( Message->Msg.hwnd, @@ -478,8 +490,23 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) to be cleaned up on thread termination anymore */ RemoveEntryList(&Message->ListEntry); - /* remove the message from the dispatching list if needed, so lock the sender's message queue */ - if (!(Message->HookMessage & MSQ_SENTNOWAIT)) + if (Message->CompletionCallback) + { + if (Message->CallBackSenderQueue) + { + Message->lResult = Result; + Message->QS_Flags |= QS_SMRESULT; + + /* queue it in the callers message queue */ + InsertTailList(&Message->CallBackSenderQueue->SentMessagesListHead, &Message->ListEntry); + MsqWakeQueue(Message->CallBackSenderQueue, QS_SENDMESSAGE, TRUE); + IntDereferenceMessageQueue(Message->CallBackSenderQueue); + } + return (TRUE); + } + + /* remove the message from the dispatching list if there is a SenderQueue, so lock the sender's message queue */ + if ((Message->SenderQueue) || (Message->CallBackSenderQueue)) { if (Message->DispatchingListEntry.Flink != NULL) { @@ -513,18 +540,8 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE); } - /* Call the callback if the message was sent with SendMessageCallback */ - if (Message->CompletionCallback != NULL) - { - co_IntCallSentMessageCallback(Message->CompletionCallback, - Message->Msg.hwnd, - Message->Msg.message, - Message->CompletionCallbackContext, - Result); - } - - /* Only if it is not a no wait message */ - if (!(Message->HookMessage & MSQ_SENTNOWAIT)) + /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */ + if (Message->SenderQueue) { IntDereferenceMessageQueue(Message->SenderQueue); IntDereferenceMessageQueue(MessageQueue); @@ -588,10 +605,11 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow) RemoveEntryList(&SentMessage->ListEntry); ClearMsgBitsMask(MessageQueue, SentMessage->QS_Flags); - /* remove the message from the dispatching list if neede */ - if ((!(SentMessage->HookMessage & MSQ_SENTNOWAIT)) + /* If there was a SenderQueue then remove the message from this threads dispatching list */ + if (((SentMessage->SenderQueue) || (SentMessage->CallBackSenderQueue)) && (SentMessage->DispatchingListEntry.Flink != NULL)) { + SentMessage->CallBackSenderQueue = NULL; RemoveEntryList(&SentMessage->DispatchingListEntry); } @@ -607,8 +625,8 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow) ExFreePool((PVOID)SentMessage->Msg.lParam); } - /* Only if it is not a no wait message */ - if (!(SentMessage->HookMessage & MSQ_SENTNOWAIT)) + /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */ + if (SentMessage->SenderQueue) { /* dereference our and the sender's message queue */ IntDereferenceMessageQueue(MessageQueue); @@ -628,8 +646,9 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow) } NTSTATUS FASTCALL -co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, - HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, +co_MsqSendMessage(PUSER_MESSAGE_QUEUE ThreadQueue, PUSER_MESSAGE_QUEUE MessageQueue, + HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL HasPackedLParam, + SENDASYNCPROC CompletionCallback, ULONG_PTR CompletionCallbackContext, UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult) { @@ -637,49 +656,87 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, PUSER_SENT_MESSAGE Message; KEVENT CompletionEvent; NTSTATUS WaitStatus; - PUSER_MESSAGE_QUEUE ThreadQueue; LARGE_INTEGER Timeout; PLIST_ENTRY Entry; + BOOL WaitForCompletion; LRESULT Result = 0; //// Result could be trashed. //// + /* Notification messages and some internal messages sent from the subsystem must not block current + thread and therefore pass NULL as ThreadQueue. Callbacks also do not block */ + WaitForCompletion = ((ThreadQueue) && (!CompletionCallback)); + if(!(Message = ExAllocatePoolWithTag(PagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG))) { DPRINT1("MsqSendMessage(): Not enough memory to allocate a message"); return STATUS_INSUFFICIENT_RESOURCES; } - KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE); + /* Initialize event if calling thread will wait on completion */ + if (WaitForCompletion) + KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE); pti = PsGetCurrentThreadWin32Thread(); - ThreadQueue = pti->MessageQueue; ptirec = MessageQueue->Thread->Tcb.Win32Thread; ASSERT(ThreadQueue != MessageQueue); ASSERT(ptirec->pcti); // Send must have a client side to receive it!!!! Timeout.QuadPart = (LONGLONG) uTimeout * (LONGLONG) -10000; - /* FIXME - increase reference counter of sender's message queue here */ - Message->Msg.hwnd = Wnd; Message->Msg.message = Msg; Message->Msg.wParam = wParam; Message->Msg.lParam = lParam; - Message->CompletionEvent = &CompletionEvent; - Message->Result = &Result; Message->lResult = 0; Message->QS_Flags = 0; - Message->SenderQueue = ThreadQueue; - Message->CallBackSenderQueue = NULL; - IntReferenceMessageQueue(ThreadQueue); - Message->CompletionCallback = NULL; - Message->CompletionCallbackContext = 0; - Message->HookMessage = HookMessage; - Message->HasPackedLParam = FALSE; + if (WaitForCompletion) + { + /* Normal SendMessage that will block until the Windows Procedure handles the message */ + Message->SenderQueue = ThreadQueue; + Message->CompletionEvent = &CompletionEvent; + Message->Result = &Result; + } + else + { + /* Either a SendMessageCallback, Notify Message or Internal Message from Win32k */ + Message->SenderQueue = NULL; + Message->CompletionEvent = NULL; + Message->Result = NULL; + } + + if (CompletionCallback) + { + Message->CallBackSenderQueue = ThreadQueue; + } + else + { + Message->CallBackSenderQueue = NULL; + } + + /* Reference the ThreadQueue if there was one. For normal messages + the thread is dereferenced when the messages is processed by windows procedure. + For callbacks it dereferenced once the callback message is processed and placed back + into the sending message queue */ + if (ThreadQueue != NULL) + IntReferenceMessageQueue(ThreadQueue); + + Message->CompletionCallback = CompletionCallback; + Message->CompletionCallbackContext = CompletionCallbackContext; + Message->HookMessage = HookMessage; + Message->HasPackedLParam = HasPackedLParam; + + if (HasPackedLParam) + { + ASSERT(Message->SenderQueue == NULL); + } + IntReferenceMessageQueue(MessageQueue); - /* add it to the list of pending messages */ - InsertTailList(&ThreadQueue->DispatchingMessagesHead, &Message->DispatchingListEntry); + /* Add it to the list of pending messages if waiting on completion or if message is callback. + This is done for callbacks as if the Sender terminates it will set the CallBackSenderQueue member to NULL, + informing the windows procedure handling the message to discard the callback procedure */ + if (ThreadQueue != NULL) + InsertTailList(&ThreadQueue->DispatchingMessagesHead, &Message->DispatchingListEntry); /* queue it in the destination's message queue */ InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry); @@ -687,6 +744,13 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, Message->QS_Flags = QS_SENDMESSAGE; MsqWakeQueue(MessageQueue, QS_SENDMESSAGE, TRUE); + /* If not waiting on completion, dereference the MessageQueue and return */ + if (!WaitForCompletion) + { + IntDereferenceMessageQueue(MessageQueue); + return STATUS_SUCCESS; + } + /* we can't access the Message anymore since it could have already been deleted! */ if(Block) @@ -854,7 +918,7 @@ MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode) * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless * the window has the WS_EX_NOPARENTNOTIFY style. */ -static void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt ) +void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt ) { PWND pwndDesktop = UserGetWindowObject(IntGetDesktopWindow()); @@ -1466,8 +1530,8 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n"); - /* remove the message from the dispatching list if needed */ - if ((!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT)) + /* remove the message from the dispatching list if there was a SenderQueue */ + if (((CurrentSentMessage->SenderQueue) || (CurrentSentMessage->CallBackSenderQueue)) && (CurrentSentMessage->DispatchingListEntry.Flink != NULL)) { RemoveEntryList(&CurrentSentMessage->DispatchingListEntry); @@ -1485,8 +1549,8 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) ExFreePool((PVOID)CurrentSentMessage->Msg.lParam); } - /* Only if it is not a no wait message */ - if (!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT)) + /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */ + if (CurrentSentMessage->SenderQueue) { /* dereference our and the sender's message queue */ IntDereferenceMessageQueue(MessageQueue); @@ -1525,8 +1589,8 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) ExFreePool((PVOID)CurrentSentMessage->Msg.lParam); } - /* Only if it is not a no wait message */ - if (!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT)) + /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */ + if (CurrentSentMessage->SenderQueue) { /* dereference our and the sender's message queue */ IntDereferenceMessageQueue(MessageQueue); From 862d46f96e0e49f4bcf58972b49906c03bf4a809 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Mon, 4 Apr 2011 22:08:39 +0000 Subject: [PATCH 10/21] - Revert 51255 that was committed on accident. The patch is not ready yet. svn path=/trunk/; revision=51256 --- .../subsystems/win32/win32k/ntuser/event.c | 10 +- reactos/subsystems/win32/win32k/ntuser/hook.c | 10 +- .../subsystems/win32/win32k/ntuser/message.c | 49 ++---- .../subsystems/win32/win32k/ntuser/msgqueue.c | 150 +++++------------- 4 files changed, 65 insertions(+), 154 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/event.c b/reactos/subsystems/win32/win32k/ntuser/event.c index 0af97a25449..18bde4ca040 100644 --- a/reactos/subsystems/win32/win32k/ntuser/event.c +++ b/reactos/subsystems/win32/win32k/ntuser/event.c @@ -115,19 +115,15 @@ IntCallLowLevelEvent( PEVENTHOOK pEH, /* FIXME should get timeout from * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */ - Status = co_MsqSendMessage( ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue, - pEH->head.pti->MessageQueue, + Status = co_MsqSendMessage( pEH->head.pti->MessageQueue, hwnd, event, 0, - (LPARAM)pEP, - FALSE, - NULL, - 0, + (LPARAM)pEP, 300, TRUE, MSQ_ISEVENT, - &uResult); + &uResult); if (!NT_SUCCESS(Status)) { ExFreePoolWithTag(pEP, TAG_HOOK); diff --git a/reactos/subsystems/win32/win32k/ntuser/hook.c b/reactos/subsystems/win32/win32k/ntuser/hook.c index d41e3218a9b..40d847b12ae 100644 --- a/reactos/subsystems/win32/win32k/ntuser/hook.c +++ b/reactos/subsystems/win32/win32k/ntuser/hook.c @@ -88,19 +88,15 @@ IntCallLowLevelHook( PHOOK Hook, /* FIXME should get timeout from * HKEY_CURRENT_USER\Control Panel\Desktop\LowLevelHooksTimeout */ - Status = co_MsqSendMessage( ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue, - pti->MessageQueue, + Status = co_MsqSendMessage( pti->MessageQueue, IntToPtr(Code), // hWnd Hook->HookId, // Msg wParam, - (LPARAM)pHP, - FALSE, - NULL, - 0, + (LPARAM)pHP, uTimeout, Block, MSQ_ISHOOK, - &uResult); + &uResult); if (!NT_SUCCESS(Status)) { DPRINT1("Error Hook Call SendMsg. %d Status: 0x%x\n", Hook->HookId, Status); diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index 922aa6d3197..4081267b8c3 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -1261,15 +1261,11 @@ co_IntSendMessageTimeoutSingle( HWND hWnd, do { - Status = co_MsqSendMessage(((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue, - Window->head.pti->MessageQueue, + Status = co_MsqSendMessage( Window->head.pti->MessageQueue, hWnd, Msg, wParam, lParam, - FALSE, - NULL, - 0, uTimeout, (uFlags & SMTO_BLOCK), MSQ_NORMAL, @@ -1358,7 +1354,6 @@ co_IntSendMessageNoWait(HWND hWnd, LPARAM lParam) { ULONG_PTR Result = 0; - /* Piggyback off CallBack */ co_IntSendMessageWithCallBack(hWnd, Msg, wParam, @@ -1377,12 +1372,12 @@ co_IntSendMessageNoWait(HWND hWnd, */ LRESULT FASTCALL co_IntSendMessageWithCallBack( HWND hWnd, - UINT Msg, - WPARAM wParam, - LPARAM lParam, - SENDASYNCPROC CompletionCallback, - ULONG_PTR CompletionCallbackContext, - ULONG_PTR *uResult) + UINT Msg, + WPARAM wParam, + LPARAM lParam, + SENDASYNCPROC CompletionCallback, + ULONG_PTR CompletionCallbackContext, + ULONG_PTR *uResult) { ULONG_PTR Result; PWND Window = NULL; @@ -1442,7 +1437,7 @@ co_IntSendMessageWithCallBack( HWND hWnd, } /* If this is not a callback and it can be sent now, then send it. */ - if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue) + if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL)) { ObReferenceObject(Win32Thread->pEThread); Result = (ULONG_PTR)co_IntCallWindowProc( Window->lpfnWndProc, @@ -1457,20 +1452,11 @@ co_IntSendMessageWithCallBack( HWND hWnd, *uResult = Result; } ObDereferenceObject(Win32Thread->pEThread); - - if (CompletionCallback) - { - co_IntCallSentMessageCallback(CompletionCallback, - hWnd, - Msg, - CompletionCallbackContext, - Result); - } } IntCallWndProcRet( Window, hWnd, Msg, wParam, lParam, (LRESULT *)uResult); - if (Window->head.pti->MessageQueue == Win32Thread->MessageQueue) + if ((Window->head.pti->MessageQueue == Win32Thread->MessageQueue) && (CompletionCallback == NULL)) { if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE))) { @@ -1494,21 +1480,18 @@ co_IntSendMessageWithCallBack( HWND hWnd, Message->lResult = 0; Message->QS_Flags = 0; Message->SenderQueue = NULL; // mjmartin, you are right! This is null. - if (CompletionCallback) - Message->CallBackSenderQueue = Win32Thread->MessageQueue; - else - Message->CallBackSenderQueue = NULL; + Message->CallBackSenderQueue = Win32Thread->MessageQueue; + IntReferenceMessageQueue(Window->head.pti->MessageQueue); Message->CompletionCallback = CompletionCallback; Message->CompletionCallbackContext = CompletionCallbackContext; - Message->HookMessage = MSQ_NORMAL; - Message->HasPackedLParam = (lParamBufferSize > -1); + Message->HookMessage = MSQ_NORMAL | MSQ_SENTNOWAIT; + Message->HasPackedLParam = (lParamBufferSize > 0); Message->QS_Flags = QS_SENDMESSAGE; - if (CompletionCallback) - InsertTailList(&Win32Thread->MessageQueue->DispatchingMessagesHead, &Message->DispatchingListEntry); - InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry); MsqWakeQueue(Window->head.pti->MessageQueue, QS_SENDMESSAGE, FALSE); + + InsertTailList(&Window->head.pti->MessageQueue->SentMessagesListHead, &Message->ListEntry); IntDereferenceMessageQueue(Window->head.pti->MessageQueue); RETURN(TRUE); @@ -2129,7 +2112,7 @@ NtUserMessageCall( HWND hWnd, { co_IntSendMessageTimeout( HWND_BROADCAST, Msg, - wParam, + wParam, lParam, SMTO_NORMAL, 2000, diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index be62390ffa4..db8ca7c97b8 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -423,7 +423,7 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) PLIST_ENTRY Entry; LRESULT Result; PTHREADINFO pti; - + if (IsListEmpty(&MessageQueue->SentMessagesListHead)) { return(FALSE); @@ -466,18 +466,6 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) Message->Msg.wParam, Message->Msg.lParam); } - else if ((Message->CompletionCallback) - && (Message->CallBackSenderQueue == MessageQueue)) - { /* Call the callback routine */ - ASSERT(Message->QS_Flags & QS_SMRESULT); - co_IntCallSentMessageCallback(Message->CompletionCallback, - Message->Msg.hwnd, - Message->Msg.message, - Message->CompletionCallbackContext, - Message->lResult); - /* Set callback to NULL to prevent reentry */ - Message->CompletionCallback = NULL; - } else { /* Call the window procedure. */ Result = co_IntSendMessage( Message->Msg.hwnd, @@ -490,23 +478,8 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) to be cleaned up on thread termination anymore */ RemoveEntryList(&Message->ListEntry); - if (Message->CompletionCallback) - { - if (Message->CallBackSenderQueue) - { - Message->lResult = Result; - Message->QS_Flags |= QS_SMRESULT; - - /* queue it in the callers message queue */ - InsertTailList(&Message->CallBackSenderQueue->SentMessagesListHead, &Message->ListEntry); - MsqWakeQueue(Message->CallBackSenderQueue, QS_SENDMESSAGE, TRUE); - IntDereferenceMessageQueue(Message->CallBackSenderQueue); - } - return (TRUE); - } - - /* remove the message from the dispatching list if there is a SenderQueue, so lock the sender's message queue */ - if ((Message->SenderQueue) || (Message->CallBackSenderQueue)) + /* remove the message from the dispatching list if needed, so lock the sender's message queue */ + if (!(Message->HookMessage & MSQ_SENTNOWAIT)) { if (Message->DispatchingListEntry.Flink != NULL) { @@ -540,8 +513,18 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE); } - /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */ - if (Message->SenderQueue) + /* Call the callback if the message was sent with SendMessageCallback */ + if (Message->CompletionCallback != NULL) + { + co_IntCallSentMessageCallback(Message->CompletionCallback, + Message->Msg.hwnd, + Message->Msg.message, + Message->CompletionCallbackContext, + Result); + } + + /* Only if it is not a no wait message */ + if (!(Message->HookMessage & MSQ_SENTNOWAIT)) { IntDereferenceMessageQueue(Message->SenderQueue); IntDereferenceMessageQueue(MessageQueue); @@ -605,11 +588,10 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow) RemoveEntryList(&SentMessage->ListEntry); ClearMsgBitsMask(MessageQueue, SentMessage->QS_Flags); - /* If there was a SenderQueue then remove the message from this threads dispatching list */ - if (((SentMessage->SenderQueue) || (SentMessage->CallBackSenderQueue)) + /* remove the message from the dispatching list if neede */ + if ((!(SentMessage->HookMessage & MSQ_SENTNOWAIT)) && (SentMessage->DispatchingListEntry.Flink != NULL)) { - SentMessage->CallBackSenderQueue = NULL; RemoveEntryList(&SentMessage->DispatchingListEntry); } @@ -625,8 +607,8 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow) ExFreePool((PVOID)SentMessage->Msg.lParam); } - /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */ - if (SentMessage->SenderQueue) + /* Only if it is not a no wait message */ + if (!(SentMessage->HookMessage & MSQ_SENTNOWAIT)) { /* dereference our and the sender's message queue */ IntDereferenceMessageQueue(MessageQueue); @@ -646,9 +628,8 @@ MsqRemoveWindowMessagesFromQueue(PVOID pWindow) } NTSTATUS FASTCALL -co_MsqSendMessage(PUSER_MESSAGE_QUEUE ThreadQueue, PUSER_MESSAGE_QUEUE MessageQueue, - HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, BOOL HasPackedLParam, - SENDASYNCPROC CompletionCallback, ULONG_PTR CompletionCallbackContext, +co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, + HWND Wnd, UINT Msg, WPARAM wParam, LPARAM lParam, UINT uTimeout, BOOL Block, INT HookMessage, ULONG_PTR *uResult) { @@ -656,87 +637,49 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE ThreadQueue, PUSER_MESSAGE_QUEUE MessageQu PUSER_SENT_MESSAGE Message; KEVENT CompletionEvent; NTSTATUS WaitStatus; + PUSER_MESSAGE_QUEUE ThreadQueue; LARGE_INTEGER Timeout; PLIST_ENTRY Entry; - BOOL WaitForCompletion; LRESULT Result = 0; //// Result could be trashed. //// - /* Notification messages and some internal messages sent from the subsystem must not block current - thread and therefore pass NULL as ThreadQueue. Callbacks also do not block */ - WaitForCompletion = ((ThreadQueue) && (!CompletionCallback)); - if(!(Message = ExAllocatePoolWithTag(PagedPool, sizeof(USER_SENT_MESSAGE), TAG_USRMSG))) { DPRINT1("MsqSendMessage(): Not enough memory to allocate a message"); return STATUS_INSUFFICIENT_RESOURCES; } - /* Initialize event if calling thread will wait on completion */ - if (WaitForCompletion) - KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE); + KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE); pti = PsGetCurrentThreadWin32Thread(); + ThreadQueue = pti->MessageQueue; ptirec = MessageQueue->Thread->Tcb.Win32Thread; ASSERT(ThreadQueue != MessageQueue); ASSERT(ptirec->pcti); // Send must have a client side to receive it!!!! Timeout.QuadPart = (LONGLONG) uTimeout * (LONGLONG) -10000; + /* FIXME - increase reference counter of sender's message queue here */ + Message->Msg.hwnd = Wnd; Message->Msg.message = Msg; Message->Msg.wParam = wParam; Message->Msg.lParam = lParam; + Message->CompletionEvent = &CompletionEvent; + Message->Result = &Result; Message->lResult = 0; Message->QS_Flags = 0; - - if (WaitForCompletion) - { - /* Normal SendMessage that will block until the Windows Procedure handles the message */ - Message->SenderQueue = ThreadQueue; - Message->CompletionEvent = &CompletionEvent; - Message->Result = &Result; - } - else - { - /* Either a SendMessageCallback, Notify Message or Internal Message from Win32k */ - Message->SenderQueue = NULL; - Message->CompletionEvent = NULL; - Message->Result = NULL; - } - - if (CompletionCallback) - { - Message->CallBackSenderQueue = ThreadQueue; - } - else - { - Message->CallBackSenderQueue = NULL; - } - - /* Reference the ThreadQueue if there was one. For normal messages - the thread is dereferenced when the messages is processed by windows procedure. - For callbacks it dereferenced once the callback message is processed and placed back - into the sending message queue */ - if (ThreadQueue != NULL) - IntReferenceMessageQueue(ThreadQueue); - - Message->CompletionCallback = CompletionCallback; - Message->CompletionCallbackContext = CompletionCallbackContext; + Message->SenderQueue = ThreadQueue; + Message->CallBackSenderQueue = NULL; + IntReferenceMessageQueue(ThreadQueue); + Message->CompletionCallback = NULL; + Message->CompletionCallbackContext = 0; Message->HookMessage = HookMessage; - Message->HasPackedLParam = HasPackedLParam; + Message->HasPackedLParam = FALSE; - if (HasPackedLParam) - { - ASSERT(Message->SenderQueue == NULL); - } - IntReferenceMessageQueue(MessageQueue); - /* Add it to the list of pending messages if waiting on completion or if message is callback. - This is done for callbacks as if the Sender terminates it will set the CallBackSenderQueue member to NULL, - informing the windows procedure handling the message to discard the callback procedure */ - if (ThreadQueue != NULL) - InsertTailList(&ThreadQueue->DispatchingMessagesHead, &Message->DispatchingListEntry); + /* add it to the list of pending messages */ + InsertTailList(&ThreadQueue->DispatchingMessagesHead, &Message->DispatchingListEntry); /* queue it in the destination's message queue */ InsertTailList(&MessageQueue->SentMessagesListHead, &Message->ListEntry); @@ -744,13 +687,6 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE ThreadQueue, PUSER_MESSAGE_QUEUE MessageQu Message->QS_Flags = QS_SENDMESSAGE; MsqWakeQueue(MessageQueue, QS_SENDMESSAGE, TRUE); - /* If not waiting on completion, dereference the MessageQueue and return */ - if (!WaitForCompletion) - { - IntDereferenceMessageQueue(MessageQueue); - return STATUS_SUCCESS; - } - /* we can't access the Message anymore since it could have already been deleted! */ if(Block) @@ -918,7 +854,7 @@ MsqPostQuitMessage(PUSER_MESSAGE_QUEUE MessageQueue, ULONG ExitCode) * Send a WM_PARENTNOTIFY to all ancestors of the given window, unless * the window has the WS_EX_NOPARENTNOTIFY style. */ -void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt ) +static void MsqSendParentNotify( PWND pwnd, WORD event, WORD idChild, POINT pt ) { PWND pwndDesktop = UserGetWindowObject(IntGetDesktopWindow()); @@ -1530,8 +1466,8 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) DPRINT("Notify the sender and remove a message from the queue that had not been dispatched\n"); - /* remove the message from the dispatching list if there was a SenderQueue */ - if (((CurrentSentMessage->SenderQueue) || (CurrentSentMessage->CallBackSenderQueue)) + /* remove the message from the dispatching list if needed */ + if ((!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT)) && (CurrentSentMessage->DispatchingListEntry.Flink != NULL)) { RemoveEntryList(&CurrentSentMessage->DispatchingListEntry); @@ -1549,8 +1485,8 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) ExFreePool((PVOID)CurrentSentMessage->Msg.lParam); } - /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */ - if (CurrentSentMessage->SenderQueue) + /* Only if it is not a no wait message */ + if (!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT)) { /* dereference our and the sender's message queue */ IntDereferenceMessageQueue(MessageQueue); @@ -1589,8 +1525,8 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue) ExFreePool((PVOID)CurrentSentMessage->Msg.lParam); } - /* If SenderQueue then SenderQueue and MessageQueue was referenced, dereference them here */ - if (CurrentSentMessage->SenderQueue) + /* Only if it is not a no wait message */ + if (!(CurrentSentMessage->HookMessage & MSQ_SENTNOWAIT)) { /* dereference our and the sender's message queue */ IntDereferenceMessageQueue(MessageQueue); From 35a75304b795aac3f50511e61bd4cd13e2860cd6 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Mon, 4 Apr 2011 22:08:45 +0000 Subject: [PATCH 11/21] [ADVAPI32/LSASRV] - Implement LsaLookupNames2 in advapi32.dll. - Implement LsarLookupNames3 in lsasrv.dll as a mock-up which returns a hard-coded user account (Administrator). This fixes several wine tests. svn path=/trunk/; revision=51257 --- reactos/dll/win32/advapi32/sec/lsa.c | 68 +++++++++++---- reactos/dll/win32/lsasrv/lsarpc.c | 124 ++++++++++++++++++++++++++- 2 files changed, 170 insertions(+), 22 deletions(-) diff --git a/reactos/dll/win32/advapi32/sec/lsa.c b/reactos/dll/win32/advapi32/sec/lsa.c index 246fbc5ae29..ec76774bbfd 100644 --- a/reactos/dll/win32/advapi32/sec/lsa.c +++ b/reactos/dll/win32/advapi32/sec/lsa.c @@ -430,20 +430,22 @@ LsaLookupNames(IN LSA_HANDLE PolicyHandle, OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains, OUT PLSA_TRANSLATED_SID *Sids) { - LSAPR_TRANSLATED_SIDS TranslatedSids; + LSAPR_TRANSLATED_SIDS TranslatedSids = {0, NULL}; ULONG MappedCount = 0; NTSTATUS Status; TRACE("(%p,0x%08x,%p,%p,%p)\n", PolicyHandle, Count, Names, ReferencedDomains, Sids); + if (ReferencedDomains == NULL || Sids == NULL) + return STATUS_INVALID_PARAMETER; + RpcTryExcept { *ReferencedDomains = NULL; *Sids = NULL; TranslatedSids.Entries = Count; - TranslatedSids.Sids = *Sids; Status = LsarLookupNames((LSAPR_HANDLE)PolicyHandle, Count, @@ -458,9 +460,7 @@ LsaLookupNames(IN LSA_HANDLE PolicyHandle, RpcExcept(EXCEPTION_EXECUTE_HANDLER) { if (TranslatedSids.Sids != NULL) - { MIDL_user_free(TranslatedSids.Sids); - } Status = I_RpcMapWin32Status(RpcExceptionCode()); } @@ -471,27 +471,56 @@ LsaLookupNames(IN LSA_HANDLE PolicyHandle, /* - * @unimplemented + * @implemented */ NTSTATUS WINAPI -LsaLookupNames2( - LSA_HANDLE PolicyHandle, - ULONG Flags, - ULONG Count, - PLSA_UNICODE_STRING Names, - PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains, - PLSA_TRANSLATED_SID2 *Sids) +LsaLookupNames2(IN LSA_HANDLE PolicyHandle, + IN ULONG Flags, + IN ULONG Count, + IN PLSA_UNICODE_STRING Names, + OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains, + OUT PLSA_TRANSLATED_SID2 *Sids) { - FIXME("(%p,0x%08x,0x%08x,%p,%p,%p) stub\n", PolicyHandle, Flags, - Count, Names, ReferencedDomains, Sids); - if (Names != NULL && Count > 0) + LSAPR_TRANSLATED_SIDS_EX2 TranslatedSids = {0, NULL}; + ULONG MappedCount = 0; + NTSTATUS Status; + + TRACE("(%p,0x%08x,0x%08x,%p,%p,%p) stub\n", PolicyHandle, Flags, + Count, Names, ReferencedDomains, Sids); + + if (ReferencedDomains == NULL || Sids == NULL) + return STATUS_INVALID_PARAMETER; + + RpcTryExcept { - *ReferencedDomains = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(LSA_REFERENCED_DOMAIN_LIST)); - *Sids = RtlAllocateHeap(RtlGetProcessHeap(), 0, Count * sizeof(LSA_TRANSLATED_SID2)); - return STATUS_SOME_NOT_MAPPED; + *ReferencedDomains = NULL; + *Sids = NULL; + + TranslatedSids.Entries = Count; + + Status = LsarLookupNames3((LSAPR_HANDLE)PolicyHandle, + Count, + (PRPC_UNICODE_STRING)Names, + (PLSAPR_REFERENCED_DOMAIN_LIST *)ReferencedDomains, + &TranslatedSids, + LsapLookupWksta, + &MappedCount, + Flags, + 2); + + *Sids = (PLSA_TRANSLATED_SID2)TranslatedSids.Sids; } - return STATUS_NONE_MAPPED; + RpcExcept(EXCEPTION_EXECUTE_HANDLER) + { + if (TranslatedSids.Sids != NULL) + MIDL_user_free(TranslatedSids.Sids); + + Status = I_RpcMapWin32Status(RpcExceptionCode()); + } + RpcEndExcept; + + return Status; } @@ -762,6 +791,7 @@ LsaQueryDomainInformationPolicy( return STATUS_NOT_IMPLEMENTED; } + /* * @unimplemented */ diff --git a/reactos/dll/win32/lsasrv/lsarpc.c b/reactos/dll/win32/lsasrv/lsarpc.c index 7887a7d5abf..c4c94970121 100644 --- a/reactos/dll/win32/lsasrv/lsarpc.c +++ b/reactos/dll/win32/lsasrv/lsarpc.c @@ -554,7 +554,7 @@ NTSTATUS WINAPI LsarLookupNames( for (i = 0; i < Count; i++) { OutputSids[i].Use = SidTypeWellKnownGroup; - OutputSids[i].RelativeId = DOMAIN_ALIAS_RID_ADMINS; + OutputSids[i].RelativeId = DOMAIN_USER_RID_ADMIN; //DOMAIN_ALIAS_RID_ADMINS; OutputSids[i].DomainIndex = i; } @@ -1293,8 +1293,126 @@ NTSTATUS WINAPI LsarLookupNames3( DWORD LookupOptions, DWORD ClientRevision) { - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + SID_IDENTIFIER_AUTHORITY IdentifierAuthority = {SECURITY_NT_AUTHORITY}; + static const UNICODE_STRING DomainName = RTL_CONSTANT_STRING(L"DOMAIN"); + PLSAPR_REFERENCED_DOMAIN_LIST DomainsBuffer = NULL; + PLSAPR_TRANSLATED_SID_EX2 SidsBuffer = NULL; + ULONG SidsBufferLength; + ULONG DomainSidLength; + ULONG AccountSidLength; + PSID DomainSid; + PSID AccountSid; + ULONG i; + NTSTATUS Status; + + TRACE("LsarLookupNames3(%p, %lu, %p, %p, %p, %d, %p, %lu, %lu)\n", + PolicyHandle, Count, Names, ReferencedDomains, TranslatedSids, + LookupLevel, MappedCount, LookupOptions, ClientRevision); + + if (Count == 0) + return STATUS_NONE_MAPPED; + + TranslatedSids->Entries = Count; + TranslatedSids->Sids = NULL; + *ReferencedDomains = NULL; + + SidsBufferLength = Count * sizeof(LSAPR_TRANSLATED_SID_EX2); + SidsBuffer = MIDL_user_allocate(SidsBufferLength); + if (SidsBuffer == NULL) + return STATUS_INSUFFICIENT_RESOURCES; + + for (i = 0; i < Count; i++) + { + SidsBuffer[i].Use = SidTypeUser; + SidsBuffer[i].Sid = NULL; + SidsBuffer[i].DomainIndex = -1; + SidsBuffer[i].Flags = 0; + } + + DomainsBuffer = MIDL_user_allocate(sizeof(LSAPR_REFERENCED_DOMAIN_LIST)); + if (DomainsBuffer == NULL) + { + MIDL_user_free(SidsBuffer); + return STATUS_INSUFFICIENT_RESOURCES; + } + + DomainsBuffer->Entries = Count; + DomainsBuffer->Domains = MIDL_user_allocate(Count * sizeof(LSA_TRUST_INFORMATION)); + if (DomainsBuffer->Domains == NULL) + { + MIDL_user_free(DomainsBuffer); + MIDL_user_free(SidsBuffer); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Status = RtlAllocateAndInitializeSid(&IdentifierAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &DomainSid); + if (!NT_SUCCESS(Status)) + { + MIDL_user_free(DomainsBuffer->Domains); + MIDL_user_free(DomainsBuffer); + MIDL_user_free(SidsBuffer); + return Status; + } + + DomainSidLength = RtlLengthSid(DomainSid); + + for (i = 0; i < Count; i++) + { + DomainsBuffer->Domains[i].Sid = MIDL_user_allocate(DomainSidLength); + RtlCopyMemory(DomainsBuffer->Domains[i].Sid, + DomainSid, + DomainSidLength); + + DomainsBuffer->Domains[i].Name.Buffer = MIDL_user_allocate(DomainName.MaximumLength); + DomainsBuffer->Domains[i].Name.Length = DomainName.Length; + DomainsBuffer->Domains[i].Name.MaximumLength = DomainName.MaximumLength; + RtlCopyMemory(DomainsBuffer->Domains[i].Name.Buffer, + DomainName.Buffer, + DomainName.MaximumLength); + } + + Status = RtlAllocateAndInitializeSid(&IdentifierAuthority, + 3, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + DOMAIN_USER_RID_ADMIN, + 0, 0, 0, 0, 0, + &AccountSid); + if (!NT_SUCCESS(Status)) + { + MIDL_user_free(DomainsBuffer->Domains); + MIDL_user_free(DomainsBuffer); + MIDL_user_free(SidsBuffer); + return Status; + } + + AccountSidLength = RtlLengthSid(AccountSid); + + for (i = 0; i < Count; i++) + { + SidsBuffer[i].Use = SidTypeWellKnownGroup; + SidsBuffer[i].Sid = MIDL_user_allocate(AccountSidLength); + + RtlCopyMemory(SidsBuffer[i].Sid, + AccountSid, + AccountSidLength); + + SidsBuffer[i].DomainIndex = i; + SidsBuffer[i].Flags = 0; + } + + *ReferencedDomains = DomainsBuffer; + *MappedCount = Count; + + TranslatedSids->Entries = Count; + TranslatedSids->Sids = SidsBuffer; + + return STATUS_SUCCESS; } From 6ecaf80fcfe4ade4db2f2f2200d6f4ff6af5e0c9 Mon Sep 17 00:00:00 2001 From: Michael Martin Date: Tue, 5 Apr 2011 11:42:38 +0000 Subject: [PATCH 12/21] [NTOS/MM] - Update PoolTag used with ExFreePooWithTag to match changes made in 46987 by richard. svn path=/trunk/; revision=51258 --- reactos/ntoskrnl/mm/ARM3/sysldr.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/reactos/ntoskrnl/mm/ARM3/sysldr.c b/reactos/ntoskrnl/mm/ARM3/sysldr.c index 443a33d5e63..2ca28005d9c 100644 --- a/reactos/ntoskrnl/mm/ARM3/sysldr.c +++ b/reactos/ntoskrnl/mm/ARM3/sysldr.c @@ -1059,7 +1059,7 @@ MiResolveImageReferences(IN PVOID ImageBase, { /* It's not, it's importing stuff it shouldn't be! */ MiDereferenceImports(LoadedImports); - if (LoadedImports) ExFreePool(LoadedImports); + if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM'); return STATUS_PROCEDURE_NOT_FOUND; } @@ -1073,7 +1073,7 @@ MiResolveImageReferences(IN PVOID ImageBase, { /* This is not kernel code */ MiDereferenceImports(LoadedImports); - if (LoadedImports) ExFreePool(LoadedImports); + if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM'); return STATUS_PROCEDURE_NOT_FOUND; } @@ -1098,7 +1098,7 @@ MiResolveImageReferences(IN PVOID ImageBase, { /* Failed */ MiDereferenceImports(LoadedImports); - if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); + if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM'); return Status; } @@ -1219,7 +1219,7 @@ CheckDllState: /* Cleanup and return */ RtlFreeUnicodeString(&NameString); MiDereferenceImports(LoadedImports); - if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); + if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM'); return Status; } @@ -1252,7 +1252,7 @@ CheckDllState: { /* Cleanup and return */ MiDereferenceImports(LoadedImports); - if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); + if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM'); DPRINT1("Warning: Driver failed to load, %S not found\n", *MissingDriver); return STATUS_DRIVER_ENTRYPOINT_NOT_FOUND; } @@ -1282,7 +1282,7 @@ CheckDllState: { /* Cleanup and return */ MiDereferenceImports(LoadedImports); - if (LoadedImports) ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); + if (LoadedImports) ExFreePoolWithTag(LoadedImports, 'TDmM'); return Status; } @@ -1315,13 +1315,13 @@ CheckDllState: if (!ImportCount) { /* Free the list and set it to no imports */ - ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); + ExFreePoolWithTag(LoadedImports, 'TDmM'); LoadedImports = MM_SYSLDR_NO_IMPORTS; } else if (ImportCount == 1) { /* Just one entry, we can free the table and only use our entry */ - ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); + ExFreePoolWithTag(LoadedImports, 'TDmM'); LoadedImports = (PLOAD_IMPORTS)ImportEntry; } else if (ImportCount != LoadedImports->Count) @@ -1349,7 +1349,7 @@ CheckDllState: } /* Free the old copy */ - ExFreePoolWithTag(LoadedImports, TAG_LDR_WSTR); + ExFreePoolWithTag(LoadedImports, 'TDmM'); LoadedImports = NewImports; } } @@ -3004,7 +3004,7 @@ Quickie: /* if (NamePrefix) ExFreePool(PrefixName.Buffer); */ /* Free the name buffer and return status */ - ExFreePoolWithTag(Buffer, TAG_LDR_WSTR); + ExFreePoolWithTag(Buffer, 'nLmM'); return Status; } From be54395eb8f2a4eb4ff326cb8a4c7c1e6119370d Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Tue, 5 Apr 2011 21:14:18 +0000 Subject: [PATCH 13/21] [PSDK] Add GetAdaptersAddresses declaration Add forgotten GetComputerNameEx macro svn path=/trunk/; revision=51259 --- reactos/include/psdk/iphlpapi.h | 3 +++ reactos/include/psdk/winbase.h | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/reactos/include/psdk/iphlpapi.h b/reactos/include/psdk/iphlpapi.h index 56c32fdc087..a799280d265 100644 --- a/reactos/include/psdk/iphlpapi.h +++ b/reactos/include/psdk/iphlpapi.h @@ -19,6 +19,9 @@ DWORD WINAPI DeleteProxyArpEntry(DWORD,DWORD,DWORD); DWORD WINAPI EnableRouter(HANDLE*,OVERLAPPED*); DWORD WINAPI FlushIpNetTable(DWORD); DWORD WINAPI GetAdapterIndex(LPWSTR,PULONG); +#ifdef _WINSOCK2API_ +DWORD WINAPI GetAdaptersAddresses(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG); +#endif DWORD WINAPI GetAdaptersInfo(PIP_ADAPTER_INFO,PULONG); DWORD WINAPI GetBestInterface(IPAddr,PDWORD); DWORD WINAPI GetBestRoute(DWORD,DWORD,PMIB_IPFORWARDROW); diff --git a/reactos/include/psdk/winbase.h b/reactos/include/psdk/winbase.h index ee06339189e..6cdb089423c 100644 --- a/reactos/include/psdk/winbase.h +++ b/reactos/include/psdk/winbase.h @@ -2416,6 +2416,9 @@ typedef PCACTCTXW PCACTCTX; #define GetCommandLine GetCommandLineW #define GetCompressedFileSize GetCompressedFileSizeW #define GetComputerName GetComputerNameW +#if (_WIN32_WINNT >= 0x0500) +#define GetComputerNameEx GetComputerNameExW +#endif #define GetCurrentDirectory GetCurrentDirectoryW #define GetDefaultCommConfig GetDefaultCommConfigW #define GetDiskFreeSpace GetDiskFreeSpaceW @@ -2619,6 +2622,9 @@ typedef ENUMRESTYPEPROCA ENUMRESTYPEPROC; #define GetBinaryType GetBinaryTypeA #define GetCommandLine GetCommandLineA #define GetComputerName GetComputerNameA +#if (_WIN32_WINNT >= 0x0500) +#define GetComputerNameEx GetComputerNameExA +#endif #define GetCompressedFileSize GetCompressedFileSizeA #define GetCurrentDirectory GetCurrentDirectoryA #define GetDefaultCommConfig GetDefaultCommConfigA From 4ce4beb1cbfbb8555a87479531c69ac8807ea5c2 Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Tue, 5 Apr 2011 21:20:42 +0000 Subject: [PATCH 14/21] [SYSTEMINFO] Add Italian translation (patch by Vincenzo Cotugno ) Decrease buffer size Don't print NULL domain/workgroup Add network adapters detection svn path=/trunk/; revision=51260 --- .../sysutils/systeminfo/lang/de-DE.rc | 6 + .../sysutils/systeminfo/lang/en-US.rc | 6 + .../sysutils/systeminfo/lang/es-ES.rc | 6 + .../sysutils/systeminfo/lang/fr-FR.rc | 6 + .../sysutils/systeminfo/lang/it-IT.rc | 72 ++++++ .../sysutils/systeminfo/lang/no-NO.rc | 6 + .../sysutils/systeminfo/lang/pl-PL.rc | 6 + .../sysutils/systeminfo/lang/sk-SK.rc | 6 + .../sysutils/systeminfo/lang/uk-UA.rc | 6 + .../sysutils/systeminfo/resource.h | 72 +++--- .../applications/sysutils/systeminfo/rsrc.rc | 4 +- .../sysutils/systeminfo/systeminfo.c | 221 ++++++++++++------ .../sysutils/systeminfo/systeminfo.rbuild | 2 + 13 files changed, 318 insertions(+), 101 deletions(-) create mode 100644 rosapps/applications/sysutils/systeminfo/lang/it-IT.rc diff --git a/rosapps/applications/sysutils/systeminfo/lang/de-DE.rc b/rosapps/applications/sysutils/systeminfo/lang/de-DE.rc index f7a0e476016..e6fdc4a6419 100644 --- a/rosapps/applications/sysutils/systeminfo/lang/de-DE.rc +++ b/rosapps/applications/sysutils/systeminfo/lang/de-DE.rc @@ -64,5 +64,11 @@ IDS_PAGEFILE_LOC, "Auslagerungsdateipfad(e): %s" IDS_DOMAIN, "Domain" IDS_NETWORK_CARDS, "Netzwerkkarte(n)" IDS_NETWORK_CARDS_FORMAT, "%u Installiert." +IDS_CONNECTION_NAME, "Connection Name" +IDS_STATUS, "Status" +IDS_MEDIA_DISCONNECTED, "Media disconnected" +IDS_DHCP_ENABLED, "DHCP Enabled" +IDS_NO, "No" +IDS_IP_ADDRESSES, "IP address(es)" END diff --git a/rosapps/applications/sysutils/systeminfo/lang/en-US.rc b/rosapps/applications/sysutils/systeminfo/lang/en-US.rc index 05bdb9dac96..2b9bed9ad6b 100644 --- a/rosapps/applications/sysutils/systeminfo/lang/en-US.rc +++ b/rosapps/applications/sysutils/systeminfo/lang/en-US.rc @@ -62,5 +62,11 @@ IDS_PAGEFILE_LOC, "Page File Location(s)" IDS_DOMAIN, "Domain" IDS_NETWORK_CARDS, "Network Card(s)" IDS_NETWORK_CARDS_FORMAT, "%u Installed." +IDS_CONNECTION_NAME, "Connection Name" +IDS_STATUS, "Status" +IDS_MEDIA_DISCONNECTED, "Media disconnected" +IDS_DHCP_ENABLED, "DHCP Enabled" +IDS_NO, "No" +IDS_IP_ADDRESSES, "IP address(es)" END diff --git a/rosapps/applications/sysutils/systeminfo/lang/es-ES.rc b/rosapps/applications/sysutils/systeminfo/lang/es-ES.rc index b57be05cf12..644e5da0ef8 100644 --- a/rosapps/applications/sysutils/systeminfo/lang/es-ES.rc +++ b/rosapps/applications/sysutils/systeminfo/lang/es-ES.rc @@ -67,5 +67,11 @@ IDS_PAGEFILE_LOC, "Ruta(s) Archivo Paginaci IDS_DOMAIN, "Dominio" IDS_NETWORK_CARDS, "Tarjeta(s) de Red" IDS_NETWORK_CARDS_FORMAT, "%u No Instalada." +IDS_CONNECTION_NAME, "Connection Name" +IDS_STATUS, "Status" +IDS_MEDIA_DISCONNECTED, "Media disconnected" +IDS_DHCP_ENABLED, "DHCP Enabled" +IDS_NO, "No" +IDS_IP_ADDRESSES, "IP address(es)" END diff --git a/rosapps/applications/sysutils/systeminfo/lang/fr-FR.rc b/rosapps/applications/sysutils/systeminfo/lang/fr-FR.rc index 88eb9c06d4c..1565ccb097d 100644 --- a/rosapps/applications/sysutils/systeminfo/lang/fr-FR.rc +++ b/rosapps/applications/sysutils/systeminfo/lang/fr-FR.rc @@ -62,5 +62,11 @@ IDS_PAGEFILE_LOC, "Emplacement(s) des fichiers d' IDS_DOMAIN, "Domaine" IDS_NETWORK_CARDS, "Carte(s) réseau" IDS_NETWORK_CARDS_FORMAT, "%u installée(s)." +IDS_CONNECTION_NAME, "Connection Name" +IDS_STATUS, "Status" +IDS_MEDIA_DISCONNECTED, "Media disconnected" +IDS_DHCP_ENABLED, "DHCP Enabled" +IDS_NO, "No" +IDS_IP_ADDRESSES, "IP address(es)" END diff --git a/rosapps/applications/sysutils/systeminfo/lang/it-IT.rc b/rosapps/applications/sysutils/systeminfo/lang/it-IT.rc new file mode 100644 index 00000000000..e02c2363925 --- /dev/null +++ b/rosapps/applications/sysutils/systeminfo/lang/it-IT.rc @@ -0,0 +1,72 @@ +LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL + +STRINGTABLE DISCARDABLE +BEGIN + +IDS_USAGE, "SYSTEMINFO [/S sistema [/U nomeutente [/P [password]]]] [/FO formato] [/NH]\n\n\ +Descrizione:\n\ + Questà utilità permettere ad un amministratore di\n\ + visualizzare alcune informazioni basilari sulla configurazione del pc.\n\n\ +Lista Parametri:\n\ + /S sistema Specifica il sistema remoto a cui connettersi.\n\n\ + /U [dominio\\]utente Specifica il contesto utente in cui eseguire\n\ + il comando.\n\n\ + /P [password] Specifica la password per il dato\n\ + contesto utente. Se omesso, viene richiesto.\n\n\ + /FO formato Specifica il formato con cui l'output\n\ + viene mostrato.\n\ + Valori Validi: ""TABLE"", ""LIST"", ""CSV"".\n\n\ + /NH Specifica che la ""Etichetta Colonna"" non\n\ + deve essere mostrata nell'output.\n\ + Valido solo per i formati ""TABLE"" e ""CSV"" .\n\n\ + /? Mostra questo aiuto.\n\n\ +Esempi:\n\ + SYSTEMINFO\n\ + SYSTEMINFO /?\n\ + SYSTEMINFO /S sistema\n\ + SYSTEMINFO /S sistema /U utente\n\ + SYSTEMINFO /S sistema /U dominio\\utente /P password /FO TABLE\n\ + SYSTEMINFO /S sistema /FO LIST\n\ + SYSTEMINFO /S sistema /FO CSV /NH\n" + +IDS_HOST_NAME, "Nome Host" +IDS_OS_NAME, "Nome SO" +IDS_OS_VERSION, "Versione SO" +IDS_BUILD, "Build" +IDS_OS_BUILD_TYPE, "Tipo SO" +IDS_REG_OWNER, "Proprietario Registrato" +IDS_REG_ORG, "Organizzazione Registrata" +IDS_PRODUCT_ID, "ID Prodotto" +IDS_INST_DATE, "Data Installazione" +IDS_UP_TIME, "Tempo di Avvio Sistema" +IDS_UP_TIME_FORMAT "%u Giorno, %u Ore, %u Minuti, %u Secondi" +IDS_SYS_MANUFACTURER, "Produttore PC" +IDS_SYS_MODEL, "Modello Sistema" +IDS_SYS_TYPE, "Tipo Sistema" +IDS_PROCESSORS, "Processore" +IDS_PROCESSORS_FORMAT, "%u Processore(i) Installato." +IDS_BIOS_DATE, "Data BIOS" +IDS_BIOS_VERSION, "Versione BIOS" +IDS_ROS_DIR, "Directory ReactOS" +IDS_SYS_DIR, "Directory di Sistema" +IDS_BOOT_DEV, "Periferica di Avvio" +IDS_SYS_LOCALE, "Impostazioni Locali Sistema" +IDS_INPUT_LOCALE, "Impostazioni Locali Input" +IDS_TIME_ZONE, "Fuso Orario" +IDS_TOTAL_PHYS_MEM, "Memoria Fisica Totale" +IDS_AVAIL_PHISICAL_MEM, "Memoria Fisica Disponibile" +IDS_VIRT_MEM_MAX, "Memoria Virtuale: Dimensione Massima" +IDS_VIRT_MEM_AVAIL, "Memoria Virtuale: Disponibile" +IDS_VIRT_MEM_INUSE, "Memoria Virtuale: In Uso" +IDS_PAGEFILE_LOC, "Posizioni File di Paging" +IDS_DOMAIN, "Dominio" +IDS_NETWORK_CARDS, "Schede di Rete" +IDS_NETWORK_CARDS_FORMAT, "%u Installate." +IDS_CONNECTION_NAME, "Nome Connessione" +IDS_STATUS, "Stato" +IDS_MEDIA_DISCONNECTED, "Disconnesso" +IDS_DHCP_ENABLED, "DHCP Abilitato" +IDS_NO, "No" +IDS_IP_ADDRESSES, "Indirizzo(i) IP" + +END diff --git a/rosapps/applications/sysutils/systeminfo/lang/no-NO.rc b/rosapps/applications/sysutils/systeminfo/lang/no-NO.rc index af655d38478..b117059d4d9 100644 --- a/rosapps/applications/sysutils/systeminfo/lang/no-NO.rc +++ b/rosapps/applications/sysutils/systeminfo/lang/no-NO.rc @@ -62,5 +62,11 @@ IDS_PAGEFILE_LOC, "Sidevekslingsfil lokalsjon(er)" IDS_DOMAIN, "Domene" IDS_NETWORK_CARDS, "Nettverkskort(er)" IDS_NETWORK_CARDS_FORMAT, "%u installert." +IDS_CONNECTION_NAME, "Connection Name" +IDS_STATUS, "Status" +IDS_MEDIA_DISCONNECTED, "Media disconnected" +IDS_DHCP_ENABLED, "DHCP Enabled" +IDS_NO, "No" +IDS_IP_ADDRESSES, "IP address(es)" END diff --git a/rosapps/applications/sysutils/systeminfo/lang/pl-PL.rc b/rosapps/applications/sysutils/systeminfo/lang/pl-PL.rc index c18a60935c2..a1706643060 100644 --- a/rosapps/applications/sysutils/systeminfo/lang/pl-PL.rc +++ b/rosapps/applications/sysutils/systeminfo/lang/pl-PL.rc @@ -69,5 +69,11 @@ IDS_PAGEFILE_LOC, "Lokalizacja pliku wymiany" IDS_DOMAIN, "Domena" IDS_NETWORK_CARDS, "Karty sieciowe" IDS_NETWORK_CARDS_FORMAT, "Zainstalowane karty NIC: %u." +IDS_CONNECTION_NAME, "Nazwa po³¹czenia" +IDS_STATUS, "Stan" +IDS_MEDIA_DISCONNECTED, "Noœnik od³¹czony" +IDS_DHCP_ENABLED, "DHCP w³¹czone" +IDS_NO, "Nie" +IDS_IP_ADDRESSES, "Adresy IP" END diff --git a/rosapps/applications/sysutils/systeminfo/lang/sk-SK.rc b/rosapps/applications/sysutils/systeminfo/lang/sk-SK.rc index 7da44551e49..4d4e89c7a7c 100644 --- a/rosapps/applications/sysutils/systeminfo/lang/sk-SK.rc +++ b/rosapps/applications/sysutils/systeminfo/lang/sk-SK.rc @@ -66,5 +66,11 @@ IDS_PAGEFILE_LOC, "Umiestnenie(a) str IDS_DOMAIN, "Dom‚na" IDS_NETWORK_CARDS, "Sieœov  karta(y)" IDS_NETWORK_CARDS_FORMAT, "%u nainçtalovan." +IDS_CONNECTION_NAME, "Connection Name" +IDS_STATUS, "Status" +IDS_MEDIA_DISCONNECTED, "Media disconnected" +IDS_DHCP_ENABLED, "DHCP Enabled" +IDS_NO, "No" +IDS_IP_ADDRESSES, "IP address(es)" END diff --git a/rosapps/applications/sysutils/systeminfo/lang/uk-UA.rc b/rosapps/applications/sysutils/systeminfo/lang/uk-UA.rc index 08e575c3fb8..6d2645ba1eb 100644 --- a/rosapps/applications/sysutils/systeminfo/lang/uk-UA.rc +++ b/rosapps/applications/sysutils/systeminfo/lang/uk-UA.rc @@ -70,5 +70,11 @@ IDS_PAGEFILE_LOC, " IDS_DOMAIN, "Äîìåí" IDS_NETWORK_CARDS, "Ìåðåæíà êàðòà(è)" IDS_NETWORK_CARDS_FORMAT, "%u Installed." +IDS_CONNECTION_NAME, "Connection Name" +IDS_STATUS, "Status" +IDS_MEDIA_DISCONNECTED, "Media disconnected" +IDS_DHCP_ENABLED, "DHCP Enabled" +IDS_NO, "No" +IDS_IP_ADDRESSES, "IP address(es)" END diff --git a/rosapps/applications/sysutils/systeminfo/resource.h b/rosapps/applications/sysutils/systeminfo/resource.h index c69f6f5a20d..2a8f5564c03 100644 --- a/rosapps/applications/sysutils/systeminfo/resource.h +++ b/rosapps/applications/sysutils/systeminfo/resource.h @@ -1,35 +1,41 @@ -#define IDS_USAGE 1000 +#define IDS_USAGE 1000 -#define IDS_HOST_NAME 100 -#define IDS_OS_NAME 101 -#define IDS_OS_VERSION 102 -#define IDS_BUILD 103 -#define IDS_OS_BUILD_TYPE 104 -#define IDS_REG_OWNER 105 -#define IDS_REG_ORG 106 -#define IDS_PRODUCT_ID 107 -#define IDS_INST_DATE 108 -#define IDS_UP_TIME 109 -#define IDS_UP_TIME_FORMAT 110 -#define IDS_SYS_MANUFACTURER 111 -#define IDS_SYS_MODEL 112 -#define IDS_SYS_TYPE 113 -#define IDS_PROCESSORS 114 -#define IDS_PROCESSORS_FORMAT 115 -#define IDS_BIOS_DATE 116 -#define IDS_BIOS_VERSION 117 -#define IDS_ROS_DIR 118 -#define IDS_SYS_DIR 119 -#define IDS_BOOT_DEV 120 -#define IDS_SYS_LOCALE 121 -#define IDS_INPUT_LOCALE 122 -#define IDS_TOTAL_PHYS_MEM 123 -#define IDS_AVAIL_PHISICAL_MEM 124 -#define IDS_VIRT_MEM_MAX 125 -#define IDS_VIRT_MEM_AVAIL 126 -#define IDS_VIRT_MEM_INUSE 127 -#define IDS_PAGEFILE_LOC 128 -#define IDS_TIME_ZONE 129 -#define IDS_DOMAIN 130 -#define IDS_NETWORK_CARDS 131 +#define IDS_HOST_NAME 100 +#define IDS_OS_NAME 101 +#define IDS_OS_VERSION 102 +#define IDS_BUILD 103 +#define IDS_OS_BUILD_TYPE 104 +#define IDS_REG_OWNER 105 +#define IDS_REG_ORG 106 +#define IDS_PRODUCT_ID 107 +#define IDS_INST_DATE 108 +#define IDS_UP_TIME 109 +#define IDS_UP_TIME_FORMAT 110 +#define IDS_SYS_MANUFACTURER 111 +#define IDS_SYS_MODEL 112 +#define IDS_SYS_TYPE 113 +#define IDS_PROCESSORS 114 +#define IDS_PROCESSORS_FORMAT 115 +#define IDS_BIOS_DATE 116 +#define IDS_BIOS_VERSION 117 +#define IDS_ROS_DIR 118 +#define IDS_SYS_DIR 119 +#define IDS_BOOT_DEV 120 +#define IDS_SYS_LOCALE 121 +#define IDS_INPUT_LOCALE 122 +#define IDS_TOTAL_PHYS_MEM 123 +#define IDS_AVAIL_PHISICAL_MEM 124 +#define IDS_VIRT_MEM_MAX 125 +#define IDS_VIRT_MEM_AVAIL 126 +#define IDS_VIRT_MEM_INUSE 127 +#define IDS_PAGEFILE_LOC 128 +#define IDS_TIME_ZONE 129 +#define IDS_DOMAIN 130 +#define IDS_NETWORK_CARDS 131 #define IDS_NETWORK_CARDS_FORMAT 132 +#define IDS_CONNECTION_NAME 133 +#define IDS_STATUS 134 +#define IDS_MEDIA_DISCONNECTED 135 +#define IDS_DHCP_ENABLED 136 +#define IDS_NO 137 +#define IDS_IP_ADDRESSES 138 diff --git a/rosapps/applications/sysutils/systeminfo/rsrc.rc b/rosapps/applications/sysutils/systeminfo/rsrc.rc index d12216077e7..42c65fabd20 100644 --- a/rosapps/applications/sysutils/systeminfo/rsrc.rc +++ b/rosapps/applications/sysutils/systeminfo/rsrc.rc @@ -5,7 +5,9 @@ #include "lang/en-US.rc" #include "lang/es-ES.rc" #include "lang/fr-FR.rc" +#include "lang/it-IT.rc" +#include "lang/no-NO.rc" #include "lang/pl-PL.rc" #include "lang/sk-SK.rc" #include "lang/uk-UA.rc" -#include "lang/no-NO.rc" + diff --git a/rosapps/applications/sysutils/systeminfo/systeminfo.c b/rosapps/applications/sysutils/systeminfo/systeminfo.c index d9ebe2a6e62..12818ecc5ee 100644 --- a/rosapps/applications/sysutils/systeminfo/systeminfo.c +++ b/rosapps/applications/sysutils/systeminfo/systeminfo.c @@ -25,31 +25,22 @@ #include #include #include +#include +#include #include "resource.h" -#define BUFFER_SIZE 32767 +#define BUFFER_SIZE 1024 -/* Load from resource and convert to OEM */ -static -BOOL -GetOemStrings(UINT rcID, LPWSTR OutMsg) -{ - if (LoadStringW(GetModuleHandle(NULL), rcID, OutMsg, BUFFER_SIZE)) - return TRUE; - - return FALSE; -} - -/* Load data from registry */ +/* Load string from registry */ static unsigned RegGetSZ(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPWSTR lpBuf, DWORD cchBuf) { - DWORD dwBytes = cchBuf*sizeof(WCHAR), dwType; + DWORD dwBytes = cchBuf*sizeof(WCHAR), dwType = 0; unsigned cChars; - /* If SubKy is specified open it */ + /* If SubKey is specified open it */ if (lpSubKey && RegOpenKeyExW(hKey, lpSubKey, 0, @@ -60,6 +51,7 @@ RegGetSZ(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPWSTR lpBuf, DWORD c return 0; } + /* Query registry value and check its type */ if (RegQueryValueExW(hKey, lpValueName, NULL, @@ -70,6 +62,11 @@ RegGetSZ(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPWSTR lpBuf, DWORD c wprintf(L"Warning! Cannot query %s. Last error: %lu, type: %lu.\n", lpValueName, GetLastError(), dwType); dwBytes = 0; } + else + { + wcscpy(lpBuf, L"N/A"); + dwBytes = 6; + } /* Close key if we opened it */ if (lpSubKey) @@ -87,6 +84,7 @@ RegGetSZ(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPWSTR lpBuf, DWORD c return cChars; } +/* Load DWORD from registry */ static BOOL RegGetDWORD(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPDWORD lpData) @@ -94,7 +92,7 @@ RegGetDWORD(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPDWORD lpData) DWORD dwBytes = sizeof(*lpData), dwType; BOOL bRet = TRUE; - /* If SubKy is specified open it */ + /* If SubKey is specified open it */ if (lpSubKey && RegOpenKeyExW(hKey, lpSubKey, 0, @@ -105,6 +103,7 @@ RegGetDWORD(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPDWORD lpData) return FALSE; } + /* Query registry value and check its type */ if (RegQueryValueExW(hKey, lpValueName, NULL, @@ -124,6 +123,7 @@ RegGetDWORD(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPDWORD lpData) return bRet; } +/* Format bytes */ static VOID FormatBytes(LPWSTR lpBuf, unsigned cBytes) @@ -147,6 +147,7 @@ FormatBytes(LPWSTR lpBuf, unsigned cBytes) wcscpy(lpBuf + i, L" MB"); } +/* Format date and time */ static VOID FormatDateTime(time_t Time, LPWSTR lpBuf) @@ -181,30 +182,35 @@ static VOID Usage(VOID) { - WCHAR Buf[BUFFER_SIZE]; - - if(GetOemStrings(IDS_USAGE, Buf)) + WCHAR Buf[4096]; + if (LoadStringW(GetModuleHandle(NULL), IDS_USAGE, Buf, 4096)) wprintf(L"%s", Buf); } static VOID -PrintRow(UINT nTitleID, unsigned cxOffset, LPWSTR lpFormat, ...) +PrintRow(UINT nTitleID, BOOL bIndent, LPWSTR lpFormat, ...) { WCHAR Buf[BUFFER_SIZE]; va_list Args; unsigned c; - + if (nTitleID) { - c = LoadStringW(GetModuleHandle(NULL), nTitleID, Buf, BUFFER_SIZE); + c = LoadStringW(GetModuleHandle(NULL), nTitleID, Buf, BUFFER_SIZE - 2); if (!c) return; - - wcscpy(Buf + c, L":"); + + wcscpy(Buf + c, L": "); } else Buf[0] = L'\0'; - wprintf(L"%-32s ", Buf); + + if (!bIndent) + wprintf(L"%-32s", Buf); + else if (Buf[0]) + wprintf(L"%38s%-16s", L"", Buf); + else + wprintf(L"%38s", L""); va_start(Args, lpFormat); vwprintf(lpFormat, Args); @@ -217,10 +223,10 @@ PrintRow(UINT nTitleID, unsigned cxOffset, LPWSTR lpFormat, ...) VOID AllSysInfo(VOID) { - DWORD dwCharCount = BUFFER_SIZE, dwTimestamp; + DWORD dwCharCount = BUFFER_SIZE, dwTimestamp, dwResult; OSVERSIONINFOW VersionInfo; SYSTEM_INFO SysInfo; - WCHAR Buf[BUFFER_SIZE], Tmp[BUFFER_SIZE], Msg[BUFFER_SIZE], szSystemDir[MAX_PATH]; + WCHAR Buf[BUFFER_SIZE], Tmp[BUFFER_SIZE], szSystemDir[MAX_PATH]; const WCHAR *lpcszSysType; LPWSTR lpBuffer; NETSETUP_JOIN_STATUS NetJoinStatus; @@ -228,6 +234,8 @@ AllSysInfo(VOID) unsigned int cSeconds, i, j; TIME_ZONE_INFORMATION TimeZoneInfo; HKEY hKey; + PIP_ADAPTER_ADDRESSES pAdapters; + ULONG cbAdapters; if (!GetSystemDirectoryW(szSystemDir, sizeof(szSystemDir)/sizeof(szSystemDir[0]))) { @@ -242,7 +250,7 @@ AllSysInfo(VOID) if (!GetComputerNameW(Buf, &dwCharCount)) wprintf(L"Error! GetComputerName failed.\n"); else - PrintRow(IDS_HOST_NAME, 0, L"%s", Buf); + PrintRow(IDS_HOST_NAME, FALSE, L"%s", Buf); // open CurrentVersion key if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, @@ -257,7 +265,7 @@ AllSysInfo(VOID) //getting OS Name RegGetSZ(hKey, NULL, L"ProductName", Buf, BUFFER_SIZE); - PrintRow(IDS_OS_NAME, 0, L"%s", Buf); + PrintRow(IDS_OS_NAME, FALSE, L"%s", Buf); //getting OS Version ZeroMemory(&VersionInfo, sizeof(VersionInfo)); @@ -267,14 +275,14 @@ AllSysInfo(VOID) if (!LoadStringW(GetModuleHandle(NULL), IDS_BUILD, Tmp, BUFFER_SIZE)) Tmp[0] = L'\0'; PrintRow(IDS_OS_VERSION, - 0, - L"%u.%u.%u %s %s %u", - (unsigned)VersionInfo.dwMajorVersion, - (unsigned)VersionInfo.dwMinorVersion, - (unsigned)VersionInfo.dwBuildNumber, + FALSE, + L"%lu.%lu.%lu %s %s %lu", + VersionInfo.dwMajorVersion, + VersionInfo.dwMinorVersion, + VersionInfo.dwBuildNumber, VersionInfo.szCSDVersion, Tmp, - (unsigned)VersionInfo.dwBuildNumber); + VersionInfo.dwBuildNumber); //getting OS Manufacturer @@ -282,24 +290,24 @@ AllSysInfo(VOID) //getting OS Build Type RegGetSZ(hKey, NULL, L"CurrentType", Buf, BUFFER_SIZE); - PrintRow(IDS_OS_BUILD_TYPE, 0, L"%s", Buf); + PrintRow(IDS_OS_BUILD_TYPE, FALSE, L"%s", Buf); //getting Registered Owner RegGetSZ(hKey, NULL, L"RegisteredOwner", Buf, BUFFER_SIZE); - PrintRow(IDS_REG_OWNER, 0, L"%s", Buf); + PrintRow(IDS_REG_OWNER, FALSE, L"%s", Buf); //getting Registered Organization RegGetSZ(hKey, NULL, L"RegisteredOrganization", Buf, BUFFER_SIZE); - PrintRow(IDS_REG_ORG, 0, L"%s", Buf); + PrintRow(IDS_REG_ORG, FALSE, L"%s", Buf); //getting Product ID RegGetSZ(hKey, NULL, L"ProductId", Buf, BUFFER_SIZE); - PrintRow(IDS_PRODUCT_ID, 0, L"%s", Buf); + PrintRow(IDS_PRODUCT_ID, FALSE, L"%s", Buf); //getting Install Date RegGetDWORD(hKey, NULL, L"InstallDate", &dwTimestamp); FormatDateTime((time_t)dwTimestamp, Buf); - PrintRow(IDS_INST_DATE, 0, L"%s", Buf); + PrintRow(IDS_INST_DATE, FALSE, L"%s", Buf); // close Current Version key now RegCloseKey(hKey); @@ -309,7 +317,7 @@ AllSysInfo(VOID) if (!LoadStringW(GetModuleHandle(NULL), IDS_UP_TIME_FORMAT, Tmp, BUFFER_SIZE)) Tmp[0] = L'\0'; swprintf(Buf, Tmp, cSeconds / (60*60*24), (cSeconds / (60*60)) % 24, (cSeconds / 60) % 60, cSeconds % 60); - PrintRow(IDS_UP_TIME, 0, L"%s", Buf); + PrintRow(IDS_UP_TIME, FALSE, L"%s", Buf); //getting System Manufacturer; HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\Manufacturer for Win >= 6.0 swprintf(Tmp, L"%s\\oeminfo.ini", szSystemDir); @@ -319,7 +327,7 @@ AllSysInfo(VOID) Buf, sizeof(Buf)/sizeof(Buf[0]), Tmp); - PrintRow(IDS_SYS_MANUFACTURER, 0, L"%s", Buf); + PrintRow(IDS_SYS_MANUFACTURER, FALSE, L"%s", Buf); //getting System Model; HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\OEMInformation\Model for Win >= 6.0 GetPrivateProfileStringW(L"General", @@ -328,7 +336,7 @@ AllSysInfo(VOID) Buf, sizeof(Buf)/sizeof(Buf[0]), Tmp); - PrintRow(IDS_SYS_MODEL, 0, L"%s", Buf); + PrintRow(IDS_SYS_MODEL, FALSE, L"%s", Buf); //getting System type switch (SysInfo.wProcessorArchitecture) @@ -346,13 +354,13 @@ AllSysInfo(VOID) lpcszSysType = L"Unknown"; break; } - PrintRow(IDS_SYS_TYPE, 0, L"%s", lpcszSysType); + PrintRow(IDS_SYS_TYPE, FALSE, L"%s", lpcszSysType); //getting Processor(s) if (!LoadStringW(GetModuleHandle(NULL), IDS_PROCESSORS_FORMAT, Tmp, BUFFER_SIZE)) Tmp[0] = L'\0'; swprintf(Buf, Tmp, (unsigned)SysInfo.dwNumberOfProcessors); - PrintRow(IDS_PROCESSORS, 0, L"%s", Buf); + PrintRow(IDS_PROCESSORS, FALSE, L"%s", Buf); for(i = 0; i < (unsigned int)SysInfo.dwNumberOfProcessors; i++) { swprintf(Tmp, L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%u", i); @@ -363,7 +371,7 @@ AllSysInfo(VOID) Buf[j++] = L' '; RegGetSZ(HKEY_LOCAL_MACHINE, Tmp, L"VendorIdentifier", Buf + j, BUFFER_SIZE - j); - PrintRow(0, 0, L"%s", Buf); + PrintRow(0, FALSE, L"%s", Buf); } //getting BIOS Version @@ -372,7 +380,7 @@ AllSysInfo(VOID) L"SystemBiosVersion", Buf, BUFFER_SIZE); - PrintRow(IDS_BIOS_VERSION, 0, L"%s", Buf); + PrintRow(IDS_BIOS_VERSION, FALSE, L"%s", Buf); //gettings BIOS date RegGetSZ(HKEY_LOCAL_MACHINE, @@ -380,13 +388,13 @@ AllSysInfo(VOID) L"SystemBiosDate", Buf, BUFFER_SIZE); - PrintRow(IDS_BIOS_DATE, 0, L"%s", Buf); + PrintRow(IDS_BIOS_DATE, FALSE, L"%s", Buf); //getting ReactOS Directory if (!GetWindowsDirectoryW(Buf, BUFFER_SIZE)) wprintf(L"Error! GetWindowsDirectory failed."); else - PrintRow(IDS_ROS_DIR, 0, L"%s", Buf); + PrintRow(IDS_ROS_DIR, FALSE, L"%s", Buf); //getting System Directory PrintRow(IDS_SYS_DIR, 0, L"%s", szSystemDir); @@ -397,7 +405,7 @@ AllSysInfo(VOID) L"SystemPartition", Buf, BUFFER_SIZE); - PrintRow(IDS_BOOT_DEV, 0, L"%s", Buf); + PrintRow(IDS_BOOT_DEV, FALSE, L"%s", Buf); //getting System Locale if (GetLocaleInfoW(LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, Tmp, BUFFER_SIZE)) @@ -412,7 +420,7 @@ AllSysInfo(VOID) if (lpBuffer) SHLoadIndirectString(lpBuffer+1, lpBuffer+1, BUFFER_SIZE - (lpBuffer-Buf) - 1, NULL); - PrintRow(IDS_SYS_LOCALE, 0, L"%s", Buf); + PrintRow(IDS_SYS_LOCALE, FALSE, L"%s", Buf); } //getting Input Locale @@ -432,7 +440,7 @@ AllSysInfo(VOID) if (lpBuffer) SHLoadIndirectString(lpBuffer+1, lpBuffer+1, BUFFER_SIZE - (lpBuffer-Buf) - 1, NULL); - PrintRow(IDS_INPUT_LOCALE, 0, L"%s", Buf); + PrintRow(IDS_INPUT_LOCALE, FALSE, L"%s", Buf); } //getting Time Zone @@ -448,16 +456,16 @@ AllSysInfo(VOID) unsigned i; /* Find current timezone */ - dwCharCount = 256; // Windows seems to have a bug - it doesnt accept BUFFER_SIZE here + dwCharCount = BUFFER_SIZE; for(i = 0; RegEnumKeyExW(hKey, i, Tmp, &dwCharCount, NULL, NULL, NULL, NULL) == ERROR_SUCCESS; ++i, dwCharCount = 255) { RegGetSZ(hKey, Tmp, L"Std", Buf, BUFFER_SIZE); - if(!wcscmp(Buf, TimeZoneInfo.StandardName)) + if (!wcscmp(Buf, TimeZoneInfo.StandardName)) { RegGetSZ(hKey, Tmp, L"Display", Buf, BUFFER_SIZE); - PrintRow(IDS_TIME_ZONE, 0, L"%s", Buf); + PrintRow(IDS_TIME_ZONE, FALSE, L"%s", Buf); break; } @@ -468,23 +476,23 @@ AllSysInfo(VOID) //getting Total Physical Memory GlobalMemoryStatus(&MemoryStatus); FormatBytes(Buf, MemoryStatus.dwTotalPhys); - PrintRow(IDS_TOTAL_PHYS_MEM, 0, L"%s", Buf); + PrintRow(IDS_TOTAL_PHYS_MEM, FALSE, L"%s", Buf); //getting Available Physical Memory FormatBytes(Buf, MemoryStatus.dwAvailPhys); - PrintRow(IDS_AVAIL_PHISICAL_MEM, 0, L"%s", Buf); + PrintRow(IDS_AVAIL_PHISICAL_MEM, FALSE, L"%s", Buf); //getting Virtual Memory: Max Size FormatBytes(Buf, MemoryStatus.dwTotalVirtual); - PrintRow(IDS_VIRT_MEM_MAX, 0, L"%s", Buf); + PrintRow(IDS_VIRT_MEM_MAX, FALSE, L"%s", Buf); //getting Virtual Memory: Available FormatBytes(Buf, MemoryStatus.dwAvailVirtual); - PrintRow(IDS_VIRT_MEM_AVAIL, 0, L"%s", Buf); + PrintRow(IDS_VIRT_MEM_AVAIL, FALSE, L"%s", Buf); //getting Virtual Memory: In Use FormatBytes(Buf, MemoryStatus.dwTotalVirtual-MemoryStatus.dwAvailVirtual); - PrintRow(IDS_VIRT_MEM_INUSE, 0, L"%s", Buf); + PrintRow(IDS_VIRT_MEM_INUSE, FALSE, L"%s", Buf); //getting Page File Location(s) if (RegGetSZ(HKEY_LOCAL_MACHINE, @@ -504,13 +512,14 @@ AllSysInfo(VOID) } } - PrintRow(IDS_PAGEFILE_LOC, 0, L"%s", Buf); + PrintRow(IDS_PAGEFILE_LOC, FALSE, L"%s", Buf); } //getting Domain if (NetGetJoinInformation (NULL, &lpBuffer, &NetJoinStatus) == NERR_Success) { - PrintRow(IDS_DOMAIN, 0, L"%s", lpBuffer); + if (NetJoinStatus == NetSetupWorkgroupName || NetJoinStatus == NetSetupDomainName) + PrintRow(IDS_DOMAIN, FALSE, L"%s", lpBuffer); NetApiBufferFree(lpBuffer); } @@ -518,22 +527,100 @@ AllSysInfo(VOID) //getting Logon Server //getting NetWork Card(s) - if(GetOemStrings(IDS_NETWORK_CARDS, Msg)) + cbAdapters = 4096; + pAdapters = malloc(cbAdapters); + while((dwResult = GetAdaptersAddresses(AF_UNSPEC, 0x0002, NULL, pAdapters, &cbAdapters)) == ERROR_BUFFER_OVERFLOW) { - + cbAdapters += 4096; + pAdapters = (PIP_ADAPTER_ADDRESSES)realloc(pAdapters, cbAdapters); } + + if (dwResult == ERROR_SUCCESS) + { + PIP_ADAPTER_ADDRESSES pCurrentAdapter = pAdapters; + unsigned cAdapters = 0; + + /* Count adapters */ + for(i = 0; pCurrentAdapter; ++i) + { + if (pCurrentAdapter->IfType != 24 && pCurrentAdapter->IfType != 131) + ++cAdapters; + pCurrentAdapter = pCurrentAdapter->Next; + } + + + /* Print adapters count */ + if (!LoadStringW(GetModuleHandle(NULL), IDS_NETWORK_CARDS_FORMAT, Tmp, BUFFER_SIZE)) + Tmp[0] = L'\0'; + swprintf(Buf, Tmp, cAdapters); + PrintRow(IDS_NETWORK_CARDS, FALSE, L"%s", Buf); + + /* Show information about each adapter */ + pCurrentAdapter = pAdapters; + for(i = 0; pCurrentAdapter; ++i) + { + if (pCurrentAdapter->IfType != 24 && pCurrentAdapter->IfType != 131)//IF_TYPE_SOFTWARE_LOOPBACK) + { + PIP_ADAPTER_UNICAST_ADDRESS pAddress; + + PrintRow(0, FALSE, L"[%02u]: %s", i + 1, pCurrentAdapter->Description); + PrintRow(IDS_CONNECTION_NAME, TRUE, L"%s", pCurrentAdapter->FriendlyName); + if (!(pCurrentAdapter->Flags & 0x0004)) + { + if (!LoadStringW(GetModuleHandle(NULL), IDS_NO, Buf, BUFFER_SIZE)) + Buf[0] = L'\0'; + PrintRow(IDS_DHCP_ENABLED, TRUE, Buf); + } + if (pCurrentAdapter->OperStatus == IfOperStatusDown) + { + if (!LoadStringW(GetModuleHandle(NULL), IDS_MEDIA_DISCONNECTED, Buf, BUFFER_SIZE)) + Buf[0] = L'\0'; + PrintRow(IDS_STATUS, TRUE, Buf); + } + else + { + if (!LoadStringW(GetModuleHandle(NULL), IDS_IP_ADDRESSES, Buf, BUFFER_SIZE)) + Buf[0] = L'\0'; + PrintRow(0, TRUE, Buf); + pAddress = pCurrentAdapter->FirstUnicastAddress; + for (j = 0; pAddress; ++j) + { + dwCharCount = BUFFER_SIZE; + WSAAddressToStringW(pAddress->Address.lpSockaddr, pAddress->Address.iSockaddrLength, NULL, Buf, &dwCharCount); + PrintRow(0, TRUE, L"[%02u]: %s", j + 1, Buf); + pAddress = pAddress->Next; + } + } + } + pCurrentAdapter = pCurrentAdapter->Next; + } + } + free(pAdapters); } /* Main program */ int main(int argc, char *argv[]) { + WSADATA WsaData; + int i; + setlocale(LC_ALL, ""); - if (argc > 1 && (!strcmp(argv[1], "/?") || !strcmp(argv[1], "-?"))) + WSAStartup(MAKEWORD(2, 2), &WsaData); + + for (i = 1; i < argc; ++i) { - Usage(); - return 0; + if (!strcmp(argv[i], "/?") || !strcmp(argv[i], "-?")) + { + Usage(); + return 0; + } + else + { + printf("Unsupported argument: %s\n", argv[i]); + return -1; + } } AllSysInfo(); diff --git a/rosapps/applications/sysutils/systeminfo/systeminfo.rbuild b/rosapps/applications/sysutils/systeminfo/systeminfo.rbuild index fc3ef6dd2c3..8a4b0fbc7b1 100644 --- a/rosapps/applications/sysutils/systeminfo/systeminfo.rbuild +++ b/rosapps/applications/sysutils/systeminfo/systeminfo.rbuild @@ -4,6 +4,8 @@ advapi32 netapi32 shlwapi + iphlpapi + ws2_32 systeminfo.c systeminfo.rc rsrc.rc From 26504807cdc2ff9c58aeba7733e6171059a750ed Mon Sep 17 00:00:00 2001 From: Rafal Harabien Date: Tue, 5 Apr 2011 21:24:25 +0000 Subject: [PATCH 15/21] [USRMGR] Free buffer instead of freeing pointer to buffer svn path=/trunk/; revision=51261 --- reactos/dll/cpl/usrmgr/groupprops.c | 2 +- reactos/dll/cpl/usrmgr/groups.c | 2 +- reactos/dll/cpl/usrmgr/userprops.c | 2 +- reactos/dll/cpl/usrmgr/users.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/reactos/dll/cpl/usrmgr/groupprops.c b/reactos/dll/cpl/usrmgr/groupprops.c index ac30a280c00..d34acd3eb51 100644 --- a/reactos/dll/cpl/usrmgr/groupprops.c +++ b/reactos/dll/cpl/usrmgr/groupprops.c @@ -139,7 +139,7 @@ InitGroupMembersList(HWND hwndDlg, pUserBuffer[i].usri20_comment); } - NetApiBufferFree(&pUserBuffer); + NetApiBufferFree(pUserBuffer); /* No more data left */ if (netStatus != ERROR_MORE_DATA) diff --git a/reactos/dll/cpl/usrmgr/groups.c b/reactos/dll/cpl/usrmgr/groups.c index 4eebfa40f26..445d90ad342 100644 --- a/reactos/dll/cpl/usrmgr/groups.c +++ b/reactos/dll/cpl/usrmgr/groups.c @@ -77,7 +77,7 @@ UpdateGroupsList(HWND hwndListView) pBuffer[i].lgrpi1_comment); } - NetApiBufferFree(&pBuffer); + NetApiBufferFree(pBuffer); /* No more data left */ if (netStatus != ERROR_MORE_DATA) diff --git a/reactos/dll/cpl/usrmgr/userprops.c b/reactos/dll/cpl/usrmgr/userprops.c index c007b1846d1..a9cd031f02a 100644 --- a/reactos/dll/cpl/usrmgr/userprops.c +++ b/reactos/dll/cpl/usrmgr/userprops.c @@ -432,7 +432,7 @@ InitUserGroupsList(HWND hwndDlg) pBuffer[i].lgrpi1_comment); } - NetApiBufferFree(&pBuffer); + NetApiBufferFree(pBuffer); /* No more data left */ if (netStatus != ERROR_MORE_DATA) diff --git a/reactos/dll/cpl/usrmgr/users.c b/reactos/dll/cpl/usrmgr/users.c index 04ff45eaca3..174ec2f4f57 100644 --- a/reactos/dll/cpl/usrmgr/users.c +++ b/reactos/dll/cpl/usrmgr/users.c @@ -441,7 +441,7 @@ UpdateUsersList(HWND hwndListView) pBuffer[i].usri20_comment); } - NetApiBufferFree(&pBuffer); + NetApiBufferFree(pBuffer); /* No more data left */ if (netStatus != ERROR_MORE_DATA) From ddb4a8780dd78ee3a31eff44a2d19d9173ad1263 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Tue, 5 Apr 2011 21:37:54 +0000 Subject: [PATCH 16/21] [WIDL] Reapply the switchtype patch. svn path=/trunk/; revision=51262 --- reactos/tools/widl/parser.tab.c | 6 ++++++ reactos/tools/widl/parser.y | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/reactos/tools/widl/parser.tab.c b/reactos/tools/widl/parser.tab.c index 3df4c104073..0166dbd56c8 100644 --- a/reactos/tools/widl/parser.tab.c +++ b/reactos/tools/widl/parser.tab.c @@ -6334,6 +6334,12 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at else if (is_attr(attrs, ATTR_UUID) && !is_attr(attrs, ATTR_PUBLIC)) attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) ); + /* Append the SWITCHTYPE attribute to a non-encapsulated union if it does not already have it. */ + if (type_get_type_detect_alias(type) == TYPE_UNION && + is_attr(attrs, ATTR_SWITCHTYPE) && + !is_attr(type->attrs, ATTR_SWITCHTYPE)) + type->attrs = append_attr(type->attrs, make_attrp(ATTR_SWITCHTYPE, get_attrp(attrs, ATTR_SWITCHTYPE))); + LIST_FOR_EACH_ENTRY( decl, decls, const declarator_t, entry ) { diff --git a/reactos/tools/widl/parser.y b/reactos/tools/widl/parser.y index c924a662f7f..d5f87f98291 100644 --- a/reactos/tools/widl/parser.y +++ b/reactos/tools/widl/parser.y @@ -1854,6 +1854,12 @@ static type_t *reg_typedefs(decl_spec_t *decl_spec, declarator_list_t *decls, at else if (is_attr(attrs, ATTR_UUID) && !is_attr(attrs, ATTR_PUBLIC)) attrs = append_attr( attrs, make_attr(ATTR_PUBLIC) ); + /* Append the SWITCHTYPE attribute to a non-encapsulated union if it does not already have it. */ + if (type_get_type_detect_alias(type) == TYPE_UNION && + is_attr(attrs, ATTR_SWITCHTYPE) && + !is_attr(type->attrs, ATTR_SWITCHTYPE)) + type->attrs = append_attr(type->attrs, make_attrp(ATTR_SWITCHTYPE, get_attrp(attrs, ATTR_SWITCHTYPE))); + LIST_FOR_EACH_ENTRY( decl, decls, const declarator_t, entry ) { From f43d2fe8ca8b3fa41d57a3021acffaa46574cc42 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Wed, 6 Apr 2011 01:31:50 +0000 Subject: [PATCH 17/21] [Win32k] - Fix to unfocused explorer minimize hang, spotted by R3dDr4g0n . svn path=/trunk/; revision=51263 --- reactos/subsystems/win32/win32k/ntuser/window.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index a64f48d5ba9..379edcd99f3 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -1529,10 +1529,14 @@ static void IntSendParentNotify( PWND pWindow, UINT msg ) { if (pWindow->spwndParent && pWindow->spwndParent != UserGetDesktopWindow()) { + USER_REFERENCE_ENTRY Ref; + UserRefObjectCo(pWindow->spwndParent, &Ref); // Fix explorer minimize hang. + // Should be co_IntSendMessage please retest, Ref to Chg, revision 51254... co_IntSendMessageNoWait( pWindow->spwndParent->head.h, WM_PARENTNOTIFY, MAKEWPARAM( msg, pWindow->IDMenu), (LPARAM)pWindow->head.h ); + UserDerefObjectCo(pWindow->spwndParent); } } } From 374e21b4e07680d6d477bb2cd59858048e5bd539 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Wed, 6 Apr 2011 12:23:54 +0000 Subject: [PATCH 18/21] [Win32k] - The Reak fix to unfocused explorer minimize hang, spotted by R3dDr4g0n . svn path=/trunk/; revision=51264 --- .../subsystems/win32/win32k/ntuser/msgqueue.c | 26 +++++-------------- .../subsystems/win32/win32k/ntuser/window.c | 2 +- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index db8ca7c97b8..6af6000137c 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -1353,28 +1353,14 @@ NTSTATUS FASTCALL co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, PWND WndFilter, UINT MsgFilterMin, UINT MsgFilterMax) { - PTHREADINFO pti; - NTSTATUS ret = STATUS_SUCCESS; - - pti = MessageQueue->Thread->Tcb.Win32Thread; - - while ( co_MsqDispatchOneSentMessage(MessageQueue) ); - - if (pti->pcti->fsWakeBits & pti->pcti->fsChangeBits ) - { - return ret; - } - - pti->pClientInfo->cSpins = 0; - IdlePing(); + NTSTATUS ret; UserLeaveCo(); - ret = KeWaitForSingleObject(MessageQueue->NewMessages, - Executive, - UserMode, - FALSE, - NULL); + ret = KeWaitForSingleObject( MessageQueue->NewMessages, + UserRequest, + UserMode, + FALSE, + NULL ); UserEnterCo(); - IdlePong(); return ret; } diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index 379edcd99f3..f07a5455517 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -1530,7 +1530,7 @@ static void IntSendParentNotify( PWND pWindow, UINT msg ) if (pWindow->spwndParent && pWindow->spwndParent != UserGetDesktopWindow()) { USER_REFERENCE_ENTRY Ref; - UserRefObjectCo(pWindow->spwndParent, &Ref); // Fix explorer minimize hang. + UserRefObjectCo(pWindow->spwndParent, &Ref); // Should be co_IntSendMessage please retest, Ref to Chg, revision 51254... co_IntSendMessageNoWait( pWindow->spwndParent->head.h, WM_PARENTNOTIFY, From 3890323807d975750a66446eb8885d89b9262128 Mon Sep 17 00:00:00 2001 From: James Tabor Date: Wed, 6 Apr 2011 12:53:52 +0000 Subject: [PATCH 19/21] [User32|Win32k] - Pass all the wine test_capture_1/2/3/4. - Fix the menu tracking pop up hang issue by looking for deceased windows that pass on while in the start of tracking. This could be a fix for other wine tests. - ReactOS is not Linux and wine is not enough! svn path=/trunk/; revision=51265 --- reactos/dll/win32/user32/windows/menu.c | 38 ++++++++++++------- reactos/dll/win32/user32/windows/message.c | 4 +- .../subsystems/win32/win32k/include/focus.h | 4 ++ .../subsystems/win32/win32k/ntuser/focus.c | 35 +++++++++++++++-- .../subsystems/win32/win32k/ntuser/message.c | 2 - .../win32/win32k/ntuser/simplecall.c | 4 +- 6 files changed, 63 insertions(+), 24 deletions(-) diff --git a/reactos/dll/win32/user32/windows/menu.c b/reactos/dll/win32/user32/windows/menu.c index 92749931c8a..004eaa7886b 100644 --- a/reactos/dll/win32/user32/windows/menu.c +++ b/reactos/dll/win32/user32/windows/menu.c @@ -1576,6 +1576,11 @@ static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT fl MenuInfo.FocusedItem = NO_SELECTED_ITEM; } + /* ReactOS Check */ + if (!ValidateHwnd(hwndOwner)) + { // This window maybe already DEAD!!! + return FALSE; + } /* store the owner for DrawItem */ MenuInfo.WndOwner = hwndOwner; MenuSetRosMenuInfo(&MenuInfo); @@ -3208,14 +3213,16 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, fEndMenu = !fRemove; } + if (wFlags & TF_ENDMENU) fEndMenu = TRUE; + /* owner may not be visible when tracking a popup, so use the menu itself */ capture_win = (wFlags & TPM_POPUPMENU) ? MenuInfo.Wnd : mt.OwnerWnd; (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, capture_win); // 1 SetCapture(capture_win); // 2 - FIXME("MenuTrackMenu 1\n"); while (! fEndMenu) { + BOOL ErrorExit = FALSE; PVOID menu = ValidateHandle(mt.CurrentMenu, VALIDATE_TYPE_MENU); if (!menu) /* sometimes happens if I do a window manager close */ break; @@ -3233,6 +3240,12 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, } else { + /* ReactOS Check */ + if (!ValidateHwnd(mt.OwnerWnd) || !ValidateHwnd(MenuInfo.Wnd)) + { + ErrorExit = TRUE; // Do not wait on dead windows, now test_capture_4 works. + break; + } if (!enterIdleSent) { HWND win = MenuInfo.Flags & MF_POPUP ? MenuInfo.Wnd : NULL; @@ -3241,9 +3254,10 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, } WaitMessage(); } - //FIXME("MenuTrackMenu loop 1\n"); } + if (ErrorExit) break; // Gracefully dropout. + /* check if EndMenu() tried to cancel us, by posting this message */ if (msg.message == WM_CANCELMODE) { @@ -3449,7 +3463,6 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, { PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); DispatchMessageW( &msg ); - //FIXME("MenuTrackMenu loop 2\n"); continue; } @@ -3460,9 +3473,7 @@ static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y, if (fRemove && !(mt.TrackFlags & TF_SKIPREMOVE) ) PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE ); else mt.TrackFlags &= ~TF_SKIPREMOVE; - //FIXME("MenuTrackMenu loop 3\n"); } - FIXME("MenuTrackMenu 2\n"); (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL); SetCapture(NULL); /* release the capture */ @@ -3521,12 +3532,11 @@ static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT HideCaret(0); - MenuGetRosMenuInfo(&MenuInfo, hMenu); /* This makes the menus of applications built with Delphi work. * It also enables menus to be displayed in more than one window, * but there are some bugs left that need to be fixed in this case. */ - if(MenuInfo.Self == hMenu) + if (MenuGetRosMenuInfo(&MenuInfo, hMenu)) { MenuInfo.Wnd = hWnd; MenuSetRosMenuInfo(&MenuInfo); @@ -3658,13 +3668,7 @@ VOID MenuTrackKbdMenuBar(HWND hwnd, UINT wParam, WCHAR wChar) MenuSelectItem( hwnd, &MenuInfo, uItem, TRUE, 0 ); - if (wParam & HTSYSMENU) - { - /* prevent sysmenu activation for managed windows on Alt down/up */ -// if (GetPropA( hwnd, "__wine_x11_managed" )) - wFlags |= TF_ENDMENU; /* schedule end of menu tracking */ - } - else + if (!(wParam & HTSYSMENU) || wChar == ' ') { if( uItem == NO_SELECTED_ITEM ) MenuMoveSelection( hwnd, &MenuInfo, ITEM_NEXT ); @@ -3693,6 +3697,12 @@ BOOL WINAPI TrackPopupMenuEx( HMENU Menu, UINT Flags, int x, int y, return FALSE; } + /* ReactOS Check */ + if (!ValidateHwnd(Wnd)) + { + return FALSE; + } + MenuGetRosMenuInfo(&MenuInfo, Menu); if (IsWindow(MenuInfo.Wnd)) { diff --git a/reactos/dll/win32/user32/windows/message.c b/reactos/dll/win32/user32/windows/message.c index 13d12147d09..8cc1a07f581 100644 --- a/reactos/dll/win32/user32/windows/message.c +++ b/reactos/dll/win32/user32/windows/message.c @@ -2380,9 +2380,7 @@ GetCapture(VOID) BOOL WINAPI ReleaseCapture(VOID) { - HWND hwndPrev = NtUserSetCapture(NULL); - return(hwndPrev ? TRUE : FALSE); -// return (BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_RELEASECAPTURE); + return (BOOL)NtUserCallNoParam(NOPARAM_ROUTINE_RELEASECAPTURE); } diff --git a/reactos/subsystems/win32/win32k/include/focus.h b/reactos/subsystems/win32/win32k/include/focus.h index 299efb56e0f..5c7e6fcefcc 100644 --- a/reactos/subsystems/win32/win32k/include/focus.h +++ b/reactos/subsystems/win32/win32k/include/focus.h @@ -7,6 +7,10 @@ HWND FASTCALL IntGetCaptureWindow(VOID); HWND FASTCALL IntGetFocusWindow(VOID); +HWND FASTCALL +co_UserSetCapture(HWND hWnd); +BOOL FASTCALL +IntReleaseCapture(VOID); /* * These functions take the window handles from current thread queue. diff --git a/reactos/subsystems/win32/win32k/ntuser/focus.c b/reactos/subsystems/win32/win32k/ntuser/focus.c index 65750944072..cdc26a7ff94 100644 --- a/reactos/subsystems/win32/win32k/ntuser/focus.c +++ b/reactos/subsystems/win32/win32k/ntuser/focus.c @@ -580,17 +580,44 @@ co_UserSetCapture(HWND hWnd) ThreadQueue->CaptureWindow = hWnd; - /// These are hacks! - /* also remove other windows if not capturing anymore */ - if (hWnd == NULL) + if (hWnd == NULL) // Release mode. { + MOUSEINPUT mi; + /// These are hacks! + /* also remove other windows if not capturing anymore */ MsqSetStateWindow(ThreadQueue, MSQ_STATE_MENUOWNER, NULL); MsqSetStateWindow(ThreadQueue, MSQ_STATE_MOVESIZE, NULL); - } /// + /* Somebody may have missed some mouse movements */ + mi.dx = 0; + mi.dy = 0; + mi.mouseData = 0; + mi.dwFlags = MOUSEEVENTF_MOVE; + mi.time = 0; + mi.dwExtraInfo = 0; + IntMouseInput(&mi); + } return hWndPrev; } +BOOL +FASTCALL +IntReleaseCapture(VOID) +{ + PTHREADINFO pti; + PUSER_MESSAGE_QUEUE ThreadQueue; + + pti = PsGetCurrentThreadWin32Thread(); + ThreadQueue = pti->MessageQueue; + + // Can not release inside WM_CAPTURECHANGED!! + if (ThreadQueue->QF_flags & QF_CAPTURELOCKED) return FALSE; + + co_UserSetCapture(NULL); + + return TRUE; +} + /* * @implemented */ diff --git a/reactos/subsystems/win32/win32k/ntuser/message.c b/reactos/subsystems/win32/win32k/ntuser/message.c index 4081267b8c3..31fc6ac7d7c 100644 --- a/reactos/subsystems/win32/win32k/ntuser/message.c +++ b/reactos/subsystems/win32/win32k/ntuser/message.c @@ -16,7 +16,6 @@ #include BOOLEAN NTAPI PsGetProcessExitProcessCalled(PEPROCESS Process); -HWND FASTCALL co_UserSetCapture(HWND hWnd); #define PM_BADMSGFLAGS ~((QS_RAWINPUT << 16)|PM_QS_SENDMESSAGE|PM_QS_PAINT|PM_QS_POSTMESSAGE|PM_QS_INPUT|PM_NOYIELD|PM_REMOVE) @@ -861,7 +860,6 @@ co_IntWaitMessage( PWND Window, { SetLastNtError(Status); DPRINT1("Exit co_IntWaitMessage on error!\n"); - return FALSE; } if (Status == STATUS_USER_APC || Status == STATUS_TIMEOUT) diff --git a/reactos/subsystems/win32/win32k/ntuser/simplecall.c b/reactos/subsystems/win32/win32k/ntuser/simplecall.c index 21109806fe9..e5243d93ad1 100644 --- a/reactos/subsystems/win32/win32k/ntuser/simplecall.c +++ b/reactos/subsystems/win32/win32k/ntuser/simplecall.c @@ -119,6 +119,9 @@ NtUserCallNoParam(DWORD Routine) RETURN( (DWORD_PTR)MAKELONG(pti->ptLast.x, pti->ptLast.y)); } + case NOPARAM_ROUTINE_RELEASECAPTURE: + RETURN( (DWORD_PTR)IntReleaseCapture()); + default: DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine); EngSetLastError(ERROR_INVALID_PARAMETER); @@ -252,7 +255,6 @@ NtUserCallOneParam( { BOOL ret = TRUE; - _SEH2_TRY { ProbeForWrite((POINT*)Param,sizeof(POINT),1); From 5cf13573ed44daa6730f3ed82afcb37e61e808ed Mon Sep 17 00:00:00 2001 From: James Tabor Date: Wed, 6 Apr 2011 12:56:46 +0000 Subject: [PATCH 20/21] - Turn on test_capture_4. svn path=/trunk/; revision=51266 --- rostests/winetests/user32/win.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/rostests/winetests/user32/win.c b/rostests/winetests/user32/win.c index 668399caeef..33c837bed0e 100644 --- a/rostests/winetests/user32/win.c +++ b/rostests/winetests/user32/win.c @@ -6058,11 +6058,7 @@ START_TEST(win) test_capture_1(); test_capture_2(); test_capture_3(hwndMain, hwndMain2); - - if(!winetest_interactive) - skip("skipping test_capture_4, that hangs on reactos\n"); - else - test_capture_4(); + test_capture_4(); test_CreateWindow(); test_parent_owner(); From 8324997bc49b90dab833189caa0285a175ebe165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Gardou?= Date: Wed, 6 Apr 2011 13:28:32 +0000 Subject: [PATCH 21/21] [CMAKE] RosTests : buildno_header is no longer a valid target svn path=/trunk/; revision=51267 --- rostests/apitests/w32kdll/w32kdll_2k3sp2/CMakeLists.txt | 2 +- rostests/apitests/w32kdll/w32kdll_2ksp4/CMakeLists.txt | 2 +- rostests/apitests/w32kdll/w32kdll_ros/CMakeLists.txt | 2 +- rostests/apitests/w32kdll/w32kdll_vista/CMakeLists.txt | 2 +- rostests/apitests/w32kdll/w32kdll_xpsp2/CMakeLists.txt | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rostests/apitests/w32kdll/w32kdll_2k3sp2/CMakeLists.txt b/rostests/apitests/w32kdll/w32kdll_2k3sp2/CMakeLists.txt index ead3b82f1bf..57da80875a3 100644 --- a/rostests/apitests/w32kdll/w32kdll_2k3sp2/CMakeLists.txt +++ b/rostests/apitests/w32kdll/w32kdll_2k3sp2/CMakeLists.txt @@ -2,5 +2,5 @@ add_library(w32kdll_2k3sp2 SHARED main.c w32kdll_2k3sp2.S) set_entrypoint(w32kdll_2k3sp2 0) target_link_libraries(w32kdll_2k3sp2 ${CMAKE_CURRENT_SOURCE_DIR}/w32kdll_2k3sp2.def) -add_dependencies(w32kdll_2k3sp2 psdk buildno_header) +add_dependencies(w32kdll_2k3sp2 psdk ) add_importlib_target(w32kdll_2k3sp2.def) diff --git a/rostests/apitests/w32kdll/w32kdll_2ksp4/CMakeLists.txt b/rostests/apitests/w32kdll/w32kdll_2ksp4/CMakeLists.txt index efc4ec0ad68..66768eeef4d 100644 --- a/rostests/apitests/w32kdll/w32kdll_2ksp4/CMakeLists.txt +++ b/rostests/apitests/w32kdll/w32kdll_2ksp4/CMakeLists.txt @@ -2,5 +2,5 @@ add_library(w32kdll_2ksp4 SHARED main.c w32kdll_2ksp4.S) set_entrypoint(w32kdll_2ksp4 0) target_link_libraries(w32kdll_2ksp4 ${CMAKE_CURRENT_SOURCE_DIR}/w32kdll_2ksp4.def) -add_dependencies(w32kdll_2ksp4 psdk buildno_header) +add_dependencies(w32kdll_2ksp4 psdk ) add_importlib_target(w32kdll_2ksp4.def) diff --git a/rostests/apitests/w32kdll/w32kdll_ros/CMakeLists.txt b/rostests/apitests/w32kdll/w32kdll_ros/CMakeLists.txt index ad143fee275..c96fff8d796 100644 --- a/rostests/apitests/w32kdll/w32kdll_ros/CMakeLists.txt +++ b/rostests/apitests/w32kdll/w32kdll_ros/CMakeLists.txt @@ -7,5 +7,5 @@ target_link_libraries(w32kdll ${CMAKE_CURRENT_SOURCE_DIR}/w32kdll_ros.def win32ksys) -add_dependencies(w32kdll psdk buildno_header) +add_dependencies(w32kdll psdk ) add_importlib_target(w32kdll_ros.def) diff --git a/rostests/apitests/w32kdll/w32kdll_vista/CMakeLists.txt b/rostests/apitests/w32kdll/w32kdll_vista/CMakeLists.txt index 5c387435e80..a70bec57cf7 100644 --- a/rostests/apitests/w32kdll/w32kdll_vista/CMakeLists.txt +++ b/rostests/apitests/w32kdll/w32kdll_vista/CMakeLists.txt @@ -2,5 +2,5 @@ add_library(w32kdll_vista SHARED main.c w32kdll_vista.S) set_entrypoint(w32kdll_vista 0) target_link_libraries(w32kdll_vista ${CMAKE_CURRENT_SOURCE_DIR}/w32kdll_vista.def) -add_dependencies(w32kdll_vista psdk buildno_header) +add_dependencies(w32kdll_vista psdk ) add_importlib_target(w32kdll_vista.def) diff --git a/rostests/apitests/w32kdll/w32kdll_xpsp2/CMakeLists.txt b/rostests/apitests/w32kdll/w32kdll_xpsp2/CMakeLists.txt index 3f86810f2c6..e3579261dd4 100644 --- a/rostests/apitests/w32kdll/w32kdll_xpsp2/CMakeLists.txt +++ b/rostests/apitests/w32kdll/w32kdll_xpsp2/CMakeLists.txt @@ -2,5 +2,5 @@ add_library(w32kdll_xpsp2 SHARED main.c w32kdll_xpsp2.S) set_entrypoint(w32kdll_xpsp2 0) target_link_libraries(w32kdll_xpsp2 ${CMAKE_CURRENT_SOURCE_DIR}/w32kdll_xpsp2.def) -add_dependencies(w32kdll_xpsp2 psdk buildno_header) +add_dependencies(w32kdll_xpsp2 psdk ) add_importlib_target(w32kdll_xpsp2.def)