📄 class.c
字号:
}
/* query the class name */
Status = RtlQueryAtomInAtomTable(gAtomTable,
Class->Atom,
NULL,
NULL,
szTemp,
&BufLen);
}
else
szTemp = szStaticTemp;
if (NT_SUCCESS(Status))
{
/* convert the atom name to ansi */
RtlInitUnicodeString(&UnicodeClassName,
szTemp);
Status = RtlUnicodeStringToAnsiString(AnsiClassName,
&UnicodeClassName,
FALSE);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
_SEH_LEAVE;
}
}
Ret = BufLen / sizeof(WCHAR);
}
else /* !Ansi */
{
BufLen = ClassName->MaximumLength;
/* query the atom name */
Status = RtlQueryAtomInAtomTable(gAtomTable,
Class->Atom,
NULL,
NULL,
ClassName->Buffer,
&BufLen);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
_SEH_LEAVE;
}
Ret = BufLen / sizeof(WCHAR);
}
}
_SEH_HANDLE
{
SetLastNtError(_SEH_GetExceptionCode());
}
_SEH_END;
if (Ansi && szTemp != NULL && szTemp != szStaticTemp)
{
ExFreePool(szTemp);
}
return Ret;
}
ULONG_PTR
UserGetClassLongPtr(IN PWINDOWCLASS Class,
IN INT Index,
IN BOOL Ansi)
{
ULONG_PTR Ret = 0;
if (Index >= 0)
{
PULONG_PTR Data;
if (Index + sizeof(ULONG_PTR) < Index ||
Index + sizeof(ULONG_PTR) > Class->ClsExtra)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
Data = (PULONG_PTR)((ULONG_PTR)(Class + 1) + Index);
/* FIXME - Data might be a unaligned pointer! Might be a problem on
certain architectures, maybe using RtlCopyMemory is a
better choice for those architectures! */
return *Data;
}
switch (Index)
{
case GCL_CBWNDEXTRA:
Ret = (ULONG_PTR)Class->WndExtra;
break;
case GCL_CBCLSEXTRA:
Ret = (ULONG_PTR)Class->ClsExtra;
break;
case GCLP_HBRBACKGROUND:
Ret = (ULONG_PTR)Class->hbrBackground;
break;
case GCLP_HCURSOR:
/* FIXME - get handle from pointer to CURSOR object */
Ret = (ULONG_PTR)Class->hCursor;
break;
case GCLP_HICON:
/* FIXME - get handle from pointer to ICON object */
Ret = (ULONG_PTR)Class->hIcon;
break;
case GCLP_HICONSM:
/* FIXME - get handle from pointer to ICON object */
Ret = (ULONG_PTR)Class->hIconSm;
break;
case GCLP_HMODULE:
Ret = (ULONG_PTR)Class->hInstance;
break;
case GCLP_MENUNAME:
/* NOTE: Returns pointer in kernel heap! */
if (Ansi)
Ret = (ULONG_PTR)Class->AnsiMenuName;
else
Ret = (ULONG_PTR)Class->MenuName;
break;
case GCL_STYLE:
Ret = (ULONG_PTR)Class->Style;
break;
case GCLP_WNDPROC:
Ret = (ULONG_PTR)IntGetClassWndProc(Class,
GetW32ProcessInfo(),
Ansi,
FALSE);
break;
case GCW_ATOM:
Ret = (ULONG_PTR)Class->Atom;
break;
default:
SetLastWin32Error(ERROR_INVALID_INDEX);
break;
}
return Ret;
}
static BOOL
IntSetClassMenuName(IN PWINDOWCLASS Class,
IN PUNICODE_STRING MenuName)
{
BOOL Ret = FALSE;
/* change the base class first */
Class = Class->Base;
if (MenuName->Length != 0)
{
ANSI_STRING AnsiString;
PWSTR strBufW;
AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(MenuName);
strBufW = UserHeapAlloc(MenuName->Length + sizeof(UNICODE_NULL) +
AnsiString.MaximumLength);
if (strBufW != NULL)
{
_SEH_TRY
{
NTSTATUS Status;
/* copy the unicode string */
RtlCopyMemory(strBufW,
MenuName->Buffer,
MenuName->Length);
strBufW[MenuName->Length / sizeof(WCHAR)] = UNICODE_NULL;
/* create an ansi copy of the string */
AnsiString.Buffer = (PSTR)(strBufW + (MenuName->Length / sizeof(WCHAR)) + 1);
Status = RtlUnicodeStringToAnsiString(&AnsiString,
MenuName,
FALSE);
if (!NT_SUCCESS(Status))
{
SetLastNtError(Status);
_SEH_LEAVE;
}
Ret = TRUE;
}
_SEH_HANDLE
{
SetLastNtError(_SEH_GetExceptionCode());
}
_SEH_END;
if (Ret)
{
/* update the base class */
IntFreeClassMenuName(Class);
Class->MenuName = strBufW;
Class->AnsiMenuName = AnsiString.Buffer;
Class->MenuNameIsString = TRUE;
/* update the clones */
Class = Class->Clone;
while (Class != NULL)
{
Class->MenuName = strBufW;
Class->AnsiMenuName = AnsiString.Buffer;
Class->MenuNameIsString = TRUE;
Class = Class->Next;
}
}
else
{
DPRINT1("Failed to copy class menu name!\n");
UserHeapFree(strBufW);
}
}
else
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
}
else
{
ASSERT(IS_INTRESOURCE(MenuName->Buffer));
/* update the base class */
IntFreeClassMenuName(Class);
Class->MenuName = MenuName->Buffer;
Class->AnsiMenuName = (PSTR)MenuName->Buffer;
Class->MenuNameIsString = FALSE;
/* update the clones */
Class = Class->Clone;
while (Class != NULL)
{
Class->MenuName = MenuName->Buffer;
Class->AnsiMenuName = (PSTR)MenuName->Buffer;
Class->MenuNameIsString = FALSE;
Class = Class->Next;
}
Ret = TRUE;
}
return Ret;
}
ULONG_PTR
UserSetClassLongPtr(IN PWINDOWCLASS Class,
IN INT Index,
IN ULONG_PTR NewLong,
IN BOOL Ansi)
{
ULONG_PTR Ret = 0;
/* NOTE: For GCLP_MENUNAME and GCW_ATOM this function may raise an exception! */
/* change the information in the base class first, then update the clones */
Class = Class->Base;
if (Index >= 0)
{
PULONG_PTR Data;
if (Index + sizeof(ULONG_PTR) < Index ||
Index + sizeof(ULONG_PTR) > Class->ClsExtra)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
Data = (PULONG_PTR)((ULONG_PTR)(Class + 1) + Index);
/* FIXME - Data might be a unaligned pointer! Might be a problem on
certain architectures, maybe using RtlCopyMemory is a
better choice for those architectures! */
Ret = *Data;
*Data = NewLong;
/* update the clones */
Class = Class->Clone;
while (Class != NULL)
{
*(PULONG_PTR)((ULONG_PTR)(Class + 1) + Index) = NewLong;
Class = Class->Next;
}
return Ret;
}
switch (Index)
{
case GCL_CBWNDEXTRA:
Ret = (ULONG_PTR)Class->WndExtra;
Class->WndExtra = (INT)NewLong;
/* update the clones */
Class = Class->Clone;
while (Class != NULL)
{
Class->WndExtra = (INT)NewLong;
Class = Class->Next;
}
break;
case GCL_CBCLSEXTRA:
SetLastWin32Error(ERROR_INVALID_PARAMETER);
break;
case GCLP_HBRBACKGROUND:
Ret = (ULONG_PTR)Class->hbrBackground;
Class->hbrBackground = (HBRUSH)NewLong;
/* update the clones */
Class = Class->Clone;
while (Class != NULL)
{
Class->hbrBackground = (HBRUSH)NewLong;
Class = Class->Next;
}
break;
case GCLP_HCURSOR:
/* FIXME - get handle from pointer to CURSOR object */
Ret = (ULONG_PTR)Class->hCursor;
Class->hCursor = (HANDLE)NewLong;
/* update the clones */
Class = Class->Clone;
while (Class != NULL)
{
Class->hCursor = (HANDLE)NewLong;
Class = Class->Next;
}
break;
case GCLP_HICON:
/* FIXME - get handle from pointer to ICON object */
Ret = (ULONG_PTR)Class->hIcon;
Class->hIcon = (HANDLE)NewLong;
/* update the clones */
Class = Class->Clone;
while (Class != NULL)
{
Class->hIcon = (HANDLE)NewLong;
Class = Class->Next;
}
break;
case GCLP_HICONSM:
/* FIXME - get handle from pointer to ICON object */
Ret = (ULONG_PTR)Class->hIconSm;
Class->hIconSm = (HANDLE)NewLong;
/* update the clones */
Class = Class->Clone;
while (Class != NULL)
{
Class->hIconSm = (HANDLE)NewLong;
Class = Class->Next;
}
break;
case GCLP_HMODULE:
Ret = (ULONG_PTR)Class->hInstance;
Class->hInstance = (HINSTANCE)NewLong;
/* update the clones */
Class = Class->Clone;
while (Class != NULL)
{
Class->hInstance = (HINSTANCE)NewLong;
Class = Class->Next;
}
break;
case GCLP_MENUNAME:
{
PUNICODE_STRING Value = (PUNICODE_STRING)NewLong;
if (!IntSetClassMenuName(Class,
Value))
{
DPRINT("Setting the class menu name failed!\n");
}
/* FIXME - really return NULL? Wine does so... */
break;
}
case GCL_STYLE:
Ret = (ULONG_PTR)Class->Style;
Class->Style = (UINT)NewLong;
/* FIXME - what if the CS_GLOBALCLASS style is changed? should we
move the class to the appropriate list? For now, we save
the original value in Class->Global, so we can always
locate the appropriate list */
/* update the clones */
Class = Class->Clone;
while (Class != NULL)
{
Class->Style = (UINT)NewLong;
Class = Class->Next;
}
break;
case GCLP_WNDPROC:
Ret = (ULONG_PTR)IntSetClassWndProc(Class,
(WNDPROC)NewLong,
Ansi);
break;
case GCW_ATOM:
{
PUNICODE_STRING Value = (PUNICODE_STRING)NewLong;
Ret = (ULONG_PTR)Class->Atom;
if (!IntSetClassAtom(Class,
Value))
{
Ret = 0;
}
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -