Author: greatlrd
Date: Fri Apr 14 22:23:11 2006
New Revision: 21593
URL:
http://svn.reactos.ru/svn/reactos?rev=21593&view=rev
Log:
Bug 1391 : Commit w3seek patch for Some Ansi vs. Unicode fixes for window classes
Removed:
trunk/reactos/subsystems/win32/win32k/include/ssec.h
Modified:
trunk/reactos/dll/win32/user32/windows/message.c
trunk/reactos/include/reactos/win32k/ntuser.h
trunk/reactos/subsystems/win32/win32k/include/window.h
trunk/reactos/subsystems/win32/win32k/ntuser/class.c
trunk/reactos/subsystems/win32/win32k/ntuser/message.c
trunk/reactos/subsystems/win32/win32k/ntuser/window.c
Modified: trunk/reactos/dll/win32/user32/windows/message.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/user32/windows/me…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/message.c (original)
+++ trunk/reactos/dll/win32/user32/windows/message.c Fri Apr 14 22:23:11 2006
@@ -1014,8 +1014,9 @@
{
WNDPROC_INFO wpInfo;
+ /* FIXME - can the first parameter be NULL? */
if (lpPrevWndFunc == NULL)
- lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWLP_WNDPROC, FALSE);
+ lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWLP_WNDPROC, TRUE);
if (!NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
&wpInfo))
@@ -1041,6 +1042,10 @@
LPARAM lParam)
{
WNDPROC_INFO wpInfo;
+
+ /* FIXME - can the first parameter be NULL? */
+ if (lpPrevWndFunc == NULL)
+ lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWLP_WNDPROC, FALSE);
if (!NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
&wpInfo))
Modified: trunk/reactos/include/reactos/win32k/ntuser.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/include/reactos/win32k/ntus…
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntuser.h (original)
+++ trunk/reactos/include/reactos/win32k/ntuser.h Fri Apr 14 22:23:11 2006
@@ -14,7 +14,7 @@
{
struct _W32PROCESSINFO *pi;
WNDPROC WndProc;
- BOOL Unicode : 1;
+ UINT Unicode : 1;
} CALLPROC, *PCALLPROC;
typedef struct _WINDOWCLASS
@@ -46,10 +46,10 @@
ULONG_PTR ClassExtraDataOffset;
- BOOL Destroying : 1;
- BOOL Unicode : 1;
- BOOL System : 1;
- BOOL Global : 1;
+ UINT Destroying : 1;
+ UINT Unicode : 1;
+ UINT System : 1;
+ UINT Global : 1;
} WINDOWCLASS, *PWINDOWCLASS;
typedef struct _W32PROCESSINFO
Removed: trunk/reactos/subsystems/win32/win32k/include/ssec.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc…
==============================================================================
(empty)
Modified: trunk/reactos/subsystems/win32/win32k/include/window.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/window.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/window.h Fri Apr 14 22:23:11 2006
@@ -37,6 +37,9 @@
/* Extra Wnd proc (windows of system classes) */
WNDPROC WndProcExtra;
};
+ /* Pointer to another call procedure handle (used for returning the previous
+ window proc in SetWindowLongPtr) */
+ PCALLPROC CallProc2;
/* Indicates whether the window is derived from a system class */
BOOL IsSystem;
/* Pointer to the window class. */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/class.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/class.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/class.c Fri Apr 14 22:23:11 2006
@@ -89,7 +89,7 @@
{
NewCallProc->pi = pi;
NewCallProc->WndProc = WndProc;
- NewCallProc->Unicode = Unicode;
+ NewCallProc->Unicode = Unicode != FALSE;
}
return NewCallProc;
@@ -109,13 +109,11 @@
otCallProc);
if (CallProc == NULL)
{
- SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
if (CallProc->pi != GetW32ProcessInfo())
{
- SetLastWin32Error(ERROR_ACCESS_DENIED);
return FALSE;
}
@@ -323,16 +321,81 @@
}
static WNDPROC
+IntGetClassWndProc(IN PWINDOWCLASS Class,
+ IN PW32PROCESSINFO pi,
+ IN BOOL Ansi)
+{
+ /* FIXME - assert for exclusive lock! */
+
+ if (Class->System)
+ {
+ return (Ansi ? Class->WndProcExtra : Class->WndProc);
+ }
+ else
+ {
+ if (!Ansi == Class->Unicode)
+ {
+ return Class->WndProc;
+ }
+ else
+ {
+ if (Class->CallProc != NULL)
+ {
+ return (WNDPROC)ObmObjectToHandle(Class->CallProc);
+ }
+ else
+ {
+ PCALLPROC NewCallProc, CallProc;
+
+ if (pi == NULL)
+ return NULL;
+
+ /* NOTE: use the interlocked functions, as this operation may be done
even
+ when only the shared lock is held! */
+ NewCallProc = CreateCallProc(Class->Desktop,
+ Class->WndProc,
+ Class->Unicode,
+ pi);
+ if (NewCallProc == NULL)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+
+ CallProc = InterlockedCompareExchangePointer(&Class->CallProc,
+ NewCallProc,
+ NULL);
+ if (CallProc != NULL)
+ {
+ DestroyCallProc(Class->Desktop,
+ NewCallProc);
+ }
+
+ return (WNDPROC)ObmObjectToHandle((CallProc == NULL ? NewCallProc :
CallProc));
+ }
+ }
+ }
+}
+
+static WNDPROC
IntSetClassWndProc(IN OUT PWINDOWCLASS Class,
IN WNDPROC WndProc,
IN BOOL Ansi)
{
- WNDPROC Ret = Class->WndProc;
+ WNDPROC Ret;
if (Class->System)
{
DPRINT1("Attempted to change window procedure of system window class
0x%p!\n", Class->Atom);
SetLastWin32Error(ERROR_ACCESS_DENIED);
+ return NULL;
+ }
+
+ Ret = IntGetClassWndProc(Class,
+ GetW32ProcessInfo(),
+ Ansi);
+ if (Ret == NULL)
+ {
return NULL;
}
@@ -733,61 +796,6 @@
return Class;
}
-static WNDPROC
-IntGetClassWndProc(IN PWINDOWCLASS Class,
- IN PW32PROCESSINFO pi,
- IN BOOL Ansi)
-{
- if (Class->System)
- {
- return (Ansi ? Class->WndProcExtra : Class->WndProc);
- }
- else
- {
- if (!Ansi == Class->Unicode)
- {
- return Class->WndProc;
- }
- else
- {
- if (Class->CallProc != NULL)
- {
- return (WNDPROC)ObmObjectToHandle(Class->CallProc);
- }
- else
- {
- PCALLPROC NewCallProc, CallProc;
-
- if (pi == NULL)
- return NULL;
-
- /* NOTE: use the interlocked functions, as this operation may be done
even
- when only the shared lock is held! */
- NewCallProc = CreateCallProc(Class->Desktop,
- Class->WndProc,
- Class->Unicode,
- pi);
- if (NewCallProc == NULL)
- {
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- return NULL;
- }
-
- CallProc = InterlockedCompareExchangePointer(&Class->CallProc,
- NewCallProc,
- NULL);
- if (CallProc != NULL)
- {
- DestroyCallProc(Class->Desktop,
- NewCallProc);
- }
-
- return (WNDPROC)ObmObjectToHandle((CallProc == NULL ? NewCallProc :
CallProc));
- }
- }
- }
-}
-
RTL_ATOM
IntGetClassAtom(IN PUNICODE_STRING ClassName,
IN HINSTANCE hInstance OPTIONAL,
@@ -1760,22 +1768,9 @@
{
lpwcx->style = Class->Style;
- if (Class->System)
- {
- lpwcx->lpfnWndProc = (!Ansi ? Class->WndProc : Class->WndProcExtra);
- }
- else
- {
- if (!Ansi == Class->Unicode)
- {
- lpwcx->lpfnWndProc = Class->WndProc;
- }
- else
- {
- /* FIXME - return callproc handle or function pointer? */
- lpwcx->lpfnWndProc = Class->CallProc->WndProc;
- }
- }
+ lpwcx->lpfnWndProc = IntGetClassWndProc(Class,
+ GetW32ProcessInfo(),
+ Ansi);
lpwcx->cbClsExtra = Class->ClsExtra;
lpwcx->cbWndExtra = Class->WndExtra;
@@ -1917,7 +1912,14 @@
PWINDOW_OBJECT Window;
ULONG_PTR Ret = 0;
- UserEnterShared();
+ if (Offset != GCLP_WNDPROC)
+ {
+ UserEnterShared();
+ }
+ else
+ {
+ UserEnterExclusive();
+ }
Window = UserGetWindowObject(hWnd);
if (Window != NULL)
@@ -2090,7 +2092,9 @@
PW32PROCESSINFO pi;
BOOL Ret = FALSE;
- UserEnterShared();
+ /* NOTE: need exclusive lock because getting the wndproc might require the
+ creation of a call procedure handle */
+ UserEnterExclusive();
pi = GetW32ProcessInfo();
if (pi == NULL)
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/message.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/message.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/message.c Fri Apr 14 22:23:11 2006
@@ -380,7 +380,10 @@
Result = 0;
MsgInfo.Ansi = !Window->Unicode;
- MsgInfo.Proc = Window->WndProc;
+ if (Window->IsSystem)
+ MsgInfo.Proc = (Window->Unicode ? Window->WndProc :
Window->WndProcExtra);
+ else
+ MsgInfo.Proc = Window->WndProc;
}
}
}
@@ -1563,7 +1566,10 @@
}
Info.Ansi = !Window->Unicode;
- Info.Proc = Window->WndProc;
+ if (Window->IsSystem)
+ Info.Proc = (Window->Unicode ? Window->WndProc :
Window->WndProcExtra);
+ else
+ Info.Proc = Window->WndProc;
}
else
{
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/window.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/window.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/window.c Fri Apr 14 22:23:11 2006
@@ -438,6 +438,13 @@
{
DestroyCallProc(Window->ti->Desktop,
Window->CallProc);
+ }
+
+ if (Window->CallProc2 != NULL)
+ {
+ DbgPrint("!!!!! Destroy call proc 0x%p\n",
ObmObjectToHandle(Window->CallProc2));
+ DestroyCallProc(Window->ti->Desktop,
+ Window->CallProc2);
}
/* dereference the class */
@@ -1572,17 +1579,10 @@
Window->IsSystem = Class->System;
if (Class->System)
{
- Window->Unicode = bUnicodeWindow;
- if (bUnicodeWindow)
- {
- Window->WndProc = Class->WndProc;
- Window->WndProcExtra = Class->WndProcExtra;
- }
- else
- {
- Window->WndProc = Class->WndProcExtra;
- Window->WndProcExtra = Class->WndProc;
- }
+ /* NOTE: Always create a unicode window for system classes! */
+ Window->Unicode = TRUE;
+ Window->WndProc = Class->WndProc;
+ Window->WndProcExtra = Class->WndProcExtra;
}
else
{
@@ -3422,7 +3422,93 @@
END_CLEANUP;
}
-
+static WNDPROC
+IntSetWindowProc(PWINDOW_OBJECT Window,
+ WNDPROC NewWndProc,
+ BOOL Ansi)
+{
+ WNDPROC Ret;
+
+ /* attempt to get the previous window proc */
+ if (Window->IsSystem)
+ {
+ Ret = (Ansi ? Window->WndProcExtra : Window->WndProc);
+ }
+ else
+ {
+ if (!Ansi == Window->Unicode)
+ {
+ Ret = Window->WndProc;
+ }
+ else
+ {
+ /* allocate or update an existing call procedure handle to return
+ the old window proc */
+ if (Window->CallProc2 != NULL)
+ {
+ Window->CallProc2->WndProc = Window->WndProc;
+ Window->CallProc2->Unicode = Window->Unicode;
+ }
+ else
+ {
+ Window->CallProc2 = CreateCallProc(Window->ti->Desktop,
+ Window->WndProc,
+ Window->Unicode,
+ Window->ti->kpi);
+ if (Window->CallProc2 == NULL)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+ }
+
+ Ret = (WNDPROC)ObmObjectToHandle(Window->CallProc2);
+ DbgPrint("!!!!!!!! Returning handle 0x%p\n", Ret);
+ }
+ }
+
+ if (Window->Class->System)
+ {
+ BOOL SysWnd = Window->IsSystem;
+
+ /* check if the new procedure matches with the one in the
+ window class. If so, we need to restore both procedures! */
+ Window->IsSystem = (NewWndProc == Window->Class->WndProc ||
+ NewWndProc == Window->Class->WndProcExtra);
+
+ if (Window->IsSystem != SysWnd)
+ {
+ if (!Window->IsSystem && Window->CallProc != NULL)
+ {
+ /* destroy the callproc, we don't need it anymore */
+ DestroyCallProc(Window->ti->Desktop,
+ Window->CallProc);
+ Window->CallProc = NULL;
+ }
+ }
+
+ if (Window->IsSystem)
+ {
+ Window->WndProc = Window->Class->WndProc;
+ Window->WndProcExtra = Window->Class->WndProcExtra;
+ Window->Unicode = !Ansi;
+ return Ret;
+ }
+ }
+
+ ASSERT(!Window->IsSystem);
+
+ /* update the window procedure */
+ Window->WndProc = NewWndProc;
+ if (Window->CallProc != NULL)
+ {
+ Window->CallProc->WndProc = NewWndProc;
+ Window->CallProc->Unicode = !Ansi;
+ }
+ Window->Unicode = !Ansi;
+
+ return Ret;
+}
LONG FASTCALL
@@ -3490,24 +3576,9 @@
case GWL_WNDPROC:
{
/* FIXME: should check if window belongs to current process */
- if (Window->IsSystem)
- {
- /* the user changes the window procedure, the window is no longer
- directly derived from the system class, because it no longer
- uses independent window procedures for ansi and unicode */
- Window->IsSystem = FALSE;
- Window->CallProc = NULL;
- }
-
- /* update the window procedure */
- OldValue = (LONG)Window->WndProc;
- Window->WndProc = (WNDPROC)NewValue;
- if (Window->CallProc != NULL)
- {
- Window->CallProc->WndProc = (WNDPROC)NewValue;
- Window->CallProc->Unicode = !Ansi;
- }
- Window->Unicode = !Ansi;
+ OldValue = (LONG)IntSetWindowProc(Window,
+ (WNDPROC)NewValue,
+ Ansi);
break;
}