mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 21:44:31 +00:00
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:
parent
9607791183
commit
ea5261fe10
|
@ -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);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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!
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
216
reactos/subsystems/win32/win32k/misc/usrheap.c
Normal file
216
reactos/subsystems/win32/win32k/misc/usrheap.c
Normal 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;
|
||||
}
|
|
@ -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
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue