mirror of
https://github.com/reactos/reactos.git
synced 2025-06-01 07:28:19 +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
33 changed files with 3599 additions and 1193 deletions
|
@ -44,15 +44,13 @@ static void RegisterBuiltinClass(const struct builtin_class_descr *Descr)
|
||||||
RtlInitUnicodeString(&ClassName, Descr->name);
|
RtlInitUnicodeString(&ClassName, Descr->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
NtUserRegisterClassExWOW(
|
NtUserRegisterClassEx(
|
||||||
&wc,
|
&wc,
|
||||||
&ClassName,
|
&ClassName,
|
||||||
&ClassName,
|
|
||||||
&MenuName,
|
&MenuName,
|
||||||
Descr->procA,
|
Descr->procA,
|
||||||
REGISTERCLASS_SYSTEM,
|
REGISTERCLASS_SYSTEM,
|
||||||
0,
|
NULL);
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -113,3 +113,34 @@ UpdatePerUserSystemParameters(
|
||||||
{
|
{
|
||||||
return NtUserUpdatePerUserSystemParameters(dwReserved, bEnable);
|
return NtUserUpdatePerUserSystemParameters(dwReserved, bEnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PW32THREADINFO
|
||||||
|
GetW32ThreadInfo(VOID)
|
||||||
|
{
|
||||||
|
PW32THREADINFO ti;
|
||||||
|
|
||||||
|
ti = (PW32THREADINFO)NtCurrentTeb()->Win32ThreadInfo;
|
||||||
|
if (ti == NULL)
|
||||||
|
{
|
||||||
|
/* create the W32THREADINFO structure */
|
||||||
|
NtUserGetThreadState(THREADSTATE_GETTHREADINFO);
|
||||||
|
ti = (PW32THREADINFO)NtCurrentTeb()->Win32ThreadInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ti;
|
||||||
|
}
|
||||||
|
|
||||||
|
PW32PROCESSINFO
|
||||||
|
GetW32ProcessInfo(VOID)
|
||||||
|
{
|
||||||
|
PW32THREADINFO ti;
|
||||||
|
PW32PROCESSINFO pi = NULL;
|
||||||
|
|
||||||
|
ti = GetW32ThreadInfo();
|
||||||
|
if (ti != NULL)
|
||||||
|
{
|
||||||
|
pi = ti->pi;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pi;
|
||||||
|
}
|
||||||
|
|
|
@ -11,117 +11,6 @@
|
||||||
|
|
||||||
#include <user32.h>
|
#include <user32.h>
|
||||||
|
|
||||||
static BOOL GetClassInfoExCommon(
|
|
||||||
HINSTANCE hInst,
|
|
||||||
LPCWSTR lpszClass,
|
|
||||||
LPWNDCLASSEXW lpwcx,
|
|
||||||
BOOL unicode)
|
|
||||||
{
|
|
||||||
LPWSTR str;
|
|
||||||
UNICODE_STRING str2, str3;
|
|
||||||
WNDCLASSEXW w;
|
|
||||||
BOOL retval;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
if ( !lpszClass || !lpwcx )
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(IS_ATOM(lpszClass))
|
|
||||||
str = (LPWSTR)lpszClass;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
extern BOOL ControlsInitialized;
|
|
||||||
|
|
||||||
if (unicode)
|
|
||||||
{
|
|
||||||
str = HEAP_strdupW ( lpszClass, wcslen(lpszClass) );
|
|
||||||
|
|
||||||
if ( !str )
|
|
||||||
{
|
|
||||||
SetLastError (ERROR_OUTOFMEMORY);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Status = HEAP_strdupAtoW(&str, (LPCSTR)lpszClass, NULL);
|
|
||||||
|
|
||||||
if (! NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
SetLastError(RtlNtStatusToDosError(Status));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Register built-in controls if not already done */
|
|
||||||
if ( !ControlsInitialized )
|
|
||||||
{
|
|
||||||
ControlsInitialized = ControlsInit(str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
str2.Length = str3.Length = 0;
|
|
||||||
str2.MaximumLength = str3.MaximumLength = 255;
|
|
||||||
str2.Buffer = (PWSTR)HEAP_alloc ( str2.MaximumLength * sizeof(WCHAR) );
|
|
||||||
if ( !str2.Buffer )
|
|
||||||
{
|
|
||||||
SetLastError (ERROR_OUTOFMEMORY);
|
|
||||||
if ( !IS_ATOM(str) )
|
|
||||||
HEAP_free ( str );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
str3.Buffer = (PWSTR)HEAP_alloc ( str3.MaximumLength * sizeof(WCHAR) );
|
|
||||||
if ( !str3.Buffer )
|
|
||||||
{
|
|
||||||
SetLastError (ERROR_OUTOFMEMORY);
|
|
||||||
HEAP_free ( str2.Buffer );
|
|
||||||
if ( !IS_ATOM(str) )
|
|
||||||
HEAP_free ( str );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
w.lpszMenuName = (LPCWSTR)&str2;
|
|
||||||
w.lpszClassName = (LPCWSTR)&str3;
|
|
||||||
|
|
||||||
/* get info about system classes? */
|
|
||||||
if (!hInst) hInst = User32Instance;
|
|
||||||
|
|
||||||
retval = (BOOL)NtUserGetClassInfo(hInst, str, &w, TRUE, 0);
|
|
||||||
|
|
||||||
w.hInstance = (hInst == User32Instance) ? 0 : hInst;
|
|
||||||
|
|
||||||
if ( !IS_ATOM(str) )
|
|
||||||
HEAP_free(str);
|
|
||||||
|
|
||||||
RtlCopyMemory ( lpwcx, &w, sizeof(WNDCLASSEXW) );
|
|
||||||
|
|
||||||
if ( !IS_INTRESOURCE(w.lpszMenuName) && w.lpszMenuName )
|
|
||||||
{
|
|
||||||
if (unicode)
|
|
||||||
lpwcx->lpszMenuName = heap_string_poolW ( str2.Buffer, str2.Length );
|
|
||||||
else
|
|
||||||
((LPWNDCLASSEXA) lpwcx)->lpszMenuName = heap_string_poolA ( str2.Buffer, str2.Length );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !IS_ATOM(w.lpszClassName) && w.lpszClassName )
|
|
||||||
{
|
|
||||||
if (unicode)
|
|
||||||
lpwcx->lpszClassName = heap_string_poolW ( str3.Buffer, str3.Length );
|
|
||||||
else
|
|
||||||
((LPWNDCLASSEXA) lpwcx)->lpszClassName = heap_string_poolA ( str3.Buffer, str3.Length );
|
|
||||||
}
|
|
||||||
|
|
||||||
HEAP_free ( str2.Buffer );
|
|
||||||
HEAP_free ( str3.Buffer );
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
|
@ -133,7 +22,40 @@ GetClassInfoExA(
|
||||||
LPCSTR lpszClass,
|
LPCSTR lpszClass,
|
||||||
LPWNDCLASSEXA lpwcx)
|
LPWNDCLASSEXA lpwcx)
|
||||||
{
|
{
|
||||||
return GetClassInfoExCommon(hinst, (LPWSTR)lpszClass, (LPWNDCLASSEXW)lpwcx, FALSE);
|
UNICODE_STRING ClassName = {0};
|
||||||
|
BOOL Ret;
|
||||||
|
|
||||||
|
if (lpszClass == NULL)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_ATOM(lpszClass))
|
||||||
|
{
|
||||||
|
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!RtlCreateUnicodeStringFromAsciiz(&ClassName,
|
||||||
|
lpszClass))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ret = NtUserGetClassInfo(hinst,
|
||||||
|
&ClassName,
|
||||||
|
(LPWNDCLASSEXW)lpwcx,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
if (!IS_ATOM(lpszClass))
|
||||||
|
{
|
||||||
|
RtlFreeUnicodeString(&ClassName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,7 +69,28 @@ GetClassInfoExW(
|
||||||
LPCWSTR lpszClass,
|
LPCWSTR lpszClass,
|
||||||
LPWNDCLASSEXW lpwcx)
|
LPWNDCLASSEXW lpwcx)
|
||||||
{
|
{
|
||||||
return GetClassInfoExCommon(hinst, lpszClass, lpwcx, TRUE);
|
UNICODE_STRING ClassName = {0};
|
||||||
|
|
||||||
|
if (lpszClass == NULL)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_ATOM(lpszClass))
|
||||||
|
{
|
||||||
|
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&ClassName,
|
||||||
|
lpszClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NtUserGetClassInfo(hinst,
|
||||||
|
&ClassName,
|
||||||
|
lpwcx,
|
||||||
|
FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,6 +113,7 @@ GetClassInfoA(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w.cbSize = sizeof(w);
|
||||||
retval = GetClassInfoExA(hInstance,lpClassName,&w);
|
retval = GetClassInfoExA(hInstance,lpClassName,&w);
|
||||||
if (retval)
|
if (retval)
|
||||||
{
|
{
|
||||||
|
@ -197,8 +141,12 @@ GetClassInfoW(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w.cbSize = sizeof(w);
|
||||||
retval = GetClassInfoExW(hInstance,lpClassName,&w);
|
retval = GetClassInfoExW(hInstance,lpClassName,&w);
|
||||||
RtlCopyMemory (lpWndClass,&w.style,sizeof(WNDCLASSW));
|
if (retval)
|
||||||
|
{
|
||||||
|
RtlCopyMemory (lpWndClass,&w.style,sizeof(WNDCLASSW));
|
||||||
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,25 +223,14 @@ GetClassNameA(
|
||||||
LPSTR lpClassName,
|
LPSTR lpClassName,
|
||||||
int nMaxCount)
|
int nMaxCount)
|
||||||
{
|
{
|
||||||
int result;
|
ANSI_STRING ClassName;
|
||||||
LPWSTR ClassNameW;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
if(!lpClassName)
|
ClassName.MaximumLength = nMaxCount;
|
||||||
return 0;
|
ClassName.Buffer = lpClassName;
|
||||||
|
|
||||||
ClassNameW = HEAP_alloc ( (nMaxCount+1)*sizeof(WCHAR) );
|
return NtUserGetClassName(hWnd,
|
||||||
|
(PUNICODE_STRING)&ClassName,
|
||||||
result = NtUserGetClassName ( hWnd, ClassNameW, nMaxCount );
|
TRUE);
|
||||||
|
|
||||||
Status = HEAP_strcpyWtoA ( lpClassName, ClassNameW, result );
|
|
||||||
|
|
||||||
HEAP_free ( ClassNameW );
|
|
||||||
|
|
||||||
if ( !NT_SUCCESS(Status) )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -307,7 +244,14 @@ GetClassNameW(
|
||||||
LPWSTR lpClassName,
|
LPWSTR lpClassName,
|
||||||
int nMaxCount)
|
int nMaxCount)
|
||||||
{
|
{
|
||||||
return NtUserGetClassName(hWnd, lpClassName, nMaxCount);
|
UNICODE_STRING ClassName;
|
||||||
|
|
||||||
|
ClassName.MaximumLength = nMaxCount;
|
||||||
|
ClassName.Buffer = lpClassName;
|
||||||
|
|
||||||
|
return NtUserGetClassName(hWnd,
|
||||||
|
&ClassName,
|
||||||
|
FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -573,8 +517,8 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
|
||||||
RTL_ATOM Atom;
|
RTL_ATOM Atom;
|
||||||
WNDCLASSEXA WndClass;
|
WNDCLASSEXA WndClass;
|
||||||
UNICODE_STRING ClassName;
|
UNICODE_STRING ClassName;
|
||||||
UNICODE_STRING MenuName;
|
UNICODE_STRING MenuName = {0};
|
||||||
HMENU hMenu;
|
HMENU hMenu = NULL;
|
||||||
|
|
||||||
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXA) ||
|
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXA) ||
|
||||||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
|
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
|
||||||
|
@ -609,16 +553,17 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
|
||||||
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
|
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
if HIWORD(lpwcx->lpszMenuName)
|
if (lpwcx->lpszMenuName != NULL)
|
||||||
{
|
{
|
||||||
hMenu = 0;
|
if (HIWORD(lpwcx->lpszMenuName))
|
||||||
RtlCreateUnicodeStringFromAsciiz(&MenuName, WndClass.lpszMenuName);
|
{
|
||||||
}
|
RtlCreateUnicodeStringFromAsciiz(&MenuName, WndClass.lpszMenuName);
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
MenuName.Length =
|
{
|
||||||
MenuName.MaximumLength = 0;
|
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
|
||||||
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
|
}
|
||||||
|
|
||||||
hMenu = LoadMenuA(WndClass.hInstance, lpwcx->lpszMenuName);
|
hMenu = LoadMenuA(WndClass.hInstance, lpwcx->lpszMenuName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,20 +572,18 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
|
||||||
ClassName.Length =
|
ClassName.Length =
|
||||||
ClassName.MaximumLength = 0;
|
ClassName.MaximumLength = 0;
|
||||||
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
|
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
RtlCreateUnicodeStringFromAsciiz(&ClassName, WndClass.lpszClassName);
|
RtlCreateUnicodeStringFromAsciiz(&ClassName, WndClass.lpszClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Atom = NtUserRegisterClassExWOW(
|
Atom = NtUserRegisterClassEx((WNDCLASSEXW*)&WndClass,
|
||||||
(WNDCLASSEXW*)&WndClass,
|
&ClassName,
|
||||||
&ClassName,
|
&MenuName,
|
||||||
&ClassName,
|
NULL,
|
||||||
&MenuName,
|
REGISTERCLASS_ANSI,
|
||||||
NULL,
|
hMenu);
|
||||||
REGISTERCLASS_ANSI,
|
|
||||||
0,
|
|
||||||
hMenu);
|
|
||||||
|
|
||||||
if (!IS_ATOM(WndClass.lpszMenuName))
|
if (!IS_ATOM(WndClass.lpszMenuName))
|
||||||
RtlFreeUnicodeString(&MenuName);
|
RtlFreeUnicodeString(&MenuName);
|
||||||
|
@ -658,8 +601,8 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
|
||||||
{
|
{
|
||||||
WNDCLASSEXW WndClass;
|
WNDCLASSEXW WndClass;
|
||||||
UNICODE_STRING ClassName;
|
UNICODE_STRING ClassName;
|
||||||
UNICODE_STRING MenuName;
|
UNICODE_STRING MenuName = {0};
|
||||||
HMENU hMenu;
|
HMENU hMenu = NULL;
|
||||||
|
|
||||||
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
|
if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
|
||||||
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
|
lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
|
||||||
|
@ -694,16 +637,16 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
|
||||||
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
|
WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
if HIWORD(lpwcx->lpszMenuName)
|
if (lpwcx->lpszMenuName != NULL)
|
||||||
{
|
{
|
||||||
hMenu = 0;
|
if (HIWORD(lpwcx->lpszMenuName))
|
||||||
RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
|
{
|
||||||
}
|
RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
MenuName.Length =
|
{
|
||||||
MenuName.MaximumLength = 0;
|
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
|
||||||
MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
|
}
|
||||||
hMenu = LoadMenuW(WndClass.hInstance, lpwcx->lpszMenuName);
|
hMenu = LoadMenuW(WndClass.hInstance, lpwcx->lpszMenuName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,20 +655,18 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
|
||||||
ClassName.Length =
|
ClassName.Length =
|
||||||
ClassName.MaximumLength = 0;
|
ClassName.MaximumLength = 0;
|
||||||
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
|
ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
|
RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ATOM)NtUserRegisterClassExWOW(
|
return (ATOM)NtUserRegisterClassEx(&WndClass,
|
||||||
&WndClass,
|
&ClassName,
|
||||||
&ClassName,
|
&MenuName,
|
||||||
&ClassName,
|
NULL,
|
||||||
&MenuName,
|
0,
|
||||||
NULL,
|
hMenu);
|
||||||
0,
|
|
||||||
0,
|
|
||||||
hMenu);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -769,42 +710,65 @@ RegisterClassW(CONST WNDCLASSW *lpWndClass)
|
||||||
*/
|
*/
|
||||||
DWORD
|
DWORD
|
||||||
STDCALL
|
STDCALL
|
||||||
SetClassLongA (
|
SetClassLongA (HWND hWnd,
|
||||||
HWND hWnd,
|
int nIndex,
|
||||||
int nIndex,
|
LONG dwNewLong)
|
||||||
LONG dwNewLong)
|
|
||||||
{
|
{
|
||||||
UNICODE_STRING str2buf;
|
PSTR lpStr = (PSTR)dwNewLong;
|
||||||
PUNICODE_STRING str;
|
UNICODE_STRING Value = {0};
|
||||||
PUNICODE_STRING str2 = &str2buf;
|
BOOL Allocated = FALSE;
|
||||||
|
DWORD Ret;
|
||||||
|
|
||||||
if ( nIndex != GCL_MENUNAME )
|
/* FIXME - portability!!!! */
|
||||||
{
|
|
||||||
return NtUserSetClassLong ( hWnd, nIndex, dwNewLong, TRUE );
|
|
||||||
}
|
|
||||||
if ( IS_INTRESOURCE(dwNewLong) )
|
|
||||||
{
|
|
||||||
str2 = (PUNICODE_STRING)dwNewLong;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RtlCreateUnicodeStringFromAsciiz ( &str2buf,(LPSTR)dwNewLong );
|
|
||||||
}
|
|
||||||
|
|
||||||
str = (PUNICODE_STRING)NtUserSetClassLong(hWnd, nIndex, (DWORD)str2, TRUE);
|
if (nIndex == GCL_MENUNAME && lpStr != NULL)
|
||||||
|
{
|
||||||
|
if (!IS_INTRESOURCE(lpStr))
|
||||||
|
{
|
||||||
|
if (!RtlCreateUnicodeStringFromAsciiz(&Value,
|
||||||
|
lpStr))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !IS_INTRESOURCE(dwNewLong) )
|
Allocated = TRUE;
|
||||||
{
|
}
|
||||||
RtlFreeUnicodeString ( str2 );
|
else
|
||||||
}
|
Value.Buffer = (PWSTR)lpStr;
|
||||||
if ( IS_INTRESOURCE(str) )
|
|
||||||
{
|
dwNewLong = (LONG)&Value;
|
||||||
return (DWORD)str;
|
}
|
||||||
}
|
else if (nIndex == GCW_ATOM && lpStr != NULL)
|
||||||
else
|
{
|
||||||
{
|
if (!IS_ATOM(lpStr))
|
||||||
return (DWORD)heap_string_poolA ( str->Buffer, str->Length );
|
{
|
||||||
}
|
if (!RtlCreateUnicodeStringFromAsciiz(&Value,
|
||||||
|
lpStr))
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Allocated = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Value.Buffer = (PWSTR)lpStr;
|
||||||
|
|
||||||
|
dwNewLong = (LONG)&Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ret = (DWORD)NtUserSetClassLong(hWnd,
|
||||||
|
nIndex,
|
||||||
|
dwNewLong,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
if (Allocated)
|
||||||
|
{
|
||||||
|
RtlFreeUnicodeString(&Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -813,42 +777,44 @@ SetClassLongA (
|
||||||
*/
|
*/
|
||||||
DWORD
|
DWORD
|
||||||
STDCALL
|
STDCALL
|
||||||
SetClassLongW(
|
SetClassLongW(HWND hWnd,
|
||||||
HWND hWnd,
|
int nIndex,
|
||||||
int nIndex,
|
LONG dwNewLong)
|
||||||
LONG dwNewLong)
|
|
||||||
{
|
{
|
||||||
UNICODE_STRING str2buf;
|
PWSTR lpStr = (PWSTR)dwNewLong;
|
||||||
PUNICODE_STRING str;
|
UNICODE_STRING Value = {0};
|
||||||
PUNICODE_STRING str2 = &str2buf;
|
|
||||||
|
|
||||||
if (nIndex != GCL_MENUNAME )
|
/* FIXME - portability!!!! */
|
||||||
{
|
|
||||||
return NtUserSetClassLong ( hWnd, nIndex, dwNewLong, FALSE );
|
|
||||||
}
|
|
||||||
if ( IS_INTRESOURCE(dwNewLong) )
|
|
||||||
{
|
|
||||||
str2 = (PUNICODE_STRING)dwNewLong;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RtlCreateUnicodeString ( &str2buf, (LPWSTR)dwNewLong );
|
|
||||||
}
|
|
||||||
|
|
||||||
str = (PUNICODE_STRING)NtUserSetClassLong(hWnd, nIndex, (DWORD)str2, TRUE);
|
if (nIndex == GCL_MENUNAME && lpStr != NULL)
|
||||||
|
{
|
||||||
|
if (!IS_INTRESOURCE(lpStr))
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&Value,
|
||||||
|
lpStr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Value.Buffer = lpStr;
|
||||||
|
|
||||||
if ( !IS_INTRESOURCE(dwNewLong) )
|
dwNewLong = (LONG)&Value;
|
||||||
{
|
}
|
||||||
RtlFreeUnicodeString(str2);
|
else if (nIndex == GCW_ATOM && lpStr != NULL)
|
||||||
}
|
{
|
||||||
if ( IS_INTRESOURCE(str) )
|
if (!IS_ATOM(lpStr))
|
||||||
{
|
{
|
||||||
return (DWORD)str;
|
RtlInitUnicodeString(&Value,
|
||||||
}
|
lpStr);
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
return (DWORD)heap_string_poolW ( str->Buffer, str->Length );
|
Value.Buffer = lpStr;
|
||||||
}
|
|
||||||
|
dwNewLong = (LONG)&Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (DWORD)NtUserSetClassLong(hWnd,
|
||||||
|
nIndex,
|
||||||
|
dwNewLong,
|
||||||
|
FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -868,7 +834,7 @@ SetClassWord(
|
||||||
if ((nIndex < 0) && (nIndex != GCW_ATOM))
|
if ((nIndex < 0) && (nIndex != GCW_ATOM))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return (WORD) NtUserSetClassLong ( hWnd, nIndex, wNewWord, TRUE );
|
return (WORD) SetClassLongW ( hWnd, nIndex, wNewWord );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -909,28 +875,32 @@ UnregisterClassA(
|
||||||
LPCSTR lpClassName,
|
LPCSTR lpClassName,
|
||||||
HINSTANCE hInstance)
|
HINSTANCE hInstance)
|
||||||
{
|
{
|
||||||
LPWSTR ClassName;
|
UNICODE_STRING ClassName = {0};
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
BOOL Result;
|
BOOL Ret;
|
||||||
|
|
||||||
if(!IS_ATOM(lpClassName))
|
if (!IS_ATOM(lpClassName))
|
||||||
{
|
|
||||||
Status = HEAP_strdupAtoW(&ClassName, lpClassName, NULL);
|
|
||||||
if(!NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
SetLastError(RtlNtStatusToDosError(Status));
|
Status = HEAP_strdupAtoW(&ClassName.Buffer, lpClassName, NULL);
|
||||||
return FALSE;
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastError(RtlNtStatusToDosError(Status));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlInitUnicodeString(&ClassName,
|
||||||
|
ClassName.Buffer);
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpClassName);
|
||||||
ClassName = (LPWSTR)lpClassName;
|
|
||||||
|
|
||||||
Result = (BOOL)NtUserUnregisterClass((LPCWSTR)ClassName, hInstance, 0);
|
Ret = NtUserUnregisterClass(&ClassName,
|
||||||
|
hInstance);
|
||||||
|
|
||||||
if(ClassName && !IS_ATOM(lpClassName))
|
if(!IS_ATOM(lpClassName) && ClassName.Buffer != NULL)
|
||||||
HEAP_free(ClassName);
|
HEAP_free(ClassName.Buffer);
|
||||||
|
|
||||||
return Result;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -943,7 +913,18 @@ UnregisterClassW(
|
||||||
LPCWSTR lpClassName,
|
LPCWSTR lpClassName,
|
||||||
HINSTANCE hInstance)
|
HINSTANCE hInstance)
|
||||||
{
|
{
|
||||||
return (BOOL)NtUserUnregisterClass(lpClassName, hInstance, 0);
|
UNICODE_STRING ClassName = {0};
|
||||||
|
|
||||||
|
if (!IS_ATOM(lpClassName))
|
||||||
|
{
|
||||||
|
RtlInitUnicodeString(&ClassName,
|
||||||
|
lpClassName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpClassName);
|
||||||
|
|
||||||
|
return NtUserUnregisterClass(&ClassName,
|
||||||
|
hInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -951,6 +951,7 @@ IntCallWindowProcW(BOOL IsAnsiProc,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
Result = WndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam);
|
Result = WndProc(AnsiMsg.hwnd, AnsiMsg.message, AnsiMsg.wParam, AnsiMsg.lParam);
|
||||||
|
|
||||||
if (! MsgiUnicodeToAnsiReply(&AnsiMsg, &UnicodeMsg, &Result))
|
if (! MsgiUnicodeToAnsiReply(&AnsiMsg, &UnicodeMsg, &Result))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -991,6 +992,7 @@ IntCallWindowProcA(BOOL IsAnsiProc,
|
||||||
}
|
}
|
||||||
Result = WndProc(UnicodeMsg.hwnd, UnicodeMsg.message,
|
Result = WndProc(UnicodeMsg.hwnd, UnicodeMsg.message,
|
||||||
UnicodeMsg.wParam, UnicodeMsg.lParam);
|
UnicodeMsg.wParam, UnicodeMsg.lParam);
|
||||||
|
|
||||||
if (! MsgiAnsiToUnicodeReply(&UnicodeMsg, &AnsiMsg, &Result))
|
if (! MsgiAnsiToUnicodeReply(&UnicodeMsg, &AnsiMsg, &Result))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1010,20 +1012,19 @@ CallWindowProcA(WNDPROC lpPrevWndFunc,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
BOOL IsHandle;
|
WNDPROC_INFO wpInfo;
|
||||||
WndProcHandle wphData;
|
|
||||||
|
|
||||||
if (lpPrevWndFunc == NULL)
|
if (lpPrevWndFunc == NULL)
|
||||||
lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWL_WNDPROC, FALSE);
|
lpPrevWndFunc = (WNDPROC)NtUserGetWindowLong(hWnd, GWLP_WNDPROC, FALSE);
|
||||||
|
|
||||||
IsHandle = NtUserDereferenceWndProcHandle(lpPrevWndFunc,&wphData);
|
if (!NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
|
||||||
if (! IsHandle)
|
&wpInfo))
|
||||||
{
|
{
|
||||||
return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
|
return IntCallWindowProcA(TRUE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return IntCallWindowProcA(! wphData.IsUnicode, wphData.WindowProc,
|
return IntCallWindowProcA(!wpInfo.IsUnicode, wpInfo.WindowProc,
|
||||||
hWnd, Msg, wParam, lParam);
|
hWnd, Msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1039,17 +1040,16 @@ CallWindowProcW(WNDPROC lpPrevWndFunc,
|
||||||
WPARAM wParam,
|
WPARAM wParam,
|
||||||
LPARAM lParam)
|
LPARAM lParam)
|
||||||
{
|
{
|
||||||
BOOL IsHandle;
|
WNDPROC_INFO wpInfo;
|
||||||
WndProcHandle wphData;
|
|
||||||
|
|
||||||
IsHandle = NtUserDereferenceWndProcHandle(lpPrevWndFunc,&wphData);
|
if (!NtUserDereferenceWndProcHandle((HANDLE)lpPrevWndFunc,
|
||||||
if (! IsHandle)
|
&wpInfo))
|
||||||
{
|
{
|
||||||
return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
|
return IntCallWindowProcW(FALSE, lpPrevWndFunc, hWnd, Msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return IntCallWindowProcW(! wphData.IsUnicode, wphData.WindowProc,
|
return IntCallWindowProcW(!wpInfo.IsUnicode, wpInfo.WindowProc,
|
||||||
hWnd, Msg, wParam, lParam);
|
hWnd, Msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,8 +289,8 @@ CreateWindowExW(DWORD dwExStyle,
|
||||||
{
|
{
|
||||||
wce.cbSize = sizeof(WNDCLASSEXW);
|
wce.cbSize = sizeof(WNDCLASSEXW);
|
||||||
if(GetClassInfoExW(hInstance, lpClassName, &wce) && wce.lpszMenuName)
|
if(GetClassInfoExW(hInstance, lpClassName, &wce) && wce.lpszMenuName)
|
||||||
{
|
{DbgPrint("LoadingMenu 0x%p %d\n", wce.lpszMenuName, IS_INTRESOURCE(wce.lpszMenuName));
|
||||||
hMenu = LoadMenuW(hInstance, wce.lpszMenuName);
|
hMenu = LoadMenuW(hInstance, wce.lpszMenuName);DbgPrint("Loaded menu: 0x%p\n", hMenu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1449,7 +1449,7 @@ HWND
|
||||||
STDCALL
|
STDCALL
|
||||||
GetFocus(VOID)
|
GetFocus(VOID)
|
||||||
{
|
{
|
||||||
return (HWND)NtUserGetThreadState(0);
|
return (HWND)NtUserGetThreadState(THREADSTATE_FOCUSWINDOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -424,7 +424,7 @@ typedef struct _TEB
|
||||||
ULONG LastErrorValue; /* 34h */
|
ULONG LastErrorValue; /* 34h */
|
||||||
ULONG CountOfOwnedCriticalSections; /* 38h */
|
ULONG CountOfOwnedCriticalSections; /* 38h */
|
||||||
PVOID CsrClientThread; /* 3Ch */
|
PVOID CsrClientThread; /* 3Ch */
|
||||||
struct _W32THREAD* Win32ThreadInfo; /* 40h */
|
PVOID Win32ThreadInfo; /* 40h */
|
||||||
ULONG User32Reserved[0x1A]; /* 44h */
|
ULONG User32Reserved[0x1A]; /* 44h */
|
||||||
ULONG UserReserved[5]; /* ACh */
|
ULONG UserReserved[5]; /* ACh */
|
||||||
PVOID WOW32Reserved; /* C0h */
|
PVOID WOW32Reserved; /* C0h */
|
||||||
|
|
|
@ -9,6 +9,14 @@ static const UNICODE_STRING __emptyUnicodeString = {0};
|
||||||
static const LARGE_INTEGER __emptyLargeInteger = {{0, 0}};
|
static const LARGE_INTEGER __emptyLargeInteger = {{0, 0}};
|
||||||
static const ULARGE_INTEGER __emptyULargeInteger = {{0, 0}};
|
static const ULARGE_INTEGER __emptyULargeInteger = {{0, 0}};
|
||||||
|
|
||||||
|
#if defined(_WIN32K_)
|
||||||
|
/*
|
||||||
|
* NOTE: NTOSKRNL unfortunately doesn't export RtlRaiseStatus!
|
||||||
|
*/
|
||||||
|
VOID NTAPI W32kRaiseStatus(NTSTATUS Status);
|
||||||
|
#define RtlRaiseStatus W32kRaiseStatus
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE: Alignment of the pointers is not verified!
|
* NOTE: Alignment of the pointers is not verified!
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,6 +1,75 @@
|
||||||
#ifndef __WIN32K_NTUSER_H
|
#ifndef __WIN32K_NTUSER_H
|
||||||
#define __WIN32K_NTUSER_H
|
#define __WIN32K_NTUSER_H
|
||||||
|
|
||||||
|
struct _W32PROCESSINFO;
|
||||||
|
struct _W32THREADINFO;
|
||||||
|
|
||||||
|
typedef struct _DESKTOP
|
||||||
|
{
|
||||||
|
HANDLE hKernelHeap;
|
||||||
|
WCHAR szDesktopName[1];
|
||||||
|
} DESKTOP, *PDESKTOP;
|
||||||
|
|
||||||
|
typedef struct _CALLPROC
|
||||||
|
{
|
||||||
|
struct _W32PROCESSINFO *pi;
|
||||||
|
WNDPROC WndProc;
|
||||||
|
BOOL Unicode : 1;
|
||||||
|
} CALLPROC, *PCALLPROC;
|
||||||
|
|
||||||
|
typedef struct _WINDOWCLASS
|
||||||
|
{
|
||||||
|
struct _WINDOWCLASS *Next;
|
||||||
|
struct _WINDOWCLASS *Clone;
|
||||||
|
struct _WINDOWCLASS *Base;
|
||||||
|
PDESKTOP Desktop;
|
||||||
|
RTL_ATOM Atom;
|
||||||
|
ULONG Windows;
|
||||||
|
|
||||||
|
UINT Style;
|
||||||
|
WNDPROC WndProc;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
WNDPROC WndProcExtra;
|
||||||
|
PCALLPROC CallProc;
|
||||||
|
};
|
||||||
|
INT ClsExtra;
|
||||||
|
INT WndExtra;
|
||||||
|
HINSTANCE hInstance;
|
||||||
|
HANDLE hIcon; /* FIXME - Use pointer! */
|
||||||
|
HANDLE hIconSm; /* FIXME - Use pointer! */
|
||||||
|
HANDLE hCursor; /* FIXME - Use pointer! */
|
||||||
|
HBRUSH hbrBackground;
|
||||||
|
HANDLE hMenu; /* FIXME - Use pointer! */
|
||||||
|
PWSTR MenuName;
|
||||||
|
PSTR AnsiMenuName;
|
||||||
|
|
||||||
|
ULONG_PTR ClassExtraDataOffset;
|
||||||
|
|
||||||
|
BOOL Destroying : 1;
|
||||||
|
BOOL Unicode : 1;
|
||||||
|
BOOL System : 1;
|
||||||
|
BOOL Global : 1;
|
||||||
|
} WINDOWCLASS, *PWINDOWCLASS;
|
||||||
|
|
||||||
|
typedef struct _W32PROCESSINFO
|
||||||
|
{
|
||||||
|
PVOID UserHandleTable;
|
||||||
|
PWINDOWCLASS LocalClassList;
|
||||||
|
PWINDOWCLASS GlobalClassList;
|
||||||
|
PWINDOWCLASS SystemClassList;
|
||||||
|
} W32PROCESSINFO, *PW32PROCESSINFO;
|
||||||
|
|
||||||
|
typedef struct _W32THREADINFO
|
||||||
|
{
|
||||||
|
PW32PROCESSINFO pi; /* [USER] */
|
||||||
|
PW32PROCESSINFO kpi; /* [KERNEL] */
|
||||||
|
PDESKTOP Desktop;
|
||||||
|
ULONG_PTR DesktopHeapDelta;
|
||||||
|
} W32THREADINFO, *PW32THREADINFO;
|
||||||
|
|
||||||
|
PW32THREADINFO GetW32ThreadInfo(VOID);
|
||||||
|
PW32PROCESSINFO GetW32ProcessInfo(VOID);
|
||||||
|
|
||||||
DWORD
|
DWORD
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -196,8 +265,8 @@ NtUserTrackPopupMenuEx(
|
||||||
ULONG NTAPI
|
ULONG NTAPI
|
||||||
NtUserGetSystemMetrics(ULONG Index);
|
NtUserGetSystemMetrics(ULONG Index);
|
||||||
|
|
||||||
DWORD NTAPI
|
ULONG_PTR NTAPI
|
||||||
NtUserGetClassLong(HWND hWnd, DWORD Offset, BOOL Ansi);
|
NtUserGetClassLong(HWND hWnd, INT Offset, BOOL Ansi);
|
||||||
|
|
||||||
LONG NTAPI
|
LONG NTAPI
|
||||||
NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi);
|
NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi);
|
||||||
|
@ -785,18 +854,17 @@ NTAPI
|
||||||
NtUserGetCaretPos(
|
NtUserGetCaretPos(
|
||||||
LPPOINT lpPoint);
|
LPPOINT lpPoint);
|
||||||
|
|
||||||
DWORD NTAPI
|
BOOL NTAPI
|
||||||
NtUserGetClassInfo(HINSTANCE hInst,
|
NtUserGetClassInfo(HINSTANCE hInstance,
|
||||||
LPCWSTR str,
|
PUNICODE_STRING ClassName,
|
||||||
LPWNDCLASSEXW wcex,
|
LPWNDCLASSEXW wcex,
|
||||||
BOOL Ansi,
|
BOOL Ansi);
|
||||||
DWORD unknown3);
|
|
||||||
|
|
||||||
DWORD
|
INT
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserGetClassName(HWND hWnd,
|
NtUserGetClassName(HWND hWnd,
|
||||||
LPWSTR lpClassName,
|
PUNICODE_STRING ClassName,
|
||||||
ULONG nMaxCount);
|
BOOL Ansi);
|
||||||
|
|
||||||
HANDLE
|
HANDLE
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -1041,6 +1109,7 @@ NtUserGetThreadDesktop(
|
||||||
DWORD dwThreadId,
|
DWORD dwThreadId,
|
||||||
DWORD Unknown1);
|
DWORD Unknown1);
|
||||||
|
|
||||||
|
#define THREADSTATE_GETTHREADINFO (0)
|
||||||
#define THREADSTATE_FOCUSWINDOW (1)
|
#define THREADSTATE_FOCUSWINDOW (1)
|
||||||
#define THREADSTATE_INSENDMESSAGE (2)
|
#define THREADSTATE_INSENDMESSAGE (2)
|
||||||
DWORD
|
DWORD
|
||||||
|
@ -1355,14 +1424,12 @@ NtUserRedrawWindow
|
||||||
#define REGISTERCLASS_ALL (REGISTERCLASS_ANSI | REGISTERCLASS_SYSTEM)
|
#define REGISTERCLASS_ALL (REGISTERCLASS_ANSI | REGISTERCLASS_SYSTEM)
|
||||||
|
|
||||||
RTL_ATOM NTAPI
|
RTL_ATOM NTAPI
|
||||||
NtUserRegisterClassExWOW(
|
NtUserRegisterClassEx(
|
||||||
CONST WNDCLASSEXW* lpwcx,
|
CONST WNDCLASSEXW* lpwcx,
|
||||||
PUNICODE_STRING ClassName,
|
PUNICODE_STRING ClassName,
|
||||||
PUNICODE_STRING ClassNameCopy,
|
|
||||||
PUNICODE_STRING MenuName,
|
PUNICODE_STRING MenuName,
|
||||||
WNDPROC wpExtra,
|
WNDPROC wpExtra,
|
||||||
DWORD Flags,
|
DWORD Flags,
|
||||||
DWORD Unknown7,
|
|
||||||
HMENU hMenu);
|
HMENU hMenu);
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -1470,11 +1537,11 @@ NtUserSetCapture(HWND Wnd);
|
||||||
HWND NTAPI
|
HWND NTAPI
|
||||||
NtUserGetCapture(VOID);
|
NtUserGetCapture(VOID);
|
||||||
|
|
||||||
DWORD NTAPI
|
ULONG_PTR NTAPI
|
||||||
NtUserSetClassLong(
|
NtUserSetClassLong(
|
||||||
HWND hWnd,
|
HWND hWnd,
|
||||||
DWORD Offset,
|
INT Offset,
|
||||||
LONG dwNewLong,
|
ULONG_PTR dwNewLong,
|
||||||
BOOL Ansi );
|
BOOL Ansi );
|
||||||
|
|
||||||
|
|
||||||
|
@ -1840,9 +1907,8 @@ NtUserUnlockWindowStation(
|
||||||
BOOL
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
NtUserUnregisterClass(
|
NtUserUnregisterClass(
|
||||||
LPCWSTR ClassNameOrAtom,
|
PUNICODE_STRING ClassNameOrAtom,
|
||||||
HINSTANCE hInstance,
|
HINSTANCE hInstance);
|
||||||
DWORD Unknown);
|
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -1951,15 +2017,15 @@ NtUserGetWindow(HWND hWnd, UINT Relationship);
|
||||||
|
|
||||||
HWND NTAPI
|
HWND NTAPI
|
||||||
NtUserGetLastActivePopup(HWND hWnd);
|
NtUserGetLastActivePopup(HWND hWnd);
|
||||||
typedef struct _WndProcHandle
|
|
||||||
|
typedef struct _WNDPROC_INFO
|
||||||
{
|
{
|
||||||
WNDPROC WindowProc;
|
WNDPROC WindowProc;
|
||||||
BOOL IsUnicode;
|
BOOL IsUnicode;
|
||||||
HANDLE ProcessID;
|
} WNDPROC_INFO, *PWNDPROC_INFO;
|
||||||
} WndProcHandle;
|
|
||||||
|
|
||||||
DWORD NTAPI
|
BOOL NTAPI
|
||||||
NtUserDereferenceWndProcHandle(WNDPROC wpHandle, WndProcHandle *Data);
|
NtUserDereferenceWndProcHandle(IN HANDLE wpHandle, OUT PWNDPROC_INFO wpInfo);
|
||||||
|
|
||||||
VOID NTAPI
|
VOID NTAPI
|
||||||
NtUserManualGuiCheck(LONG Check);
|
NtUserManualGuiCheck(LONG Check);
|
||||||
|
|
|
@ -311,7 +311,7 @@ HEAP_Commit(SUBHEAP *subheap,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = NtAllocateVirtualMemory(NtCurrentProcess(),
|
Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
|
||||||
&address,
|
&address,
|
||||||
0,
|
0,
|
||||||
&commitsize,
|
&commitsize,
|
||||||
|
@ -570,13 +570,24 @@ static BOOLEAN HEAP_InitSubHeap( HEAP *heap, PVOID address, ULONG flags,
|
||||||
|
|
||||||
/* Initialize critical section */
|
/* Initialize critical section */
|
||||||
|
|
||||||
RtlInitializeHeapLock( &heap->critSection );
|
if (RtlpGetMode() == UserMode)
|
||||||
|
{
|
||||||
|
RtlInitializeHeapLock( &heap->critSection );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Commit memory */
|
/* Commit memory */
|
||||||
if (heap->commitRoutine)
|
if (heap->commitRoutine)
|
||||||
{
|
{
|
||||||
Status = heap->commitRoutine(heap, &address, &commitSize);
|
if (subheap != (SUBHEAP *)heap)
|
||||||
|
{
|
||||||
|
Status = heap->commitRoutine(heap, &address, &commitSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* the caller is responsible for committing the first page! */
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,28 +4,19 @@
|
||||||
#define IS_ATOM(x) \
|
#define IS_ATOM(x) \
|
||||||
(((ULONG_PTR)(x) > 0x0) && ((ULONG_PTR)(x) < 0x10000))
|
(((ULONG_PTR)(x) > 0x0) && ((ULONG_PTR)(x) < 0x10000))
|
||||||
|
|
||||||
typedef struct _WNDCLASS_OBJECT
|
VOID
|
||||||
{
|
DestroyCallProc(IN PDESKTOP Desktop,
|
||||||
UINT cbSize;
|
IN OUT PCALLPROC CallProc);
|
||||||
LONG refs; /* windows using this class (is 0 after class creation) */
|
|
||||||
UINT style;
|
PCALLPROC
|
||||||
WNDPROC lpfnWndProcA;
|
CloneCallProc(IN PDESKTOP Desktop,
|
||||||
WNDPROC lpfnWndProcW;
|
IN PCALLPROC CallProc);
|
||||||
int cbClsExtra;
|
|
||||||
int cbWndExtra;
|
PCALLPROC
|
||||||
HANDLE hInstance;
|
CreateCallProc(IN PDESKTOP Desktop,
|
||||||
HICON hIcon;
|
IN WNDPROC WndProc,
|
||||||
HCURSOR hCursor;
|
IN BOOL Unicode,
|
||||||
HBRUSH hbrBackground;
|
IN PW32PROCESSINFO pi);
|
||||||
HMENU hMenu;
|
|
||||||
UNICODE_STRING lpszMenuName;
|
|
||||||
RTL_ATOM Atom;
|
|
||||||
HICON hIconSm;
|
|
||||||
BOOL Unicode;
|
|
||||||
BOOL Global;
|
|
||||||
LIST_ENTRY ListEntry; /* linked into owning process */
|
|
||||||
PCHAR ExtraData;
|
|
||||||
} WNDCLASS_OBJECT, *PWNDCLASS_OBJECT;
|
|
||||||
|
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
InitClassImpl(VOID);
|
InitClassImpl(VOID);
|
||||||
|
@ -33,32 +24,45 @@ InitClassImpl(VOID);
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
CleanupClassImpl(VOID);
|
CleanupClassImpl(VOID);
|
||||||
|
|
||||||
void FASTCALL DestroyProcessClasses(PW32PROCESS Process );
|
BOOL
|
||||||
|
UserGetCallProcInfo(IN HANDLE hCallProc,
|
||||||
|
OUT PWNDPROC_INFO wpInfo);
|
||||||
|
|
||||||
__inline VOID FASTCALL
|
void FASTCALL
|
||||||
ClassDerefObject(PWNDCLASS_OBJECT Class);
|
DestroyProcessClasses(PW32PROCESS Process );
|
||||||
|
|
||||||
__inline VOID FASTCALL
|
PWINDOWCLASS
|
||||||
ClassRefObject(PWNDCLASS_OBJECT Class);
|
IntReferenceClass(IN PWINDOWCLASS BaseClass,
|
||||||
|
IN PDESKTOP Desktop);
|
||||||
|
|
||||||
PWNDCLASS_OBJECT FASTCALL
|
VOID
|
||||||
ClassGetClassByAtom(
|
IntDereferenceClass(IN OUT PWINDOWCLASS Class,
|
||||||
RTL_ATOM Atom,
|
IN PDESKTOP Desktop,
|
||||||
HINSTANCE hInstance);
|
IN PW32PROCESSINFO pi);
|
||||||
|
|
||||||
PWNDCLASS_OBJECT FASTCALL
|
RTL_ATOM
|
||||||
ClassGetClassByName(
|
UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx,
|
||||||
LPCWSTR ClassName,
|
IN PUNICODE_STRING ClassName,
|
||||||
HINSTANCE hInstance);
|
IN PUNICODE_STRING MenuName,
|
||||||
|
IN HANDLE hMenu,
|
||||||
|
IN WNDPROC wpExtra,
|
||||||
|
IN DWORD dwFlags);
|
||||||
|
|
||||||
PWNDCLASS_OBJECT FASTCALL
|
BOOL
|
||||||
ClassGetClassByNameOrAtom(
|
UserUnregisterClass(IN PUNICODE_STRING ClassName,
|
||||||
LPCWSTR ClassNameOrAtom,
|
IN HINSTANCE hInstance);
|
||||||
HINSTANCE hInstance);
|
|
||||||
|
|
||||||
struct _WINDOW_OBJECT;
|
ULONG_PTR
|
||||||
ULONG FASTCALL
|
UserGetClassLongPtr(IN PWINDOWCLASS Class,
|
||||||
IntGetClassLong(struct _WINDOW_OBJECT *WindowObject, ULONG Offset, BOOL Ansi);
|
IN INT Index,
|
||||||
|
IN BOOL Ansi);
|
||||||
|
|
||||||
|
RTL_ATOM
|
||||||
|
IntGetClassAtom(IN PUNICODE_STRING ClassName,
|
||||||
|
IN HINSTANCE hInstance OPTIONAL,
|
||||||
|
IN PW32PROCESSINFO pi OPTIONAL,
|
||||||
|
OUT PWINDOWCLASS *BaseClass OPTIONAL,
|
||||||
|
OUT PWINDOWCLASS **Link OPTIONAL);
|
||||||
|
|
||||||
#endif /* _WIN32K_CLASS_H */
|
#endif /* _WIN32K_CLASS_H */
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,6 @@
|
||||||
|
|
||||||
typedef struct _DESKTOP_OBJECT
|
typedef struct _DESKTOP_OBJECT
|
||||||
{
|
{
|
||||||
PVOID DesktopHeap; /* points to kmode memory! */
|
|
||||||
|
|
||||||
CSHORT Type;
|
CSHORT Type;
|
||||||
CSHORT Size;
|
CSHORT Size;
|
||||||
LIST_ENTRY ListEntry;
|
LIST_ENTRY ListEntry;
|
||||||
|
@ -26,11 +24,15 @@ typedef struct _DESKTOP_OBJECT
|
||||||
PVOID BlockInputThread;
|
PVOID BlockInputThread;
|
||||||
|
|
||||||
LIST_ENTRY ShellHookWindows;
|
LIST_ENTRY ShellHookWindows;
|
||||||
|
|
||||||
|
HANDLE hDesktopHeap;
|
||||||
|
PSECTION_OBJECT DesktopHeapSection;
|
||||||
|
PDESKTOP DesktopInfo;
|
||||||
} DESKTOP_OBJECT, *PDESKTOP_OBJECT;
|
} DESKTOP_OBJECT, *PDESKTOP_OBJECT;
|
||||||
|
|
||||||
extern PDESKTOP_OBJECT InputDesktop;
|
extern PDESKTOP_OBJECT InputDesktop;
|
||||||
extern HDESK InputDesktopHandle;
|
extern HDESK InputDesktopHandle;
|
||||||
extern PWNDCLASS_OBJECT DesktopWindowClass;
|
extern PWINDOWCLASS DesktopWindowClass;
|
||||||
extern HDC ScreenDeviceContext;
|
extern HDC ScreenDeviceContext;
|
||||||
extern BOOL g_PaintDesktopVersion;
|
extern BOOL g_PaintDesktopVersion;
|
||||||
|
|
||||||
|
@ -91,6 +93,8 @@ IntHideDesktop(PDESKTOP_OBJECT Desktop);
|
||||||
HDESK FASTCALL
|
HDESK FASTCALL
|
||||||
IntGetDesktopObjectHandle(PDESKTOP_OBJECT DesktopObject);
|
IntGetDesktopObjectHandle(PDESKTOP_OBJECT DesktopObject);
|
||||||
|
|
||||||
|
BOOL IntSetThreadDesktop(IN PDESKTOP_OBJECT DesktopObject);
|
||||||
|
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
IntValidateDesktopHandle(
|
IntValidateDesktopHandle(
|
||||||
HDESK Desktop,
|
HDESK Desktop,
|
||||||
|
@ -115,6 +119,113 @@ VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam);
|
||||||
#define IntIsActiveDesktop(Desktop) \
|
#define IntIsActiveDesktop(Desktop) \
|
||||||
((Desktop)->WindowStation->ActiveDesktop == (Desktop))
|
((Desktop)->WindowStation->ActiveDesktop == (Desktop))
|
||||||
|
|
||||||
|
static __inline PVOID
|
||||||
|
DesktopHeapAlloc(IN PDESKTOP Desktop,
|
||||||
|
IN SIZE_T Bytes)
|
||||||
|
{
|
||||||
|
return RtlAllocateHeap(Desktop->hKernelHeap,
|
||||||
|
HEAP_NO_SERIALIZE,
|
||||||
|
Bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline BOOL
|
||||||
|
DesktopHeapFree(IN PDESKTOP Desktop,
|
||||||
|
IN PVOID lpMem)
|
||||||
|
{
|
||||||
|
return RtlFreeHeap(Desktop->hKernelHeap,
|
||||||
|
HEAP_NO_SERIALIZE,
|
||||||
|
lpMem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline PVOID
|
||||||
|
DesktopHeapReAlloc(IN PDESKTOP Desktop,
|
||||||
|
IN PVOID lpMem,
|
||||||
|
IN SIZE_T Bytes)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
/* NOTE: ntoskrnl doesn't export RtlReAllocateHeap... */
|
||||||
|
return RtlReAllocateHeap(Desktop->hKernelHeap,
|
||||||
|
HEAP_NO_SERIALIZE,
|
||||||
|
lpMem,
|
||||||
|
Bytes);
|
||||||
|
#else
|
||||||
|
SIZE_T PrevSize;
|
||||||
|
PVOID pNew;
|
||||||
|
|
||||||
|
PrevSize = RtlSizeHeap(Desktop->hKernelHeap,
|
||||||
|
HEAP_NO_SERIALIZE,
|
||||||
|
lpMem);
|
||||||
|
|
||||||
|
if (PrevSize == Bytes)
|
||||||
|
return lpMem;
|
||||||
|
|
||||||
|
pNew = RtlAllocateHeap(Desktop->hKernelHeap,
|
||||||
|
HEAP_NO_SERIALIZE,
|
||||||
|
Bytes);
|
||||||
|
if (pNew != NULL)
|
||||||
|
{
|
||||||
|
if (PrevSize < Bytes)
|
||||||
|
Bytes = PrevSize;
|
||||||
|
|
||||||
|
RtlCopyMemory(pNew,
|
||||||
|
lpMem,
|
||||||
|
Bytes);
|
||||||
|
|
||||||
|
RtlFreeHeap(Desktop->hKernelHeap,
|
||||||
|
HEAP_NO_SERIALIZE,
|
||||||
|
lpMem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pNew;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline ULONG_PTR
|
||||||
|
DesktopHeapGetUserDelta(VOID)
|
||||||
|
{
|
||||||
|
PW32HEAP_USER_MAPPING Mapping;
|
||||||
|
HANDLE hDesktopHeap;
|
||||||
|
ULONG_PTR Delta = 0;
|
||||||
|
|
||||||
|
ASSERT(PsGetWin32Thread()->Desktop != NULL);
|
||||||
|
hDesktopHeap = PsGetWin32Thread()->Desktop->hDesktopHeap;
|
||||||
|
|
||||||
|
Mapping = PsGetWin32Process()->HeapMappings.Next;
|
||||||
|
while (Mapping != NULL)
|
||||||
|
{
|
||||||
|
if (Mapping->UserMapping == (PVOID)hDesktopHeap)
|
||||||
|
{
|
||||||
|
Delta = (ULONG_PTR)Mapping->KernelMapping - (ULONG_PTR)Mapping->UserMapping;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mapping = Mapping->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline PVOID
|
||||||
|
DesktopHeapAddressToUser(IN PDESKTOP Desktop,
|
||||||
|
PVOID lpMem)
|
||||||
|
{
|
||||||
|
PW32HEAP_USER_MAPPING Mapping;
|
||||||
|
|
||||||
|
Mapping = PsGetWin32Process()->HeapMappings.Next;
|
||||||
|
while (Mapping != NULL)
|
||||||
|
{
|
||||||
|
if (Mapping->KernelMapping == (PVOID)Desktop->hKernelHeap)
|
||||||
|
{
|
||||||
|
return (PVOID)(((ULONG_PTR)lpMem - (ULONG_PTR)Desktop->hKernelHeap) +
|
||||||
|
(ULONG_PTR)Mapping->UserMapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mapping = Mapping->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _WIN32K_DESKTOP_H */
|
#endif /* _WIN32K_DESKTOP_H */
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -45,7 +45,7 @@ typedef enum _USER_OBJECT_TYPE
|
||||||
otCursorIcon,
|
otCursorIcon,
|
||||||
otHook,
|
otHook,
|
||||||
otMonitor,
|
otMonitor,
|
||||||
otClass //fixme: remove
|
otCallProc
|
||||||
|
|
||||||
} USER_OBJECT_TYPE;
|
} USER_OBJECT_TYPE;
|
||||||
|
|
||||||
|
@ -125,6 +125,8 @@ typedef struct _USER_REFERENCE_ENTRY
|
||||||
\
|
\
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HANDLE FASTCALL ObmObjectToHandle(PVOID obj);
|
||||||
|
|
||||||
VOID FASTCALL CreateStockObjects (VOID);
|
VOID FASTCALL CreateStockObjects (VOID);
|
||||||
VOID FASTCALL CreateSysColorObjects (VOID);
|
VOID FASTCALL CreateSysColorObjects (VOID);
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ BOOL FASTCALL ObmCreateHandleTable();
|
||||||
|
|
||||||
/******************** HANDLE.C ***************/
|
/******************** HANDLE.C ***************/
|
||||||
|
|
||||||
extern USER_HANDLE_TABLE gHandleTable;
|
extern PUSER_HANDLE_TABLE gHandleTable;
|
||||||
|
|
||||||
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle );
|
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle );
|
||||||
VOID UserInitHandleTable(PUSER_HANDLE_TABLE ht, PVOID mem, ULONG bytes);
|
VOID UserInitHandleTable(PUSER_HANDLE_TABLE ht, PVOID mem, ULONG bytes);
|
||||||
|
|
|
@ -15,10 +15,18 @@ typedef struct _W32THREAD
|
||||||
BOOLEAN IsExiting;
|
BOOLEAN IsExiting;
|
||||||
SINGLE_LIST_ENTRY ReferencesList;
|
SINGLE_LIST_ENTRY ReferencesList;
|
||||||
|
|
||||||
|
PW32THREADINFO ThreadInfo;
|
||||||
} W32THREAD, *PW32THREAD;
|
} W32THREAD, *PW32THREAD;
|
||||||
|
|
||||||
#include <poppack.h>
|
#include <poppack.h>
|
||||||
|
|
||||||
|
typedef struct _W32HEAP_USER_MAPPING
|
||||||
|
{
|
||||||
|
struct _W32HEAP_USER_MAPPING *Next;
|
||||||
|
PVOID KernelMapping;
|
||||||
|
PVOID UserMapping;
|
||||||
|
ULONG Count;
|
||||||
|
} W32HEAP_USER_MAPPING, *PW32HEAP_USER_MAPPING;
|
||||||
|
|
||||||
typedef struct _W32PROCESS
|
typedef struct _W32PROCESS
|
||||||
{
|
{
|
||||||
|
@ -32,6 +40,9 @@ typedef struct _W32PROCESS
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
LONG GDIObjects;
|
LONG GDIObjects;
|
||||||
LONG UserObjects;
|
LONG UserObjects;
|
||||||
|
|
||||||
|
W32HEAP_USER_MAPPING HeapMappings;
|
||||||
|
PW32PROCESSINFO ProcessInfo;
|
||||||
} W32PROCESS, *PW32PROCESS;
|
} W32PROCESS, *PW32PROCESS;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,21 @@ typedef struct _INTERNALPOS
|
||||||
|
|
||||||
typedef struct _WINDOW_OBJECT
|
typedef struct _WINDOW_OBJECT
|
||||||
{
|
{
|
||||||
|
/* Pointer to the thread information */
|
||||||
|
PW32THREADINFO ti;
|
||||||
|
/* Pointer to the desktop */
|
||||||
|
PDESKTOP Desktop;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
/* Pointer to a call procedure handle */
|
||||||
|
PCALLPROC CallProc;
|
||||||
|
/* Extra Wnd proc (windows of system classes) */
|
||||||
|
WNDPROC WndProcExtra;
|
||||||
|
};
|
||||||
|
/* Indicates whether the window is derived from a system class */
|
||||||
|
BOOL IsSystem;
|
||||||
/* Pointer to the window class. */
|
/* Pointer to the window class. */
|
||||||
PWNDCLASS_OBJECT Class;
|
PWINDOWCLASS Class;
|
||||||
/* Extended style. */
|
/* Extended style. */
|
||||||
DWORD ExStyle;
|
DWORD ExStyle;
|
||||||
/* Window name. */
|
/* Window name. */
|
||||||
|
@ -81,8 +94,7 @@ typedef struct _WINDOW_OBJECT
|
||||||
PWINDOW_SCROLLINFO Scroll;
|
PWINDOW_SCROLLINFO Scroll;
|
||||||
LONG UserData;
|
LONG UserData;
|
||||||
BOOL Unicode;
|
BOOL Unicode;
|
||||||
WNDPROC WndProcA;
|
WNDPROC WndProc;
|
||||||
WNDPROC WndProcW;
|
|
||||||
PETHREAD OwnerThread;
|
PETHREAD OwnerThread;
|
||||||
HWND hWndLastPopup; /* handle to last active popup window (wine doesn't use pointer, for unk. reason)*/
|
HWND hWndLastPopup; /* handle to last active popup window (wine doesn't use pointer, for unk. reason)*/
|
||||||
PINTERNALPOS InternalPos;
|
PINTERNALPOS InternalPos;
|
||||||
|
@ -190,10 +202,6 @@ IntAnyPopup(VOID);
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntIsWindowInDestroy(PWINDOW_OBJECT Window);
|
IntIsWindowInDestroy(PWINDOW_OBJECT Window);
|
||||||
|
|
||||||
DWORD IntRemoveWndProcHandle(WNDPROC Handle);
|
|
||||||
DWORD IntRemoveProcessWndProcHandles(HANDLE ProcessID);
|
|
||||||
DWORD IntAddWndProcHandle(WNDPROC WindowProc, BOOL IsUnicode);
|
|
||||||
|
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntShowOwnedPopups( PWINDOW_OBJECT owner, BOOL fShow );
|
IntShowOwnedPopups( PWINDOW_OBJECT owner, BOOL fShow );
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,9 @@ BOOL INTERNAL_CALL GDI_CleanupForProcess (PGDI_HANDLE_TABLE HandleTable, struct
|
||||||
PGDI_HANDLE_TABLE GdiHandleTable = NULL;
|
PGDI_HANDLE_TABLE GdiHandleTable = NULL;
|
||||||
PSECTION_OBJECT GdiTableSection = NULL;
|
PSECTION_OBJECT GdiTableSection = NULL;
|
||||||
|
|
||||||
|
HANDLE GlobalUserHeap = NULL;
|
||||||
|
PSECTION_OBJECT GlobalUserHeapSection = NULL;
|
||||||
|
|
||||||
extern ULONG_PTR Win32kSSDT[];
|
extern ULONG_PTR Win32kSSDT[];
|
||||||
extern UCHAR Win32kSSPT[];
|
extern UCHAR Win32kSSPT[];
|
||||||
extern ULONG Win32kNumberOfSysCalls;
|
extern ULONG Win32kNumberOfSysCalls;
|
||||||
|
@ -69,8 +72,35 @@ Win32kProcessCallback(struct _EPROCESS *Process,
|
||||||
|
|
||||||
if (Create)
|
if (Create)
|
||||||
{
|
{
|
||||||
|
ULONG ViewSize = 0;
|
||||||
|
LARGE_INTEGER Offset;
|
||||||
|
PVOID UserBase = NULL;
|
||||||
|
NTSTATUS Status;
|
||||||
|
extern PSECTION_OBJECT GlobalUserHeapSection;
|
||||||
DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
|
DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
|
||||||
|
|
||||||
|
/* map the global heap into the process */
|
||||||
|
Offset.QuadPart = 0;
|
||||||
|
Status = MmMapViewOfSection(GlobalUserHeapSection,
|
||||||
|
PsGetCurrentProcess(),
|
||||||
|
&UserBase,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
&Offset,
|
||||||
|
&ViewSize,
|
||||||
|
ViewUnmap,
|
||||||
|
SEC_NO_CHANGE,
|
||||||
|
PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but thanks to RTL heaps... */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to map the global heap! 0x%x\n", Status);
|
||||||
|
RETURN(Status);
|
||||||
|
}
|
||||||
|
Win32Process->HeapMappings.Next = NULL;
|
||||||
|
Win32Process->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap;
|
||||||
|
Win32Process->HeapMappings.UserMapping = UserBase;
|
||||||
|
Win32Process->HeapMappings.Count = 1;
|
||||||
|
|
||||||
InitializeListHead(&Win32Process->ClassList);
|
InitializeListHead(&Win32Process->ClassList);
|
||||||
|
|
||||||
InitializeListHead(&Win32Process->MenuListHead);
|
InitializeListHead(&Win32Process->MenuListHead);
|
||||||
|
@ -95,7 +125,6 @@ Win32kProcessCallback(struct _EPROCESS *Process,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
|
DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
|
||||||
IntRemoveProcessWndProcHandles((HANDLE)Process->UniqueProcessId);
|
|
||||||
IntCleanupMenus(Process, Win32Process);
|
IntCleanupMenus(Process, Win32Process);
|
||||||
IntCleanupCurIcons(Process, Win32Process);
|
IntCleanupCurIcons(Process, Win32Process);
|
||||||
IntEngCleanupDriverObjs(Process, Win32Process);
|
IntEngCleanupDriverObjs(Process, Win32Process);
|
||||||
|
@ -115,6 +144,12 @@ Win32kProcessCallback(struct _EPROCESS *Process,
|
||||||
{
|
{
|
||||||
LogonProcess = NULL;
|
LogonProcess = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Win32Process->ProcessInfo != NULL)
|
||||||
|
{
|
||||||
|
UserHeapFree(Win32Process->ProcessInfo);
|
||||||
|
Win32Process->ProcessInfo = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN( STATUS_SUCCESS);
|
RETURN( STATUS_SUCCESS);
|
||||||
|
@ -198,17 +233,25 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
|
||||||
|
|
||||||
if (hDesk != NULL)
|
if (hDesk != NULL)
|
||||||
{
|
{
|
||||||
|
PDESKTOP_OBJECT DesktopObject;
|
||||||
|
Win32Thread->Desktop = NULL;
|
||||||
Status = ObReferenceObjectByHandle(hDesk,
|
Status = ObReferenceObjectByHandle(hDesk,
|
||||||
0,
|
0,
|
||||||
ExDesktopObjectType,
|
ExDesktopObjectType,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
(PVOID*)&Win32Thread->Desktop,
|
(PVOID*)&DesktopObject,
|
||||||
NULL);
|
NULL);
|
||||||
NtClose(hDesk);
|
NtClose(hDesk);
|
||||||
if(!NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
if (!IntSetThreadDesktop(DesktopObject))
|
||||||
|
{
|
||||||
|
DPRINT1("Unable to set thread desktop\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk);
|
DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk);
|
||||||
Win32Thread->Desktop = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,11 +277,15 @@ Win32kThreadCallback(struct _ETHREAD *Thread,
|
||||||
IntBlockInput(Win32Thread, FALSE);
|
IntBlockInput(Win32Thread, FALSE);
|
||||||
MsqDestroyMessageQueue(Win32Thread->MessageQueue);
|
MsqDestroyMessageQueue(Win32Thread->MessageQueue);
|
||||||
IntCleanupThreadCallbacks(Win32Thread);
|
IntCleanupThreadCallbacks(Win32Thread);
|
||||||
if(Win32Thread->Desktop != NULL)
|
|
||||||
|
IntSetThreadDesktop(NULL);
|
||||||
|
|
||||||
|
if (Win32Thread->ThreadInfo != NULL)
|
||||||
{
|
{
|
||||||
ObDereferenceObject(Win32Thread->Desktop);
|
UserHeapFree(Win32Thread->ThreadInfo);
|
||||||
|
Win32Thread->ThreadInfo = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* cleanup user object references stack */
|
/* cleanup user object references stack */
|
||||||
e = PopEntryList(&Win32Thread->ReferencesList);
|
e = PopEntryList(&Win32Thread->ReferencesList);
|
||||||
while (e)
|
while (e)
|
||||||
|
@ -309,6 +356,7 @@ DriverEntry (
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
BOOLEAN Result;
|
BOOLEAN Result;
|
||||||
W32_CALLOUT_DATA CalloutData;
|
W32_CALLOUT_DATA CalloutData;
|
||||||
|
PVOID GlobalUserHeapBase = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register user mode call interface
|
* Register user mode call interface
|
||||||
|
@ -342,6 +390,16 @@ DriverEntry (
|
||||||
*/
|
*/
|
||||||
PsEstablishWin32Callouts(&CalloutData);
|
PsEstablishWin32Callouts(&CalloutData);
|
||||||
|
|
||||||
|
GlobalUserHeap = UserCreateHeap(&GlobalUserHeapSection,
|
||||||
|
&GlobalUserHeapBase,
|
||||||
|
1 * 1024 * 1024); /* FIXME - 1 MB for now... */
|
||||||
|
if (GlobalUserHeap == NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("Failed to initialize the global heap!\n");
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Status = InitUserImpl();
|
Status = InitUserImpl();
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,4 +61,22 @@ GetLastNtError()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
W32kRaiseStatus(NTSTATUS Status)
|
||||||
|
{
|
||||||
|
EXCEPTION_RECORD ExceptionRecord;
|
||||||
|
|
||||||
|
/* Create an exception record */
|
||||||
|
ExceptionRecord.ExceptionCode = Status;
|
||||||
|
ExceptionRecord.ExceptionRecord = NULL;
|
||||||
|
ExceptionRecord.NumberParameters = 0;
|
||||||
|
ExceptionRecord.ExceptionFlags = EXCEPTION_NONCONTINUABLE;
|
||||||
|
|
||||||
|
RtlRaiseException(&ExceptionRecord);
|
||||||
|
|
||||||
|
/* If we returned, raise a status */
|
||||||
|
W32kRaiseStatus(Status);
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Accel= UserGetObject(&gHandleTable, hAccel, otAccel);
|
Accel= UserGetObject(gHandleTable, hAccel, otAccel);
|
||||||
if (!Accel)
|
if (!Accel)
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE);
|
SetLastWin32Error(ERROR_INVALID_ACCEL_HANDLE);
|
||||||
|
@ -344,7 +344,7 @@ NtUserCreateAcceleratorTable(
|
||||||
Entries, EntriesCount);
|
Entries, EntriesCount);
|
||||||
UserEnterExclusive();
|
UserEnterExclusive();
|
||||||
|
|
||||||
Accel = ObmCreateObject(&gHandleTable, (PHANDLE)&hAccel, otAccel, sizeof(ACCELERATOR_TABLE));
|
Accel = ObmCreateObject(gHandleTable, (PHANDLE)&hAccel, otAccel, sizeof(ACCELERATOR_TABLE));
|
||||||
|
|
||||||
if (Accel == NULL)
|
if (Accel == NULL)
|
||||||
{
|
{
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -83,7 +83,7 @@ PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurIcon = (PCURICON_OBJECT)UserGetObject(&gHandleTable, hCurIcon, otCursorIcon);
|
CurIcon = (PCURICON_OBJECT)UserGetObject(gHandleTable, hCurIcon, otCursorIcon);
|
||||||
if (!CurIcon)
|
if (!CurIcon)
|
||||||
{
|
{
|
||||||
/* we never set ERROR_INVALID_ICON_HANDLE. lets hope noone ever checks for it */
|
/* we never set ERROR_INVALID_ICON_HANDLE. lets hope noone ever checks for it */
|
||||||
|
@ -397,7 +397,7 @@ IntCreateCurIconHandle(PWINSTATION_OBJECT WinSta)
|
||||||
PCURICON_OBJECT CurIcon;
|
PCURICON_OBJECT CurIcon;
|
||||||
HANDLE hCurIcon;
|
HANDLE hCurIcon;
|
||||||
|
|
||||||
CurIcon = ObmCreateObject(&gHandleTable, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
|
CurIcon = ObmCreateObject(gHandleTable, &hCurIcon, otCursorIcon, sizeof(CURICON_OBJECT));
|
||||||
|
|
||||||
if(!CurIcon)
|
if(!CurIcon)
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,6 +43,8 @@ HDC ScreenDeviceContext = NULL;
|
||||||
|
|
||||||
BOOL g_PaintDesktopVersion = FALSE;
|
BOOL g_PaintDesktopVersion = FALSE;
|
||||||
|
|
||||||
|
static VOID IntFreeDesktopHeap(IN OUT PDESKTOP_OBJECT Desktop);
|
||||||
|
|
||||||
/* INITALIZATION FUNCTIONS ****************************************************/
|
/* INITALIZATION FUNCTIONS ****************************************************/
|
||||||
|
|
||||||
static GENERIC_MAPPING IntDesktopMapping =
|
static GENERIC_MAPPING IntDesktopMapping =
|
||||||
|
@ -121,6 +123,8 @@ IntDesktopObjectDelete(PVOID DeletedObject)
|
||||||
RemoveEntryList(&Desktop->ListEntry);
|
RemoveEntryList(&Desktop->ListEntry);
|
||||||
|
|
||||||
RtlFreeUnicodeString(&Desktop->Name);
|
RtlFreeUnicodeString(&Desktop->Name);
|
||||||
|
|
||||||
|
IntFreeDesktopHeap(Desktop);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
@ -723,7 +727,15 @@ BOOL IntDeRegisterShellHookWindow(HWND hWnd)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VOID
|
||||||
|
IntFreeDesktopHeap(IN OUT PDESKTOP_OBJECT Desktop)
|
||||||
|
{
|
||||||
|
if (Desktop->DesktopHeapSection != NULL)
|
||||||
|
{
|
||||||
|
ObDereferenceObject(Desktop->DesktopHeapSection);
|
||||||
|
Desktop->DesktopHeapSection = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* SYSCALLS *******************************************************************/
|
/* SYSCALLS *******************************************************************/
|
||||||
|
@ -776,6 +788,8 @@ NtUserCreateDesktop(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HDESK Desktop;
|
HDESK Desktop;
|
||||||
CSR_API_MESSAGE Request;
|
CSR_API_MESSAGE Request;
|
||||||
|
PVOID DesktopHeapSystemBase = NULL;
|
||||||
|
SIZE_T DesktopInfoSize;
|
||||||
DECLARE_RETURN(HDESK);
|
DECLARE_RETURN(HDESK);
|
||||||
|
|
||||||
DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
|
DPRINT("Enter NtUserCreateDesktop: %wZ\n", lpszDesktopName);
|
||||||
|
@ -858,6 +872,39 @@ NtUserCreateDesktop(
|
||||||
RETURN( NULL);
|
RETURN( NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DesktopObject->DesktopHeapSection = NULL;
|
||||||
|
DesktopObject->hDesktopHeap = UserCreateHeap(&DesktopObject->DesktopHeapSection,
|
||||||
|
&DesktopHeapSystemBase,
|
||||||
|
4 * 1024 * 1024); /* FIXME */
|
||||||
|
if (DesktopObject->hDesktopHeap == NULL)
|
||||||
|
{
|
||||||
|
ObDereferenceObject(DesktopObject);
|
||||||
|
DPRINT1("Failed to create desktop heap!\n");
|
||||||
|
RETURN(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
DesktopInfoSize = FIELD_OFFSET(DESKTOP,
|
||||||
|
szDesktopName[(lpszDesktopName->Length / sizeof(WCHAR)) + 1]);
|
||||||
|
|
||||||
|
DesktopObject->DesktopInfo = RtlAllocateHeap(DesktopObject->hDesktopHeap,
|
||||||
|
HEAP_NO_SERIALIZE,
|
||||||
|
DesktopInfoSize);
|
||||||
|
|
||||||
|
if (DesktopObject->DesktopInfo == NULL)
|
||||||
|
{
|
||||||
|
ObDereferenceObject(DesktopObject);
|
||||||
|
DPRINT1("Failed to create the DESKTOP structure!\n");
|
||||||
|
RETURN(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
RtlZeroMemory(DesktopObject->DesktopInfo,
|
||||||
|
DesktopInfoSize);
|
||||||
|
|
||||||
|
DesktopObject->DesktopInfo->hKernelHeap = DesktopObject->hDesktopHeap;
|
||||||
|
RtlCopyMemory(DesktopObject->DesktopInfo->szDesktopName,
|
||||||
|
lpszDesktopName->Buffer,
|
||||||
|
lpszDesktopName->Length);
|
||||||
|
|
||||||
// init desktop area
|
// init desktop area
|
||||||
DesktopObject->WorkArea.left = 0;
|
DesktopObject->WorkArea.left = 0;
|
||||||
DesktopObject->WorkArea.top = 0;
|
DesktopObject->WorkArea.top = 0;
|
||||||
|
@ -1216,7 +1263,7 @@ NtUserPaintDesktop(HDC hDC)
|
||||||
RETURN(FALSE);
|
RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
DesktopBrush = (HBRUSH)IntGetClassLong(WndDesktop, GCL_HBRBACKGROUND, FALSE); //fixme: verify retval
|
DesktopBrush = (HBRUSH)UserGetClassLongPtr(WndDesktop->Class, GCL_HBRBACKGROUND, FALSE);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1560,6 +1607,183 @@ CLEANUP:
|
||||||
END_CLEANUP;
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
IntUnmapDesktopView(IN PDESKTOP_OBJECT DesktopObject)
|
||||||
|
{
|
||||||
|
PW32THREADINFO ti;
|
||||||
|
PW32HEAP_USER_MAPPING HeapMapping, *PrevLink = &PsGetWin32Process()->HeapMappings.Next;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
|
/* unmap if we're the last thread using the desktop */
|
||||||
|
HeapMapping = *PrevLink;
|
||||||
|
while (HeapMapping != NULL)
|
||||||
|
{
|
||||||
|
if (HeapMapping->KernelMapping == (PVOID)DesktopObject->hDesktopHeap)
|
||||||
|
{
|
||||||
|
if (--HeapMapping->Count == 0)
|
||||||
|
{
|
||||||
|
*PrevLink = HeapMapping->Next;
|
||||||
|
|
||||||
|
Status = MmUnmapViewOfSection(PsGetCurrentProcess(),
|
||||||
|
HeapMapping->UserMapping);
|
||||||
|
|
||||||
|
ObDereferenceObject(DesktopObject);
|
||||||
|
|
||||||
|
UserHeapFree(HeapMapping);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PrevLink = &HeapMapping->Next;
|
||||||
|
HeapMapping = HeapMapping->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
ti = GetW32ThreadInfo();
|
||||||
|
if (ti != NULL)
|
||||||
|
{
|
||||||
|
if (ti->Desktop == DesktopObject->DesktopInfo)
|
||||||
|
{
|
||||||
|
ti->Desktop = NULL;
|
||||||
|
ti->DesktopHeapDelta = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
IntMapDesktopView(IN PDESKTOP_OBJECT DesktopObject)
|
||||||
|
{
|
||||||
|
PW32THREADINFO ti;
|
||||||
|
PW32HEAP_USER_MAPPING HeapMapping, *PrevLink = &PsGetWin32Process()->HeapMappings.Next;
|
||||||
|
PVOID UserBase = NULL;
|
||||||
|
ULONG ViewSize = 0;
|
||||||
|
LARGE_INTEGER Offset;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* find out if another thread already mapped the desktop heap */
|
||||||
|
HeapMapping = *PrevLink;
|
||||||
|
while (HeapMapping != NULL)
|
||||||
|
{
|
||||||
|
if (HeapMapping->KernelMapping == (PVOID)DesktopObject->hDesktopHeap)
|
||||||
|
{
|
||||||
|
HeapMapping->Count++;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrevLink = &HeapMapping->Next;
|
||||||
|
HeapMapping = HeapMapping->Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we're the first, map the heap */
|
||||||
|
Offset.QuadPart = 0;
|
||||||
|
Status = MmMapViewOfSection(DesktopObject->DesktopHeapSection,
|
||||||
|
PsGetCurrentProcess(),
|
||||||
|
&UserBase,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
&Offset,
|
||||||
|
&ViewSize,
|
||||||
|
ViewUnmap,
|
||||||
|
SEC_NO_CHANGE,
|
||||||
|
PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but thanks to RTL heaps... */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Failed to map desktop\n");
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the mapping */
|
||||||
|
HeapMapping = UserHeapAlloc(sizeof(W32HEAP_USER_MAPPING));
|
||||||
|
if (HeapMapping == NULL)
|
||||||
|
{
|
||||||
|
MmUnmapViewOfSection(PsGetCurrentProcess(),
|
||||||
|
UserBase);
|
||||||
|
return STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
HeapMapping->Next = NULL;
|
||||||
|
HeapMapping->KernelMapping = (PVOID)DesktopObject->hDesktopHeap;
|
||||||
|
HeapMapping->UserMapping = UserBase;
|
||||||
|
HeapMapping->Count = 1;
|
||||||
|
|
||||||
|
ObReferenceObject(DesktopObject);
|
||||||
|
|
||||||
|
/* create a W32THREADINFO structure if not already done, or update it */
|
||||||
|
ti = GetW32ThreadInfo();
|
||||||
|
if (ti != NULL)
|
||||||
|
{
|
||||||
|
if (ti->Desktop == NULL)
|
||||||
|
{
|
||||||
|
ti->Desktop = DesktopObject->DesktopInfo;
|
||||||
|
ti->DesktopHeapDelta = DesktopHeapGetUserDelta();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
IntSetThreadDesktop(IN PDESKTOP_OBJECT DesktopObject)
|
||||||
|
{
|
||||||
|
PDESKTOP_OBJECT OldDesktop;
|
||||||
|
PW32THREAD W32Thread;
|
||||||
|
NTSTATUS Status;
|
||||||
|
BOOL MapHeap;
|
||||||
|
|
||||||
|
MapHeap = (PsGetCurrentProcess() != PsInitialSystemProcess);
|
||||||
|
W32Thread = PsGetWin32Thread();
|
||||||
|
|
||||||
|
if (W32Thread->Desktop != DesktopObject)
|
||||||
|
{
|
||||||
|
OldDesktop = W32Thread->Desktop;
|
||||||
|
|
||||||
|
W32Thread->Desktop = DesktopObject;
|
||||||
|
|
||||||
|
if (MapHeap && DesktopObject != NULL)
|
||||||
|
{
|
||||||
|
Status = IntMapDesktopView(DesktopObject);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastNtError(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DesktopObject != NULL)
|
||||||
|
{
|
||||||
|
ObReferenceObject(DesktopObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OldDesktop != NULL)
|
||||||
|
{
|
||||||
|
if (MapHeap)
|
||||||
|
{
|
||||||
|
IntUnmapDesktopView(OldDesktop);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(OldDesktop);
|
||||||
|
|
||||||
|
if (W32Thread != NULL && W32Thread->ThreadInfo != NULL &&
|
||||||
|
W32Thread->ThreadInfo->Desktop != (DesktopObject != NULL ? DesktopObject->DesktopInfo : NULL))
|
||||||
|
{
|
||||||
|
if (DesktopObject != NULL)
|
||||||
|
{
|
||||||
|
W32Thread->ThreadInfo->Desktop = DesktopObject->DesktopInfo;
|
||||||
|
W32Thread->ThreadInfo->DesktopHeapDelta = DesktopHeapGetUserDelta();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
W32Thread->ThreadInfo->Desktop = NULL;
|
||||||
|
W32Thread->ThreadInfo->DesktopHeapDelta = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NtUserSetThreadDesktop
|
* NtUserSetThreadDesktop
|
||||||
*
|
*
|
||||||
|
@ -1570,7 +1794,6 @@ CLEANUP:
|
||||||
BOOL STDCALL
|
BOOL STDCALL
|
||||||
NtUserSetThreadDesktop(HDESK hDesktop)
|
NtUserSetThreadDesktop(HDESK hDesktop)
|
||||||
{
|
{
|
||||||
PW32THREAD W32Thread;
|
|
||||||
PDESKTOP_OBJECT DesktopObject;
|
PDESKTOP_OBJECT DesktopObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
DECLARE_RETURN(BOOL);
|
DECLARE_RETURN(BOOL);
|
||||||
|
@ -1591,18 +1814,13 @@ NtUserSetThreadDesktop(HDESK hDesktop)
|
||||||
RETURN(FALSE);
|
RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
W32Thread = PsGetWin32Thread();
|
|
||||||
|
|
||||||
/* FIXME: Should check here to see if the thread has any windows. */
|
/* FIXME: Should check here to see if the thread has any windows. */
|
||||||
|
|
||||||
if (W32Thread->Desktop != NULL)
|
if (!IntSetThreadDesktop(DesktopObject))
|
||||||
{
|
{
|
||||||
ObDereferenceObject(W32Thread->Desktop);
|
RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
W32Thread->Desktop = DesktopObject;
|
|
||||||
W32Thread->hDesktop = hDesktop;
|
|
||||||
|
|
||||||
RETURN(TRUE);
|
RETURN(TRUE);
|
||||||
|
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
|
|
|
@ -69,7 +69,7 @@ PHOOK FASTCALL IntGetHookObject(HHOOK hHook)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hook = (PHOOK)UserGetObject(&gHandleTable, hHook, otHook);
|
Hook = (PHOOK)UserGetObject(gHandleTable, hHook, otHook);
|
||||||
if (!Hook)
|
if (!Hook)
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE);
|
SetLastWin32Error(ERROR_INVALID_HOOK_HANDLE);
|
||||||
|
@ -110,7 +110,7 @@ IntAddHook(PETHREAD Thread, int HookId, BOOLEAN Global, PWINSTATION_OBJECT WinSt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hook = ObmCreateObject(&gHandleTable, &Handle, otHook, sizeof(HOOK));
|
Hook = ObmCreateObject(gHandleTable, &Handle, otHook, sizeof(HOOK));
|
||||||
if (NULL == Hook)
|
if (NULL == Hook)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -127,7 +127,7 @@ PMENU_OBJECT FASTCALL UserGetMenuObject(HMENU hMenu)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu = (PMENU_OBJECT)UserGetObject(&gHandleTable, hMenu, otMenu);
|
Menu = (PMENU_OBJECT)UserGetObject(gHandleTable, hMenu, otMenu);
|
||||||
if (!Menu)
|
if (!Menu)
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
|
SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
|
||||||
|
@ -310,7 +310,7 @@ IntCreateMenu(PHANDLE Handle, BOOL IsMenuBar)
|
||||||
PMENU_OBJECT Menu;
|
PMENU_OBJECT Menu;
|
||||||
|
|
||||||
Menu = (PMENU_OBJECT)ObmCreateObject(
|
Menu = (PMENU_OBJECT)ObmCreateObject(
|
||||||
&gHandleTable, Handle,
|
gHandleTable, Handle,
|
||||||
otMenu, sizeof(MENU_OBJECT));
|
otMenu, sizeof(MENU_OBJECT));
|
||||||
|
|
||||||
if(!Menu)
|
if(!Menu)
|
||||||
|
@ -419,7 +419,7 @@ IntCloneMenu(PMENU_OBJECT Source)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
Menu = (PMENU_OBJECT)ObmCreateObject(
|
Menu = (PMENU_OBJECT)ObmCreateObject(
|
||||||
&gHandleTable, &hMenu,
|
gHandleTable, &hMenu,
|
||||||
otMenu, sizeof(MENU_OBJECT));
|
otMenu, sizeof(MENU_OBJECT));
|
||||||
|
|
||||||
if(!Menu)
|
if(!Menu)
|
||||||
|
|
|
@ -378,28 +378,9 @@ NtUserDispatchMessage(PNTUSERDISPATCHMESSAGEINFO UnsafeMsgInfo)
|
||||||
|
|
||||||
MsgInfo.HandledByKernel = FALSE;
|
MsgInfo.HandledByKernel = FALSE;
|
||||||
Result = 0;
|
Result = 0;
|
||||||
if (0xFFFF0000 != ((DWORD) Window->WndProcW & 0xFFFF0000))
|
|
||||||
{
|
MsgInfo.Ansi = !Window->Unicode;
|
||||||
if (0xFFFF0000 != ((DWORD) Window->WndProcA & 0xFFFF0000))
|
MsgInfo.Proc = Window->WndProc;
|
||||||
{
|
|
||||||
/* Both Unicode and Ansi winprocs are real, use whatever
|
|
||||||
usermode prefers */
|
|
||||||
MsgInfo.Proc = (MsgInfo.Ansi ? Window->WndProcA
|
|
||||||
: Window->WndProcW);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Real Unicode winproc */
|
|
||||||
MsgInfo.Ansi = FALSE;
|
|
||||||
MsgInfo.Proc = Window->WndProcW;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Must have real Ansi winproc */
|
|
||||||
MsgInfo.Ansi = TRUE;
|
|
||||||
MsgInfo.Proc = Window->WndProcA;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -615,7 +596,7 @@ co_IntTranslateMouseMessage(PUSER_MESSAGE_QUEUE ThreadQueue, LPMSG Msg, USHORT *
|
||||||
{
|
{
|
||||||
/* generate double click messages, if necessary */
|
/* generate double click messages, if necessary */
|
||||||
if ((((*HitTest) != HTCLIENT) ||
|
if ((((*HitTest) != HTCLIENT) ||
|
||||||
(IntGetClassLong(Window, GCL_STYLE, FALSE) & CS_DBLCLKS)) &&
|
(Window->Class->Style & CS_DBLCLKS)) &&
|
||||||
MsqIsDblClk(Msg, Remove))
|
MsqIsDblClk(Msg, Remove))
|
||||||
{
|
{
|
||||||
Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
|
Msg->message += WM_LBUTTONDBLCLK - WM_LBUTTONDOWN;
|
||||||
|
@ -1401,16 +1382,9 @@ co_IntSendMessageTimeoutSingle(HWND hWnd,
|
||||||
DPRINT1("Failed to pack message parameters\n");
|
DPRINT1("Failed to pack message parameters\n");
|
||||||
RETURN( FALSE);
|
RETURN( FALSE);
|
||||||
}
|
}
|
||||||
if (0xFFFF0000 != ((DWORD) Window->WndProcW & 0xFFFF0000))
|
|
||||||
{
|
Result = (ULONG_PTR)co_IntCallWindowProc(Window->WndProc, !Window->Unicode, hWnd, Msg, wParam,
|
||||||
Result = (ULONG_PTR)co_IntCallWindowProc(Window->WndProcW, FALSE, hWnd, Msg, wParam,
|
lParamPacked,lParamBufferSize);
|
||||||
lParamPacked,lParamBufferSize);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Result = (ULONG_PTR)co_IntCallWindowProc(Window->WndProcA, TRUE, hWnd, Msg, wParam,
|
|
||||||
lParamPacked,lParamBufferSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(uResult)
|
if(uResult)
|
||||||
{
|
{
|
||||||
|
@ -1580,32 +1554,16 @@ co_IntDoSendMessage(HWND hWnd,
|
||||||
{
|
{
|
||||||
/* Gather the information usermode needs to call the window proc directly */
|
/* Gather the information usermode needs to call the window proc directly */
|
||||||
Info.HandledByKernel = FALSE;
|
Info.HandledByKernel = FALSE;
|
||||||
if (0xFFFF0000 != ((DWORD) Window->WndProcW & 0xFFFF0000))
|
|
||||||
|
Status = MmCopyFromCaller(&(Info.Ansi), &(UnsafeInfo->Ansi),
|
||||||
|
sizeof(BOOL));
|
||||||
|
if (! NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
if (0xFFFF0000 != ((DWORD) Window->WndProcA & 0xFFFF0000))
|
Info.Ansi = ! Window->Unicode;
|
||||||
{
|
|
||||||
/* Both Unicode and Ansi winprocs are real, see what usermode prefers */
|
|
||||||
Status = MmCopyFromCaller(&(Info.Ansi), &(UnsafeInfo->Ansi),
|
|
||||||
sizeof(BOOL));
|
|
||||||
if (! NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
Info.Ansi = ! Window->Unicode;
|
|
||||||
}
|
|
||||||
Info.Proc = (Info.Ansi ? Window->WndProcA : Window->WndProcW);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Real Unicode winproc */
|
|
||||||
Info.Ansi = FALSE;
|
|
||||||
Info.Proc = Window->WndProcW;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Must have real Ansi winproc */
|
|
||||||
Info.Ansi = TRUE;
|
|
||||||
Info.Proc = Window->WndProcA;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Info.Ansi = !Window->Unicode;
|
||||||
|
Info.Proc = Window->WndProc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -886,11 +886,22 @@ NtUserGetThreadState(
|
||||||
DECLARE_RETURN(DWORD);
|
DECLARE_RETURN(DWORD);
|
||||||
|
|
||||||
DPRINT("Enter NtUserGetThreadState\n");
|
DPRINT("Enter NtUserGetThreadState\n");
|
||||||
UserEnterShared();
|
if (Routine != THREADSTATE_GETTHREADINFO)
|
||||||
|
{
|
||||||
|
UserEnterShared();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UserEnterExclusive();
|
||||||
|
}
|
||||||
|
|
||||||
switch (Routine)
|
switch (Routine)
|
||||||
{
|
{
|
||||||
case 0:
|
case THREADSTATE_GETTHREADINFO:
|
||||||
|
GetW32ThreadInfo();
|
||||||
|
RETURN(0);
|
||||||
|
|
||||||
|
case THREADSTATE_FOCUSWINDOW:
|
||||||
RETURN( (DWORD)IntGetThreadFocusWindow());
|
RETURN( (DWORD)IntGetThreadFocusWindow());
|
||||||
}
|
}
|
||||||
RETURN( 0);
|
RETURN( 0);
|
||||||
|
@ -1829,4 +1840,106 @@ CLEANUP:
|
||||||
END_CLEANUP;
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PW32PROCESSINFO
|
||||||
|
GetW32ProcessInfo(VOID)
|
||||||
|
{
|
||||||
|
PW32PROCESSINFO pi;
|
||||||
|
PW32PROCESS W32Process = PsGetWin32Process();
|
||||||
|
|
||||||
|
if (W32Process == NULL)
|
||||||
|
{
|
||||||
|
/* FIXME - temporary hack for system threads... */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (W32Process->ProcessInfo == NULL)
|
||||||
|
{
|
||||||
|
pi = UserHeapAlloc(sizeof(W32PROCESSINFO));
|
||||||
|
if (pi != NULL)
|
||||||
|
{
|
||||||
|
RtlZeroMemory(pi,
|
||||||
|
sizeof(W32PROCESSINFO));
|
||||||
|
|
||||||
|
/* initialize it */
|
||||||
|
pi->UserHandleTable = gHandleTable;
|
||||||
|
|
||||||
|
if (InterlockedCompareExchangePointer(&W32Process->ProcessInfo,
|
||||||
|
pi,
|
||||||
|
NULL) != NULL)
|
||||||
|
{
|
||||||
|
UserHeapFree(pi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return W32Process->ProcessInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
PW32THREADINFO
|
||||||
|
GetW32ThreadInfo(VOID)
|
||||||
|
{
|
||||||
|
PTEB Teb;
|
||||||
|
PW32THREADINFO ti;
|
||||||
|
PW32THREAD W32Thread = PsGetWin32Thread();
|
||||||
|
|
||||||
|
if (W32Thread == NULL)
|
||||||
|
{
|
||||||
|
/* FIXME - temporary hack for system threads... */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* allocate a W32THREAD structure if neccessary */
|
||||||
|
if (W32Thread->ThreadInfo == NULL)
|
||||||
|
{
|
||||||
|
ti = UserHeapAlloc(sizeof(W32THREADINFO));
|
||||||
|
if (ti != NULL)
|
||||||
|
{
|
||||||
|
RtlZeroMemory(ti,
|
||||||
|
sizeof(W32THREADINFO));
|
||||||
|
|
||||||
|
/* initialize it */
|
||||||
|
ti->kpi = GetW32ProcessInfo();
|
||||||
|
ti->pi = UserHeapAddressToUser(ti->kpi);
|
||||||
|
if (W32Thread->Desktop != NULL)
|
||||||
|
{
|
||||||
|
ti->Desktop = W32Thread->Desktop->DesktopInfo;
|
||||||
|
ti->DesktopHeapDelta = DesktopHeapGetUserDelta();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ti->Desktop = NULL;
|
||||||
|
ti->DesktopHeapDelta = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
W32Thread->ThreadInfo = ti;
|
||||||
|
/* update the TEB */
|
||||||
|
Teb = NtCurrentTeb();
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
ProbeForWrite(Teb,
|
||||||
|
sizeof(TEB),
|
||||||
|
sizeof(ULONG));
|
||||||
|
|
||||||
|
Teb->Win32ThreadInfo = UserHeapAddressToUser(W32Thread->ThreadInfo);
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
SetLastNtError(_SEH_GetExceptionCode());
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return W32Thread->ThreadInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -89,7 +89,7 @@ IntCreateMonitorObject()
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
PMONITOR_OBJECT Monitor;
|
PMONITOR_OBJECT Monitor;
|
||||||
|
|
||||||
Monitor = ObmCreateObject(&gHandleTable, &Handle, otMonitor, sizeof (MONITOR_OBJECT));
|
Monitor = ObmCreateObject(gHandleTable, &Handle, otMonitor, sizeof (MONITOR_OBJECT));
|
||||||
if (Monitor == NULL)
|
if (Monitor == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -133,7 +133,7 @@ UserGetMonitorObject(IN HMONITOR hMonitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Monitor = (PMONITOR_OBJECT)UserGetObject(&gHandleTable, hMonitor, otMonitor);
|
Monitor = (PMONITOR_OBJECT)UserGetObject(gHandleTable, hMonitor, otMonitor);
|
||||||
if (!Monitor)
|
if (!Monitor)
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE);
|
SetLastWin32Error(ERROR_INVALID_MONITOR_HANDLE);
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
int usedHandles=0;
|
int usedHandles=0;
|
||||||
USER_HANDLE_TABLE gHandleTable;
|
PUSER_HANDLE_TABLE gHandleTable = NULL;
|
||||||
|
|
||||||
|
|
||||||
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle )
|
PUSER_HANDLE_ENTRY handle_to_entry(PUSER_HANDLE_TABLE ht, HANDLE handle )
|
||||||
|
@ -71,19 +71,17 @@ __inline static PUSER_HANDLE_ENTRY alloc_user_entry(PUSER_HANDLE_TABLE ht)
|
||||||
DPRINT1("Out of user handles!\n");
|
DPRINT1("Out of user handles!\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
#if 0
|
#if 0
|
||||||
|
PUSER_HANDLE_ENTRY new_handles;
|
||||||
struct user_handle *new_handles;
|
|
||||||
/* grow array by 50% (but at minimum 32 entries) */
|
/* grow array by 50% (but at minimum 32 entries) */
|
||||||
int growth = max( 32, allocated_handles / 2 );
|
int growth = max( 32, ht->allocated_handles / 2 );
|
||||||
int new_size = min( allocated_handles + growth, (LAST_USER_HANDLE-FIRST_USER_HANDLE+1) >> 1 );
|
int new_size = min( ht->allocated_handles + growth, (LAST_USER_HANDLE-FIRST_USER_HANDLE+1) >> 1 );
|
||||||
if (new_size <= allocated_handles)
|
if (new_size <= ht->allocated_handles)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!(new_handles = realloc( handles, new_size * sizeof(*handles) )))
|
if (!(new_handles = UserHeapReAlloc( ht->handles, new_size * sizeof(*ht->handles) )))
|
||||||
return NULL;
|
return NULL;
|
||||||
handles = new_handles;
|
ht->handles = new_handles;
|
||||||
allocated_handles = new_size;
|
ht->allocated_handles = new_size;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = &ht->handles[ht->nb_handles++];
|
entry = &ht->handles[ht->nb_handles++];
|
||||||
|
@ -217,7 +215,7 @@ ObmCreateObject(PUSER_HANDLE_TABLE ht, HANDLE* h,USER_OBJECT_TYPE type , ULONG s
|
||||||
{
|
{
|
||||||
|
|
||||||
HANDLE hi;
|
HANDLE hi;
|
||||||
PUSER_OBJECT_HEADER hdr = ExAllocatePool(PagedPool, size + sizeof(USER_OBJECT_HEADER));
|
PUSER_OBJECT_HEADER hdr = UserHeapAlloc(size + sizeof(USER_OBJECT_HEADER));//ExAllocatePool(PagedPool, size + sizeof(USER_OBJECT_HEADER));
|
||||||
if (!hdr)
|
if (!hdr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -225,7 +223,8 @@ ObmCreateObject(PUSER_HANDLE_TABLE ht, HANDLE* h,USER_OBJECT_TYPE type , ULONG s
|
||||||
hi = UserAllocHandle(ht, USER_HEADER_TO_BODY(hdr), type );
|
hi = UserAllocHandle(ht, USER_HEADER_TO_BODY(hdr), type );
|
||||||
if (!hi)
|
if (!hi)
|
||||||
{
|
{
|
||||||
ExFreePool(hdr);
|
//ExFreePool(hdr);
|
||||||
|
UserHeapFree(hdr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,7 +241,7 @@ BOOL FASTCALL
|
||||||
ObmDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
|
ObmDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
|
||||||
{
|
{
|
||||||
PUSER_OBJECT_HEADER hdr;
|
PUSER_OBJECT_HEADER hdr;
|
||||||
PVOID body = UserGetObject(&gHandleTable, h, type);
|
PVOID body = UserGetObject(gHandleTable, h, type);
|
||||||
if (!body)
|
if (!body)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -252,11 +251,12 @@ ObmDeleteObject(HANDLE h, USER_OBJECT_TYPE type )
|
||||||
hdr->destroyed = TRUE;
|
hdr->destroyed = TRUE;
|
||||||
if (hdr->RefCount == 0)
|
if (hdr->RefCount == 0)
|
||||||
{
|
{
|
||||||
UserFreeHandle(&gHandleTable, h);
|
UserFreeHandle(gHandleTable, h);
|
||||||
|
|
||||||
memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
|
memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
|
||||||
|
|
||||||
ExFreePool(hdr);
|
UserHeapFree(hdr);
|
||||||
|
//ExFreePool(hdr);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,6 +274,12 @@ VOID FASTCALL ObmReferenceObject(PVOID obj)
|
||||||
hdr->RefCount++;
|
hdr->RefCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HANDLE FASTCALL ObmObjectToHandle(PVOID obj)
|
||||||
|
{
|
||||||
|
PUSER_OBJECT_HEADER hdr = USER_BODY_TO_HEADER(obj);
|
||||||
|
return hdr->hSelf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL FASTCALL ObmDereferenceObject2(PVOID obj)
|
BOOL FASTCALL ObmDereferenceObject2(PVOID obj)
|
||||||
{
|
{
|
||||||
|
@ -287,11 +293,12 @@ BOOL FASTCALL ObmDereferenceObject2(PVOID obj)
|
||||||
{
|
{
|
||||||
// DPRINT1("info: something destroyed bcaise of deref, in use=%i\n",usedHandles);
|
// DPRINT1("info: something destroyed bcaise of deref, in use=%i\n",usedHandles);
|
||||||
|
|
||||||
UserFreeHandle(&gHandleTable, hdr->hSelf);
|
UserFreeHandle(gHandleTable, hdr->hSelf);
|
||||||
|
|
||||||
memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
|
memset(hdr, 0x55, sizeof(USER_OBJECT_HEADER));
|
||||||
|
|
||||||
ExFreePool(hdr);
|
UserHeapFree(hdr);
|
||||||
|
//ExFreePool(hdr);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -307,15 +314,24 @@ BOOL FASTCALL ObmCreateHandleTable()
|
||||||
PVOID mem;
|
PVOID mem;
|
||||||
|
|
||||||
//FIXME: dont alloc all at once! must be mapped into umode also...
|
//FIXME: dont alloc all at once! must be mapped into umode also...
|
||||||
mem = ExAllocatePool(PagedPool, sizeof(USER_HANDLE_ENTRY) * 1024*2);
|
//mem = ExAllocatePool(PagedPool, sizeof(USER_HANDLE_ENTRY) * 1024*2);
|
||||||
|
mem = UserHeapAlloc(sizeof(USER_HANDLE_ENTRY) * 1024*2);
|
||||||
if (!mem)
|
if (!mem)
|
||||||
{
|
{
|
||||||
DPRINT1("Failed creating handle table\n");
|
DPRINT1("Failed creating handle table\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gHandleTable = UserHeapAlloc(sizeof(USER_HANDLE_TABLE));
|
||||||
|
if (gHandleTable == NULL)
|
||||||
|
{
|
||||||
|
UserHeapFree(mem);
|
||||||
|
DPRINT1("Failed creating handle table\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
//FIXME: make auto growable
|
//FIXME: make auto growable
|
||||||
UserInitHandleTable(&gHandleTable, mem, sizeof(USER_HANDLE_ENTRY) * 1024*2);
|
UserInitHandleTable(gHandleTable, mem, sizeof(USER_HANDLE_ENTRY) * 1024*2);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -353,7 +353,7 @@ UserGetDCEx(PWINDOW_OBJECT Window OPTIONAL, HANDLE ClipRegion, ULONG Flags)
|
||||||
|
|
||||||
if (!(Flags & DCX_WINDOW))
|
if (!(Flags & DCX_WINDOW))
|
||||||
{
|
{
|
||||||
if (Window->Class->style & CS_PARENTDC)
|
if (Window->Class->Style & CS_PARENTDC)
|
||||||
{
|
{
|
||||||
Flags |= DCX_PARENTCLIP;
|
Flags |= DCX_PARENTCLIP;
|
||||||
}
|
}
|
||||||
|
@ -676,7 +676,7 @@ DceFreeWindowDCE(PWINDOW_OBJECT Window)
|
||||||
{
|
{
|
||||||
if (pDCE == Window->Dce) /* owned or Class DCE*/
|
if (pDCE == Window->Dce) /* owned or Class DCE*/
|
||||||
{
|
{
|
||||||
if (Window->Class->style & CS_OWNDC) /* owned DCE*/
|
if (Window->Class->Style & CS_OWNDC) /* owned DCE*/
|
||||||
{
|
{
|
||||||
pDCE = DceFreeDCE(pDCE, FALSE);
|
pDCE = DceFreeDCE(pDCE, FALSE);
|
||||||
Window->Dce = NULL;
|
Window->Dce = NULL;
|
||||||
|
|
|
@ -33,10 +33,6 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
static WndProcHandle *WndProcHandlesArray = 0;
|
|
||||||
static WORD WndProcHandlesArraySize = 0;
|
|
||||||
#define WPH_SIZE 0x40 /* the size to add to the WndProcHandle array each time */
|
|
||||||
|
|
||||||
/* dialog resources appear to pass this in 16 bits, handle them properly */
|
/* dialog resources appear to pass this in 16 bits, handle them properly */
|
||||||
#define CW_USEDEFAULT16 (0x8000)
|
#define CW_USEDEFAULT16 (0x8000)
|
||||||
|
|
||||||
|
@ -53,8 +49,6 @@ static WORD WndProcHandlesArraySize = 0;
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
InitWindowImpl(VOID)
|
InitWindowImpl(VOID)
|
||||||
{
|
{
|
||||||
WndProcHandlesArray = ExAllocatePoolWithTag(PagedPool,WPH_SIZE * sizeof(WndProcHandle), TAG_WINPROCLST);
|
|
||||||
WndProcHandlesArraySize = WPH_SIZE;
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,9 +61,6 @@ InitWindowImpl(VOID)
|
||||||
NTSTATUS FASTCALL
|
NTSTATUS FASTCALL
|
||||||
CleanupWindowImpl(VOID)
|
CleanupWindowImpl(VOID)
|
||||||
{
|
{
|
||||||
ExFreePool(WndProcHandlesArray);
|
|
||||||
WndProcHandlesArray = 0;
|
|
||||||
WndProcHandlesArraySize = 0;
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,15 +86,26 @@ PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
|
||||||
/* temp hack */
|
/* temp hack */
|
||||||
PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
|
PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
|
||||||
{
|
{
|
||||||
|
PW32THREADINFO ti;
|
||||||
PWINDOW_OBJECT Window;
|
PWINDOW_OBJECT Window;
|
||||||
|
|
||||||
|
if (PsGetCurrentProcess() != PsInitialSystemProcess)
|
||||||
|
{
|
||||||
|
ti = GetW32ThreadInfo();
|
||||||
|
if (ti == NULL)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!hWnd)
|
if (!hWnd)
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window = (PWINDOW_OBJECT)UserGetObject(&gHandleTable, hWnd, otWindow);
|
Window = (PWINDOW_OBJECT)UserGetObject(gHandleTable, hWnd, otWindow);
|
||||||
if (!Window || 0 != (Window->Status & WINDOWSTATUS_DESTROYED))
|
if (!Window || 0 != (Window->Status & WINDOWSTATUS_DESTROYED))
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
||||||
|
@ -432,8 +434,16 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
|
||||||
|
|
||||||
IntDestroyScrollBars(Window);
|
IntDestroyScrollBars(Window);
|
||||||
|
|
||||||
|
if (!Window->Class->System && Window->CallProc != NULL)
|
||||||
|
{
|
||||||
|
DestroyCallProc(Window->ti->Desktop,
|
||||||
|
Window->CallProc);
|
||||||
|
}
|
||||||
|
|
||||||
/* dereference the class */
|
/* dereference the class */
|
||||||
ClassDerefObject(Window->Class);
|
IntDereferenceClass(Window->Class,
|
||||||
|
Window->ti->Desktop,
|
||||||
|
Window->ti->kpi);
|
||||||
Window->Class = NULL;
|
Window->Class = NULL;
|
||||||
|
|
||||||
if(Window->WindowRegion)
|
if(Window->WindowRegion)
|
||||||
|
@ -475,6 +485,57 @@ IntGetWindowBorderMeasures(PWINDOW_OBJECT Window, UINT *cx, UINT *cy)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WNDPROC
|
||||||
|
IntGetWindowProc(IN PWINDOW_OBJECT Window,
|
||||||
|
IN BOOL Ansi)
|
||||||
|
{
|
||||||
|
if (Window->IsSystem)
|
||||||
|
{
|
||||||
|
return (Ansi ? Window->WndProcExtra : Window->WndProc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!Ansi == Window->Unicode)
|
||||||
|
{
|
||||||
|
return Window->WndProc;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Window->CallProc != NULL)
|
||||||
|
{
|
||||||
|
return (WNDPROC)ObmObjectToHandle(Window->CallProc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PCALLPROC NewCallProc, CallProc;
|
||||||
|
|
||||||
|
/* NOTE: use the interlocked functions, as this operation may be done even
|
||||||
|
when only the shared lock is held! */
|
||||||
|
NewCallProc = CreateCallProc(Window->ti->Desktop,
|
||||||
|
Window->WndProc,
|
||||||
|
Window->Unicode,
|
||||||
|
Window->ti->kpi);
|
||||||
|
if (NewCallProc == NULL)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CallProc = InterlockedCompareExchangePointer(&Window->CallProc,
|
||||||
|
NewCallProc,
|
||||||
|
NULL);
|
||||||
|
if (CallProc != NULL)
|
||||||
|
{
|
||||||
|
DestroyCallProc(Window->ti->Desktop,
|
||||||
|
NewCallProc);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (WNDPROC)ObmObjectToHandle((CallProc == NULL ? NewCallProc : CallProc));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
|
IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
|
||||||
{
|
{
|
||||||
|
@ -1333,7 +1394,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
BOOL bUnicodeWindow)
|
BOOL bUnicodeWindow)
|
||||||
{
|
{
|
||||||
PWINSTATION_OBJECT WinSta;
|
PWINSTATION_OBJECT WinSta;
|
||||||
PWNDCLASS_OBJECT Class = NULL;
|
PWINDOWCLASS Class = NULL;
|
||||||
|
RTL_ATOM ClassAtom;
|
||||||
PWINDOW_OBJECT Window = NULL;
|
PWINDOW_OBJECT Window = NULL;
|
||||||
PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
|
PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
|
||||||
HWND ParentWindowHandle;
|
HWND ParentWindowHandle;
|
||||||
|
@ -1342,6 +1404,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
POINT Pos;
|
POINT Pos;
|
||||||
SIZE Size;
|
SIZE Size;
|
||||||
|
PW32THREADINFO ti = NULL;
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
POINT MaxSize, MaxPos, MinTrack, MaxTrack;
|
POINT MaxSize, MaxPos, MinTrack, MaxTrack;
|
||||||
|
@ -1349,7 +1412,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
|
|
||||||
POINT MaxPos;
|
POINT MaxPos;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CREATESTRUCTW Cs;
|
CREATESTRUCTW Cs;
|
||||||
CBT_CREATEWNDW CbtCreate;
|
CBT_CREATEWNDW CbtCreate;
|
||||||
LRESULT Result;
|
LRESULT Result;
|
||||||
|
@ -1399,13 +1461,27 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
|
|
||||||
/* FIXME: parent must belong to the current process */
|
/* FIXME: parent must belong to the current process */
|
||||||
|
|
||||||
|
/* Check the window station. */
|
||||||
|
ti = GetW32ThreadInfo();
|
||||||
|
if (ti == NULL || PsGetWin32Thread()->Desktop == NULL)
|
||||||
|
{
|
||||||
|
DPRINT1("Thread is not attached to a desktop! Cannot create window!\n");
|
||||||
|
RETURN( (HWND)0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check the class. */
|
/* Check the class. */
|
||||||
Class = ClassGetClassByNameOrAtom(ClassName->Buffer, hInstance);
|
|
||||||
if (!Class)
|
ClassAtom = IntGetClassAtom(ClassName,
|
||||||
|
hInstance,
|
||||||
|
ti->kpi,
|
||||||
|
&Class,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
if (ClassAtom == (RTL_ATOM)0)
|
||||||
{
|
{
|
||||||
if (IS_ATOM(ClassName->Buffer))
|
if (IS_ATOM(ClassName->Buffer))
|
||||||
{
|
{
|
||||||
DPRINT1("Class 0x%x not found\n", (DWORD_PTR) ClassName->Buffer);
|
DPRINT1("Class 0x%p not found\n", (DWORD_PTR) ClassName->Buffer);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1416,14 +1492,14 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
RETURN((HWND)0);
|
RETURN((HWND)0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassRefObject(Class);
|
Class = IntReferenceClass(Class,
|
||||||
|
ti->Desktop);
|
||||||
/* Check the window station. */
|
if (Class == NULL)
|
||||||
if (PsGetWin32Thread()->Desktop == NULL)
|
|
||||||
{
|
{
|
||||||
DPRINT("Thread is not attached to a desktop! Cannot create window!\n");
|
DPRINT1("Failed to reference window class!\n");
|
||||||
RETURN( (HWND)0);
|
RETURN(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
WinSta = PsGetWin32Thread()->Desktop->WindowStation;
|
WinSta = PsGetWin32Thread()->Desktop->WindowStation;
|
||||||
|
|
||||||
//FIXME: Reference thread/desktop instead
|
//FIXME: Reference thread/desktop instead
|
||||||
|
@ -1431,8 +1507,8 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
|
|
||||||
/* Create the window object. */
|
/* Create the window object. */
|
||||||
Window = (PWINDOW_OBJECT)
|
Window = (PWINDOW_OBJECT)
|
||||||
ObmCreateObject(&gHandleTable, (PHANDLE)&hWnd,
|
ObmCreateObject(gHandleTable, (PHANDLE)&hWnd,
|
||||||
otWindow, sizeof(WINDOW_OBJECT) + Class->cbWndExtra
|
otWindow, sizeof(WINDOW_OBJECT) + Class->WndExtra
|
||||||
);
|
);
|
||||||
|
|
||||||
DPRINT("Created object with handle %X\n", hWnd);
|
DPRINT("Created object with handle %X\n", hWnd);
|
||||||
|
@ -1456,6 +1532,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
/*
|
/*
|
||||||
* Fill out the structure describing it.
|
* Fill out the structure describing it.
|
||||||
*/
|
*/
|
||||||
|
Window->ti = ti;
|
||||||
Window->Class = Class;
|
Window->Class = Class;
|
||||||
Window->SystemMenu = (HMENU)0;
|
Window->SystemMenu = (HMENU)0;
|
||||||
Window->ContextHelpId = 0;
|
Window->ContextHelpId = 0;
|
||||||
|
@ -1474,7 +1551,7 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
{
|
{
|
||||||
IntSetMenu(Window, hMenu, &MenuChanged);
|
IntSetMenu(Window, hMenu, &MenuChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
Window->MessageQueue = PsGetWin32Thread()->MessageQueue;
|
Window->MessageQueue = PsGetWin32Thread()->MessageQueue;
|
||||||
IntReferenceMessageQueue(Window->MessageQueue);
|
IntReferenceMessageQueue(Window->MessageQueue);
|
||||||
Window->Parent = ParentWindow;
|
Window->Parent = ParentWindow;
|
||||||
|
@ -1491,27 +1568,38 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
}
|
}
|
||||||
|
|
||||||
Window->UserData = 0;
|
Window->UserData = 0;
|
||||||
|
|
||||||
if ((((DWORD)Class->lpfnWndProcA & 0xFFFF0000) != 0xFFFF0000)
|
Window->IsSystem = Class->System;
|
||||||
&& (((DWORD)Class->lpfnWndProcW & 0xFFFF0000) != 0xFFFF0000))
|
if (Class->System)
|
||||||
{
|
{
|
||||||
Window->Unicode = bUnicodeWindow;
|
Window->Unicode = bUnicodeWindow;
|
||||||
|
if (bUnicodeWindow)
|
||||||
|
{
|
||||||
|
Window->WndProc = Class->WndProc;
|
||||||
|
Window->WndProcExtra = Class->WndProcExtra;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Window->WndProc = Class->WndProcExtra;
|
||||||
|
Window->WndProcExtra = Class->WndProc;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Window->Unicode = Class->Unicode;
|
Window->Unicode = Class->Unicode;
|
||||||
|
Window->WndProc = Class->WndProc;
|
||||||
|
Window->CallProc = NULL;
|
||||||
}
|
}
|
||||||
Window->WndProcA = Class->lpfnWndProcA;
|
|
||||||
Window->WndProcW = Class->lpfnWndProcW;
|
|
||||||
Window->OwnerThread = PsGetCurrentThread();
|
Window->OwnerThread = PsGetCurrentThread();
|
||||||
Window->FirstChild = NULL;
|
Window->FirstChild = NULL;
|
||||||
Window->LastChild = NULL;
|
Window->LastChild = NULL;
|
||||||
Window->PrevSibling = NULL;
|
Window->PrevSibling = NULL;
|
||||||
Window->NextSibling = NULL;
|
Window->NextSibling = NULL;
|
||||||
Window->ExtraDataSize = Class->cbWndExtra;
|
Window->ExtraDataSize = Class->WndExtra;
|
||||||
|
|
||||||
/* extra window data */
|
/* extra window data */
|
||||||
if (Class->cbWndExtra)
|
if (Class->WndExtra)
|
||||||
Window->ExtraData = (PCHAR)(Window + 1);
|
Window->ExtraData = (PCHAR)(Window + 1);
|
||||||
|
|
||||||
InitializeListHead(&Window->PropListHead);
|
InitializeListHead(&Window->PropListHead);
|
||||||
|
@ -1536,7 +1624,6 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
RtlInitUnicodeString(&Window->WindowName, NULL);
|
RtlInitUnicodeString(&Window->WindowName, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This has been tested for WS_CHILD | WS_VISIBLE. It has not been
|
* This has been tested for WS_CHILD | WS_VISIBLE. It has not been
|
||||||
* tested for WS_POPUP
|
* tested for WS_POPUP
|
||||||
|
@ -1931,7 +2018,15 @@ co_IntCreateWindowEx(DWORD dwExStyle,
|
||||||
CLEANUP:
|
CLEANUP:
|
||||||
if (Window) UserDerefObjectCo(Window);
|
if (Window) UserDerefObjectCo(Window);
|
||||||
if (ParentWindow) UserDerefObjectCo(ParentWindow);
|
if (ParentWindow) UserDerefObjectCo(ParentWindow);
|
||||||
if (!_ret_ && Class) ClassDerefObject(Class); /* only deref if failure (return 0) */
|
if (!_ret_ && ti != NULL)
|
||||||
|
{
|
||||||
|
if (Class != NULL)
|
||||||
|
{
|
||||||
|
IntDereferenceClass(Class,
|
||||||
|
ti->Desktop,
|
||||||
|
ti->kpi);
|
||||||
|
}
|
||||||
|
}
|
||||||
END_CLEANUP;
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1967,7 +2062,7 @@ NtUserCreateWindowEx(DWORD dwExStyle,
|
||||||
SetLastNtError(Status);
|
SetLastNtError(Status);
|
||||||
RETURN( NULL);
|
RETURN( NULL);
|
||||||
}
|
}
|
||||||
if (! IS_ATOM(ClassName.Buffer))
|
if (ClassName.Length != 0)
|
||||||
{
|
{
|
||||||
Status = IntSafeCopyUnicodeStringTerminateNULL(&ClassName, UnsafeClassName);
|
Status = IntSafeCopyUnicodeStringTerminateNULL(&ClassName, UnsafeClassName);
|
||||||
if (! NT_SUCCESS(Status))
|
if (! NT_SUCCESS(Status))
|
||||||
|
@ -1976,6 +2071,11 @@ NtUserCreateWindowEx(DWORD dwExStyle,
|
||||||
RETURN( NULL);
|
RETURN( NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (! IS_INTRESOURCE(ClassName.Buffer))
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* safely copy the window name */
|
/* safely copy the window name */
|
||||||
if (NULL != UnsafeWindowName)
|
if (NULL != UnsafeWindowName)
|
||||||
|
@ -3254,10 +3354,8 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GWL_WNDPROC:
|
case GWL_WNDPROC:
|
||||||
if (Ansi)
|
Result = (LONG)IntGetWindowProc(Window,
|
||||||
Result = (LONG) Window->WndProcA;
|
Ansi);
|
||||||
else
|
|
||||||
Result = (LONG) Window->WndProcW;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GWL_HINSTANCE:
|
case GWL_HINSTANCE:
|
||||||
|
@ -3390,22 +3488,28 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GWL_WNDPROC:
|
case GWL_WNDPROC:
|
||||||
|
{
|
||||||
/* FIXME: should check if window belongs to current process */
|
/* FIXME: should check if window belongs to current process */
|
||||||
if (Ansi)
|
if (Window->IsSystem)
|
||||||
{
|
{
|
||||||
OldValue = (LONG) Window->WndProcA;
|
/* the user changes the window procedure, the window is no longer
|
||||||
Window->WndProcA = (WNDPROC) NewValue;
|
directly derived from the system class, because it no longer
|
||||||
Window->WndProcW = (WNDPROC) IntAddWndProcHandle((WNDPROC)NewValue,FALSE);
|
uses independent window procedures for ansi and unicode */
|
||||||
Window->Unicode = FALSE;
|
Window->IsSystem = FALSE;
|
||||||
|
Window->CallProc = NULL;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
/* update the window procedure */
|
||||||
|
OldValue = (LONG)Window->WndProc;
|
||||||
|
Window->WndProc = (WNDPROC)NewValue;
|
||||||
|
if (Window->CallProc != NULL)
|
||||||
{
|
{
|
||||||
OldValue = (LONG) Window->WndProcW;
|
Window->CallProc->WndProc = (WNDPROC)NewValue;
|
||||||
Window->WndProcW = (WNDPROC) NewValue;
|
Window->CallProc->Unicode = !Ansi;
|
||||||
Window->WndProcA = (WNDPROC) IntAddWndProcHandle((WNDPROC)NewValue,TRUE);
|
|
||||||
Window->Unicode = TRUE;
|
|
||||||
}
|
}
|
||||||
|
Window->Unicode = !Ansi;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case GWL_HINSTANCE:
|
case GWL_HINSTANCE:
|
||||||
OldValue = (LONG) Window->Instance;
|
OldValue = (LONG) Window->Instance;
|
||||||
|
@ -4404,99 +4508,6 @@ CLEANUP:
|
||||||
END_CLEANUP;
|
END_CLEANUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD STDCALL
|
|
||||||
NtUserDereferenceWndProcHandle(WNDPROC wpHandle, WndProcHandle *Data)
|
|
||||||
{
|
|
||||||
DECLARE_RETURN(DWORD);
|
|
||||||
WndProcHandle Entry;
|
|
||||||
|
|
||||||
DPRINT("Enter NtUserDereferenceWndProcHandle\n");
|
|
||||||
UserEnterShared();
|
|
||||||
|
|
||||||
if (((DWORD)wpHandle & 0xFFFF0000) == 0xFFFF0000)
|
|
||||||
{
|
|
||||||
Entry = WndProcHandlesArray[(DWORD)wpHandle & 0x0000FFFF];
|
|
||||||
Data->WindowProc = Entry.WindowProc;
|
|
||||||
Data->IsUnicode = Entry.IsUnicode;
|
|
||||||
Data->ProcessID = Entry.ProcessID;
|
|
||||||
RETURN( TRUE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RETURN( FALSE);
|
|
||||||
}
|
|
||||||
RETURN( FALSE);
|
|
||||||
|
|
||||||
CLEANUP:
|
|
||||||
DPRINT("Leave NtUserDereferenceWndProcHandle, ret=%i\n",_ret_);
|
|
||||||
UserLeave();
|
|
||||||
END_CLEANUP;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD
|
|
||||||
IntAddWndProcHandle(WNDPROC WindowProc, BOOL IsUnicode)
|
|
||||||
{
|
|
||||||
WORD i;
|
|
||||||
WORD FreeSpot = 0;
|
|
||||||
BOOL found;
|
|
||||||
WndProcHandle *OldArray;
|
|
||||||
WORD OldArraySize;
|
|
||||||
found = FALSE;
|
|
||||||
for (i = 0;i < WndProcHandlesArraySize;i++)
|
|
||||||
{
|
|
||||||
if (WndProcHandlesArray[i].WindowProc == NULL)
|
|
||||||
{
|
|
||||||
FreeSpot = i;
|
|
||||||
found = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
{
|
|
||||||
OldArray = WndProcHandlesArray;
|
|
||||||
OldArraySize = WndProcHandlesArraySize;
|
|
||||||
WndProcHandlesArray = ExAllocatePoolWithTag(PagedPool,(OldArraySize + WPH_SIZE) * sizeof(WndProcHandle), TAG_WINPROCLST);
|
|
||||||
WndProcHandlesArraySize = OldArraySize + WPH_SIZE;
|
|
||||||
RtlCopyMemory(WndProcHandlesArray,OldArray,OldArraySize * sizeof(WndProcHandle));
|
|
||||||
ExFreePool(OldArray);
|
|
||||||
FreeSpot = OldArraySize + 1;
|
|
||||||
}
|
|
||||||
WndProcHandlesArray[FreeSpot].WindowProc = WindowProc;
|
|
||||||
WndProcHandlesArray[FreeSpot].IsUnicode = IsUnicode;
|
|
||||||
WndProcHandlesArray[FreeSpot].ProcessID = PsGetCurrentProcessId();
|
|
||||||
return FreeSpot + 0xFFFF0000;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD
|
|
||||||
IntRemoveWndProcHandle(WNDPROC Handle)
|
|
||||||
{
|
|
||||||
WORD position;
|
|
||||||
position = (DWORD)Handle & 0x0000FFFF;
|
|
||||||
if (position > WndProcHandlesArraySize)
|
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
WndProcHandlesArray[position].WindowProc = NULL;
|
|
||||||
WndProcHandlesArray[position].IsUnicode = FALSE;
|
|
||||||
WndProcHandlesArray[position].ProcessID = NULL;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD
|
|
||||||
IntRemoveProcessWndProcHandles(HANDLE ProcessID)
|
|
||||||
{
|
|
||||||
WORD i;
|
|
||||||
for (i = 0;i < WndProcHandlesArraySize;i++)
|
|
||||||
{
|
|
||||||
if (WndProcHandlesArray[i].ProcessID == ProcessID)
|
|
||||||
{
|
|
||||||
WndProcHandlesArray[i].WindowProc = NULL;
|
|
||||||
WndProcHandlesArray[i].IsUnicode = FALSE;
|
|
||||||
WndProcHandlesArray[i].ProcessID = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
|
#define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#ifndef __W32K_H
|
||||||
|
#define __W32K_H
|
||||||
/*
|
/*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS Graphics Subsystem
|
* PROJECT: ReactOS Graphics Subsystem
|
||||||
|
@ -68,3 +70,77 @@ typedef DRIVEROBJ *PDRIVEROBJ;
|
||||||
#define M_PI_2 1.57079632679489661923
|
#define M_PI_2 1.57079632679489661923
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* User heap */
|
||||||
|
extern HANDLE GlobalUserHeap;
|
||||||
|
|
||||||
|
HANDLE
|
||||||
|
UserCreateHeap(OUT PSECTION_OBJECT *SectionObject,
|
||||||
|
IN OUT PVOID *SystemBase,
|
||||||
|
IN ULONG HeapSize);
|
||||||
|
|
||||||
|
static __inline PVOID
|
||||||
|
UserHeapAlloc(SIZE_T Bytes)
|
||||||
|
{
|
||||||
|
return RtlAllocateHeap(GlobalUserHeap,
|
||||||
|
HEAP_NO_SERIALIZE,
|
||||||
|
Bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline BOOL
|
||||||
|
UserHeapFree(PVOID lpMem)
|
||||||
|
{
|
||||||
|
return RtlFreeHeap(GlobalUserHeap,
|
||||||
|
HEAP_NO_SERIALIZE,
|
||||||
|
lpMem);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline PVOID
|
||||||
|
UserHeapReAlloc(PVOID lpMem,
|
||||||
|
SIZE_T Bytes)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
/* NOTE: ntoskrnl doesn't export RtlReAllocateHeap... */
|
||||||
|
return RtlReAllocateHeap(GlobalUserHeap,
|
||||||
|
HEAP_NO_SERIALIZE,
|
||||||
|
lpMem,
|
||||||
|
Bytes);
|
||||||
|
#else
|
||||||
|
SIZE_T PrevSize;
|
||||||
|
PVOID pNew;
|
||||||
|
|
||||||
|
PrevSize = RtlSizeHeap(GlobalUserHeap,
|
||||||
|
HEAP_NO_SERIALIZE,
|
||||||
|
lpMem);
|
||||||
|
|
||||||
|
if (PrevSize == Bytes)
|
||||||
|
return lpMem;
|
||||||
|
|
||||||
|
pNew = RtlAllocateHeap(GlobalUserHeap,
|
||||||
|
HEAP_NO_SERIALIZE,
|
||||||
|
Bytes);
|
||||||
|
if (pNew != NULL)
|
||||||
|
{
|
||||||
|
if (PrevSize < Bytes)
|
||||||
|
Bytes = PrevSize;
|
||||||
|
|
||||||
|
RtlCopyMemory(pNew,
|
||||||
|
lpMem,
|
||||||
|
Bytes);
|
||||||
|
|
||||||
|
RtlFreeHeap(GlobalUserHeap,
|
||||||
|
HEAP_NO_SERIALIZE,
|
||||||
|
lpMem);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pNew;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static __inline PVOID
|
||||||
|
UserHeapAddressToUser(PVOID lpMem)
|
||||||
|
{
|
||||||
|
return (PVOID)(((ULONG_PTR)lpMem - (ULONG_PTR)GlobalUserHeap) +
|
||||||
|
(ULONG_PTR)PsGetWin32Process()->HeapMappings.UserMapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __W32K_H */
|
||||||
|
|
|
@ -64,14 +64,15 @@
|
||||||
<file>err.c</file>
|
<file>err.c</file>
|
||||||
<file>math.c</file>
|
<file>math.c</file>
|
||||||
<file>copy.c</file>
|
<file>copy.c</file>
|
||||||
|
<file>usrheap.c</file>
|
||||||
</compilationunit>
|
</compilationunit>
|
||||||
<directory name="i386">
|
<directory name="i386">
|
||||||
<file>cos_asm.s</file>
|
<file>cos_asm.s</file>
|
||||||
<file>sin_asm.s</file>
|
<file>sin_asm.s</file>
|
||||||
<file>atan2_asm.s</file>
|
<file>atan2_asm.s</file>
|
||||||
<file>floor_asm.s</file>
|
<file>floor_asm.s</file>
|
||||||
<file>ceil_asm.s</file>
|
<file>ceil_asm.s</file>
|
||||||
</directory>
|
</directory>
|
||||||
</directory>
|
</directory>
|
||||||
<directory name="ntddraw">
|
<directory name="ntddraw">
|
||||||
<compilationunit name="ntddraw.c">
|
<compilationunit name="ntddraw.c">
|
||||||
|
|
|
@ -356,7 +356,7 @@ NtUserGetAsyncKeyState 1
|
||||||
NtUserGetCapture 0
|
NtUserGetCapture 0
|
||||||
NtUserGetCaretBlinkTime 0
|
NtUserGetCaretBlinkTime 0
|
||||||
NtUserGetCaretPos 1
|
NtUserGetCaretPos 1
|
||||||
NtUserGetClassInfo 5
|
NtUserGetClassInfo 4
|
||||||
NtUserGetClassLong 3
|
NtUserGetClassLong 3
|
||||||
NtUserGetClassName 3
|
NtUserGetClassName 3
|
||||||
NtUserGetClientOrigin 2
|
NtUserGetClientOrigin 2
|
||||||
|
@ -457,7 +457,7 @@ NtUserQueryWindow 2
|
||||||
NtUserReleaseDC 2
|
NtUserReleaseDC 2
|
||||||
NtUserRealChildWindowFromPoint 3
|
NtUserRealChildWindowFromPoint 3
|
||||||
NtUserRedrawWindow 4
|
NtUserRedrawWindow 4
|
||||||
NtUserRegisterClassExWOW 8
|
NtUserRegisterClassEx 6
|
||||||
NtUserRegisterHotKey 4
|
NtUserRegisterHotKey 4
|
||||||
NtUserRegisterTasklist 1
|
NtUserRegisterTasklist 1
|
||||||
NtUserRegisterWindowMessage 1
|
NtUserRegisterWindowMessage 1
|
||||||
|
@ -536,7 +536,7 @@ NtUserUnhookWindowsHookEx 1
|
||||||
NtUserUnhookWinEvent 1
|
NtUserUnhookWinEvent 1
|
||||||
NtUserUnloadKeyboardLayout 1
|
NtUserUnloadKeyboardLayout 1
|
||||||
NtUserUnlockWindowStation 1
|
NtUserUnlockWindowStation 1
|
||||||
NtUserUnregisterClass 3
|
NtUserUnregisterClass 2
|
||||||
NtUserUnregisterHotKey 2
|
NtUserUnregisterHotKey 2
|
||||||
NtUserUpdateInputContext 3
|
NtUserUpdateInputContext 3
|
||||||
NtUserUpdateInstance 3
|
NtUserUpdateInstance 3
|
||||||
|
|
Loading…
Reference in a new issue