ReactOS  0.4.14-dev-115-g4576127
class.c File Reference
#include <win32k.h>
Include dependency graph for class.c:

Go to the source code of this file.

Functions

 DBG_DEFAULT_CHANNEL (UserClass)
 
static NTSTATUS IntDeregisterClassAtom (IN RTL_ATOM Atom)
 
BOOL FASTCALL LookupFnIdToiCls (int FnId, int *iCls)
 
_Must_inspect_result_ NTSTATUS NTAPI ProbeAndCaptureUnicodeStringOrAtom (_Out_ _When_(return >=0, _At_(pustrOut->Buffer, _Post_ _Notnull_)) PUNICODE_STRING pustrOut, __in_data_source(USER_MODE) _In_ PUNICODE_STRING pustrUnsafe)
 
static VOID IntFreeClassMenuName (IN OUT PCLS Class)
 
static VOID IntDestroyClass (IN OUT PCLS Class)
 
void FASTCALL DestroyProcessClasses (PPROCESSINFO Process)
 
static BOOL IntRegisterClassAtom (IN PUNICODE_STRING ClassName, OUT RTL_ATOM *pAtom)
 
BOOL FASTCALL RegisterControlAtoms (VOID)
 
VOID UserAddCallProcToClass (IN OUT PCLS Class, IN PCALLPROCDATA CallProc)
 
static BOOL IntSetClassAtom (IN OUT PCLS Class, IN PUNICODE_STRING ClassName)
 
WNDPROC FASTCALL IntGetClassWndProc (PCLS Class, BOOL Ansi)
 
static WNDPROC FASTCALL IntSetClassWndProc (IN OUT PCLS Class, IN WNDPROC WndProc, IN BOOL Ansi)
 
static PCLS IntGetClassForDesktop (IN OUT PCLS BaseClass, IN OUT PCLS *ClassLink, IN PDESKTOP Desktop)
 
PCLS IntReferenceClass (IN OUT PCLS BaseClass, IN OUT PCLS *ClassLink, IN PDESKTOP Desktop)
 
static VOID IntMakeCloneBaseClass (IN OUT PCLS Class, IN OUT PCLS *BaseClassLink, IN OUT PCLS *CloneLink)
 
VOID IntDereferenceClass (IN OUT PCLS Class, IN PDESKTOPINFO Desktop, IN PPROCESSINFO pi)
 
static BOOL IntMoveClassToSharedHeap (IN OUT PCLS Class, IN OUT PCLS **ClassLinkPtr)
 
static VOID IntCheckDesktopClasses (IN PDESKTOP Desktop, IN OUT PCLS *ClassList, IN BOOL FreeOnFailure, OUT BOOL *Ret)
 
BOOL IntCheckProcessDesktopClasses (IN PDESKTOP Desktop, IN BOOL FreeOnFailure)
 
PCLS FASTCALL IntCreateClass (IN CONST WNDCLASSEXW *lpwcx, IN PUNICODE_STRING ClassName, IN PUNICODE_STRING ClassVersion, IN PUNICODE_STRING MenuName, IN DWORD fnID, IN DWORD dwFlags, IN PDESKTOP Desktop, IN PPROCESSINFO pi)
 
static PCLS IntFindClass (IN RTL_ATOM Atom, IN HINSTANCE hInstance, IN PCLS *ClassList, OUT PCLS **Link OPTIONAL)
 
 _Success_ (return)
 
RTL_ATOM IntGetClassAtom (_In_ PUNICODE_STRING ClassName, IN HINSTANCE hInstance OPTIONAL, IN PPROCESSINFO pi OPTIONAL, OUT PCLS *BaseClass OPTIONAL, OUT PCLS **Link OPTIONAL)
 
PCLS IntGetAndReferenceClass (PUNICODE_STRING ClassName, HINSTANCE hInstance, BOOL bDesktopThread)
 
RTL_ATOM UserRegisterClass (IN CONST WNDCLASSEXW *lpwcx, IN PUNICODE_STRING ClassName, IN PUNICODE_STRING ClassVersion, IN PUNICODE_STRING MenuName, IN DWORD fnID, IN DWORD dwFlags)
 
BOOL UserUnregisterClass (IN PUNICODE_STRING ClassName, IN HINSTANCE hInstance, OUT PCLSMENUNAME pClassMenuName)
 
INT UserGetClassName (IN PCLS Class, IN OUT PUNICODE_STRING ClassName, IN RTL_ATOM Atom, IN BOOL Ansi)
 
static BOOL IntSetClassMenuName (IN PCLS Class, IN PUNICODE_STRING MenuName)
 
ULONG_PTR UserSetClassLongPtr (IN PCLS Class, IN INT Index, IN ULONG_PTR NewLong, IN BOOL Ansi)
 
static BOOL UserGetClassInfo (IN PCLS Class, OUT PWNDCLASSEXW lpwcx, IN BOOL Ansi, HINSTANCE hInstance)
 
BOOL FASTCALL UserRegisterSystemClasses (VOID)
 
RTL_ATOM APIENTRY NtUserRegisterClassExWOW (WNDCLASSEXW *lpwcx, PUNICODE_STRING ClassName, PUNICODE_STRING ClsVersion, PCLSMENUNAME pClassMenuName, DWORD fnID, DWORD Flags, LPDWORD pWow)
 
ULONG_PTR APIENTRY NtUserSetClassLong (HWND hWnd, INT Offset, ULONG_PTR dwNewLong, BOOL Ansi)
 
WORD APIENTRY NtUserSetClassWord (HWND hWnd, INT nIndex, WORD wNewWord)
 
BOOL APIENTRY NtUserUnregisterClass (IN PUNICODE_STRING ClassNameOrAtom, IN HINSTANCE hInstance, OUT PCLSMENUNAME pClassMenuName)
 
BOOL APIENTRY NtUserGetClassInfo (HINSTANCE hInstance, PUNICODE_STRING ClassName, LPWNDCLASSEXW lpWndClassEx, LPWSTR *ppszMenuName, BOOL bAnsi)
 
INT APIENTRY NtUserGetClassName (IN HWND hWnd, IN BOOL Real, OUT PUNICODE_STRING ClassName)
 
PCLS APIENTRY NtUserGetWOWClass (HINSTANCE hInstance, PUNICODE_STRING ClassName)
 

Variables

static PWSTR ControlsList []
 
REGISTER_SYSCLASS DefaultServerClasses []
 
struct {
   int   FnId
 
   int   ClsId
 
FnidToiCls []
 

Function Documentation

◆ _Success_()

_Success_ ( return  )

Definition at line 1266 of file class.c.

1272 {
1273  BOOL Ret = FALSE;
1274 
1275  if (ClassName->Length != 0)
1276  {
1277  WCHAR szBuf[65];
1278  PWSTR AtomName;
1279  NTSTATUS Status;
1280 
1281  *Atom = 0;
1282 
1283  /* NOTE: Caller has to protect the call with SEH! */
1284 
1285  if (ClassName->Length != 0)
1286  {
1287  /* FIXME: Don't limit to 64 characters! use SEH when allocating memory! */
1288  if (ClassName->Length / sizeof(WCHAR) >= sizeof(szBuf) / sizeof(szBuf[0]))
1289  {
1291  return (RTL_ATOM)0;
1292  }
1293 
1294  /* We need to make a local copy of the class name! The caller could
1295  modify the buffer and we could overflow in RtlLookupAtomInAtomTable.
1296  We're protected by SEH, but the ranges that might be accessed were
1297  not probed... */
1298  RtlCopyMemory(szBuf,
1299  ClassName->Buffer,
1300  ClassName->Length);
1301  szBuf[ClassName->Length / sizeof(WCHAR)] = UNICODE_NULL;
1302  AtomName = szBuf;
1303  }
1304  else
1305  AtomName = ClassName->Buffer;
1306 
1307  /* Lookup the atom */
1309  AtomName,
1310  Atom);
1311  if (NT_SUCCESS(Status))
1312  {
1313  Ret = TRUE;
1314  }
1315  else
1316  {
1318  {
1320  }
1321  }
1322  }
1323  else
1324  {
1325  ASSERT(IS_ATOM(ClassName->Buffer));
1326  *Atom = (RTL_ATOM)((ULONG_PTR)ClassName->Buffer);
1327  Ret = TRUE;
1328  }
1329 
1330  return Ret;
1331 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
NTSYSAPI NTSTATUS NTAPI RtlLookupAtomInAtomTable(_In_ PRTL_ATOM_TABLE AtomTable, _In_ PWSTR AtomName, _Out_ PRTL_ATOM Atom)
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
unsigned short RTL_ATOM
Definition: atom.c:42
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
PRTL_ATOM_TABLE gAtomTable
Definition: session.c:13
_Out_ RTL_ATOM * Atom
Definition: class.h:54
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define UNICODE_NULL
unsigned int BOOL
Definition: ntddk_ex.h:94
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define IS_ATOM(x)
Definition: class.h:3
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

◆ DBG_DEFAULT_CHANNEL()

DBG_DEFAULT_CHANNEL ( UserClass  )

◆ DestroyProcessClasses()

void FASTCALL DestroyProcessClasses ( PPROCESSINFO  Process)

Definition at line 300 of file class.c.

301 {
302  PCLS Class;
304 
305  if (pi != NULL)
306  {
307  /* Free all local classes */
308  Class = pi->pclsPrivateList;
309  while (Class != NULL)
310  {
311  pi->pclsPrivateList = Class->pclsNext;
312 
313  ASSERT(Class->pclsBase == Class);
315 
316  Class = pi->pclsPrivateList;
317  }
318 
319  /* Free all global classes */
320  Class = pi->pclsPublicList;
321  while (Class != NULL)
322  {
323  pi->pclsPublicList = Class->pclsNext;
324 
325  ASSERT(Class->pclsBase == Class);
327 
328  Class = pi->pclsPublicList;
329  }
330  }
331 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
struct _PROCESSINFO * PPROCESSINFO
Definition: ntwin32.h:5
static VOID IntDestroyClass(IN OUT PCLS Class)
Definition: class.c:228
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static DWORD pi
Definition: protocol.c:150
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219

Referenced by ExitThreadCallback().

◆ IntCheckDesktopClasses()

static VOID IntCheckDesktopClasses ( IN PDESKTOP  Desktop,
IN OUT PCLS ClassList,
IN BOOL  FreeOnFailure,
OUT BOOL Ret 
)
static

Definition at line 920 of file class.c.

924 {
925  PCLS Class, NextClass, *Link;
926 
927  /* NOTE: We only need to check base classes! When classes are no longer needed
928  on a desktop, the clones will be freed automatically as soon as possible.
929  However, we need to move base classes to the shared heap, as soon as
930  the last desktop heap where a class is allocated on is about to be destroyed.
931  If we didn't move the class to the shared heap, the class would become
932  inaccessible! */
933 
934  ASSERT(Desktop != NULL);
935 
936  Link = ClassList;
937  Class = *Link;
938  while (Class != NULL)
939  {
940  NextClass = Class->pclsNext;
941 
942  ASSERT(Class->pclsBase == Class);
943 
944  if (Class->rpdeskParent == Desktop &&
945  Class->cWndReferenceCount == 0)
946  {
947  /* There shouldn't be any clones around anymore! */
948  ASSERT(Class->pclsClone == NULL);
949 
950  /* FIXME: If process is terminating, don't move the class but rather destroy it! */
951  /* FIXME: We could move the class to another desktop heap if there's still desktops
952  mapped into the process... */
953 
954  /* Move the class to the shared heap */
956  &Link))
957  {
958  ASSERT(*Link == NextClass);
959  }
960  else
961  {
962  ASSERT(NextClass == Class->pclsNext);
963 
964  if (FreeOnFailure)
965  {
966  /* Unlink the base class */
968  Class->pclsNext);
969 
970  /* We can free the old base class now */
971  Class->pclsBase = NULL;
973  }
974  else
975  {
976  Link = &Class->pclsNext;
977  *Ret = FALSE;
978  }
979  }
980  }
981  else
982  Link = &Class->pclsNext;
983 
984  Class = NextClass;
985  }
986 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
static VOID IntDestroyClass(IN OUT PCLS Class)
Definition: class.c:228
static int Link(const char **args)
Definition: vfdcmd.c:2414
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
static BOOL IntMoveClassToSharedHeap(IN OUT PCLS Class, IN OUT PCLS **ClassLinkPtr)
Definition: class.c:874
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

Referenced by IntCheckProcessDesktopClasses().

◆ IntCheckProcessDesktopClasses()

BOOL IntCheckProcessDesktopClasses ( IN PDESKTOP  Desktop,
IN BOOL  FreeOnFailure 
)

Definition at line 989 of file class.c.

991 {
993  BOOL Ret = TRUE;
994 
995  pi = GetW32ProcessInfo();
996 
997  /* Check all local classes */
999  &pi->pclsPrivateList,
1000  FreeOnFailure,
1001  &Ret);
1002 
1003  /* Check all global classes */
1005  &pi->pclsPublicList,
1006  FreeOnFailure,
1007  &Ret);
1008  if (!Ret)
1009  {
1010  ERR("Failed to move process classes from desktop 0x%p to the shared heap!\n", Desktop);
1012  }
1013 
1014  return Ret;
1015 }
#define TRUE
Definition: types.h:120
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
unsigned int BOOL
Definition: ntddk_ex.h:94
struct _PROCESSINFO * GetW32ProcessInfo(VOID)
Definition: misc.c:775
static VOID IntCheckDesktopClasses(IN PDESKTOP Desktop, IN OUT PCLS *ClassList, IN BOOL FreeOnFailure, OUT BOOL *Ret)
Definition: class.c:920
static DWORD pi
Definition: protocol.c:150
#define ERR(fmt,...)
Definition: debug.h:109
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by IntSetThreadDesktop().

◆ IntCreateClass()

PCLS FASTCALL IntCreateClass ( IN CONST WNDCLASSEXW lpwcx,
IN PUNICODE_STRING  ClassName,
IN PUNICODE_STRING  ClassVersion,
IN PUNICODE_STRING  MenuName,
IN DWORD  fnID,
IN DWORD  dwFlags,
IN PDESKTOP  Desktop,
IN PPROCESSINFO  pi 
)

Definition at line 1019 of file class.c.

1027 {
1028  SIZE_T ClassSize;
1029  PCLS Class = NULL;
1030  RTL_ATOM Atom, verAtom;
1031  WNDPROC WndProc;
1032  PWSTR pszMenuName = NULL;
1034 
1035  TRACE("lpwcx=%p ClassName=%wZ MenuName=%wZ dwFlags=%08x Desktop=%p pi=%p\n",
1036  lpwcx, ClassName, MenuName, dwFlags, Desktop, pi);
1037 
1038  if (!IntRegisterClassAtom(ClassName,
1039  &Atom))
1040  {
1041  ERR("Failed to register class atom!\n");
1042  return NULL;
1043  }
1044 
1045  if (!IntRegisterClassAtom(ClassVersion,
1046  &verAtom))
1047  {
1048  ERR("Failed to register version class atom!\n");
1050  return NULL;
1051  }
1052 
1053  ClassSize = sizeof(*Class) + lpwcx->cbClsExtra;
1054  if (MenuName->Length != 0)
1055  {
1056  pszMenuName = UserHeapAlloc(MenuName->Length + sizeof(UNICODE_NULL) +
1057  RtlUnicodeStringToAnsiSize(MenuName));
1058  if (pszMenuName == NULL)
1059  goto NoMem;
1060  }
1061 
1062  if (Desktop != NULL)
1063  {
1065  ClassSize);
1066  }
1067  else
1068  {
1069  /* FIXME: The class was created before being connected
1070  to a desktop. It is possible for the desktop window,
1071  but should it be allowed for any other case? */
1072  TRACE("This CLASS has no Desktop to heap from! Atom %u\n",Atom);
1073  Class = UserHeapAlloc(ClassSize);
1074  }
1075 
1076  if (Class != NULL)
1077  {
1078  int iCls = 0;
1079 
1080  RtlZeroMemory(Class, ClassSize);
1081 
1082  Class->rpdeskParent = Desktop;
1083  Class->pclsBase = Class;
1084  Class->atomClassName = verAtom;
1085  Class->atomNVClassName = Atom;
1086  Class->fnid = fnID;
1087  Class->CSF_flags = dwFlags;
1088 
1089  if (LookupFnIdToiCls(Class->fnid, &iCls) && gpsi->atomSysClass[iCls] == 0)
1090  {
1091  gpsi->atomSysClass[iCls] = Class->atomClassName;
1092  }
1093 
1094  _SEH2_TRY
1095  {
1096  PWSTR pszMenuNameBuffer = pszMenuName;
1097 
1098  /* Need to protect with SEH since accessing the WNDCLASSEX structure
1099  and string buffers might raise an exception! We don't want to
1100  leak memory... */
1101  // What?! If the user interface was written correctly this would not be an issue!
1102  Class->lpfnWndProc = lpwcx->lpfnWndProc;
1103  Class->style = lpwcx->style;
1104  Class->cbclsExtra = lpwcx->cbClsExtra;
1105  Class->cbwndExtra = lpwcx->cbWndExtra;
1106  Class->hModule = lpwcx->hInstance;
1107  Class->spicn = lpwcx->hIcon ? UserGetCurIconObject(lpwcx->hIcon) : NULL;
1108  Class->spcur = lpwcx->hCursor ? UserGetCurIconObject(lpwcx->hCursor) : NULL;
1109  Class->spicnSm = lpwcx->hIconSm ? UserGetCurIconObject(lpwcx->hIconSm) : NULL;
1111  Class->hbrBackground = lpwcx->hbrBackground;
1112 
1113  /* Make a copy of the string */
1114  if (pszMenuNameBuffer != NULL)
1115  {
1116  Class->MenuNameIsString = TRUE;
1117 
1118  Class->lpszClientUnicodeMenuName = pszMenuNameBuffer;
1119  RtlCopyMemory(Class->lpszClientUnicodeMenuName,
1120  MenuName->Buffer,
1121  MenuName->Length);
1122  Class->lpszClientUnicodeMenuName[MenuName->Length / sizeof(WCHAR)] = UNICODE_NULL;
1123 
1124  pszMenuNameBuffer += (MenuName->Length / sizeof(WCHAR)) + 1;
1125  }
1126  else
1127  Class->lpszClientUnicodeMenuName = MenuName->Buffer;
1128 
1129  /* Save an ANSI copy of the string */
1130  if (pszMenuNameBuffer != NULL)
1131  {
1133 
1134  Class->lpszClientAnsiMenuName = (PSTR)pszMenuNameBuffer;
1135  AnsiString.MaximumLength = (USHORT)RtlUnicodeStringToAnsiSize(MenuName);
1136  AnsiString.Buffer = Class->lpszClientAnsiMenuName;
1138  MenuName,
1139  FALSE);
1140  if (!NT_SUCCESS(Status))
1141  {
1142  ERR("Failed to convert unicode menu name to ansi!\n");
1143 
1144  /* Life would've been much prettier if ntoskrnl exported RtlRaiseStatus()... */
1145  _SEH2_LEAVE;
1146  }
1147  }
1148  else
1149  Class->lpszClientAnsiMenuName = (PSTR)MenuName->Buffer;
1150 
1151  /* Save kernel use menu name and ansi class name */
1152  Class->lpszMenuName = Class->lpszClientUnicodeMenuName; // FIXME!
1153  //Class->lpszAnsiClassName = FIXME
1154 
1155  /* Server Side overrides class calling type (A/W)!
1156  User32 whine test_builtinproc: "deftest"
1157  built-in winproc - window A/W type automatically detected */
1158  if (!(Class->CSF_flags & CSF_SERVERSIDEPROC))
1159  {
1160  int i;
1161  WndProc = NULL;
1162  /* Due to the wine class "deftest" and most likely no FNID to reference
1163  from, sort through the Server Side list and compare proc addresses
1164  for match. This method will be used in related code.
1165  */
1166  for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
1167  { // Open ANSI or Unicode, just match, set and break.
1168  if (GETPFNCLIENTW(i) == Class->lpfnWndProc)
1169  {
1170  WndProc = GETPFNSERVER(i);
1171  break;
1172  }
1173  if (GETPFNCLIENTA(i) == Class->lpfnWndProc)
1174  {
1175  WndProc = GETPFNSERVER(i);
1176  break;
1177  }
1178  }
1179  if (WndProc)
1180  { // If a hit, we are Server Side so set the right flags and proc.
1181  Class->CSF_flags |= CSF_SERVERSIDEPROC;
1182  Class->CSF_flags &= ~CSF_ANSIPROC;
1183  Class->lpfnWndProc = WndProc;
1184  }
1185  }
1186 
1187  if (!(Class->CSF_flags & CSF_ANSIPROC))
1188  Class->Unicode = TRUE;
1189 
1190  if (Class->style & CS_GLOBALCLASS)
1191  Class->Global = TRUE;
1192  }
1194  {
1196  }
1197  _SEH2_END;
1198 
1199  if (!NT_SUCCESS(Status))
1200  {
1201  ERR("Failed creating the class: 0x%x\n", Status);
1202 
1204 
1205  if (pszMenuName != NULL)
1206  UserHeapFree(pszMenuName);
1207 
1209  Class);
1210  Class = NULL;
1211 
1212  IntDeregisterClassAtom(verAtom);
1214  }
1215  }
1216  else
1217  {
1218 NoMem:
1219  ERR("Failed to allocate class on Desktop 0x%p\n", Desktop);
1220 
1221  if (pszMenuName != NULL)
1222  UserHeapFree(pszMenuName);
1223 
1225  IntDeregisterClassAtom(verAtom);
1226 
1228  }
1229 
1230  TRACE("Created class 0x%p with name %wZ and proc 0x%p for atom 0x%x and version atom 0x%x and hInstance 0x%p, global %u\n",
1231  Class, ClassName, Class ? Class->lpfnWndProc : NULL, Atom, verAtom,
1232  Class ? Class->hModule : NULL , Class ? Class->Global : 0);
1233 
1234  return Class;
1235 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSYSAPI DWORD WINAPI RtlUnicodeStringToAnsiSize(const UNICODE_STRING *)
#define GETPFNSERVER(fnid)
Definition: ntuser.h:870
unsigned short RTL_ATOM
Definition: atom.c:42
PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
Definition: cursoricon.c:200
#define GETPFNCLIENTW(fnid)
Definition: ntuser.h:867
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
static __inline BOOL UserHeapFree(PVOID lpMem)
Definition: usrheap.h:42
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
static __inline PVOID UserHeapAlloc(SIZE_T Bytes)
Definition: usrheap.h:34
_Out_ RTL_ATOM * Atom
Definition: class.h:54
PSERVERINFO gpsi
Definition: main.c:27
_SEH2_TRY
Definition: create.c:4250
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, IN SIZE_T Bytes)
Definition: desktop.h:230
#define UNICODE_NULL
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
static CHAR Desktop[MAX_PATH]
Definition: dem.c:256
static NTSTATUS IntDeregisterClassAtom(IN RTL_ATOM Atom)
Definition: class.c:393
#define TRACE(s)
Definition: solgame.cpp:4
#define FNID_SWITCH
Definition: ntuser.h:827
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define CS_GLOBALCLASS
Definition: winuser.h:647
static DWORD pi
Definition: protocol.c:150
#define CSF_SERVERSIDEPROC
Definition: ntuser.h:524
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define GETPFNCLIENTA(fnid)
Definition: ntuser.h:865
#define CSF_ANSIPROC
Definition: ntuser.h:525
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Status
Definition: gdiplustypes.h:24
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
Definition: solitaire.cpp:598
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2880
#define ERR(fmt,...)
Definition: debug.h:109
ULONG_PTR SIZE_T
Definition: typedefs.h:78
_SEH2_END
Definition: create.c:4424
unsigned short USHORT
Definition: pedump.c:61
signed char * PSTR
Definition: retypes.h:7
BOOL FASTCALL LookupFnIdToiCls(int FnId, int *iCls)
Definition: class.c:131
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
static __inline BOOL DesktopHeapFree(IN PDESKTOP Desktop, IN PVOID lpMem)
Definition: desktop.h:239
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define _SEH2_LEAVE
Definition: filesup.c:20
static BOOL IntRegisterClassAtom(IN PUNICODE_STRING ClassName, OUT RTL_ATOM *pAtom)
Definition: class.c:334
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define FNID_FIRST
Definition: ntuser.h:820
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1013

Referenced by UserRegisterClass(), and UserRegisterSystemClasses().

◆ IntDereferenceClass()

VOID IntDereferenceClass ( IN OUT PCLS  Class,
IN PDESKTOPINFO  Desktop,
IN PPROCESSINFO  pi 
)

Definition at line 792 of file class.c.

795 {
796  PCLS *PrevLink, BaseClass, CurrentClass;
797 
798  ASSERT(Class->cWndReferenceCount >= 1);
799 
800  BaseClass = Class->pclsBase;
801 
802  if (--Class->cWndReferenceCount == 0)
803  {
804  if (BaseClass == Class)
805  {
806  ASSERT(Class->pclsBase == Class);
807 
808  TRACE("IntDereferenceClass 0x%p\n", Class);
809  /* Check if there are clones of the class on other desktops,
810  link the first clone in if possible. If there are no clones
811  then leave the class on the desktop heap. It will get moved
812  to the shared heap when the thread detaches. */
813  if (BaseClass->pclsClone != NULL)
814  {
815  if (BaseClass->Global)
816  PrevLink = &pi->pclsPublicList;
817  else
818  PrevLink = &pi->pclsPrivateList;
819 
820  CurrentClass = *PrevLink;
821  while (CurrentClass != BaseClass)
822  {
823  ASSERT(CurrentClass != NULL);
824 
825  PrevLink = &CurrentClass->pclsNext;
826  CurrentClass = CurrentClass->pclsNext;
827  }
828 
829  ASSERT(*PrevLink == BaseClass);
830 
831  /* Make the first clone become the new base class */
832  IntMakeCloneBaseClass(BaseClass->pclsClone,
833  PrevLink,
834  &BaseClass->pclsClone);
835 
836  /* Destroy the class, there's still another clone of the class
837  that now serves as a base class. Make sure we don't destruct
838  resources shared by all classes (Base = NULL)! */
839  BaseClass->pclsBase = NULL;
840  BaseClass->pclsClone = NULL;
841  IntDestroyClass(BaseClass);
842  }
843  }
844  else
845  {
846  TRACE("IntDereferenceClass1 0x%p\n", Class);
847 
848  /* Locate the cloned class and unlink it */
849  PrevLink = &BaseClass->pclsClone;
850  CurrentClass = BaseClass->pclsClone;
851  while (CurrentClass != Class)
852  {
853  ASSERT(CurrentClass != NULL);
854 
855  PrevLink = &CurrentClass->pclsNext;
856  CurrentClass = CurrentClass->pclsNext;
857  }
858 
859  ASSERT(CurrentClass == Class);
860 
862  Class->pclsNext);
863 
864  ASSERT(Class->pclsBase == BaseClass);
865  ASSERT(Class->pclsClone == NULL);
866 
867  /* The class was just a clone, we don't need it anymore */
869  }
870  }
871 }
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
UINT Global
Definition: ntuser.h:561
static VOID IntDestroyClass(IN OUT PCLS Class)
Definition: class.c:228
struct _CLS * pclsClone
Definition: ntuser.h:546
static VOID IntMakeCloneBaseClass(IN OUT PCLS Class, IN OUT PCLS *BaseClassLink, IN OUT PCLS *CloneLink)
Definition: class.c:754
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
struct _CLS * pclsBase
Definition: ntuser.h:545
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static DWORD pi
Definition: protocol.c:150
struct _CLS * pclsNext
Definition: ntuser.h:535

Referenced by co_UserCreateWindowEx(), and co_UserFreeWindow().

◆ IntDeregisterClassAtom()

static NTSTATUS IntDeregisterClassAtom ( IN RTL_ATOM  Atom)
static

Definition at line 393 of file class.c.

394 {
396  Atom);
397 }
PRTL_ATOM_TABLE gAtomTable
Definition: session.c:13
_Out_ RTL_ATOM * Atom
Definition: class.h:54
NTSYSAPI NTSTATUS NTAPI RtlDeleteAtomFromAtomTable(_In_ PRTL_ATOM_TABLE AtomTable, _In_ RTL_ATOM Atom)

Referenced by IntCreateClass(), IntDestroyClass(), IntSetClassAtom(), and UserUnregisterClass().

◆ IntDestroyClass()

static VOID IntDestroyClass ( IN OUT PCLS  Class)
static

Definition at line 228 of file class.c.

229 {
230  PDESKTOP pDesk;
231 
232  /* There shouldn't be any clones anymore */
233  ASSERT(Class->cWndReferenceCount == 0);
234  ASSERT(Class->pclsClone == NULL);
235 
236  if (Class->pclsBase == Class)
237  {
238  PCALLPROCDATA CallProc, NextCallProc;
239 
240  /* Destroy allocated callproc handles */
241  CallProc = Class->spcpdFirst;
242  while (CallProc != NULL)
243  {
244  NextCallProc = CallProc->spcpdNext;
245 
246  CallProc->spcpdNext = NULL;
247  DestroyCallProc(CallProc);
248 
249  CallProc = NextCallProc;
250  }
251 
252  // Fixes running the static test then run class test issue.
253  // Some applications do not use UnregisterClass before exiting.
254  // Keep from reusing the same atom with case insensitive
255  // comparisons, remove registration of the atom if not zeroed.
256  if (Class->atomClassName)
257  IntDeregisterClassAtom(Class->atomClassName);
258  // Dereference non-versioned class name
259  if (Class->atomNVClassName)
260  IntDeregisterClassAtom(Class->atomNVClassName);
261 
262  if (Class->pdce)
263  {
264  DceFreeClassDCE(Class->pdce);
265  Class->pdce = NULL;
266  }
267 
269  }
270 
271  if (Class->spicn)
273  if (Class->spcur)
275  if (Class->spicnSm)
276  {
277  UserDereferenceObject(Class->spicnSm);
278  /* Destroy the icon if we own it */
279  if ((Class->CSF_flags & CSF_CACHEDSMICON)
280  && !(UserObjectInDestroy(UserHMGetHandle(Class->spicnSm))))
281  IntDestroyCurIconObject(Class->spicnSm);
282  }
283 
284  pDesk = Class->rpdeskParent;
285  Class->rpdeskParent = NULL;
286 
287  /* Free the structure */
288  if (pDesk != NULL)
289  {
290  DesktopHeapFree(pDesk, Class);
291  }
292  else
293  {
295  }
296 }
static VOID IntFreeClassMenuName(IN OUT PCLS Class)
Definition: class.c:216
static __inline BOOL UserHeapFree(PVOID lpMem)
Definition: usrheap.h:42
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:610
struct _CALLPROCDATA * spcpdNext
Definition: ntuser.h:519
#define CSF_CACHEDSMICON
Definition: ntuser.h:530
BOOLEAN DestroyCallProc(_Inout_ PVOID Object)
Definition: callproc.c:22
smooth NULL
Definition: ftsmooth.c:416
BOOL FASTCALL UserObjectInDestroy(HANDLE h)
Definition: object.c:669
#define UserHMGetHandle(obj)
Definition: ntuser.h:208
static NTSTATUS IntDeregisterClassAtom(IN RTL_ATOM Atom)
Definition: class.c:393
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOLEAN IntDestroyCurIconObject(_In_ PVOID Object)
Definition: cursoricon.c:313
static __inline BOOL DesktopHeapFree(IN PDESKTOP Desktop, IN PVOID lpMem)
Definition: desktop.h:239
void FASTCALL DceFreeClassDCE(PDCE)
Definition: windc.c:761

Referenced by DestroyProcessClasses(), IntCheckDesktopClasses(), IntDereferenceClass(), IntGetClassForDesktop(), IntMoveClassToSharedHeap(), and UserUnregisterClass().

◆ IntFindClass()

static PCLS IntFindClass ( IN RTL_ATOM  Atom,
IN HINSTANCE  hInstance,
IN PCLS ClassList,
OUT PCLS **Link  OPTIONAL 
)
static

Definition at line 1238 of file class.c.

1242 {
1243  PCLS Class, *PrevLink = ClassList;
1244 
1245  Class = *PrevLink;
1246  while (Class != NULL)
1247  {
1248  if (Class->atomClassName == Atom &&
1249  (hInstance == NULL || Class->hModule == hInstance) &&
1250  !(Class->CSF_flags & CSF_WOWDEFERDESTROY))
1251  {
1252  ASSERT(Class->pclsBase == Class);
1253 
1254  if (Link != NULL)
1255  *Link = PrevLink;
1256  break;
1257  }
1258 
1259  PrevLink = &Class->pclsNext;
1260  Class = Class->pclsNext;
1261  }
1262 
1263  return Class;
1264 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
_Out_ RTL_ATOM * Atom
Definition: class.h:54
static int Link(const char **args)
Definition: vfdcmd.c:2414
HINSTANCE hInstance
Definition: charmap.c:20
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define CSF_WOWDEFERDESTROY
Definition: ntuser.h:526

Referenced by IntGetClassAtom(), and UserRegisterClass().

◆ IntFreeClassMenuName()

static VOID IntFreeClassMenuName ( IN OUT PCLS  Class)
static

Definition at line 216 of file class.c.

217 {
218  /* Free the menu name, if it was changed and allocated */
219  if (Class->lpszClientUnicodeMenuName != NULL && Class->MenuNameIsString)
220  {
221  UserHeapFree(Class->lpszClientUnicodeMenuName);
222  Class->lpszClientUnicodeMenuName = NULL;
223  Class->lpszClientAnsiMenuName = NULL;
224  }
225 }
static __inline BOOL UserHeapFree(PVOID lpMem)
Definition: usrheap.h:42
smooth NULL
Definition: ftsmooth.c:416

Referenced by IntDestroyClass(), and IntSetClassMenuName().

◆ IntGetAndReferenceClass()

PCLS IntGetAndReferenceClass ( PUNICODE_STRING  ClassName,
HINSTANCE  hInstance,
BOOL  bDesktopThread 
)

Definition at line 1407 of file class.c.

1408 {
1409  PCLS *ClassLink, Class = NULL;
1410  RTL_ATOM ClassAtom;
1411  PTHREADINFO pti;
1412 
1413  if (bDesktopThread)
1414  pti = gptiDesktopThread;
1415  else
1417 
1418  if ( !(pti->ppi->W32PF_flags & W32PF_CLASSESREGISTERED ))
1419  {
1421  }
1422 
1423  /* Check the class. */
1424 
1425  TRACE("Finding Class %wZ for hInstance 0x%p\n", ClassName, hInstance);
1426 
1427  ClassAtom = IntGetClassAtom(ClassName,
1428  hInstance,
1429  pti->ppi,
1430  &Class,
1431  &ClassLink);
1432 
1433  if (ClassAtom == (RTL_ATOM)0)
1434  {
1435  if (IS_ATOM(ClassName->Buffer))
1436  {
1437  ERR("Class 0x%p not found\n", ClassName->Buffer);
1438  }
1439  else
1440  {
1441  ERR("Class \"%wZ\" not found\n", ClassName);
1442  }
1443 
1444  return NULL;
1445  }
1446 
1447  TRACE("Referencing Class 0x%p with atom 0x%x\n", Class, ClassAtom);
1449  ClassLink,
1450  pti->rpdesk);
1451  if (Class == NULL)
1452  {
1453  ERR("Failed to reference window class!\n");
1454  return NULL;
1455  }
1456 
1457  return Class;
1458 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
unsigned short RTL_ATOM
Definition: atom.c:42
BOOL FASTCALL UserRegisterSystemClasses(VOID)
Definition: class.c:2276
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
struct _DESKTOP * rpdesk
Definition: win32.h:91
PPROCESSINFO ppi
Definition: win32.h:87
PTHREADINFO gptiDesktopThread
Definition: desktop.c:37
HINSTANCE hInstance
Definition: charmap.c:20
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
#define TRACE(s)
Definition: solgame.cpp:4
#define ERR(fmt,...)
Definition: debug.h:109
#define W32PF_CLASSESREGISTERED
Definition: win32.h:17
PCLS IntReferenceClass(IN OUT PCLS BaseClass, IN OUT PCLS *ClassLink, IN PDESKTOP Desktop)
Definition: class.c:726
RTL_ATOM IntGetClassAtom(_In_ PUNICODE_STRING ClassName, IN HINSTANCE hInstance OPTIONAL, IN PPROCESSINFO pi OPTIONAL, OUT PCLS *BaseClass OPTIONAL, OUT PCLS **Link OPTIONAL)
Definition: class.c:1334
#define IS_ATOM(x)
Definition: class.h:3

Referenced by co_UserCreateWindowEx(), and IntCreateDesktop().

◆ IntGetClassAtom()

RTL_ATOM IntGetClassAtom ( _In_ PUNICODE_STRING  ClassName,
IN HINSTANCE hInstance  OPTIONAL,
IN PPROCESSINFO pi  OPTIONAL,
OUT PCLS *BaseClass  OPTIONAL,
OUT PCLS **Link  OPTIONAL 
)

Definition at line 1334 of file class.c.

1340 {
1341  RTL_ATOM Atom = (RTL_ATOM)0;
1342 
1343  ASSERT(BaseClass != NULL);
1344 
1345  if (IntGetAtomFromStringOrAtom(ClassName, &Atom) &&
1346  Atom != (RTL_ATOM)0)
1347  {
1348  PCLS Class;
1349 
1350  /* Attempt to locate the class object */
1351 
1352  ASSERT(pi != NULL);
1353 
1354  /* Step 1: Try to find an exact match of locally registered classes */
1356  hInstance,
1357  &pi->pclsPrivateList,
1358  Link);
1359  if (Class != NULL)
1360  { TRACE("Step 1: 0x%p\n",Class );
1361  goto FoundClass;
1362  }
1363 
1364  /* Step 2: Try to find any globally registered class. The hInstance
1365  is not relevant for global classes */
1367  NULL,
1368  &pi->pclsPublicList,
1369  Link);
1370  if (Class != NULL)
1371  { TRACE("Step 2: 0x%p 0x%p\n",Class, Class->hModule);
1372  goto FoundClass;
1373  }
1374 
1375  /* Step 3: Try to find any local class registered by user32 */
1377  hModClient,
1378  &pi->pclsPrivateList,
1379  Link);
1380  if (Class != NULL)
1381  { TRACE("Step 3: 0x%p\n",Class );
1382  goto FoundClass;
1383  }
1384 
1385  /* Step 4: Try to find any global class registered by user32 */
1387  hModClient,
1388  &pi->pclsPublicList,
1389  Link);
1390  if (Class == NULL)
1391  {
1392  return (RTL_ATOM)0;
1393  }else{TRACE("Step 4: 0x%p\n",Class );}
1394 
1395 FoundClass:
1396  *BaseClass = Class;
1397  }
1398  else
1399  {
1400  Atom = 0;
1401  }
1402 
1403  return Atom;
1404 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
unsigned short RTL_ATOM
Definition: atom.c:42
_Out_ RTL_ATOM * Atom
Definition: class.h:54
static int Link(const char **args)
Definition: vfdcmd.c:2414
HINSTANCE hInstance
Definition: charmap.c:20
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
#define TRACE(s)
Definition: solgame.cpp:4
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static DWORD pi
Definition: protocol.c:150
static PCLS IntFindClass(IN RTL_ATOM Atom, IN HINSTANCE hInstance, IN PCLS *ClassList, OUT PCLS **Link OPTIONAL)
Definition: class.c:1238
HINSTANCE hModClient
Definition: ntuser.c:25

Referenced by IntGetAndReferenceClass(), NtUserGetClassInfo(), NtUserGetWOWClass(), and UserUnregisterClass().

◆ IntGetClassForDesktop()

static PCLS IntGetClassForDesktop ( IN OUT PCLS  BaseClass,
IN OUT PCLS ClassLink,
IN PDESKTOP  Desktop 
)
static

Definition at line 602 of file class.c.

605 {
606  SIZE_T ClassSize;
607  PCLS Class;
608 
609  ASSERT(Desktop != NULL);
610  ASSERT(BaseClass->pclsBase == BaseClass);
611 
612  if (BaseClass->rpdeskParent == Desktop)
613  {
614  /* It is most likely that a window is created on the same
615  desktop as the window class. */
616 
617  return BaseClass;
618  }
619 
620  if (BaseClass->rpdeskParent == NULL)
621  {
622  ASSERT(BaseClass->cWndReferenceCount == 0);
623  ASSERT(BaseClass->pclsClone == NULL);
624 
625  /* Classes are also located in the shared heap when the class
626  was created before the thread attached to a desktop. As soon
627  as a window is created for such a class located on the shared
628  heap, the class is cloned into the desktop heap on which the
629  window is created. */
630  Class = NULL;
631  }
632  else
633  {
634  /* The user is asking for a class object on a different desktop,
635  try to find one! */
636  Class = BaseClass->pclsClone;
637  while (Class != NULL)
638  {
639  if (Class->rpdeskParent == Desktop)
640  {
641  ASSERT(Class->pclsBase == BaseClass);
642  ASSERT(Class->pclsClone == NULL);
643  break;
644  }
645 
646  Class = Class->pclsNext;
647  }
648  }
649 
650  if (Class == NULL)
651  {
652  /* The window is created on a different desktop, we need to
653  clone the class object to the desktop heap of the window! */
654  ClassSize = sizeof(*BaseClass) + (SIZE_T)BaseClass->cbclsExtra;
655 
657  ClassSize);
658 
659  if (Class != NULL)
660  {
661  /* Simply clone the class */
662  RtlCopyMemory( Class, BaseClass, ClassSize);
663 
664  /* Reference our objects */
665  if (Class->spcur)
666  UserReferenceObject(Class->spcur);
667  if (Class->spicn)
668  UserReferenceObject(Class->spicn);
669  if (Class->spicnSm)
670  UserReferenceObject(Class->spicnSm);
671 
672  TRACE("Clone Class 0x%p hM 0x%p\n %S\n",Class, Class->hModule, Class->lpszClientUnicodeMenuName);
673 
674  /* Restore module address if default user class Ref: Bug 4778 */
675  if ( Class->hModule != hModClient &&
676  Class->fnid <= FNID_GHOST &&
677  Class->fnid >= FNID_BUTTON )
678  {
679  Class->hModule = hModClient;
680  TRACE("Clone Class 0x%p Reset hM 0x%p\n",Class, Class->hModule);
681  }
682 
683  /* Update some pointers and link the class */
684  Class->rpdeskParent = Desktop;
685  Class->cWndReferenceCount = 0;
686 
687  if (BaseClass->rpdeskParent == NULL)
688  {
689  /* We don't really need the base class on the shared
690  heap anymore, delete it so the only class left is
691  the clone we just created, which now serves as the
692  new base class */
693  ASSERT(BaseClass->pclsClone == NULL);
694  ASSERT(Class->pclsClone == NULL);
695  Class->pclsBase = Class;
696  Class->pclsNext = BaseClass->pclsNext;
697 
698  /* Replace the base class */
700  Class);
701 
702  /* Destroy the obsolete copy on the shared heap */
703  BaseClass->pclsBase = NULL;
704  BaseClass->pclsClone = NULL;
705  IntDestroyClass(BaseClass);
706  }
707  else
708  {
709  /* Link in the clone */
710  Class->pclsClone = NULL;
711  Class->pclsBase = BaseClass;
712  Class->pclsNext = BaseClass->pclsClone;
713  (void)InterlockedExchangePointer((PVOID*)&BaseClass->pclsClone,
714  Class);
715  }
716  }
717  else
718  {
720  }
721  }
722  return Class;
723 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
static VOID IntDestroyClass(IN OUT PCLS Class)
Definition: class.c:228
static __inline PVOID DesktopHeapAlloc(IN PDESKTOP Desktop, IN SIZE_T Bytes)
Definition: desktop.h:230
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
static CHAR Desktop[MAX_PATH]
Definition: dem.c:256
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define FNID_GHOST
Definition: ntuser.h:837
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define FNID_BUTTON
Definition: ntuser.h:828
HINSTANCE hModClient
Definition: ntuser.c:25
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:697

Referenced by IntReferenceClass().

◆ IntGetClassWndProc()

WNDPROC FASTCALL IntGetClassWndProc ( PCLS  Class,
BOOL  Ansi 
)

Definition at line 471 of file class.c.

472 {
473  INT i;
474  WNDPROC gcpd = NULL, Ret = NULL;
475 
476  if (Class->CSF_flags & CSF_SERVERSIDEPROC)
477  {
478  for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
479  {
480  if (GETPFNSERVER(i) == Class->lpfnWndProc)
481  {
482  if (Ansi)
483  Ret = GETPFNCLIENTA(i);
484  else
485  Ret = GETPFNCLIENTW(i);
486  }
487  }
488  return Ret;
489  }
490  Ret = Class->lpfnWndProc;
491 
492  if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
493  {
494  if (Ansi)
495  {
496  if (GETPFNCLIENTW(Class->fnid) == Class->lpfnWndProc)
497  Ret = GETPFNCLIENTA(Class->fnid);
498  }
499  else
500  {
501  if (GETPFNCLIENTA(Class->fnid) == Class->lpfnWndProc)
502  Ret = GETPFNCLIENTW(Class->fnid);
503  }
504  }
505 
506  if ( Ret != Class->lpfnWndProc ||
507  Ansi == !!(Class->CSF_flags & CSF_ANSIPROC) )
508  return Ret;
509 
510  gcpd = (WNDPROC)UserGetCPD( Class,
512  (ULONG_PTR)Ret);
513 
514  return (gcpd ? gcpd : Ret);
515 }
#define GETPFNSERVER(fnid)
Definition: ntuser.h:870
#define GETPFNCLIENTW(fnid)
Definition: ntuser.h:867
ULONG_PTR FASTCALL UserGetCPD(PVOID pvClsWnd, GETCPD Flags, ULONG_PTR ProcIn)
Definition: callproc.c:107
int32_t INT
Definition: typedefs.h:56
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
smooth NULL
Definition: ftsmooth.c:416
#define FNID_SWITCH
Definition: ntuser.h:827
#define CSF_SERVERSIDEPROC
Definition: ntuser.h:524
#define GETPFNCLIENTA(fnid)
Definition: ntuser.h:865
#define CSF_ANSIPROC
Definition: ntuser.h:525
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2880
#define FNID_GHOST
Definition: ntuser.h:837
#define FNID_BUTTON
Definition: ntuser.h:828
#define ULONG_PTR
Definition: config.h:101
#define FNID_FIRST
Definition: ntuser.h:820

Referenced by IntSetClassWndProc(), and UserGetClassInfo().

◆ IntMakeCloneBaseClass()

static VOID IntMakeCloneBaseClass ( IN OUT PCLS  Class,
IN OUT PCLS BaseClassLink,
IN OUT PCLS CloneLink 
)
static

Definition at line 754 of file class.c.

757 {
758  PCLS Clone;
759 
760  ASSERT(Class->pclsBase != Class);
761  ASSERT(Class->pclsBase->pclsClone != NULL);
762  ASSERT(Class->rpdeskParent != NULL);
763  ASSERT(Class->cWndReferenceCount != 0);
764  ASSERT(Class->pclsBase->rpdeskParent != NULL);
765  ASSERT(Class->pclsBase->cWndReferenceCount == 0);
766 
767  /* Unlink the clone */
768  *CloneLink = Class->pclsNext;
769  Class->pclsClone = Class->pclsBase->pclsClone;
770 
771  /* Update the class information to make it a base class */
772  Class->pclsBase = Class;
773  Class->pclsNext = (*BaseClassLink)->pclsNext;
774 
775  /* Update all clones */
776  Clone = Class->pclsClone;
777  while (Clone != NULL)
778  {
779  ASSERT(Clone->pclsClone == NULL);
780  Clone->pclsBase = Class;
781 
782  Clone = Clone->pclsNext;
783  }
784 
785  /* Link in the new base class */
786  (void)InterlockedExchangePointer((PVOID*)BaseClassLink,
787  Class);
788 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
struct _CLS * pclsClone
Definition: ntuser.h:546
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
struct _CLS * pclsBase
Definition: ntuser.h:545
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _CLS * pclsNext
Definition: ntuser.h:535

Referenced by IntDereferenceClass().

◆ IntMoveClassToSharedHeap()

static BOOL IntMoveClassToSharedHeap ( IN OUT PCLS  Class,
IN OUT PCLS **  ClassLinkPtr 
)
static

Definition at line 874 of file class.c.

876 {
877  PCLS NewClass;
878  SIZE_T ClassSize;
879 
880  ASSERT(Class->pclsBase == Class);
881  ASSERT(Class->rpdeskParent != NULL);
882  ASSERT(Class->cWndReferenceCount == 0);
883  ASSERT(Class->pclsClone == NULL);
884 
885  ClassSize = sizeof(*Class) + (SIZE_T)Class->cbclsExtra;
886 
887  /* Allocate the new base class on the shared heap */
888  NewClass = UserHeapAlloc(ClassSize);
889  if (NewClass != NULL)
890  {
891  RtlCopyMemory(NewClass,
892  Class,
893  ClassSize);
894 
895  NewClass->rpdeskParent = NULL;
896  NewClass->pclsBase = NewClass;
897 
898  if (NewClass->spcur)
899  UserReferenceObject(NewClass->spcur);
900  if (NewClass->spicn)
901  UserReferenceObject(NewClass->spicn);
902  if (NewClass->spicnSm)
903  UserReferenceObject(NewClass->spicnSm);
904 
905  /* Replace the class in the list */
906  (void)InterlockedExchangePointer((PVOID*)*ClassLinkPtr,
907  NewClass);
908  *ClassLinkPtr = &NewClass->pclsNext;
909 
910  /* Free the obsolete class on the desktop heap */
911  Class->pclsBase = NULL;
913  return TRUE;
914  }
915 
916  return FALSE;
917 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
struct _DESKTOP * rpdeskParent
Definition: ntuser.h:539
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
struct _CURICON_OBJECT * spcur
Definition: ntuser.h:554
static __inline PVOID UserHeapAlloc(SIZE_T Bytes)
Definition: usrheap.h:34
static VOID IntDestroyClass(IN OUT PCLS Class)
Definition: class.c:228
struct _CURICON_OBJECT * spicn
Definition: ntuser.h:553
struct _CURICON_OBJECT * spicnSm
Definition: ntuser.h:558
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
struct _CLS * pclsBase
Definition: ntuser.h:545
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
ULONG_PTR SIZE_T
Definition: typedefs.h:78
struct _CLS * pclsNext
Definition: ntuser.h:535
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:697

Referenced by IntCheckDesktopClasses().

◆ IntReferenceClass()

PCLS IntReferenceClass ( IN OUT PCLS  BaseClass,
IN OUT PCLS ClassLink,
IN PDESKTOP  Desktop 
)

Definition at line 726 of file class.c.

729 {
730  PCLS Class;
731  ASSERT(BaseClass->pclsBase == BaseClass);
732 
733  if (Desktop != NULL)
734  {
735  Class = IntGetClassForDesktop(BaseClass,
736  ClassLink,
737  Desktop);
738  }
739  else
740  {
741  Class = BaseClass;
742  }
743 
744  if (Class != NULL)
745  {
746  Class->cWndReferenceCount++;
747  }
748 
749  return Class;
750 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
static PCLS IntGetClassForDesktop(IN OUT PCLS BaseClass, IN OUT PCLS *ClassLink, IN PDESKTOP Desktop)
Definition: class.c:602
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

Referenced by IntGetAndReferenceClass().

◆ IntRegisterClassAtom()

static BOOL IntRegisterClassAtom ( IN PUNICODE_STRING  ClassName,
OUT RTL_ATOM pAtom 
)
static

Definition at line 334 of file class.c.

336 {
337  WCHAR szBuf[65];
338  PWSTR AtomName;
340 
341  if (ClassName->Length != 0)
342  {
343  /* FIXME: Don't limit to 64 characters! Use SEH when allocating memory! */
344  if (ClassName->Length / sizeof(WCHAR) >= sizeof(szBuf) / sizeof(szBuf[0]))
345  {
347  return (RTL_ATOM)0;
348  }
349 
350  RtlCopyMemory(szBuf,
351  ClassName->Buffer,
352  ClassName->Length);
353  szBuf[ClassName->Length / sizeof(WCHAR)] = UNICODE_NULL;
354  AtomName = szBuf;
355  }
356  else
357  AtomName = ClassName->Buffer;
358 
360  AtomName,
361  pAtom);
362 
363  if (!NT_SUCCESS(Status))
364  {
366  return FALSE;
367  }
368 
369  return TRUE;
370 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
unsigned short RTL_ATOM
Definition: atom.c:42
uint16_t * PWSTR
Definition: typedefs.h:54
NTSYSAPI NTSTATUS NTAPI RtlAddAtomToAtomTable(_In_ PRTL_ATOM_TABLE AtomTable, _In_ PWSTR AtomName, _Out_ PRTL_ATOM Atom)
LONG NTSTATUS
Definition: precomp.h:26
PRTL_ATOM_TABLE gAtomTable
Definition: session.c:13
#define UNICODE_NULL
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Status
Definition: gdiplustypes.h:24
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by IntCreateClass(), IntSetClassAtom(), and RegisterControlAtoms().

◆ IntSetClassAtom()

static BOOL IntSetClassAtom ( IN OUT PCLS  Class,
IN PUNICODE_STRING  ClassName 
)
static

Definition at line 422 of file class.c.

424 {
425  RTL_ATOM Atom = (RTL_ATOM)0;
426 
427  /* Update the base class first */
428  Class = Class->pclsBase;
429  if (ClassName->Length > 0)
430  {
431  if (!IntRegisterClassAtom(ClassName,
432  &Atom))
433  {
434  ERR("RegisterClassAtom failed ! %x\n", EngGetLastError());
435  return FALSE;
436  }
437  }
438  else
439  {
440  if (IS_ATOM(ClassName->Buffer))
441  {
442  Atom = (ATOM)((ULONG_PTR)ClassName->Buffer & 0xffff); // XXX: are we missing refcount here ?
443  }
444  else
445  {
447  return FALSE;
448  }
449  }
450 
451  IntDeregisterClassAtom(Class->atomNVClassName);
452 
453  Class->atomNVClassName = Atom;
454 
455  /* Update the clones */
456  Class = Class->pclsClone;
457  while (Class != NULL)
458  {
459  Class->atomNVClassName = Atom;
460 
461  Class = Class->pclsNext;
462  }
463 
464  return TRUE;
465 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define TRUE
Definition: types.h:120
ENGAPI ULONG APIENTRY EngGetLastError(VOID)
Definition: error.c:12
unsigned short RTL_ATOM
Definition: atom.c:42
WORD ATOM
Definition: dimm.idl:113
_Out_ RTL_ATOM * Atom
Definition: class.h:54
uint32_t ULONG_PTR
Definition: typedefs.h:63
smooth NULL
Definition: ftsmooth.c:416
static NTSTATUS IntDeregisterClassAtom(IN RTL_ATOM Atom)
Definition: class.c:393
#define ERR(fmt,...)
Definition: debug.h:109
#define IS_ATOM(x)
Definition: class.h:3
static BOOL IntRegisterClassAtom(IN PUNICODE_STRING ClassName, OUT RTL_ATOM *pAtom)
Definition: class.c:334
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by UserSetClassLongPtr().

◆ IntSetClassMenuName()

static BOOL IntSetClassMenuName ( IN PCLS  Class,
IN PUNICODE_STRING  MenuName 
)
static

Definition at line 1724 of file class.c.

1726 {
1727  BOOL Ret = FALSE;
1728 
1729  /* Change the base class first */
1730  Class = Class->pclsBase;
1731 
1732  if (MenuName->Length != 0)
1733  {
1735  PWSTR strBufW;
1736 
1737  AnsiString.MaximumLength = (USHORT)RtlUnicodeStringToAnsiSize(MenuName);
1738 
1739  strBufW = UserHeapAlloc(MenuName->Length + sizeof(UNICODE_NULL) +
1740  AnsiString.MaximumLength);
1741  if (strBufW != NULL)
1742  {
1743  _SEH2_TRY
1744  {
1745  NTSTATUS Status;
1746 
1747  /* Copy the unicode string */
1748  RtlCopyMemory(strBufW,
1749  MenuName->Buffer,
1750  MenuName->Length);
1751  strBufW[MenuName->Length / sizeof(WCHAR)] = UNICODE_NULL;
1752 
1753  /* Create an ANSI copy of the string */
1754  AnsiString.Buffer = (PSTR)(strBufW + (MenuName->Length / sizeof(WCHAR)) + 1);
1756  MenuName,
1757  FALSE);
1758  if (!NT_SUCCESS(Status))
1759  {
1761  _SEH2_LEAVE;
1762  }
1763 
1764  Ret = TRUE;
1765  }
1767  {
1769  }
1770  _SEH2_END;
1771 
1772  if (Ret)
1773  {
1774  /* Update the base class */
1776  Class->lpszClientUnicodeMenuName = strBufW;
1777  Class->lpszClientAnsiMenuName = AnsiString.Buffer;
1778  Class->MenuNameIsString = TRUE;
1779 
1780  /* Update the clones */
1781  Class = Class->pclsClone;
1782  while (Class != NULL)
1783  {
1784  Class->lpszClientUnicodeMenuName = strBufW;
1785  Class->lpszClientAnsiMenuName = AnsiString.Buffer;
1786  Class->MenuNameIsString = TRUE;
1787 
1788  Class = Class->pclsNext;
1789  }
1790  }
1791  else
1792  {
1793  ERR("Failed to copy class menu name!\n");
1794  UserHeapFree(strBufW);
1795  }
1796  }
1797  else
1799  }
1800  else
1801  {
1802  ASSERT(IS_INTRESOURCE(MenuName->Buffer));
1803 
1804  /* Update the base class */
1806  Class->lpszClientUnicodeMenuName = MenuName->Buffer;
1807  Class->lpszClientAnsiMenuName = (PSTR)MenuName->Buffer;
1808  Class->MenuNameIsString = FALSE;
1809 
1810  /* Update the clones */
1811  Class = Class->pclsClone;
1812  while (Class != NULL)
1813  {
1814  Class->lpszClientUnicodeMenuName = MenuName->Buffer;
1815  Class->lpszClientAnsiMenuName = (PSTR)MenuName->Buffer;
1816  Class->MenuNameIsString = FALSE;
1817 
1818  Class = Class->pclsNext;
1819  }
1820 
1821  Ret = TRUE;
1822  }
1823 
1824  return Ret;
1825 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSYSAPI DWORD WINAPI RtlUnicodeStringToAnsiSize(const UNICODE_STRING *)
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
static VOID IntFreeClassMenuName(IN OUT PCLS Class)
Definition: class.c:216
static __inline BOOL UserHeapFree(PVOID lpMem)
Definition: usrheap.h:42
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
static __inline PVOID UserHeapAlloc(SIZE_T Bytes)
Definition: usrheap.h:34
_SEH2_TRY
Definition: create.c:4250
while(1)
Definition: macro.lex.yy.c:740
#define UNICODE_NULL
unsigned int BOOL
Definition: ntddk_ex.h:94
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
_SEH2_END
Definition: create.c:4424
unsigned short USHORT
Definition: pedump.c:61
signed char * PSTR
Definition: retypes.h:7
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define _SEH2_LEAVE
Definition: filesup.c:20
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by UserSetClassLongPtr().

◆ IntSetClassWndProc()

static WNDPROC FASTCALL IntSetClassWndProc ( IN OUT PCLS  Class,
IN WNDPROC  WndProc,
IN BOOL  Ansi 
)
static

Definition at line 520 of file class.c.

523 {
524  INT i;
525  PCALLPROCDATA pcpd;
526  WNDPROC Ret, chWndProc;
527 
528  Ret = IntGetClassWndProc(Class, Ansi);
529 
530  // If Server Side, downgrade to Client Side.
531  if (Class->CSF_flags & CSF_SERVERSIDEPROC)
532  {
533  if (Ansi) Class->CSF_flags |= CSF_ANSIPROC;
534  Class->CSF_flags &= ~CSF_SERVERSIDEPROC;
535  Class->Unicode = !Ansi;
536  }
537 
538  if (!WndProc) WndProc = Class->lpfnWndProc;
539 
540  chWndProc = WndProc;
541 
542  // Check if CallProc handle and retrieve previous call proc address and set.
544  {
546  if (pcpd) chWndProc = pcpd->pfnClientPrevious;
547  }
548 
549  Class->lpfnWndProc = chWndProc;
550 
551  // Clear test proc.
552  chWndProc = NULL;
553 
554  // Switch from Client Side call to Server Side call if match. Ref: "deftest".
555  for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
556  {
557  if (GETPFNCLIENTW(i) == Class->lpfnWndProc)
558  {
559  chWndProc = GETPFNSERVER(i);
560  break;
561  }
562  if (GETPFNCLIENTA(i) == Class->lpfnWndProc)
563  {
564  chWndProc = GETPFNSERVER(i);
565  break;
566  }
567  }
568  // If match, set/reset to Server Side and clear ansi.
569  if (chWndProc)
570  {
571  Class->lpfnWndProc = chWndProc;
572  Class->Unicode = TRUE;
573  Class->CSF_flags &= ~CSF_ANSIPROC;
574  Class->CSF_flags |= CSF_SERVERSIDEPROC;
575  }
576  else
577  {
578  Class->Unicode = !Ansi;
579 
580  if (Ansi)
581  Class->CSF_flags |= CSF_ANSIPROC;
582  else
583  Class->CSF_flags &= ~CSF_ANSIPROC;
584  }
585 
586  /* Update the clones */
587  chWndProc = Class->lpfnWndProc;
588 
589  Class = Class->pclsClone;
590  while (Class != NULL)
591  {
592  Class->Unicode = !Ansi;
593  Class->lpfnWndProc = chWndProc;
594 
595  Class = Class->pclsNext;
596  }
597 
598  return Ret;
599 }
#define TRUE
Definition: types.h:120
#define GETPFNSERVER(fnid)
Definition: ntuser.h:870
WNDPROC pfnClientPrevious
Definition: ntuser.h:520
#define GETPFNCLIENTW(fnid)
Definition: ntuser.h:867
int32_t INT
Definition: typedefs.h:56
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
smooth NULL
Definition: ftsmooth.c:416
#define FNID_SWITCH
Definition: ntuser.h:827
#define CSF_SERVERSIDEPROC
Definition: ntuser.h:524
#define GETPFNCLIENTA(fnid)
Definition: ntuser.h:865
#define CSF_ANSIPROC
Definition: ntuser.h:525
LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
Definition: solitaire.cpp:598
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2880
PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, HANDLE_TYPE type)
Definition: object.c:462
WNDPROC FASTCALL IntGetClassWndProc(PCLS Class, BOOL Ansi)
Definition: class.c:471
static __inline BOOL IsCallProcHandle(IN WNDPROC lpWndProc)
Definition: class.h:13
PUSER_HANDLE_TABLE gHandleTable
Definition: object.c:13
#define FNID_FIRST
Definition: ntuser.h:820

Referenced by UserSetClassLongPtr().

◆ LookupFnIdToiCls()

BOOL FASTCALL LookupFnIdToiCls ( int  FnId,
int iCls 
)

Definition at line 131 of file class.c.

132 {
133  int i;
134 
135  for ( i = 0; i < ARRAYSIZE(FnidToiCls); i++)
136  {
137  if (FnidToiCls[i].FnId == FnId)
138  {
139  if (iCls) *iCls = FnidToiCls[i].ClsId;
140  return TRUE;
141  }
142  }
143  if (iCls) *iCls = 0;
144  return FALSE;
145 }
#define TRUE
Definition: types.h:120
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
int FnId
Definition: class.c:106
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static struct @4133 FnidToiCls[]

Referenced by IntCreateClass(), IntIsGhostWindow(), and NtUserGetClassName().

◆ NtUserGetClassInfo()

BOOL APIENTRY NtUserGetClassInfo ( HINSTANCE  hInstance,
PUNICODE_STRING  ClassName,
LPWNDCLASSEXW  lpWndClassEx,
LPWSTR ppszMenuName,
BOOL  bAnsi 
)

Definition at line 2690 of file class.c.

2696 {
2697  UNICODE_STRING SafeClassName;
2698  WNDCLASSEXW Safewcexw;
2699  PCLS Class;
2700  RTL_ATOM ClassAtom = 0;
2701  PPROCESSINFO ppi;
2702  BOOL Ret = TRUE;
2703  NTSTATUS Status;
2704 
2705  _SEH2_TRY
2706  {
2707  ProbeForWrite( lpWndClassEx, sizeof(WNDCLASSEXW), sizeof(ULONG));
2708  RtlCopyMemory( &Safewcexw, lpWndClassEx, sizeof(WNDCLASSEXW));
2709  }
2711  {
2713  _SEH2_YIELD(return FALSE);
2714  }
2715  _SEH2_END;
2716 
2717  Status = ProbeAndCaptureUnicodeStringOrAtom(&SafeClassName, ClassName);
2718  if (!NT_SUCCESS(Status))
2719  {
2720  ERR("Error capturing the class name\n");
2722  return FALSE;
2723  }
2724 
2725  // If null instance use client.
2726  if (!hInstance) hInstance = hModClient;
2727 
2728  TRACE("GetClassInfo(%wZ, %p)\n", &SafeClassName, hInstance);
2729 
2730  /* NOTE: Need exclusive lock because getting the wndproc might require the
2731  creation of a call procedure handle */
2733 
2734  ppi = GetW32ProcessInfo();
2735  if (!(ppi->W32PF_flags & W32PF_CLASSESREGISTERED))
2736  {
2738  }
2739 
2740  ClassAtom = IntGetClassAtom(&SafeClassName,
2741  hInstance,
2742  ppi,
2743  &Class,
2744  NULL);
2745  if (ClassAtom != (RTL_ATOM)0)
2746  {
2747  ClassAtom = Class->atomNVClassName;
2748  Ret = UserGetClassInfo(Class, &Safewcexw, bAnsi, hInstance);
2749  }
2750  else
2751  {
2753  Ret = FALSE;
2754  }
2755 
2756  UserLeave();
2757 
2758  if (Ret)
2759  {
2760  _SEH2_TRY
2761  {
2762  /* Emulate Function. */
2763  if (ppszMenuName) *ppszMenuName = (LPWSTR)Safewcexw.lpszMenuName;
2764 
2765  RtlCopyMemory(lpWndClassEx, &Safewcexw, sizeof(WNDCLASSEXW));
2766 
2767  // From Wine:
2768  /* We must return the atom of the class here instead of just TRUE. */
2769  /* Undocumented behavior! Return the class atom as a BOOL! */
2770  Ret = (BOOL)ClassAtom;
2771  }
2773  {
2775  Ret = FALSE;
2776  }
2777  _SEH2_END;
2778  }
2779 
2780  if (!IS_ATOM(SafeClassName.Buffer))
2781  ExFreePoolWithTag(SafeClassName.Buffer, TAG_STRING);
2782 
2783  return Ret;
2784 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
unsigned short RTL_ATOM
Definition: atom.c:42
static BOOL UserGetClassInfo(IN PCLS Class, OUT PWNDCLASSEXW lpwcx, IN BOOL Ansi, HINSTANCE hInstance)
Definition: class.c:2219
BOOL FASTCALL UserRegisterSystemClasses(VOID)
Definition: class.c:2276
LONG NTSTATUS
Definition: precomp.h:26
#define BOOL
Definition: nt_native.h:43
_Must_inspect_result_ NTSTATUS NTAPI ProbeAndCaptureUnicodeStringOrAtom(_Out_ _When_(return >=0, _At_(pustrOut->Buffer, _Post_ _Notnull_)) PUNICODE_STRING pustrOut, __in_data_source(USER_MODE) _In_ PUNICODE_STRING pustrUnsafe)
Definition: class.c:150
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
_SEH2_TRY
Definition: create.c:4250
HINSTANCE hInstance
Definition: charmap.c:20
LPCWSTR lpszMenuName
Definition: winuser.h:3199
unsigned int BOOL
Definition: ntddk_ex.h:94
#define TAG_STRING
Definition: oslist.h:22
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
struct _PROCESSINFO * GetW32ProcessInfo(VOID)
Definition: misc.c:775
#define TRACE(s)
Definition: solgame.cpp:4
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
_SEH2_END
Definition: create.c:4424
#define W32PF_CLASSESREGISTERED
Definition: win32.h:17
unsigned int ULONG
Definition: retypes.h:1
RTL_ATOM IntGetClassAtom(_In_ PUNICODE_STRING ClassName, IN HINSTANCE hInstance OPTIONAL, IN PPROCESSINFO pi OPTIONAL, OUT PCLS *BaseClass OPTIONAL, OUT PCLS **Link OPTIONAL)
Definition: class.c:1334
#define IS_ATOM(x)
Definition: class.h:3
HINSTANCE hModClient
Definition: ntuser.c:25
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define ERROR_CLASS_DOES_NOT_EXIST
Definition: winerror.h:892
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by GetClassInfoExA(), GetClassInfoExW(), and START_TEST().

◆ NtUserGetClassName()

INT APIENTRY NtUserGetClassName ( IN HWND  hWnd,
IN BOOL  Real,
OUT PUNICODE_STRING  ClassName 
)

Definition at line 2788 of file class.c.

2791 {
2792  PWND Window;
2793  UNICODE_STRING CapturedClassName;
2794  INT iCls, Ret = 0;
2795  RTL_ATOM Atom = 0;
2796 
2797  UserEnterShared();
2798 
2800  if (Window != NULL)
2801  {
2802  if (Real && Window->fnid && !(Window->fnid & FNID_DESTROY))
2803  {
2804  if (LookupFnIdToiCls(Window->fnid, &iCls))
2805  {
2806  Atom = gpsi->atomSysClass[iCls];
2807  }
2808  }
2809 
2810  _SEH2_TRY
2811  {
2812  ProbeForWriteUnicodeString(ClassName);
2813  CapturedClassName = *ClassName;
2814 
2815  /* Get the class name */
2816  Ret = UserGetClassName(Window->pcls,
2817  &CapturedClassName,
2818  Atom,
2819  FALSE);
2820 
2821  if (Ret != 0)
2822  {
2823  /* Update the Length field */
2824  ClassName->Length = CapturedClassName.Length;
2825  }
2826  }
2828  {
2830  }
2831  _SEH2_END;
2832  }
2833 
2834  UserLeave();
2835 
2836  return Ret;
2837 }
VOID FASTCALL UserEnterShared(VOID)
Definition: ntuser.c:241
unsigned short RTL_ATOM
Definition: atom.c:42
HWND hWnd
Definition: settings.c:17
#define FNID_DESTROY
Definition: ntuser.h:859
_Out_ RTL_ATOM * Atom
Definition: class.h:54
PSERVERINFO gpsi
Definition: main.c:27
int32_t INT
Definition: typedefs.h:56
_SEH2_TRY
Definition: create.c:4250
Definition: window.c:29
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
INT UserGetClassName(IN PCLS Class, IN OUT PUNICODE_STRING ClassName, IN RTL_ATOM Atom, IN BOOL Ansi)
Definition: class.c:1604
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:103
#define ProbeForWriteUnicodeString(Ptr)
Definition: probe.h:48
int Window
Definition: x11stubs.h:26
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Definition: ntuser.h:657
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
_SEH2_END
Definition: create.c:4424
BOOL FASTCALL LookupFnIdToiCls(int FnId, int *iCls)
Definition: class.c:131
float Real
Definition: definitions.h:36
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1013

Referenced by GetClassNameW(), and RealGetWindowClassW().

◆ NtUserGetWOWClass()

PCLS APIENTRY NtUserGetWOWClass ( HINSTANCE  hInstance,
PUNICODE_STRING  ClassName 
)

Definition at line 2842 of file class.c.

2845 {
2846  UNICODE_STRING SafeClassName;
2847  PPROCESSINFO pi;
2848  PCLS Class = NULL;
2849  RTL_ATOM ClassAtom = 0;
2850  NTSTATUS Status;
2851 
2852  Status = ProbeAndCaptureUnicodeStringOrAtom(&SafeClassName, ClassName);
2853  if (!NT_SUCCESS(Status))
2854  {
2855  ERR("Error capturing the class name\n");
2857  return FALSE;
2858  }
2859 
2861 
2862  pi = GetW32ProcessInfo();
2863 
2864  ClassAtom = IntGetClassAtom(&SafeClassName,
2865  hInstance,
2866  pi,
2867  &Class,
2868  NULL);
2869  if (!ClassAtom)
2870  {
2872  }
2873 
2874 
2875  if (SafeClassName.Buffer && !IS_ATOM(SafeClassName.Buffer))
2876  ExFreePoolWithTag(SafeClassName.Buffer, TAG_STRING);
2877 
2878  UserLeave();
2879 //
2880 // Don't forget to use DesktopPtrToUser( ? ) with return pointer in user space.
2881 //
2882  return Class;
2883 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
unsigned short RTL_ATOM
Definition: atom.c:42
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ NTSTATUS NTAPI ProbeAndCaptureUnicodeStringOrAtom(_Out_ _When_(return >=0, _At_(pustrOut->Buffer, _Post_ _Notnull_)) PUNICODE_STRING pustrOut, __in_data_source(USER_MODE) _In_ PUNICODE_STRING pustrUnsafe)
Definition: class.c:150
HINSTANCE hInstance
Definition: charmap.c:20
#define TAG_STRING
Definition: oslist.h:22
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
struct _PROCESSINFO * GetW32ProcessInfo(VOID)
Definition: misc.c:775
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static DWORD pi
Definition: protocol.c:150
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
RTL_ATOM IntGetClassAtom(_In_ PUNICODE_STRING ClassName, IN HINSTANCE hInstance OPTIONAL, IN PPROCESSINFO pi OPTIONAL, OUT PCLS *BaseClass OPTIONAL, OUT PCLS **Link OPTIONAL)
Definition: class.c:1334
#define IS_ATOM(x)
Definition: class.h:3
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define ERROR_CLASS_DOES_NOT_EXIST
Definition: winerror.h:892
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by START_TEST().

◆ NtUserRegisterClassExWOW()

RTL_ATOM APIENTRY NtUserRegisterClassExWOW ( WNDCLASSEXW lpwcx,
PUNICODE_STRING  ClassName,
PUNICODE_STRING  ClsVersion,
PCLSMENUNAME  pClassMenuName,
DWORD  fnID,
DWORD  Flags,
LPDWORD  pWow 
)

Definition at line 2383 of file class.c.

2401 {
2402  WNDCLASSEXW CapturedClassInfo = {0};
2403  UNICODE_STRING CapturedName = {0}, CapturedMenuName = {0}, CapturedVersion = {0};
2404  RTL_ATOM Ret = (RTL_ATOM)0;
2406  BOOL Exception = FALSE;
2407 
2408  if (Flags & ~(CSF_ANSIPROC))
2409  {
2410  ERR("NtUserRegisterClassExWOW Bad Flags!\n");
2412  return Ret;
2413  }
2414 
2416 
2417  TRACE("NtUserRegisterClassExWOW ClsN %wZ\n",ClassName);
2418 
2419  if ( !(ppi->W32PF_flags & W32PF_CLASSESREGISTERED ))
2420  {
2422  }
2423 
2424  _SEH2_TRY
2425  {
2426  /* Probe the parameters and basic parameter checks */
2427  if (ProbeForReadUint(&lpwcx->cbSize) != sizeof(WNDCLASSEXW))
2428  {
2429  ERR("NtUserRegisterClassExWOW Wrong cbSize!\n");
2430  goto InvalidParameter;
2431  }
2432 
2433  ProbeForRead(lpwcx,
2434  sizeof(WNDCLASSEXW),
2435  sizeof(ULONG));
2436  RtlCopyMemory(&CapturedClassInfo,
2437  lpwcx,
2438  sizeof(WNDCLASSEXW));
2439 
2440  CapturedName = ProbeForReadUnicodeString(ClassName);
2441  CapturedVersion = ProbeForReadUnicodeString(ClsVersion);
2442 
2443  ProbeForRead(pClassMenuName,
2444  sizeof(CLSMENUNAME),
2445  1);
2446 
2447  CapturedMenuName = ProbeForReadUnicodeString(pClassMenuName->pusMenuName);
2448 
2449  if ( (CapturedName.Length & 1) ||
2450  (CapturedMenuName.Length & 1) ||
2451  (CapturedClassInfo.cbClsExtra < 0) ||
2452  ((CapturedClassInfo.cbClsExtra + CapturedName.Length +
2453  CapturedMenuName.Length + sizeof(CLS))
2454  < (ULONG)CapturedClassInfo.cbClsExtra) ||
2455  (CapturedClassInfo.cbWndExtra < 0) ||
2456  (CapturedClassInfo.hInstance == NULL) )
2457  {
2458  ERR("NtUserRegisterClassExWOW Invalid Parameter Error!\n");
2459  goto InvalidParameter;
2460  }
2461 
2462  if (CapturedName.Length != 0)
2463  {
2464  ProbeForRead(CapturedName.Buffer,
2465  CapturedName.Length,
2466  sizeof(WCHAR));
2467  }
2468  else
2469  {
2470  if (!IS_ATOM(CapturedName.Buffer))
2471  {
2472  ERR("NtUserRegisterClassExWOW ClassName Error!\n");
2473  goto InvalidParameter;
2474  }
2475  }
2476 
2477  if (CapturedVersion.Length != 0)
2478  {
2479  ProbeForRead(CapturedVersion.Buffer,
2480  CapturedVersion.Length,
2481  sizeof(WCHAR));
2482  }
2483  else
2484  {
2485  if (!IS_ATOM(CapturedVersion.Buffer))
2486  {
2487  ERR("NtUserRegisterClassExWOW ClassName Error!\n");
2488  goto InvalidParameter;
2489  }
2490  }
2491 
2492  if (CapturedMenuName.Length != 0)
2493  {
2494  ProbeForRead(CapturedMenuName.Buffer,
2495  CapturedMenuName.Length,
2496  sizeof(WCHAR));
2497  }
2498  else if (CapturedMenuName.Buffer != NULL &&
2499  !IS_INTRESOURCE(CapturedMenuName.Buffer))
2500  {
2501  ERR("NtUserRegisterClassExWOW MenuName Error!\n");
2504  _SEH2_LEAVE;
2505  }
2506 
2507  if (IsCallProcHandle(lpwcx->lpfnWndProc))
2508  { // Never seen this yet, but I'm sure it's a little haxxy trick!
2509  // If this pops up we know what todo!
2510  ERR("NtUserRegisterClassExWOW WndProc is CallProc!!\n");
2511  }
2512 
2513  TRACE("NtUserRegisterClassExWOW MnuN %wZ\n",&CapturedMenuName);
2514  }
2516  {
2517  ERR("NtUserRegisterClassExWOW Exception Error!\n");
2519  Exception = TRUE;
2520  }
2521  _SEH2_END;
2522 
2523  if (!Exception)
2524  {
2525  /* Register the class */
2526  Ret = UserRegisterClass(&CapturedClassInfo,
2527  &CapturedName,
2528  &CapturedVersion,
2529  &CapturedMenuName,
2530  fnID,
2531  Flags);
2532  }
2533 
2534  if (!Ret)
2535  {
2536  TRACE("NtUserRegisterClassExWOW Null Return!\n");
2537  }
2538 
2539  UserLeave();
2540 
2541  return Ret;
2542 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
unsigned short RTL_ATOM
Definition: atom.c:42
int cbWndExtra
Definition: winuser.h:3194
BOOL FASTCALL UserRegisterSystemClasses(VOID)
Definition: class.c:2276
_SEH2_TRY
Definition: create.c:4250
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
unsigned int BOOL
Definition: ntddk_ex.h:94
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
int cbClsExtra
Definition: winuser.h:3193
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
struct _PROCESSINFO * GetW32ProcessInfo(VOID)
Definition: misc.c:775
#define TRACE(s)
Definition: solgame.cpp:4
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
#define ProbeForReadUint(Ptr)
Definition: probe.h:67
__wchar_t WCHAR
Definition: xmlstorage.h:180
UINT cbSize
Definition: winuser.h:3190
HINSTANCE hInstance
Definition: winuser.h:3195
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define CSF_ANSIPROC
Definition: ntuser.h:525
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
WNDPROC lpfnWndProc
Definition: winuser.h:3192
#define ERR(fmt,...)
Definition: debug.h:109
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
_SEH2_END
Definition: create.c:4424
#define W32PF_CLASSESREGISTERED
Definition: win32.h:17
PUNICODE_STRING pusMenuName
Definition: ntuser.h:468
#define ProbeForReadUnicodeString(Ptr)
Definition: probe.h:77
unsigned int ULONG
Definition: retypes.h:1
#define IS_ATOM(x)
Definition: class.h:3
RTL_ATOM UserRegisterClass(IN CONST WNDCLASSEXW *lpwcx, IN PUNICODE_STRING ClassName, IN PUNICODE_STRING ClassVersion, IN PUNICODE_STRING MenuName, IN DWORD fnID, IN DWORD dwFlags)
Definition: class.c:1461
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define _SEH2_LEAVE
Definition: filesup.c:20
static __inline BOOL IsCallProcHandle(IN WNDPROC lpWndProc)
Definition: class.h:13
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by RegisterClassExWOWW(), and START_TEST().

◆ NtUserSetClassLong()

ULONG_PTR APIENTRY NtUserSetClassLong ( HWND  hWnd,
INT  Offset,
ULONG_PTR  dwNewLong,
BOOL  Ansi 
)

Definition at line 2545 of file class.c.

2549 {
2550  PPROCESSINFO pi;
2551  PWND Window;
2552  ULONG_PTR Ret = 0;
2553 
2555 
2556  pi = GetW32ProcessInfo();
2557 
2559  if (Window != NULL)
2560  {
2561  if (Window->head.pti->ppi != pi)
2562  {
2564  goto Cleanup;
2565  }
2566 
2567  _SEH2_TRY
2568  {
2570 
2571  /* Probe the parameters */
2572  if (Offset == GCW_ATOM || Offset == GCLP_MENUNAME)
2573  {
2574  /* FIXME: Resource ID can be passed directly without UNICODE_STRING ? */
2575  if (IS_ATOM(dwNewLong))
2576  {
2577  Value.MaximumLength = 0;
2578  Value.Length = 0;
2579  Value.Buffer = (PWSTR)dwNewLong;
2580  }
2581  else
2582  {
2584  }
2585 
2586  if (Value.Length & 1)
2587  {
2588  goto InvalidParameter;
2589  }
2590 
2591  if (Value.Length != 0)
2592  {
2593  ProbeForRead(Value.Buffer,
2594  Value.Length,
2595  sizeof(WCHAR));
2596  }
2597  else
2598  {
2599  if (Offset == GCW_ATOM && !IS_ATOM(Value.Buffer))
2600  {
2601  goto InvalidParameter;
2602  }
2603  else if (Offset == GCLP_MENUNAME && !IS_INTRESOURCE(Value.Buffer))
2604  {
2607  _SEH2_LEAVE;
2608  }
2609  }
2610 
2611  dwNewLong = (ULONG_PTR)&Value;
2612  }
2613 
2614  Ret = UserSetClassLongPtr(Window->pcls,
2615  Offset,
2616  dwNewLong,
2617  Ansi);
2618  switch(Offset)
2619  {
2620  case GCLP_HICONSM:
2621  case GCLP_HICON:
2622  {
2623  if (Ret && Ret != dwNewLong)
2625  }
2626  }
2627  }
2629  {
2631  }
2632  _SEH2_END;
2633  }
2634 
2635 Cleanup:
2636  UserLeave();
2637 
2638  return Ret;
2639 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
uint16_t * PWSTR
Definition: typedefs.h:54
HWND hWnd
Definition: settings.c:17
#define GCW_ATOM
Definition: winuser.h:656
#define GCLP_MENUNAME
Definition: winuser.h:672
_SEH2_TRY
Definition: create.c:4250
#define DC_ICON
Definition: winuser.h:429
uint32_t ULONG_PTR
Definition: typedefs.h:63
Definition: window.c:29
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
PWND FASTCALL UserGetWindowObject(HWND hWnd)
Definition: window.c:103
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
#define GCLP_HICONSM
Definition: winuser.h:670
struct _PROCESSINFO * GetW32ProcessInfo(VOID)
Definition: misc.c:775
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
__wchar_t WCHAR
Definition: xmlstorage.h:180
int Window
Definition: x11stubs.h:26
static DWORD pi
Definition: protocol.c:150
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define GCLP_HICON
Definition: winuser.h:669
static const WCHAR Cleanup[]
Definition: register.c:80
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Definition: ntuser.h:657
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
_SEH2_END
Definition: create.c:4424
ULONG_PTR UserSetClassLongPtr(IN PCLS Class, IN INT Index, IN ULONG_PTR NewLong, IN BOOL Ansi)
Definition: class.c:1828
BOOL UserPaintCaption(PWND pWnd, INT Flags)
Definition: defwnd.c:396
#define ProbeForReadUnicodeString(Ptr)
Definition: probe.h:77
#define ULONG_PTR
Definition: config.h:101
#define IS_ATOM(x)
Definition: class.h:3
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define _SEH2_LEAVE
Definition: filesup.c:20
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by SetClassLongA(), SetClassLongW(), and START_TEST().

◆ NtUserSetClassWord()

WORD APIENTRY NtUserSetClassWord ( HWND  hWnd,
INT  nIndex,
WORD  wNewWord 
)

Definition at line 2643 of file class.c.

2647 {
2648 /*
2649  * NOTE: Obsoleted in 32-bit windows
2650  */
2651  return(0);
2652 }

◆ NtUserUnregisterClass()

BOOL APIENTRY NtUserUnregisterClass ( IN PUNICODE_STRING  ClassNameOrAtom,
IN HINSTANCE  hInstance,
OUT PCLSMENUNAME  pClassMenuName 
)

Definition at line 2656 of file class.c.

2660 {
2661  UNICODE_STRING SafeClassName;
2662  NTSTATUS Status;
2663  BOOL Ret;
2664 
2665  Status = ProbeAndCaptureUnicodeStringOrAtom(&SafeClassName, ClassNameOrAtom);
2666  if (!NT_SUCCESS(Status))
2667  {
2668  ERR("Error capturing the class name\n");
2670  return FALSE;
2671  }
2672 
2674 
2675  /* Unregister the class */
2676  Ret = UserUnregisterClass(&SafeClassName, hInstance, NULL); // Null for now~
2677 
2678  UserLeave();
2679 
2680  if (SafeClassName.Buffer && !IS_ATOM(SafeClassName.Buffer))
2681  ExFreePoolWithTag(SafeClassName.Buffer, TAG_STRING);
2682 
2683  return Ret;
2684 }
BOOL UserUnregisterClass(IN PUNICODE_STRING ClassName, IN HINSTANCE hInstance, OUT PCLSMENUNAME pClassMenuName)
Definition: class.c:1548
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ NTSTATUS NTAPI ProbeAndCaptureUnicodeStringOrAtom(_Out_ _When_(return >=0, _At_(pustrOut->Buffer, _Post_ _Notnull_)) PUNICODE_STRING pustrOut, __in_data_source(USER_MODE) _In_ PUNICODE_STRING pustrUnsafe)
Definition: class.c:150
HINSTANCE hInstance
Definition: charmap.c:20
unsigned int BOOL
Definition: ntddk_ex.h:94
#define TAG_STRING
Definition: oslist.h:22
smooth NULL
Definition: ftsmooth.c:416
VOID FASTCALL UserEnterExclusive(VOID)
Definition: ntuser.c:247
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Status
Definition: gdiplustypes.h:24
#define ERR(fmt,...)
Definition: debug.h:109
VOID FASTCALL UserLeave(VOID)
Definition: ntuser.c:255
#define IS_ATOM(x)
Definition: class.h:3
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by UnregisterClassA(), and UnregisterClassW().

◆ ProbeAndCaptureUnicodeStringOrAtom()

_Must_inspect_result_ NTSTATUS NTAPI ProbeAndCaptureUnicodeStringOrAtom ( _Out_ _When_(return >=0, _At_(pustrOut->Buffer, _Post_ _Notnull_)) PUNICODE_STRING  pustrOut,
__in_data_source(USER_MODE) _In_ PUNICODE_STRING  pustrUnsafe 
)

Definition at line 150 of file class.c.

153 {
155 
156  /* Default to NULL */
157  pustrOut->Buffer = NULL;
158 
159  _SEH2_TRY
160  {
161  ProbeForRead(pustrUnsafe, sizeof(UNICODE_STRING), 1);
162 
163  /* Validate the string */
164  if ((pustrUnsafe->Length & 1) || (pustrUnsafe->Buffer == NULL))
165  {
166  /* This is not legal */
168  }
169 
170  /* Check if this is an atom */
171  if (IS_ATOM(pustrUnsafe->Buffer))
172  {
173  /* Copy the atom, length is 0 */
174  pustrOut->MaximumLength = pustrOut->Length = 0;
175  pustrOut->Buffer = pustrUnsafe->Buffer;
176  }
177  else
178  {
179  /* Get the length, maximum length includes zero termination */
180  pustrOut->Length = pustrUnsafe->Length;
181  pustrOut->MaximumLength = pustrOut->Length + sizeof(WCHAR);
182 
183  /* Allocate a buffer */
184  pustrOut->Buffer = ExAllocatePoolWithTag(PagedPool,
185  pustrOut->MaximumLength,
186  TAG_STRING);
187  if (!pustrOut->Buffer)
188  {
190  }
191 
192  /* Copy the string and zero terminate it */
193  ProbeForRead(pustrUnsafe->Buffer, pustrOut->Length, 1);
194  RtlCopyMemory(pustrOut->Buffer, pustrUnsafe->Buffer, pustrOut->Length);
195  pustrOut->Buffer[pustrOut->Length / sizeof(WCHAR)] = L'\0';
196  }
197  }
199  {
200  /* Check if we already allocated a buffer */
201  if (pustrOut->Buffer)
202  {
203  /* Free the buffer */
204  ExFreePoolWithTag(pustrOut->Buffer, TAG_STRING);
206  }
207  }
208  _SEH2_END;
209 
210  return Status;
211 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
_SEH2_TRY
Definition: create.c:4250
#define TAG_STRING
Definition: oslist.h:22
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
static const WCHAR L[]
Definition: oid.c:1250
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
#define IS_ATOM(x)
Definition: class.h:3
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
return STATUS_SUCCESS
Definition: btrfs.c:2966

Referenced by NtUserFindExistingCursorIcon(), NtUserGetClassInfo(), NtUserGetWOWClass(), NtUserSetCursorIconData(), and NtUserUnregisterClass().

◆ RegisterControlAtoms()

BOOL FASTCALL RegisterControlAtoms ( VOID  )

Definition at line 373 of file class.c.

374 {
375  RTL_ATOM Atom;
376  UNICODE_STRING ClassName;
377  INT i = 0;
378 
379  while ( i < ICLS_DESKTOP)
380  {
381  RtlInitUnicodeString(&ClassName, ControlsList[i]);
382  if (IntRegisterClassAtom(&ClassName, &Atom))
383  {
384  gpsi->atomSysClass[i] = Atom;
385  TRACE("Reg Control Atom %ls: 0x%x\n", ControlsList[i], Atom);
386  }
387  i++;
388  }
389  return TRUE;
390 }
#define TRUE
Definition: types.h:120
unsigned short RTL_ATOM
Definition: atom.c:42
#define ICLS_DESKTOP
Definition: ntuser.h:890
_Out_ RTL_ATOM * Atom
Definition: class.h:54
PSERVERINFO gpsi
Definition: main.c:27
int32_t INT
Definition: typedefs.h:56
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define TRACE(s)
Definition: solgame.cpp:4
static PWSTR ControlsList[]
Definition: class.c:12
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
static BOOL IntRegisterClassAtom(IN PUNICODE_STRING ClassName, OUT RTL_ATOM *pAtom)
Definition: class.c:334
ATOM atomSysClass[ICLS_NOTUSED+1]
Definition: ntuser.h:1013

Referenced by InitUserAtoms().

◆ UserAddCallProcToClass()

VOID UserAddCallProcToClass ( IN OUT PCLS  Class,
IN PCALLPROCDATA  CallProc 
)

Definition at line 400 of file class.c.

402 {
403  PCLS BaseClass;
404 
405  ASSERT(CallProc->spcpdNext == NULL);
406 
407  BaseClass = Class->pclsBase;
408  ASSERT(CallProc->spcpdNext == NULL);
409  CallProc->spcpdNext = BaseClass->spcpdFirst;
410  BaseClass->spcpdFirst = CallProc;
411 
412  /* Update all clones */
413  Class = Class->pclsClone;
414  while (Class != NULL)
415  {
416  Class->spcpdFirst = BaseClass->spcpdFirst;
417  Class = Class->pclsNext;
418  }
419 }
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
PCALLPROCDATA spcpdFirst
Definition: ntuser.h:544
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)

Referenced by IntCreateWindow().

◆ UserGetClassInfo()

static BOOL UserGetClassInfo ( IN PCLS  Class,
OUT PWNDCLASSEXW  lpwcx,
IN BOOL  Ansi,
HINSTANCE  hInstance 
)
static

Definition at line 2219 of file class.c.

2223 {
2224  if (!Class) return FALSE;
2225 
2226  lpwcx->style = Class->style;
2227 
2228  // If fnId is set, clear the global bit. See wine class test check_style.
2229  if (Class->fnid)
2230  lpwcx->style &= ~CS_GLOBALCLASS;
2231 
2232  lpwcx->lpfnWndProc = IntGetClassWndProc(Class, Ansi);
2233 
2234  lpwcx->cbClsExtra = Class->cbclsExtra;
2235  lpwcx->cbWndExtra = Class->cbwndExtra;
2236  lpwcx->hIcon = Class->spicn ? UserHMGetHandle(Class->spicn) : NULL;
2237  lpwcx->hCursor = Class->spcur ? UserHMGetHandle(Class->spcur) : NULL;
2238  lpwcx->hIconSm = Class->spicnSm ? UserHMGetHandle(Class->spicnSm) : NULL;
2239  lpwcx->hbrBackground = Class->hbrBackground;
2240 
2241  /* Copy non-string to user first. */
2242  if (Ansi)
2243  ((PWNDCLASSEXA)lpwcx)->lpszMenuName = Class->lpszClientAnsiMenuName;
2244  else
2245  lpwcx->lpszMenuName = Class->lpszClientUnicodeMenuName;
2246 /*
2247  * FIXME: CLSMENUNAME has the answers! Copy the already made buffers from there!
2248  * Cls: lpszMenuName and lpszAnsiClassName should be used by kernel space.
2249  * lpszClientXxxMenuName should already be mapped to user space.
2250  */
2251  /* Copy string ptr to user. */
2252  if ( Class->lpszClientUnicodeMenuName != NULL &&
2253  Class->MenuNameIsString)
2254  {
2255  lpwcx->lpszMenuName = UserHeapAddressToUser(Ansi ?
2256  (PVOID)Class->lpszClientAnsiMenuName :
2257  (PVOID)Class->lpszClientUnicodeMenuName);
2258  }
2259 
2260  if (hInstance == hModClient)
2261  lpwcx->hInstance = NULL;
2262  else
2263  lpwcx->hInstance = hInstance;
2264 
2265  /* FIXME: Return the string? Okay! This is performed in User32! */
2266  //lpwcx->lpszClassName = (LPCWSTR)((ULONG_PTR)Class->atomClassName);
2267 
2268  return TRUE;
2269 }
#define TRUE
Definition: types.h:120
struct _WNDCLASSEXA * PWNDCLASSEXA
HINSTANCE hInstance
Definition: charmap.c:20
smooth NULL
Definition: ftsmooth.c:416
#define UserHMGetHandle(obj)
Definition: ntuser.h:208
#define CS_GLOBALCLASS
Definition: winuser.h:647
static __inline PVOID UserHeapAddressToUser(PVOID lpMem)
Definition: usrheap.h:92
WNDPROC FASTCALL IntGetClassWndProc(PCLS Class, BOOL Ansi)
Definition: class.c:471
HINSTANCE hModClient
Definition: ntuser.c:25

Referenced by NtUserGetClassInfo().

◆ UserGetClassName()

INT UserGetClassName ( IN PCLS  Class,
IN OUT PUNICODE_STRING  ClassName,
IN RTL_ATOM  Atom,
IN BOOL  Ansi 
)

Definition at line 1604 of file class.c.

1608 {
1610  WCHAR szStaticTemp[32];
1611  PWSTR szTemp = NULL;
1612  ULONG BufLen = sizeof(szStaticTemp);
1613  INT Ret = 0;
1614 
1615  /* Note: Accessing the buffer in ClassName may raise an exception! */
1616 
1617  _SEH2_TRY
1618  {
1619  if (Ansi)
1620  {
1621  PANSI_STRING AnsiClassName = (PANSI_STRING)ClassName;
1622  UNICODE_STRING UnicodeClassName;
1623 
1624  /* Limit the size of the static buffer on the stack to the
1625  size of the buffer provided by the caller */
1626  if (BufLen / sizeof(WCHAR) > AnsiClassName->MaximumLength)
1627  {
1628  BufLen = AnsiClassName->MaximumLength * sizeof(WCHAR);
1629  }
1630 
1631  /* Find out how big the buffer needs to be */
1633  Class->atomClassName,
1634  NULL,
1635  NULL,
1636  szStaticTemp,
1637  &BufLen);
1639  {
1640  if (BufLen / sizeof(WCHAR) > AnsiClassName->MaximumLength)
1641  {
1642  /* The buffer required exceeds the ansi buffer provided,
1643  pretend like we're using the ansi buffer and limit the
1644  size to the buffer size provided */
1645  BufLen = AnsiClassName->MaximumLength * sizeof(WCHAR);
1646  }
1647 
1648  /* Allocate a temporary buffer that can hold the unicode class name */
1650  BufLen,
1651  USERTAG_CLASS);
1652  if (szTemp == NULL)
1653  {
1655  _SEH2_LEAVE;
1656  }
1657 
1658  /* Query the class name */
1660  Atom ? Atom : Class->atomNVClassName,
1661  NULL,
1662  NULL,
1663  szTemp,
1664  &BufLen);
1665  }
1666  else
1667  szTemp = szStaticTemp;
1668 
1669  if (NT_SUCCESS(Status))
1670  {
1671  /* Convert the atom name to ansi */
1672 
1673  RtlInitUnicodeString(&UnicodeClassName,
1674  szTemp);
1675 
1676  Status = RtlUnicodeStringToAnsiString(AnsiClassName,
1677  &UnicodeClassName,
1678  FALSE);
1679  if (!NT_SUCCESS(Status))
1680  {
1682  _SEH2_LEAVE;
1683  }
1684  }
1685 
1686  Ret = BufLen / sizeof(WCHAR);
1687  }
1688  else /* !ANSI */
1689  {
1690  BufLen = ClassName->MaximumLength;
1691 
1692  /* Query the atom name */
1694  Atom ? Atom : Class->atomNVClassName,
1695  NULL,
1696  NULL,
1697  ClassName->Buffer,
1698  &BufLen);
1699 
1700  if (!NT_SUCCESS(Status))
1701  {
1703  _SEH2_LEAVE;
1704  }
1705 
1706  Ret = BufLen / sizeof(WCHAR);
1707  }
1708  }
1710  {
1712  }
1713  _SEH2_END;
1714 
1715  if (Ansi && szTemp != NULL && szTemp != szStaticTemp)
1716  {
1718  }
1719 
1720  return Ret;
1721 }
#define BufLen
Definition: fatfs.h:167
#define USERTAG_CLASS
Definition: tags.h:203
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
PRTL_ATOM_TABLE gAtomTable
Definition: session.c:13
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
_Out_ RTL_ATOM * Atom
Definition: class.h:54
int32_t INT
Definition: typedefs.h:56
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
_SEH2_TRY
Definition: create.c:4250
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
USHORT MaximumLength
Definition: env_spec_w32.h:377
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ANSI_STRING * PANSI_STRING
Definition: env_spec_w32.h:380
NTSYSAPI NTSTATUS NTAPI RtlQueryAtomInAtomTable(_In_ PRTL_ATOM_TABLE AtomTable, _In_ RTL_ATOM Atom, _Out_opt_ PULONG RefCount, _Out_opt_ PULONG PinCount, _Out_opt_z_bytecap_(*NameLength) PWSTR AtomName, _Inout_opt_ PULONG NameLength)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
VOID FASTCALL SetLastNtError(NTSTATUS Status)
Definition: error.c:36
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define _SEH2_LEAVE
Definition: filesup.c:20
return STATUS_SUCCESS
Definition: btrfs.c:2966
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by IntIsGhostWindow(), and NtUserGetClassName().

◆ UserRegisterClass()

RTL_ATOM UserRegisterClass ( IN CONST WNDCLASSEXW lpwcx,
IN PUNICODE_STRING  ClassName,
IN PUNICODE_STRING  ClassVersion,
IN PUNICODE_STRING  MenuName,
IN DWORD  fnID,
IN DWORD  dwFlags 
)

Definition at line 1461 of file class.c.

1467 {
1468  PTHREADINFO pti;
1469  PPROCESSINFO pi;
1470  PCLS Class;
1471  RTL_ATOM ClassAtom;
1472  RTL_ATOM Ret = (RTL_ATOM)0;
1473 
1474  /* NOTE: Accessing the buffers in ClassName and MenuName may raise exceptions! */
1475 
1476  pti = GetW32ThreadInfo();
1477 
1478  pi = pti->ppi;
1479 
1480  // Need only to test for two conditions not four....... Fix more whine tests....
1481  if ( IntGetAtomFromStringOrAtom( ClassVersion, &ClassAtom) &&
1482  ClassAtom != (RTL_ATOM)0 &&
1483  !(dwFlags & CSF_SERVERSIDEPROC) ) // Bypass Server Sides
1484  {
1485  Class = IntFindClass( ClassAtom,
1486  lpwcx->hInstance,
1487  &pi->pclsPrivateList,
1488  NULL);
1489 
1490  if (Class != NULL && !Class->Global)
1491  {
1492  // Local class already exists
1493  TRACE("Local Class 0x%x does already exist!\n", ClassAtom);
1495  return (RTL_ATOM)0;
1496  }
1497 
1498  if (lpwcx->style & CS_GLOBALCLASS)
1499  {
1500  Class = IntFindClass( ClassAtom,
1501  NULL,
1502  &pi->pclsPublicList,
1503  NULL);
1504 
1505  if (Class != NULL && Class->Global)
1506  {
1507  TRACE("Global Class 0x%x does already exist!\n", ClassAtom);
1509  return (RTL_ATOM)0;
1510  }
1511  }
1512  }
1513 
1514  Class = IntCreateClass(lpwcx,
1515  ClassName,
1516  ClassVersion,
1517  MenuName,
1518  fnID,
1519  dwFlags,
1520  pti->rpdesk,
1521  pi);
1522 
1523  if (Class != NULL)
1524  {
1525  PCLS *List;
1526 
1527  /* Register the class */
1528  if (Class->Global)
1529  List = &pi->pclsPublicList;
1530  else
1531  List = &pi->pclsPrivateList;
1532 
1533  Class->pclsNext = *List;
1535  Class);
1536 
1537  Ret = Class->atomNVClassName;
1538  }
1539  else
1540  {
1541  ERR("UserRegisterClass: Yes, that is right, you have no Class!\n");
1542  }
1543 
1544  return Ret;
1545 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
unsigned short RTL_ATOM
Definition: atom.c:42
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
PCLS FASTCALL IntCreateClass(IN CONST WNDCLASSEXW *lpwcx, IN PUNICODE_STRING ClassName, IN PUNICODE_STRING ClassVersion, IN PUNICODE_STRING MenuName, IN DWORD fnID, IN DWORD dwFlags, IN PDESKTOP Desktop, IN PPROCESSINFO pi)
Definition: class.c:1019
struct _DESKTOP * rpdesk
Definition: win32.h:91
struct _THREADINFO * GetW32ThreadInfo(VOID)
Definition: misc.c:781
PPROCESSINFO ppi
Definition: win32.h:87
smooth NULL
Definition: ftsmooth.c:416
#define ERROR_CLASS_ALREADY_EXISTS
Definition: winerror.h:891
Definition: ntuser.h:533
#define TRACE(s)
Definition: solgame.cpp:4
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
LIST_ENTRY List
Definition: psmgr.c:57
#define CS_GLOBALCLASS
Definition: winuser.h:647
static DWORD pi
Definition: protocol.c:150
#define CSF_SERVERSIDEPROC
Definition: ntuser.h:524
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
#define ERR(fmt,...)
Definition: debug.h:109
static PCLS IntFindClass(IN RTL_ATOM Atom, IN HINSTANCE hInstance, IN PCLS *ClassList, OUT PCLS **Link OPTIONAL)
Definition: class.c:1238
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by NtUserRegisterClassExWOW().

◆ UserRegisterSystemClasses()

BOOL FASTCALL UserRegisterSystemClasses ( VOID  )

Definition at line 2276 of file class.c.

2277 {
2278  UINT i;
2279  UNICODE_STRING ClassName, MenuName;
2281  WNDCLASSEXW wc;
2282  PCLS Class;
2283  BOOL Ret = TRUE;
2284  HBRUSH hBrush;
2285  DWORD Flags = 0;
2286 
2287  if (ppi->W32PF_flags & W32PF_CLASSESREGISTERED)
2288  return TRUE;
2289 
2290  if ( hModClient == NULL)
2291  return FALSE;
2292 
2293  RtlZeroMemory(&ClassName, sizeof(ClassName));
2294  RtlZeroMemory(&MenuName, sizeof(MenuName));
2295 
2296  for (i = 0; i != ARRAYSIZE(DefaultServerClasses); i++)
2297  {
2298  if (!IS_ATOM(DefaultServerClasses[i].ClassName))
2299  {
2300  RtlInitUnicodeString(&ClassName, DefaultServerClasses[i].ClassName);
2301  }
2302  else
2303  {
2304  ClassName.Buffer = DefaultServerClasses[i].ClassName;
2305  ClassName.Length = 0;
2306  ClassName.MaximumLength = 0;
2307  }
2308 
2309  wc.cbSize = sizeof(wc);
2311 
2313 
2314  if (DefaultServerClasses[i].ProcW)
2315  {
2317  wc.hInstance = hModuleWin;
2318  }
2319  else
2320  {
2322  wc.hInstance = hModClient;
2323  }
2324 
2325  wc.cbClsExtra = 0;
2327  wc.hIcon = NULL;
2328 
2330  wc.hCursor = NULL;
2331  if (DefaultServerClasses[i].hCursor == (HICON)OCR_NORMAL)
2332  {
2333  if (SYSTEMCUR(ARROW) == NULL)
2334  {
2335  ERR("SYSTEMCUR(ARROW) == NULL, should not happen!!\n");
2336  }
2337  else
2338  {
2339  wc.hCursor = UserHMGetHandle(SYSTEMCUR(ARROW));
2340  }
2341  }
2342 
2343  hBrush = DefaultServerClasses[i].hBrush;
2344  if (hBrush <= (HBRUSH)COLOR_MENUBAR)
2345  {
2346  hBrush = IntGetSysColorBrush(HandleToUlong(hBrush));
2347  }
2348  wc.hbrBackground = hBrush;
2349  wc.lpszMenuName = NULL;
2350  wc.lpszClassName = ClassName.Buffer;
2351  wc.hIconSm = NULL;
2352 
2353  Class = IntCreateClass( &wc,
2354  &ClassName,
2355  &ClassName,
2356  &MenuName,
2357  DefaultServerClasses[i].fiId,
2358  Flags,
2359  NULL,
2360  ppi);
2361  if (Class != NULL)
2362  {
2363  Class->pclsNext = ppi->pclsPublicList;
2365  Class);
2366 
2368  }
2369  else
2370  {
2371  ERR("!!! Registering system class failed!\n");
2372  Ret = FALSE;
2373  }
2374  }
2375  if (Ret) ppi->W32PF_flags |= W32PF_CLASSESREGISTERED;
2376  return Ret;
2377 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
static HICON
Definition: imagelist.c:84
#define TRUE
Definition: types.h:120
#define GETPFNSERVER(fnid)
Definition: ntuser.h:870
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
int cbWndExtra
Definition: winuser.h:3194
DWORD dwRegisteredClasses
Definition: win32.h:271
HGDIOBJ FASTCALL IntGetSysColorBrush(INT Object)
Definition: stockobj.c:317
#define HandleToUlong(h)
Definition: basetsd.h:79
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
HICON hIcon
Definition: winuser.h:3196
PCLS FASTCALL IntCreateClass(IN CONST WNDCLASSEXW *lpwcx, IN PUNICODE_STRING ClassName, IN PUNICODE_STRING ClassVersion, IN PUNICODE_STRING MenuName, IN DWORD fnID, IN DWORD dwFlags, IN PDESKTOP Desktop, IN PPROCESSINFO pi)
Definition: class.c:1019
REGISTER_SYSCLASS DefaultServerClasses[]
Definition: class.c:35
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
LPCWSTR lpszMenuName
Definition: winuser.h:3199
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
int cbClsExtra
Definition: winuser.h:3193
LPCWSTR lpszClassName
Definition: winuser.h:3200
#define UserHMGetHandle(obj)
Definition: ntuser.h:208
struct _PROCESSINFO * GetW32ProcessInfo(VOID)
Definition: misc.c:775
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
struct _CLS * pclsPublicList
Definition: win32.h:251
HBRUSH hbrBackground
Definition: winuser.h:3198
UINT cbSize
Definition: winuser.h:3190
unsigned long DWORD
Definition: ntddk_ex.h:95
WNDPROC ProcW
Definition: ntuser.h:456
HINSTANCE hInstance
Definition: winuser.h:3195
#define CSF_SERVERSIDEPROC
Definition: ntuser.h:524
HCURSOR hCursor
Definition: winuser.h:3197
UINT style
Definition: winuser.h:3191
WNDPROC lpfnWndProc
Definition: winuser.h:3192
#define ERR(fmt,...)
Definition: debug.h:109
#define OCR_NORMAL
Definition: winuser.h:1132
#define W32PF_CLASSESREGISTERED
Definition: win32.h:17
unsigned int UINT
Definition: ndis.h:50
HANDLE hModuleWin
Definition: main.c:16
HICON hIconSm
Definition: winuser.h:3201
#define ICLASS_TO_MASK(iCls)
Definition: ntuser.h:863
#define SYSTEMCUR(func)
Definition: cursoricon.h:129
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define IS_ATOM(x)
Definition: class.h:3
HINSTANCE hModClient
Definition: ntuser.c:25

Referenced by DesktopThreadMain(), IntGetAndReferenceClass(), NtUserGetClassInfo(), and NtUserRegisterClassExWOW().

◆ UserSetClassLongPtr()

ULONG_PTR UserSetClassLongPtr ( IN PCLS  Class,
IN INT  Index,
IN ULONG_PTR  NewLong,
IN BOOL  Ansi 
)

Definition at line 1828 of file class.c.

1832 {
1833  ULONG_PTR Ret = 0;
1834 
1835  /* NOTE: For GCLP_MENUNAME and GCW_ATOM this function may raise an exception! */
1836 
1837  /* Change the information in the base class first, then update the clones */
1838  Class = Class->pclsBase;
1839 
1840  if (Index >= 0)
1841  {
1842  PULONG_PTR Data;
1843 
1844  TRACE("SetClassLong(%d, %x)\n", Index, NewLong);
1845 
1846  if (((ULONG)Index + sizeof(ULONG_PTR)) < (ULONG)Index ||
1847  ((ULONG)Index + sizeof(ULONG_PTR)) > (ULONG)Class->cbclsExtra)
1848  {
1850  return 0;
1851  }
1852 
1853  Data = (PULONG_PTR)((ULONG_PTR)(Class + 1) + Index);
1854 
1855  /* FIXME: Data might be a unaligned pointer! Might be a problem on
1856  certain architectures, maybe using RtlCopyMemory is a
1857  better choice for those architectures! */
1858  Ret = *Data;
1859  *Data = NewLong;
1860 
1861  /* Update the clones */
1862  Class = Class->pclsClone;
1863  while (Class != NULL)
1864  {
1865  *(PULONG_PTR)((ULONG_PTR)(Class + 1) + Index) = NewLong;
1866  Class = Class->pclsNext;
1867  }
1868 
1869  return Ret;
1870  }
1871 
1872  switch (Index)
1873  {
1874  case GCL_CBWNDEXTRA:
1875  Ret = (ULONG_PTR)Class->cbwndExtra;
1876  Class->cbwndExtra = (INT)NewLong;
1877 
1878  /* Update the clones */
1879  Class = Class->pclsClone;
1880  while (Class != NULL)
1881  {
1882  Class->cbwndExtra = (INT)NewLong;
1883  Class = Class->pclsNext;
1884  }
1885 
1886  break;
1887 
1888  case GCL_CBCLSEXTRA:
1890  break;
1891 
1892  case GCLP_HBRBACKGROUND:
1893  Ret = (ULONG_PTR)Class->hbrBackground;
1894  Class->hbrBackground = (HBRUSH)NewLong;
1895 
1896  /* Update the clones */
1897  Class = Class->pclsClone;
1898  while (Class != NULL)
1899  {
1900  Class->hbrBackground = (HBRUSH)NewLong;
1901  Class = Class->pclsNext;
1902  }
1903  break;
1904 
1905  case GCLP_HCURSOR:
1906  {
1907  PCURICON_OBJECT NewCursor = NULL;
1908 
1909  if (NewLong)
1910  {
1911  NewCursor = UserGetCurIconObject((HCURSOR)NewLong);
1912  if (!NewCursor)
1913  {
1915  return 0;
1916  }
1917  }
1918 
1919  if (Class->spcur)
1920  {
1921  Ret = (ULONG_PTR)UserHMGetHandle(Class->spcur);
1922  UserDereferenceObject(Class->spcur);
1923  }
1924  else
1925  {
1926  Ret = 0;
1927  }
1928 
1929  if (Ret == NewLong)
1930  {
1931  /* It's a nop */
1932  return Ret;
1933  }
1934 
1935  Class->spcur = NewCursor;
1936 
1937  /* Update the clones */
1938  Class = Class->pclsClone;
1939  while (Class != NULL)
1940  {
1941  if (Class->spcur)
1942  UserDereferenceObject(Class->spcur);
1943  if (NewCursor)
1944  UserReferenceObject(NewCursor);
1945  Class->spcur = NewCursor;
1946  Class = Class->pclsNext;
1947  }
1948 
1949  break;
1950  }
1951 
1952  // MSDN:
1953  // hIconSm, A handle to a small icon that is associated with the window class.
1954  // If this member is NULL, the system searches the icon resource specified by
1955  // the hIcon member for an icon of the appropriate size to use as the small icon.
1956  //
1957  case GCLP_HICON:
1958  {
1959  PCURICON_OBJECT NewIcon = NULL;
1960  PCURICON_OBJECT NewSmallIcon = NULL;
1961 
1962  if (NewLong)
1963  {
1964  NewIcon = UserGetCurIconObject((HCURSOR)NewLong);
1965  if (!NewIcon)
1966  {
1968  return 0;
1969  }
1970  }
1971 
1972  if (Class->spicn)
1973  {
1974  Ret = (ULONG_PTR)UserHMGetHandle(Class->spicn);
1975  UserDereferenceObject(Class->spicn);
1976  }
1977  else
1978  {
1979  Ret = 0;
1980  }
1981 
1982  if (Ret == NewLong)
1983  {
1984  /* It's a nop */
1985  return Ret;
1986  }
1987 
1988  if (Ret && (Class->CSF_flags & CSF_CACHEDSMICON))
1989  {
1990  /* We will change the small icon */
1991  UserDereferenceObject(Class->spicnSm);
1992  IntDestroyCurIconObject(Class->spicnSm);
1993  Class->spicnSm = NULL;
1994  Class->CSF_flags &= ~CSF_CACHEDSMICON;
1995  }
1996 
1997  if (NewLong && !Class->spicnSm)
1998  {
1999  /* Create the new small icon from the new large(?) one */
2000  HICON SmallIconHandle = NULL;
2003  {
2004  SmallIconHandle = co_IntCopyImage(
2005  (HICON)NewLong,
2006  IMAGE_ICON,
2010  }
2011  if (!SmallIconHandle)
2012  {
2013  /* Retry without copying from resource */
2014  SmallIconHandle = co_IntCopyImage(
2015  (HICON)NewLong,
2016  IMAGE_ICON,
2019  0);
2020  }
2021  if (SmallIconHandle)
2022  {
2023  /* So use it */
2024  NewSmallIcon = Class->spicnSm = UserGetCurIconObject(SmallIconHandle);
2025  Class->CSF_flags |= CSF_CACHEDSMICON;
2026  }
2027  }
2028 
2029  Class->spicn = NewIcon;
2030 
2031  /* Update the clones */
2032  Class = Class->pclsClone;
2033  while (Class != NULL)
2034  {
2035  if (Class->spicn)
2036  UserDereferenceObject(Class->spicn);
2037  if (NewIcon)
2038  UserReferenceObject(NewIcon);
2039  Class->spicn = NewIcon;
2040  if (NewSmallIcon)
2041  {
2042  if (Class->spicnSm)
2043  UserDereferenceObject(Class->spicnSm);
2044  UserReferenceObject(NewSmallIcon);
2045  Class->spicnSm = NewSmallIcon;
2046  Class->CSF_flags |= CSF_CACHEDSMICON;
2047  }
2048  Class = Class->pclsNext;
2049  }
2050  break;
2051  }
2052 
2053  case GCLP_HICONSM:
2054  {
2055  PCURICON_OBJECT NewSmallIcon = NULL;
2056  BOOLEAN NewIconFromCache = FALSE;
2057 
2058  if (NewLong)
2059  {
2060  NewSmallIcon = UserGetCurIconObject((HCURSOR)NewLong);
2061  if (!NewSmallIcon)
2062  {
2064  return 0;
2065  }
2066  }
2067  else
2068  {
2069  /* Create the new small icon from the large one */
2070  HICON SmallIconHandle = NULL;
2071  if((Class->spicn->CURSORF_flags & (CURSORF_LRSHARED | CURSORF_FROMRESOURCE))
2073  {
2074  SmallIconHandle = co_IntCopyImage(
2075  UserHMGetHandle(Class->spicn),
2076  IMAGE_ICON,
2080  }
2081  if (!SmallIconHandle)
2082  {
2083  /* Retry without copying from resource */
2084  SmallIconHandle = co_IntCopyImage(
2085  UserHMGetHandle(Class->spicn),
2086  IMAGE_ICON,
2089  0);
2090  }
2091  if (SmallIconHandle)
2092  {
2093  /* So use it */
2094  NewSmallIcon = UserGetCurIconObject(SmallIconHandle);
2095  NewIconFromCache = TRUE;
2096  }
2097  else
2098  {
2099  ERR("Failed getting a small icon for the class.\n");
2100  }
2101  }
2102 
2103  if (Class->spicnSm)
2104  {
2105  if (Class->CSF_flags & CSF_CACHEDSMICON)
2106  {
2107  /* We must destroy the icon if we own it */
2108  IntDestroyCurIconObject(Class->spicnSm);
2109  Ret = 0;
2110  }
2111  else
2112  {
2113  Ret = (ULONG_PTR)UserHMGetHandle(Class->spicnSm);
2114  }
2115  UserDereferenceObject(Class->spicnSm);
2116  }
2117  else
2118  {
2119  Ret = 0;
2120  }
2121 
2122  if (NewIconFromCache)
2123  Class->CSF_flags |= CSF_CACHEDSMICON;
2124  else
2125  Class->CSF_flags &= ~CSF_CACHEDSMICON;
2126  Class->spicnSm = NewSmallIcon;
2127 
2128  /* Update the clones */
2129  Class = Class->pclsClone;
2130  while (Class != NULL)
2131  {
2132  if (Class->spicnSm)
2133  UserDereferenceObject(Class->spicnSm);
2134  if (NewSmallIcon)
2135  UserReferenceObject(NewSmallIcon);
2136  if (NewIconFromCache)
2137  Class->CSF_flags |= CSF_CACHEDSMICON;
2138  else
2139  Class->CSF_flags &= ~CSF_CACHEDSMICON;
2140  Class->spicnSm = NewSmallIcon;
2141  Class = Class->pclsNext;
2142  }
2143  }
2144  break;
2145 
2146  case GCLP_HMODULE:
2147  Ret = (ULONG_PTR)Class->hModule;
2148  Class->hModule = (HINSTANCE)NewLong;
2149 
2150  /* Update the clones */
2151  Class = Class->pclsClone;
2152  while (Class != NULL)
2153  {
2154  Class->hModule = (HINSTANCE)NewLong;
2155  Class = Class->pclsNext;
2156  }
2157  break;
2158 
2159  case GCLP_MENUNAME:
2160  {
2162 
2164  Value))
2165  {
2166  ERR("Setting the class menu name failed!\n");
2167  }
2168 
2169  /* FIXME: Really return NULL? Wine does so... */
2170  break;
2171  }
2172 
2173  case GCL_STYLE:
2174  Ret = (ULONG_PTR)Class->style;
2175  Class->style = (UINT)NewLong;
2176 
2177  /* FIXME: What if the CS_GLOBALCLASS style is changed? should we
2178  move the class to the appropriate list? For now, we save
2179  the original value in Class->Global, so we can always
2180  locate the appropriate list */
2181 
2182  /* Update the clones */
2183  Class = Class->pclsClone;
2184  while (Class != NULL)
2185  {
2186  Class->style = (UINT)NewLong;
2187  Class = Class->pclsNext;
2188  }
2189  break;
2190 
2191  case GCLP_WNDPROC:
2193  (WNDPROC)NewLong,
2194  Ansi);
2195  break;
2196 
2197  case GCW_ATOM:
2198  {
2200 
2201  Ret = (ULONG_PTR)Class->atomNVClassName;
2203  Value))
2204  {
2205  Ret = 0;
2206  }
2207  break;
2208  }
2209 
2210  default:
2212  break;
2213  }
2214 
2215  return Ret;
2216 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define ERROR_INVALID_CURSOR_HANDLE
Definition: winerror.h:883
static HICON
Definition: imagelist.c:84
#define TRUE
Definition: types.h:120
#define IMAGE_ICON
Definition: winuser.h:212
PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
Definition: cursoricon.c:200
#define CURSORF_FROMRESOURCE
Definition: ntuser.h:1148
#define INT
Definition: polytest.cpp:20
#define GCLP_HCURSOR
Definition: winuser.h:668
static WNDPROC FASTCALL IntSetClassWndProc(IN OUT PCLS Class, IN WNDPROC WndProc, IN BOOL Ansi)
Definition: class.c:520
#define SM_CYSMICON
Definition: winuser.h:1003
BOOL FASTCALL UserDereferenceObject(PVOID Object)
Definition: object.c:610
HICON HCURSOR
Definition: windef.h:284
#define GCLP_WNDPROC
Definition: winuser.h:673
int32_t INT
Definition: typedefs.h:56
#define GCW_ATOM
Definition: winuser.h:656
#define GCLP_MENUNAME
Definition: winuser.h:672
uint32_t ULONG_PTR
Definition: typedefs.h:63
static BOOL IntSetClassAtom(IN OUT PCLS Class, IN PUNICODE_STRING ClassName)
Definition: class.c:422
#define GCLP_HMODULE
Definition: winuser.h:671
#define ERROR_INVALID_ICON_HANDLE
Definition: winerror.h:895
#define GCL_STYLE
Definition: winuser.h:665
#define CSF_CACHEDSMICON
Definition: ntuser.h:530
#define CURSORF_LRSHARED
Definition: ntuser.h:1150
#define GCLP_HBRBACKGROUND
Definition: winuser.h:667
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
HANDLE FASTCALL co_IntCopyImage(HANDLE hnd, UINT type, INT desiredx, INT desiredy, UINT flags)
Definition: callback.c:974
LONG NTAPI UserGetSystemMetrics(ULONG Index)
Definition: metric.c:180
#define UserHMGetHandle(obj)
Definition: ntuser.h:208
#define GCLP_HICONSM
Definition: winuser.h:670
#define TRACE(s)
Definition: solgame.cpp:4
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define GCL_CBWNDEXTRA
Definition: winuser.h:658
static const UCHAR Index[8]
Definition: usbohci.c:18
#define GCL_CBCLSEXTRA
Definition: winuser.h:657
#define SM_CXSMICON
Definition: winuser.h:1002
HANDLE HINSTANCE
Definition: typedefs.h:75
#define GCLP_HICON
Definition: winuser.h:669
ULONG CURSORF_flags
Definition: cursoricon.h:16
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2880
#define ERR(fmt,...)
Definition: debug.h:109
#define LR_COPYFROMRESOURCE
Definition: winuser.h:1089
BOOLEAN IntDestroyCurIconObject(_In_ PVOID Object)
Definition: cursoricon.c:313
unsigned int UINT
Definition: ndis.h:50
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define ERROR_INVALID_INDEX
Definition: winerror.h:894
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:63
static BOOL IntSetClassMenuName(IN PCLS Class, IN PUNICODE_STRING MenuName)
Definition: class.c:1724
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27
VOID FASTCALL UserReferenceObject(PVOID obj)
Definition: object.c:697

Referenced by NtUserSetClassLong().

◆ UserUnregisterClass()

BOOL UserUnregisterClass ( IN PUNICODE_STRING  ClassName,
IN HINSTANCE  hInstance,
OUT PCLSMENUNAME  pClassMenuName 
)

Definition at line 1548 of file class.c.

1551 {
1552  PCLS *Link;
1553  PPROCESSINFO pi;
1554  RTL_ATOM ClassAtom;
1555  PCLS Class;
1556 
1557  pi = GetW32ProcessInfo();
1558 
1559  TRACE("UserUnregisterClass(%wZ, 0x%p)\n", ClassName, hInstance);
1560 
1561  /* NOTE: Accessing the buffer in ClassName may raise an exception! */
1562  ClassAtom = IntGetClassAtom(ClassName,
1563  hInstance,
1564  pi,
1565  &Class,
1566  &Link);
1567  if (ClassAtom == (RTL_ATOM)0)
1568  {
1570  TRACE("UserUnregisterClass: No Class found.\n");
1571  return FALSE;
1572  }
1573 
1574  ASSERT(Class != NULL);
1575 
1576  if (Class->cWndReferenceCount != 0 ||
1577  Class->pclsClone != NULL)
1578  {
1579  TRACE("UserUnregisterClass: Class has a Window. Ct %u : Clone 0x%p\n", Class->cWndReferenceCount, Class->pclsClone);
1581  return FALSE;
1582  }
1583 
1584  /* Must be a base class! */
1585  ASSERT(Class->pclsBase == Class);
1586 
1587  /* Unlink the class */
1588  *Link = Class->pclsNext;
1589 
1590  if (NT_SUCCESS(IntDeregisterClassAtom(Class->atomClassName)))
1591  {
1592  TRACE("Class 0x%p\n", Class);
1593  TRACE("UserUnregisterClass: Good Exit!\n");
1594  Class->atomClassName = 0; // Don't let it linger...
1595  /* Finally free the resources */
1597  return TRUE;
1598  }
1599  ERR("UserUnregisterClass: Can not deregister Class Atom.\n");
1600  return FALSE;
1601 }
static const WCHAR Class[]
Definition: cfgmgr.c:39
#define TRUE
Definition: types.h:120
unsigned short RTL_ATOM
Definition: atom.c:42
static VOID IntDestroyClass(IN OUT PCLS Class)
Definition: class.c:228
static int Link(const char **args)
Definition: vfdcmd.c:2414
HINSTANCE hInstance
Definition: charmap.c:20
#define ERROR_CLASS_HAS_WINDOWS
Definition: winerror.h:893
smooth NULL
Definition: ftsmooth.c:416
Definition: ntuser.h:533
static NTSTATUS IntDeregisterClassAtom(IN RTL_ATOM Atom)
Definition: class.c:393
struct _PROCESSINFO * GetW32ProcessInfo(VOID)
Definition: misc.c:775
#define TRACE(s)
Definition: solgame.cpp:4
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static DWORD pi
Definition: protocol.c:150
#define ERR(fmt,...)
Definition: debug.h:109
RTL_ATOM IntGetClassAtom(_In_ PUNICODE_STRING ClassName, IN HINSTANCE hInstance OPTIONAL, IN PPROCESSINFO pi OPTIONAL, OUT PCLS *BaseClass OPTIONAL, OUT PCLS **Link OPTIONAL)
Definition: class.c:1334
#define ERROR_CLASS_DOES_NOT_EXIST
Definition: winerror.h:892
ENGAPI VOID APIENTRY EngSetLastError(_In_ ULONG iError)
Definition: error.c:27

Referenced by NtUserUnregisterClass().

Variable Documentation

◆ ClsId

int ClsId

Definition at line 107 of file class.c.

◆ ControlsList

PWSTR ControlsList[]
static
Initial value:
=
{
L"Button",
L"Edit",
L"Static",
L"ListBox",
L"ScrollBar",
L"ComboBox",
L"MDIClient",
L"ComboLBox",
L"DDEMLEvent",
L"DDEMLMom",
L"DMGClass",
L"DDEMLAnsiClient",
L"DDEMLUnicodeClient",
L"DDEMLAnsiServer",
L"DDEMLUnicodeServer",
L"IME",
L"Ghost",
}
static const WCHAR L[]
Definition: oid.c:1250

Definition at line 12 of file class.c.

Referenced by RegisterControlAtoms().

◆ DefaultServerClasses

REGISTER_SYSCLASS DefaultServerClasses[]

Definition at line 35 of file class.c.

Referenced by UserRegisterSystemClasses().

◆ FnId

int FnId

Definition at line 106 of file class.c.

Referenced by LookupFnIdToiCls().

◆ FnidToiCls

struct { ... } FnidToiCls[]
Initial value:
=
{
{ FNID_MESSAGEWND, ICLS_HWNDMESSAGE},
}
#define FNID_EDIT
Definition: ntuser.h:832
#define ICLS_ICONTITLE
Definition: ntuser.h:894
#define ICLS_MDICLIENT
Definition: ntuser.h:879
#define FNID_COMBOBOX
Definition: ntuser.h:829
#define ICLS_SCROLLBAR
Definition: ntuser.h:877
#define FNID_MENU
Definition: ntuser.h:823
#define ICLS_EDIT
Definition: ntuser.h:874
#define FNID_ICONTITLE
Definition: ntuser.h:822
#define ICLS_DESKTOP
Definition: ntuser.h:890
#define ICLS_DIALOG
Definition: ntuser.h:891
#define FNID_MESSAGEWND
Definition: ntuser.h:826
#define ICLS_LISTBOX
Definition: ntuser.h:876
#define FNID_DESKTOP
Definition: ntuser.h:824
#define FNID_DIALOG
Definition: ntuser.h:831
#define ICLS_GHOST
Definition: ntuser.h:889
#define FNID_MDICLIENT
Definition: ntuser.h:834
#define ICLS_STATIC
Definition: ntuser.h:875
#define ICLS_TOOLTIPS
Definition: ntuser.h:895
#define FNID_SWITCH
Definition: ntuser.h:827
#define ICLS_SWITCH
Definition: ntuser.h:893
#define FNID_TOOLTIPS
Definition: ntuser.h:850
#define ICLS_IME
Definition: ntuser.h:888
#define FNID_COMBOLBOX
Definition: ntuser.h:830
#define FNID_LISTBOX
Definition: ntuser.h:833
#define ICLS_COMBOLBOX
Definition: ntuser.h:880
#define FNID_GHOST
Definition: ntuser.h:837
#define FNID_SCROLLBAR
Definition: ntuser.h:821
#define FNID_BUTTON
Definition: ntuser.h:828
#define ICLS_BUTTON
Definition: ntuser.h:873
#define ICLS_MENU
Definition: ntuser.h:892
#define FNID_STATIC
Definition: ntuser.h:835
#define FNID_IME
Definition: ntuser.h:836
#define ICLS_COMBOBOX
Definition: ntuser.h:878

Referenced by LookupFnIdToiCls().