Author: peterw
Date: Wed Apr 5 12:05:55 2006
New Revision: 21460
URL:
http://svn.reactos.ru/svn/reactos?rev=21460&view=rev
Log:
Applied patch by: Thomas Weidenmueller
- win32k window class rewrite.
-
http://www.reactos.org/bugzilla/show_bug.cgi?id=1366
Added:
trunk/reactos/subsystems/win32/win32k/misc/usrheap.c
Modified:
trunk/reactos/dll/win32/user32/controls/regcontrol.c
trunk/reactos/dll/win32/user32/misc/misc.c
trunk/reactos/dll/win32/user32/windows/class.c
trunk/reactos/dll/win32/user32/windows/message.c
trunk/reactos/dll/win32/user32/windows/window.c
trunk/reactos/include/ndk/pstypes.h
trunk/reactos/include/reactos/probe.h
trunk/reactos/include/reactos/win32k/ntuser.h
trunk/reactos/lib/rtl/heap.c
trunk/reactos/subsystems/win32/win32k/include/class.h
trunk/reactos/subsystems/win32/win32k/include/desktop.h
trunk/reactos/subsystems/win32/win32k/include/object.h
trunk/reactos/subsystems/win32/win32k/include/userfuncs.h
trunk/reactos/subsystems/win32/win32k/include/win32.h
trunk/reactos/subsystems/win32/win32k/include/window.h
trunk/reactos/subsystems/win32/win32k/main/dllmain.c
trunk/reactos/subsystems/win32/win32k/misc/err.c
trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c
trunk/reactos/subsystems/win32/win32k/ntuser/class.c
trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c
trunk/reactos/subsystems/win32/win32k/ntuser/hook.c
trunk/reactos/subsystems/win32/win32k/ntuser/menu.c
trunk/reactos/subsystems/win32/win32k/ntuser/message.c
trunk/reactos/subsystems/win32/win32k/ntuser/misc.c
trunk/reactos/subsystems/win32/win32k/ntuser/monitor.c
trunk/reactos/subsystems/win32/win32k/ntuser/object.c
trunk/reactos/subsystems/win32/win32k/ntuser/windc.c
trunk/reactos/subsystems/win32/win32k/ntuser/window.c
trunk/reactos/subsystems/win32/win32k/w32k.h
trunk/reactos/subsystems/win32/win32k/win32k.rbuild
trunk/reactos/tools/nci/w32ksvc.db
Modified: trunk/reactos/dll/win32/user32/controls/regcontrol.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/user32/controls/r…
==============================================================================
--- trunk/reactos/dll/win32/user32/controls/regcontrol.c (original)
+++ trunk/reactos/dll/win32/user32/controls/regcontrol.c Wed Apr 5 12:05:55 2006
@@ -44,15 +44,13 @@
RtlInitUnicodeString(&ClassName, Descr->name);
}
- NtUserRegisterClassExWOW(
+ NtUserRegisterClassEx(
&wc,
- &ClassName,
&ClassName,
&MenuName,
Descr->procA,
REGISTERCLASS_SYSTEM,
- 0,
- 0);
+ NULL);
}
/***********************************************************************
Modified: trunk/reactos/dll/win32/user32/misc/misc.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/user32/misc/misc.…
==============================================================================
--- trunk/reactos/dll/win32/user32/misc/misc.c (original)
+++ trunk/reactos/dll/win32/user32/misc/misc.c Wed Apr 5 12:05:55 2006
@@ -113,3 +113,34 @@
{
return NtUserUpdatePerUserSystemParameters(dwReserved, bEnable);
}
+
+PW32THREADINFO
+GetW32ThreadInfo(VOID)
+{
+ PW32THREADINFO ti;
+
+ ti = (PW32THREADINFO)NtCurrentTeb()->Win32ThreadInfo;
+ if (ti == NULL)
+ {
+ /* create the W32THREADINFO structure */
+ NtUserGetThreadState(THREADSTATE_GETTHREADINFO);
+ ti = (PW32THREADINFO)NtCurrentTeb()->Win32ThreadInfo;
+ }
+
+ return ti;
+}
+
+PW32PROCESSINFO
+GetW32ProcessInfo(VOID)
+{
+ PW32THREADINFO ti;
+ PW32PROCESSINFO pi = NULL;
+
+ ti = GetW32ThreadInfo();
+ if (ti != NULL)
+ {
+ pi = ti->pi;
+ }
+
+ return pi;
+}
Modified: trunk/reactos/dll/win32/user32/windows/class.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/user32/windows/cl…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/class.c (original)
+++ trunk/reactos/dll/win32/user32/windows/class.c Wed Apr 5 12:05:55 2006
@@ -11,117 +11,6 @@
#include <user32.h>
-static BOOL GetClassInfoExCommon(
- HINSTANCE hInst,
- LPCWSTR lpszClass,
- LPWNDCLASSEXW lpwcx,
- BOOL unicode)
-{
- LPWSTR str;
- UNICODE_STRING str2, str3;
- WNDCLASSEXW w;
- BOOL retval;
- NTSTATUS Status;
-
- if ( !lpszClass || !lpwcx )
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- if(IS_ATOM(lpszClass))
- str = (LPWSTR)lpszClass;
- else
- {
- extern BOOL ControlsInitialized;
-
- if (unicode)
- {
- str = HEAP_strdupW ( lpszClass, wcslen(lpszClass) );
-
- if ( !str )
- {
- SetLastError (ERROR_OUTOFMEMORY);
- return FALSE;
- }
- }
-
- else
- {
- Status = HEAP_strdupAtoW(&str, (LPCSTR)lpszClass, NULL);
-
- if (! NT_SUCCESS(Status))
- {
- SetLastError(RtlNtStatusToDosError(Status));
- return FALSE;
- }
- }
-
- /* Register built-in controls if not already done */
- if ( !ControlsInitialized )
- {
- ControlsInitialized = ControlsInit(str);
- }
- }
-
- str2.Length = str3.Length = 0;
- str2.MaximumLength = str3.MaximumLength = 255;
- str2.Buffer = (PWSTR)HEAP_alloc ( str2.MaximumLength * sizeof(WCHAR) );
- if ( !str2.Buffer )
- {
- SetLastError (ERROR_OUTOFMEMORY);
- if ( !IS_ATOM(str) )
- HEAP_free ( str );
- return FALSE;
- }
-
- str3.Buffer = (PWSTR)HEAP_alloc ( str3.MaximumLength * sizeof(WCHAR) );
- if ( !str3.Buffer )
- {
- SetLastError (ERROR_OUTOFMEMORY);
- HEAP_free ( str2.Buffer );
- if ( !IS_ATOM(str) )
- HEAP_free ( str );
- return FALSE;
- }
-
- w.lpszMenuName = (LPCWSTR)&str2;
- w.lpszClassName = (LPCWSTR)&str3;
-
- /* get info about system classes? */
- if (!hInst) hInst = User32Instance;
-
- retval = (BOOL)NtUserGetClassInfo(hInst, str, &w, TRUE, 0);
-
- w.hInstance = (hInst == User32Instance) ? 0 : hInst;
-
- if ( !IS_ATOM(str) )
- HEAP_free(str);
-
- RtlCopyMemory ( lpwcx, &w, sizeof(WNDCLASSEXW) );
-
- if ( !IS_INTRESOURCE(w.lpszMenuName) && w.lpszMenuName )
- {
- if (unicode)
- lpwcx->lpszMenuName = heap_string_poolW ( str2.Buffer, str2.Length );
- else
- ((LPWNDCLASSEXA) lpwcx)->lpszMenuName = heap_string_poolA ( str2.Buffer,
str2.Length );
- }
-
- if ( !IS_ATOM(w.lpszClassName) && w.lpszClassName )
- {
- if (unicode)
- lpwcx->lpszClassName = heap_string_poolW ( str3.Buffer, str3.Length );
- else
- ((LPWNDCLASSEXA) lpwcx)->lpszClassName = heap_string_poolA ( str3.Buffer,
str3.Length );
- }
-
- HEAP_free ( str2.Buffer );
- HEAP_free ( str3.Buffer );
-
- return retval;
-}
-
/*
* @implemented
@@ -133,7 +22,40 @@
LPCSTR lpszClass,
LPWNDCLASSEXA lpwcx)
{
- return GetClassInfoExCommon(hinst, (LPWSTR)lpszClass, (LPWNDCLASSEXW)lpwcx, FALSE);
+ UNICODE_STRING ClassName = {0};
+ BOOL Ret;
+
+ if (lpszClass == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (IS_ATOM(lpszClass))
+ {
+ ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
+ }
+ else
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&ClassName,
+ lpszClass))
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+ }
+
+ Ret = NtUserGetClassInfo(hinst,
+ &ClassName,
+ (LPWNDCLASSEXW)lpwcx,
+ TRUE);
+
+ if (!IS_ATOM(lpszClass))
+ {
+ RtlFreeUnicodeString(&ClassName);
+ }
+
+ return Ret;
}
@@ -147,7 +69,28 @@
LPCWSTR lpszClass,
LPWNDCLASSEXW lpwcx)
{
- return GetClassInfoExCommon(hinst, lpszClass, lpwcx, TRUE);
+ UNICODE_STRING ClassName = {0};
+
+ if (lpszClass == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (IS_ATOM(lpszClass))
+ {
+ ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
+ }
+ else
+ {
+ RtlInitUnicodeString(&ClassName,
+ lpszClass);
+ }
+
+ return NtUserGetClassInfo(hinst,
+ &ClassName,
+ lpwcx,
+ FALSE);
}
@@ -170,6 +113,7 @@
return FALSE;
}
+ w.cbSize = sizeof(w);
retval = GetClassInfoExA(hInstance,lpClassName,&w);
if (retval)
{
@@ -197,8 +141,12 @@
return FALSE;
}
+ w.cbSize = sizeof(w);
retval = GetClassInfoExW(hInstance,lpClassName,&w);
- RtlCopyMemory (lpWndClass,&w.style,sizeof(WNDCLASSW));
+ if (retval)
+ {
+ RtlCopyMemory (lpWndClass,&w.style,sizeof(WNDCLASSW));
+ }
return retval;
}
@@ -275,25 +223,14 @@
LPSTR lpClassName,
int nMaxCount)
{
- int result;
- LPWSTR ClassNameW;
- NTSTATUS Status;
-
- if(!lpClassName)
- return 0;
-
- ClassNameW = HEAP_alloc ( (nMaxCount+1)*sizeof(WCHAR) );
-
- result = NtUserGetClassName ( hWnd, ClassNameW, nMaxCount );
-
- Status = HEAP_strcpyWtoA ( lpClassName, ClassNameW, result );
-
- HEAP_free ( ClassNameW );
-
- if ( !NT_SUCCESS(Status) )
- return 0;
-
- return result;
+ ANSI_STRING ClassName;
+
+ ClassName.MaximumLength = nMaxCount;
+ ClassName.Buffer = lpClassName;
+
+ return NtUserGetClassName(hWnd,
+ (PUNICODE_STRING)&ClassName,
+ TRUE);
}
@@ -307,7 +244,14 @@
LPWSTR lpClassName,
int nMaxCount)
{
- return NtUserGetClassName(hWnd, lpClassName, nMaxCount);
+ UNICODE_STRING ClassName;
+
+ ClassName.MaximumLength = nMaxCount;
+ ClassName.Buffer = lpClassName;
+
+ return NtUserGetClassName(hWnd,
+ &ClassName,
+ FALSE);
}
@@ -573,8 +517,8 @@
RTL_ATOM Atom;
WNDCLASSEXA WndClass;
UNICODE_STRING ClassName;
- UNICODE_STRING MenuName;
- HMENU hMenu;
+ UNICODE_STRING MenuName = {0};
+ HMENU hMenu = NULL;
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXA) ||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
@@ -609,16 +553,17 @@
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
}
- if HIWORD(lpwcx->lpszMenuName)
- {
- hMenu = 0;
- RtlCreateUnicodeStringFromAsciiz(&MenuName, WndClass.lpszMenuName);
- }
- else
- {
- MenuName.Length =
- MenuName.MaximumLength = 0;
- MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
+ if (lpwcx->lpszMenuName != NULL)
+ {
+ if (HIWORD(lpwcx->lpszMenuName))
+ {
+ RtlCreateUnicodeStringFromAsciiz(&MenuName, WndClass.lpszMenuName);
+ }
+ else
+ {
+ MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
+ }
+
hMenu = LoadMenuA(WndClass.hInstance, lpwcx->lpszMenuName);
}
@@ -627,20 +572,18 @@
ClassName.Length =
ClassName.MaximumLength = 0;
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
- } else
+ }
+ else
{
RtlCreateUnicodeStringFromAsciiz(&ClassName, WndClass.lpszClassName);
}
- Atom = NtUserRegisterClassExWOW(
- (WNDCLASSEXW*)&WndClass,
- &ClassName,
- &ClassName,
- &MenuName,
- NULL,
- REGISTERCLASS_ANSI,
- 0,
- hMenu);
+ Atom = NtUserRegisterClassEx((WNDCLASSEXW*)&WndClass,
+ &ClassName,
+ &MenuName,
+ NULL,
+ REGISTERCLASS_ANSI,
+ hMenu);
if (!IS_ATOM(WndClass.lpszMenuName))
RtlFreeUnicodeString(&MenuName);
@@ -658,8 +601,8 @@
{
WNDCLASSEXW WndClass;
UNICODE_STRING ClassName;
- UNICODE_STRING MenuName;
- HMENU hMenu;
+ UNICODE_STRING MenuName = {0};
+ HMENU hMenu = NULL;
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
@@ -694,16 +637,16 @@
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
}
- if HIWORD(lpwcx->lpszMenuName)
- {
- hMenu = 0;
- RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
- }
- else
- {
- MenuName.Length =
- MenuName.MaximumLength = 0;
- MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
+ if (lpwcx->lpszMenuName != NULL)
+ {
+ if (HIWORD(lpwcx->lpszMenuName))
+ {
+ RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
+ }
+ else
+ {
+ MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
+ }
hMenu = LoadMenuW(WndClass.hInstance, lpwcx->lpszMenuName);
}
@@ -712,20 +655,18 @@
ClassName.Length =
ClassName.MaximumLength = 0;
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
- } else
+ }
+ else
{
RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
}
- return (ATOM)NtUserRegisterClassExWOW(
- &WndClass,
- &ClassName,
- &ClassName,
- &MenuName,
- NULL,
- 0,
- 0,
- hMenu);
+ return (ATOM)NtUserRegisterClassEx(&WndClass,
+ &ClassName,
+ &MenuName,
+ NULL,
+ 0,
+ hMenu);
}
/*
@@ -769,42 +710,65 @@
*/
DWORD
STDCALL
-SetClassLongA (
- HWND hWnd,
- int nIndex,
- LONG dwNewLong)
-{
- UNICODE_STRING str2buf;
- PUNICODE_STRING str;
- PUNICODE_STRING str2 = &str2buf;
-
- if ( nIndex != GCL_MENUNAME )
- {
- return NtUserSetClassLong ( hWnd, nIndex, dwNewLong, TRUE );
- }
- if ( IS_INTRESOURCE(dwNewLong) )
- {
- str2 = (PUNICODE_STRING)dwNewLong;
- }
- else
- {
- RtlCreateUnicodeStringFromAsciiz ( &str2buf,(LPSTR)dwNewLong );
- }
-
- str = (PUNICODE_STRING)NtUserSetClassLong(hWnd, nIndex, (DWORD)str2, TRUE);
-
- if ( !IS_INTRESOURCE(dwNewLong) )
- {
- RtlFreeUnicodeString ( str2 );
- }
- if ( IS_INTRESOURCE(str) )
- {
- return (DWORD)str;
- }
- else
- {
- return (DWORD)heap_string_poolA ( str->Buffer, str->Length );
- }
+SetClassLongA (HWND hWnd,
+ int nIndex,
+ LONG dwNewLong)
+{
+ PSTR lpStr = (PSTR)dwNewLong;
+ UNICODE_STRING Value = {0};
+ BOOL Allocated = FALSE;
+ DWORD Ret;
+
+ /* FIXME - portability!!!! */
+
+ if (nIndex == GCL_MENUNAME && lpStr != NULL)
+ {
+ if (!IS_INTRESOURCE(lpStr))
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&Value,
+ lpStr))
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return 0;
+ }
+
+ Allocated = TRUE;
+ }
+ else
+ Value.Buffer = (PWSTR)lpStr;
+
+ dwNewLong = (LONG)&Value;
+ }
+ else if (nIndex == GCW_ATOM && lpStr != NULL)
+ {
+ if (!IS_ATOM(lpStr))
+ {
+ if (!RtlCreateUnicodeStringFromAsciiz(&Value,
+ lpStr))
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return 0;
+ }
+
+ Allocated = TRUE;
+ }
+ else
+ Value.Buffer = (PWSTR)lpStr;
+
+ dwNewLong = (LONG)&Value;
+ }
+
+ Ret = (DWORD)NtUserSetClassLong(hWnd,
+ nIndex,
+ dwNewLong,
+ TRUE);
+
+ if (Allocated)
+ {
+ RtlFreeUnicodeString(&Value);
+ }
+
+ return Ret;
}
@@ -813,42 +777,44 @@
*/
DWORD
STDCALL
-SetClassLongW(
- HWND hWnd,
- int nIndex,
- LONG dwNewLong)
-{
- UNICODE_STRING str2buf;
- PUNICODE_STRING str;
- PUNICODE_STRING str2 = &str2buf;
-
- if (nIndex != GCL_MENUNAME )
- {
- return NtUserSetClassLong ( hWnd, nIndex, dwNewLong, FALSE );
- }
- if ( IS_INTRESOURCE(dwNewLong) )
- {
- str2 = (PUNICODE_STRING)dwNewLong;
- }
- else
- {
- RtlCreateUnicodeString ( &str2buf, (LPWSTR)dwNewLong );
- }
-
- str = (PUNICODE_STRING)NtUserSetClassLong(hWnd, nIndex, (DWORD)str2, TRUE);
-
- if ( !IS_INTRESOURCE(dwNewLong) )
- {
- RtlFreeUnicodeString(str2);
- }
- if ( IS_INTRESOURCE(str) )
- {
- return (DWORD)str;
- }
- else
- {
- return (DWORD)heap_string_poolW ( str->Buffer, str->Length );
- }
+SetClassLongW(HWND hWnd,
+ int nIndex,
+ LONG dwNewLong)
+{
+ PWSTR lpStr = (PWSTR)dwNewLong;
+ UNICODE_STRING Value = {0};
+
+ /* FIXME - portability!!!! */
+
+ if (nIndex == GCL_MENUNAME && lpStr != NULL)
+ {
+ if (!IS_INTRESOURCE(lpStr))
+ {
+ RtlInitUnicodeString(&Value,
+ lpStr);
+ }
+ else
+ Value.Buffer = lpStr;
+
+ dwNewLong = (LONG)&Value;
+ }
+ else if (nIndex == GCW_ATOM && lpStr != NULL)
+ {
+ if (!IS_ATOM(lpStr))
+ {
+ RtlInitUnicodeString(&Value,
+ lpStr);
+ }
+ else
+ Value.Buffer = lpStr;
+
+ dwNewLong = (LONG)&Value;
+ }
+
+ return (DWORD)NtUserSetClassLong(hWnd,
+ nIndex,
+ dwNewLong,
+ FALSE);
}
@@ -868,7 +834,7 @@
if ((nIndex < 0) && (nIndex != GCW_ATOM))
return 0;
- return (WORD) NtUserSetClassLong ( hWnd, nIndex, wNewWord, TRUE );
+ return (WORD) SetClassLongW ( hWnd, nIndex, wNewWord );
}
@@ -909,28 +875,32 @@
LPCSTR lpClassName,
HINSTANCE hInstance)
{
- LPWSTR ClassName;
- NTSTATUS Status;
- BOOL Result;
-
- if(!IS_ATOM(lpClassName))
- {
- Status = HEAP_strdupAtoW(&ClassName, lpClassName, NULL);
- if(!NT_SUCCESS(Status))
- {
- SetLastError(RtlNtStatusToDosError(Status));
- return FALSE;
- }
- }
- else
- ClassName = (LPWSTR)lpClassName;
-
- Result = (BOOL)NtUserUnregisterClass((LPCWSTR)ClassName, hInstance, 0);
-
- if(ClassName && !IS_ATOM(lpClassName))
- HEAP_free(ClassName);
-
- return Result;
+ UNICODE_STRING ClassName = {0};
+ NTSTATUS Status;
+ BOOL Ret;
+
+ if (!IS_ATOM(lpClassName))
+ {
+ Status = HEAP_strdupAtoW(&ClassName.Buffer, lpClassName, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ RtlInitUnicodeString(&ClassName,
+ ClassName.Buffer);
+ }
+ else
+ ClassName.Buffer = (PWSTR)((ULONG_PTR)lpClassName);
+
+ Ret = NtUserUnregisterClass(&ClassName,
+ hInstance);
+
+ if(!IS_ATOM(lpClassName) && ClassName.Buffer != NULL)
+ HEAP_free(ClassName.Buffer);
+
+ return Ret;
}
@@ -943,7 +913,18 @@
LPCWSTR lpClassName,
HINSTANCE hInstance)
{
- return (BOOL)NtUserUnregisterClass(lpClassName, hInstance, 0);
+ UNICODE_STRING ClassName = {0};
+
+ if (!IS_ATOM(lpClassName))
+ {
+ RtlInitUnicodeString(&ClassName,
+ lpClassName);
+ }
+ else
+ ClassName.Buffer = (PWSTR)((ULONG_PTR)lpClassName);
+
+ return NtUserUnregisterClass(&ClassName,
+ hInstance);
}
/* EOF */
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 Wed Apr 5 12:05:55 2006
@@ -951,6 +951,7 @@
return FALSE;
}
Result = WndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam);
+
if (! MsgiUnicodeToAnsiReply(&AnsiMsg, &UnicodeMsg, &Result))
{
return FALSE;
@@ -991,6 +992,7 @@
}
Result = WndProc(UnicodeMsg.hwnd, UnicodeMsg.message,
UnicodeMsg.wParam, UnicodeMsg.lParam);
+
if (! MsgiAnsiToUnicodeReply(&UnicodeMsg, &AnsiMsg, &Result))
{
return FALSE;
@@ -1010,20 +1012,19 @@
WPARAM wParam,
LPARAM lParam)
{
- BOOL IsHandle;
- WndProcHandle wphData;
+ WNDPROC_INFO wpInfo;
if (lpPrevWndFunc == NULL)
- lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWL_WNDPROC, FALSE);
-
- IsHandle = NtUserDereferenceWndProcHandle(lpPrevWndFunc,&wphData);
- if (! IsHandle)
+ lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWLP_WNDPROC, FALSE);
+
+ if (!NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
+ &wpInfo))
{
return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
}
else
{
- return IntCallWindowProcA(! wphData.IsUnicode, wphData.WindowProc,
+ return IntCallWindowProcA(!wpInfo.IsUnicode, wpInfo.WindowProc,
hWnd, Msg, wParam, lParam);
}
}
@@ -1039,17 +1040,16 @@
WPARAM wParam,
LPARAM lParam)
{
- BOOL IsHandle;
- WndProcHandle wphData;
-
- IsHandle = NtUserDereferenceWndProcHandle(lpPrevWndFunc,&wphData);
- if (! IsHandle)
+ WNDPROC_INFO wpInfo;
+
+ if (!NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
+ &wpInfo))
{
return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
}
else
{
- return IntCallWindowProcW(! wphData.IsUnicode, wphData.WindowProc,
+ return IntCallWindowProcW(!wpInfo.IsUnicode, wpInfo.WindowProc,
hWnd, Msg, wParam, lParam);
}
}
Modified: trunk/reactos/dll/win32/user32/windows/window.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/dll/win32/user32/windows/wi…
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/window.c (original)
+++ trunk/reactos/dll/win32/user32/windows/window.c Wed Apr 5 12:05:55 2006
@@ -289,8 +289,8 @@
{
wce.cbSize = sizeof(WNDCLASSEXW);
if(GetClassInfoExW(hInstance, lpClassName, &wce) && wce.lpszMenuName)
- {
- hMenu = LoadMenuW(hInstance, wce.lpszMenuName);
+ {DbgPrint("LoadingMenu 0x%p %d\n", wce.lpszMenuName,
IS_INTRESOURCE(wce.lpszMenuName));
+ hMenu = LoadMenuW(hInstance, wce.lpszMenuName);DbgPrint("Loaded menu:
0x%p\n", hMenu);
}
}
@@ -1449,7 +1449,7 @@
STDCALL
GetFocus(VOID)
{
- return (HWND)NtUserGetThreadState(0);
+ return (HWND)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW);
}
/*
Modified: trunk/reactos/include/ndk/pstypes.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/include/ndk/pstypes.h?rev=2…
==============================================================================
--- trunk/reactos/include/ndk/pstypes.h (original)
+++ trunk/reactos/include/ndk/pstypes.h Wed Apr 5 12:05:55 2006
@@ -424,7 +424,7 @@
ULONG LastErrorValue; /* 34h */
ULONG CountOfOwnedCriticalSections; /* 38h */
PVOID CsrClientThread; /* 3Ch */
- struct _W32THREAD* Win32ThreadInfo; /* 40h */
+ PVOID Win32ThreadInfo; /* 40h */
ULONG User32Reserved[0x1A]; /* 44h */
ULONG UserReserved[5]; /* ACh */
PVOID WOW32Reserved; /* C0h */
Modified: trunk/reactos/include/reactos/probe.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/include/reactos/probe.h?rev…
==============================================================================
--- trunk/reactos/include/reactos/probe.h (original)
+++ trunk/reactos/include/reactos/probe.h Wed Apr 5 12:05:55 2006
@@ -8,6 +8,14 @@
static const UNICODE_STRING __emptyUnicodeString = {0};
static const LARGE_INTEGER __emptyLargeInteger = {{0, 0}};
static const ULARGE_INTEGER __emptyULargeInteger = {{0, 0}};
+
+#if defined(_WIN32K_)
+/*
+ * NOTE: NTOSKRNL unfortunately doesn't export RtlRaiseStatus!
+ */
+VOID NTAPI W32kRaiseStatus(NTSTATUS Status);
+#define RtlRaiseStatus W32kRaiseStatus
+#endif
/*
* NOTE: Alignment of the pointers is not verified!
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 Wed Apr 5 12:05:55 2006
@@ -1,6 +1,75 @@
#ifndef __WIN32K_NTUSER_H
#define __WIN32K_NTUSER_H
+struct _W32PROCESSINFO;
+struct _W32THREADINFO;
+
+typedef struct _DESKTOP
+{
+ HANDLE hKernelHeap;
+ WCHAR szDesktopName[1];
+} DESKTOP, *PDESKTOP;
+
+typedef struct _CALLPROC
+{
+ struct _W32PROCESSINFO *pi;
+ WNDPROC WndProc;
+ BOOL Unicode : 1;
+} CALLPROC, *PCALLPROC;
+
+typedef struct _WINDOWCLASS
+{
+ struct _WINDOWCLASS *Next;
+ struct _WINDOWCLASS *Clone;
+ struct _WINDOWCLASS *Base;
+ PDESKTOP Desktop;
+ RTL_ATOM Atom;
+ ULONG Windows;
+
+ UINT Style;
+ WNDPROC WndProc;
+ union
+ {
+ WNDPROC WndProcExtra;
+ PCALLPROC CallProc;
+ };
+ INT ClsExtra;
+ INT WndExtra;
+ HINSTANCE hInstance;
+ HANDLE hIcon; /* FIXME - Use pointer! */
+ HANDLE hIconSm; /* FIXME - Use pointer! */
+ HANDLE hCursor; /* FIXME - Use pointer! */
+ HBRUSH hbrBackground;
+ HANDLE hMenu; /* FIXME - Use pointer! */
+ PWSTR MenuName;
+ PSTR AnsiMenuName;
+
+ ULONG_PTR ClassExtraDataOffset;
+
+ BOOL Destroying : 1;
+ BOOL Unicode : 1;
+ BOOL System : 1;
+ BOOL Global : 1;
+} WINDOWCLASS, *PWINDOWCLASS;
+
+typedef struct _W32PROCESSINFO
+{
+ PVOID UserHandleTable;
+ PWINDOWCLASS LocalClassList;
+ PWINDOWCLASS GlobalClassList;
+ PWINDOWCLASS SystemClassList;
+} W32PROCESSINFO, *PW32PROCESSINFO;
+
+typedef struct _W32THREADINFO
+{
+ PW32PROCESSINFO pi; /* [USER] */
+ PW32PROCESSINFO kpi; /* [KERNEL] */
+ PDESKTOP Desktop;
+ ULONG_PTR DesktopHeapDelta;
+} W32THREADINFO, *PW32THREADINFO;
+
+PW32THREADINFO GetW32ThreadInfo(VOID);
+PW32PROCESSINFO GetW32ProcessInfo(VOID);
DWORD
NTAPI
@@ -196,8 +265,8 @@
ULONG NTAPI
NtUserGetSystemMetrics(ULONG Index);
-DWORD NTAPI
-NtUserGetClassLong(HWND hWnd, DWORD Offset, BOOL Ansi);
+ULONG_PTR NTAPI
+NtUserGetClassLong(HWND hWnd, INT Offset, BOOL Ansi);
LONG NTAPI
NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi);
@@ -785,18 +854,17 @@
NtUserGetCaretPos(
LPPOINT lpPoint);
-DWORD NTAPI
-NtUserGetClassInfo(HINSTANCE hInst,
- LPCWSTR str,
+BOOL NTAPI
+NtUserGetClassInfo(HINSTANCE hInstance,
+ PUNICODE_STRING ClassName,
LPWNDCLASSEXW wcex,
- BOOL Ansi,
- DWORD unknown3);
-
-DWORD
+ BOOL Ansi);
+
+INT
NTAPI
NtUserGetClassName(HWND hWnd,
- LPWSTR lpClassName,
- ULONG nMaxCount);
+ PUNICODE_STRING ClassName,
+ BOOL Ansi);
HANDLE
NTAPI
@@ -1041,6 +1109,7 @@
DWORD dwThreadId,
DWORD Unknown1);
+#define THREADSTATE_GETTHREADINFO (0)
#define THREADSTATE_FOCUSWINDOW (1)
#define THREADSTATE_INSENDMESSAGE (2)
DWORD
@@ -1355,14 +1424,12 @@
#define REGISTERCLASS_ALL (REGISTERCLASS_ANSI | REGISTERCLASS_SYSTEM)
RTL_ATOM NTAPI
-NtUserRegisterClassExWOW(
+NtUserRegisterClassEx(
CONST WNDCLASSEXW* lpwcx,
PUNICODE_STRING ClassName,
- PUNICODE_STRING ClassNameCopy,
PUNICODE_STRING MenuName,
WNDPROC wpExtra,
DWORD Flags,
- DWORD Unknown7,
HMENU hMenu);
BOOL
@@ -1470,11 +1537,11 @@
HWND NTAPI
NtUserGetCapture(VOID);
-DWORD NTAPI
+ULONG_PTR NTAPI
NtUserSetClassLong(
HWND hWnd,
- DWORD Offset,
- LONG dwNewLong,
+ INT Offset,
+ ULONG_PTR dwNewLong,
BOOL Ansi );
@@ -1840,9 +1907,8 @@
BOOL
NTAPI
NtUserUnregisterClass(
- LPCWSTR ClassNameOrAtom,
- HINSTANCE hInstance,
- DWORD Unknown);
+ PUNICODE_STRING ClassNameOrAtom,
+ HINSTANCE hInstance);
BOOL
NTAPI
@@ -1951,15 +2017,15 @@
HWND NTAPI
NtUserGetLastActivePopup(HWND hWnd);
-typedef struct _WndProcHandle
+
+typedef struct _WNDPROC_INFO
{
- WNDPROC WindowProc;
- BOOL IsUnicode;
- HANDLE ProcessID;
-} WndProcHandle;
+ WNDPROC WindowProc;
+ BOOL IsUnicode;
+} WNDPROC_INFO, *PWNDPROC_INFO;
-DWORD NTAPI
-NtUserDereferenceWndProcHandle(WNDPROC wpHandle, WndProcHandle *Data);
+BOOL NTAPI
+NtUserDereferenceWndProcHandle(IN HANDLE wpHandle, OUT PWNDPROC_INFO wpInfo);
VOID NTAPI
NtUserManualGuiCheck(LONG Check);
Modified: trunk/reactos/lib/rtl/heap.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/lib/rtl/heap.c?rev=21460&am…
==============================================================================
--- trunk/reactos/lib/rtl/heap.c (original)
+++ trunk/reactos/lib/rtl/heap.c Wed Apr 5 12:05:55 2006
@@ -311,7 +311,7 @@
}
else
{
- Status = NtAllocateVirtualMemory(NtCurrentProcess(),
+ Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
&address,
0,
&commitsize,
@@ -570,13 +570,24 @@
/* Initialize critical section */
- RtlInitializeHeapLock( &heap->critSection );
+ if (RtlpGetMode() == UserMode)
+ {
+ RtlInitializeHeapLock( &heap->critSection );
+ }
}
/* Commit memory */
if (heap->commitRoutine)
{
- Status = heap->commitRoutine(heap, &address, &commitSize);
+ if (subheap != (SUBHEAP *)heap)
+ {
+ Status = heap->commitRoutine(heap, &address, &commitSize);
+ }
+ else
+ {
+ /* the caller is responsible for committing the first page! */
+ Status = STATUS_SUCCESS;
+ }
}
else
{
Modified: trunk/reactos/subsystems/win32/win32k/include/class.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/class.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/class.h Wed Apr 5 12:05:55 2006
@@ -4,28 +4,19 @@
#define IS_ATOM(x) \
(((ULONG_PTR)(x) > 0x0) && ((ULONG_PTR)(x) < 0x10000))
-typedef struct _WNDCLASS_OBJECT
-{
- UINT cbSize;
- LONG refs; /* windows using this class (is 0 after class creation)
*/
- UINT style;
- WNDPROC lpfnWndProcA;
- WNDPROC lpfnWndProcW;
- int cbClsExtra;
- int cbWndExtra;
- HANDLE hInstance;
- HICON hIcon;
- HCURSOR hCursor;
- HBRUSH hbrBackground;
- HMENU hMenu;
- UNICODE_STRING lpszMenuName;
- RTL_ATOM Atom;
- HICON hIconSm;
- BOOL Unicode;
- BOOL Global;
- LIST_ENTRY ListEntry; /* linked into owning process */
- PCHAR ExtraData;
-} WNDCLASS_OBJECT, *PWNDCLASS_OBJECT;
+VOID
+DestroyCallProc(IN PDESKTOP Desktop,
+ IN OUT PCALLPROC CallProc);
+
+PCALLPROC
+CloneCallProc(IN PDESKTOP Desktop,
+ IN PCALLPROC CallProc);
+
+PCALLPROC
+CreateCallProc(IN PDESKTOP Desktop,
+ IN WNDPROC WndProc,
+ IN BOOL Unicode,
+ IN PW32PROCESSINFO pi);
NTSTATUS FASTCALL
InitClassImpl(VOID);
@@ -33,32 +24,45 @@
NTSTATUS FASTCALL
CleanupClassImpl(VOID);
-void FASTCALL DestroyProcessClasses(PW32PROCESS Process );
+BOOL
+UserGetCallProcInfo(IN HANDLE hCallProc,
+ OUT PWNDPROC_INFO wpInfo);
-__inline VOID FASTCALL
-ClassDerefObject(PWNDCLASS_OBJECT Class);
+void FASTCALL
+DestroyProcessClasses(PW32PROCESS Process );
-__inline VOID FASTCALL
-ClassRefObject(PWNDCLASS_OBJECT Class);
+PWINDOWCLASS
+IntReferenceClass(IN PWINDOWCLASS BaseClass,
+ IN PDESKTOP Desktop);
-PWNDCLASS_OBJECT FASTCALL
-ClassGetClassByAtom(
- RTL_ATOM Atom,
- HINSTANCE hInstance);
+VOID
+IntDereferenceClass(IN OUT PWINDOWCLASS Class,
+ IN PDESKTOP Desktop,
+ IN PW32PROCESSINFO pi);
-PWNDCLASS_OBJECT FASTCALL
-ClassGetClassByName(
- LPCWSTR ClassName,
- HINSTANCE hInstance);
+RTL_ATOM
+UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
+ IN PUNICODE_STRING ClassName,
+ IN PUNICODE_STRING MenuName,
+ IN HANDLE hMenu,
+ IN WNDPROC wpExtra,
+ IN DWORD dwFlags);
-PWNDCLASS_OBJECT FASTCALL
-ClassGetClassByNameOrAtom(
- LPCWSTR ClassNameOrAtom,
- HINSTANCE hInstance);
+BOOL
+UserUnregisterClass(IN PUNICODE_STRING ClassName,
+ IN HINSTANCE hInstance);
-struct _WINDOW_OBJECT;
-ULONG FASTCALL
-IntGetClassLong(struct _WINDOW_OBJECT *WindowObject, ULONG Offset, BOOL Ansi);
+ULONG_PTR
+UserGetClassLongPtr(IN PWINDOWCLASS Class,
+ IN INT Index,
+ IN BOOL Ansi);
+
+RTL_ATOM
+IntGetClassAtom(IN PUNICODE_STRING ClassName,
+ IN HINSTANCE hInstance OPTIONAL,
+ IN PW32PROCESSINFO pi OPTIONAL,
+ OUT PWINDOWCLASS *BaseClass OPTIONAL,
+ OUT PWINDOWCLASS **Link OPTIONAL);
#endif /* _WIN32K_CLASS_H */
Modified: trunk/reactos/subsystems/win32/win32k/include/desktop.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/desktop.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/desktop.h Wed Apr 5 12:05:55 2006
@@ -6,8 +6,6 @@
typedef struct _DESKTOP_OBJECT
{
- PVOID DesktopHeap; /* points to kmode memory! */
-
CSHORT Type;
CSHORT Size;
LIST_ENTRY ListEntry;
@@ -26,11 +24,15 @@
PVOID BlockInputThread;
LIST_ENTRY ShellHookWindows;
+
+ HANDLE hDesktopHeap;
+ PSECTION_OBJECT DesktopHeapSection;
+ PDESKTOP DesktopInfo;
} DESKTOP_OBJECT, *PDESKTOP_OBJECT;
extern PDESKTOP_OBJECT InputDesktop;
extern HDESK InputDesktopHandle;
-extern PWNDCLASS_OBJECT DesktopWindowClass;
+extern PWINDOWCLASS DesktopWindowClass;
extern HDC ScreenDeviceContext;
extern BOOL g_PaintDesktopVersion;
@@ -91,6 +93,8 @@
HDESK FASTCALL
IntGetDesktopObjectHandle(PDESKTOP_OBJECT DesktopObject);
+BOOL IntSetThreadDesktop(IN PDESKTOP_OBJECT DesktopObject);
+
NTSTATUS FASTCALL
IntValidateDesktopHandle(
HDESK Desktop,
@@ -115,6 +119,113 @@
#define IntIsActiveDesktop(Desktop) \
((Desktop)->WindowStation->ActiveDesktop == (Desktop))
+static __inline PVOID
+DesktopHeapAlloc(IN PDESKTOP Desktop,
+ IN SIZE_T Bytes)
+{
+ return RtlAllocateHeap(Desktop->hKernelHeap,
+ HEAP_NO_SERIALIZE,
+ Bytes);
+}
+
+static __inline BOOL
+DesktopHeapFree(IN PDESKTOP Desktop,
+ IN PVOID lpMem)
+{
+ return RtlFreeHeap(Desktop->hKernelHeap,
+ HEAP_NO_SERIALIZE,
+ lpMem);
+}
+
+static __inline PVOID
+DesktopHeapReAlloc(IN PDESKTOP Desktop,
+ IN PVOID lpMem,
+ IN SIZE_T Bytes)
+{
+#if 0
+ /* NOTE: ntoskrnl doesn't export RtlReAllocateHeap... */
+ return RtlReAllocateHeap(Desktop->hKernelHeap,
+ HEAP_NO_SERIALIZE,
+ lpMem,
+ Bytes);
+#else
+ SIZE_T PrevSize;
+ PVOID pNew;
+
+ PrevSize = RtlSizeHeap(Desktop->hKernelHeap,
+ HEAP_NO_SERIALIZE,
+ lpMem);
+
+ if (PrevSize == Bytes)
+ return lpMem;
+
+ pNew = RtlAllocateHeap(Desktop->hKernelHeap,
+ HEAP_NO_SERIALIZE,
+ Bytes);
+ if (pNew != NULL)
+ {
+ if (PrevSize < Bytes)
+ Bytes = PrevSize;
+
+ RtlCopyMemory(pNew,
+ lpMem,
+ Bytes);
+
+ RtlFreeHeap(Desktop->hKernelHeap,
+ HEAP_NO_SERIALIZE,
+ lpMem);
+ }
+
+ return pNew;
+#endif
+}
+
+static __inline ULONG_PTR
+DesktopHeapGetUserDelta(VOID)
+{
+ PW32HEAP_USER_MAPPING Mapping;
+ HANDLE hDesktopHeap;
+ ULONG_PTR Delta = 0;
+
+ ASSERT(PsGetWin32Thread()->Desktop != NULL);
+ hDesktopHeap = PsGetWin32Thread()->Desktop->hDesktopHeap;
+
+ Mapping = PsGetWin32Process()->HeapMappings.Next;
+ while (Mapping != NULL)
+ {
+ if (Mapping->UserMapping == (PVOID)hDesktopHeap)
+ {
+ Delta = (ULONG_PTR)Mapping->KernelMapping -
(ULONG_PTR)Mapping->UserMapping;
+ break;
+ }
+
+ Mapping = Mapping->Next;
+ }
+
+ return Delta;
+}
+
+static __inline PVOID
+DesktopHeapAddressToUser(IN PDESKTOP Desktop,
+ PVOID lpMem)
+{
+ PW32HEAP_USER_MAPPING Mapping;
+
+ Mapping = PsGetWin32Process()->HeapMappings.Next;
+ while (Mapping != NULL)
+ {
+ if (Mapping->KernelMapping == (PVOID)Desktop->hKernelHeap)
+ {
+ return (PVOID)(((ULONG_PTR)lpMem - (ULONG_PTR)Desktop->hKernelHeap) +
+ (ULONG_PTR)Mapping->UserMapping);
+ }
+
+ Mapping = Mapping->Next;
+ }
+
+ return NULL;
+}
+
#endif /* _WIN32K_DESKTOP_H */
/* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/include/object.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/object.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/object.h Wed Apr 5 12:05:55 2006
@@ -45,7 +45,7 @@
otCursorIcon,
otHook,
otMonitor,
- otClass //fixme: remove
+ otCallProc
} USER_OBJECT_TYPE;
@@ -125,6 +125,8 @@
\
}
+HANDLE FASTCALL ObmObjectToHandle(PVOID obj);
+
VOID FASTCALL CreateStockObjects (VOID);
VOID FASTCALL CreateSysColorObjects (VOID);
Modified: trunk/reactos/subsystems/win32/win32k/include/userfuncs.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/userfuncs.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/userfuncs.h Wed Apr 5 12:05:55 2006
@@ -75,7 +75,7 @@
/******************** HANDLE.C ***************/
-extern USER_HANDLE_TABLE gHandleTable;
+extern PUSER_HANDLE_TABLE gHandleTable;
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle );
VOID UserInitHandleTable(PUSER_HANDLE_TABLE ht, PVOID mem, ULONG bytes);
Modified: trunk/reactos/subsystems/win32/win32k/include/win32.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/inc…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/win32.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/win32.h Wed Apr 5 12:05:55 2006
@@ -15,10 +15,18 @@
BOOLEAN IsExiting;
SINGLE_LIST_ENTRY ReferencesList;
+ PW32THREADINFO ThreadInfo;
} W32THREAD, *PW32THREAD;
#include <poppack.h>
+typedef struct _W32HEAP_USER_MAPPING
+{
+ struct _W32HEAP_USER_MAPPING *Next;
+ PVOID KernelMapping;
+ PVOID UserMapping;
+ ULONG Count;
+} W32HEAP_USER_MAPPING, *PW32HEAP_USER_MAPPING;
typedef struct _W32PROCESS
{
@@ -32,6 +40,9 @@
ULONG Flags;
LONG GDIObjects;
LONG UserObjects;
+
+ W32HEAP_USER_MAPPING HeapMappings;
+ PW32PROCESSINFO ProcessInfo;
} W32PROCESS, *PW32PROCESS;
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 Wed Apr 5 12:05:55 2006
@@ -26,8 +26,21 @@
typedef struct _WINDOW_OBJECT
{
+ /* Pointer to the thread information */
+ PW32THREADINFO ti;
+ /* Pointer to the desktop */
+ PDESKTOP Desktop;
+ union
+ {
+ /* Pointer to a call procedure handle */
+ PCALLPROC CallProc;
+ /* Extra Wnd proc (windows of system classes) */
+ WNDPROC WndProcExtra;
+ };
+ /* Indicates whether the window is derived from a system class */
+ BOOL IsSystem;
/* Pointer to the window class. */
- PWNDCLASS_OBJECT Class;
+ PWINDOWCLASS Class;
/* Extended style. */
DWORD ExStyle;
/* Window name. */
@@ -81,8 +94,7 @@
PWINDOW_SCROLLINFO Scroll;
LONG UserData;
BOOL Unicode;
- WNDPROC WndProcA;
- WNDPROC WndProcW;
+ WNDPROC WndProc;
PETHREAD OwnerThread;
HWND hWndLastPopup; /* handle to last active popup window (wine doesn't use
pointer, for unk. reason)*/
PINTERNALPOS InternalPos;
@@ -190,10 +202,6 @@
BOOL FASTCALL
IntIsWindowInDestroy(PWINDOW_OBJECT Window);
-DWORD IntRemoveWndProcHandle(WNDPROC Handle);
-DWORD IntRemoveProcessWndProcHandles(HANDLE ProcessID);
-DWORD IntAddWndProcHandle(WNDPROC WindowProc, BOOL IsUnicode);
-
BOOL FASTCALL
IntShowOwnedPopups( PWINDOW_OBJECT owner, BOOL fShow );
Modified: trunk/reactos/subsystems/win32/win32k/main/dllmain.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/mai…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/main/dllmain.c (original)
+++ trunk/reactos/subsystems/win32/win32k/main/dllmain.c Wed Apr 5 12:05:55 2006
@@ -33,6 +33,9 @@
PGDI_HANDLE_TABLE GdiHandleTable = NULL;
PSECTION_OBJECT GdiTableSection = NULL;
+HANDLE GlobalUserHeap = NULL;
+PSECTION_OBJECT GlobalUserHeapSection = NULL;
+
extern ULONG_PTR Win32kSSDT[];
extern UCHAR Win32kSSPT[];
extern ULONG Win32kNumberOfSysCalls;
@@ -69,7 +72,34 @@
if (Create)
{
+ ULONG ViewSize = 0;
+ LARGE_INTEGER Offset;
+ PVOID UserBase = NULL;
+ NTSTATUS Status;
+ extern PSECTION_OBJECT GlobalUserHeapSection;
DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n",
Process->UniqueProcessId, KeGetCurrentIrql());
+
+ /* map the global heap into the process */
+ Offset.QuadPart = 0;
+ Status = MmMapViewOfSection(GlobalUserHeapSection,
+ PsGetCurrentProcess(),
+ &UserBase,
+ 0,
+ 0,
+ &Offset,
+ &ViewSize,
+ ViewUnmap,
+ SEC_NO_CHANGE,
+ PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but
thanks to RTL heaps... */
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to map the global heap! 0x%x\n", Status);
+ RETURN(Status);
+ }
+ Win32Process->HeapMappings.Next = NULL;
+ Win32Process->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap;
+ Win32Process->HeapMappings.UserMapping = UserBase;
+ Win32Process->HeapMappings.Count = 1;
InitializeListHead(&Win32Process->ClassList);
@@ -95,7 +125,6 @@
else
{
DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n",
Process->UniqueProcessId, KeGetCurrentIrql());
- IntRemoveProcessWndProcHandles((HANDLE)Process->UniqueProcessId);
IntCleanupMenus(Process, Win32Process);
IntCleanupCurIcons(Process, Win32Process);
IntEngCleanupDriverObjs(Process, Win32Process);
@@ -114,6 +143,12 @@
if(LogonProcess == Win32Process)
{
LogonProcess = NULL;
+ }
+
+ if (Win32Process->ProcessInfo != NULL)
+ {
+ UserHeapFree(Win32Process->ProcessInfo);
+ Win32Process->ProcessInfo = NULL;
}
}
@@ -198,17 +233,25 @@
if (hDesk != NULL)
{
+ PDESKTOP_OBJECT DesktopObject;
+ Win32Thread->Desktop = NULL;
Status = ObReferenceObjectByHandle(hDesk,
0,
ExDesktopObjectType,
KernelMode,
- (PVOID*)&Win32Thread->Desktop,
+ (PVOID*)&DesktopObject,
NULL);
NtClose(hDesk);
- if(!NT_SUCCESS(Status))
+ if(NT_SUCCESS(Status))
+ {
+ if (!IntSetThreadDesktop(DesktopObject))
+ {
+ DPRINT1("Unable to set thread desktop\n");
+ }
+ }
+ else
{
DPRINT1("Unable to reference thread desktop handle 0x%x\n",
hDesk);
- Win32Thread->Desktop = NULL;
}
}
}
@@ -234,11 +277,15 @@
IntBlockInput(Win32Thread, FALSE);
MsqDestroyMessageQueue(Win32Thread->MessageQueue);
IntCleanupThreadCallbacks(Win32Thread);
- if(Win32Thread->Desktop != NULL)
- {
- ObDereferenceObject(Win32Thread->Desktop);
- }
-
+
+ IntSetThreadDesktop(NULL);
+
+ if (Win32Thread->ThreadInfo != NULL)
+ {
+ UserHeapFree(Win32Thread->ThreadInfo);
+ Win32Thread->ThreadInfo = NULL;
+ }
+
/* cleanup user object references stack */
e = PopEntryList(&Win32Thread->ReferencesList);
while (e)
@@ -309,6 +356,7 @@
NTSTATUS Status;
BOOLEAN Result;
W32_CALLOUT_DATA CalloutData;
+ PVOID GlobalUserHeapBase = NULL;
/*
* Register user mode call interface
@@ -342,6 +390,16 @@
*/
PsEstablishWin32Callouts(&CalloutData);
+ GlobalUserHeap = UserCreateHeap(&GlobalUserHeapSection,
+ &GlobalUserHeapBase,
+ 1 * 1024 * 1024); /* FIXME - 1 MB for now... */
+ if (GlobalUserHeap == NULL)
+ {
+ DPRINT1("Failed to initialize the global heap!\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+
+
Status = InitUserImpl();
if (!NT_SUCCESS(Status))
{
Modified: trunk/reactos/subsystems/win32/win32k/misc/err.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/mis…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/misc/err.c (original)
+++ trunk/reactos/subsystems/win32/win32k/misc/err.c Wed Apr 5 12:05:55 2006
@@ -61,4 +61,22 @@
return 0;
}
+VOID
+NTAPI
+W32kRaiseStatus(NTSTATUS Status)
+{
+ EXCEPTION_RECORD ExceptionRecord;
+
+ /* Create an exception record */
+ ExceptionRecord.ExceptionCode = Status;
+ ExceptionRecord.ExceptionRecord = NULL;
+ ExceptionRecord.NumberParameters = 0;
+ ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
+
+ RtlRaiseException(&ExceptionRecord);
+
+ /* If we returned, raise a status */
+ W32kRaiseStatus(Status);
+}
+
/* EOF */
Added: trunk/reactos/subsystems/win32/win32k/misc/usrheap.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/mis…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/misc/usrheap.c (added)
+++ trunk/reactos/subsystems/win32/win32k/misc/usrheap.c Wed Apr 5 12:05:55 2006
@@ -1,0 +1,216 @@
+/*
+ * ReactOS W32 Subsystem
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <w32k.h>
+
+#define NDEBUG
+#include <debug.h>
+
+
+static NTSTATUS NTAPI
+IntUserHeapCommitRoutine(IN PVOID Base,
+ IN OUT PVOID *CommitAddress,
+ IN OUT PSIZE_T CommitSize)
+{
+ PW32PROCESS W32Process;
+ PW32HEAP_USER_MAPPING Mapping;
+ PVOID UserBase = NULL;
+ NTSTATUS Status;
+ SIZE_T Delta = (SIZE_T)((ULONG_PTR)(*CommitAddress) - (ULONG_PTR)Base);
+
+ W32Process = PsGetWin32Process();
+
+ if (W32Process != NULL)
+ {
+ /* search for the mapping */
+ Mapping = &W32Process->HeapMappings;
+ while (Mapping != NULL)
+ {
+ if (Mapping->KernelMapping == Base)
+ {
+ UserBase = Mapping->UserMapping;
+ break;
+ }
+
+ Mapping = Mapping->Next;
+ }
+
+ ASSERT(UserBase != NULL);
+ }
+ else
+ {
+ ULONG ViewSize = 0;
+ LARGE_INTEGER Offset;
+ extern PSECTION_OBJECT GlobalUserHeapSection;
+
+ /* HACK: This needs to be handled during startup only... */
+ ASSERT(Base == (PVOID)GlobalUserHeap);
+
+ /* temporarily map it into user space */
+ Offset.QuadPart = 0;
+ Status = MmMapViewOfSection(GlobalUserHeapSection,
+ PsGetCurrentProcess(),
+ &UserBase,
+ 0,
+ 0,
+ &Offset,
+ &ViewSize,
+ ViewUnmap,
+ SEC_NO_CHANGE,
+ PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY,
but thanks to RTL heaps... */
+
+ if (!NT_SUCCESS(Status))
+ return Status;
+ }
+
+ /* commit! */
+ UserBase = (PVOID)((ULONG_PTR)UserBase + Delta);
+
+ Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+ &UserBase,
+ 0,
+ CommitSize,
+ MEM_COMMIT,
+ PAGE_EXECUTE_READ);
+ if (NT_SUCCESS(Status))
+ {
+ *CommitAddress = (PVOID)((ULONG_PTR)UserBase + Delta);
+ }
+
+ if (W32Process == NULL)
+ {
+ MmUnmapViewOfSection(PsGetCurrentProcess(),
+ UserBase);
+ }
+
+ return Status;
+}
+
+static HANDLE
+IntUserHeapCreate(IN PSECTION_OBJECT SectionObject,
+ IN PVOID *SystemMappedBase,
+ IN ULONG HeapSize)
+{
+ PVOID MappedView = NULL;
+ LARGE_INTEGER Offset;
+ ULONG ViewSize = PAGE_SIZE;
+ RTL_HEAP_PARAMETERS Parameters = {0};
+ HANDLE hHeap;
+ NTSTATUS Status;
+
+ Offset.QuadPart = 0;
+
+ /* Commit the first page before creating the heap! */
+ Status = MmMapViewOfSection(SectionObject,
+ PsGetCurrentProcess(),
+ &MappedView,
+ 0,
+ 0,
+ &Offset,
+ &ViewSize,
+ ViewUnmap,
+ SEC_NO_CHANGE,
+ PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but
thanks to RTL heaps... */
+ if (!NT_SUCCESS(Status))
+ return NULL;
+
+ Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+ &MappedView,
+ 0,
+ &ViewSize,
+ MEM_COMMIT,
+ PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY,
but thanks to RTL heaps... */
+
+ MmUnmapViewOfSection(PsGetCurrentProcess(),
+ MappedView);
+
+ if (!NT_SUCCESS(Status))
+ return NULL;
+
+ /* Create the heap, don't serialize in kmode! The caller is responsible
+ to synchronize the heap! */
+ Parameters.Length = sizeof(Parameters);
+ Parameters.InitialCommit = PAGE_SIZE;
+ Parameters.InitialReserve = (SIZE_T)HeapSize;
+ Parameters.CommitRoutine = IntUserHeapCommitRoutine;
+
+ hHeap = RtlCreateHeap(HEAP_ZERO_MEMORY | HEAP_NO_SERIALIZE,
+ *SystemMappedBase,
+ (SIZE_T)HeapSize,
+ PAGE_SIZE,
+ NULL,
+ &Parameters);
+
+ return hHeap;
+}
+
+HANDLE
+UserCreateHeap(OUT PSECTION_OBJECT *SectionObject,
+ IN OUT PVOID *SystemBase,
+ IN ULONG HeapSize)
+{
+ LARGE_INTEGER SizeHeap;
+ HANDLE hHeap = NULL;
+ NTSTATUS Status;
+
+ SizeHeap.QuadPart = HeapSize;
+
+ /* create the section and map it into session space */
+ Status = MmCreateSection((PVOID*)SectionObject,
+ SECTION_ALL_ACCESS,
+ NULL,
+ &SizeHeap,
+ PAGE_EXECUTE_READWRITE, /* would prefer PAGE_READWRITE, but
thanks to RTL heaps... */
+ SEC_RESERVE,
+ NULL,
+ NULL);
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return FALSE;
+ }
+
+ Status = MmMapViewInSystemSpace(*SectionObject,
+ SystemBase,
+ &HeapSize);
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(*SectionObject);
+ *SectionObject = NULL;
+
+ SetLastNtError(Status);
+ return FALSE;
+ }
+
+ /* create the heap */
+ hHeap = IntUserHeapCreate(*SectionObject,
+ SystemBase,
+ HeapSize);
+
+ if (hHeap == NULL)
+ {
+ ObDereferenceObject(*SectionObject);
+ *SectionObject = NULL;
+
+ SetLastNtError(STATUS_UNSUCCESSFUL);
+ }
+
+ return hHeap;
+}
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/accelerator.c Wed Apr 5 12:05:55 2006
@@ -80,7 +80,7 @@
return NULL;
}
- Accel= UserGetObject(&gHandleTable, hAccel, otAccel);
+ Accel= UserGetObject(gHandleTable, hAccel, otAccel);
if (!Accel)
{
SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE);
@@ -344,7 +344,7 @@
Entries, EntriesCount);
UserEnterExclusive();
- Accel = ObmCreateObject(&gHandleTable, (PHANDLE)&hAccel, otAccel,
sizeof(ACCELERATOR_TABLE));
+ Accel = ObmCreateObject(gHandleTable, (PHANDLE)&hAccel, otAccel,
sizeof(ACCELERATOR_TABLE));
if (Accel == NULL)
{
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 Wed Apr 5 12:05:55 2006
@@ -1,6 +1,6 @@
/*
* ReactOS W32 Subsystem
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
+ * Copyright (C) 1998 - 2006 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,9 +22,12 @@
* PROJECT: ReactOS kernel
* PURPOSE: Window classes
* FILE: subsys/win32k/ntuser/class.c
- * PROGRAMER: Casper S. Hornstrup (chorns(a)users.sourceforge.net)
+ * PROGRAMER: Thomas Weidenmueller <w3seek(a)reactos.com>
* REVISION HISTORY:
* 06-06-2001 CSH Created
+ *
+ * NOTE: Should classes created on a desktop heap be moved to the shared
+ * heap when the desktop is destroyed, or should they be unregistered?
*/
/* INCLUDES ******************************************************************/
@@ -33,7 +36,96 @@
#define NDEBUG
#include <debug.h>
-/* FUNCTIONS *****************************************************************/
+/* CALLPROC ******************************************************************/
+
+VOID
+DestroyCallProc(IN PDESKTOP Desktop,
+ IN OUT PCALLPROC CallProc)
+{
+ /* FIXME - use new object manager! */
+ HANDLE Handle = ObmObjectToHandle(CallProc);
+
+ ObmDeleteObject(Handle,
+ otCallProc);
+}
+
+PCALLPROC
+CloneCallProc(IN PDESKTOP Desktop,
+ IN PCALLPROC CallProc)
+{
+ PCALLPROC NewCallProc;
+ HANDLE Handle;
+
+ /* FIXME - use new object manager! */
+ NewCallProc = (PCALLPROC)ObmCreateObject(gHandleTable,
+ &Handle,
+ otCallProc,
+ sizeof(CALLPROC));
+ if (NewCallProc != NULL)
+ {
+ NewCallProc->pi = CallProc->pi;
+ NewCallProc->WndProc = CallProc->WndProc;
+ NewCallProc->Unicode = CallProc->Unicode;
+ }
+
+ return NewCallProc;
+}
+
+PCALLPROC
+CreateCallProc(IN PDESKTOP Desktop,
+ IN WNDPROC WndProc,
+ IN BOOL Unicode,
+ IN PW32PROCESSINFO pi)
+{
+ PCALLPROC NewCallProc;
+ HANDLE Handle;
+
+ /* FIXME - use new object manager! */
+ NewCallProc = (PCALLPROC)ObmCreateObject(gHandleTable,
+ &Handle,
+ otCallProc,
+ sizeof(CALLPROC));
+ if (NewCallProc != NULL)
+ {
+ NewCallProc->pi = pi;
+ NewCallProc->WndProc = WndProc;
+ NewCallProc->Unicode = Unicode;
+ }
+
+ return NewCallProc;
+}
+
+BOOL
+UserGetCallProcInfo(IN HANDLE hCallProc,
+ OUT PWNDPROC_INFO wpInfo)
+{
+ PCALLPROC CallProc;
+
+ /* NOTE: Accessing the WNDPROC_INFO structure may raise an exception! */
+
+ /* FIXME - use new object manager! */
+ CallProc = UserGetObject(gHandleTable,
+ hCallProc,
+ otCallProc);
+ if (CallProc == NULL)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (CallProc->pi != GetW32ProcessInfo())
+ {
+ SetLastWin32Error(ERROR_ACCESS_DENIED);
+ return FALSE;
+ }
+
+ wpInfo->WindowProc = CallProc->WndProc;
+ wpInfo->IsUnicode = CallProc->Unicode;
+
+ return TRUE;
+}
+
+/* WINDOWCLASS ***************************************************************/
NTSTATUS FASTCALL
InitClassImpl(VOID)
@@ -47,398 +139,1673 @@
return(STATUS_SUCCESS);
}
-
-__inline VOID FASTCALL
-ClassDerefObject(PWNDCLASS_OBJECT Class)
-{
- ASSERT(Class->refs >= 1);
- Class->refs--;
-}
-
-
-__inline VOID FASTCALL
-ClassRefObject(PWNDCLASS_OBJECT Class)
-{
- ASSERT(Class->refs >= 0);
- Class->refs++;
-}
-
-
-VOID FASTCALL DestroyClass(PWNDCLASS_OBJECT Class)
-{
-#if defined(DBG) || defined(KDBG)
- if ( Class->refs != 0 )
- {
- WCHAR AtomName[256];
- ULONG AtomNameLen = sizeof(AtomName);
- RtlQueryAtomInAtomTable ( gAtomTable, Class->Atom,
- NULL, NULL, AtomName, &AtomNameLen );
- DPRINT1("DestroyClass(): can't delete class = '%ws', b/c refs =
%lu\n", AtomName, Class->refs );
- }
-#endif
- ASSERT(Class->refs == 0);
-
- RemoveEntryList(&Class->ListEntry);
- if (Class->hMenu)
- UserDestroyMenu(Class->hMenu);
- RtlDeleteAtomFromAtomTable(gAtomTable, Class->Atom);
- ExFreePool(Class);
+static VOID
+IntFreeClassMenuName(IN OUT PWINDOWCLASS Class)
+{
+ /* free the menu name, if it was changed and allocated */
+ if (Class->MenuName != NULL && !IS_INTRESOURCE(Class->MenuName)
&&
+ Class->MenuName != (PWSTR)(Class + 1))
+ {
+ UserHeapFree(Class->MenuName);
+ Class->MenuName = NULL;
+ Class->AnsiMenuName = NULL;
+ }
+}
+
+static VOID
+IntDestroyClass(IN OUT PWINDOWCLASS Class)
+{
+ /* there shouldn't be any clones anymore */
+
+ ASSERT(Class->Windows == 0);
+
+ if (Class->Desktop != NULL)
+ {
+ ASSERT(Class->Clone == NULL);
+ }
+ else if (Class->Clone != NULL)
+ {
+ /* there must not be more than one clone! This can be the case
+ when the base class is on the shared heap */
+ ASSERT(Class->Clone->Next == NULL);
+
+ /* free the clone */
+ IntDestroyClass(Class->Clone);
+ Class->Clone = NULL;
+ }
+
+ if (Class->Base == Class)
+ {
+ /* destruct resources shared with clones */
+ if (!Class->System && Class->CallProc != NULL)
+ {
+ DestroyCallProc(Class->Desktop,
+ Class->CallProc);
+ }
+
+ IntFreeClassMenuName(Class);
+ }
+
+ /* free the structure */
+ if (Class->Desktop != NULL)
+ {
+ DesktopHeapFree(Class->Desktop,
+ Class);
+ }
+ else
+ {
+ UserHeapFree(Class);
+ }
}
/* clean all process classes. all process windows must cleaned first!! */
void FASTCALL DestroyProcessClasses(PW32PROCESS Process )
{
- PWNDCLASS_OBJECT Class;
-
- while (!IsListEmpty(&Process->ClassList))
- {
- Class = CONTAINING_RECORD(RemoveHeadList(&Process->ClassList),
WNDCLASS_OBJECT, ListEntry);
- DestroyClass(Class);
- }
-}
-
-
-
-
-PWNDCLASS_OBJECT FASTCALL
-ClassGetClassByAtom(RTL_ATOM Atom, HINSTANCE hInstance)
-{
- PWNDCLASS_OBJECT Class;
- PW32PROCESS Process = PsGetWin32Process();
-
- LIST_FOR_EACH(Class, &Process->ClassList, WNDCLASS_OBJECT, ListEntry)
- {
- if (Class->Atom != Atom) continue;
-
- if (!hInstance || Class->Global || Class->hInstance == hInstance) return
Class;
- }
-
- return NULL;
-}
-
-
-PWNDCLASS_OBJECT FASTCALL
-ClassGetClassByName(LPCWSTR ClassName, HINSTANCE hInstance)
-{
- NTSTATUS Status;
- RTL_ATOM Atom;
-
- if (!ClassName || !PsGetWin32Thread()->Desktop)
- return FALSE;
-
- Status = RtlLookupAtomInAtomTable(
- gAtomTable,
- (LPWSTR)ClassName,
- &Atom);
-
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed to lookup class atom (ClassName '%S')!\n",
ClassName);
- return FALSE;
- }
-
- return ClassGetClassByAtom(Atom, hInstance);
-}
-
-
-PWNDCLASS_OBJECT FASTCALL
-ClassGetClassByNameOrAtom(LPCWSTR ClassNameOrAtom, HINSTANCE hInstance)
-{
- if (!ClassNameOrAtom) return NULL;
-
- if (IS_ATOM(ClassNameOrAtom))
- return ClassGetClassByAtom((RTL_ATOM)((ULONG_PTR)ClassNameOrAtom), hInstance);
- else
- return ClassGetClassByName(ClassNameOrAtom, hInstance);
-}
-
-
-static
-BOOL FASTCALL
-IntRegisterClass(
- CONST WNDCLASSEXW *lpwcx,
- DWORD Flags,
- WNDPROC wpExtra,
- PUNICODE_STRING MenuName,
- RTL_ATOM Atom,
- HMENU hMenu)
-{
- PWNDCLASS_OBJECT Class;
- ULONG objectSize;
- BOOL Global;
-
- ASSERT(lpwcx);
- ASSERT(Atom);
- ASSERT(lpwcx->hInstance);
-
- Global = (Flags & REGISTERCLASS_SYSTEM) || (lpwcx->style &
CS_GLOBALCLASS);
-
- /* Check for double registration of the class. */
- Class = ClassGetClassByAtom(Atom, lpwcx->hInstance);
- if (Class && Global == Class->Global)
- {
- /* can max have one class of each type (global/local) */
- SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
- return(FALSE);
- }
-
- objectSize = sizeof(WNDCLASS_OBJECT) + lpwcx->cbClsExtra;
-
- //FIXME: allocate in session heap (or possibly desktop heap)
- Class = ExAllocatePool(PagedPool, objectSize);
- if (!Class)
- {
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- return(FALSE);
- }
- RtlZeroMemory(Class, objectSize);
-
- Class->cbSize = lpwcx->cbSize;
- Class->style = lpwcx->style;
- Class->cbClsExtra = lpwcx->cbClsExtra;
- Class->cbWndExtra = lpwcx->cbWndExtra;
- Class->hInstance = lpwcx->hInstance;
- Class->hIcon = lpwcx->hIcon;
- Class->hCursor = lpwcx->hCursor;
- Class->hMenu = hMenu;
- Class->hbrBackground = lpwcx->hbrBackground;
- Class->Unicode = !(Flags & REGISTERCLASS_ANSI);
- Class->Global = Global;
- Class->hIconSm = lpwcx->hIconSm;
- Class->Atom = Atom;
-
- if (MenuName->Length == 0)
- {
- Class->lpszMenuName.Length =
- Class->lpszMenuName.MaximumLength = 0;
- Class->lpszMenuName.Buffer = MenuName->Buffer;
- }
- else
- {
- Class->lpszMenuName.Length =
- Class->lpszMenuName.MaximumLength = MenuName->MaximumLength;
- Class->lpszMenuName.Buffer = ExAllocatePoolWithTag(PagedPool,
Class->lpszMenuName.MaximumLength, TAG_STRING);
-
- if (Class->lpszMenuName.Buffer == NULL)
- {
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- return(FALSE);
- }
-
- RtlCopyUnicodeString(&Class->lpszMenuName, MenuName);
- }
-
- if (wpExtra == NULL)
- {
- if (Flags & REGISTERCLASS_ANSI)
- {
- Class->lpfnWndProcA = lpwcx->lpfnWndProc;
- Class->lpfnWndProcW =
(WNDPROC)IntAddWndProcHandle(lpwcx->lpfnWndProc,FALSE);
- }
- else
- {
- Class->lpfnWndProcW = lpwcx->lpfnWndProc;
- Class->lpfnWndProcA =
(WNDPROC)IntAddWndProcHandle(lpwcx->lpfnWndProc,TRUE);
- }
- }
- else
- {
- if (Flags & REGISTERCLASS_ANSI)
- {
- Class->lpfnWndProcA = lpwcx->lpfnWndProc;
- Class->lpfnWndProcW = wpExtra;
- }
- else
- {
- Class->lpfnWndProcW = lpwcx->lpfnWndProc;
- Class->lpfnWndProcA = wpExtra;
- }
- }
-
-
-
- /* Extra class data */
- if (Class->cbClsExtra)
- Class->ExtraData = (PCHAR)(Class + 1);
-
- if (Global)
- {
- /* global classes go last (incl. system classes) */
- InsertTailList(&PsGetWin32Process()->ClassList, &Class->ListEntry);
- }
- else
- {
- /* local classes have priority so we put them first */
- InsertHeadList(&PsGetWin32Process()->ClassList, &Class->ListEntry);
- }
-
- return TRUE;
-}
-
-
-ULONG FASTCALL
-IntGetClassLong(PWINDOW_OBJECT Window, ULONG Offset, BOOL Ansi)
-{
- LONG Ret;
-
- if ((int)Offset >= 0)
- {
- DPRINT("GetClassLong(%x, %d)\n", Window->hSelf, Offset);
- if ((Offset + sizeof(LONG)) > Window->Class->cbClsExtra)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return 0;
- }
- Ret = *((LONG *)(Window->Class->ExtraData + Offset));
- DPRINT("Result: %x\n", Ret);
- return Ret;
- }
-
- switch (Offset)
- {
- case GCL_CBWNDEXTRA:
- Ret = Window->Class->cbWndExtra;
- break;
- case GCL_CBCLSEXTRA:
- Ret = Window->Class->cbClsExtra;
- break;
- case GCL_HBRBACKGROUND:
- Ret = (ULONG)Window->Class->hbrBackground;
- break;
- case GCL_HCURSOR:
- Ret = (ULONG)Window->Class->hCursor;
- break;
- case GCL_HICON:
- Ret = (ULONG)Window->Class->hIcon;
- break;
- case GCL_HICONSM:
- Ret = (ULONG)Window->Class->hIconSm;
- break;
- case GCL_HMODULE:
- Ret = (ULONG)Window->Class->hInstance;
- break;
- case GCL_MENUNAME:
- Ret = (ULONG)Window->Class->lpszMenuName.Buffer;
- break;
- case GCL_STYLE:
- Ret = Window->Class->style;
- break;
- case GCL_WNDPROC:
- if (Ansi)
- {
- Ret = (ULONG)Window->Class->lpfnWndProcA;
- }
- else
- {
- Ret = (ULONG)Window->Class->lpfnWndProcW;
- }
- break;
- case GCW_ATOM:
- Ret = Window->Class->Atom;
- break;
- default:
- Ret = 0;
- break;
- }
- return(Ret);
-}
-
-static
-void FASTCALL
-co_IntSetClassLong(PWINDOW_OBJECT Window, ULONG Offset, LONG dwNewLong, BOOL Ansi)
-{
- ASSERT_REFS_CO(Window);
-
- if ((int)Offset >= 0)
- {
- DPRINT("SetClassLong(%x, %d, %x)\n", Window->hSelf, Offset,
dwNewLong);
- if ((Offset + sizeof(LONG)) > Window->Class->cbClsExtra)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- return;
- }
- *((LONG *)(Window->Class->ExtraData + Offset)) = dwNewLong;
- return;
- }
-
- switch (Offset)
- {
- case GCL_CBWNDEXTRA:
- Window->Class->cbWndExtra = dwNewLong;
- break;
- case GCL_CBCLSEXTRA:
- Window->Class->cbClsExtra = dwNewLong;
- break;
- case GCL_HBRBACKGROUND:
- Window->Class->hbrBackground = (HBRUSH)dwNewLong;
- break;
- case GCL_HCURSOR:
- Window->Class->hCursor = (HCURSOR)dwNewLong;
- break;
- case GCL_HICON:
- Window->Class->hIcon = (HICON)dwNewLong;
-
- if (!IntGetOwner(Window) && !IntGetParent(Window))
- {
- co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) Window->hSelf);
- }
- break;
- case GCL_HICONSM:
- Window->Class->hIconSm = (HICON)dwNewLong;
- break;
- case GCL_HMODULE:
- Window->Class->hInstance = (HINSTANCE)dwNewLong;
- break;
- case GCL_MENUNAME:
- if (Window->Class->lpszMenuName.MaximumLength)
- RtlFreeUnicodeString(&Window->Class->lpszMenuName);
- if (!IS_INTRESOURCE(dwNewLong))
- {
- Window->Class->lpszMenuName.Length =
- Window->Class->lpszMenuName.MaximumLength =
((PUNICODE_STRING)dwNewLong)->MaximumLength;
- Window->Class->lpszMenuName.Buffer = ExAllocatePoolWithTag(PagedPool,
Window->Class->lpszMenuName.MaximumLength, TAG_STRING);
- RtlCopyUnicodeString(&Window->Class->lpszMenuName,
(PUNICODE_STRING)dwNewLong);
- }
- else
- {
- Window->Class->lpszMenuName.Length =
- Window->Class->lpszMenuName.MaximumLength = 0;
- Window->Class->lpszMenuName.Buffer = (LPWSTR)dwNewLong;
- }
- break;
- case GCL_STYLE:
- Window->Class->style = dwNewLong;
- break;
- case GCL_WNDPROC:
- if (Ansi)
- {
- Window->Class->lpfnWndProcA = (WNDPROC)dwNewLong;
- Window->Class->lpfnWndProcW = (WNDPROC)
IntAddWndProcHandle((WNDPROC)dwNewLong,FALSE);
- Window->Class->Unicode = FALSE;
- }
- else
- {
- Window->Class->lpfnWndProcW = (WNDPROC)dwNewLong;
- Window->Class->lpfnWndProcA = (WNDPROC)
IntAddWndProcHandle((WNDPROC)dwNewLong,TRUE);
- Window->Class->Unicode = TRUE;
- }
- break;
- }
-}
+ PWINDOWCLASS Class;
+ PW32PROCESSINFO pi = Process->ProcessInfo;
+
+ if (pi != NULL)
+ {
+ /* free all local classes */
+ Class = pi->LocalClassList;
+ while (Class != NULL)
+ {
+ pi->LocalClassList = Class->Next;
+
+ ASSERT(Class->Base == Class);
+ IntDestroyClass(Class);
+
+ Class = pi->LocalClassList;
+ }
+
+ /* free all global classes */
+ Class = pi->GlobalClassList;
+ while (Class != NULL)
+ {
+ pi->GlobalClassList = Class->Next;
+
+ ASSERT(Class->Base == Class);
+ IntDestroyClass(Class);
+
+ Class = pi->GlobalClassList;
+ }
+
+ /* free all system classes */
+ Class = pi->SystemClassList;
+ while (Class != NULL)
+ {
+ pi->SystemClassList = Class->Next;
+
+ ASSERT(Class->Base == Class);
+ IntDestroyClass(Class);
+
+ Class = pi->SystemClassList;
+ }
+ }
+}
+
+static BOOL
+IntRegisterClassAtom(IN PUNICODE_STRING ClassName,
+ OUT RTL_ATOM *pAtom)
+{
+ WCHAR szBuf[65];
+ PWSTR AtomName;
+ NTSTATUS Status;
+
+ if (ClassName->Length != 0)
+ {
+ /* FIXME - Don't limit to 64 characters! use SEH when allocating memory! */
+ if (ClassName->Length / sizeof(WCHAR) >= sizeof(szBuf) / sizeof(szBuf[0]))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return (RTL_ATOM)0;
+ }
+
+ RtlCopyMemory(szBuf,
+ ClassName->Buffer,
+ ClassName->Length);
+ szBuf[ClassName->Length / sizeof(WCHAR)] = UNICODE_NULL;
+ AtomName = szBuf;
+ }
+ else
+ AtomName = ClassName->Buffer;
+
+ Status = RtlAddAtomToAtomTable(gAtomTable,
+ AtomName,
+ pAtom);
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static VOID
+IntDeregisterClassAtom(IN RTL_ATOM Atom)
+{
+ RtlDeleteAtomFromAtomTable(gAtomTable,
+ Atom);
+}
+
+static BOOL
+IntSetClassAtom(IN OUT PWINDOWCLASS Class,
+ IN PUNICODE_STRING ClassName)
+{
+ RTL_ATOM Atom = (RTL_ATOM)0;
+
+ /* update the base class first */
+ Class = Class->Base;
+
+ if (!IntRegisterClassAtom(ClassName,
+ &Atom))
+ {
+ return FALSE;
+ }
+
+ IntDeregisterClassAtom(Class->Atom);
+
+ Class->Atom = Atom;
+
+ /* update the clones */
+ Class = Class->Clone;
+ while (Class != NULL)
+ {
+ Class->Atom = Atom;
+
+ Class = Class->Next;
+ }
+
+ return TRUE;
+}
+
+static WNDPROC
+IntSetClassWndProc(IN OUT PWINDOWCLASS Class,
+ IN WNDPROC WndProc,
+ IN BOOL Ansi)
+{
+ WNDPROC Ret = Class->WndProc;
+
+ if (Class->System)
+ {
+ DPRINT1("Attempted to change window procedure of system window class
0x%p!\n", Class->Atom);
+ SetLastWin32Error(ERROR_ACCESS_DENIED);
+ return NULL;
+ }
+
+ /* update the base class first */
+ Class = Class->Base;
+
+ Class->Unicode = !Ansi;
+ Class->WndProc = WndProc;
+ if (Class->CallProc != NULL)
+ {
+ Class->CallProc->WndProc = WndProc;
+ Class->CallProc->Unicode = !Ansi;
+ }
+
+ /* update the clones */
+ Class = Class->Clone;
+ while (Class != NULL)
+ {
+ Class->Unicode = !Ansi;
+ Class->WndProc = WndProc;
+
+ Class = Class->Next;
+ }
+
+ return Ret;
+}
+
+static PWINDOWCLASS
+IntGetClassForDesktop(IN PWINDOWCLASS BaseClass,
+ IN PDESKTOP Desktop)
+{
+ SIZE_T ClassSize;
+ PWINDOWCLASS Class;
+
+ ASSERT(Desktop != NULL);
+ ASSERT(BaseClass->Base == BaseClass);
+
+ if (BaseClass->Desktop == Desktop)
+ {
+ /* it is most likely that a window is created on the same
+ desktop as the window class. */
+
+ return BaseClass;
+ }
+
+ if (BaseClass->Desktop == NULL)
+ {
+ /* Classes are also located in the shared heap when the class
+ was created before the thread attached to a desktop. As soon
+ as a window is created for such a class located on the shared
+ heap, the class is cloned into the desktop heap on which the
+ window is created. */
+ Class = NULL;
+ }
+ else
+ {
+ /* The user is asking for a class object on a different desktop,
+ try to find one! */
+ Class = BaseClass->Clone;
+ while (Class != NULL)
+ {
+ if (Class->Desktop == Desktop)
+ {
+ ASSERT(Class->Base == BaseClass);
+ ASSERT(Class->Clone == NULL);
+ break;
+ }
+
+ Class = Class->Next;
+ }
+ }
+
+ if (Class == NULL)
+ {
+ /* The window is created on a different desktop, we need to
+ clone the class object to the desktop heap of the window! */
+ ClassSize = (SIZE_T)BaseClass->ClassExtraDataOffset +
+ (SIZE_T)BaseClass->ClsExtra;
+
+ Class = DesktopHeapAlloc(Desktop,
+ ClassSize);
+ if (Class != NULL)
+ {
+ /* simply clone the class */
+ RtlCopyMemory(Class,
+ BaseClass,
+ ClassSize);
+
+ /* update some pointers and link the class */
+ Class->Next = BaseClass->Clone;
+ Class->Clone = NULL;
+ Class->Base = BaseClass;
+ Class->Desktop = Desktop;
+ Class->Windows = 0;
+ (void)InterlockedExchangePointer(&BaseClass->Clone,
+ Class);
+ }
+ else
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ }
+ }
+
+ return Class;
+}
+
+PWINDOWCLASS
+IntReferenceClass(IN PWINDOWCLASS BaseClass,
+ IN PDESKTOP Desktop)
+{
+ PWINDOWCLASS Class;
+
+ Class = IntGetClassForDesktop(BaseClass,
+ Desktop);
+ if (Class != NULL)
+ {
+ Class->Windows++;
+ }
+
+ return Class;
+}
+
+VOID
+IntDereferenceClass(IN OUT PWINDOWCLASS Class,
+ IN PDESKTOP Desktop,
+ IN PW32PROCESSINFO pi)
+{
+ PWINDOWCLASS *PrevLink, BaseClass, CurrentClass;
+
+ BaseClass = Class->Base;
+
+ if (--Class->Windows == 0)
+ {
+ if (BaseClass == Class)
+ {
+ ASSERT(Class->Base == Class);
+
+ /* check if there are clones of the class on other desktops,
+ link the first clone in if possible. If there are no clones
+ then leave the class on the desktop heap... */
+ if (BaseClass->Clone != NULL)
+ {
+ PWINDOWCLASS NewBase = BaseClass->Clone;
+
+ /* locate the base class and unlink it */
+ if (BaseClass->System)
+ PrevLink = &pi->SystemClassList;
+ else if (BaseClass->Global)
+ PrevLink = &pi->GlobalClassList;
+ else
+ PrevLink = &pi->LocalClassList;
+
+ CurrentClass = *PrevLink;
+ while (CurrentClass != BaseClass)
+ {
+ ASSERT(CurrentClass != NULL);
+
+ PrevLink = &CurrentClass->Next;
+ CurrentClass = CurrentClass->Next;
+ }
+
+ ASSERT(CurrentClass == BaseClass);
+
+ NewBase->Clone = NewBase->Next;
+ NewBase->Next = BaseClass->Next;
+ NewBase->Base = NewBase;
+
+ /* update all clones */
+ CurrentClass = NewBase->Clone;
+ while (CurrentClass != NULL)
+ {
+ ASSERT(CurrentClass->Clone == NULL);
+
+ CurrentClass->Base = NewBase;
+
+ CurrentClass = CurrentClass->Next;
+ }
+
+ /* link in the new base class */
+ (void)InterlockedExchangePointer(PrevLink,
+ NewBase);
+
+ /* destroy the class, there's still another clone of the class
+ that now serves as a base class. Make sure we don't destruct
+ resources shared by all classes (Base = NULL)! */
+ BaseClass->Base = NULL;
+ BaseClass->Clone = NULL;
+ IntDestroyClass(BaseClass);
+ }
+ }
+ else
+ {
+ /* locate the cloned class and unlink it */
+ PrevLink = &BaseClass->Clone;
+ CurrentClass = BaseClass->Clone;
+ while (CurrentClass != Class)
+ {
+ ASSERT(CurrentClass != NULL);
+
+ PrevLink = &CurrentClass->Next;
+ CurrentClass = CurrentClass->Next;
+ }
+
+ ASSERT(CurrentClass == Class);
+
+ (void)InterlockedExchangePointer(PrevLink,
+ Class->Next);
+
+ ASSERT(Class->Base == BaseClass);
+ ASSERT(Class->Clone == NULL);
+
+ /* the class was just a clone, we don't need it anymore */
+ IntDestroyClass(Class);
+ }
+ }
+}
+
+static PWINDOWCLASS
+IntCreateClass(IN CONST WNDCLASSEXW* lpwcx,
+ IN PUNICODE_STRING ClassName,
+ IN PUNICODE_STRING MenuName,
+ IN WNDPROC wpExtra,
+ IN DWORD dwFlags,
+ IN PDESKTOP Desktop,
+ IN PW32PROCESSINFO pi)
+{
+ SIZE_T ClassSize;
+ PWINDOWCLASS Class = NULL;
+ RTL_ATOM Atom;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ if (!IntRegisterClassAtom(ClassName,
+ &Atom))
+ {
+ DPRINT1("Failed to register class atom!\n");
+ return NULL;
+ }
+
+ ClassSize = sizeof(WINDOWCLASS) + lpwcx->cbClsExtra;
+ ClassSize += ClassName->Length + sizeof(UNICODE_NULL);
+ ClassSize += MenuName->Length + sizeof(UNICODE_NULL);
+ if (ClassName->Length != 0)
+ ClassSize += RtlUnicodeStringToAnsiSize(ClassName);
+ if (MenuName->Length != 0)
+ ClassSize += RtlUnicodeStringToAnsiSize(MenuName);
+
+ if (Desktop != NULL)
+ {
+ Class = DesktopHeapAlloc(Desktop,
+ ClassSize);
+ }
+ else
+ {
+ /* FIXME - the class was created before being connected
+ to a desktop. It is possible for the desktop window,
+ but should it be allowed for any other case? */
+ Class = UserHeapAlloc(ClassSize);
+ }
+
+ if (Class != NULL)
+ {
+ RtlZeroMemory(Class,
+ sizeof(ClassSize));
+
+ Class->Desktop = Desktop;
+ Class->Base = Class;
+ Class->Atom = Atom;
+
+ if (dwFlags & REGISTERCLASS_SYSTEM)
+ {
+ dwFlags &= ~REGISTERCLASS_ANSI;
+ Class->WndProcExtra = wpExtra;
+ Class->System = TRUE;
+ }
+
+ _SEH_TRY
+ {
+ PWSTR strBuf;
+ PSTR strBufA;
+ ANSI_STRING AnsiString;
+
+ /* need to protect with SEH since accessing the WNDCLASSEX structure
+ and string buffers might raise an exception! We don't want to
+ leak memory... */
+ Class->WndProc = lpwcx->lpfnWndProc;
+ Class->Style = lpwcx->style;
+ Class->ClsExtra = lpwcx->cbClsExtra;
+ Class->WndExtra = lpwcx->cbWndExtra;
+ Class->hInstance = lpwcx->hInstance;
+ Class->hIcon = lpwcx->hIcon; /* FIXME */
+ Class->hIconSm = lpwcx->hIconSm; /* FIXME */
+ Class->hCursor = lpwcx->hCursor; /* FIXME */
+ Class->hbrBackground = lpwcx->hbrBackground;
+
+ /* make a copy of the string */
+ strBuf = (PWSTR)(Class + 1);
+ if (MenuName->Length != 0)
+ {
+ Class->MenuName = strBuf;
+ RtlCopyMemory(Class->MenuName,
+ MenuName->Buffer,
+ MenuName->Length);
+
+ strBuf += (MenuName->Length / sizeof(WCHAR)) + 1;
+ }
+ else
+ Class->MenuName = MenuName->Buffer;
+
+ /* save an ansi copy of the string */
+ strBufA = (PSTR)strBuf;
+ if (MenuName->Length != 0)
+ {
+ Class->AnsiMenuName = strBufA;
+ AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(MenuName);
+ AnsiString.Buffer = strBufA;
+ Status = RtlUnicodeStringToAnsiString(&AnsiString,
+ MenuName,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to convert unicode menu name to ansi!\n");
+
+ /* life would've been much prettier if ntoskrnl exported
RtlRaiseStatus()... */
+ _SEH_LEAVE;
+ }
+
+ strBufA += AnsiString.Length + 1;
+ }
+ else
+ Class->AnsiMenuName = (PSTR)MenuName->Buffer;
+
+ /* calculate the offset of the extra data */
+ Class->ClassExtraDataOffset = (ULONG_PTR)strBufA - (ULONG_PTR)Class;
+
+ if (!(dwFlags & REGISTERCLASS_ANSI))
+ Class->Unicode = TRUE;
+
+ if (Class->Style & CS_GLOBALCLASS)
+ Class->Global = TRUE;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed creating the class: 0x%x\n", Status);
+
+ SetLastNtError(Status);
+
+ DesktopHeapFree(Desktop,
+ Class);
+ Class = NULL;
+
+ IntDeregisterClassAtom(Atom);
+ }
+ }
+ else
+ {
+ DPRINT1("Failed to allocate class on Desktop 0x%p\n", Desktop);
+
+ IntDeregisterClassAtom(Atom);
+
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ }
+
+ return Class;
+}
+
+static PWINDOWCLASS
+IntFindClass(IN RTL_ATOM Atom,
+ IN HINSTANCE hInstance,
+ IN PWINDOWCLASS *ClassList,
+ OUT PWINDOWCLASS **Link OPTIONAL)
+{
+ PWINDOWCLASS Class, *PrevLink = ClassList;
+
+ Class = *PrevLink;
+ while (Class != NULL)
+ {
+ if (Class->Atom == Atom &&
+ (hInstance == NULL || Class->hInstance == hInstance) &&
+ !Class->Destroying)
+ {
+ ASSERT(Class->Base == Class);
+
+ if (Link != NULL)
+ *Link = PrevLink;
+ break;
+ }
+
+ PrevLink = &Class->Next;
+ Class = Class->Next;
+ }
+
+ 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,
+ IN PW32PROCESSINFO pi OPTIONAL,
+ OUT PWINDOWCLASS *BaseClass OPTIONAL,
+ OUT PWINDOWCLASS **Link OPTIONAL)
+{
+ RTL_ATOM Atom = (RTL_ATOM)0;
+
+ if (ClassName->Length != 0)
+ {
+ WCHAR szBuf[65];
+ PWSTR AtomName;
+ NTSTATUS Status;
+
+ /* NOTE: Caller has to protect the call with SEH! */
+
+ if (ClassName->Length != 0)
+ {
+ /* FIXME - Don't limit to 64 characters! use SEH when allocating memory!
*/
+ if (ClassName->Length / sizeof(WCHAR) >= sizeof(szBuf) /
sizeof(szBuf[0]))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return (RTL_ATOM)0;
+ }
+
+ /* We need to make a local copy of the class name! The caller could
+ modify the buffer and we could overflow in RtlLookupAtomInAtomTable.
+ We're protected by SEH, but the ranges that might be accessed were
+ not probed... */
+ RtlCopyMemory(szBuf,
+ ClassName->Buffer,
+ ClassName->Length);
+ szBuf[ClassName->Length / sizeof(WCHAR)] = UNICODE_NULL;
+ AtomName = szBuf;
+ }
+ else
+ AtomName = ClassName->Buffer;
+
+ /* lookup the atom */
+ Status = RtlLookupAtomInAtomTable(gAtomTable,
+ AtomName,
+ &Atom);
+ if (!NT_SUCCESS(Status))
+ {
+ if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+ {
+ SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS);
+ }
+ else
+ {
+ SetLastNtError(Status);
+ }
+ }
+ }
+ else
+ {
+ ASSERT(IS_ATOM(ClassName->Buffer));
+ Atom = (RTL_ATOM)((ULONG_PTR)ClassName->Buffer);
+ }
+
+ if (BaseClass != NULL && Atom != (RTL_ATOM)0)
+ {
+ PWINDOWCLASS Class;
+
+ /* attempt to locate the class object */
+
+ ASSERT(pi != NULL);
+
+ /* Step 1: try to find an exact match of locally registered classes */
+ Class = IntFindClass(Atom,
+ hInstance,
+ &pi->LocalClassList,
+ Link);
+ if (Class != NULL)
+ {
+ goto FoundClass;
+ }
+
+ /* Step 2: try to find any globally registered class. The hInstance
+ is not relevant for global classes */
+ Class = IntFindClass(Atom,
+ NULL,
+ &pi->GlobalClassList,
+ Link);
+ if (Class != NULL)
+ {
+ goto FoundClass;
+ }
+
+ /* Step 3: try to find a system class */
+ Class = IntFindClass(Atom,
+ NULL,
+ &pi->SystemClassList,
+ Link);
+
+ if (Class == NULL)
+ {
+ SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
+ return (RTL_ATOM)0;
+ }
+
+FoundClass:
+ *BaseClass = Class;
+ }
+
+ return Atom;
+}
+
+static PWINDOWCLASS
+IntClassResizeInternal(IN OUT PWINDOWCLASS Class,
+ IN INT ClsExtraNew,
+ IN PWINDOWCLASS *List)
+{
+ PWINDOWCLASS *PrevLink, CurrentClass, NewClass;
+ SIZE_T NewSize;
+
+ /* temporarily unlink the class, as resizing it may change it's location */
+ PrevLink = List;
+ CurrentClass = *PrevLink;
+ while (CurrentClass != Class)
+ {
+ ASSERT(CurrentClass != NULL);
+
+ PrevLink = &CurrentClass->Next;
+ CurrentClass = CurrentClass->Next;
+ }
+
+ ASSERT(CurrentClass == Class);
+
+ (void)InterlockedExchangePointer(PrevLink,
+ Class->Next);
+
+ NewSize = (SIZE_T)ClsExtraNew + Class->ClassExtraDataOffset;
+ if (Class->Desktop != NULL)
+ {
+ NewClass = DesktopHeapReAlloc(Class->Desktop,
+ Class,
+ NewSize);
+ }
+ else
+ {
+ NewClass = UserHeapReAlloc(Class,
+ NewSize);
+ }
+
+ if (NewClass == NULL)
+ {
+ /* link in the class again */
+ (void)InterlockedExchangePointer(PrevLink,
+ Class);
+
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+
+ if (Class != NewClass)
+ {
+ /* adjust the menu name pointers, if neccessary */
+ if (NewClass->MenuName != NULL &&
!IS_INTRESOURCE(NewClass->MenuName) &&
+ NewClass->MenuName == (PWSTR)(NewClass + 1))
+ {
+ ULONG_PTR PtrDelta = (ULONG_PTR)NewClass - (ULONG_PTR)Class;
+
+ NewClass->MenuName = (PWSTR)((ULONG_PTR)NewClass->MenuName +
PtrDelta);
+ NewClass->AnsiMenuName = (PSTR)((ULONG_PTR)NewClass->MenuName +
PtrDelta);
+ }
+
+ Class = NewClass;
+ }
+
+ if (Class->ClsExtra < ClsExtraNew)
+ {
+ /* zero the memory allocated */
+ RtlZeroMemory((PVOID)((ULONG_PTR)Class + Class->ClassExtraDataOffset +
Class->ClsExtra),
+ ClsExtraNew - Class->ClsExtra);
+ }
+
+ /* link in the class again */
+ (void)InterlockedExchangePointer(PrevLink,
+ Class);
+
+ return Class;
+}
+
+static BOOL
+IntClassResize(IN OUT PWINDOWCLASS Class,
+ IN PW32PROCESSINFO pi,
+ IN INT ClsExtraNew)
+{
+ PWINDOWCLASS *List, *CloneList, NewClass, Clone, FailedResize = NULL;
+ BOOL FailOnResize;
+
+ if (pi == NULL)
+ return FALSE;
+
+ /* first modify the base class, then the clones */
+ Class = Class->Base;
+
+ if (ClsExtraNew < 0 ||
+ (ULONG_PTR)ClsExtraNew + Class->ClassExtraDataOffset <
Class->ClassExtraDataOffset)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (Class->System)
+ List = &pi->SystemClassList;
+ else if (Class->Global)
+ List = &pi->GlobalClassList;
+ else
+ List = &pi->LocalClassList;
+
+ FailOnResize = Class->ClsExtra < ClsExtraNew;
+
+ /* resize the base class */
+ NewClass = IntClassResizeInternal(Class,
+ ClsExtraNew,
+ List);
+ if (NewClass == NULL)
+ {
+ if (FailOnResize)
+ {
+ DPRINT1("Failed to resize the base class\n");
+ return FALSE;
+ }
+ }
+ else
+ Class = NewClass;
+
+ /* resize the clones */
+ CloneList = &Class->Clone;
+ Clone = Class->Clone;
+ while (Clone != NULL)
+ {
+ NewClass = IntClassResizeInternal(Clone,
+ ClsExtraNew,
+ CloneList);
+
+ if (NewClass == NULL)
+ {
+ if (FailOnResize)
+ {
+ /* roll back all changes */
+ FailedResize = Clone;
+ break;
+ }
+ }
+ else
+ Clone = NewClass;
+
+ /* save the pointer to the base class in case it changed */
+ Clone->Base = Class;
+
+ Clone = Clone->Next;
+ }
+
+ if (FailedResize != NULL)
+ {
+ /* failed to resize one clone, roll back the changes to all
+ other clones and to the base class */
+ DPRINT1("Failed to resize the cloned class 0x%p\n", FailedResize);
+
+ /* roll back the changes made to the base class */
+ NewClass = IntClassResizeInternal(Class,
+ Class->ClsExtra,
+ List);
+ if (NewClass != NULL)
+ Class = NewClass;
+
+ /* roll back all changes made to the class clones */
+ CloneList = &Class->Clone;
+ Clone = Class->Clone;
+ while (Clone != FailedResize)
+ {
+ ASSERT(Clone != NULL);
+
+ NewClass = IntClassResizeInternal(Clone,
+ Class->ClsExtra,
+ CloneList);
+ if (NewClass != NULL)
+ Clone = NewClass;
+
+ /* save the pointer to the base class in case it changed */
+ Clone->Base = Class;
+
+ CloneList = &Clone->Next;
+ Clone = Clone->Next;
+ }
+
+ return FALSE;
+ }
+ else
+ {
+ /* all classes were successfully resized,
+ save the new extra data size */
+ Class->ClsExtra = ClsExtraNew;
+ Clone = Class->Clone;
+ while (Clone != NULL)
+ {
+ Clone->ClsExtra = ClsExtraNew;
+ Clone = Clone->Next;
+ }
+
+ return TRUE;
+ }
+}
+
+RTL_ATOM
+UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
+ IN PUNICODE_STRING ClassName,
+ IN PUNICODE_STRING MenuName,
+ IN HANDLE hMenu, /* FIXME */
+ IN WNDPROC wpExtra,
+ IN DWORD dwFlags)
+{
+ PW32THREADINFO ti;
+ PW32PROCESSINFO pi;
+ PWINDOWCLASS Class;
+ RTL_ATOM ClassAtom;
+ RTL_ATOM Ret = (RTL_ATOM)0;
+
+ /* NOTE: Accessing the buffers in ClassName and MenuName may raise exceptions! */
+
+ ti = GetW32ThreadInfo();
+ if (ti == NULL)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return (RTL_ATOM)0;
+ }
+
+ pi = ti->kpi;
+
+ /* try to find a previously registered class */
+ ClassAtom = IntGetClassAtom(ClassName,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (ClassAtom != (RTL_ATOM)0)
+ {
+ Class = IntFindClass(ClassAtom,
+ lpwcx->hInstance,
+ &pi->LocalClassList,
+ NULL);
+ if (Class != NULL)
+ {
+ goto ClassAlreadyExists;
+ }
+
+ /* if CS_GLOBALCLASS is set, try to find a previously registered global class.
+ Re-registering system classes as global classes seems to be allowed,
+ so we don't fail */
+ if (lpwcx->style & CS_GLOBALCLASS)
+ {
+ Class = IntFindClass(ClassAtom,
+ NULL,
+ ((dwFlags & REGISTERCLASS_SYSTEM) ?
+ &pi->SystemClassList :
&pi->GlobalClassList),
+ NULL);
+ if (Class != NULL)
+ {
+ClassAlreadyExists:
+ DPRINT1("Class 0x%p does already exist!\n", ClassAtom);
+ SetLastWin32Error(ERROR_CLASS_ALREADY_EXISTS);
+ return (RTL_ATOM)0;
+ }
+ }
+ }
+
+ ASSERT(ti->Desktop != NULL);
+
+ Class = IntCreateClass(lpwcx,
+ ClassName,
+ MenuName,
+ wpExtra,
+ dwFlags,
+ ti->Desktop,
+ pi);
+
+ if (Class != NULL)
+ {
+ PWINDOWCLASS *List;
+
+ /* FIXME - pass the PMENU pointer to IntCreateClass instead! */
+ Class->hMenu = hMenu;
+
+ /* Register the class */
+ if (Class->System)
+ List = &pi->SystemClassList;
+ else if (Class->Global)
+ List = &pi->GlobalClassList;
+ else
+ List = &pi->LocalClassList;
+
+ Class->Next = *List;
+ (void)InterlockedExchangePointer(List,
+ Class);
+
+ Ret = Class->Atom;
+ }
+
+ return Ret;
+}
+
+BOOL
+UserUnregisterClass(IN PUNICODE_STRING ClassName,
+ IN HINSTANCE hInstance)
+{
+ PWINDOWCLASS *Link;
+ PW32PROCESSINFO pi;
+ RTL_ATOM ClassAtom;
+ PWINDOWCLASS Class;
+
+ pi = GetW32ProcessInfo();
+ if (pi == NULL)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ /* NOTE: Accessing the buffer in ClassName may raise an exception! */
+ ClassAtom = IntGetClassAtom(ClassName,
+ hInstance,
+ pi,
+ &Class,
+ &Link);
+ if (ClassAtom == (RTL_ATOM)0)
+ {
+ return FALSE;
+ }
+
+ ASSERT(Class != NULL);
+
+ if (Class->System)
+ {
+ DPRINT1("Attempted to unregister system class 0x%p!\n", ClassAtom);
+ SetLastWin32Error(ERROR_ACCESS_DENIED);
+ return FALSE;
+ }
+
+ if (Class->Windows != 0 ||
+ Class->Clone != NULL)
+ {
+ SetLastWin32Error(ERROR_CLASS_HAS_WINDOWS);
+ return FALSE;
+ }
+
+ /* must be a base class! */
+ ASSERT(Class->Base == Class);
+
+ /* unlink the class */
+ *Link = Class->Next;
+
+ /* finally free the resources */
+ IntDestroyClass(Class);
+ return TRUE;
+}
+
+INT
+UserGetClassName(IN PWINDOWCLASS Class,
+ IN OUT PUNICODE_STRING ClassName,
+ IN BOOL Ansi)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ WCHAR szStaticTemp[32];
+ PWSTR szTemp = NULL;
+ ULONG BufLen = sizeof(szStaticTemp);
+ INT Ret = 0;
+
+ /* Note: Accessing the buffer in ClassName may raise an exception! */
+
+ _SEH_TRY
+ {
+ if (Ansi)
+ {
+ PANSI_STRING AnsiClassName = (PANSI_STRING)ClassName;
+ UNICODE_STRING UnicodeClassName;
+
+ /* limit the size of the static buffer on the stack to the
+ size of the buffer provided by the caller */
+ if (BufLen / sizeof(WCHAR) > AnsiClassName->MaximumLength)
+ {
+ BufLen = AnsiClassName->MaximumLength * sizeof(WCHAR);
+ }
+
+ /* find out how big the buffer needs to be */
+ Status = RtlQueryAtomInAtomTable(gAtomTable,
+ Class->Atom,
+ NULL,
+ NULL,
+ szStaticTemp,
+ &BufLen);
+ if (Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ if (BufLen / sizeof(WCHAR) > AnsiClassName->MaximumLength)
+ {
+ /* the buffer required exceeds the ansi buffer provided,
+ pretend like we're using the ansi buffer and limit the
+ size to the buffer size provided */
+ BufLen = AnsiClassName->MaximumLength * sizeof(WCHAR);
+ }
+
+ /* allocate a temporary buffer that can hold the unicode class name */
+ szTemp = ExAllocatePool(PagedPool,
+ BufLen);
+ if (szTemp == NULL)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ _SEH_LEAVE;
+ }
+
+ /* query the class name */
+ Status = RtlQueryAtomInAtomTable(gAtomTable,
+ Class->Atom,
+ NULL,
+ NULL,
+ szTemp,
+ &BufLen);
+ }
+ else
+ szTemp = szStaticTemp;
+
+ if (NT_SUCCESS(Status))
+ {
+ /* convert the atom name to ansi */
+
+ RtlInitUnicodeString(&UnicodeClassName,
+ szTemp);
+
+ Status = RtlUnicodeStringToAnsiString(AnsiClassName,
+ &UnicodeClassName,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ _SEH_LEAVE;
+ }
+ }
+
+ Ret = BufLen / sizeof(WCHAR);
+ }
+ else /* !Ansi */
+ {
+ BufLen = ClassName->MaximumLength;
+
+ /* query the atom name */
+ Status = RtlQueryAtomInAtomTable(gAtomTable,
+ Class->Atom,
+ NULL,
+ NULL,
+ ClassName->Buffer,
+ &BufLen);
+
+ if (NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ _SEH_LEAVE;
+ }
+
+ Ret = BufLen / sizeof(WCHAR);
+ }
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+
+ if (Ansi && szTemp != NULL && szTemp != szStaticTemp)
+ {
+ ExFreePool(szTemp);
+ }
+
+ return Ret;
+}
+
+ULONG_PTR
+UserGetClassLongPtr(IN PWINDOWCLASS Class,
+ IN INT Index,
+ IN BOOL Ansi)
+{
+ ULONG_PTR Ret = 0;
+
+ if (Index > 0)
+ {
+ PULONG_PTR Data;
+
+ if (Index + sizeof(ULONG_PTR) < Index ||
+ Index + sizeof(ULONG_PTR) > Class->ClsExtra)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ Data = (PULONG_PTR)((ULONG_PTR)Class + Class->ClassExtraDataOffset);
+
+ /* FIXME - Data might be a unaligned pointer! Might be a problem on
+ certain architectures, maybe using RtlCopyMemory is a
+ better choice for those architectures! */
+ return *Data;
+ }
+
+ switch (Index)
+ {
+ case GCL_CBWNDEXTRA:
+ Ret = (ULONG_PTR)Class->WndExtra;
+ break;
+
+ case GCL_CBCLSEXTRA:
+ Ret = (ULONG_PTR)Class->ClsExtra;
+ break;
+
+ case GCLP_HBRBACKGROUND:
+ Ret = (ULONG_PTR)Class->hbrBackground;
+ 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_HMODULE:
+ Ret = (ULONG_PTR)Class->hInstance;
+ break;
+
+ case GCLP_MENUNAME:
+ /* NOTE: Returns pointer in kernel heap! */
+ if (Ansi)
+ Ret = (ULONG_PTR)Class->AnsiMenuName;
+ else
+ Ret = (ULONG_PTR)Class->MenuName;
+ break;
+
+ case GCL_STYLE:
+ Ret = (ULONG_PTR)Class->Style;
+ break;
+
+ case GCLP_WNDPROC:
+ Ret = (ULONG_PTR)IntGetClassWndProc(Class,
+ GetW32ProcessInfo(),
+ Ansi);
+ break;
+
+ case GCW_ATOM:
+ Ret = (ULONG_PTR)Class->Atom;
+ break;
+
+ default:
+ SetLastWin32Error(ERROR_INVALID_INDEX);
+ break;
+ }
+
+ return Ret;
+}
+
+static BOOL
+IntSetClassMenuName(IN PWINDOWCLASS Class,
+ IN PUNICODE_STRING MenuName)
+{
+ BOOL Ret = FALSE;
+
+ /* change the base class first */
+ Class = Class->Base;
+
+ if (MenuName->Length != 0)
+ {
+ ANSI_STRING AnsiString;
+ PWSTR strBufW;
+
+ AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(MenuName);
+
+ strBufW = UserHeapAlloc(MenuName->Length + sizeof(UNICODE_NULL) +
+ AnsiString.MaximumLength);
+ if (strBufW != NULL)
+ {
+ _SEH_TRY
+ {
+ NTSTATUS Status;
+
+ /* copy the unicode string */
+ RtlCopyMemory(strBufW,
+ MenuName->Buffer,
+ MenuName->Length);
+ strBufW[MenuName->Length / sizeof(WCHAR)] = UNICODE_NULL;
+
+ /* create an ansi copy of the string */
+ AnsiString.Buffer = (PSTR)(strBufW + (MenuName->Length /
sizeof(WCHAR)) + 1);
+ Status = RtlUnicodeStringToAnsiString(&AnsiString,
+ MenuName,
+ FALSE);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ _SEH_LEAVE;
+ }
+
+ Ret = TRUE;
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+
+ if (Ret)
+ {
+ /* update the base class */
+ IntFreeClassMenuName(Class);
+ Class->MenuName = strBufW;
+ Class->AnsiMenuName = AnsiString.Buffer;
+
+ /* update the clones */
+ Class = Class->Clone;
+ while (Class != NULL)
+ {
+ Class->MenuName = strBufW;
+ Class->AnsiMenuName = AnsiString.Buffer;
+
+ Class = Class->Next;
+ }
+ }
+ else
+ {
+ DPRINT1("Failed to copy class menu name!\n");
+ UserHeapFree(strBufW);
+ }
+ }
+ else
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ }
+ else
+ {
+ ASSERT(IS_INTRESOURCE(MenuName->Buffer));
+
+ /* update the base class */
+ IntFreeClassMenuName(Class);
+ Class->MenuName = MenuName->Buffer;
+ Class->AnsiMenuName = (PSTR)MenuName->Buffer;
+
+ /* update the clones */
+ Class = Class->Clone;
+ while (Class != NULL)
+ {
+ Class->MenuName = MenuName->Buffer;
+ Class->AnsiMenuName = (PSTR)MenuName->Buffer;
+
+ Class = Class->Next;
+ }
+
+ Ret = TRUE;
+ }
+
+ return Ret;
+}
+
+ULONG_PTR
+UserSetClassLongPtr(IN PWINDOWCLASS Class,
+ IN INT Index,
+ IN ULONG_PTR NewLong,
+ IN BOOL Ansi)
+{
+ ULONG_PTR Ret = 0;
+
+ /* NOTE: For GCLP_MENUNAME and GCW_ATOM this function may raise an exception! */
+
+ /* change the information in the base class first, then update the clones */
+ Class = Class->Base;
+
+ if (Index > 0)
+ {
+ PULONG_PTR Data;
+
+ if (Index + sizeof(ULONG_PTR) < Index ||
+ Index + sizeof(ULONG_PTR) > Class->ClsExtra)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ Data = (PULONG_PTR)((ULONG_PTR)Class + Class->ClassExtraDataOffset);
+
+ /* FIXME - Data might be a unaligned pointer! Might be a problem on
+ certain architectures, maybe using RtlCopyMemory is a
+ better choice for those architectures! */
+ Ret = *Data;
+ *Data = NewLong;
+
+ /* update the clones */
+ Class = Class->Clone;
+ while (Class != NULL)
+ {
+ *(PULONG_PTR)((ULONG_PTR)Class + Class->ClassExtraDataOffset) = NewLong;
+ Class = Class->Next;
+ }
+
+ return Ret;
+ }
+
+ switch (Index)
+ {
+ case GCL_CBWNDEXTRA:
+ Ret = (ULONG_PTR)Class->WndExtra;
+ Class->WndExtra = (INT)NewLong;
+
+ /* update the clones */
+ Class = Class->Clone;
+ while (Class != NULL)
+ {
+ Class->WndExtra = (INT)NewLong;
+ Class = Class->Next;
+ }
+
+ break;
+
+ case GCL_CBCLSEXTRA:
+ Ret = (ULONG_PTR)Class->ClsExtra;
+ if (Class->ClsExtra != (INT)NewLong)
+ {
+ if (!IntClassResize(Class,
+ GetW32ProcessInfo(),
+ (INT)NewLong))
+ {
+ Ret = 0;
+ }
+ }
+ break;
+
+ case GCLP_HBRBACKGROUND:
+ Ret = (ULONG_PTR)Class->hbrBackground;
+ Class->hbrBackground = (HBRUSH)NewLong;
+
+ /* update the clones */
+ Class = Class->Clone;
+ while (Class != NULL)
+ {
+ Class->hbrBackground = (HBRUSH)NewLong;
+ Class = Class->Next;
+ }
+ break;
+
+ case GCLP_HCURSOR:
+ /* FIXME - get handle from pointer to CURSOR object */
+ Ret = (ULONG_PTR)Class->hCursor;
+ Class->hCursor = (HANDLE)NewLong;
+
+ /* update the clones */
+ Class = Class->Clone;
+ while (Class != NULL)
+ {
+ Class->hCursor = (HANDLE)NewLong;
+ Class = Class->Next;
+ }
+ break;
+
+ case GCLP_HICON:
+ /* FIXME - get handle from pointer to ICON object */
+ Ret = (ULONG_PTR)Class->hIcon;
+ Class->hIcon = (HANDLE)NewLong;
+
+ /* update the clones */
+ Class = Class->Clone;
+ while (Class != NULL)
+ {
+ Class->hIcon = (HANDLE)NewLong;
+ Class = Class->Next;
+ }
+ break;
+
+ case GCLP_HICONSM:
+ /* FIXME - get handle from pointer to ICON object */
+ Ret = (ULONG_PTR)Class->hIconSm;
+ Class->hIconSm = (HANDLE)NewLong;
+
+ /* update the clones */
+ Class = Class->Clone;
+ while (Class != NULL)
+ {
+ Class->hIconSm = (HANDLE)NewLong;
+ Class = Class->Next;
+ }
+ break;
+
+ case GCLP_HMODULE:
+ Ret = (ULONG_PTR)Class->hInstance;
+ Class->hInstance = (HINSTANCE)NewLong;
+
+ /* update the clones */
+ Class = Class->Clone;
+ while (Class != NULL)
+ {
+ Class->hInstance = (HINSTANCE)NewLong;
+ Class = Class->Next;
+ }
+ break;
+
+ case GCLP_MENUNAME:
+ {
+ PUNICODE_STRING Value = (PUNICODE_STRING)NewLong;
+
+ if (!IntSetClassMenuName(Class,
+ Value))
+ {
+ DPRINT("Setting the class menu name failed!\n");
+ }
+
+ /* FIXME - really return NULL? Wine does so... */
+ break;
+ }
+
+ case GCL_STYLE:
+ Ret = (ULONG_PTR)Class->Style;
+ Class->Style = (UINT)NewLong;
+
+ /* FIXME - what if the CS_GLOBALCLASS style is changed? should we
+ move the class to the appropriate list? For now, we save
+ the original value in Class->Global, so we can always
+ locate the appropriate list */
+
+ /* update the clones */
+ Class = Class->Clone;
+ while (Class != NULL)
+ {
+ Class->Style = (UINT)NewLong;
+ Class = Class->Next;
+ }
+ break;
+
+ case GCLP_WNDPROC:
+ Ret = (ULONG_PTR)IntSetClassWndProc(Class,
+ (WNDPROC)NewLong,
+ Ansi);
+ break;
+
+ case GCW_ATOM:
+ {
+ PUNICODE_STRING Value = (PUNICODE_STRING)NewLong;
+
+ Ret = (ULONG_PTR)Class->Atom;
+ if (!IntSetClassAtom(Class,
+ Value))
+ {
+ Ret = 0;
+ }
+ break;
+ }
+
+ default:
+ SetLastWin32Error(ERROR_INVALID_INDEX);
+ break;
+ }
+
+ return Ret;
+}
+
+static BOOL
+UserGetClassInfo(IN PWINDOWCLASS Class,
+ OUT PWNDCLASSEXW lpwcx,
+ IN BOOL Ansi)
+{
+ 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->cbClsExtra = Class->ClsExtra;
+ lpwcx->cbWndExtra = Class->WndExtra;
+ lpwcx->hInstance = Class->hInstance;
+ lpwcx->hIcon = Class->hIcon; /* FIXME - get handle from pointer */
+ lpwcx->hCursor = Class->hCursor; /* FIXME - get handle from pointer */
+ lpwcx->hbrBackground = Class->hbrBackground;
+
+ if (Ansi)
+ ((PWNDCLASSEXA)lpwcx)->lpszMenuName = Class->AnsiMenuName;
+ else
+ lpwcx->lpszMenuName = Class->MenuName;
+
+ lpwcx->lpszClassName = (LPCWSTR)((ULONG_PTR)Class->Atom); /* FIXME - return the
string? */
+
+ lpwcx->hIconSm = Class->hIconSm; /* FIXME - get handle from pointer */
+
+ return TRUE;
+}
+
/* SYSCALLS *****************************************************************/
-RTL_ATOM STDCALL
-NtUserRegisterClassExWOW(
- CONST WNDCLASSEXW* lpwcx,
- PUNICODE_STRING ClassName,
- PUNICODE_STRING ClassNameCopy,//huhuhuhu???
- PUNICODE_STRING MenuName,
- WNDPROC wpExtra,
- DWORD Flags,
- DWORD Unknown7,
- HMENU hMenu)
+RTL_ATOM NTAPI
+NtUserRegisterClassEx(IN CONST WNDCLASSEXW* lpwcx,
+ IN PUNICODE_STRING ClassName,
+ IN PUNICODE_STRING MenuName,
+ IN WNDPROC wpExtra,
+ IN DWORD Flags,
+ IN HMENU hMenu)
/*
* FUNCTION:
@@ -452,149 +1819,204 @@
* Atom identifying the new class
*/
{
- WNDCLASSEXW SafeClass;
- NTSTATUS Status;
- RTL_ATOM Atom;
- DECLARE_RETURN(RTL_ATOM);
-
- DPRINT("Enter NtUserRegisterClassExWOW\n");
- UserEnterExclusive();
-
- if (!lpwcx)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( (RTL_ATOM)0);
- }
-
- if (Flags & ~REGISTERCLASS_ALL)
- {
- SetLastWin32Error(ERROR_INVALID_FLAGS);
- RETURN( (RTL_ATOM)0);
- }
-
- Status = MmCopyFromCaller(&SafeClass, lpwcx, sizeof(WNDCLASSEXW));
- if (!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN( (RTL_ATOM)0);
- }
-
- /* Deny negative sizes */
- if (lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( (RTL_ATOM)0);
- }
-
- if (!lpwcx->hInstance)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN( (RTL_ATOM)0);
- }
-
- //FIXME: make ClassName ptr the atom, not buffer
- if (ClassName->Length > 0)
- {
- DPRINT("NtUserRegisterClassExWOW(%S)\n", ClassName->Buffer);
- /* FIXME - Safely copy/verify the buffer first!!! */
- Status = RtlAddAtomToAtomTable(gAtomTable,
- ClassName->Buffer,
- &Atom);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("Failed adding class name (%S) to atom table\n",
- ClassName->Buffer);
- SetLastNtError(Status);
- RETURN((RTL_ATOM)0);
- }
- }
- else
- {
- Atom = (RTL_ATOM)(ULONG)ClassName->Buffer;
- }
-
- if (!Atom)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN(0);
- }
-
- if (!IntRegisterClass(&SafeClass, Flags, wpExtra, MenuName, Atom, hMenu))
- {
- if (ClassName->Length)
- {
- RtlDeleteAtomFromAtomTable(gAtomTable, Atom);
- }
- DPRINT("Failed creating window class object\n");
- RETURN((RTL_ATOM)0);
- }
-
- RETURN(Atom);
-
-CLEANUP:
- DPRINT("Leave NtUserRegisterClassExWOW, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-
-
-DWORD STDCALL
-NtUserGetClassLong(HWND hWnd, DWORD Offset, BOOL Ansi)
-{
- PWINDOW_OBJECT Window;
- DECLARE_RETURN(DWORD);
-
- DPRINT("Enter NtUserGetClassLong\n");
- UserEnterExclusive();
-
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN(0);
- }
-
- RETURN(IntGetClassLong(Window, Offset, Ansi));
-
-CLEANUP:
- DPRINT("Leave NtUserGetClassLong, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-
-
-DWORD STDCALL
+ WNDCLASSEXW CapturedClassInfo = {0};
+ UNICODE_STRING CapturedName = {0}, CapturedMenuName = {0};
+ RTL_ATOM Ret = (RTL_ATOM)0;
+
+ if (Flags & ~REGISTERCLASS_ALL)
+ {
+ SetLastWin32Error(ERROR_INVALID_FLAGS);
+ return Ret;
+ }
+
+ UserEnterExclusive();
+
+ _SEH_TRY
+ {
+ /* Probe the parameters and basic parameter checks */
+ if (ProbeForReadUint(&lpwcx->cbSize) != sizeof(WNDCLASSEXW))
+ {
+ goto InvalidParameter;
+ }
+
+ ProbeForRead(lpwcx,
+ sizeof(WNDCLASSEXW),
+ sizeof(ULONG));
+ RtlCopyMemory(&CapturedClassInfo,
+ lpwcx,
+ sizeof(WNDCLASSEXW));
+
+ CapturedName = ProbeForReadUnicodeString(ClassName);
+ CapturedMenuName = ProbeForReadUnicodeString(MenuName);
+
+ if (CapturedName.Length & 1 || CapturedMenuName.Length & 1 ||
+ CapturedClassInfo.cbClsExtra < 0 ||
+ CapturedClassInfo.cbClsExtra + CapturedName.Length +
+ CapturedMenuName.Length + sizeof(WINDOWCLASS) <
CapturedClassInfo.cbClsExtra ||
+ CapturedClassInfo.cbWndExtra < 0 ||
+ CapturedClassInfo.hInstance == NULL)
+ {
+ goto InvalidParameter;
+ }
+
+ if (CapturedName.Length != 0)
+ {
+ ProbeForRead(CapturedName.Buffer,
+ CapturedName.Length,
+ sizeof(WCHAR));
+ }
+ else
+ {
+ if (!IS_ATOM(CapturedName.Buffer))
+ {
+ goto InvalidParameter;
+ }
+ }
+
+ if (CapturedMenuName.Length != 0)
+ {
+ ProbeForRead(CapturedMenuName.Buffer,
+ CapturedMenuName.Length,
+ sizeof(WCHAR));
+ }
+ else if (CapturedMenuName.Buffer != NULL &&
+ !IS_INTRESOURCE(CapturedMenuName.Buffer))
+ {
+InvalidParameter:
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ _SEH_LEAVE;
+ }
+
+ /* Register the class */
+ Ret = UserRegisterClass(&CapturedClassInfo,
+ &CapturedName,
+ &CapturedMenuName,
+ hMenu, /* FIXME - pass pointer */
+ wpExtra,
+ Flags);
+
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+
+ UserLeave();
+
+ return Ret;
+}
+
+
+
+ULONG_PTR NTAPI
+NtUserGetClassLong(IN HWND hWnd,
+ IN INT Offset,
+ IN BOOL Ansi)
+{
+ PWINDOW_OBJECT Window;
+ ULONG_PTR Ret = 0;
+
+ UserEnterShared();
+
+ Window = UserGetWindowObject(hWnd);
+ if (Window != NULL)
+ {
+ Ret = UserGetClassLongPtr(Window->Class,
+ Offset,
+ Ansi);
+
+ if (Ret != 0 && Offset == GCLP_MENUNAME && !IS_INTRESOURCE(Ret))
+ {
+ Ret = (ULONG_PTR)DesktopHeapAddressToUser(Window->Class->Desktop,
+ (PVOID)Ret);
+ }
+ }
+
+ UserLeave();
+
+ return Ret;
+}
+
+
+
+ULONG_PTR STDCALL
NtUserSetClassLong(HWND hWnd,
- DWORD Offset,
- LONG dwNewLong,
+ INT Offset,
+ ULONG_PTR dwNewLong,
BOOL Ansi)
{
- PWINDOW_OBJECT Window;
- LONG Ret;
- USER_REFERENCE_ENTRY Ref;
- DECLARE_RETURN(DWORD);
-
- DPRINT("Enter NtUserSetClassLong\n");
- UserEnterExclusive();
-
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN(0);
- }
-
- UserRefObjectCo(Window, &Ref);
-
- Ret = IntGetClassLong(Window, Offset, Ansi);
- co_IntSetClassLong(Window, Offset, dwNewLong, Ansi);
-
- UserDerefObjectCo(Window);
-
- RETURN(Ret);
-
-CLEANUP:
- DPRINT("Leave NtUserSetClassLong, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ PW32PROCESSINFO pi;
+ PWINDOW_OBJECT Window;
+ ULONG_PTR Ret = 0;
+
+ UserEnterExclusive();
+
+ pi = GetW32ProcessInfo();
+ if (pi == NULL)
+ goto Cleanup;
+
+ Window = UserGetWindowObject(hWnd);
+ if (Window != NULL)
+ {
+ if (Window->ti->kpi != pi)
+ {
+ SetLastWin32Error(ERROR_ACCESS_DENIED);
+ goto Cleanup;
+ }
+
+ _SEH_TRY
+ {
+ UNICODE_STRING Value;
+
+ /* probe the parameters */
+ if (Offset == GCW_ATOM || Offset == GCLP_MENUNAME)
+ {
+ Value = ProbeForReadUnicodeString((PUNICODE_STRING)dwNewLong);
+ if (Value.Length & 1)
+ {
+ goto InvalidParameter;
+ }
+
+ if (Value.Length != 0)
+ {
+ ProbeForRead(Value.Buffer,
+ Value.Length,
+ sizeof(WCHAR));
+ }
+ else
+ {
+ if (Offset == GCW_ATOM && !IS_ATOM(Value.Buffer))
+ {
+ goto InvalidParameter;
+ }
+ else if (Offset == GCLP_MENUNAME &&
!IS_INTRESOURCE(Value.Buffer))
+ {
+InvalidParameter:
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ _SEH_LEAVE;
+ }
+ }
+
+ dwNewLong = (ULONG_PTR)&Value;
+ }
+
+ Ret = UserSetClassLongPtr(Window->Class,
+ Offset,
+ dwNewLong,
+ Ansi);
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+ }
+
+Cleanup:
+ UserLeave();
+
+ return Ret;
}
DWORD STDCALL
@@ -602,164 +2024,232 @@
DWORD Unknown1,
DWORD Unknown2)
{
- UNIMPLEMENTED;
return(0);
}
+BOOL NTAPI
+NtUserUnregisterClass(IN PUNICODE_STRING ClassNameOrAtom,
+ IN HINSTANCE hInstance)
+{
+ UNICODE_STRING CapturedClassName;
+ BOOL Ret = FALSE;
+
+ UserEnterExclusive();
+
+ _SEH_TRY
+ {
+ /* probe the paramters */
+ CapturedClassName = ProbeForReadUnicodeString(ClassNameOrAtom);
+ if (CapturedClassName.Length & 1)
+ {
+ goto InvalidParameter;
+ }
+
+ if (CapturedClassName.Length != 0)
+ {
+ ProbeForRead(CapturedClassName.Buffer,
+ CapturedClassName.Length,
+ sizeof(WCHAR));
+ }
+ else
+ {
+ if (!IS_ATOM(CapturedClassName.Buffer))
+ {
+InvalidParameter:
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ _SEH_LEAVE;
+ }
+ }
+
+ /* unregister the class */
+ Ret = UserUnregisterClass(&CapturedClassName,
+ hInstance);
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+
+ UserLeave();
+
+ return Ret;
+}
+
+/* NOTE: for system classes hInstance is not NULL here, but User32Instance */
BOOL STDCALL
-NtUserUnregisterClass(
- LPCWSTR ClassNameOrAtom,
- HINSTANCE hInstance, /* can be 0 */
- DWORD Unknown)
-{
- PWNDCLASS_OBJECT Class;
- DECLARE_RETURN(BOOL);
-
- DPRINT("Enter NtUserUnregisterClass(%S)\n", ClassNameOrAtom);
- UserEnterExclusive();
-
- if (!ClassNameOrAtom)
- {
- SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
- RETURN(FALSE);
- }
-
- if (!(Class = ClassGetClassByNameOrAtom(ClassNameOrAtom, hInstance)))
- {
- SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
- RETURN(FALSE);
- }
-
- if (Class->refs)
- {
- /* NOTE: the class will not be freed when its refs become 0 ie. no more
- * windows are using it. I dunno why that is but its how Windows does it (and
Wine).
- * The class will hang around until the process exit. -Gunnar
- */
- SetLastWin32Error(ERROR_CLASS_HAS_WINDOWS);
- RETURN(FALSE);
- }
-
- DestroyClass(Class);
-
- RETURN(TRUE);
-
-CLEANUP:
- DPRINT("Leave NtUserUnregisterClass, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-/* NOTE: for system classes hInstance is not NULL here, but User32Instance */
-DWORD STDCALL
NtUserGetClassInfo(
HINSTANCE hInstance,
- LPCWSTR lpClassName,
+ PUNICODE_STRING ClassName,
LPWNDCLASSEXW lpWndClassEx,
- BOOL Ansi,
- DWORD unknown3)
-{
- PWNDCLASS_OBJECT Class;
- RTL_ATOM Atom;
- DECLARE_RETURN(DWORD);
-
- if (IS_ATOM(lpClassName))
- DPRINT("NtUserGetClassInfo - %x (%lx)\n", lpClassName, hInstance);
- else
- DPRINT("NtUserGetClassInfo - %S (%lx)\n", lpClassName, hInstance);
-
- UserEnterExclusive();
-
- if (!hInstance)
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- RETURN(0);
- }
-
- if (!(Class = ClassGetClassByNameOrAtom(lpClassName, hInstance)))
- {
- SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
- RETURN(0);
- }
-
- lpWndClassEx->cbSize = sizeof(WNDCLASSEXW);
- lpWndClassEx->style = Class->style;
- if (Ansi)
- lpWndClassEx->lpfnWndProc = Class->lpfnWndProcA;
- else
- lpWndClassEx->lpfnWndProc = Class->lpfnWndProcW;
- lpWndClassEx->cbClsExtra = Class->cbClsExtra;
- lpWndClassEx->cbWndExtra = Class->cbWndExtra;
- /* This is not typo, we're really not going to use Class->hInstance here. */
- /* Well, i think its wrong so i changed it -Gunnar */
- lpWndClassEx->hInstance = Class->hInstance;
- lpWndClassEx->hIcon = Class->hIcon;
- lpWndClassEx->hCursor = Class->hCursor;
- lpWndClassEx->hbrBackground = Class->hbrBackground;
- if (Class->lpszMenuName.MaximumLength)
- RtlCopyUnicodeString((PUNICODE_STRING)lpWndClassEx->lpszMenuName,
&Class->lpszMenuName);
- else
- lpWndClassEx->lpszMenuName = Class->lpszMenuName.Buffer;
- lpWndClassEx->lpszClassName = lpClassName;
- lpWndClassEx->hIconSm = Class->hIconSm;
- Atom = Class->Atom;
-
- RETURN(Atom);
-
-CLEANUP:
- DPRINT("Leave NtUserGetClassInfo, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-
-
-DWORD STDCALL
-NtUserGetClassName (
- HWND hWnd,
- LPWSTR lpClassName,
- ULONG nMaxCount /* in TCHARS */
- )
-{
- PWINDOW_OBJECT Window;
- DECLARE_RETURN(DWORD);
- NTSTATUS Status;
-
- UserEnterShared();
- DPRINT("Enter NtUserGetClassName\n");
-
- if (!(Window = UserGetWindowObject(hWnd)))
- {
- RETURN(0);
- }
-
- nMaxCount *= sizeof(WCHAR);
-
- //FIXME: wrap in SEH to protect lpClassName access
- Status = RtlQueryAtomInAtomTable(gAtomTable,
- Window->Class->Atom, NULL, NULL,
- lpClassName, &nMaxCount);
- if (!NT_SUCCESS(Status))
- {
- SetLastNtError(Status);
- RETURN(0);
- }
-
- RETURN(nMaxCount / sizeof(WCHAR));
-
-CLEANUP:
- DPRINT("Leave NtUserGetClassName, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
+ BOOL Ansi)
+{
+ UNICODE_STRING CapturedClassName;
+ PWINDOWCLASS Class;
+ RTL_ATOM ClassAtom;
+ PW32PROCESSINFO pi;
+ BOOL Ret = FALSE;
+
+ UserEnterShared();
+
+ pi = GetW32ProcessInfo();
+ if (pi == NULL)
+ {
+ goto Cleanup;
+ }
+
+ _SEH_TRY
+ {
+ /* probe the paramters */
+ CapturedClassName = ProbeForReadUnicodeString(ClassName);
+ if (CapturedClassName.Length & 1)
+ {
+ goto InvalidParameter;
+ }
+
+ if (CapturedClassName.Length != 0)
+ {
+ ProbeForRead(CapturedClassName.Buffer,
+ CapturedClassName.Length,
+ sizeof(WCHAR));
+ }
+ else
+ {
+ if (!IS_ATOM(CapturedClassName.Buffer))
+ {
+ goto InvalidParameter;
+ }
+ }
+
+ if (ProbeForReadUint(&lpWndClassEx->cbSize) != sizeof(WNDCLASSEXW))
+ {
+InvalidParameter:
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ _SEH_LEAVE;
+ }
+
+ ProbeForWrite(lpWndClassEx,
+ sizeof(WNDCLASSEXW),
+ sizeof(ULONG));
+
+ ClassAtom = IntGetClassAtom(&CapturedClassName,
+ hInstance,
+ pi,
+ &Class,
+ NULL);
+ if (ClassAtom != (RTL_ATOM)0)
+ {
+ Ret = UserGetClassInfo(Class,
+ lpWndClassEx,
+ Ansi);
+
+ if (Ret)
+ {
+ lpWndClassEx->lpszClassName = CapturedClassName.Buffer;
+
+ /* FIXME - handle Class->Desktop == NULL!!!!! */
+
+ if (Class->MenuName != NULL &&
+ !IS_INTRESOURCE(Class->MenuName))
+ {
+ lpWndClassEx->lpszMenuName =
DesktopHeapAddressToUser(Class->Desktop,
+ (Ansi ?
+
(PVOID)Class->AnsiMenuName :
+
(PVOID)Class->MenuName));
+ }
+ }
+ }
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+
+Cleanup:
+ UserLeave();
+
+ return Ret;
+}
+
+
+
+INT NTAPI
+NtUserGetClassName (IN HWND hWnd,
+ OUT PUNICODE_STRING ClassName,
+ IN BOOL Ansi)
+{
+ PWINDOW_OBJECT Window;
+ UNICODE_STRING CapturedClassName;
+ INT Ret = 0;
+
+ UserEnterShared();
+
+ Window = UserGetWindowObject(hWnd);
+ if (Window != NULL)
+ {
+ _SEH_TRY
+ {
+ ProbeForWriteUnicodeString(ClassName);
+ CapturedClassName = *ClassName;
+
+ /* get the class name */
+ Ret = UserGetClassName(Window->Class,
+ &CapturedClassName,
+ Ansi);
+
+ if (Ret != 0)
+ {
+ /* update the Length field */
+ ClassName->Length = CapturedClassName.Length;
+ }
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+ }
+
+ UserLeave();
+
+ return Ret;
}
DWORD STDCALL
NtUserGetWOWClass(DWORD Unknown0,
DWORD Unknown1)
{
- UNIMPLEMENTED;
return(0);
}
+BOOL NTAPI
+NtUserDereferenceWndProcHandle(IN HANDLE wpHandle,
+ OUT PWNDPROC_INFO wpInfo)
+{
+ BOOL Ret = FALSE;
+
+ UserEnterShared();
+
+ _SEH_TRY
+ {
+ ProbeForWrite(wpInfo,
+ sizeof(WNDPROC_INFO),
+ sizeof(ULONG));
+
+ Ret = UserGetCallProcInfo(wpHandle,
+ wpInfo);
+ }
+ _SEH_HANDLE
+ {
+ SetLastWin32Error(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+
+ UserLeave();
+
+ return Ret;
+}
+
/* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c Wed Apr 5 12:05:55 2006
@@ -83,7 +83,7 @@
return NULL;
}
- CurIcon = (PCURICON_OBJECT)UserGetObject(&gHandleTable, hCurIcon, otCursorIcon);
+ CurIcon = (PCURICON_OBJECT)UserGetObject(gHandleTable, hCurIcon, otCursorIcon);
if (!CurIcon)
{
/* we never set ERROR_INVALID_ICON_HANDLE. lets hope noone ever checks for it */
@@ -397,7 +397,7 @@
PCURICON_OBJECT CurIcon;
HANDLE hCurIcon;
- CurIcon = ObmCreateObject(&gHandleTable, &hCurIcon, otCursorIcon,
sizeof(CURICON_OBJECT));
+ CurIcon = ObmCreateObject(gHandleTable, &hCurIcon, otCursorIcon,
sizeof(CURICON_OBJECT));
if(!CurIcon)
{
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/desktop.c Wed Apr 5 12:05:55 2006
@@ -43,6 +43,8 @@
BOOL g_PaintDesktopVersion = FALSE;
+static VOID IntFreeDesktopHeap(IN OUT PDESKTOP_OBJECT Desktop);
+
/* INITALIZATION FUNCTIONS ****************************************************/
static GENERIC_MAPPING IntDesktopMapping =
@@ -121,6 +123,8 @@
RemoveEntryList(&Desktop->ListEntry);
RtlFreeUnicodeString(&Desktop->Name);
+
+ IntFreeDesktopHeap(Desktop);
}
/* PRIVATE FUNCTIONS **********************************************************/
@@ -723,7 +727,15 @@
return FALSE;
}
-
+static VOID
+IntFreeDesktopHeap(IN OUT PDESKTOP_OBJECT Desktop)
+{
+ if (Desktop->DesktopHeapSection != NULL)
+ {
+ ObDereferenceObject(Desktop->DesktopHeapSection);
+ Desktop->DesktopHeapSection = NULL;
+ }
+}
/* SYSCALLS *******************************************************************/
@@ -776,6 +788,8 @@
NTSTATUS Status;
HDESK Desktop;
CSR_API_MESSAGE Request;
+ PVOID DesktopHeapSystemBase = NULL;
+ SIZE_T DesktopInfoSize;
DECLARE_RETURN(HDESK);
DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
@@ -857,6 +871,39 @@
SetLastNtError(STATUS_UNSUCCESSFUL);
RETURN( NULL);
}
+
+ DesktopObject->DesktopHeapSection = NULL;
+ DesktopObject->hDesktopHeap =
UserCreateHeap(&DesktopObject->DesktopHeapSection,
+ &DesktopHeapSystemBase,
+ 4 * 1024 * 1024); /* FIXME */
+ if (DesktopObject->hDesktopHeap == NULL)
+ {
+ ObDereferenceObject(DesktopObject);
+ DPRINT1("Failed to create desktop heap!\n");
+ RETURN(NULL);
+ }
+
+ DesktopInfoSize = FIELD_OFFSET(DESKTOP,
+ szDesktopName[(lpszDesktopName->Length /
sizeof(WCHAR)) + 1]);
+
+ DesktopObject->DesktopInfo = RtlAllocateHeap(DesktopObject->hDesktopHeap,
+ HEAP_NO_SERIALIZE,
+ DesktopInfoSize);
+
+ if (DesktopObject->DesktopInfo == NULL)
+ {
+ ObDereferenceObject(DesktopObject);
+ DPRINT1("Failed to create the DESKTOP structure!\n");
+ RETURN(NULL);
+ }
+
+ RtlZeroMemory(DesktopObject->DesktopInfo,
+ DesktopInfoSize);
+
+ DesktopObject->DesktopInfo->hKernelHeap = DesktopObject->hDesktopHeap;
+ RtlCopyMemory(DesktopObject->DesktopInfo->szDesktopName,
+ lpszDesktopName->Buffer,
+ lpszDesktopName->Length);
// init desktop area
DesktopObject->WorkArea.left = 0;
@@ -1216,7 +1263,7 @@
RETURN(FALSE);
}
- DesktopBrush = (HBRUSH)IntGetClassLong(WndDesktop, GCL_HBRBACKGROUND, FALSE); //fixme:
verify retval
+ DesktopBrush = (HBRUSH)UserGetClassLongPtr(WndDesktop->Class, GCL_HBRBACKGROUND,
FALSE);
/*
@@ -1560,6 +1607,183 @@
END_CLEANUP;
}
+static NTSTATUS
+IntUnmapDesktopView(IN PDESKTOP_OBJECT DesktopObject)
+{
+ PW32THREADINFO ti;
+ PW32HEAP_USER_MAPPING HeapMapping, *PrevLink =
&PsGetWin32Process()->HeapMappings.Next;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ /* unmap if we're the last thread using the desktop */
+ HeapMapping = *PrevLink;
+ while (HeapMapping != NULL)
+ {
+ if (HeapMapping->KernelMapping == (PVOID)DesktopObject->hDesktopHeap)
+ {
+ if (--HeapMapping->Count == 0)
+ {
+ *PrevLink = HeapMapping->Next;
+
+ Status = MmUnmapViewOfSection(PsGetCurrentProcess(),
+ HeapMapping->UserMapping);
+
+ ObDereferenceObject(DesktopObject);
+
+ UserHeapFree(HeapMapping);
+ break;
+ }
+ }
+
+ PrevLink = &HeapMapping->Next;
+ HeapMapping = HeapMapping->Next;
+ }
+
+ ti = GetW32ThreadInfo();
+ if (ti != NULL)
+ {
+ if (ti->Desktop == DesktopObject->DesktopInfo)
+ {
+ ti->Desktop = NULL;
+ ti->DesktopHeapDelta = 0;
+ }
+ }
+
+ return Status;
+}
+
+static NTSTATUS
+IntMapDesktopView(IN PDESKTOP_OBJECT DesktopObject)
+{
+ PW32THREADINFO ti;
+ PW32HEAP_USER_MAPPING HeapMapping, *PrevLink =
&PsGetWin32Process()->HeapMappings.Next;
+ PVOID UserBase = NULL;
+ ULONG ViewSize = 0;
+ LARGE_INTEGER Offset;
+ NTSTATUS Status;
+
+ /* find out if another thread already mapped the desktop heap */
+ HeapMapping = *PrevLink;
+ while (HeapMapping != NULL)
+ {
+ if (HeapMapping->KernelMapping == (PVOID)DesktopObject->hDesktopHeap)
+ {
+ HeapMapping->Count++;
+ return STATUS_SUCCESS;
+ }
+
+ PrevLink = &HeapMapping->Next;
+ HeapMapping = HeapMapping->Next;
+ }
+
+ /* we're the first, map the heap */
+ Offset.QuadPart = 0;
+ Status = MmMapViewOfSection(DesktopObject->DesktopHeapSection,
+ PsGetCurrentProcess(),
+ &UserBase,
+ 0,
+ 0,
+ &Offset,
+ &ViewSize,
+ ViewUnmap,
+ SEC_NO_CHANGE,
+ PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but
thanks to RTL heaps... */
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("Failed to map desktop\n");
+ return Status;
+ }
+
+ /* add the mapping */
+ HeapMapping = UserHeapAlloc(sizeof(W32HEAP_USER_MAPPING));
+ if (HeapMapping == NULL)
+ {
+ MmUnmapViewOfSection(PsGetCurrentProcess(),
+ UserBase);
+ return STATUS_NO_MEMORY;
+ }
+
+ HeapMapping->Next = NULL;
+ HeapMapping->KernelMapping = (PVOID)DesktopObject->hDesktopHeap;
+ HeapMapping->UserMapping = UserBase;
+ HeapMapping->Count = 1;
+
+ ObReferenceObject(DesktopObject);
+
+ /* create a W32THREADINFO structure if not already done, or update it */
+ ti = GetW32ThreadInfo();
+ if (ti != NULL)
+ {
+ if (ti->Desktop == NULL)
+ {
+ ti->Desktop = DesktopObject->DesktopInfo;
+ ti->DesktopHeapDelta = DesktopHeapGetUserDelta();
+ }
+ }
+
+ return STATUS_SUCCESS;
+}
+
+BOOL
+IntSetThreadDesktop(IN PDESKTOP_OBJECT DesktopObject)
+{
+ PDESKTOP_OBJECT OldDesktop;
+ PW32THREAD W32Thread;
+ NTSTATUS Status;
+ BOOL MapHeap;
+
+ MapHeap = (PsGetCurrentProcess() != PsInitialSystemProcess);
+ W32Thread = PsGetWin32Thread();
+
+ if (W32Thread->Desktop != DesktopObject)
+ {
+ OldDesktop = W32Thread->Desktop;
+
+ W32Thread->Desktop = DesktopObject;
+
+ if (MapHeap && DesktopObject != NULL)
+ {
+ Status = IntMapDesktopView(DesktopObject);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return FALSE;
+ }
+ }
+
+ if (DesktopObject != NULL)
+ {
+ ObReferenceObject(DesktopObject);
+ }
+
+ if (OldDesktop != NULL)
+ {
+ if (MapHeap)
+ {
+ IntUnmapDesktopView(OldDesktop);
+ }
+
+ ObDereferenceObject(OldDesktop);
+
+ if (W32Thread != NULL && W32Thread->ThreadInfo != NULL &&
+ W32Thread->ThreadInfo->Desktop != (DesktopObject != NULL ?
DesktopObject->DesktopInfo : NULL))
+ {
+ if (DesktopObject != NULL)
+ {
+ W32Thread->ThreadInfo->Desktop =
DesktopObject->DesktopInfo;
+ W32Thread->ThreadInfo->DesktopHeapDelta =
DesktopHeapGetUserDelta();
+ }
+ else
+ {
+ W32Thread->ThreadInfo->Desktop = NULL;
+ W32Thread->ThreadInfo->DesktopHeapDelta = 0;
+ }
+ }
+ }
+ }
+
+ return TRUE;
+}
+
/*
* NtUserSetThreadDesktop
*
@@ -1570,7 +1794,6 @@
BOOL STDCALL
NtUserSetThreadDesktop(HDESK hDesktop)
{
- PW32THREAD W32Thread;
PDESKTOP_OBJECT DesktopObject;
NTSTATUS Status;
DECLARE_RETURN(BOOL);
@@ -1591,17 +1814,12 @@
RETURN(FALSE);
}
- W32Thread = PsGetWin32Thread();
-
/* FIXME: Should check here to see if the thread has any windows. */
- if (W32Thread->Desktop != NULL)
- {
- ObDereferenceObject(W32Thread->Desktop);
- }
-
- W32Thread->Desktop = DesktopObject;
- W32Thread->hDesktop = hDesktop;
+ if (!IntSetThreadDesktop(DesktopObject))
+ {
+ RETURN(FALSE);
+ }
RETURN(TRUE);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/hook.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/hook.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/hook.c Wed Apr 5 12:05:55 2006
@@ -69,7 +69,7 @@
return NULL;
}
- Hook = (PHOOK)UserGetObject(&gHandleTable, hHook, otHook);
+ Hook = (PHOOK)UserGetObject(gHandleTable, hHook, otHook);
if (!Hook)
{
SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE);
@@ -110,7 +110,7 @@
}
}
- Hook = ObmCreateObject(&gHandleTable, &Handle, otHook, sizeof(HOOK));
+ Hook = ObmCreateObject(gHandleTable, &Handle, otHook, sizeof(HOOK));
if (NULL == Hook)
{
return NULL;
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/menu.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/menu.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/menu.c Wed Apr 5 12:05:55 2006
@@ -127,7 +127,7 @@
return NULL;
}
- Menu = (PMENU_OBJECT)UserGetObject(&gHandleTable, hMenu, otMenu);
+ Menu = (PMENU_OBJECT)UserGetObject(gHandleTable, hMenu, otMenu);
if (!Menu)
{
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
@@ -310,7 +310,7 @@
PMENU_OBJECT Menu;
Menu = (PMENU_OBJECT)ObmCreateObject(
- &gHandleTable, Handle,
+ gHandleTable, Handle,
otMenu, sizeof(MENU_OBJECT));
if(!Menu)
@@ -419,7 +419,7 @@
return NULL;
Menu = (PMENU_OBJECT)ObmCreateObject(
- &gHandleTable, &hMenu,
+ gHandleTable, &hMenu,
otMenu, sizeof(MENU_OBJECT));
if(!Menu)
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 Wed Apr 5 12:05:55 2006
@@ -378,28 +378,9 @@
MsgInfo.HandledByKernel = FALSE;
Result = 0;
- if (0xFFFF0000 != ((DWORD) Window->WndProcW & 0xFFFF0000))
- {
- if (0xFFFF0000 != ((DWORD) Window->WndProcA & 0xFFFF0000))
- {
- /* Both Unicode and Ansi winprocs are real, use whatever
- usermode prefers */
- MsgInfo.Proc = (MsgInfo.Ansi ? Window->WndProcA
- : Window->WndProcW);
- }
- else
- {
- /* Real Unicode winproc */
- MsgInfo.Ansi = FALSE;
- MsgInfo.Proc = Window->WndProcW;
- }
- }
- else
- {
- /* Must have real Ansi winproc */
- MsgInfo.Ansi = TRUE;
- MsgInfo.Proc = Window->WndProcA;
- }
+
+ MsgInfo.Ansi = !Window->Unicode;
+ MsgInfo.Proc = Window->WndProc;
}
}
}
@@ -615,7 +596,7 @@
{
/* generate double click messages, if necessary */
if ((((*HitTest) != HTCLIENT) ||
- (IntGetClassLong(Window, GCL_STYLE, FALSE) & CS_DBLCLKS)) &&
+ (Window->Class->Style & CS_DBLCLKS)) &&
MsqIsDblClk(Msg, Remove))
{
Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
@@ -1401,16 +1382,9 @@
DPRINT1("Failed to pack message parameters\n");
RETURN( FALSE);
}
- if (0xFFFF0000 != ((DWORD) Window->WndProcW & 0xFFFF0000))
- {
- Result = (ULONG_PTR)co_IntCallWindowProc(Window->WndProcW, FALSE, hWnd, Msg,
wParam,
- lParamPacked,lParamBufferSize);
- }
- else
- {
- Result = (ULONG_PTR)co_IntCallWindowProc(Window->WndProcA, TRUE, hWnd, Msg,
wParam,
- lParamPacked,lParamBufferSize);
- }
+
+ Result = (ULONG_PTR)co_IntCallWindowProc(Window->WndProc, !Window->Unicode,
hWnd, Msg, wParam,
+ lParamPacked,lParamBufferSize);
if(uResult)
{
@@ -1580,32 +1554,16 @@
{
/* Gather the information usermode needs to call the window proc directly */
Info.HandledByKernel = FALSE;
- if (0xFFFF0000 != ((DWORD) Window->WndProcW & 0xFFFF0000))
- {
- if (0xFFFF0000 != ((DWORD) Window->WndProcA & 0xFFFF0000))
- {
- /* Both Unicode and Ansi winprocs are real, see what usermode prefers */
- Status = MmCopyFromCaller(&(Info.Ansi), &(UnsafeInfo->Ansi),
- sizeof(BOOL));
- if (! NT_SUCCESS(Status))
- {
- Info.Ansi = ! Window->Unicode;
- }
- Info.Proc = (Info.Ansi ? Window->WndProcA : Window->WndProcW);
- }
- else
- {
- /* Real Unicode winproc */
- Info.Ansi = FALSE;
- Info.Proc = Window->WndProcW;
- }
- }
- else
- {
- /* Must have real Ansi winproc */
- Info.Ansi = TRUE;
- Info.Proc = Window->WndProcA;
- }
+
+ Status = MmCopyFromCaller(&(Info.Ansi), &(UnsafeInfo->Ansi),
+ sizeof(BOOL));
+ if (! NT_SUCCESS(Status))
+ {
+ Info.Ansi = ! Window->Unicode;
+ }
+
+ Info.Ansi = !Window->Unicode;
+ Info.Proc = Window->WndProc;
}
else
{
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/misc.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/misc.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/misc.c Wed Apr 5 12:05:55 2006
@@ -886,11 +886,22 @@
DECLARE_RETURN(DWORD);
DPRINT("Enter NtUserGetThreadState\n");
- UserEnterShared();
+ if (Routine != THREADSTATE_GETTHREADINFO)
+ {
+ UserEnterShared();
+ }
+ else
+ {
+ UserEnterExclusive();
+ }
switch (Routine)
{
- case 0:
+ case THREADSTATE_GETTHREADINFO:
+ GetW32ThreadInfo();
+ RETURN(0);
+
+ case THREADSTATE_FOCUSWINDOW:
RETURN( (DWORD)IntGetThreadFocusWindow());
}
RETURN( 0);
@@ -1829,4 +1840,106 @@
END_CLEANUP;
}
+PW32PROCESSINFO
+GetW32ProcessInfo(VOID)
+{
+ PW32PROCESSINFO pi;
+ PW32PROCESS W32Process = PsGetWin32Process();
+
+ if (W32Process == NULL)
+ {
+ /* FIXME - temporary hack for system threads... */
+ return NULL;
+ }
+
+ if (W32Process->ProcessInfo == NULL)
+ {
+ pi = UserHeapAlloc(sizeof(W32PROCESSINFO));
+ if (pi != NULL)
+ {
+ RtlZeroMemory(pi,
+ sizeof(W32PROCESSINFO));
+
+ /* initialize it */
+ pi->UserHandleTable = gHandleTable;
+
+ if (InterlockedCompareExchangePointer(&W32Process->ProcessInfo,
+ pi,
+ NULL) != NULL)
+ {
+ UserHeapFree(pi);
+ }
+ }
+ else
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ }
+ }
+
+ return W32Process->ProcessInfo;
+}
+
+PW32THREADINFO
+GetW32ThreadInfo(VOID)
+{
+ PTEB Teb;
+ PW32THREADINFO ti;
+ PW32THREAD W32Thread = PsGetWin32Thread();
+
+ if (W32Thread == NULL)
+ {
+ /* FIXME - temporary hack for system threads... */
+ return NULL;
+ }
+
+ /* allocate a W32THREAD structure if neccessary */
+ if (W32Thread->ThreadInfo == NULL)
+ {
+ ti = UserHeapAlloc(sizeof(W32THREADINFO));
+ if (ti != NULL)
+ {
+ RtlZeroMemory(ti,
+ sizeof(W32THREADINFO));
+
+ /* initialize it */
+ ti->kpi = GetW32ProcessInfo();
+ ti->pi = UserHeapAddressToUser(ti->kpi);
+ if (W32Thread->Desktop != NULL)
+ {
+ ti->Desktop = W32Thread->Desktop->DesktopInfo;
+ ti->DesktopHeapDelta = DesktopHeapGetUserDelta();
+ }
+ else
+ {
+ ti->Desktop = NULL;
+ ti->DesktopHeapDelta = 0;
+ }
+
+ W32Thread->ThreadInfo = ti;
+ /* update the TEB */
+ Teb = NtCurrentTeb();
+ _SEH_TRY
+ {
+ ProbeForWrite(Teb,
+ sizeof(TEB),
+ sizeof(ULONG));
+
+ Teb->Win32ThreadInfo =
UserHeapAddressToUser(W32Thread->ThreadInfo);
+ }
+ _SEH_HANDLE
+ {
+ SetLastNtError(_SEH_GetExceptionCode());
+ }
+ _SEH_END;
+ }
+ else
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ }
+ }
+
+ return W32Thread->ThreadInfo;
+}
+
+
/* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/monitor.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/monitor.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/monitor.c Wed Apr 5 12:05:55 2006
@@ -89,7 +89,7 @@
HANDLE Handle;
PMONITOR_OBJECT Monitor;
- Monitor = ObmCreateObject(&gHandleTable, &Handle, otMonitor, sizeof
(MONITOR_OBJECT));
+ Monitor = ObmCreateObject(gHandleTable, &Handle, otMonitor, sizeof
(MONITOR_OBJECT));
if (Monitor == NULL)
{
return NULL;
@@ -133,7 +133,7 @@
}
- Monitor = (PMONITOR_OBJECT)UserGetObject(&gHandleTable, hMonitor, otMonitor);
+ Monitor = (PMONITOR_OBJECT)UserGetObject(gHandleTable, hMonitor, otMonitor);
if (!Monitor)
{
SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE);
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/object.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/object.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/object.c Wed Apr 5 12:05:55 2006
@@ -28,7 +28,7 @@
#include <debug.h>
int usedHandles=0;
-USER_HANDLE_TABLE gHandleTable;
+PUSER_HANDLE_TABLE gHandleTable = NULL;
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle )
@@ -71,19 +71,17 @@
DPRINT1("Out of user handles!\n");
return NULL;
#if 0
-
- struct user_handle *new_handles;
+ PUSER_HANDLE_ENTRY new_handles;
/* grow array by 50% (but at minimum 32 entries) */
- int growth = max( 32, allocated_handles / 2 );
- int new_size = min( allocated_handles + growth,
(LAST_USER_HANDLE-FIRST_USER_HANDLE+1) >> 1 );
- if (new_size <= allocated_handles)
+ int growth = max( 32, ht->allocated_handles / 2 );
+ int new_size = min( ht->allocated_handles + growth,
(LAST_USER_HANDLE-FIRST_USER_HANDLE+1) >> 1 );
+ if (new_size <= ht->allocated_handles)
return NULL;
- if (!(new_handles = realloc( handles, new_size * sizeof(*handles) )))
+ if (!(new_handles = UserHeapReAlloc( ht->handles, new_size *
sizeof(*ht->handles) )))
return NULL;
- handles = new_handles;
- allocated_handles = new_size;
+ ht->handles = new_handles;
+ ht->allocated_handles = new_size;
#endif
-
}
entry = &ht->handles[ht->nb_handles++];
@@ -217,7 +215,7 @@
{
HANDLE hi;
- PUSER_OBJECT_HEADER hdr = ExAllocatePool(PagedPool, size +
sizeof(USER_OBJECT_HEADER));
+ PUSER_OBJECT_HEADER hdr = UserHeapAlloc(size +
sizeof(USER_OBJECT_HEADER));//ExAllocatePool(PagedPool, size +
sizeof(USER_OBJECT_HEADER));
if (!hdr)
return NULL;
@@ -225,7 +223,8 @@
hi = UserAllocHandle(ht, USER_HEADER_TO_BODY(hdr), type );
if (!hi)
{
- ExFreePool(hdr);
+ //ExFreePool(hdr);
+ UserHeapFree(hdr);
return NULL;
}
@@ -242,7 +241,7 @@
ObmDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
{
PUSER_OBJECT_HEADER hdr;
- PVOID body = UserGetObject(&gHandleTable, h, type);
+ PVOID body = UserGetObject(gHandleTable, h, type);
if (!body)
return FALSE;
@@ -252,11 +251,12 @@
hdr->destroyed = TRUE;
if (hdr->RefCount == 0)
{
- UserFreeHandle(&gHandleTable, h);
+ UserFreeHandle(gHandleTable, h);
memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
- ExFreePool(hdr);
+ UserHeapFree(hdr);
+ //ExFreePool(hdr);
return TRUE;
}
@@ -274,6 +274,12 @@
hdr->RefCount++;
}
+HANDLE FASTCALL ObmObjectToHandle(PVOID obj)
+{
+ PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
+ return hdr->hSelf;
+}
+
BOOL FASTCALL ObmDereferenceObject2(PVOID obj)
{
@@ -287,11 +293,12 @@
{
// DPRINT1("info: something destroyed bcaise of deref, in
use=%i\n",usedHandles);
- UserFreeHandle(&gHandleTable, hdr->hSelf);
+ UserFreeHandle(gHandleTable, hdr->hSelf);
memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
- ExFreePool(hdr);
+ UserHeapFree(hdr);
+ //ExFreePool(hdr);
return TRUE;
}
@@ -307,15 +314,24 @@
PVOID mem;
//FIXME: dont alloc all at once! must be mapped into umode also...
- mem = ExAllocatePool(PagedPool, sizeof(USER_HANDLE_ENTRY) * 1024*2);
+ //mem = ExAllocatePool(PagedPool, sizeof(USER_HANDLE_ENTRY) * 1024*2);
+ mem = UserHeapAlloc(sizeof(USER_HANDLE_ENTRY) * 1024*2);
if (!mem)
{
DPRINT1("Failed creating handle table\n");
return FALSE;
}
+ gHandleTable = UserHeapAlloc(sizeof(USER_HANDLE_TABLE));
+ if (gHandleTable == NULL)
+ {
+ UserHeapFree(mem);
+ DPRINT1("Failed creating handle table\n");
+ return FALSE;
+ }
+
//FIXME: make auto growable
- UserInitHandleTable(&gHandleTable, mem, sizeof(USER_HANDLE_ENTRY) * 1024*2);
+ UserInitHandleTable(gHandleTable, mem, sizeof(USER_HANDLE_ENTRY) * 1024*2);
return TRUE;
}
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/windc.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/windc.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/windc.c Wed Apr 5 12:05:55 2006
@@ -353,7 +353,7 @@
if (!(Flags & DCX_WINDOW))
{
- if (Window->Class->style & CS_PARENTDC)
+ if (Window->Class->Style & CS_PARENTDC)
{
Flags |= DCX_PARENTCLIP;
}
@@ -676,7 +676,7 @@
{
if (pDCE == Window->Dce) /* owned or Class DCE*/
{
- if (Window->Class->style & CS_OWNDC) /* owned DCE*/
+ if (Window->Class->Style & CS_OWNDC) /* owned DCE*/
{
pDCE = DceFreeDCE(pDCE, FALSE);
Window->Dce = NULL;
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 Wed Apr 5 12:05:55 2006
@@ -33,10 +33,6 @@
#define NDEBUG
#include <debug.h>
-static WndProcHandle *WndProcHandlesArray = 0;
-static WORD WndProcHandlesArraySize = 0;
-#define WPH_SIZE 0x40 /* the size to add to the WndProcHandle array each time */
-
/* dialog resources appear to pass this in 16 bits, handle them properly */
#define CW_USEDEFAULT16 (0x8000)
@@ -53,8 +49,6 @@
NTSTATUS FASTCALL
InitWindowImpl(VOID)
{
- WndProcHandlesArray = ExAllocatePoolWithTag(PagedPool,WPH_SIZE *
sizeof(WndProcHandle), TAG_WINPROCLST);
- WndProcHandlesArraySize = WPH_SIZE;
return STATUS_SUCCESS;
}
@@ -67,9 +61,6 @@
NTSTATUS FASTCALL
CleanupWindowImpl(VOID)
{
- ExFreePool(WndProcHandlesArray);
- WndProcHandlesArray = 0;
- WndProcHandlesArraySize = 0;
return STATUS_SUCCESS;
}
@@ -95,15 +86,26 @@
/* temp hack */
PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
{
+ PW32THREADINFO ti;
PWINDOW_OBJECT Window;
-
+
+ if (PsGetCurrentProcess() != PsInitialSystemProcess)
+ {
+ ti = GetW32ThreadInfo();
+ if (ti == NULL)
+ {
+ SetLastWin32Error(ERROR_ACCESS_DENIED);
+ return NULL;
+ }
+ }
+
if (!hWnd)
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return NULL;
}
- Window = (PWINDOW_OBJECT)UserGetObject(&gHandleTable, hWnd, otWindow);
+ Window = (PWINDOW_OBJECT)UserGetObject(gHandleTable, hWnd, otWindow);
if (!Window || 0 != (Window->Status & WINDOWSTATUS_DESTROYED))
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
@@ -432,8 +434,16 @@
IntDestroyScrollBars(Window);
+ if (!Window->Class->System && Window->CallProc != NULL)
+ {
+ DestroyCallProc(Window->ti->Desktop,
+ Window->CallProc);
+ }
+
/* dereference the class */
- ClassDerefObject(Window->Class);
+ IntDereferenceClass(Window->Class,
+ Window->ti->Desktop,
+ Window->ti->kpi);
Window->Class = NULL;
if(Window->WindowRegion)
@@ -473,6 +483,57 @@
*cx = *cy = 0;
}
}
+}
+
+static WNDPROC
+IntGetWindowProc(IN PWINDOW_OBJECT Window,
+ IN BOOL Ansi)
+{
+ if (Window->IsSystem)
+ {
+ return (Ansi ? Window->WndProcExtra : Window->WndProc);
+ }
+ else
+ {
+ if (!Ansi == Window->Unicode)
+ {
+ return Window->WndProc;
+ }
+ else
+ {
+ if (Window->CallProc != NULL)
+ {
+ return (WNDPROC)ObmObjectToHandle(Window->CallProc);
+ }
+ else
+ {
+ PCALLPROC NewCallProc, CallProc;
+
+ /* NOTE: use the interlocked functions, as this operation may be done
even
+ when only the shared lock is held! */
+ NewCallProc = CreateCallProc(Window->ti->Desktop,
+ Window->WndProc,
+ Window->Unicode,
+ Window->ti->kpi);
+ if (NewCallProc == NULL)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return NULL;
+ }
+
+ CallProc = InterlockedCompareExchangePointer(&Window->CallProc,
+ NewCallProc,
+ NULL);
+ if (CallProc != NULL)
+ {
+ DestroyCallProc(Window->ti->Desktop,
+ NewCallProc);
+ }
+
+ return (WNDPROC)ObmObjectToHandle((CallProc == NULL ? NewCallProc :
CallProc));
+ }
+ }
+ }
}
BOOL FASTCALL
@@ -1333,7 +1394,8 @@
BOOL bUnicodeWindow)
{
PWINSTATION_OBJECT WinSta;
- PWNDCLASS_OBJECT Class = NULL;
+ PWINDOWCLASS Class = NULL;
+ RTL_ATOM ClassAtom;
PWINDOW_OBJECT Window = NULL;
PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
HWND ParentWindowHandle;
@@ -1342,6 +1404,7 @@
HWND hWnd;
POINT Pos;
SIZE Size;
+ PW32THREADINFO ti = NULL;
#if 0
POINT MaxSize, MaxPos, MinTrack, MaxTrack;
@@ -1349,7 +1412,6 @@
POINT MaxPos;
#endif
-
CREATESTRUCTW Cs;
CBT_CREATEWNDW CbtCreate;
LRESULT Result;
@@ -1399,13 +1461,27 @@
/* FIXME: parent must belong to the current process */
+ /* Check the window station. */
+ ti = GetW32ThreadInfo();
+ if (ti == NULL || PsGetWin32Thread()->Desktop == NULL)
+ {
+ DPRINT1("Thread is not attached to a desktop! Cannot create window!\n");
+ RETURN( (HWND)0);
+ }
+
/* Check the class. */
- Class = ClassGetClassByNameOrAtom(ClassName->Buffer, hInstance);
- if (!Class)
+
+ ClassAtom = IntGetClassAtom(ClassName,
+ hInstance,
+ ti->kpi,
+ &Class,
+ NULL);
+
+ if (ClassAtom == (RTL_ATOM)0)
{
if (IS_ATOM(ClassName->Buffer))
{
- DPRINT1("Class 0x%x not found\n", (DWORD_PTR) ClassName->Buffer);
+ DPRINT1("Class 0x%p not found\n", (DWORD_PTR) ClassName->Buffer);
}
else
{
@@ -1416,14 +1492,14 @@
RETURN((HWND)0);
}
- ClassRefObject(Class);
-
- /* Check the window station. */
- if (PsGetWin32Thread()->Desktop == NULL)
- {
- DPRINT("Thread is not attached to a desktop! Cannot create window!\n");
- RETURN( (HWND)0);
- }
+ Class = IntReferenceClass(Class,
+ ti->Desktop);
+ if (Class == NULL)
+ {
+ DPRINT1("Failed to reference window class!\n");
+ RETURN(NULL);
+ }
+
WinSta = PsGetWin32Thread()->Desktop->WindowStation;
//FIXME: Reference thread/desktop instead
@@ -1431,8 +1507,8 @@
/* Create the window object. */
Window = (PWINDOW_OBJECT)
- ObmCreateObject(&gHandleTable, (PHANDLE)&hWnd,
- otWindow, sizeof(WINDOW_OBJECT) + Class->cbWndExtra
+ ObmCreateObject(gHandleTable, (PHANDLE)&hWnd,
+ otWindow, sizeof(WINDOW_OBJECT) + Class->WndExtra
);
DPRINT("Created object with handle %X\n", hWnd);
@@ -1456,6 +1532,7 @@
/*
* Fill out the structure describing it.
*/
+ Window->ti = ti;
Window->Class = Class;
Window->SystemMenu = (HMENU)0;
Window->ContextHelpId = 0;
@@ -1474,7 +1551,7 @@
{
IntSetMenu(Window, hMenu, &MenuChanged);
}
-
+
Window->MessageQueue = PsGetWin32Thread()->MessageQueue;
IntReferenceMessageQueue(Window->MessageQueue);
Window->Parent = ParentWindow;
@@ -1491,27 +1568,38 @@
}
Window->UserData = 0;
-
- if ((((DWORD)Class->lpfnWndProcA & 0xFFFF0000) != 0xFFFF0000)
- && (((DWORD)Class->lpfnWndProcW & 0xFFFF0000) != 0xFFFF0000))
- {
- Window->Unicode = bUnicodeWindow;
+
+ 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;
+ }
}
else
{
- Window->Unicode = Class->Unicode;
- }
- Window->WndProcA = Class->lpfnWndProcA;
- Window->WndProcW = Class->lpfnWndProcW;
+ Window->Unicode = Class->Unicode;
+ Window->WndProc = Class->WndProc;
+ Window->CallProc = NULL;
+ }
+
Window->OwnerThread = PsGetCurrentThread();
Window->FirstChild = NULL;
Window->LastChild = NULL;
Window->PrevSibling = NULL;
Window->NextSibling = NULL;
- Window->ExtraDataSize = Class->cbWndExtra;
+ Window->ExtraDataSize = Class->WndExtra;
/* extra window data */
- if (Class->cbWndExtra)
+ if (Class->WndExtra)
Window->ExtraData = (PCHAR)(Window + 1);
InitializeListHead(&Window->PropListHead);
@@ -1535,7 +1623,6 @@
{
RtlInitUnicodeString(&Window->WindowName, NULL);
}
-
/*
* This has been tested for WS_CHILD | WS_VISIBLE. It has not been
@@ -1931,7 +2018,15 @@
CLEANUP:
if (Window) UserDerefObjectCo(Window);
if (ParentWindow) UserDerefObjectCo(ParentWindow);
- if (!_ret_ && Class) ClassDerefObject(Class); /* only deref if failure (return
0) */
+ if (!_ret_ && ti != NULL)
+ {
+ if (Class != NULL)
+ {
+ IntDereferenceClass(Class,
+ ti->Desktop,
+ ti->kpi);
+ }
+ }
END_CLEANUP;
}
@@ -1967,7 +2062,7 @@
SetLastNtError(Status);
RETURN( NULL);
}
- if (! IS_ATOM(ClassName.Buffer))
+ if (ClassName.Length != 0)
{
Status = IntSafeCopyUnicodeStringTerminateNULL(&ClassName, UnsafeClassName);
if (! NT_SUCCESS(Status))
@@ -1975,6 +2070,11 @@
SetLastNtError(Status);
RETURN( NULL);
}
+ }
+ else if (! IS_INTRESOURCE(ClassName.Buffer))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return NULL;
}
/* safely copy the window name */
@@ -3254,10 +3354,8 @@
break;
case GWL_WNDPROC:
- if (Ansi)
- Result = (LONG) Window->WndProcA;
- else
- Result = (LONG) Window->WndProcW;
+ Result = (LONG)IntGetWindowProc(Window,
+ Ansi);
break;
case GWL_HINSTANCE:
@@ -3390,22 +3488,28 @@
break;
case GWL_WNDPROC:
+ {
/* FIXME: should check if window belongs to current process */
- if (Ansi)
+ if (Window->IsSystem)
{
- OldValue = (LONG) Window->WndProcA;
- Window->WndProcA = (WNDPROC) NewValue;
- Window->WndProcW = (WNDPROC)
IntAddWndProcHandle((WNDPROC)NewValue,FALSE);
- Window->Unicode = FALSE;
+ /* 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;
}
- else
+
+ /* update the window procedure */
+ OldValue = (LONG)Window->WndProc;
+ Window->WndProc = (WNDPROC)NewValue;
+ if (Window->CallProc != NULL)
{
- OldValue = (LONG) Window->WndProcW;
- Window->WndProcW = (WNDPROC) NewValue;
- Window->WndProcA = (WNDPROC)
IntAddWndProcHandle((WNDPROC)NewValue,TRUE);
- Window->Unicode = TRUE;
+ Window->CallProc->WndProc = (WNDPROC)NewValue;
+ Window->CallProc->Unicode = !Ansi;
}
+ Window->Unicode = !Ansi;
break;
+ }
case GWL_HINSTANCE:
OldValue = (LONG) Window->Instance;
@@ -4404,99 +4508,6 @@
END_CLEANUP;
}
-DWORD STDCALL
-NtUserDereferenceWndProcHandle(WNDPROC wpHandle, WndProcHandle *Data)
-{
- DECLARE_RETURN(DWORD);
- WndProcHandle Entry;
-
- DPRINT("Enter NtUserDereferenceWndProcHandle\n");
- UserEnterShared();
-
- if (((DWORD)wpHandle & 0xFFFF0000) == 0xFFFF0000)
- {
- Entry = WndProcHandlesArray[(DWORD)wpHandle & 0x0000FFFF];
- Data->WindowProc = Entry.WindowProc;
- Data->IsUnicode = Entry.IsUnicode;
- Data->ProcessID = Entry.ProcessID;
- RETURN( TRUE);
- }
- else
- {
- RETURN( FALSE);
- }
- RETURN( FALSE);
-
-CLEANUP:
- DPRINT("Leave NtUserDereferenceWndProcHandle, ret=%i\n",_ret_);
- UserLeave();
- END_CLEANUP;
-}
-
-DWORD
-IntAddWndProcHandle(WNDPROC WindowProc, BOOL IsUnicode)
-{
- WORD i;
- WORD FreeSpot = 0;
- BOOL found;
- WndProcHandle *OldArray;
- WORD OldArraySize;
- found = FALSE;
- for (i = 0;i < WndProcHandlesArraySize;i++)
- {
- if (WndProcHandlesArray[i].WindowProc == NULL)
- {
- FreeSpot = i;
- found = TRUE;
- }
- }
- if (!found)
- {
- OldArray = WndProcHandlesArray;
- OldArraySize = WndProcHandlesArraySize;
- WndProcHandlesArray = ExAllocatePoolWithTag(PagedPool,(OldArraySize + WPH_SIZE) *
sizeof(WndProcHandle), TAG_WINPROCLST);
- WndProcHandlesArraySize = OldArraySize + WPH_SIZE;
- RtlCopyMemory(WndProcHandlesArray,OldArray,OldArraySize * sizeof(WndProcHandle));
- ExFreePool(OldArray);
- FreeSpot = OldArraySize + 1;
- }
- WndProcHandlesArray[FreeSpot].WindowProc = WindowProc;
- WndProcHandlesArray[FreeSpot].IsUnicode = IsUnicode;
- WndProcHandlesArray[FreeSpot].ProcessID = PsGetCurrentProcessId();
- return FreeSpot + 0xFFFF0000;
-}
-
-DWORD
-IntRemoveWndProcHandle(WNDPROC Handle)
-{
- WORD position;
- position = (DWORD)Handle & 0x0000FFFF;
- if (position > WndProcHandlesArraySize)
- {
- return FALSE;
- }
- WndProcHandlesArray[position].WindowProc = NULL;
- WndProcHandlesArray[position].IsUnicode = FALSE;
- WndProcHandlesArray[position].ProcessID = NULL;
- return TRUE;
-}
-
-DWORD
-IntRemoveProcessWndProcHandles(HANDLE ProcessID)
-{
- WORD i;
- for (i = 0;i < WndProcHandlesArraySize;i++)
- {
- if (WndProcHandlesArray[i].ProcessID == ProcessID)
- {
- WndProcHandlesArray[i].WindowProc = NULL;
- WndProcHandlesArray[i].IsUnicode = FALSE;
- WndProcHandlesArray[i].ProcessID = NULL;
- }
- }
- return TRUE;
-}
-
#define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
BOOL
Modified: trunk/reactos/subsystems/win32/win32k/w32k.h
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/w32…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/w32k.h (original)
+++ trunk/reactos/subsystems/win32/win32k/w32k.h Wed Apr 5 12:05:55 2006
@@ -1,3 +1,5 @@
+#ifndef __W32K_H
+#define __W32K_H
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Graphics Subsystem
@@ -68,3 +70,77 @@
#define M_PI_2 1.57079632679489661923
#endif
+/* User heap */
+extern HANDLE GlobalUserHeap;
+
+HANDLE
+UserCreateHeap(OUT PSECTION_OBJECT *SectionObject,
+ IN OUT PVOID *SystemBase,
+ IN ULONG HeapSize);
+
+static __inline PVOID
+UserHeapAlloc(SIZE_T Bytes)
+{
+ return RtlAllocateHeap(GlobalUserHeap,
+ HEAP_NO_SERIALIZE,
+ Bytes);
+}
+
+static __inline BOOL
+UserHeapFree(PVOID lpMem)
+{
+ return RtlFreeHeap(GlobalUserHeap,
+ HEAP_NO_SERIALIZE,
+ lpMem);
+}
+
+static __inline PVOID
+UserHeapReAlloc(PVOID lpMem,
+ SIZE_T Bytes)
+{
+#if 0
+ /* NOTE: ntoskrnl doesn't export RtlReAllocateHeap... */
+ return RtlReAllocateHeap(GlobalUserHeap,
+ HEAP_NO_SERIALIZE,
+ lpMem,
+ Bytes);
+#else
+ SIZE_T PrevSize;
+ PVOID pNew;
+
+ PrevSize = RtlSizeHeap(GlobalUserHeap,
+ HEAP_NO_SERIALIZE,
+ lpMem);
+
+ if (PrevSize == Bytes)
+ return lpMem;
+
+ pNew = RtlAllocateHeap(GlobalUserHeap,
+ HEAP_NO_SERIALIZE,
+ Bytes);
+ if (pNew != NULL)
+ {
+ if (PrevSize < Bytes)
+ Bytes = PrevSize;
+
+ RtlCopyMemory(pNew,
+ lpMem,
+ Bytes);
+
+ RtlFreeHeap(GlobalUserHeap,
+ HEAP_NO_SERIALIZE,
+ lpMem);
+ }
+
+ return pNew;
+#endif
+}
+
+static __inline PVOID
+UserHeapAddressToUser(PVOID lpMem)
+{
+ return (PVOID)(((ULONG_PTR)lpMem - (ULONG_PTR)GlobalUserHeap) +
+ (ULONG_PTR)PsGetWin32Process()->HeapMappings.UserMapping);
+}
+
+#endif /* __W32K_H */
Modified: trunk/reactos/subsystems/win32/win32k/win32k.rbuild
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/win…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/win32k.rbuild (original)
+++ trunk/reactos/subsystems/win32/win32k/win32k.rbuild Wed Apr 5 12:05:55 2006
@@ -64,14 +64,15 @@
<file>err.c</file>
<file>math.c</file>
<file>copy.c</file>
+ <file>usrheap.c</file>
</compilationunit>
<directory name="i386">
- <file>cos_asm.s</file>
- <file>sin_asm.s</file>
- <file>atan2_asm.s</file>
- <file>floor_asm.s</file>
- <file>ceil_asm.s</file>
- </directory>
+ <file>cos_asm.s</file>
+ <file>sin_asm.s</file>
+ <file>atan2_asm.s</file>
+ <file>floor_asm.s</file>
+ <file>ceil_asm.s</file>
+ </directory>
</directory>
<directory name="ntddraw">
<compilationunit name="ntddraw.c">
Modified: trunk/reactos/tools/nci/w32ksvc.db
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/tools/nci/w32ksvc.db?rev=21…
==============================================================================
--- trunk/reactos/tools/nci/w32ksvc.db (original)
+++ trunk/reactos/tools/nci/w32ksvc.db Wed Apr 5 12:05:55 2006
@@ -356,7 +356,7 @@
NtUserGetCapture 0
NtUserGetCaretBlinkTime 0
NtUserGetCaretPos 1
-NtUserGetClassInfo 5
+NtUserGetClassInfo 4
NtUserGetClassLong 3
NtUserGetClassName 3
NtUserGetClientOrigin 2
@@ -457,7 +457,7 @@
NtUserReleaseDC 2
NtUserRealChildWindowFromPoint 3
NtUserRedrawWindow 4
-NtUserRegisterClassExWOW 8
+NtUserRegisterClassEx 6
NtUserRegisterHotKey 4
NtUserRegisterTasklist 1
NtUserRegisterWindowMessage 1
@@ -536,7 +536,7 @@
NtUserUnhookWinEvent 1
NtUserUnloadKeyboardLayout 1
NtUserUnlockWindowStation 1
-NtUserUnregisterClass 3
+NtUserUnregisterClass 2
NtUserUnregisterHotKey 2
NtUserUpdateInputContext 3
NtUserUpdateInstance 3