Applied patch by: Thomas Weidenmueller

- win32k window class rewrite.
- http://www.reactos.org/bugzilla/show_bug.cgi?id=1366

svn path=/trunk/; revision=21460
This commit is contained in:
Peter Ward 2006-04-05 08:05:55 +00:00
parent 9607791183
commit ea5261fe10
33 changed files with 3599 additions and 1193 deletions

View file

@ -44,15 +44,13 @@ static void RegisterBuiltinClass(const struct builtin_class_descr *Descr)
RtlInitUnicodeString(&ClassName, Descr->name); RtlInitUnicodeString(&ClassName, Descr->name);
} }
NtUserRegisterClassExWOW( NtUserRegisterClassEx(
&wc, &wc,
&ClassName, &ClassName,
&ClassName,
&MenuName, &MenuName,
Descr->procA, Descr->procA,
REGISTERCLASS_SYSTEM, REGISTERCLASS_SYSTEM,
0, NULL);
0);
} }
/*********************************************************************** /***********************************************************************

View file

@ -113,3 +113,34 @@ UpdatePerUserSystemParameters(
{ {
return NtUserUpdatePerUserSystemParameters(dwReserved, bEnable); 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;
}

View file

@ -11,117 +11,6 @@
#include <user32.h> #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 * @implemented
@ -133,7 +22,40 @@ GetClassInfoExA(
LPCSTR lpszClass, LPCSTR lpszClass,
LPWNDCLASSEXA lpwcx) 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 @@ GetClassInfoExW(
LPCWSTR lpszClass, LPCWSTR lpszClass,
LPWNDCLASSEXW lpwcx) 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 @@ GetClassInfoA(
return FALSE; return FALSE;
} }
w.cbSize = sizeof(w);
retval = GetClassInfoExA(hInstance,lpClassName,&w); retval = GetClassInfoExA(hInstance,lpClassName,&w);
if (retval) if (retval)
{ {
@ -197,8 +141,12 @@ GetClassInfoW(
return FALSE; return FALSE;
} }
w.cbSize = sizeof(w);
retval = GetClassInfoExW(hInstance,lpClassName,&w); retval = GetClassInfoExW(hInstance,lpClassName,&w);
RtlCopyMemory (lpWndClass,&w.style,sizeof(WNDCLASSW)); if (retval)
{
RtlCopyMemory (lpWndClass,&w.style,sizeof(WNDCLASSW));
}
return retval; return retval;
} }
@ -275,25 +223,14 @@ GetClassNameA(
LPSTR lpClassName, LPSTR lpClassName,
int nMaxCount) int nMaxCount)
{ {
int result; ANSI_STRING ClassName;
LPWSTR ClassNameW;
NTSTATUS Status;
if(!lpClassName) ClassName.MaximumLength = nMaxCount;
return 0; ClassName.Buffer = lpClassName;
ClassNameW = HEAP_alloc ( (nMaxCount+1)*sizeof(WCHAR) ); return NtUserGetClassName(hWnd,
(PUNICODE_STRING)&ClassName,
result = NtUserGetClassName ( hWnd, ClassNameW, nMaxCount ); TRUE);
Status = HEAP_strcpyWtoA ( lpClassName, ClassNameW, result );
HEAP_free ( ClassNameW );
if ( !NT_SUCCESS(Status) )
return 0;
return result;
} }
@ -307,7 +244,14 @@ GetClassNameW(
LPWSTR lpClassName, LPWSTR lpClassName,
int nMaxCount) 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 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
RTL_ATOM Atom; RTL_ATOM Atom;
WNDCLASSEXA WndClass; WNDCLASSEXA WndClass;
UNICODE_STRING ClassName; UNICODE_STRING ClassName;
UNICODE_STRING MenuName; UNICODE_STRING MenuName = {0};
HMENU hMenu; HMENU hMenu = NULL;
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXA) || if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXA) ||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 || lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
@ -609,16 +553,17 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon); WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
} }
if HIWORD(lpwcx->lpszMenuName) if (lpwcx->lpszMenuName != NULL)
{ {
hMenu = 0; if (HIWORD(lpwcx->lpszMenuName))
RtlCreateUnicodeStringFromAsciiz(&MenuName, WndClass.lpszMenuName); {
} RtlCreateUnicodeStringFromAsciiz(&MenuName, WndClass.lpszMenuName);
else }
{ else
MenuName.Length = {
MenuName.MaximumLength = 0; MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName; }
hMenu = LoadMenuA(WndClass.hInstance, lpwcx->lpszMenuName); hMenu = LoadMenuA(WndClass.hInstance, lpwcx->lpszMenuName);
} }
@ -627,20 +572,18 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
ClassName.Length = ClassName.Length =
ClassName.MaximumLength = 0; ClassName.MaximumLength = 0;
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName; ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
} else }
else
{ {
RtlCreateUnicodeStringFromAsciiz(&ClassName, WndClass.lpszClassName); RtlCreateUnicodeStringFromAsciiz(&ClassName, WndClass.lpszClassName);
} }
Atom = NtUserRegisterClassExWOW( Atom = NtUserRegisterClassEx((WNDCLASSEXW*)&WndClass,
(WNDCLASSEXW*)&WndClass, &ClassName,
&ClassName, &MenuName,
&ClassName, NULL,
&MenuName, REGISTERCLASS_ANSI,
NULL, hMenu);
REGISTERCLASS_ANSI,
0,
hMenu);
if (!IS_ATOM(WndClass.lpszMenuName)) if (!IS_ATOM(WndClass.lpszMenuName))
RtlFreeUnicodeString(&MenuName); RtlFreeUnicodeString(&MenuName);
@ -658,8 +601,8 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
{ {
WNDCLASSEXW WndClass; WNDCLASSEXW WndClass;
UNICODE_STRING ClassName; UNICODE_STRING ClassName;
UNICODE_STRING MenuName; UNICODE_STRING MenuName = {0};
HMENU hMenu; HMENU hMenu = NULL;
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) || if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 || lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
@ -694,16 +637,16 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon); WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
} }
if HIWORD(lpwcx->lpszMenuName) if (lpwcx->lpszMenuName != NULL)
{ {
hMenu = 0; if (HIWORD(lpwcx->lpszMenuName))
RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName); {
} RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
else }
{ else
MenuName.Length = {
MenuName.MaximumLength = 0; MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName; }
hMenu = LoadMenuW(WndClass.hInstance, lpwcx->lpszMenuName); hMenu = LoadMenuW(WndClass.hInstance, lpwcx->lpszMenuName);
} }
@ -712,20 +655,18 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
ClassName.Length = ClassName.Length =
ClassName.MaximumLength = 0; ClassName.MaximumLength = 0;
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName; ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
} else }
else
{ {
RtlInitUnicodeString(&ClassName, WndClass.lpszClassName); RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
} }
return (ATOM)NtUserRegisterClassExWOW( return (ATOM)NtUserRegisterClassEx(&WndClass,
&WndClass, &ClassName,
&ClassName, &MenuName,
&ClassName, NULL,
&MenuName, 0,
NULL, hMenu);
0,
0,
hMenu);
} }
/* /*
@ -769,42 +710,65 @@ RegisterClassW(CONST WNDCLASSW *lpWndClass)
*/ */
DWORD DWORD
STDCALL STDCALL
SetClassLongA ( SetClassLongA (HWND hWnd,
HWND hWnd, int nIndex,
int nIndex, LONG dwNewLong)
LONG dwNewLong)
{ {
UNICODE_STRING str2buf; PSTR lpStr = (PSTR)dwNewLong;
PUNICODE_STRING str; UNICODE_STRING Value = {0};
PUNICODE_STRING str2 = &str2buf; BOOL Allocated = FALSE;
DWORD Ret;
if ( nIndex != GCL_MENUNAME ) /* FIXME - portability!!!! */
{
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 (nIndex == GCL_MENUNAME && lpStr != NULL)
{
if (!IS_INTRESOURCE(lpStr))
{
if (!RtlCreateUnicodeStringFromAsciiz(&Value,
lpStr))
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
if ( !IS_INTRESOURCE(dwNewLong) ) Allocated = TRUE;
{ }
RtlFreeUnicodeString ( str2 ); else
} Value.Buffer = (PWSTR)lpStr;
if ( IS_INTRESOURCE(str) )
{ dwNewLong = (LONG)&Value;
return (DWORD)str; }
} else if (nIndex == GCW_ATOM && lpStr != NULL)
else {
{ if (!IS_ATOM(lpStr))
return (DWORD)heap_string_poolA ( str->Buffer, str->Length ); {
} 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 @@ SetClassLongA (
*/ */
DWORD DWORD
STDCALL STDCALL
SetClassLongW( SetClassLongW(HWND hWnd,
HWND hWnd, int nIndex,
int nIndex, LONG dwNewLong)
LONG dwNewLong)
{ {
UNICODE_STRING str2buf; PWSTR lpStr = (PWSTR)dwNewLong;
PUNICODE_STRING str; UNICODE_STRING Value = {0};
PUNICODE_STRING str2 = &str2buf;
if (nIndex != GCL_MENUNAME ) /* FIXME - portability!!!! */
{
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 (nIndex == GCL_MENUNAME && lpStr != NULL)
{
if (!IS_INTRESOURCE(lpStr))
{
RtlInitUnicodeString(&Value,
lpStr);
}
else
Value.Buffer = lpStr;
if ( !IS_INTRESOURCE(dwNewLong) ) dwNewLong = (LONG)&Value;
{ }
RtlFreeUnicodeString(str2); else if (nIndex == GCW_ATOM && lpStr != NULL)
} {
if ( IS_INTRESOURCE(str) ) if (!IS_ATOM(lpStr))
{ {
return (DWORD)str; RtlInitUnicodeString(&Value,
} lpStr);
else }
{ else
return (DWORD)heap_string_poolW ( str->Buffer, str->Length ); Value.Buffer = lpStr;
}
dwNewLong = (LONG)&Value;
}
return (DWORD)NtUserSetClassLong(hWnd,
nIndex,
dwNewLong,
FALSE);
} }
@ -868,7 +834,7 @@ SetClassWord(
if ((nIndex < 0) && (nIndex != GCW_ATOM)) if ((nIndex < 0) && (nIndex != GCW_ATOM))
return 0; return 0;
return (WORD) NtUserSetClassLong ( hWnd, nIndex, wNewWord, TRUE ); return (WORD) SetClassLongW ( hWnd, nIndex, wNewWord );
} }
@ -909,28 +875,32 @@ UnregisterClassA(
LPCSTR lpClassName, LPCSTR lpClassName,
HINSTANCE hInstance) HINSTANCE hInstance)
{ {
LPWSTR ClassName; UNICODE_STRING ClassName = {0};
NTSTATUS Status; NTSTATUS Status;
BOOL Result; BOOL Ret;
if(!IS_ATOM(lpClassName)) if (!IS_ATOM(lpClassName))
{
Status = HEAP_strdupAtoW(&ClassName, lpClassName, NULL);
if(!NT_SUCCESS(Status))
{ {
SetLastError(RtlNtStatusToDosError(Status)); Status = HEAP_strdupAtoW(&ClassName.Buffer, lpClassName, NULL);
return FALSE; if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
RtlInitUnicodeString(&ClassName,
ClassName.Buffer);
} }
} else
else ClassName.Buffer = (PWSTR)((ULONG_PTR)lpClassName);
ClassName = (LPWSTR)lpClassName;
Result = (BOOL)NtUserUnregisterClass((LPCWSTR)ClassName, hInstance, 0); Ret = NtUserUnregisterClass(&ClassName,
hInstance);
if(ClassName && !IS_ATOM(lpClassName)) if(!IS_ATOM(lpClassName) && ClassName.Buffer != NULL)
HEAP_free(ClassName); HEAP_free(ClassName.Buffer);
return Result; return Ret;
} }
@ -943,7 +913,18 @@ UnregisterClassW(
LPCWSTR lpClassName, LPCWSTR lpClassName,
HINSTANCE hInstance) 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 */ /* EOF */

View file

@ -951,6 +951,7 @@ IntCallWindowProcW(BOOL IsAnsiProc,
return FALSE; return FALSE;
} }
Result = WndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam); Result = WndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam);
if (! MsgiUnicodeToAnsiReply(&AnsiMsg, &UnicodeMsg, &Result)) if (! MsgiUnicodeToAnsiReply(&AnsiMsg, &UnicodeMsg, &Result))
{ {
return FALSE; return FALSE;
@ -991,6 +992,7 @@ IntCallWindowProcA(BOOL IsAnsiProc,
} }
Result = WndProc(UnicodeMsg.hwnd, UnicodeMsg.message, Result = WndProc(UnicodeMsg.hwnd, UnicodeMsg.message,
UnicodeMsg.wParam, UnicodeMsg.lParam); UnicodeMsg.wParam, UnicodeMsg.lParam);
if (! MsgiAnsiToUnicodeReply(&UnicodeMsg, &AnsiMsg, &Result)) if (! MsgiAnsiToUnicodeReply(&UnicodeMsg, &AnsiMsg, &Result))
{ {
return FALSE; return FALSE;
@ -1010,20 +1012,19 @@ CallWindowProcA(WNDPROC lpPrevWndFunc,
WPARAM wParam, WPARAM wParam,
LPARAM lParam) LPARAM lParam)
{ {
BOOL IsHandle; WNDPROC_INFO wpInfo;
WndProcHandle wphData;
if (lpPrevWndFunc == NULL) if (lpPrevWndFunc == NULL)
lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWL_WNDPROC, FALSE); lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWLP_WNDPROC, FALSE);
IsHandle = NtUserDereferenceWndProcHandle(lpPrevWndFunc,&wphData); if (!NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
if (! IsHandle) &wpInfo))
{ {
return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam); return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
} }
else else
{ {
return IntCallWindowProcA(! wphData.IsUnicode, wphData.WindowProc, return IntCallWindowProcA(!wpInfo.IsUnicode, wpInfo.WindowProc,
hWnd, Msg, wParam, lParam); hWnd, Msg, wParam, lParam);
} }
} }
@ -1039,17 +1040,16 @@ CallWindowProcW(WNDPROC lpPrevWndFunc,
WPARAM wParam, WPARAM wParam,
LPARAM lParam) LPARAM lParam)
{ {
BOOL IsHandle; WNDPROC_INFO wpInfo;
WndProcHandle wphData;
IsHandle = NtUserDereferenceWndProcHandle(lpPrevWndFunc,&wphData); if (!NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
if (! IsHandle) &wpInfo))
{ {
return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam); return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
} }
else else
{ {
return IntCallWindowProcW(! wphData.IsUnicode, wphData.WindowProc, return IntCallWindowProcW(!wpInfo.IsUnicode, wpInfo.WindowProc,
hWnd, Msg, wParam, lParam); hWnd, Msg, wParam, lParam);
} }
} }

View file

@ -289,8 +289,8 @@ CreateWindowExW(DWORD dwExStyle,
{ {
wce.cbSize = sizeof(WNDCLASSEXW); wce.cbSize = sizeof(WNDCLASSEXW);
if(GetClassInfoExW(hInstance, lpClassName, &wce) && wce.lpszMenuName) if(GetClassInfoExW(hInstance, lpClassName, &wce) && wce.lpszMenuName)
{ {DbgPrint("LoadingMenu 0x%p %d\n", wce.lpszMenuName, IS_INTRESOURCE(wce.lpszMenuName));
hMenu = LoadMenuW(hInstance, wce.lpszMenuName); hMenu = LoadMenuW(hInstance, wce.lpszMenuName);DbgPrint("Loaded menu: 0x%p\n", hMenu);
} }
} }
@ -1449,7 +1449,7 @@ HWND
STDCALL STDCALL
GetFocus(VOID) GetFocus(VOID)
{ {
return (HWND)NtUserGetThreadState(0); return (HWND)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW);
} }
/* /*

View file

@ -424,7 +424,7 @@ typedef struct _TEB
ULONG LastErrorValue; /* 34h */ ULONG LastErrorValue; /* 34h */
ULONG CountOfOwnedCriticalSections; /* 38h */ ULONG CountOfOwnedCriticalSections; /* 38h */
PVOID CsrClientThread; /* 3Ch */ PVOID CsrClientThread; /* 3Ch */
struct _W32THREAD* Win32ThreadInfo; /* 40h */ PVOID Win32ThreadInfo; /* 40h */
ULONG User32Reserved[0x1A]; /* 44h */ ULONG User32Reserved[0x1A]; /* 44h */
ULONG UserReserved[5]; /* ACh */ ULONG UserReserved[5]; /* ACh */
PVOID WOW32Reserved; /* C0h */ PVOID WOW32Reserved; /* C0h */

View file

@ -9,6 +9,14 @@ static const UNICODE_STRING __emptyUnicodeString = {0};
static const LARGE_INTEGER __emptyLargeInteger = {{0, 0}}; static const LARGE_INTEGER __emptyLargeInteger = {{0, 0}};
static const ULARGE_INTEGER __emptyULargeInteger = {{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! * NOTE: Alignment of the pointers is not verified!
*/ */

View file

@ -1,6 +1,75 @@
#ifndef __WIN32K_NTUSER_H #ifndef __WIN32K_NTUSER_H
#define __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 DWORD
NTAPI NTAPI
@ -196,8 +265,8 @@ NtUserTrackPopupMenuEx(
ULONG NTAPI ULONG NTAPI
NtUserGetSystemMetrics(ULONG Index); NtUserGetSystemMetrics(ULONG Index);
DWORD NTAPI ULONG_PTR NTAPI
NtUserGetClassLong(HWND hWnd, DWORD Offset, BOOL Ansi); NtUserGetClassLong(HWND hWnd, INT Offset, BOOL Ansi);
LONG NTAPI LONG NTAPI
NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi); NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi);
@ -785,18 +854,17 @@ NTAPI
NtUserGetCaretPos( NtUserGetCaretPos(
LPPOINT lpPoint); LPPOINT lpPoint);
DWORD NTAPI BOOL NTAPI
NtUserGetClassInfo(HINSTANCE hInst, NtUserGetClassInfo(HINSTANCE hInstance,
LPCWSTR str, PUNICODE_STRING ClassName,
LPWNDCLASSEXW wcex, LPWNDCLASSEXW wcex,
BOOL Ansi, BOOL Ansi);
DWORD unknown3);
DWORD INT
NTAPI NTAPI
NtUserGetClassName(HWND hWnd, NtUserGetClassName(HWND hWnd,
LPWSTR lpClassName, PUNICODE_STRING ClassName,
ULONG nMaxCount); BOOL Ansi);
HANDLE HANDLE
NTAPI NTAPI
@ -1041,6 +1109,7 @@ NtUserGetThreadDesktop(
DWORD dwThreadId, DWORD dwThreadId,
DWORD Unknown1); DWORD Unknown1);
#define THREADSTATE_GETTHREADINFO (0)
#define THREADSTATE_FOCUSWINDOW (1) #define THREADSTATE_FOCUSWINDOW (1)
#define THREADSTATE_INSENDMESSAGE (2) #define THREADSTATE_INSENDMESSAGE (2)
DWORD DWORD
@ -1355,14 +1424,12 @@ NtUserRedrawWindow
#define REGISTERCLASS_ALL (REGISTERCLASS_ANSI | REGISTERCLASS_SYSTEM) #define REGISTERCLASS_ALL (REGISTERCLASS_ANSI | REGISTERCLASS_SYSTEM)
RTL_ATOM NTAPI RTL_ATOM NTAPI
NtUserRegisterClassExWOW( NtUserRegisterClassEx(
CONST WNDCLASSEXW* lpwcx, CONST WNDCLASSEXW* lpwcx,
PUNICODE_STRING ClassName, PUNICODE_STRING ClassName,
PUNICODE_STRING ClassNameCopy,
PUNICODE_STRING MenuName, PUNICODE_STRING MenuName,
WNDPROC wpExtra, WNDPROC wpExtra,
DWORD Flags, DWORD Flags,
DWORD Unknown7,
HMENU hMenu); HMENU hMenu);
BOOL BOOL
@ -1470,11 +1537,11 @@ NtUserSetCapture(HWND Wnd);
HWND NTAPI HWND NTAPI
NtUserGetCapture(VOID); NtUserGetCapture(VOID);
DWORD NTAPI ULONG_PTR NTAPI
NtUserSetClassLong( NtUserSetClassLong(
HWND hWnd, HWND hWnd,
DWORD Offset, INT Offset,
LONG dwNewLong, ULONG_PTR dwNewLong,
BOOL Ansi ); BOOL Ansi );
@ -1840,9 +1907,8 @@ NtUserUnlockWindowStation(
BOOL BOOL
NTAPI NTAPI
NtUserUnregisterClass( NtUserUnregisterClass(
LPCWSTR ClassNameOrAtom, PUNICODE_STRING ClassNameOrAtom,
HINSTANCE hInstance, HINSTANCE hInstance);
DWORD Unknown);
BOOL BOOL
NTAPI NTAPI
@ -1951,15 +2017,15 @@ NtUserGetWindow(HWND hWnd, UINT Relationship);
HWND NTAPI HWND NTAPI
NtUserGetLastActivePopup(HWND hWnd); NtUserGetLastActivePopup(HWND hWnd);
typedef struct _WndProcHandle
typedef struct _WNDPROC_INFO
{ {
WNDPROC WindowProc; WNDPROC WindowProc;
BOOL IsUnicode; BOOL IsUnicode;
HANDLE ProcessID; } WNDPROC_INFO, *PWNDPROC_INFO;
} WndProcHandle;
DWORD NTAPI BOOL NTAPI
NtUserDereferenceWndProcHandle(WNDPROC wpHandle, WndProcHandle *Data); NtUserDereferenceWndProcHandle(IN HANDLE wpHandle, OUT PWNDPROC_INFO wpInfo);
VOID NTAPI VOID NTAPI
NtUserManualGuiCheck(LONG Check); NtUserManualGuiCheck(LONG Check);

View file

@ -311,7 +311,7 @@ HEAP_Commit(SUBHEAP *subheap,
} }
else else
{ {
Status = NtAllocateVirtualMemory(NtCurrentProcess(), Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
&address, &address,
0, 0,
&commitsize, &commitsize,
@ -570,13 +570,24 @@ static BOOLEAN HEAP_InitSubHeap( HEAP *heap, PVOID address, ULONG flags,
/* Initialize critical section */ /* Initialize critical section */
RtlInitializeHeapLock( &heap->critSection ); if (RtlpGetMode() == UserMode)
{
RtlInitializeHeapLock( &heap->critSection );
}
} }
/* Commit memory */ /* Commit memory */
if (heap->commitRoutine) 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 else
{ {

View file

@ -4,28 +4,19 @@
#define IS_ATOM(x) \ #define IS_ATOM(x) \
(((ULONG_PTR)(x) > 0x0) && ((ULONG_PTR)(x) < 0x10000)) (((ULONG_PTR)(x) > 0x0) && ((ULONG_PTR)(x) < 0x10000))
typedef struct _WNDCLASS_OBJECT VOID
{ DestroyCallProc(IN PDESKTOP Desktop,
UINT cbSize; IN OUT PCALLPROC CallProc);
LONG refs; /* windows using this class (is 0 after class creation) */
UINT style; PCALLPROC
WNDPROC lpfnWndProcA; CloneCallProc(IN PDESKTOP Desktop,
WNDPROC lpfnWndProcW; IN PCALLPROC CallProc);
int cbClsExtra;
int cbWndExtra; PCALLPROC
HANDLE hInstance; CreateCallProc(IN PDESKTOP Desktop,
HICON hIcon; IN WNDPROC WndProc,
HCURSOR hCursor; IN BOOL Unicode,
HBRUSH hbrBackground; IN PW32PROCESSINFO pi);
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;
NTSTATUS FASTCALL NTSTATUS FASTCALL
InitClassImpl(VOID); InitClassImpl(VOID);
@ -33,32 +24,45 @@ InitClassImpl(VOID);
NTSTATUS FASTCALL NTSTATUS FASTCALL
CleanupClassImpl(VOID); CleanupClassImpl(VOID);
void FASTCALL DestroyProcessClasses(PW32PROCESS Process ); BOOL
UserGetCallProcInfo(IN HANDLE hCallProc,
OUT PWNDPROC_INFO wpInfo);
__inline VOID FASTCALL void FASTCALL
ClassDerefObject(PWNDCLASS_OBJECT Class); DestroyProcessClasses(PW32PROCESS Process );
__inline VOID FASTCALL PWINDOWCLASS
ClassRefObject(PWNDCLASS_OBJECT Class); IntReferenceClass(IN PWINDOWCLASS BaseClass,
IN PDESKTOP Desktop);
PWNDCLASS_OBJECT FASTCALL VOID
ClassGetClassByAtom( IntDereferenceClass(IN OUT PWINDOWCLASS Class,
RTL_ATOM Atom, IN PDESKTOP Desktop,
HINSTANCE hInstance); IN PW32PROCESSINFO pi);
PWNDCLASS_OBJECT FASTCALL RTL_ATOM
ClassGetClassByName( UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
LPCWSTR ClassName, IN PUNICODE_STRING ClassName,
HINSTANCE hInstance); IN PUNICODE_STRING MenuName,
IN HANDLE hMenu,
IN WNDPROC wpExtra,
IN DWORD dwFlags);
PWNDCLASS_OBJECT FASTCALL BOOL
ClassGetClassByNameOrAtom( UserUnregisterClass(IN PUNICODE_STRING ClassName,
LPCWSTR ClassNameOrAtom, IN HINSTANCE hInstance);
HINSTANCE hInstance);
struct _WINDOW_OBJECT; ULONG_PTR
ULONG FASTCALL UserGetClassLongPtr(IN PWINDOWCLASS Class,
IntGetClassLong(struct _WINDOW_OBJECT *WindowObject, ULONG Offset, BOOL Ansi); 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 */ #endif /* _WIN32K_CLASS_H */

View file

@ -6,8 +6,6 @@
typedef struct _DESKTOP_OBJECT typedef struct _DESKTOP_OBJECT
{ {
PVOID DesktopHeap; /* points to kmode memory! */
CSHORT Type; CSHORT Type;
CSHORT Size; CSHORT Size;
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
@ -26,11 +24,15 @@ typedef struct _DESKTOP_OBJECT
PVOID BlockInputThread; PVOID BlockInputThread;
LIST_ENTRY ShellHookWindows; LIST_ENTRY ShellHookWindows;
HANDLE hDesktopHeap;
PSECTION_OBJECT DesktopHeapSection;
PDESKTOP DesktopInfo;
} DESKTOP_OBJECT, *PDESKTOP_OBJECT; } DESKTOP_OBJECT, *PDESKTOP_OBJECT;
extern PDESKTOP_OBJECT InputDesktop; extern PDESKTOP_OBJECT InputDesktop;
extern HDESK InputDesktopHandle; extern HDESK InputDesktopHandle;
extern PWNDCLASS_OBJECT DesktopWindowClass; extern PWINDOWCLASS DesktopWindowClass;
extern HDC ScreenDeviceContext; extern HDC ScreenDeviceContext;
extern BOOL g_PaintDesktopVersion; extern BOOL g_PaintDesktopVersion;
@ -91,6 +93,8 @@ IntHideDesktop(PDESKTOP_OBJECT Desktop);
HDESK FASTCALL HDESK FASTCALL
IntGetDesktopObjectHandle(PDESKTOP_OBJECT DesktopObject); IntGetDesktopObjectHandle(PDESKTOP_OBJECT DesktopObject);
BOOL IntSetThreadDesktop(IN PDESKTOP_OBJECT DesktopObject);
NTSTATUS FASTCALL NTSTATUS FASTCALL
IntValidateDesktopHandle( IntValidateDesktopHandle(
HDESK Desktop, HDESK Desktop,
@ -115,6 +119,113 @@ VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam);
#define IntIsActiveDesktop(Desktop) \ #define IntIsActiveDesktop(Desktop) \
((Desktop)->WindowStation->ActiveDesktop == (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 */ #endif /* _WIN32K_DESKTOP_H */
/* EOF */ /* EOF */

View file

@ -45,7 +45,7 @@ typedef enum _USER_OBJECT_TYPE
otCursorIcon, otCursorIcon,
otHook, otHook,
otMonitor, otMonitor,
otClass //fixme: remove otCallProc
} USER_OBJECT_TYPE; } USER_OBJECT_TYPE;
@ -125,6 +125,8 @@ typedef struct _USER_REFERENCE_ENTRY
\ \
} }
HANDLE FASTCALL ObmObjectToHandle(PVOID obj);
VOID FASTCALL CreateStockObjects (VOID); VOID FASTCALL CreateStockObjects (VOID);
VOID FASTCALL CreateSysColorObjects (VOID); VOID FASTCALL CreateSysColorObjects (VOID);

View file

@ -75,7 +75,7 @@ BOOL FASTCALL ObmCreateHandleTable();
/******************** HANDLE.C ***************/ /******************** HANDLE.C ***************/
extern USER_HANDLE_TABLE gHandleTable; extern PUSER_HANDLE_TABLE gHandleTable;
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle ); PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle );
VOID UserInitHandleTable(PUSER_HANDLE_TABLE ht, PVOID mem, ULONG bytes); VOID UserInitHandleTable(PUSER_HANDLE_TABLE ht, PVOID mem, ULONG bytes);

View file

@ -15,10 +15,18 @@ typedef struct _W32THREAD
BOOLEAN IsExiting; BOOLEAN IsExiting;
SINGLE_LIST_ENTRY ReferencesList; SINGLE_LIST_ENTRY ReferencesList;
PW32THREADINFO ThreadInfo;
} W32THREAD, *PW32THREAD; } W32THREAD, *PW32THREAD;
#include <poppack.h> #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 typedef struct _W32PROCESS
{ {
@ -32,6 +40,9 @@ typedef struct _W32PROCESS
ULONG Flags; ULONG Flags;
LONG GDIObjects; LONG GDIObjects;
LONG UserObjects; LONG UserObjects;
W32HEAP_USER_MAPPING HeapMappings;
PW32PROCESSINFO ProcessInfo;
} W32PROCESS, *PW32PROCESS; } W32PROCESS, *PW32PROCESS;

View file

@ -26,8 +26,21 @@ typedef struct _INTERNALPOS
typedef struct _WINDOW_OBJECT 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. */ /* Pointer to the window class. */
PWNDCLASS_OBJECT Class; PWINDOWCLASS Class;
/* Extended style. */ /* Extended style. */
DWORD ExStyle; DWORD ExStyle;
/* Window name. */ /* Window name. */
@ -81,8 +94,7 @@ typedef struct _WINDOW_OBJECT
PWINDOW_SCROLLINFO Scroll; PWINDOW_SCROLLINFO Scroll;
LONG UserData; LONG UserData;
BOOL Unicode; BOOL Unicode;
WNDPROC WndProcA; WNDPROC WndProc;
WNDPROC WndProcW;
PETHREAD OwnerThread; PETHREAD OwnerThread;
HWND hWndLastPopup; /* handle to last active popup window (wine doesn't use pointer, for unk. reason)*/ HWND hWndLastPopup; /* handle to last active popup window (wine doesn't use pointer, for unk. reason)*/
PINTERNALPOS InternalPos; PINTERNALPOS InternalPos;
@ -190,10 +202,6 @@ IntAnyPopup(VOID);
BOOL FASTCALL BOOL FASTCALL
IntIsWindowInDestroy(PWINDOW_OBJECT Window); IntIsWindowInDestroy(PWINDOW_OBJECT Window);
DWORD IntRemoveWndProcHandle(WNDPROC Handle);
DWORD IntRemoveProcessWndProcHandles(HANDLE ProcessID);
DWORD IntAddWndProcHandle(WNDPROC WindowProc, BOOL IsUnicode);
BOOL FASTCALL BOOL FASTCALL
IntShowOwnedPopups( PWINDOW_OBJECT owner, BOOL fShow ); IntShowOwnedPopups( PWINDOW_OBJECT owner, BOOL fShow );

View file

@ -33,6 +33,9 @@ BOOL INTERNAL_CALL GDI_CleanupForProcess (PGDI_HANDLE_TABLE HandleTable, struct
PGDI_HANDLE_TABLE GdiHandleTable = NULL; PGDI_HANDLE_TABLE GdiHandleTable = NULL;
PSECTION_OBJECT GdiTableSection = NULL; PSECTION_OBJECT GdiTableSection = NULL;
HANDLE GlobalUserHeap = NULL;
PSECTION_OBJECT GlobalUserHeapSection = NULL;
extern ULONG_PTR Win32kSSDT[]; extern ULONG_PTR Win32kSSDT[];
extern UCHAR Win32kSSPT[]; extern UCHAR Win32kSSPT[];
extern ULONG Win32kNumberOfSysCalls; extern ULONG Win32kNumberOfSysCalls;
@ -69,8 +72,35 @@ Win32kProcessCallback(struct _EPROCESS *Process,
if (Create) 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()); 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); InitializeListHead(&Win32Process->ClassList);
InitializeListHead(&Win32Process->MenuListHead); InitializeListHead(&Win32Process->MenuListHead);
@ -95,7 +125,6 @@ Win32kProcessCallback(struct _EPROCESS *Process,
else else
{ {
DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql()); DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
IntRemoveProcessWndProcHandles((HANDLE)Process->UniqueProcessId);
IntCleanupMenus(Process, Win32Process); IntCleanupMenus(Process, Win32Process);
IntCleanupCurIcons(Process, Win32Process); IntCleanupCurIcons(Process, Win32Process);
IntEngCleanupDriverObjs(Process, Win32Process); IntEngCleanupDriverObjs(Process, Win32Process);
@ -115,6 +144,12 @@ Win32kProcessCallback(struct _EPROCESS *Process,
{ {
LogonProcess = NULL; LogonProcess = NULL;
} }
if (Win32Process->ProcessInfo != NULL)
{
UserHeapFree(Win32Process->ProcessInfo);
Win32Process->ProcessInfo = NULL;
}
} }
RETURN( STATUS_SUCCESS); RETURN( STATUS_SUCCESS);
@ -198,17 +233,25 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
if (hDesk != NULL) if (hDesk != NULL)
{ {
PDESKTOP_OBJECT DesktopObject;
Win32Thread->Desktop = NULL;
Status = ObReferenceObjectByHandle(hDesk, Status = ObReferenceObjectByHandle(hDesk,
0, 0,
ExDesktopObjectType, ExDesktopObjectType,
KernelMode, KernelMode,
(PVOID*)&Win32Thread->Desktop, (PVOID*)&DesktopObject,
NULL); NULL);
NtClose(hDesk); 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); DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk);
Win32Thread->Desktop = NULL;
} }
} }
} }
@ -234,11 +277,15 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
IntBlockInput(Win32Thread, FALSE); IntBlockInput(Win32Thread, FALSE);
MsqDestroyMessageQueue(Win32Thread->MessageQueue); MsqDestroyMessageQueue(Win32Thread->MessageQueue);
IntCleanupThreadCallbacks(Win32Thread); IntCleanupThreadCallbacks(Win32Thread);
if(Win32Thread->Desktop != NULL)
IntSetThreadDesktop(NULL);
if (Win32Thread->ThreadInfo != NULL)
{ {
ObDereferenceObject(Win32Thread->Desktop); UserHeapFree(Win32Thread->ThreadInfo);
Win32Thread->ThreadInfo = NULL;
} }
/* cleanup user object references stack */ /* cleanup user object references stack */
e = PopEntryList(&Win32Thread->ReferencesList); e = PopEntryList(&Win32Thread->ReferencesList);
while (e) while (e)
@ -309,6 +356,7 @@ DriverEntry (
NTSTATUS Status; NTSTATUS Status;
BOOLEAN Result; BOOLEAN Result;
W32_CALLOUT_DATA CalloutData; W32_CALLOUT_DATA CalloutData;
PVOID GlobalUserHeapBase = NULL;
/* /*
* Register user mode call interface * Register user mode call interface
@ -342,6 +390,16 @@ DriverEntry (
*/ */
PsEstablishWin32Callouts(&CalloutData); 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(); Status = InitUserImpl();
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {

View file

@ -61,4 +61,22 @@ GetLastNtError()
return 0; 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 */ /* EOF */

View file

@ -0,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;
}

View file

@ -80,7 +80,7 @@ PACCELERATOR_TABLE FASTCALL UserGetAccelObject(HACCEL hAccel)
return NULL; return NULL;
} }
Accel= UserGetObject(&gHandleTable, hAccel, otAccel); Accel= UserGetObject(gHandleTable, hAccel, otAccel);
if (!Accel) if (!Accel)
{ {
SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE); SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE);
@ -344,7 +344,7 @@ NtUserCreateAcceleratorTable(
Entries, EntriesCount); Entries, EntriesCount);
UserEnterExclusive(); UserEnterExclusive();
Accel = ObmCreateObject(&gHandleTable, (PHANDLE)&hAccel, otAccel, sizeof(ACCELERATOR_TABLE)); Accel = ObmCreateObject(gHandleTable, (PHANDLE)&hAccel, otAccel, sizeof(ACCELERATOR_TABLE));
if (Accel == NULL) if (Accel == NULL)
{ {

File diff suppressed because it is too large Load diff

View file

@ -83,7 +83,7 @@ PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
return NULL; return NULL;
} }
CurIcon = (PCURICON_OBJECT)UserGetObject(&gHandleTable, hCurIcon, otCursorIcon); CurIcon = (PCURICON_OBJECT)UserGetObject(gHandleTable, hCurIcon, otCursorIcon);
if (!CurIcon) if (!CurIcon)
{ {
/* we never set ERROR_INVALID_ICON_HANDLE. lets hope noone ever checks for it */ /* we never set ERROR_INVALID_ICON_HANDLE. lets hope noone ever checks for it */
@ -397,7 +397,7 @@ IntCreateCurIconHandle(PWINSTATION_OBJECT WinSta)
PCURICON_OBJECT CurIcon; PCURICON_OBJECT CurIcon;
HANDLE hCurIcon; HANDLE hCurIcon;
CurIcon = ObmCreateObject(&gHandleTable, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT)); CurIcon = ObmCreateObject(gHandleTable, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
if(!CurIcon) if(!CurIcon)
{ {

View file

@ -43,6 +43,8 @@ HDC ScreenDeviceContext = NULL;
BOOL g_PaintDesktopVersion = FALSE; BOOL g_PaintDesktopVersion = FALSE;
static VOID IntFreeDesktopHeap(IN OUT PDESKTOP_OBJECT Desktop);
/* INITALIZATION FUNCTIONS ****************************************************/ /* INITALIZATION FUNCTIONS ****************************************************/
static GENERIC_MAPPING IntDesktopMapping = static GENERIC_MAPPING IntDesktopMapping =
@ -121,6 +123,8 @@ IntDesktopObjectDelete(PVOID DeletedObject)
RemoveEntryList(&Desktop->ListEntry); RemoveEntryList(&Desktop->ListEntry);
RtlFreeUnicodeString(&Desktop->Name); RtlFreeUnicodeString(&Desktop->Name);
IntFreeDesktopHeap(Desktop);
} }
/* PRIVATE FUNCTIONS **********************************************************/ /* PRIVATE FUNCTIONS **********************************************************/
@ -723,7 +727,15 @@ BOOL IntDeRegisterShellHookWindow(HWND hWnd)
return FALSE; return FALSE;
} }
static VOID
IntFreeDesktopHeap(IN OUT PDESKTOP_OBJECT Desktop)
{
if (Desktop->DesktopHeapSection != NULL)
{
ObDereferenceObject(Desktop->DesktopHeapSection);
Desktop->DesktopHeapSection = NULL;
}
}
/* SYSCALLS *******************************************************************/ /* SYSCALLS *******************************************************************/
@ -776,6 +788,8 @@ NtUserCreateDesktop(
NTSTATUS Status; NTSTATUS Status;
HDESK Desktop; HDESK Desktop;
CSR_API_MESSAGE Request; CSR_API_MESSAGE Request;
PVOID DesktopHeapSystemBase = NULL;
SIZE_T DesktopInfoSize;
DECLARE_RETURN(HDESK); DECLARE_RETURN(HDESK);
DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName); DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
@ -858,6 +872,39 @@ NtUserCreateDesktop(
RETURN( NULL); 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 // init desktop area
DesktopObject->WorkArea.left = 0; DesktopObject->WorkArea.left = 0;
DesktopObject->WorkArea.top = 0; DesktopObject->WorkArea.top = 0;
@ -1216,7 +1263,7 @@ NtUserPaintDesktop(HDC hDC)
RETURN(FALSE); RETURN(FALSE);
} }
DesktopBrush = (HBRUSH)IntGetClassLong(WndDesktop, GCL_HBRBACKGROUND, FALSE); //fixme: verify retval DesktopBrush = (HBRUSH)UserGetClassLongPtr(WndDesktop->Class, GCL_HBRBACKGROUND, FALSE);
/* /*
@ -1560,6 +1607,183 @@ CLEANUP:
END_CLEANUP; 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 * NtUserSetThreadDesktop
* *
@ -1570,7 +1794,6 @@ CLEANUP:
BOOL STDCALL BOOL STDCALL
NtUserSetThreadDesktop(HDESK hDesktop) NtUserSetThreadDesktop(HDESK hDesktop)
{ {
PW32THREAD W32Thread;
PDESKTOP_OBJECT DesktopObject; PDESKTOP_OBJECT DesktopObject;
NTSTATUS Status; NTSTATUS Status;
DECLARE_RETURN(BOOL); DECLARE_RETURN(BOOL);
@ -1591,18 +1814,13 @@ NtUserSetThreadDesktop(HDESK hDesktop)
RETURN(FALSE); RETURN(FALSE);
} }
W32Thread = PsGetWin32Thread();
/* FIXME: Should check here to see if the thread has any windows. */ /* FIXME: Should check here to see if the thread has any windows. */
if (W32Thread->Desktop != NULL) if (!IntSetThreadDesktop(DesktopObject))
{ {
ObDereferenceObject(W32Thread->Desktop); RETURN(FALSE);
} }
W32Thread->Desktop = DesktopObject;
W32Thread->hDesktop = hDesktop;
RETURN(TRUE); RETURN(TRUE);
CLEANUP: CLEANUP:

View file

@ -69,7 +69,7 @@ PHOOK FASTCALL IntGetHookObject(HHOOK hHook)
return NULL; return NULL;
} }
Hook = (PHOOK)UserGetObject(&gHandleTable, hHook, otHook); Hook = (PHOOK)UserGetObject(gHandleTable, hHook, otHook);
if (!Hook) if (!Hook)
{ {
SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE); SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE);
@ -110,7 +110,7 @@ IntAddHook(PETHREAD Thread, int HookId, BOOLEAN Global, PWINSTATION_OBJECT WinSt
} }
} }
Hook = ObmCreateObject(&gHandleTable, &Handle, otHook, sizeof(HOOK)); Hook = ObmCreateObject(gHandleTable, &Handle, otHook, sizeof(HOOK));
if (NULL == Hook) if (NULL == Hook)
{ {
return NULL; return NULL;

View file

@ -127,7 +127,7 @@ PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu)
return NULL; return NULL;
} }
Menu = (PMENU_OBJECT)UserGetObject(&gHandleTable, hMenu, otMenu); Menu = (PMENU_OBJECT)UserGetObject(gHandleTable, hMenu, otMenu);
if (!Menu) if (!Menu)
{ {
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE); SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
@ -310,7 +310,7 @@ IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar)
PMENU_OBJECT Menu; PMENU_OBJECT Menu;
Menu = (PMENU_OBJECT)ObmCreateObject( Menu = (PMENU_OBJECT)ObmCreateObject(
&gHandleTable, Handle, gHandleTable, Handle,
otMenu, sizeof(MENU_OBJECT)); otMenu, sizeof(MENU_OBJECT));
if(!Menu) if(!Menu)
@ -419,7 +419,7 @@ IntCloneMenu(PMENU_OBJECT Source)
return NULL; return NULL;
Menu = (PMENU_OBJECT)ObmCreateObject( Menu = (PMENU_OBJECT)ObmCreateObject(
&gHandleTable, &hMenu, gHandleTable, &hMenu,
otMenu, sizeof(MENU_OBJECT)); otMenu, sizeof(MENU_OBJECT));
if(!Menu) if(!Menu)

View file

@ -378,28 +378,9 @@ NtUserDispatchMessage(PNTUSERDISPATCHMESSAGEINFO UnsafeMsgInfo)
MsgInfo.HandledByKernel = FALSE; MsgInfo.HandledByKernel = FALSE;
Result = 0; Result = 0;
if (0xFFFF0000 != ((DWORD) Window->WndProcW & 0xFFFF0000))
{ MsgInfo.Ansi = !Window->Unicode;
if (0xFFFF0000 != ((DWORD) Window->WndProcA & 0xFFFF0000)) MsgInfo.Proc = Window->WndProc;
{
/* 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;
}
} }
} }
} }
@ -615,7 +596,7 @@ co_IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *
{ {
/* generate double click messages, if necessary */ /* generate double click messages, if necessary */
if ((((*HitTest) != HTCLIENT) || if ((((*HitTest) != HTCLIENT) ||
(IntGetClassLong(Window, GCL_STYLE, FALSE) & CS_DBLCLKS)) && (Window->Class->Style & CS_DBLCLKS)) &&
MsqIsDblClk(Msg, Remove)) MsqIsDblClk(Msg, Remove))
{ {
Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN; Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
@ -1401,16 +1382,9 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
DPRINT1("Failed to pack message parameters\n"); DPRINT1("Failed to pack message parameters\n");
RETURN( FALSE); RETURN( FALSE);
} }
if (0xFFFF0000 != ((DWORD) Window->WndProcW & 0xFFFF0000))
{ Result = (ULONG_PTR)co_IntCallWindowProc(Window->WndProc, !Window->Unicode, hWnd, Msg, wParam,
Result = (ULONG_PTR)co_IntCallWindowProc(Window->WndProcW, FALSE, hWnd, Msg, wParam, lParamPacked,lParamBufferSize);
lParamPacked,lParamBufferSize);
}
else
{
Result = (ULONG_PTR)co_IntCallWindowProc(Window->WndProcA, TRUE, hWnd, Msg, wParam,
lParamPacked,lParamBufferSize);
}
if(uResult) if(uResult)
{ {
@ -1580,32 +1554,16 @@ co_IntDoSendMessage(HWND hWnd,
{ {
/* Gather the information usermode needs to call the window proc directly */ /* Gather the information usermode needs to call the window proc directly */
Info.HandledByKernel = FALSE; Info.HandledByKernel = FALSE;
if (0xFFFF0000 != ((DWORD) Window->WndProcW & 0xFFFF0000))
Status = MmCopyFromCaller(&(Info.Ansi), &(UnsafeInfo->Ansi),
sizeof(BOOL));
if (! NT_SUCCESS(Status))
{ {
if (0xFFFF0000 != ((DWORD) Window->WndProcA & 0xFFFF0000)) Info.Ansi = ! Window->Unicode;
{
/* 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;
} }
Info.Ansi = !Window->Unicode;
Info.Proc = Window->WndProc;
} }
else else
{ {

View file

@ -886,11 +886,22 @@ NtUserGetThreadState(
DECLARE_RETURN(DWORD); DECLARE_RETURN(DWORD);
DPRINT("Enter NtUserGetThreadState\n"); DPRINT("Enter NtUserGetThreadState\n");
UserEnterShared(); if (Routine != THREADSTATE_GETTHREADINFO)
{
UserEnterShared();
}
else
{
UserEnterExclusive();
}
switch (Routine) switch (Routine)
{ {
case 0: case THREADSTATE_GETTHREADINFO:
GetW32ThreadInfo();
RETURN(0);
case THREADSTATE_FOCUSWINDOW:
RETURN( (DWORD)IntGetThreadFocusWindow()); RETURN( (DWORD)IntGetThreadFocusWindow());
} }
RETURN( 0); RETURN( 0);
@ -1829,4 +1840,106 @@ CLEANUP:
END_CLEANUP; 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 */ /* EOF */

View file

@ -89,7 +89,7 @@ IntCreateMonitorObject()
HANDLE Handle; HANDLE Handle;
PMONITOR_OBJECT Monitor; PMONITOR_OBJECT Monitor;
Monitor = ObmCreateObject(&gHandleTable, &Handle, otMonitor, sizeof (MONITOR_OBJECT)); Monitor = ObmCreateObject(gHandleTable, &Handle, otMonitor, sizeof (MONITOR_OBJECT));
if (Monitor == NULL) if (Monitor == NULL)
{ {
return NULL; return NULL;
@ -133,7 +133,7 @@ UserGetMonitorObject(IN HMONITOR hMonitor)
} }
Monitor = (PMONITOR_OBJECT)UserGetObject(&gHandleTable, hMonitor, otMonitor); Monitor = (PMONITOR_OBJECT)UserGetObject(gHandleTable, hMonitor, otMonitor);
if (!Monitor) if (!Monitor)
{ {
SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE); SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE);

View file

@ -28,7 +28,7 @@
#include <debug.h> #include <debug.h>
int usedHandles=0; int usedHandles=0;
USER_HANDLE_TABLE gHandleTable; PUSER_HANDLE_TABLE gHandleTable = NULL;
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle ) PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle )
@ -71,19 +71,17 @@ __inline static PUSER_HANDLE_ENTRY alloc_user_entry(PUSER_HANDLE_TABLE ht)
DPRINT1("Out of user handles!\n"); DPRINT1("Out of user handles!\n");
return NULL; return NULL;
#if 0 #if 0
PUSER_HANDLE_ENTRY new_handles;
struct user_handle *new_handles;
/* grow array by 50% (but at minimum 32 entries) */ /* grow array by 50% (but at minimum 32 entries) */
int growth = max( 32, allocated_handles / 2 ); int growth = max( 32, ht->allocated_handles / 2 );
int new_size = min( allocated_handles + growth, (LAST_USER_HANDLE-FIRST_USER_HANDLE+1) >> 1 ); int new_size = min( ht->allocated_handles + growth, (LAST_USER_HANDLE-FIRST_USER_HANDLE+1) >> 1 );
if (new_size <= allocated_handles) if (new_size <= ht->allocated_handles)
return NULL; return NULL;
if (!(new_handles = realloc( handles, new_size * sizeof(*handles) ))) if (!(new_handles = UserHeapReAlloc( ht->handles, new_size * sizeof(*ht->handles) )))
return NULL; return NULL;
handles = new_handles; ht->handles = new_handles;
allocated_handles = new_size; ht->allocated_handles = new_size;
#endif #endif
} }
entry = &ht->handles[ht->nb_handles++]; entry = &ht->handles[ht->nb_handles++];
@ -217,7 +215,7 @@ ObmCreateObject(PUSER_HANDLE_TABLE ht, HANDLE* h,USER_OBJECT_TYPE type , ULONG s
{ {
HANDLE hi; 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) if (!hdr)
return NULL; return NULL;
@ -225,7 +223,8 @@ ObmCreateObject(PUSER_HANDLE_TABLE ht, HANDLE* h,USER_OBJECT_TYPE type , ULONG s
hi = UserAllocHandle(ht, USER_HEADER_TO_BODY(hdr), type ); hi = UserAllocHandle(ht, USER_HEADER_TO_BODY(hdr), type );
if (!hi) if (!hi)
{ {
ExFreePool(hdr); //ExFreePool(hdr);
UserHeapFree(hdr);
return NULL; return NULL;
} }
@ -242,7 +241,7 @@ BOOL FASTCALL
ObmDeleteObject(HANDLE h, USER_OBJECT_TYPE type ) ObmDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
{ {
PUSER_OBJECT_HEADER hdr; PUSER_OBJECT_HEADER hdr;
PVOID body = UserGetObject(&gHandleTable, h, type); PVOID body = UserGetObject(gHandleTable, h, type);
if (!body) if (!body)
return FALSE; return FALSE;
@ -252,11 +251,12 @@ ObmDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
hdr->destroyed = TRUE; hdr->destroyed = TRUE;
if (hdr->RefCount == 0) if (hdr->RefCount == 0)
{ {
UserFreeHandle(&gHandleTable, h); UserFreeHandle(gHandleTable, h);
memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER)); memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
ExFreePool(hdr); UserHeapFree(hdr);
//ExFreePool(hdr);
return TRUE; return TRUE;
} }
@ -274,6 +274,12 @@ VOID FASTCALL ObmReferenceObject(PVOID obj)
hdr->RefCount++; hdr->RefCount++;
} }
HANDLE FASTCALL ObmObjectToHandle(PVOID obj)
{
PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
return hdr->hSelf;
}
BOOL FASTCALL ObmDereferenceObject2(PVOID obj) BOOL FASTCALL ObmDereferenceObject2(PVOID obj)
{ {
@ -287,11 +293,12 @@ BOOL FASTCALL ObmDereferenceObject2(PVOID obj)
{ {
// DPRINT1("info: something destroyed bcaise of deref, in use=%i\n",usedHandles); // 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)); memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
ExFreePool(hdr); UserHeapFree(hdr);
//ExFreePool(hdr);
return TRUE; return TRUE;
} }
@ -307,15 +314,24 @@ BOOL FASTCALL ObmCreateHandleTable()
PVOID mem; PVOID mem;
//FIXME: dont alloc all at once! must be mapped into umode also... //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) if (!mem)
{ {
DPRINT1("Failed creating handle table\n"); DPRINT1("Failed creating handle table\n");
return FALSE; 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 //FIXME: make auto growable
UserInitHandleTable(&gHandleTable, mem, sizeof(USER_HANDLE_ENTRY) * 1024*2); UserInitHandleTable(gHandleTable, mem, sizeof(USER_HANDLE_ENTRY) * 1024*2);
return TRUE; return TRUE;
} }

View file

@ -353,7 +353,7 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
if (!(Flags & DCX_WINDOW)) if (!(Flags & DCX_WINDOW))
{ {
if (Window->Class->style & CS_PARENTDC) if (Window->Class->Style & CS_PARENTDC)
{ {
Flags |= DCX_PARENTCLIP; Flags |= DCX_PARENTCLIP;
} }
@ -676,7 +676,7 @@ DceFreeWindowDCE(PWINDOW_OBJECT Window)
{ {
if (pDCE == Window->Dce) /* owned or Class DCE*/ 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); pDCE = DceFreeDCE(pDCE, FALSE);
Window->Dce = NULL; Window->Dce = NULL;

View file

@ -33,10 +33,6 @@
#define NDEBUG #define NDEBUG
#include <debug.h> #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 */ /* dialog resources appear to pass this in 16 bits, handle them properly */
#define CW_USEDEFAULT16 (0x8000) #define CW_USEDEFAULT16 (0x8000)
@ -53,8 +49,6 @@ static WORD WndProcHandlesArraySize = 0;
NTSTATUS FASTCALL NTSTATUS FASTCALL
InitWindowImpl(VOID) InitWindowImpl(VOID)
{ {
WndProcHandlesArray = ExAllocatePoolWithTag(PagedPool,WPH_SIZE * sizeof(WndProcHandle), TAG_WINPROCLST);
WndProcHandlesArraySize = WPH_SIZE;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -67,9 +61,6 @@ InitWindowImpl(VOID)
NTSTATUS FASTCALL NTSTATUS FASTCALL
CleanupWindowImpl(VOID) CleanupWindowImpl(VOID)
{ {
ExFreePool(WndProcHandlesArray);
WndProcHandlesArray = 0;
WndProcHandlesArraySize = 0;
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -95,15 +86,26 @@ PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
/* temp hack */ /* temp hack */
PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd) PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
{ {
PW32THREADINFO ti;
PWINDOW_OBJECT Window; PWINDOW_OBJECT Window;
if (PsGetCurrentProcess() != PsInitialSystemProcess)
{
ti = GetW32ThreadInfo();
if (ti == NULL)
{
SetLastWin32Error(ERROR_ACCESS_DENIED);
return NULL;
}
}
if (!hWnd) if (!hWnd)
{ {
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return NULL; return NULL;
} }
Window = (PWINDOW_OBJECT)UserGetObject(&gHandleTable, hWnd, otWindow); Window = (PWINDOW_OBJECT)UserGetObject(gHandleTable, hWnd, otWindow);
if (!Window || 0 != (Window->Status & WINDOWSTATUS_DESTROYED)) if (!Window || 0 != (Window->Status & WINDOWSTATUS_DESTROYED))
{ {
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
@ -432,8 +434,16 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
IntDestroyScrollBars(Window); IntDestroyScrollBars(Window);
if (!Window->Class->System && Window->CallProc != NULL)
{
DestroyCallProc(Window->ti->Desktop,
Window->CallProc);
}
/* dereference the class */ /* dereference the class */
ClassDerefObject(Window->Class); IntDereferenceClass(Window->Class,
Window->ti->Desktop,
Window->ti->kpi);
Window->Class = NULL; Window->Class = NULL;
if(Window->WindowRegion) if(Window->WindowRegion)
@ -475,6 +485,57 @@ IntGetWindowBorderMeasures(PWINDOW_OBJECT Window, UINT *cx, UINT *cy)
} }
} }
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 BOOL FASTCALL
IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi) IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
{ {
@ -1333,7 +1394,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
BOOL bUnicodeWindow) BOOL bUnicodeWindow)
{ {
PWINSTATION_OBJECT WinSta; PWINSTATION_OBJECT WinSta;
PWNDCLASS_OBJECT Class = NULL; PWINDOWCLASS Class = NULL;
RTL_ATOM ClassAtom;
PWINDOW_OBJECT Window = NULL; PWINDOW_OBJECT Window = NULL;
PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow; PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
HWND ParentWindowHandle; HWND ParentWindowHandle;
@ -1342,6 +1404,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
HWND hWnd; HWND hWnd;
POINT Pos; POINT Pos;
SIZE Size; SIZE Size;
PW32THREADINFO ti = NULL;
#if 0 #if 0
POINT MaxSize, MaxPos, MinTrack, MaxTrack; POINT MaxSize, MaxPos, MinTrack, MaxTrack;
@ -1349,7 +1412,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
POINT MaxPos; POINT MaxPos;
#endif #endif
CREATESTRUCTW Cs; CREATESTRUCTW Cs;
CBT_CREATEWNDW CbtCreate; CBT_CREATEWNDW CbtCreate;
LRESULT Result; LRESULT Result;
@ -1399,13 +1461,27 @@ co_IntCreateWindowEx(DWORD dwExStyle,
/* FIXME: parent must belong to the current process */ /* 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. */ /* 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)) 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 else
{ {
@ -1416,14 +1492,14 @@ co_IntCreateWindowEx(DWORD dwExStyle,
RETURN((HWND)0); RETURN((HWND)0);
} }
ClassRefObject(Class); Class = IntReferenceClass(Class,
ti->Desktop);
/* Check the window station. */ if (Class == NULL)
if (PsGetWin32Thread()->Desktop == NULL)
{ {
DPRINT("Thread is not attached to a desktop! Cannot create window!\n"); DPRINT1("Failed to reference window class!\n");
RETURN( (HWND)0); RETURN(NULL);
} }
WinSta = PsGetWin32Thread()->Desktop->WindowStation; WinSta = PsGetWin32Thread()->Desktop->WindowStation;
//FIXME: Reference thread/desktop instead //FIXME: Reference thread/desktop instead
@ -1431,8 +1507,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
/* Create the window object. */ /* Create the window object. */
Window = (PWINDOW_OBJECT) Window = (PWINDOW_OBJECT)
ObmCreateObject(&gHandleTable, (PHANDLE)&hWnd, ObmCreateObject(gHandleTable, (PHANDLE)&hWnd,
otWindow, sizeof(WINDOW_OBJECT) + Class->cbWndExtra otWindow, sizeof(WINDOW_OBJECT) + Class->WndExtra
); );
DPRINT("Created object with handle %X\n", hWnd); DPRINT("Created object with handle %X\n", hWnd);
@ -1456,6 +1532,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
/* /*
* Fill out the structure describing it. * Fill out the structure describing it.
*/ */
Window->ti = ti;
Window->Class = Class; Window->Class = Class;
Window->SystemMenu = (HMENU)0; Window->SystemMenu = (HMENU)0;
Window->ContextHelpId = 0; Window->ContextHelpId = 0;
@ -1474,7 +1551,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
{ {
IntSetMenu(Window, hMenu, &MenuChanged); IntSetMenu(Window, hMenu, &MenuChanged);
} }
Window->MessageQueue = PsGetWin32Thread()->MessageQueue; Window->MessageQueue = PsGetWin32Thread()->MessageQueue;
IntReferenceMessageQueue(Window->MessageQueue); IntReferenceMessageQueue(Window->MessageQueue);
Window->Parent = ParentWindow; Window->Parent = ParentWindow;
@ -1491,27 +1568,38 @@ co_IntCreateWindowEx(DWORD dwExStyle,
} }
Window->UserData = 0; Window->UserData = 0;
if ((((DWORD)Class->lpfnWndProcA & 0xFFFF0000) != 0xFFFF0000) Window->IsSystem = Class->System;
&& (((DWORD)Class->lpfnWndProcW & 0xFFFF0000) != 0xFFFF0000)) if (Class->System)
{ {
Window->Unicode = bUnicodeWindow; Window->Unicode = bUnicodeWindow;
if (bUnicodeWindow)
{
Window->WndProc = Class->WndProc;
Window->WndProcExtra = Class->WndProcExtra;
}
else
{
Window->WndProc = Class->WndProcExtra;
Window->WndProcExtra = Class->WndProc;
}
} }
else else
{ {
Window->Unicode = Class->Unicode; Window->Unicode = Class->Unicode;
Window->WndProc = Class->WndProc;
Window->CallProc = NULL;
} }
Window->WndProcA = Class->lpfnWndProcA;
Window->WndProcW = Class->lpfnWndProcW;
Window->OwnerThread = PsGetCurrentThread(); Window->OwnerThread = PsGetCurrentThread();
Window->FirstChild = NULL; Window->FirstChild = NULL;
Window->LastChild = NULL; Window->LastChild = NULL;
Window->PrevSibling = NULL; Window->PrevSibling = NULL;
Window->NextSibling = NULL; Window->NextSibling = NULL;
Window->ExtraDataSize = Class->cbWndExtra; Window->ExtraDataSize = Class->WndExtra;
/* extra window data */ /* extra window data */
if (Class->cbWndExtra) if (Class->WndExtra)
Window->ExtraData = (PCHAR)(Window + 1); Window->ExtraData = (PCHAR)(Window + 1);
InitializeListHead(&Window->PropListHead); InitializeListHead(&Window->PropListHead);
@ -1536,7 +1624,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
RtlInitUnicodeString(&Window->WindowName, NULL); RtlInitUnicodeString(&Window->WindowName, NULL);
} }
/* /*
* This has been tested for WS_CHILD | WS_VISIBLE. It has not been * This has been tested for WS_CHILD | WS_VISIBLE. It has not been
* tested for WS_POPUP * tested for WS_POPUP
@ -1931,7 +2018,15 @@ co_IntCreateWindowEx(DWORD dwExStyle,
CLEANUP: CLEANUP:
if (Window) UserDerefObjectCo(Window); if (Window) UserDerefObjectCo(Window);
if (ParentWindow) UserDerefObjectCo(ParentWindow); 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; END_CLEANUP;
} }
@ -1967,7 +2062,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
SetLastNtError(Status); SetLastNtError(Status);
RETURN( NULL); RETURN( NULL);
} }
if (! IS_ATOM(ClassName.Buffer)) if (ClassName.Length != 0)
{ {
Status = IntSafeCopyUnicodeStringTerminateNULL(&ClassName, UnsafeClassName); Status = IntSafeCopyUnicodeStringTerminateNULL(&ClassName, UnsafeClassName);
if (! NT_SUCCESS(Status)) if (! NT_SUCCESS(Status))
@ -1976,6 +2071,11 @@ NtUserCreateWindowEx(DWORD dwExStyle,
RETURN( NULL); RETURN( NULL);
} }
} }
else if (! IS_INTRESOURCE(ClassName.Buffer))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return NULL;
}
/* safely copy the window name */ /* safely copy the window name */
if (NULL != UnsafeWindowName) if (NULL != UnsafeWindowName)
@ -3254,10 +3354,8 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
break; break;
case GWL_WNDPROC: case GWL_WNDPROC:
if (Ansi) Result = (LONG)IntGetWindowProc(Window,
Result = (LONG) Window->WndProcA; Ansi);
else
Result = (LONG) Window->WndProcW;
break; break;
case GWL_HINSTANCE: case GWL_HINSTANCE:
@ -3390,22 +3488,28 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
break; break;
case GWL_WNDPROC: case GWL_WNDPROC:
{
/* FIXME: should check if window belongs to current process */ /* FIXME: should check if window belongs to current process */
if (Ansi) if (Window->IsSystem)
{ {
OldValue = (LONG) Window->WndProcA; /* the user changes the window procedure, the window is no longer
Window->WndProcA = (WNDPROC) NewValue; directly derived from the system class, because it no longer
Window->WndProcW = (WNDPROC) IntAddWndProcHandle((WNDPROC)NewValue,FALSE); uses independent window procedures for ansi and unicode */
Window->Unicode = FALSE; 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->CallProc->WndProc = (WNDPROC)NewValue;
Window->WndProcW = (WNDPROC) NewValue; Window->CallProc->Unicode = !Ansi;
Window->WndProcA = (WNDPROC) IntAddWndProcHandle((WNDPROC)NewValue,TRUE);
Window->Unicode = TRUE;
} }
Window->Unicode = !Ansi;
break; break;
}
case GWL_HINSTANCE: case GWL_HINSTANCE:
OldValue = (LONG) Window->Instance; OldValue = (LONG) Window->Instance;
@ -4404,99 +4508,6 @@ CLEANUP:
END_CLEANUP; 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) #define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
BOOL BOOL

View file

@ -1,3 +1,5 @@
#ifndef __W32K_H
#define __W32K_H
/* /*
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Graphics Subsystem * PROJECT: ReactOS Graphics Subsystem
@ -68,3 +70,77 @@ typedef DRIVEROBJ *PDRIVEROBJ;
#define M_PI_2 1.57079632679489661923 #define M_PI_2 1.57079632679489661923
#endif #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 */

View file

@ -64,14 +64,15 @@
<file>err.c</file> <file>err.c</file>
<file>math.c</file> <file>math.c</file>
<file>copy.c</file> <file>copy.c</file>
<file>usrheap.c</file>
</compilationunit> </compilationunit>
<directory name="i386"> <directory name="i386">
<file>cos_asm.s</file> <file>cos_asm.s</file>
<file>sin_asm.s</file> <file>sin_asm.s</file>
<file>atan2_asm.s</file> <file>atan2_asm.s</file>
<file>floor_asm.s</file> <file>floor_asm.s</file>
<file>ceil_asm.s</file> <file>ceil_asm.s</file>
</directory> </directory>
</directory> </directory>
<directory name="ntddraw"> <directory name="ntddraw">
<compilationunit name="ntddraw.c"> <compilationunit name="ntddraw.c">

View file

@ -356,7 +356,7 @@ NtUserGetAsyncKeyState 1
NtUserGetCapture 0 NtUserGetCapture 0
NtUserGetCaretBlinkTime 0 NtUserGetCaretBlinkTime 0
NtUserGetCaretPos 1 NtUserGetCaretPos 1
NtUserGetClassInfo 5 NtUserGetClassInfo 4
NtUserGetClassLong 3 NtUserGetClassLong 3
NtUserGetClassName 3 NtUserGetClassName 3
NtUserGetClientOrigin 2 NtUserGetClientOrigin 2
@ -457,7 +457,7 @@ NtUserQueryWindow 2
NtUserReleaseDC 2 NtUserReleaseDC 2
NtUserRealChildWindowFromPoint 3 NtUserRealChildWindowFromPoint 3
NtUserRedrawWindow 4 NtUserRedrawWindow 4
NtUserRegisterClassExWOW 8 NtUserRegisterClassEx 6
NtUserRegisterHotKey 4 NtUserRegisterHotKey 4
NtUserRegisterTasklist 1 NtUserRegisterTasklist 1
NtUserRegisterWindowMessage 1 NtUserRegisterWindowMessage 1
@ -536,7 +536,7 @@ NtUserUnhookWindowsHookEx 1
NtUserUnhookWinEvent 1 NtUserUnhookWinEvent 1
NtUserUnloadKeyboardLayout 1 NtUserUnloadKeyboardLayout 1
NtUserUnlockWindowStation 1 NtUserUnlockWindowStation 1
NtUserUnregisterClass 3 NtUserUnregisterClass 2
NtUserUnregisterHotKey 2 NtUserUnregisterHotKey 2
NtUserUpdateInputContext 3 NtUserUpdateInputContext 3
NtUserUpdateInstance 3 NtUserUpdateInstance 3