diff --git a/reactos/dll/win32/user32/user32.rbuild b/reactos/dll/win32/user32/user32.rbuild index 11fa1e0ecfa..0295681a7b9 100644 --- a/reactos/dll/win32/user32/user32.rbuild +++ b/reactos/dll/win32/user32/user32.rbuild @@ -14,6 +14,7 @@ advapi32 imm32 win32ksys + pseh user32.h diff --git a/reactos/dll/win32/user32/windows/class.c b/reactos/dll/win32/user32/windows/class.c index f9a79c8ade8..479f8ba2e24 100644 --- a/reactos/dll/win32/user32/windows/class.c +++ b/reactos/dll/win32/user32/windows/class.c @@ -199,80 +199,101 @@ GetClassLongA(HWND hWnd, int nIndex) if (!Wnd) return 0; - Class = DesktopPtrToUser(Wnd->Class); - ASSERT(Class != NULL); - - if (nIndex >= 0) + _SEH_TRY { - if (nIndex + sizeof(ULONG_PTR) < nIndex || - nIndex + sizeof(ULONG_PTR) > Class->ClsExtra) + Class = DesktopPtrToUser(Wnd->Class); + if (Class != NULL) { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; + if (nIndex >= 0) + { + if (nIndex + sizeof(ULONG_PTR) < nIndex || + nIndex + sizeof(ULONG_PTR) > Class->ClsExtra) + { + SetLastError(ERROR_INVALID_PARAMETER); + } + else + Ret = *(PULONG_PTR)((ULONG_PTR)(Class + 1) + nIndex); + } + else + { + switch (nIndex) + { + case GCL_CBWNDEXTRA: + Ret = (ULONG_PTR)Class->WndExtra; + break; + + case GCL_CBCLSEXTRA: + Ret = (ULONG_PTR)Class->ClsExtra; + break; + + case GCL_HBRBACKGROUND: + Ret = (ULONG_PTR)Class->hbrBackground; + if (Ret != 0 && Ret < 0x4000) + Ret = (ULONG_PTR)GetSysColorBrush((ULONG)Ret - 1); + break; + + case GCL_HMODULE: + Ret = (ULONG_PTR)Class->hInstance; + break; + + case GCL_MENUNAME: + Ret = (ULONG_PTR)Class->AnsiMenuName; + break; + + case GCL_STYLE: + Ret = (ULONG_PTR)Class->Style; + break; + + case GCW_ATOM: + Ret = (ULONG_PTR)Class->Atom; + break; + + case GCLP_HCURSOR: + /* FIXME - get handle from pointer to CURSOR object */ + Ret = (ULONG_PTR)Class->hCursor; + break; + + case GCLP_HICON: + /* FIXME - get handle from pointer to ICON object */ + Ret = (ULONG_PTR)Class->hIcon; + break; + + case GCLP_HICONSM: + /* FIXME - get handle from pointer to ICON object */ + Ret = (ULONG_PTR)Class->hIconSm; + break; + + case GCLP_WNDPROC: + /* We need to make a call to win32k as it may be required to + create a callproc handle */ + Wnd = NULL; + break; + + default: + SetLastError(ERROR_INVALID_INDEX); + break; + } + } } - - Ret = *(PULONG_PTR)((ULONG_PTR)(Class + 1) + nIndex); - } - else - { - switch (nIndex) + else { - case GCL_CBWNDEXTRA: - Ret = (ULONG_PTR)Class->WndExtra; - break; + /* This is a race condition! Call win32k to make sure we're getting + the correct result */ + Wnd = NULL; /* Make sure we call NtUserGetClassLong */ - case GCL_CBCLSEXTRA: - Ret = (ULONG_PTR)Class->ClsExtra; - break; - - case GCL_HBRBACKGROUND: - Ret = (ULONG_PTR)Class->hbrBackground; - if (Ret != 0 && Ret < 0x4000) - Ret = (ULONG_PTR)GetSysColorBrush((ULONG)Ret - 1); - break; - - case GCL_HMODULE: - Ret = (ULONG_PTR)Class->hInstance; - break; - - case GCL_MENUNAME: - Ret = (ULONG_PTR)Class->AnsiMenuName; - break; - - case GCL_STYLE: - Ret = (ULONG_PTR)Class->Style; - break; - - case GCW_ATOM: - Ret = (ULONG_PTR)Class->Atom; - break; - - case GCLP_HCURSOR: - /* FIXME - get handle from pointer to CURSOR object */ - Ret = (ULONG_PTR)Class->hCursor; - break; - - case GCLP_HICON: - /* FIXME - get handle from pointer to ICON object */ - Ret = (ULONG_PTR)Class->hIcon; - break; - - case GCLP_HICONSM: - /* FIXME - get handle from pointer to ICON object */ - Ret = (ULONG_PTR)Class->hIconSm; - break; - - case GCLP_WNDPROC: - /* We need to make a call to win32k as it may be required to - create a callproc handle */ - return NtUserGetClassLong(hWnd, nIndex, TRUE); - - default: - SetLastError(ERROR_INVALID_INDEX); + WARN("Invalid class for hwnd 0x%p!\n", hWnd); } } + _SEH_HANDLE + { + Wnd = NULL; /* Make sure we call NtUserGetClassLong */ + } + _SEH_END; - return Ret; + if (Wnd == NULL) + Ret = NtUserGetClassLong(hWnd, nIndex, TRUE); + + return Ret; } /* @@ -291,80 +312,101 @@ GetClassLongW ( HWND hWnd, int nIndex ) if (!Wnd) return 0; - Class = DesktopPtrToUser(Wnd->Class); - ASSERT(Class != NULL); - - if (nIndex >= 0) + _SEH_TRY { - if (nIndex + sizeof(ULONG_PTR) < nIndex || - nIndex + sizeof(ULONG_PTR) > Class->ClsExtra) + Class = DesktopPtrToUser(Wnd->Class); + if (Class != NULL) { - SetLastError(ERROR_INVALID_PARAMETER); - return 0; + if (nIndex >= 0) + { + if (nIndex + sizeof(ULONG_PTR) < nIndex || + nIndex + sizeof(ULONG_PTR) > Class->ClsExtra) + { + SetLastError(ERROR_INVALID_PARAMETER); + } + else + Ret = *(PULONG_PTR)((ULONG_PTR)(Class + 1) + nIndex); + } + else + { + switch (nIndex) + { + case GCL_CBWNDEXTRA: + Ret = (ULONG_PTR)Class->WndExtra; + break; + + case GCL_CBCLSEXTRA: + Ret = (ULONG_PTR)Class->ClsExtra; + break; + + case GCL_HBRBACKGROUND: + Ret = (ULONG_PTR)Class->hbrBackground; + if (Ret != 0 && Ret < 0x4000) + Ret = (ULONG_PTR)GetSysColorBrush((ULONG)Ret - 1); + break; + + case GCL_HMODULE: + Ret = (ULONG_PTR)Class->hInstance; + break; + + case GCL_MENUNAME: + Ret = (ULONG_PTR)Class->MenuName; + break; + + case GCL_STYLE: + Ret = (ULONG_PTR)Class->Style; + break; + + case GCW_ATOM: + Ret = (ULONG_PTR)Class->Atom; + break; + + case GCLP_HCURSOR: + /* FIXME - get handle from pointer to CURSOR object */ + Ret = (ULONG_PTR)Class->hCursor; + break; + + case GCLP_HICON: + /* FIXME - get handle from pointer to ICON object */ + Ret = (ULONG_PTR)Class->hIcon; + break; + + case GCLP_HICONSM: + /* FIXME - get handle from pointer to ICON object */ + Ret = (ULONG_PTR)Class->hIconSm; + break; + + case GCLP_WNDPROC: + /* We need to make a call to win32k as it may be required to + create a callproc handle */ + Wnd = NULL; + break; + + default: + SetLastError(ERROR_INVALID_INDEX); + break; + } + } } - - Ret = *(PULONG_PTR)((ULONG_PTR)(Class + 1) + nIndex); - } - else - { - switch (nIndex) + else { - case GCL_CBWNDEXTRA: - Ret = (ULONG_PTR)Class->WndExtra; - break; + /* This is a race condition! Call win32k to make sure we're getting + the correct result */ + Wnd = NULL; /* Make sure we call NtUserGetClassLong */ - case GCL_CBCLSEXTRA: - Ret = (ULONG_PTR)Class->ClsExtra; - break; - - case GCL_HBRBACKGROUND: - Ret = (ULONG_PTR)Class->hbrBackground; - if (Ret != 0 && Ret < 0x4000) - Ret = (ULONG_PTR)GetSysColorBrush((ULONG)Ret - 1); - break; - - case GCL_HMODULE: - Ret = (ULONG_PTR)Class->hInstance; - break; - - case GCL_MENUNAME: - Ret = (ULONG_PTR)Class->MenuName; - break; - - case GCL_STYLE: - Ret = (ULONG_PTR)Class->Style; - break; - - case GCW_ATOM: - Ret = (ULONG_PTR)Class->Atom; - break; - - case GCLP_HCURSOR: - /* FIXME - get handle from pointer to CURSOR object */ - Ret = (ULONG_PTR)Class->hCursor; - break; - - case GCLP_HICON: - /* FIXME - get handle from pointer to ICON object */ - Ret = (ULONG_PTR)Class->hIcon; - break; - - case GCLP_HICONSM: - /* FIXME - get handle from pointer to ICON object */ - Ret = (ULONG_PTR)Class->hIconSm; - break; - - case GCLP_WNDPROC: - /* We need to make a call to win32k as it may be required to - create a callproc handle */ - return NtUserGetClassLong(hWnd, nIndex, FALSE); - - default: - SetLastError(ERROR_INVALID_INDEX); + WARN("Invalid class for hwnd 0x%p!\n", hWnd); } } + _SEH_HANDLE + { + Wnd = NULL; /* Make sure we call NtUserGetClassLong */ + } + _SEH_END; - return Ret; + if (Wnd == NULL) + Ret = NtUserGetClassLong(hWnd, nIndex, FALSE); + + return Ret; } diff --git a/reactos/dll/win32/user32/windows/window.c b/reactos/dll/win32/user32/windows/window.c index 897843e501c..321b2757407 100644 --- a/reactos/dll/win32/user32/windows/window.c +++ b/reactos/dll/win32/user32/windows/window.c @@ -1027,55 +1027,67 @@ GetWindowRect(HWND hWnd, int STDCALL GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount) { - PWINDOW Wnd; - PCWSTR Buffer; + PWINDOW Wnd; + PCWSTR Buffer; + INT Length = 0; - if (lpString == NULL) - return 0; + if (lpString == NULL) + return 0; - Wnd = ValidateHwnd(hWnd); - if (!Wnd) - return 0; + Wnd = ValidateHwnd(hWnd); + if (!Wnd) + return 0; - if (Wnd->pi != g_kpi) - { - INT Length; + _SEH_TRY + { + if (Wnd->pi != g_kpi) + { + if (nMaxCount > 0) + { + /* do not send WM_GETTEXT messages to other processes */ + Length = Wnd->WindowName.Length / sizeof(WCHAR); + if (Length != 0) + { + Buffer = DesktopPtrToUser(Wnd->WindowName.Buffer); + if (Buffer != NULL) + { + if (!WideCharToMultiByte(CP_ACP, + 0, + Buffer, + Length + 1, + lpString, + nMaxCount, + NULL, + NULL)) + { + lpString[nMaxCount - 1] = '\0'; + } + } + else + { + Length = 0; + lpString[0] = '\0'; + } + } + else + lpString[0] = '\0'; + } - if (nMaxCount <= 0) - return 0; + Wnd = NULL; /* Don't send a message */ + } + } + _SEH_HANDLE + { + lpString[0] = '\0'; + Length = 0; + Wnd = NULL; /* Don't send a message */ + } + _SEH_END; - /* do not send WM_GETTEXT messages to other processes */ - Length = Wnd->WindowName.Length / sizeof(WCHAR); - if (Length != 0) - { - Buffer = DesktopPtrToUser(Wnd->WindowName.Buffer); - if (Buffer != NULL) - { - if (!WideCharToMultiByte(CP_ACP, - 0, - Buffer, - Length + 1, - lpString, - nMaxCount, - NULL, - NULL)) - { - lpString[nMaxCount - 1] = '\0'; - } - } - else - { - Length = 0; - lpString[0] = '\0'; - } - } - else - lpString[0] = '\0'; + if (Wnd != NULL) + Length = SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString); - return (LRESULT)Length; - } - - return SendMessageA(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString); + return Length; } @@ -1105,47 +1117,59 @@ GetWindowTextLengthW(HWND hWnd) int STDCALL GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount) { - PWINDOW Wnd; - PCWSTR Buffer; + PWINDOW Wnd; + PCWSTR Buffer; + INT Length = 0; - if (lpString == NULL) - return 0; + if (lpString == NULL) + return 0; - Wnd = ValidateHwnd(hWnd); - if (!Wnd) - return 0; + Wnd = ValidateHwnd(hWnd); + if (!Wnd) + return 0; - if (Wnd->pi != g_kpi) - { - INT Length; + _SEH_TRY + { + if (Wnd->pi != g_kpi) + { + if (nMaxCount > 0) + { + /* do not send WM_GETTEXT messages to other processes */ + Length = Wnd->WindowName.Length / sizeof(WCHAR); + if (Length != 0) + { + Buffer = DesktopPtrToUser(Wnd->WindowName.Buffer); + if (Buffer != NULL) + { + RtlCopyMemory(lpString, + Buffer, + (Length + 1) * sizeof(WCHAR)); + } + else + { + Length = 0; + lpString[0] = '\0'; + } + } + else + lpString[0] = '\0'; + } - if (nMaxCount <= 0) - return 0; + Wnd = NULL; /* Don't send a message */ + } + } + _SEH_HANDLE + { + lpString[0] = '\0'; + Length = 0; + Wnd = NULL; /* Don't send a message */ + } + _SEH_END; - /* do not send WM_GETTEXT messages to other processes */ - Length = Wnd->WindowName.Length / sizeof(WCHAR); - if (Length != 0) - { - Buffer = DesktopPtrToUser(Wnd->WindowName.Buffer); - if (Buffer != NULL) - { - RtlCopyMemory(lpString, - Buffer, - (Length + 1) * sizeof(WCHAR)); - } - else - { - Length = 0; - lpString[0] = L'\0'; - } - } - else - lpString[0] = L'\0'; + if (Wnd != NULL) + Length = SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString); - return (LRESULT)Length; - } - - return SendMessageW(hWnd, WM_GETTEXT, nMaxCount, (LPARAM)lpString); + return Length; } DWORD STDCALL @@ -1187,9 +1211,7 @@ IsIconic(HWND hWnd) PWINDOW Wnd = ValidateHwnd(hWnd); if (Wnd != NULL) - { return (Wnd->Style & WS_MINIMIZE) != 0; - } return FALSE; }