📄 class.c
字号:
default:
SetLastWin32Error(ERROR_INVALID_INDEX);
break;
}
return Ret;
}
static BOOL
UserGetClassInfo(IN PWINDOWCLASS Class,
OUT PWNDCLASSEXW lpwcx,
IN BOOL Ansi,
HINSTANCE hInstance)
{
PW32PROCESSINFO pi;
lpwcx->style = Class->Style;
pi = GetW32ProcessInfo();
lpwcx->lpfnWndProc = IntGetClassWndProc(Class,
pi,
Ansi,
FALSE);
lpwcx->cbClsExtra = Class->ClsExtra;
lpwcx->cbWndExtra = Class->WndExtra;
lpwcx->hIcon = Class->hIcon; /* FIXME - get handle from pointer */
lpwcx->hCursor = Class->hCursor; /* FIXME - get handle from pointer */
lpwcx->hbrBackground = Class->hbrBackground;
if (Ansi)
((PWNDCLASSEXA)lpwcx)->lpszMenuName = Class->AnsiMenuName;
else
lpwcx->lpszMenuName = Class->MenuName;
if (Class->hInstance == pi->hModUser)
lpwcx->hInstance = NULL;
else
lpwcx->hInstance = Class->hInstance;
lpwcx->lpszClassName = (LPCWSTR)((ULONG_PTR)Class->Atom); /* FIXME - return the string? */
lpwcx->hIconSm = Class->hIconSm; /* FIXME - get handle from pointer */
return TRUE;
}
/* SYSCALLS *****************************************************************/
RTL_ATOM NTAPI
NtUserRegisterClassEx(IN CONST WNDCLASSEXW* lpwcx,
IN PUNICODE_STRING ClassName,
IN PUNICODE_STRING MenuName,
IN WNDPROC wpExtra,
IN DWORD Flags,
IN HMENU hMenu)
/*
* FUNCTION:
* Registers a new class with the window manager
* ARGUMENTS:
* lpwcx = Win32 extended window class structure
* bUnicodeClass = Whether to send ANSI or unicode strings
* to window procedures
* wpExtra = Extra window procedure, if this is not null, its used for the second window procedure for standard controls.
* RETURNS:
* Atom identifying the new class
*/
{
WNDCLASSEXW CapturedClassInfo = {0};
UNICODE_STRING CapturedName = {0}, CapturedMenuName = {0};
RTL_ATOM Ret = (RTL_ATOM)0;
if (Flags & ~REGISTERCLASS_ALL)
{
SetLastWin32Error(ERROR_INVALID_FLAGS);
return Ret;
}
UserEnterExclusive();
_SEH_TRY
{
/* Probe the parameters and basic parameter checks */
if (ProbeForReadUint(&lpwcx->cbSize) != sizeof(WNDCLASSEXW))
{
goto InvalidParameter;
}
ProbeForRead(lpwcx,
sizeof(WNDCLASSEXW),
sizeof(ULONG));
RtlCopyMemory(&CapturedClassInfo,
lpwcx,
sizeof(WNDCLASSEXW));
CapturedName = ProbeForReadUnicodeString(ClassName);
CapturedMenuName = ProbeForReadUnicodeString(MenuName);
if (CapturedName.Length & 1 || CapturedMenuName.Length & 1 ||
CapturedClassInfo.cbClsExtra < 0 ||
CapturedClassInfo.cbClsExtra + CapturedName.Length +
CapturedMenuName.Length + sizeof(WINDOWCLASS) < CapturedClassInfo.cbClsExtra ||
CapturedClassInfo.cbWndExtra < 0 ||
CapturedClassInfo.hInstance == NULL)
{
goto InvalidParameter;
}
if (CapturedName.Length != 0)
{
ProbeForRead(CapturedName.Buffer,
CapturedName.Length,
sizeof(WCHAR));
}
else
{
if (!IS_ATOM(CapturedName.Buffer))
{
goto InvalidParameter;
}
}
if (CapturedMenuName.Length != 0)
{
ProbeForRead(CapturedMenuName.Buffer,
CapturedMenuName.Length,
sizeof(WCHAR));
}
else if (CapturedMenuName.Buffer != NULL &&
!IS_INTRESOURCE(CapturedMenuName.Buffer))
{
InvalidParameter:
SetLastWin32Error(ERROR_INVALID_PARAMETER);
_SEH_LEAVE;
}
/* Register the class */
Ret = UserRegisterClass(&CapturedClassInfo,
&CapturedName,
&CapturedMenuName,
hMenu, /* FIXME - pass pointer */
wpExtra,
Flags);
}
_SEH_HANDLE
{
SetLastNtError(_SEH_GetExceptionCode());
}
_SEH_END;
UserLeave();
return Ret;
}
ULONG_PTR NTAPI
NtUserGetClassLong(IN HWND hWnd,
IN INT Offset,
IN BOOL Ansi)
{
PWINDOW_OBJECT Window;
ULONG_PTR Ret = 0;
if (Offset != GCLP_WNDPROC)
{
UserEnterShared();
}
else
{
UserEnterExclusive();
}
Window = UserGetWindowObject(hWnd);
if (Window != NULL)
{
Ret = UserGetClassLongPtr(Window->Class,
Offset,
Ansi);
if (Ret != 0 && Offset == GCLP_MENUNAME && Window->Class->MenuNameIsString)
{
Ret = (ULONG_PTR)UserHeapAddressToUser((PVOID)Ret);
}
}
UserLeave();
return Ret;
}
ULONG_PTR STDCALL
NtUserSetClassLong(HWND hWnd,
INT Offset,
ULONG_PTR dwNewLong,
BOOL Ansi)
{
PW32PROCESSINFO pi;
PWINDOW_OBJECT Window;
ULONG_PTR Ret = 0;
UserEnterExclusive();
pi = GetW32ProcessInfo();
if (pi == NULL)
goto Cleanup;
Window = UserGetWindowObject(hWnd);
if (Window != NULL)
{
if (Window->ti->kpi != pi)
{
SetLastWin32Error(ERROR_ACCESS_DENIED);
goto Cleanup;
}
_SEH_TRY
{
UNICODE_STRING Value;
/* probe the parameters */
if (Offset == GCW_ATOM || Offset == GCLP_MENUNAME)
{
Value = ProbeForReadUnicodeString((PUNICODE_STRING)dwNewLong);
if (Value.Length & 1)
{
goto InvalidParameter;
}
if (Value.Length != 0)
{
ProbeForRead(Value.Buffer,
Value.Length,
sizeof(WCHAR));
}
else
{
if (Offset == GCW_ATOM && !IS_ATOM(Value.Buffer))
{
goto InvalidParameter;
}
else if (Offset == GCLP_MENUNAME && !IS_INTRESOURCE(Value.Buffer))
{
InvalidParameter:
SetLastWin32Error(ERROR_INVALID_PARAMETER);
_SEH_LEAVE;
}
}
dwNewLong = (ULONG_PTR)&Value;
}
Ret = UserSetClassLongPtr(Window->Class,
Offset,
dwNewLong,
Ansi);
}
_SEH_HANDLE
{
SetLastNtError(_SEH_GetExceptionCode());
}
_SEH_END;
}
Cleanup:
UserLeave();
return Ret;
}
DWORD STDCALL
NtUserSetClassWord(DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2)
{
return(0);
}
BOOL NTAPI
NtUserUnregisterClass(IN PUNICODE_STRING ClassNameOrAtom,
IN HINSTANCE hInstance)
{
UNICODE_STRING CapturedClassName;
BOOL Ret = FALSE;
UserEnterExclusive();
_SEH_TRY
{
/* probe the paramters */
CapturedClassName = ProbeForReadUnicodeString(ClassNameOrAtom);
if (CapturedClassName.Length & 1)
{
goto InvalidParameter;
}
if (CapturedClassName.Length != 0)
{
ProbeForRead(CapturedClassName.Buffer,
CapturedClassName.Length,
sizeof(WCHAR));
}
else
{
if (!IS_ATOM(CapturedClassName.Buffer))
{
InvalidParameter:
SetLastWin32Error(ERROR_INVALID_PARAMETER);
_SEH_LEAVE;
}
}
/* unregister the class */
Ret = UserUnregisterClass(&CapturedClassName,
hInstance);
}
_SEH_HANDLE
{
SetLastNtError(_SEH_GetExceptionCode());
}
_SEH_END;
UserLeave();
return Ret;
}
/* NOTE: for system classes hInstance is not NULL here, but User32Instance */
BOOL STDCALL
NtUserGetClassInfo(
HINSTANCE hInstance,
PUNICODE_STRING ClassName,
LPWNDCLASSEXW lpWndClassEx,
BOOL Ansi)
{
UNICODE_STRING CapturedClassName;
PWINDOWCLASS Class;
RTL_ATOM ClassAtom;
PW32PROCESSINFO pi;
BOOL Ret = FALSE;
/* NOTE: need exclusive lock because getting the wndproc might require the
creation of a call procedure handle */
UserEnterExclusive();
pi = GetW32ProcessInfo();
if (pi == NULL)
{
ERR("GetW32ProcessInfo() returned NULL!\n");
goto Cleanup;
}
_SEH_TRY
{
/* probe the paramters */
CapturedClassName = ProbeForReadUnicodeString(ClassName);
if (CapturedClassName.Length == 0)
TRACE("hInst %p atom %04X lpWndClassEx %p Ansi %d\n", hInstance, CapturedClassName.Buffer, lpWndClassEx, Ansi);
else
TRACE("hInst %p class %wZ lpWndClassEx %p Ansi %d\n", hInstance, &CapturedClassName, lpWndClassEx, Ansi);
if (CapturedClassName.Length & 1)
{
goto InvalidParameter;
}
if (CapturedClassName.Length != 0)
{
ProbeForRead(CapturedClassName.Buffer,
CapturedClassName.Length,
sizeof(WCHAR));
}
else
{
if (!IS_ATOM(CapturedClassName.Buffer))
{
ERR("NtUserGetClassInfo() got ClassName instead of Atom!\n");
goto InvalidParameter;
}
}
if (ProbeForReadUint(&lpWndClassEx->cbSize) != sizeof(WNDCLASSEXW))
{
InvalidParameter:
SetLastWin32Error(ERROR_INVALID_PARAMETER);
_SEH_LEAVE;
}
ProbeForWrite(lpWndClassEx,
sizeof(WNDCLASSEXW),
sizeof(ULONG));
ClassAtom = IntGetClassAtom(&CapturedClassName,
hInstance,
pi,
&Class,
NULL);
if (ClassAtom != (RTL_ATOM)0)
{
if (hInstance == NULL)
hInstance = pi->hModUser;
Ret = UserGetClassInfo(Class,
lpWndClassEx,
Ansi,
hInstance);
if (Ret)
{
lpWndClassEx->lpszClassName = CapturedClassName.Buffer;
/* FIXME - handle Class->Desktop == NULL!!!!! */
if (Class->MenuName != NULL && Class->MenuNameIsString)
{
lpWndClassEx->lpszMenuName = UserHeapAddressToUser(Ansi ?
(PVOID)Class->AnsiMenuName :
(PVOID)Class->MenuName);
}
/* Undocumented behavior! Return the class atom as a BOOL! */
Ret = (BOOL)ClassAtom;
}
}
else
{
if (CapturedClassName.Length == 0)
WARN("Tried to get information of a non-existing class atom 0x%p\n", CapturedClassName.Buffer);
else
WARN("Tried to get information of a non-existing class \"%wZ\"\n", &CapturedClassName);
SetLastWin32Error(ERROR_CLASS_DOES_NOT_EXIST);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -