ULONG_PTR _GetClassData( PCLS pcls, PWND pwnd, // used for transition to kernel-mode for GCL_WNDPROC int index, BOOL bAnsi) { KERNEL_ULONG_PTR dwData; DWORD dwCPDType = 0; index -= INDEX_OFFSET; if (index < 0) { RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); return 0; } UserAssert(index >= 0); UserAssert(index < sizeof(afClassDWord)); UserAssert(sizeof(afClassDWord) == sizeof(aiClassOffset)); if (afClassDWord[index] == sizeof(DWORD)) { dwData = *(DWORD *)(((BYTE *)pcls) + aiClassOffset[index]); } else if (afClassDWord[index] == sizeof(KERNEL_ULONG_PTR)) { dwData = *(KERNEL_ULONG_PTR *)(((BYTE *)pcls) + aiClassOffset[index]); } else { dwData = (DWORD)*(WORD *)(((BYTE *)pcls) + aiClassOffset[index]); } index += INDEX_OFFSET; /* * If we're returning an icon or cursor handle, do the reverse * mapping here. */ switch(index) { case GCLP_MENUNAME: if (IS_PTR(pcls->lpszMenuName)) { /* * The Menu Name is a real string: return the client-side address. * (If the class was registered by another app this returns an * address in that app's addr. space, but it's the best we can do) */ dwData = bAnsi ? (ULONG_PTR)pcls->lpszClientAnsiMenuName : (ULONG_PTR)pcls->lpszClientUnicodeMenuName; } break; case GCLP_HICON: case GCLP_HCURSOR: case GCLP_HICONSM: /* * We have to go to the kernel to convert the pcursor to a handle because * cursors are allocated out of POOL, which is not accessable from the client. */ if (dwData) { dwData = NtUserCallHwndParam(PtoH(pwnd), index, SFI_GETCLASSICOCUR); } break; case GCLP_WNDPROC: { /* * Always return the client wndproc in case this is a server * window class. */ if (pcls->CSF_flags & CSF_SERVERSIDEPROC) { dwData = MapServerToClientPfn(dwData, bAnsi); } else { KERNEL_ULONG_PTR dwT = dwData; dwData = MapClientNeuterToClientPfn(pcls, dwT, bAnsi); /* * If the client mapping didn't change the window proc then see if * we need a callproc handle. */ if (dwData == dwT) { /* * Need to return a CallProc handle if there is an Ansi/Unicode mismatch */ if (bAnsi != !!(pcls->CSF_flags & CSF_ANSIPROC)) { dwCPDType |= bAnsi ? CPD_ANSI_TO_UNICODE : CPD_UNICODE_TO_ANSI; } } } if (dwCPDType) { ULONG_PTR dwCPD; dwCPD = GetCPD(pwnd, dwCPDType | CPD_WNDTOCLS, KERNEL_ULONG_PTR_TO_ULONG_PTR(dwData)); if (dwCPD) { dwData = dwCPD; } else { RIPMSG0(RIP_WARNING, "GetClassLong unable to alloc CPD returning handle\n"); } } } break; case GCL_CBCLSEXTRA: if ((pcls->CSF_flags & CSF_WOWCLASS) && (pcls->CSF_flags & CSF_WOWEXTRA)) { /* * The 16-bit app changed its Extra bytes value. Return the changed * value. FritzS */ return PWCFromPCLS(pcls)->iClsExtra; } else return pcls->cbclsExtra; break; /* * WOW uses a pointer straight into the class structure. */ case GCLP_WOWWORDS: if (pcls->CSF_flags & CSF_WOWCLASS) { return ((ULONG_PTR)PWCFromPCLS(pcls)); } else return 0; case GCL_STYLE: dwData &= CS_VALID; break; } return KERNEL_ULONG_PTR_TO_ULONG_PTR(dwData); }
DWORD _GetClassData( PCLS pcls, PWND pwnd, // used for transition to kernel-mode for GCL_WNDPROC int index, BOOL bAnsi) { DWORD dwData; DWORD dwCPDType = 0; index -= INDEX_OFFSET; if (index < 0) { RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); return 0; } UserAssert(index >= 0); UserAssert(index < sizeof(afClassDWord)); UserAssert(sizeof(afClassDWord) == sizeof(aiClassOffset)); if (afClassDWord[index]) { dwData = *(DWORD *)(((BYTE *)pcls) + aiClassOffset[index]); } else { dwData = (DWORD)*(WORD *)(((BYTE *)pcls) + aiClassOffset[index]); } index += INDEX_OFFSET; /* * If we're returning an icon or cursor handle, do the reverse * mapping here. */ switch(index) { case GCL_MENUNAME: if (pcls->lpszMenuName != MAKEINTRESOURCE(pcls->lpszMenuName)) { /* * The Menu Name is a real string: return the client-side address. * (If the class was registered by another app this returns an * address in that app's addr. space, but it's the best we can do) */ dwData = bAnsi ? (DWORD)pcls->lpszClientAnsiMenuName : (DWORD)pcls->lpszClientUnicodeMenuName; } break; case GCL_HICON: case GCL_HCURSOR: case GCL_HICONSM: /* * We have to go to the kernel to convert the pcursor to a handle because * cursors are allocated out of POOL, which is not accessable from the client. */ if (dwData) { dwData = NtUserCallOneParam(dwData, SFI_KERNELPTOH); } break; case GCL_WNDPROC: { /* * Always return the client wndproc in case this is a server * window class. */ if (pcls->flags & CSF_SERVERSIDEPROC) { dwData = MapServerToClientPfn(dwData, bAnsi); } else { DWORD dwT = dwData; dwData = MapClientNeuterToClientPfn(pcls, dwT, bAnsi); /* * If the client mapping didn't change the window proc then see if * we need a callproc handle. */ if (dwData == dwT) { /* * Need to return a CallProc handle if there is an Ansi/Unicode mismatch */ if (bAnsi != !!(pcls->flags & CSF_ANSIPROC)) { dwCPDType |= bAnsi ? CPD_ANSI_TO_UNICODE : CPD_UNICODE_TO_ANSI; } } } if (dwCPDType) { DWORD dwCPD; dwCPD = GetCPD(pwnd, dwCPDType | CPD_WNDTOCLS, dwData); if (dwCPD) { dwData = dwCPD; } else { RIPMSG0(RIP_WARNING, "GetClassLong unable to alloc CPD returning handle\n"); } } } break; /* * WOW uses a pointer straight into the class structure. */ case GCL_WOWWORDS: return (DWORD) pcls->adwWOW; } return dwData; }