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);
}
NtUserRegisterClassExWOW(
NtUserRegisterClassEx(
&wc,
&ClassName,
&ClassName,
&MenuName,
Descr->procA,
REGISTERCLASS_SYSTEM,
0,
0);
NULL);
}
/***********************************************************************

View file

@ -113,3 +113,34 @@ UpdatePerUserSystemParameters(
{
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>
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 @@ GetClassInfoExA(
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 @@ GetClassInfoExW(
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 @@ GetClassInfoA(
return FALSE;
}
w.cbSize = sizeof(w);
retval = GetClassInfoExA(hInstance,lpClassName,&w);
if (retval)
{
@ -197,8 +141,12 @@ GetClassInfoW(
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 @@ GetClassNameA(
LPSTR lpClassName,
int nMaxCount)
{
int result;
LPWSTR ClassNameW;
NTSTATUS Status;
ANSI_STRING ClassName;
if(!lpClassName)
return 0;
ClassName.MaximumLength = nMaxCount;
ClassName.Buffer = lpClassName;
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;
return NtUserGetClassName(hWnd,
(PUNICODE_STRING)&ClassName,
TRUE);
}
@ -307,7 +244,14 @@ GetClassNameW(
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 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
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 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
}
if HIWORD(lpwcx->lpszMenuName)
if (lpwcx->lpszMenuName != NULL)
{
hMenu = 0;
RtlCreateUnicodeStringFromAsciiz(&MenuName, WndClass.lpszMenuName);
}
else
{
MenuName.Length =
MenuName.MaximumLength = 0;
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
if (HIWORD(lpwcx->lpszMenuName))
{
RtlCreateUnicodeStringFromAsciiz(&MenuName, WndClass.lpszMenuName);
}
else
{
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
}
hMenu = LoadMenuA(WndClass.hInstance, lpwcx->lpszMenuName);
}
@ -627,20 +572,18 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
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 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
{
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 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
}
if HIWORD(lpwcx->lpszMenuName)
if (lpwcx->lpszMenuName != NULL)
{
hMenu = 0;
RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
}
else
{
MenuName.Length =
MenuName.MaximumLength = 0;
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
if (HIWORD(lpwcx->lpszMenuName))
{
RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
}
else
{
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
}
hMenu = LoadMenuW(WndClass.hInstance, lpwcx->lpszMenuName);
}
@ -712,20 +655,18 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
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 @@ RegisterClassW(CONST WNDCLASSW *lpWndClass)
*/
DWORD
STDCALL
SetClassLongA (
HWND hWnd,
int nIndex,
LONG dwNewLong)
SetClassLongA (HWND hWnd,
int nIndex,
LONG dwNewLong)
{
UNICODE_STRING str2buf;
PUNICODE_STRING str;
PUNICODE_STRING str2 = &str2buf;
PSTR lpStr = (PSTR)dwNewLong;
UNICODE_STRING Value = {0};
BOOL Allocated = FALSE;
DWORD Ret;
if ( nIndex != GCL_MENUNAME )
{
return NtUserSetClassLong ( hWnd, nIndex, dwNewLong, TRUE );
}
if ( IS_INTRESOURCE(dwNewLong) )
{
str2 = (PUNICODE_STRING)dwNewLong;
}
else
{
RtlCreateUnicodeStringFromAsciiz ( &str2buf,(LPSTR)dwNewLong );
}
/* FIXME - portability!!!! */
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) )
{
RtlFreeUnicodeString ( str2 );
}
if ( IS_INTRESOURCE(str) )
{
return (DWORD)str;
}
else
{
return (DWORD)heap_string_poolA ( str->Buffer, str->Length );
}
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 @@ SetClassLongA (
*/
DWORD
STDCALL
SetClassLongW(
HWND hWnd,
int nIndex,
LONG dwNewLong)
SetClassLongW(HWND hWnd,
int nIndex,
LONG dwNewLong)
{
UNICODE_STRING str2buf;
PUNICODE_STRING str;
PUNICODE_STRING str2 = &str2buf;
PWSTR lpStr = (PWSTR)dwNewLong;
UNICODE_STRING Value = {0};
if (nIndex != GCL_MENUNAME )
{
return NtUserSetClassLong ( hWnd, nIndex, dwNewLong, FALSE );
}
if ( IS_INTRESOURCE(dwNewLong) )
{
str2 = (PUNICODE_STRING)dwNewLong;
}
else
{
RtlCreateUnicodeString ( &str2buf, (LPWSTR)dwNewLong );
}
/* FIXME - portability!!!! */
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) )
{
RtlFreeUnicodeString(str2);
}
if ( IS_INTRESOURCE(str) )
{
return (DWORD)str;
}
else
{
return (DWORD)heap_string_poolW ( str->Buffer, str->Length );
}
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 @@ SetClassWord(
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 @@ UnregisterClassA(
LPCSTR lpClassName,
HINSTANCE hInstance)
{
LPWSTR ClassName;
NTSTATUS Status;
BOOL Result;
UNICODE_STRING ClassName = {0};
NTSTATUS Status;
BOOL Ret;
if(!IS_ATOM(lpClassName))
{
Status = HEAP_strdupAtoW(&ClassName, lpClassName, NULL);
if(!NT_SUCCESS(Status))
if (!IS_ATOM(lpClassName))
{
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
Status = HEAP_strdupAtoW(&ClassName.Buffer, lpClassName, NULL);
if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
RtlInitUnicodeString(&ClassName,
ClassName.Buffer);
}
}
else
ClassName = (LPWSTR)lpClassName;
else
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpClassName);
Result = (BOOL)NtUserUnregisterClass((LPCWSTR)ClassName, hInstance, 0);
Ret = NtUserUnregisterClass(&ClassName,
hInstance);
if(ClassName && !IS_ATOM(lpClassName))
HEAP_free(ClassName);
if(!IS_ATOM(lpClassName) && ClassName.Buffer != NULL)
HEAP_free(ClassName.Buffer);
return Result;
return Ret;
}
@ -943,7 +913,18 @@ UnregisterClassW(
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 */

View file

@ -951,6 +951,7 @@ IntCallWindowProcW(BOOL IsAnsiProc,
return FALSE;
}
Result = WndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam);
if (! MsgiUnicodeToAnsiReply(&AnsiMsg, &UnicodeMsg, &Result))
{
return FALSE;
@ -991,6 +992,7 @@ IntCallWindowProcA(BOOL IsAnsiProc,
}
Result = WndProc(UnicodeMsg.hwnd, UnicodeMsg.message,
UnicodeMsg.wParam, UnicodeMsg.lParam);
if (! MsgiAnsiToUnicodeReply(&UnicodeMsg, &AnsiMsg, &Result))
{
return FALSE;
@ -1010,20 +1012,19 @@ CallWindowProcA(WNDPROC lpPrevWndFunc,
WPARAM wParam,
LPARAM lParam)
{
BOOL IsHandle;
WndProcHandle wphData;
WNDPROC_INFO wpInfo;
if (lpPrevWndFunc == NULL)
lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWL_WNDPROC, FALSE);
lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWLP_WNDPROC, FALSE);
IsHandle = NtUserDereferenceWndProcHandle(lpPrevWndFunc,&wphData);
if (! IsHandle)
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 @@ CallWindowProcW(WNDPROC lpPrevWndFunc,
WPARAM wParam,
LPARAM lParam)
{
BOOL IsHandle;
WndProcHandle wphData;
WNDPROC_INFO wpInfo;
IsHandle = NtUserDereferenceWndProcHandle(lpPrevWndFunc,&wphData);
if (! IsHandle)
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);
}
}

View file

@ -289,8 +289,8 @@ CreateWindowExW(DWORD dwExStyle,
{
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 @@ HWND
STDCALL
GetFocus(VOID)
{
return (HWND)NtUserGetThreadState(0);
return (HWND)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW);
}
/*

View file

@ -424,7 +424,7 @@ typedef struct _TEB
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 */

View file

@ -9,6 +9,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!
*/

View file

@ -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 @@ NtUserTrackPopupMenuEx(
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 @@ NTAPI
NtUserGetCaretPos(
LPPOINT lpPoint);
DWORD NTAPI
NtUserGetClassInfo(HINSTANCE hInst,
LPCWSTR str,
BOOL NTAPI
NtUserGetClassInfo(HINSTANCE hInstance,
PUNICODE_STRING ClassName,
LPWNDCLASSEXW wcex,
BOOL Ansi,
DWORD unknown3);
BOOL Ansi);
DWORD
INT
NTAPI
NtUserGetClassName(HWND hWnd,
LPWSTR lpClassName,
ULONG nMaxCount);
PUNICODE_STRING ClassName,
BOOL Ansi);
HANDLE
NTAPI
@ -1041,6 +1109,7 @@ NtUserGetThreadDesktop(
DWORD dwThreadId,
DWORD Unknown1);
#define THREADSTATE_GETTHREADINFO (0)
#define THREADSTATE_FOCUSWINDOW (1)
#define THREADSTATE_INSENDMESSAGE (2)
DWORD
@ -1355,14 +1424,12 @@ NtUserRedrawWindow
#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 @@ NtUserSetCapture(HWND Wnd);
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 @@ NtUserUnlockWindowStation(
BOOL
NTAPI
NtUserUnregisterClass(
LPCWSTR ClassNameOrAtom,
HINSTANCE hInstance,
DWORD Unknown);
PUNICODE_STRING ClassNameOrAtom,
HINSTANCE hInstance);
BOOL
NTAPI
@ -1951,15 +2017,15 @@ NtUserGetWindow(HWND hWnd, UINT Relationship);
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);

View file

@ -311,7 +311,7 @@ HEAP_Commit(SUBHEAP *subheap,
}
else
{
Status = NtAllocateVirtualMemory(NtCurrentProcess(),
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
&address,
0,
&commitsize,
@ -570,13 +570,24 @@ static BOOLEAN HEAP_InitSubHeap( HEAP *heap, PVOID address, ULONG flags,
/* 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
{

View file

@ -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 @@ InitClassImpl(VOID);
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 */

View file

@ -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 @@ typedef struct _DESKTOP_OBJECT
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 @@ IntHideDesktop(PDESKTOP_OBJECT Desktop);
HDESK FASTCALL
IntGetDesktopObjectHandle(PDESKTOP_OBJECT DesktopObject);
BOOL IntSetThreadDesktop(IN PDESKTOP_OBJECT DesktopObject);
NTSTATUS FASTCALL
IntValidateDesktopHandle(
HDESK Desktop,
@ -115,6 +119,113 @@ VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam);
#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 */

View file

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

View file

@ -75,7 +75,7 @@ BOOL FASTCALL ObmCreateHandleTable();
/******************** 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);

View file

@ -15,10 +15,18 @@ typedef struct _W32THREAD
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 @@ typedef struct _W32PROCESS
ULONG Flags;
LONG GDIObjects;
LONG UserObjects;
W32HEAP_USER_MAPPING HeapMappings;
PW32PROCESSINFO ProcessInfo;
} W32PROCESS, *PW32PROCESS;

View file

@ -26,8 +26,21 @@ typedef struct _INTERNALPOS
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 @@ typedef struct _WINDOW_OBJECT
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 @@ IntAnyPopup(VOID);
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 );

View file

@ -33,6 +33,9 @@ BOOL INTERNAL_CALL GDI_CleanupForProcess (PGDI_HANDLE_TABLE HandleTable, struct
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,8 +72,35 @@ Win32kProcessCallback(struct _EPROCESS *Process,
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);
InitializeListHead(&Win32Process->MenuListHead);
@ -95,7 +125,6 @@ Win32kProcessCallback(struct _EPROCESS *Process,
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);
@ -115,6 +144,12 @@ Win32kProcessCallback(struct _EPROCESS *Process,
{
LogonProcess = NULL;
}
if (Win32Process->ProcessInfo != NULL)
{
UserHeapFree(Win32Process->ProcessInfo);
Win32Process->ProcessInfo = NULL;
}
}
RETURN( STATUS_SUCCESS);
@ -198,17 +233,25 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
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 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
IntBlockInput(Win32Thread, FALSE);
MsqDestroyMessageQueue(Win32Thread->MessageQueue);
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 */
e = PopEntryList(&Win32Thread->ReferencesList);
while (e)
@ -309,6 +356,7 @@ DriverEntry (
NTSTATUS Status;
BOOLEAN Result;
W32_CALLOUT_DATA CalloutData;
PVOID GlobalUserHeapBase = NULL;
/*
* Register user mode call interface
@ -342,6 +390,16 @@ DriverEntry (
*/
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))
{

View file

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

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;
}
Accel= UserGetObject(&gHandleTable, hAccel, otAccel);
Accel= UserGetObject(gHandleTable, hAccel, otAccel);
if (!Accel)
{
SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE);
@ -344,7 +344,7 @@ NtUserCreateAcceleratorTable(
Entries, EntriesCount);
UserEnterExclusive();
Accel = ObmCreateObject(&gHandleTable, (PHANDLE)&hAccel, otAccel, sizeof(ACCELERATOR_TABLE));
Accel = ObmCreateObject(gHandleTable, (PHANDLE)&hAccel, otAccel, sizeof(ACCELERATOR_TABLE));
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;
}
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 @@ IntCreateCurIconHandle(PWINSTATION_OBJECT WinSta)
PCURICON_OBJECT CurIcon;
HANDLE hCurIcon;
CurIcon = ObmCreateObject(&gHandleTable, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
CurIcon = ObmCreateObject(gHandleTable, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
if(!CurIcon)
{

View file

@ -43,6 +43,8 @@ HDC ScreenDeviceContext = NULL;
BOOL g_PaintDesktopVersion = FALSE;
static VOID IntFreeDesktopHeap(IN OUT PDESKTOP_OBJECT Desktop);
/* INITALIZATION FUNCTIONS ****************************************************/
static GENERIC_MAPPING IntDesktopMapping =
@ -121,6 +123,8 @@ IntDesktopObjectDelete(PVOID DeletedObject)
RemoveEntryList(&Desktop->ListEntry);
RtlFreeUnicodeString(&Desktop->Name);
IntFreeDesktopHeap(Desktop);
}
/* PRIVATE FUNCTIONS **********************************************************/
@ -723,7 +727,15 @@ BOOL IntDeRegisterShellHookWindow(HWND hWnd)
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 @@ NtUserCreateDesktop(
NTSTATUS Status;
HDESK Desktop;
CSR_API_MESSAGE Request;
PVOID DesktopHeapSystemBase = NULL;
SIZE_T DesktopInfoSize;
DECLARE_RETURN(HDESK);
DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
@ -858,6 +872,39 @@ NtUserCreateDesktop(
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;
DesktopObject->WorkArea.top = 0;
@ -1216,7 +1263,7 @@ NtUserPaintDesktop(HDC hDC)
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;
}
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 @@ CLEANUP:
BOOL STDCALL
NtUserSetThreadDesktop(HDESK hDesktop)
{
PW32THREAD W32Thread;
PDESKTOP_OBJECT DesktopObject;
NTSTATUS Status;
DECLARE_RETURN(BOOL);
@ -1591,18 +1814,13 @@ NtUserSetThreadDesktop(HDESK hDesktop)
RETURN(FALSE);
}
W32Thread = PsGetWin32Thread();
/* 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);
CLEANUP:

View file

@ -69,7 +69,7 @@ PHOOK FASTCALL IntGetHookObject(HHOOK hHook)
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 @@ 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)
{
return NULL;

View file

@ -127,7 +127,7 @@ PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu)
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 @@ IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar)
PMENU_OBJECT Menu;
Menu = (PMENU_OBJECT)ObmCreateObject(
&gHandleTable, Handle,
gHandleTable, Handle,
otMenu, sizeof(MENU_OBJECT));
if(!Menu)
@ -419,7 +419,7 @@ IntCloneMenu(PMENU_OBJECT Source)
return NULL;
Menu = (PMENU_OBJECT)ObmCreateObject(
&gHandleTable, &hMenu,
gHandleTable, &hMenu,
otMenu, sizeof(MENU_OBJECT));
if(!Menu)

View file

@ -378,28 +378,9 @@ NtUserDispatchMessage(PNTUSERDISPATCHMESSAGEINFO UnsafeMsgInfo)
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 @@ co_IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *
{
/* 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 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
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 @@ co_IntDoSendMessage(HWND hWnd,
{
/* Gather the information usermode needs to call the window proc directly */
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))
{
/* 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.Ansi = !Window->Unicode;
Info.Proc = Window->WndProc;
}
else
{

View file

@ -886,11 +886,22 @@ NtUserGetThreadState(
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 @@ 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 */

View file

@ -89,7 +89,7 @@ IntCreateMonitorObject()
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 @@ UserGetMonitorObject(IN HMONITOR hMonitor)
}
Monitor = (PMONITOR_OBJECT)UserGetObject(&gHandleTable, hMonitor, otMonitor);
Monitor = (PMONITOR_OBJECT)UserGetObject(gHandleTable, hMonitor, otMonitor);
if (!Monitor)
{
SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE);

View file

@ -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 @@ __inline static PUSER_HANDLE_ENTRY alloc_user_entry(PUSER_HANDLE_TABLE ht)
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 @@ ObmCreateObject(PUSER_HANDLE_TABLE ht, HANDLE* h,USER_OBJECT_TYPE type , ULONG s
{
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 @@ ObmCreateObject(PUSER_HANDLE_TABLE ht, HANDLE* h,USER_OBJECT_TYPE type , ULONG s
hi = UserAllocHandle(ht, USER_HEADER_TO_BODY(hdr), type );
if (!hi)
{
ExFreePool(hdr);
//ExFreePool(hdr);
UserHeapFree(hdr);
return NULL;
}
@ -242,7 +241,7 @@ BOOL FASTCALL
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 @@ ObmDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
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 @@ VOID FASTCALL ObmReferenceObject(PVOID obj)
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 @@ BOOL FASTCALL ObmDereferenceObject2(PVOID obj)
{
// 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 @@ BOOL FASTCALL ObmCreateHandleTable()
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;
}

View file

@ -353,7 +353,7 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
if (!(Flags & DCX_WINDOW))
{
if (Window->Class->style & CS_PARENTDC)
if (Window->Class->Style & CS_PARENTDC)
{
Flags |= DCX_PARENTCLIP;
}
@ -676,7 +676,7 @@ DceFreeWindowDCE(PWINDOW_OBJECT Window)
{
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;

View file

@ -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 @@ static WORD WndProcHandlesArraySize = 0;
NTSTATUS FASTCALL
InitWindowImpl(VOID)
{
WndProcHandlesArray = ExAllocatePoolWithTag(PagedPool,WPH_SIZE * sizeof(WndProcHandle), TAG_WINPROCLST);
WndProcHandlesArraySize = WPH_SIZE;
return STATUS_SUCCESS;
}
@ -67,9 +61,6 @@ InitWindowImpl(VOID)
NTSTATUS FASTCALL
CleanupWindowImpl(VOID)
{
ExFreePool(WndProcHandlesArray);
WndProcHandlesArray = 0;
WndProcHandlesArraySize = 0;
return STATUS_SUCCESS;
}
@ -95,15 +86,26 @@ PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
/* 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 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
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)
@ -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
IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
{
@ -1333,7 +1394,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
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 @@ co_IntCreateWindowEx(DWORD dwExStyle,
HWND hWnd;
POINT Pos;
SIZE Size;
PW32THREADINFO ti = NULL;
#if 0
POINT MaxSize, MaxPos, MinTrack, MaxTrack;
@ -1349,7 +1412,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
POINT MaxPos;
#endif
CREATESTRUCTW Cs;
CBT_CREATEWNDW CbtCreate;
LRESULT Result;
@ -1399,13 +1461,27 @@ co_IntCreateWindowEx(DWORD dwExStyle,
/* 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 @@ co_IntCreateWindowEx(DWORD dwExStyle,
RETURN((HWND)0);
}
ClassRefObject(Class);
/* Check the window station. */
if (PsGetWin32Thread()->Desktop == NULL)
Class = IntReferenceClass(Class,
ti->Desktop);
if (Class == NULL)
{
DPRINT("Thread is not attached to a desktop! Cannot create window!\n");
RETURN( (HWND)0);
DPRINT1("Failed to reference window class!\n");
RETURN(NULL);
}
WinSta = PsGetWin32Thread()->Desktop->WindowStation;
//FIXME: Reference thread/desktop instead
@ -1431,8 +1507,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
/* 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 @@ co_IntCreateWindowEx(DWORD dwExStyle,
/*
* Fill out the structure describing it.
*/
Window->ti = ti;
Window->Class = Class;
Window->SystemMenu = (HMENU)0;
Window->ContextHelpId = 0;
@ -1474,7 +1551,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
{
IntSetMenu(Window, hMenu, &MenuChanged);
}
Window->MessageQueue = PsGetWin32Thread()->MessageQueue;
IntReferenceMessageQueue(Window->MessageQueue);
Window->Parent = ParentWindow;
@ -1491,27 +1568,38 @@ co_IntCreateWindowEx(DWORD dwExStyle,
}
Window->UserData = 0;
if ((((DWORD)Class->lpfnWndProcA & 0xFFFF0000) != 0xFFFF0000)
&& (((DWORD)Class->lpfnWndProcW & 0xFFFF0000) != 0xFFFF0000))
Window->IsSystem = Class->System;
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
{
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->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);
@ -1536,7 +1624,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
RtlInitUnicodeString(&Window->WindowName, NULL);
}
/*
* This has been tested for WS_CHILD | WS_VISIBLE. It has not been
* tested for WS_POPUP
@ -1931,7 +2018,15 @@ co_IntCreateWindowEx(DWORD dwExStyle,
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 @@ NtUserCreateWindowEx(DWORD dwExStyle,
SetLastNtError(Status);
RETURN( NULL);
}
if (! IS_ATOM(ClassName.Buffer))
if (ClassName.Length != 0)
{
Status = IntSafeCopyUnicodeStringTerminateNULL(&ClassName, UnsafeClassName);
if (! NT_SUCCESS(Status))
@ -1976,6 +2071,11 @@ NtUserCreateWindowEx(DWORD dwExStyle,
RETURN( NULL);
}
}
else if (! IS_INTRESOURCE(ClassName.Buffer))
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return NULL;
}
/* safely copy the window name */
if (NULL != UnsafeWindowName)
@ -3254,10 +3354,8 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
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 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
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 @@ 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)
BOOL

View file

@ -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 @@ typedef DRIVEROBJ *PDRIVEROBJ;
#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 */

View file

@ -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">

View file

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