Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

class.c File Reference

#include "precomp.h"

Go to the source code of this file.

Defines

#define INDEX_OFFSET   GCLP_HICONSM

Functions

ATOM xxxRegisterClassEx (LPWNDCLASSEX cczpwc, PCLSMENUNAME pcmn, WORD fnid, DWORD dwFlags, LPDWORD pdwWOW)
PVOID ClassAlloc (PDESKTOP pdesk, DWORD cbAlloc)
VOID ClassFree (PDESKTOP pdesk, PVOID pvfree)
BOOL ValidateAndLockCursor (PCURSOR *ppcursor, BOOL fIs40Compat)
PCLS InternalRegisterClassEx (LPWNDCLASSEX cczlpwndcls, WORD fnid, DWORD CSF_flags)
BOOL _UnregisterClass (LPCWSTR ccxlpszClassName, HANDLE hModule, PCLSMENUNAME pcmn)
PCLS _GetWOWClass (HANDLE hModule, LPCWSTR ccxlpszClassName)
ATOM _GetClassInfoEx (HANDLE hModule, LPCWSTR ccxlpszClassName, LPWNDCLASSEX pwc, LPWSTR *ppszMenuName, BOOL bAnsi)
WORD _SetClassWord (PWND pwnd, int index, WORD value)
ULONG_PTR xxxSetClassLongPtr (PWND pwnd, int index, ULONG_PTR value, BOOL bAnsi)
PPCLS _InnerGetClassPtr (ATOM atom, PPCLS ppcls, HANDLE hModule)
PPCLS GetClassPtr (ATOM atom, PPROCESSINFO ppi, HANDLE hModule)
VOID UnlockAndFreeCPDs (PCALLPROCDATA *ppCPD)
void DestroyClassBrush (PCLS pcls)
void DestroyClass (PPCLS ppcls)
PCURSOR GetClassIcoCur (PWND pwnd, int index)
ULONG_PTR SetClassCursor (PWND pwnd, PCLS pcls, DWORD index, ULONG_PTR dwData)
ULONG_PTR xxxSetClassData (PWND pwnd, int index, ULONG_PTR dwData, BOOL bAnsi)
BOOL ReferenceClass (PCLS pcls, PWND pwnd)
VOID DereferenceClass (PWND pwnd)
VOID DestroyProcessesClasses (PPROCESSINFO ppi)

Variables

CONST BYTE afClassDWord []
CONST BYTE aiClassOffset []


Define Documentation

#define INDEX_OFFSET   GCLP_HICONSM
 

Definition at line 87 of file class.c.


Function Documentation

ATOM _GetClassInfoEx HANDLE  hModule,
LPCWSTR  ccxlpszClassName,
LPWNDCLASSEX  pwc,
LPWSTR *  ppszMenuName,
BOOL  bAnsi
 

Definition at line 678 of file class.c.

References tagCLS::atomClassName, CheckCritIn, CPD_ANSI_TO_UNICODE, CPD_CLASS, CPD_UNICODE_TO_ANSI, CSF_ANSIPROC, tagCLS::CSF_flags, CSF_SERVERSIDEPROC, CURSORF_SECRET, tagTHREADINFO::dwExpWinVer, DWORD, FindClassAtom, tagCLS::fnid, GetClassPtr(), GetCPD(), hModClient, hModuleWin, tagCLS::lpszClientAnsiMenuName, tagCLS::lpszClientUnicodeMenuName, MapClientNeuterToClientPfn(), MapServerToClientPfn(), NULL, tagTHREADINFO::ppi, PtiCurrent, PtoH, TIF_16BIT, tagTHREADINFO::TIF_flags, and VER40.

Referenced by NtUserGetClassInfo().

00684 { 00685 PCLS pcls; 00686 PPCLS ppcls; 00687 ATOM atomT; 00688 PTHREADINFO ptiCurrent; 00689 DWORD dwCPDType = 0; 00690 00691 CheckCritIn(); 00692 00693 ptiCurrent = PtiCurrent(); 00694 00695 /* 00696 * These are done first so if we don't find the class, and therefore 00697 * fail, the return thank won't try to copy back these (nonexistant) 00698 * strings. 00699 */ 00700 pwc->lpszMenuName = NULL; 00701 pwc->lpszClassName = NULL; 00702 00703 /* 00704 * Is this class registered as a private class? 00705 */ 00706 00707 /* 00708 * bradg (3/9/95) - Must first check to see if an ATOM has been passed. 00709 */ 00710 atomT = FindClassAtom(ccxlpszClassName); 00711 00712 /* 00713 * Windows 3.1 does not perform the class search with 00714 * a null hModule. If an application supplies a NULL 00715 * hModule, they search on hModuleWin instead. 00716 */ 00717 00718 if (hModule == NULL) 00719 hModule = hModClient; 00720 00721 ppcls = GetClassPtr(atomT, ptiCurrent->ppi, hModule); 00722 00723 00724 if (ppcls == NULL) { 00725 RIPERR0(ERROR_CLASS_DOES_NOT_EXIST, RIP_VERBOSE, "GetClassInfo: Class does not exist"); 00726 return 0; 00727 } 00728 00729 pcls = *ppcls; 00730 00731 /* 00732 * Copy all the fields common to CLS and WNDCLASS structures except 00733 * the lpszMenuName and lpszClassName which will be filled in by the 00734 * client-side piece of GetClassInfo. 00735 */ 00736 00737 /* 00738 * Return public bits only 00739 */ 00740 pwc->style = pcls->style & CS_VALID; 00741 00742 /* 00743 * Corel Depth 6.0 calls GetClassInfo (COMBOBOX) and registers a class 00744 * using the same name and style bits. This works OK on Win95 because 00745 * their "system" (combo, edit, etc) classes are not CS_GLOBALCLASS 00746 * So we got to mask this bit out for our classes 00747 */ 00748 00749 /* 00750 * Bug 17998. If the app is 32bit and WinVer is less than 4.0 don't mask 00751 * out the CS_GLOBALCLASS bit. 00752 */ 00753 00754 if ( (pcls->fnid != 0) && 00755 ((LOWORD(ptiCurrent->dwExpWinVer) >= VER40) || (ptiCurrent->TIF_flags & TIF_16BIT)) ) { 00756 pwc->style &= ~CS_GLOBALCLASS; 00757 } 00758 00759 00760 pwc->cbClsExtra = pcls->cbclsExtra; 00761 pwc->cbWndExtra = pcls->cbwndExtra; 00762 00763 /* 00764 * Stop 32-bit apps from inadvertantly using hModuleWin as their hInstance 00765 * when they register a window class. FritzS 00766 */ 00767 00768 if (LOWORD(ptiCurrent->dwExpWinVer) >= VER40) { 00769 /* 00770 * This is actually, Win95 behavior -- the USER.EXE hModule gets thunked to NULL on 00771 * the way out of the 16->32 bit thunk. Note -- if we ever need to support 16-bit 00772 * 4.0 apps (shudder), this may need to change. FritzS 00773 */ 00774 if (hModule == hModClient) { 00775 pwc->hInstance = NULL; 00776 } else { 00777 pwc->hInstance = hModule; 00778 } 00779 } else { 00780 /* 00781 * Win NT 3.1/3.51 returned the hInstance from the class. 00782 * Note that this is incompatible with Win 3.1. WoW has hacks for 16-bit apps. 00783 */ 00784 00785 if ((pcls->hModule == hModuleWin) || (pcls->hModule == hModClient)) { 00786 pwc->hInstance = hModClient; 00787 } else { 00788 pwc->hInstance = pcls->hModule; 00789 } 00790 } 00791 00792 pwc->hIcon = PtoH(pcls->spicn); 00793 pwc->hCursor = PtoH(pcls->spcur); 00794 pwc->hbrBackground = pcls->hbrBackground; 00795 00796 /* 00797 * Need to hide the small icon if it's USER created 00798 */ 00799 if (pcls->spicnSm && (pcls->spicnSm->CURSORF_flags & CURSORF_SECRET)) 00800 pwc->hIconSm = NULL; 00801 else 00802 pwc->hIconSm = PtoH(pcls->spicnSm); 00803 00804 /* 00805 * If its a server proc then map it to a client proc. If not we may have 00806 * to create a CPD. 00807 */ 00808 if (pcls->CSF_flags & CSF_SERVERSIDEPROC) { 00809 pwc->lpfnWndProc = 00810 (WNDPROC)MapServerToClientPfn((ULONG_PTR)pcls->lpfnWndProc, bAnsi); 00811 } else { 00812 pwc->lpfnWndProc = (WNDPROC)MapClientNeuterToClientPfn(pcls, 0, bAnsi); 00813 00814 /* 00815 * If the client mapping didn't change the window proc then see if 00816 * we need a callproc handle. 00817 */ 00818 if (pwc->lpfnWndProc == (WNDPROC)pcls->lpfnWndProc) { 00819 /* 00820 * Need to return a CallProc handle if there is an Ansi/Unicode mismatch 00821 */ 00822 if (bAnsi != !!(pcls->CSF_flags & CSF_ANSIPROC)) { 00823 dwCPDType |= bAnsi ? CPD_ANSI_TO_UNICODE : CPD_UNICODE_TO_ANSI; 00824 } 00825 } 00826 } 00827 00828 if (dwCPDType) { 00829 ULONG_PTR dwCPD; 00830 00831 dwCPD = GetCPD(pcls, dwCPDType | CPD_CLASS, (ULONG_PTR)pwc->lpfnWndProc); 00832 00833 if (dwCPD) { 00834 pwc->lpfnWndProc = (WNDPROC)dwCPD; 00835 } else { 00836 RIPMSG0(RIP_WARNING, "GetClassInfo unable to alloc CPD returning handle\n"); 00837 } 00838 } 00839 00840 /* 00841 * Return the stashed pointer to the client-side menu name string. 00842 */ 00843 if (bAnsi) { 00844 *ppszMenuName = (LPWSTR)pcls->lpszClientAnsiMenuName; 00845 } else { 00846 *ppszMenuName = pcls->lpszClientUnicodeMenuName; 00847 } 00848 return pcls->atomClassName; 00849 }

PCLS _GetWOWClass HANDLE  hModule,
LPCWSTR  ccxlpszClassName
 

Definition at line 616 of file class.c.

References CheckCritInShared, GetClassPtr(), NULL, tagCLS::pclsClone, tagCLS::pclsNext, tagTHREADINFO::ppi, PtiCurrentShared, tagTHREADINFO::rpdesk, tagCLS::rpdeskParent, and UserFindAtom().

Referenced by NtUserGetWOWClass().

00619 { 00620 PCLS pcls; 00621 PPCLS ppcls = NULL; 00622 ATOM atomT; 00623 PTHREADINFO ptiCurrent; 00624 00625 CheckCritInShared(); 00626 00627 ptiCurrent = PtiCurrentShared(); 00628 00629 /* 00630 * Is this class registered as a private class? 00631 */ 00632 atomT = UserFindAtom(ccxlpszClassName); 00633 if (atomT != 0) 00634 ppcls = GetClassPtr(atomT, ptiCurrent->ppi, hModule); 00635 if (ppcls == NULL) { 00636 RIPERR0(ERROR_CLASS_DOES_NOT_EXIST, RIP_VERBOSE, ""); 00637 return NULL; 00638 } 00639 00640 pcls = *ppcls; 00641 00642 if (ptiCurrent->rpdesk != pcls->rpdeskParent) { 00643 pcls = pcls->pclsClone; 00644 while (pcls != NULL) { 00645 if (ptiCurrent->rpdesk == pcls->rpdeskParent) { 00646 goto Done; 00647 } 00648 pcls = pcls->pclsNext; 00649 } 00650 RIPERR0(ERROR_CLASS_DOES_NOT_EXIST, RIP_VERBOSE, ""); 00651 return NULL; 00652 } 00653 Done: 00654 return pcls; 00655 }

PPCLS _InnerGetClassPtr ATOM  atom,
PPCLS  ppcls,
HANDLE  hModule
 

Definition at line 997 of file class.c.

References CSF_WOWDEFERDESTROY, and NULL.

Referenced by _UnregisterClass(), GetClassPtr(), and InternalRegisterClassEx().

01001 { 01002 if (atom == 0) 01003 return NULL; 01004 01005 while (*ppcls != NULL) { 01006 if ((*ppcls)->atomClassName == atom && 01007 (hModule == NULL || HIWORD((ULONG_PTR)(*ppcls)->hModule) == HIWORD((ULONG_PTR)hModule)) && 01008 !((*ppcls)->CSF_flags & CSF_WOWDEFERDESTROY)) { 01009 return ppcls; 01010 } 01011 01012 ppcls = (PPCLS)*ppcls; 01013 } 01014 01015 return NULL; 01016 }

WORD _SetClassWord PWND  pwnd,
int  index,
WORD  value
 

Definition at line 863 of file class.c.

References BYTE, CheckCritIn, GETPTI, NULL, tagWND::pcls, tagCLS::pclsBase, tagCLS::pclsClone, tagCLS::pclsNext, and PpiCurrent.

Referenced by NtUserSetClassWord().

00867 { 00868 WORD wOld; 00869 WORD UNALIGNED *pw; 00870 PCLS pcls; 00871 00872 CheckCritIn(); 00873 00874 if (GETPTI(pwnd)->ppi != PpiCurrent()) { 00875 RIPERR1(ERROR_ACCESS_DENIED, RIP_WARNING, "SetClassWord: different process: index 0x%lx", index); 00876 return 0; 00877 } 00878 00879 pcls = pwnd->pcls->pclsBase; 00880 if ((index < 0) || (index + (int)sizeof(WORD) > pcls->cbclsExtra)) { 00881 RIPERR0(ERROR_INVALID_INDEX, RIP_WARNING, "SetClassWord: invalid index"); 00882 return 0; 00883 } else { 00884 pw = (WORD UNALIGNED *)((BYTE *)(pcls + 1) + index); 00885 wOld = *pw; 00886 *pw = value; 00887 pcls = pcls->pclsClone; 00888 while (pcls != NULL) { 00889 pw = (WORD UNALIGNED *)((BYTE *)(pcls + 1) + index); 00890 *pw = value; 00891 pcls = pcls->pclsNext; 00892 } 00893 return wOld; 00894 } 00895 }

BOOL _UnregisterClass LPCWSTR  ccxlpszClassName,
HANDLE  hModule,
PCLSMENUNAME  pcmn
 

Definition at line 555 of file class.c.

References _InnerGetClassPtr(), BOOL, CheckCritIn, DestroyClass(), DWORD, FALSE, FindClassAtom, NULL, tagPROCESSINFO::pclsPrivateList, tagPROCESSINFO::pclsPublicList, tagTHREADINFO::ppi, tagCLSMENUNAME::pszClientAnsiMenuName, PtiCurrent, tagCLSMENUNAME::pusMenuName, tagCLSMENUNAME::pwszClientUnicodeMenuName, and TRUE.

Referenced by NtUserUnregisterClass().

00559 { 00560 ATOM atomT; 00561 PPCLS ppcls; 00562 PTHREADINFO ptiCurrent; 00563 00564 CheckCritIn(); 00565 00566 ptiCurrent = PtiCurrent(); 00567 00568 /* 00569 * Check whether the given ClassName is already registered by the 00570 * Application with the given handle. 00571 * Return error, if either the Class does not exist or it does not 00572 * belong to the calling process. 00573 */ 00574 00575 /* 00576 * bradg (3/9/95) - Must first check to see if an ATOM has been passed 00577 */ 00578 atomT = FindClassAtom(ccxlpszClassName); 00579 00580 ppcls = _InnerGetClassPtr(atomT, &ptiCurrent->ppi->pclsPrivateList, hModule); 00581 if (ppcls == NULL) { 00582 /* 00583 * Maybe this is a public class. 00584 */ 00585 ppcls = _InnerGetClassPtr(atomT, &ptiCurrent->ppi->pclsPublicList, NULL); 00586 if (ppcls == NULL) { 00587 RIPERR1(ERROR_CLASS_DOES_NOT_EXIST, RIP_WARNING, "UnregisterClass: Class does not exist; atom=%lX", (DWORD)atomT); 00588 return FALSE; 00589 } 00590 } 00591 00592 /* 00593 * If any windows created with this class still exist return an error. 00594 */ 00595 if ((*ppcls)->cWndReferenceCount != 0) { 00596 RIPERR0(ERROR_CLASS_HAS_WINDOWS, RIP_WARNING, "UnregisterClass: Class still has window"); 00597 return FALSE; 00598 } 00599 00600 /* 00601 * Return client side pointers for cleanup 00602 */ 00603 pcmn->pszClientAnsiMenuName = (*ppcls)->lpszClientAnsiMenuName; 00604 pcmn->pwszClientUnicodeMenuName = (*ppcls)->lpszClientUnicodeMenuName; 00605 pcmn->pusMenuName = NULL; 00606 00607 /* 00608 * Release the Window class and related information. 00609 */ 00610 DestroyClass(ppcls); 00611 00612 return TRUE; 00613 }

PVOID ClassAlloc PDESKTOP  pdesk,
DWORD  cbAlloc
 

Definition at line 169 of file class.c.

References DesktopAllocAlways, and DTAG_CLASS.

Referenced by InternalRegisterClassEx(), and ReferenceClass().

00172 { 00173 PVOID pvalloc; 00174 00175 if (pdesk) 00176 /* 00177 * Later5.0 GerardoB. Make this allocation directly to avoid 00178 * DesktopAlloc from failing it when the desktop is destroyed. 00179 * When destroying a locked window, we might need to clone the 00180 * zombie class which requires an allocation on the wnd's desktop. 00181 * We need to make sure that the client side doesn't get to the 00182 * class of a zombie window; then we won't need to make the heap 00183 * allocation; or is there any other reason for that allocation? 00184 */ 00185 pvalloc = (PCLS)DesktopAllocAlways(pdesk, cbAlloc, DTAG_CLASS); 00186 else { 00187 pvalloc = (PCLS)UserAllocPoolWithQuotaZInit(cbAlloc, TAG_CLASS); 00188 } 00189 00190 return pvalloc; 00191 }

VOID ClassFree PDESKTOP  pdesk,
PVOID  pvfree
 

Definition at line 193 of file class.c.

References DesktopFree, NULL, and VOID().

Referenced by DestroyClass(), InternalRegisterClassEx(), and ReferenceClass().

00196 { 00197 if (pdesk != NULL) 00198 DesktopFree(pdesk, pvfree); 00199 else 00200 UserFreePool(pvfree); 00201 }

VOID DereferenceClass PWND  pwnd  ) 
 

Definition at line 1735 of file class.c.

References tagCLS::cWndReferenceCount, DestroyClass(), tagWND::pcls, tagCLS::pclsBase, tagCLS::pclsClone, tagCLS::pclsNext, and VOID().

Referenced by HMChangeOwnerThread(), and xxxFreeWindow().

01737 { 01738 PCLS pcls = pwnd->pcls; 01739 PPCLS ppcls; 01740 01741 UserAssert(pcls->cWndReferenceCount >= 1); 01742 01743 pcls->cWndReferenceCount--; 01744 if (pcls != pcls->pclsBase) { 01745 01746 UserAssert(pcls->pclsBase->cWndReferenceCount >= 1); 01747 01748 pcls->pclsBase->cWndReferenceCount--; 01749 01750 if (pcls->cWndReferenceCount == 0) { 01751 ppcls = &pcls->pclsBase->pclsClone; 01752 while ((*ppcls) != pcls) 01753 ppcls = &(*ppcls)->pclsNext; 01754 UserAssert(ppcls); 01755 DestroyClass(ppcls); 01756 } 01757 } 01758 }

void DestroyClass PPCLS  ppcls  ) 
 

Definition at line 1207 of file class.c.

References tagCLS::atomClassName, ClassFree(), tagCLS::cWndReferenceCount, DestroyCacheDC(), DestroyClassBrush(), DestroyClassSmIcon(), tagDCE::hdc, IS_PTR, LockDesktop, NULL, tagCLS::pclsBase, tagCLS::pclsClone, tagCLS::pclsNext, tagCLS::pdce, PtiCurrent, tagCLS::rpdeskParent, tagCLS::spcpdFirst, Unlock, UnlockAndFreeCPDs(), UnlockDesktop, and UserDeleteAtom().

Referenced by _UnregisterClass(), _WOWCleanup(), _WOWModuleUnload(), CleanupResources(), DereferenceClass(), DestroyProcessesClasses(), and FinalUserInit().

01209 { 01210 PPCLS ppclsClone; 01211 PCLS pcls; 01212 PDESKTOP rpdesk; 01213 01214 pcls = *ppcls; 01215 01216 UserAssert(pcls->cWndReferenceCount == 0); 01217 01218 /* 01219 * If this is a base class, destroy all clones before deleting 01220 * stuff. 01221 */ 01222 if (pcls == pcls->pclsBase) { 01223 ppclsClone = &pcls->pclsClone; 01224 while (*ppclsClone != NULL) { 01225 DestroyClass(ppclsClone); 01226 } 01227 01228 UserDeleteAtom(pcls->atomClassName); 01229 01230 /* 01231 * No freeing if it's an integer resource. 01232 */ 01233 if (IS_PTR(pcls->lpszMenuName)) { 01234 UserFreePool(pcls->lpszMenuName); 01235 } 01236 01237 /* 01238 * Free up the class dc if there is one. 01239 */ 01240 if (pcls->pdce != NULL) 01241 DestroyCacheDC(NULL, pcls->pdce->hdc); 01242 01243 /* 01244 * Delete the hBrBackground brush if nobody else is 01245 * using it. 01246 */ 01247 DestroyClassBrush(pcls); 01248 } 01249 01250 /* 01251 * If we created the small icon delete it 01252 */ 01253 DestroyClassSmIcon(pcls); 01254 01255 /* 01256 * Unlock cursor and icon 01257 */ 01258 Unlock(&pcls->spicn); 01259 Unlock(&pcls->spicnSm); 01260 Unlock(&pcls->spcur); 01261 01262 /* 01263 * Free any CallProcData objects associated with this class 01264 */ 01265 if (pcls->spcpdFirst) { 01266 UnlockAndFreeCPDs(&pcls->spcpdFirst); 01267 } 01268 01269 /* 01270 * Point the previous guy at the guy we currently point to. 01271 */ 01272 *ppcls = pcls->pclsNext; 01273 01274 /* 01275 * Lock the desktop. Do not use a thread lock because 01276 * this may be called during process cleanup when thread 01277 * locks are no longer usable. 01278 */ 01279 rpdesk = NULL; 01280 LockDesktop(&rpdesk, pcls->rpdeskParent, LDL_FN_DESTROYCLASS, (ULONG_PTR)PtiCurrent()); 01281 UnlockDesktop(&pcls->rpdeskParent, LDU_CLS_DESKPARENT2, (ULONG_PTR)pcls); 01282 ClassFree(rpdesk, pcls->lpszAnsiClassName); 01283 ClassFree(rpdesk, pcls); 01284 UnlockDesktop(&rpdesk, LDU_FN_DESTROYCLASS, (ULONG_PTR)PtiCurrent()); 01285 }

void DestroyClassBrush PCLS  pcls  ) 
 

Definition at line 1128 of file class.c.

References BOOL, gpclsList, tagCLS::pclsNext, tagPROCESSINFO::pclsPrivateList, tagPROCESSINFO::pclsPublicList, PpiCurrent, and SYSHBRUSH.

Referenced by DestroyClass().

01130 { 01131 PPROCESSINFO ppi = PpiCurrent(); 01132 PCLS pclsWalk; 01133 int nInd; 01134 BOOL bRet; 01135 /* 01136 * Return if it's not a real brush 01137 */ 01138 if (pcls->hbrBackground <= (HBRUSH)(COLOR_MAX)) 01139 return; 01140 01141 /* 01142 * Don't delete the system brushes 01143 */ 01144 for (nInd = 0; nInd < COLOR_MAX; nInd++) { 01145 if (pcls->hbrBackground == SYSHBRUSH(nInd)) 01146 return; 01147 } 01148 01149 01150 /* 01151 * Walk the process public public list 01152 */ 01153 pclsWalk = ppi->pclsPublicList; 01154 01155 while (pclsWalk) { 01156 if (pclsWalk != pcls && pclsWalk->hbrBackground == pcls->hbrBackground) 01157 return; 01158 01159 pclsWalk = pclsWalk->pclsNext; 01160 } 01161 01162 /* 01163 * Walk the process private class list 01164 */ 01165 pclsWalk = ppi->pclsPrivateList; 01166 01167 while (pclsWalk) { 01168 if (pclsWalk != pcls && pclsWalk->hbrBackground == pcls->hbrBackground) 01169 return; 01170 01171 pclsWalk = pclsWalk->pclsNext; 01172 } 01173 01174 /* 01175 * Finaly walk the system class list 01176 */ 01177 pclsWalk = gpclsList; 01178 01179 while (pclsWalk) { 01180 if (pclsWalk != pcls && pclsWalk->hbrBackground == pcls->hbrBackground) 01181 return; 01182 01183 pclsWalk = pclsWalk->pclsNext; 01184 } 01185 01186 bRet = GreDeleteObject(pcls->hbrBackground); 01187 01188 #if DBG 01189 if (!bRet) 01190 RIPERR1(ERROR_INVALID_HANDLE, RIP_WARNING, 01191 "DestroyClassBrush: failed to destroy brush %#p", pcls->hbrBackground); 01192 #endif 01193 }

VOID DestroyProcessesClasses PPROCESSINFO  ppi  ) 
 

Definition at line 1768 of file class.c.

References DestroyClass(), NULL, tagPROCESSINFO::pclsPrivateList, tagPROCESSINFO::pclsPublicList, and VOID().

Referenced by xxxDestroyThreadInfo().

01770 { 01771 PPCLS ppcls; 01772 01773 /* 01774 * Destroy the private classes first 01775 */ 01776 ppcls = &(ppi->pclsPrivateList); 01777 while (*ppcls != NULL) { 01778 DestroyClass(ppcls); 01779 } 01780 01781 /* 01782 * Then the cloned public classes 01783 */ 01784 ppcls = &(ppi->pclsPublicList); 01785 while (*ppcls != NULL) { 01786 DestroyClass(ppcls); 01787 } 01788 }

PCURSOR GetClassIcoCur PWND  pwnd,
int  index
 

Definition at line 1297 of file class.c.

References NULL, and tagWND::pcls.

01298 { 01299 PCLS pcls = pwnd->pcls; 01300 PCURSOR pcur; 01301 01302 switch (index) { 01303 case GCLP_HICON: 01304 pcur = pcls->spicn; 01305 break; 01306 01307 case GCLP_HCURSOR: 01308 pcur = pcls->spcur; 01309 break; 01310 01311 case GCLP_HICONSM: 01312 pcur = pcls->spicnSm; 01313 break; 01314 01315 default: 01316 RIPMSG2(RIP_WARNING, "GetWndIcoCur: Invalid index:%#lx. pwnd:%#p", 01317 index, pwnd); 01318 pcur = NULL; 01319 } 01320 01321 return pcur; 01322 }

PPCLS GetClassPtr ATOM  atom,
PPROCESSINFO  ppi,
HANDLE  hModule
 

Definition at line 1036 of file class.c.

References _InnerGetClassPtr(), gpclsList, hModClient, NULL, tagPROCESSINFO::pclsPrivateList, and tagPROCESSINFO::pclsPublicList.

Referenced by _GetClassInfoEx(), _GetWOWClass(), HMChangeOwnerThread(), xxxCreateWindowEx(), and xxxFreeWindow().

01040 { 01041 PPCLS ppcls; 01042 01043 /* 01044 * First search public then private then usersrv registered classes 01045 */ 01046 ppcls = _InnerGetClassPtr(atom, &ppi->pclsPrivateList, hModule); 01047 if (ppcls) 01048 return ppcls; 01049 01050 ppcls = _InnerGetClassPtr(atom, &ppi->pclsPublicList, NULL); 01051 if (ppcls) 01052 return ppcls; 01053 01054 /* 01055 * Next seach public and private classes and override hmodule; 01056 * some apps (bunny) do a GetClassInfo(dialog) and RegisterClass 01057 * and only change the wndproc which set the hmodule to be just 01058 * like usersrv created it even though it is in the app's public 01059 * or private class list 01060 */ 01061 01062 /* 01063 * Later -- since we are no longer returning hModuleWin to any app, 01064 * we may only need to check for hModClient. Check this out. 01065 * FritzS 01066 */ 01067 01068 ppcls = _InnerGetClassPtr(atom, &ppi->pclsPrivateList, hModClient); 01069 if (ppcls) 01070 return ppcls; 01071 01072 ppcls = _InnerGetClassPtr(atom, &ppi->pclsPublicList, hModClient); 01073 if (ppcls) 01074 return ppcls; 01075 01076 /* 01077 * Search the system class list 01078 */ 01079 ppcls = _InnerGetClassPtr(atom, &gpclsList, NULL); 01080 return ppcls; 01081 }

PCLS InternalRegisterClassEx LPWNDCLASSEX  cczlpwndcls,
WORD  fnid,
DWORD  CSF_flags
 

Definition at line 244 of file class.c.

References _InnerGetClassPtr(), AllocateUnicodeString(), BOOL, CBFNID, CheckCritIn, _CLIENTINFO::CI_flags, CI_REGISTERCLASSES, ClassAlloc(), ClassFree(), COMMON_WNDCLASS, CSF_ANSIPROC, CSF_SERVERSIDEPROC, CSF_SYSTEMCLASS, CSF_WIN40COMPAT, CSF_WOWCLASS, tagTHREADINFO::dwExpWinVer, DWORD, FALSE, FindClassAtom, gpclsList, hModuleWin, IS_PTR, L, LockDesktop, MapClientToServerPfn(), NULL, tagTHREADINFO::pClientInfo, tagCLS::pclsNext, tagPROCESSINFO::pclsPrivateList, tagPROCESSINFO::pclsPublicList, tagTHREADINFO::ppi, PtiCurrent, PTR_TO_ID, tagTHREADINFO::rpdesk, tagCLS::rpdeskParent, RtlInitUnicodeString(), RtlIntegerToChar(), RtlUnicodeStringToAnsiString(), tagTHREADINFO::TIF_flags, TIF_SYSTEMTHREAD, Unlock, UnlockDesktop, UserAddAtom(), UserDeleteAtom(), USHORT, ValidateAndLockCursor(), VER40, WND, and WNDPROC_PWND.

Referenced by LW_RegisterWindows(), and xxxRegisterClassEx().

00249 { 00250 BOOL fIs40Compat; 00251 ULONG_PTR dwT; 00252 PCLS pcls; 00253 LPWSTR pszT1; 00254 ATOM atomT; 00255 PTHREADINFO ptiCurrent; 00256 HANDLE hModule; 00257 PDESKTOP pdesk; 00258 ULONG cch; 00259 UNICODE_STRING UString; 00260 ANSI_STRING AString; 00261 00262 /* 00263 * NOTE -- lpszClassName and lpszMenuName in the wndclass may be client-side 00264 * pointers. Use of those fields must be protected in try blocks. 00265 */ 00266 CheckCritIn(); 00267 00268 ptiCurrent = PtiCurrent(); 00269 00270 /* 00271 * Don't allow 4.0 apps to register a class using hModuleWin 00272 * LATER GerardoB: Our client side classes use hmodUser (USER32) while 00273 * our server side classes use hWinInstance (WIN32K). We should change 00274 * CreateThreadInfo and LW_RegisterWindows so all classes use hModUser. 00275 */ 00276 hModule = cczlpwndcls->hInstance; 00277 if (!(CSF_flags & (CSF_SYSTEMCLASS | CSF_SERVERSIDEPROC)) 00278 && (hModule == hModuleWin) 00279 && (LOWORD(ptiCurrent->dwExpWinVer) >= VER40)) { 00280 00281 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "InternalRegisterClassEx: Invalid hInstance (Cannot use system's hInstance)"); 00282 return NULL; 00283 } 00284 00285 00286 /* 00287 * As of NT 4.0 we no longer honor CS_BYTEALIGNCLIENT or CS_BYTEALIGNWINDOW 00288 */ 00289 if (cczlpwndcls->style & (CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW)) { 00290 RIPMSG0(RIP_VERBOSE, "CS_BYTEALIGNCLIENT and CS_BYTEALIGNWINDOW styles no longer honored."); 00291 } 00292 00293 /* 00294 * Does this class exist as a private class? If so, fail. 00295 */ 00296 atomT = FindClassAtom(cczlpwndcls->lpszClassName); 00297 00298 if (atomT != 0 && !(CSF_flags & CSF_SERVERSIDEPROC)) { 00299 /* 00300 * First check private classes. If already exists, return error. 00301 */ 00302 if (_InnerGetClassPtr(atomT, &ptiCurrent->ppi->pclsPrivateList, 00303 hModule) != NULL) { 00304 RIPERR1(ERROR_CLASS_ALREADY_EXISTS, RIP_VERBOSE, "RegisterClass: Class already exists %lx", (DWORD)atomT); 00305 return NULL; 00306 } 00307 00308 /* 00309 * Now only check public classes if CS_GLOBALCLASS is set. If it 00310 * isn't set, then this will allow an application to re-register 00311 * a private class to take precedence over a public class. 00312 */ 00313 if (cczlpwndcls->style & CS_GLOBALCLASS) { 00314 if (_InnerGetClassPtr(atomT, &ptiCurrent->ppi->pclsPublicList, NULL) != NULL) { 00315 RIPERR0(ERROR_CLASS_ALREADY_EXISTS, RIP_VERBOSE, "RegisterClass: Global Class already exists"); 00316 return NULL; 00317 } 00318 } 00319 } 00320 00321 /* 00322 * Alloc space for the class. 00323 */ 00324 if (ptiCurrent->TIF_flags & TIF_SYSTEMTHREAD) { 00325 pdesk = NULL; 00326 } else { 00327 pdesk = ptiCurrent->rpdesk; 00328 } 00329 pcls = (PCLS)ClassAlloc(pdesk, sizeof(CLS) + cczlpwndcls->cbClsExtra + (CSF_flags & CSF_WOWCLASS ? sizeof(WC):0)); 00330 if (pcls == NULL) { 00331 return NULL; 00332 } 00333 00334 LockDesktop(&pcls->rpdeskParent, pdesk, LDL_CLS_DESKPARENT1, (ULONG_PTR)pcls); 00335 pcls->pclsBase = pcls; 00336 00337 /* 00338 * Copy over the shared part of the class structure. 00339 */ 00340 UserAssert(FIELD_OFFSET(WNDCLASSEX, style) == FIELD_OFFSET(COMMON_WNDCLASS, style)); 00341 RtlCopyMemory(&pcls->style, &(cczlpwndcls->style), 00342 sizeof(COMMON_WNDCLASS) - FIELD_OFFSET(COMMON_WNDCLASS, style)); 00343 00344 /* 00345 * Copy CSF_SERVERSIDEPROC, CSF_ANSIPROC (etc.) flags 00346 */ 00347 pcls->CSF_flags = LOWORD(CSF_flags); 00348 pcls->fnid = fnid; 00349 if (fnid) { 00350 CBFNID(fnid) = (WORD)(pcls->cbwndExtra + sizeof(WND)); 00351 00352 if (!(pcls->CSF_flags & CSF_SERVERSIDEPROC) && ptiCurrent->pClientInfo != NULL) { 00353 /* 00354 * Clear the bit so new threads in this process 00355 * won't bother to reregister the client-side USER classes. 00356 */ 00357 ptiCurrent->pClientInfo->CI_flags &= ~CI_REGISTERCLASSES; 00358 } 00359 } 00360 00361 /* 00362 * If this wndproc happens to be a client wndproc stub for a server 00363 * wndproc, then remember the server wndproc! This should be rare: why 00364 * would an application re-register a class that isn't "subclassed"? 00365 */ 00366 if (!(pcls->CSF_flags & CSF_SERVERSIDEPROC)) { 00367 dwT = MapClientToServerPfn((ULONG_PTR)pcls->lpfnWndProc); 00368 if (dwT != 0) { 00369 pcls->CSF_flags |= CSF_SERVERSIDEPROC; 00370 pcls->CSF_flags &= ~CSF_ANSIPROC; 00371 pcls->lpfnWndProc = (WNDPROC_PWND)dwT; 00372 } 00373 } 00374 00375 /* 00376 * Win95 compatible validation. 00377 * 00378 * hbrBackground was validated by GDI in the client side 00379 * NULL hInstances are mapped to GetModuleHandle(NULL) in the client 00380 * side 00381 */ 00382 00383 fIs40Compat = (CSF_flags & CSF_WIN40COMPAT) != 0; 00384 00385 if (!ValidateAndLockCursor(&pcls->spcur, fIs40Compat)) { 00386 goto ValidateError1; 00387 } 00388 00389 if (!ValidateAndLockCursor(&pcls->spicn, fIs40Compat)) { 00390 goto ValidateError2; 00391 } 00392 00393 if (!ValidateAndLockCursor(&pcls->spicnSm, fIs40Compat)) { 00394 goto ValidateError3; 00395 } 00396 00397 /* 00398 * Add the class name to the atom table. 00399 */ 00400 00401 if (IS_PTR(cczlpwndcls->lpszClassName)) 00402 atomT = UserAddAtom(cczlpwndcls->lpszClassName, FALSE); 00403 else 00404 atomT = PTR_TO_ID(cczlpwndcls->lpszClassName); 00405 00406 if (atomT == 0) { 00407 goto AtomError; 00408 } 00409 pcls->atomClassName = atomT; 00410 00411 /* 00412 * Make an ANSI version of the class name to optimize 00413 * GetClassNameA for WOW. 00414 */ 00415 if (IS_PTR(cczlpwndcls->lpszClassName)) { 00416 try { 00417 RtlInitUnicodeString(&UString, cczlpwndcls->lpszClassName); 00418 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 00419 goto MemError2; 00420 } 00421 #ifdef FE_SB // InternalRegisterClassEx() 00422 cch = UString.Length + 1; 00423 #else 00424 cch = UString.Length / sizeof(WCHAR) + 1; 00425 #endif // FE_SB 00426 } else { 00427 cch = 7; // 1 char for '#', 5 for '65536'. 00428 } 00429 00430 /* 00431 * Allocate the ANSI name buffer and convert the unicode name 00432 * to ANSI. 00433 */ 00434 pcls->lpszAnsiClassName = (LPSTR)ClassAlloc(pdesk, cch); 00435 if (pcls->lpszAnsiClassName == NULL) { 00436 goto MemError2; 00437 } 00438 00439 /* 00440 * Form the ANSI class name. 00441 */ 00442 if (IS_PTR(cczlpwndcls->lpszClassName)) { 00443 00444 /* 00445 * Class name is a string. 00446 */ 00447 AString.Length = 0; 00448 AString.MaximumLength = (USHORT)cch; 00449 AString.Buffer = pcls->lpszAnsiClassName; 00450 try { 00451 RtlUnicodeStringToAnsiString(&AString, &UString, FALSE); 00452 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 00453 goto MemError3; 00454 } 00455 } else { 00456 00457 /* 00458 * Class name is an integer atom. 00459 */ 00460 pcls->lpszAnsiClassName[0] = L'#'; 00461 RtlIntegerToChar(PTR_TO_ID(cczlpwndcls->lpszClassName), 10, cch - 1, 00462 &pcls->lpszAnsiClassName[1]); 00463 } 00464 00465 /* 00466 * Make local copy of menu name. 00467 */ 00468 pszT1 = pcls->lpszMenuName; 00469 00470 if (pszT1 != NULL) { 00471 if (IS_PTR(pszT1)) { 00472 try { 00473 RtlInitUnicodeString(&UString, pszT1); 00474 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 00475 goto MemError3; 00476 } 00477 if (UString.Length == 0) { 00478 00479 /* 00480 * app passed an empty string for the name 00481 */ 00482 pcls->lpszMenuName = NULL; 00483 } else { 00484 UNICODE_STRING strMenuName; 00485 00486 /* 00487 * Alloc space for the Menu Name. 00488 */ 00489 if (!AllocateUnicodeString(&strMenuName, &UString)) { 00490 MemError3: 00491 ClassFree(pdesk, pcls->lpszAnsiClassName); 00492 MemError2: 00493 UserDeleteAtom(pcls->atomClassName); 00494 AtomError: 00495 Unlock(&pcls->spicnSm); 00496 ValidateError3: 00497 Unlock(&pcls->spicn); 00498 ValidateError2: 00499 Unlock(&pcls->spcur); 00500 ValidateError1: 00501 UnlockDesktop(&pcls->rpdeskParent, LDU_CLS_DESKPARENT1, (ULONG_PTR)pcls); 00502 ClassFree(pdesk, pcls); 00503 return NULL; 00504 } 00505 00506 pcls->lpszMenuName = strMenuName.Buffer; 00507 } 00508 } 00509 } 00510 00511 if ((CSF_flags & CSF_SERVERSIDEPROC) || (pcls->style & CS_GLOBALCLASS)) { 00512 if (pcls->CSF_flags & CSF_SYSTEMCLASS) { 00513 pcls->pclsNext = gpclsList; 00514 gpclsList = pcls; 00515 } else { 00516 pcls->pclsNext = ptiCurrent->ppi->pclsPublicList; 00517 ptiCurrent->ppi->pclsPublicList = pcls; 00518 } 00519 } else { 00520 pcls->pclsNext = ptiCurrent->ppi->pclsPrivateList; 00521 ptiCurrent->ppi->pclsPrivateList = pcls; 00522 } 00523 00524 /* 00525 * Because Memory is allocated with ZEROINIT, the pcls->cWndReferenceCount 00526 * field is automatically initialised to zero. 00527 */ 00528 00529 return pcls; 00530 }

BOOL ReferenceClass PCLS  pcls,
PWND  pwnd
 

Definition at line 1645 of file class.c.

References BOOL, ClassAlloc(), ClassFree(), CLS, tagCLS::CSF_flags, CSF_WOWCLASS, tagCLS::cWndReferenceCount, DWORD, FALSE, tagWND::head, Lock, LockDesktop, NULL, tagWND::pcls, tagCLS::pclsClone, tagCLS::pclsNext, tagCLS::rpdeskParent, strlen(), and TRUE.

Referenced by xxxCreateWindowEx().

01648 { 01649 DWORD cbName; 01650 PCLS pclsClone; 01651 PDESKTOP pdesk; 01652 01653 /* 01654 * If the window is on the same desktop as the base class, just 01655 * increment the window count. 01656 */ 01657 if (pcls->rpdeskParent == pwnd->head.rpdesk) { 01658 pcls->cWndReferenceCount++; 01659 return TRUE; 01660 } 01661 01662 /* 01663 * The window is not on the base desktop. Try to find a cloned 01664 * class. 01665 */ 01666 for (pclsClone = pcls->pclsClone; pclsClone != NULL; 01667 pclsClone = pclsClone->pclsNext) { 01668 if (pclsClone->rpdeskParent == pwnd->head.rpdesk) 01669 break; 01670 } 01671 01672 /* 01673 * If we can't find one, clone the base class. 01674 */ 01675 if (pclsClone == NULL) { 01676 pdesk = pwnd->head.rpdesk; 01677 pclsClone = ClassAlloc(pdesk, sizeof(CLS) + pcls->cbclsExtra + (pcls->CSF_flags & CSF_WOWCLASS ?sizeof(WC):0)); 01678 if (pclsClone == NULL) { 01679 RIPMSG0(RIP_WARNING, "ReferenceClass: Failed Clone-Class Allocation\n"); 01680 return FALSE; 01681 } 01682 01683 RtlCopyMemory(pclsClone, pcls, sizeof(CLS) + pcls->cbclsExtra + (pcls->CSF_flags & CSF_WOWCLASS?sizeof(WC):0)); 01684 cbName = strlen(pcls->lpszAnsiClassName) + 1; 01685 pclsClone->lpszAnsiClassName = ClassAlloc(pdesk, cbName); 01686 if (pclsClone->lpszAnsiClassName == NULL) { 01687 ClassFree(pdesk, pclsClone); 01688 RIPMSG0(RIP_WARNING, "ReferenceClass: No Clone Class Name\n"); 01689 return FALSE; 01690 } 01691 01692 /* 01693 * Everything has been allocated, now lock everything down. 01694 * NULL pointers in clone to prevent Lock() from incorrectly 01695 * decrementing object reference count 01696 */ 01697 pclsClone->rpdeskParent = NULL; 01698 LockDesktop(&pclsClone->rpdeskParent, pdesk, 01699 LDL_CLS_DESKPARENT2, (ULONG_PTR)pclsClone); 01700 pclsClone->pclsNext = pcls->pclsClone; 01701 pclsClone->pclsClone = NULL; 01702 pcls->pclsClone = pclsClone; 01703 RtlCopyMemory(pclsClone->lpszAnsiClassName, pcls->lpszAnsiClassName, cbName); 01704 01705 pclsClone->spicn = pclsClone->spicnSm = pclsClone->spcur = NULL; 01706 01707 Lock(&pclsClone->spicn, pcls->spicn); 01708 Lock(&pclsClone->spicnSm, pcls->spicnSm); 01709 Lock(&pclsClone->spcur, pcls->spcur); 01710 pclsClone->spcpdFirst = NULL; 01711 pclsClone->cWndReferenceCount = 0; 01712 } 01713 01714 /* 01715 * Increment reference counts. 01716 */ 01717 pcls->cWndReferenceCount++; 01718 pclsClone->cWndReferenceCount++; 01719 pwnd->pcls = pclsClone; 01720 01721 return TRUE; 01722 }

ULONG_PTR SetClassCursor PWND  pwnd,
PCLS  pcls,
DWORD  index,
ULONG_PTR  dwData
 

Definition at line 1329 of file class.c.

References CheckLock, HMValidateHandle(), Lock, NULL, tagCLS::pclsBase, tagCLS::pclsClone, tagCLS::pclsNext, PtoH, TYPE_CURSOR, and xxxSetClassIcon().

Referenced by xxxSetClassData().

01334 { 01335 ULONG_PTR dwOld; 01336 01337 CheckLock(pwnd); 01338 01339 if ((HANDLE)dwData != NULL) { 01340 dwData = (ULONG_PTR)HMValidateHandle((HANDLE)dwData, TYPE_CURSOR); 01341 if ((PVOID)dwData == NULL) { 01342 if (index == GCLP_HICON || index == GCLP_HICONSM) { 01343 RIPERR0(ERROR_INVALID_ICON_HANDLE, RIP_WARNING, "SetClassData: invalid icon"); 01344 } else { 01345 RIPERR0(ERROR_INVALID_CURSOR_HANDLE, RIP_WARNING, "SetClassData: invalid cursor"); 01346 } 01347 } 01348 } 01349 01350 /* 01351 * Handle the locking issue. 01352 */ 01353 pcls = pcls->pclsBase; 01354 switch (index) { 01355 case GCLP_HICON: 01356 case GCLP_HICONSM: 01357 dwOld = (ULONG_PTR)xxxSetClassIcon(pwnd, pcls, (PCURSOR)dwData, index); 01358 break; 01359 01360 case GCLP_HCURSOR: 01361 dwOld = (ULONG_PTR)Lock(&pcls->spcur, dwData); 01362 break; 01363 } 01364 01365 /* 01366 * Now set it for each clone class. 01367 */ 01368 pcls = pcls->pclsClone; 01369 while (pcls != NULL) { 01370 switch(index) { 01371 case GCLP_HICON: 01372 case GCLP_HICONSM: 01373 xxxSetClassIcon(pwnd, pcls, (PCURSOR)dwData, index); 01374 break; 01375 01376 case GCLP_HCURSOR: 01377 Lock(&pcls->spcur, dwData); 01378 break; 01379 } 01380 pcls = pcls->pclsNext; 01381 } 01382 01383 return (ULONG_PTR)PtoH((PVOID)dwOld); 01384 }

VOID UnlockAndFreeCPDs PCALLPROCDATA ppCPD  ) 
 

Definition at line 1092 of file class.c.

References HMIsMarkDestroy, HMMarkObjectDestroy(), NULL, _CALLPROCDATA::spcpdNext, Unlock, and VOID().

Referenced by DestroyClass().

01094 { 01095 PCALLPROCDATA pCPD; 01096 01097 while ((pCPD = *ppCPD) != NULL) { 01098 /* 01099 * Unlink the CPD from the list. 01100 */ 01101 *ppCPD = pCPD->spcpdNext; 01102 pCPD->spcpdNext = NULL; 01103 01104 /* 01105 * Mark it for destruction. 01106 */ 01107 if (!HMIsMarkDestroy(pCPD)) { 01108 HMMarkObjectDestroy(pCPD); 01109 } 01110 01111 /* 01112 * Unlock it and it will be destroyed. 01113 */ 01114 Unlock(&pCPD); 01115 } 01116 }

BOOL ValidateAndLockCursor PCURSOR ppcursor,
BOOL  fIs40Compat
 

Definition at line 211 of file class.c.

References BOOL, FALSE, HMValidateHandleNoSecure(), Lock, NULL, TRUE, and TYPE_CURSOR.

Referenced by InternalRegisterClassEx().

00212 { 00213 PCURSOR pcur; 00214 00215 if (*ppcursor == NULL) { 00216 return TRUE; 00217 } 00218 00219 pcur = HMValidateHandleNoSecure(*ppcursor, TYPE_CURSOR); 00220 if (pcur == NULL) { 00221 RIPMSG1(RIP_WARNING, "ValidateAndLockCursor: Invalid Cursor or Icon:%#p", *ppcursor); 00222 if (fIs40Compat) { 00223 RIPERR0(ERROR_INVALID_PARAMETER, RIP_VERBOSE, "RegisterClass: Invalid Parameter"); 00224 return FALSE; 00225 } 00226 } 00227 00228 *ppcursor = NULL; 00229 Lock(ppcursor, pcur); 00230 return TRUE; 00231 }

ATOM xxxRegisterClassEx LPWNDCLASSEX  cczpwc,
PCLSMENUNAME  pcmn,
WORD  fnid,
DWORD  dwFlags,
LPDWORD  pdwWOW
 

Definition at line 101 of file class.c.

References tagCLS::atomClassName, CSF_WOWCLASS, dwFlags, HMValidateHandleNoRip(), tagCLS::hTaskWow, tagTDB::hTaskWow, InternalRegisterClassEx(), ISCPDTAG, tagCLS::lpszClientAnsiMenuName, tagCLS::lpszClientUnicodeMenuName, NULL, PCALLPROCDATA, PCLSMENUNAME, _CALLPROCDATA::pfnClientPrevious, tagCLSMENUNAME::pszClientAnsiMenuName, tagTHREADINFO::ptdb, PtiCurrent, PWCFromPCLS, tagCLSMENUNAME::pwszClientUnicodeMenuName, TIF_16BIT, tagTHREADINFO::TIF_flags, and TYPE_CALLPROC.

Referenced by NtUserRegisterClassExWOW().

00107 { 00108 PCLS pcls; 00109 PTHREADINFO ptiCurrent = PtiCurrent(); 00110 00111 /* 00112 * NOTE -- lpszClassName and lpszMenuName in the wndclass may be client-side 00113 * pointers. Use of those fields must be protected in try blocks. 00114 */ 00115 00116 /* 00117 * Convert a possible CallProc Handle into a real address. They may 00118 * have kept the CallProc Handle from some previous mixed GetClassinfo 00119 * or SetWindowLong. 00120 */ 00121 if (ISCPDTAG(cczpwc->lpfnWndProc)) { 00122 PCALLPROCDATA pCPD; 00123 if (pCPD = HMValidateHandleNoRip((HANDLE)cczpwc->lpfnWndProc, TYPE_CALLPROC)) { 00124 cczpwc->lpfnWndProc = (WNDPROC)pCPD->pfnClientPrevious; 00125 } 00126 } 00127 00128 pcls = InternalRegisterClassEx(cczpwc, fnid, dwFlags | ((ptiCurrent->TIF_flags & TIF_16BIT)? CSF_WOWCLASS : 0) ); 00129 if (pcls != NULL) { 00130 00131 pcls->lpszClientUnicodeMenuName = pcmn->pwszClientUnicodeMenuName; 00132 pcls->lpszClientAnsiMenuName = pcmn->pszClientAnsiMenuName; 00133 00134 /* 00135 * copy 5 WOW dwords. 00136 */ 00137 if (pdwWOW) { 00138 RtlCopyMemory (PWCFromPCLS(pcls), pdwWOW, sizeof(WC)); 00139 } 00140 00141 if ((ptiCurrent->TIF_flags & TIF_16BIT) && ptiCurrent->ptdb) { 00142 pcls->hTaskWow = ptiCurrent->ptdb->hTaskWow; 00143 } else { 00144 pcls->hTaskWow = 0; 00145 } 00146 00147 /* 00148 * For some (presumably good) reason Win 3.1 changed RegisterClass 00149 * to return the classes classname atom. 00150 */ 00151 return pcls->atomClassName; 00152 } else { 00153 return 0; 00154 } 00155 }

ULONG_PTR xxxSetClassData PWND  pwnd,
int  index,
ULONG_PTR  dwData,
BOOL  bAnsi
 

Definition at line 1399 of file class.c.

References afClassDWord, aiClassOffset, AllocateUnicodeString(), BYTE, CheckLock, CPD_ANSI_TO_UNICODE, CPD_CLASS, CPD_UNICODE_TO_ANSI, CSF_ANSIPROC, tagCLS::CSF_flags, CSF_SERVERSIDEPROC, CSF_WOWCLASS, CSF_WOWEXTRA, DWORD, FALSE, GetCPD(), HMValidateHandleNoRip(), INDEX_OFFSET, IS_PTR, ISCPDTAG, tagCLS::lpszClientAnsiMenuName, tagCLS::lpszClientUnicodeMenuName, MapClientNeuterToClientPfn(), MapClientToServerPfn(), MapServerToClientPfn(), NULL, tagWND::pcls, tagCLS::pclsBase, tagCLS::pclsClone, tagCLS::pclsNext, _CALLPROCDATA::pfnClientPrevious, tagCLSMENUNAME::pszClientAnsiMenuName, tagCLSMENUNAME::pusMenuName, PWCFromPCLS, tagCLSMENUNAME::pwszClientUnicodeMenuName, RtlInitUnicodeString(), SetClassCursor(), TRUE, TYPE_CALLPROC, WNDPROC_PWND, and xxxClientWOWGetProcModule().

Referenced by xxxSetClassLongPtr().

01404 { 01405 PCLS pcls = pwnd->pcls; 01406 BYTE *pb; 01407 ULONG_PTR dwT; 01408 ULONG_PTR dwOld; 01409 DWORD dwCPDType = 0; 01410 PCLSMENUNAME pcmn; 01411 UNICODE_STRING strMenuName, UString; 01412 01413 CheckLock(pwnd); 01414 01415 switch(index) { 01416 case GCLP_WNDPROC: 01417 01418 /* 01419 * If the application (client) subclasses a class that has a server - 01420 * side window proc we must return a client side proc stub that it 01421 * can call. 01422 */ 01423 if (pcls->CSF_flags & CSF_SERVERSIDEPROC) { 01424 dwOld = MapServerToClientPfn((ULONG_PTR)pcls->lpfnWndProc, bAnsi); 01425 pcls->CSF_flags &= ~CSF_SERVERSIDEPROC; 01426 01427 UserAssert(!(pcls->CSF_flags & CSF_ANSIPROC)); 01428 if (bAnsi) { 01429 pcls->CSF_flags |= CSF_ANSIPROC; 01430 } 01431 } else { 01432 dwOld = MapClientNeuterToClientPfn(pcls, 0, bAnsi); 01433 01434 /* 01435 * If the client mapping didn't change the window proc then see if 01436 * we need a callproc handle. 01437 */ 01438 if (dwOld == (ULONG_PTR)pcls->lpfnWndProc) { 01439 /* 01440 * Need to return a CallProc handle if there is an Ansi/Unicode mismatch 01441 */ 01442 if (bAnsi != !!(pcls->CSF_flags & CSF_ANSIPROC)) { 01443 dwCPDType |= bAnsi ? CPD_ANSI_TO_UNICODE : CPD_UNICODE_TO_ANSI; 01444 } 01445 } 01446 } 01447 01448 if (dwCPDType) { 01449 ULONG_PTR dwCPD; 01450 01451 dwCPD = GetCPD(pcls, dwCPDType | CPD_CLASS, dwOld); 01452 01453 if (dwCPD) { 01454 dwOld = dwCPD; 01455 } else { 01456 RIPMSG0(RIP_WARNING, "GetClassLong unable to alloc CPD returning handle\n"); 01457 } 01458 } 01459 01460 /* 01461 * Convert a possible CallProc Handle into a real address. They may 01462 * have kept the CallProc Handle from some previous mixed GetClassinfo 01463 * or SetWindowLong. 01464 */ 01465 if (ISCPDTAG(dwData)) { 01466 PCALLPROCDATA pCPD; 01467 if (pCPD = HMValidateHandleNoRip((HANDLE)dwData, TYPE_CALLPROC)) { 01468 dwData = pCPD->pfnClientPrevious; 01469 } 01470 } 01471 01472 /* 01473 * If an app 'unsubclasses' a server-side window proc we need to 01474 * restore everything so SendMessage and friends know that it's 01475 * a server-side proc again. Need to check against client side 01476 * stub addresses. 01477 */ 01478 pcls->lpfnWndProc = (WNDPROC_PWND)dwData; 01479 if ((dwT = MapClientToServerPfn(dwData)) != 0) { 01480 pcls->lpfnWndProc = (WNDPROC_PWND)dwT; 01481 pcls->CSF_flags |= CSF_SERVERSIDEPROC; 01482 pcls->CSF_flags &= ~CSF_ANSIPROC; 01483 } else { 01484 if (bAnsi) { 01485 pcls->CSF_flags |= CSF_ANSIPROC; 01486 } else { 01487 pcls->CSF_flags &= ~CSF_ANSIPROC; 01488 } 01489 } 01490 if (pcls->CSF_flags & CSF_WOWCLASS) { 01491 PWC pwc = PWCFromPCLS(pcls); 01492 pwc->hMod16 = (pcls->CSF_flags & CSF_SERVERSIDEPROC) ? 0:xxxClientWOWGetProcModule(pcls->lpfnWndProc); 01493 } 01494 01495 return dwOld; 01496 break; 01497 01498 case GCLP_HICON: 01499 case GCLP_HICONSM: 01500 case GCLP_HCURSOR: 01501 return SetClassCursor(pwnd, pcls, index, dwData); 01502 break; 01503 01504 01505 case GCL_WOWMENUNAME: 01506 if (pcls->CSF_flags & CSF_WOWCLASS) { 01507 PWCFromPCLS(pcls)->vpszMenu = (DWORD)dwData; 01508 } else { 01509 UserAssert(FALSE); 01510 } 01511 break; 01512 01513 case GCL_CBCLSEXTRA: 01514 if (pcls->CSF_flags & CSF_WOWCLASS) { 01515 /* 01516 * yes -- we can do this for WOW classes only. 01517 */ 01518 if (pcls->CSF_flags & CSF_WOWEXTRA) { 01519 dwOld = PWCFromPCLS(pcls)->iClsExtra; 01520 PWCFromPCLS(pcls)->iClsExtra = LOWORD(dwData); 01521 return dwOld; 01522 } else { 01523 PWCFromPCLS(pcls)->iClsExtra = LOWORD(dwData); 01524 pcls->CSF_flags |= CSF_WOWEXTRA; 01525 return pcls->cbclsExtra; 01526 } 01527 } 01528 RIPERR0(ERROR_INVALID_PARAMETER, RIP_WARNING, "Attempt to change cbClsExtra\n"); 01529 break; 01530 01531 case GCLP_MENUNAME: 01532 pcmn = (PCLSMENUNAME) dwData; 01533 01534 /* 01535 * pcmn->pusMenuName->Buffer is a client-side address. 01536 */ 01537 01538 dwOld = (ULONG_PTR) pcls->lpszMenuName; 01539 /* Is it a string? */ 01540 if (IS_PTR(pcmn->pusMenuName->Buffer)) { 01541 try { 01542 RtlInitUnicodeString(&UString, pcmn->pusMenuName->Buffer); 01543 } except (W32ExceptionHandler(TRUE, RIP_WARNING)) { 01544 break; 01545 } 01546 /* Empty String? */ 01547 if (UString.Length == 0) { 01548 pcls->lpszMenuName = NULL; 01549 } else { 01550 /* Make a copy of the string */ 01551 if (!AllocateUnicodeString(&strMenuName, &UString)) { 01552 RIPMSG0(RIP_WARNING, "xxxSetClassData: GCL_MENUNAME AllocateUnicodeString failed\n"); 01553 break; 01554 } 01555 01556 pcls->lpszMenuName = strMenuName.Buffer; 01557 } 01558 } else { 01559 /* Just copy the id */ 01560 pcls->lpszMenuName = pcmn->pusMenuName->Buffer; 01561 } 01562 /* Don't return the kernel side pointer */ 01563 pcmn->pusMenuName = NULL; 01564 01565 /* Free old string, if any */ 01566 if (IS_PTR(dwOld)) { 01567 UserFreePool((PVOID)dwOld); 01568 } 01569 01570 /* Return client side pointers */ 01571 dwOld = (ULONG_PTR) pcls->lpszClientAnsiMenuName; 01572 pcls->lpszClientAnsiMenuName = pcmn->pszClientAnsiMenuName; 01573 pcmn->pszClientAnsiMenuName = (LPSTR)dwOld; 01574 01575 dwOld = (ULONG_PTR) pcls->lpszClientUnicodeMenuName; 01576 pcls->lpszClientUnicodeMenuName = pcmn->pwszClientUnicodeMenuName; 01577 pcmn->pwszClientUnicodeMenuName = (LPWSTR)dwOld; 01578 01579 return (bAnsi ? (ULONG_PTR) pcmn->pszClientAnsiMenuName : (ULONG_PTR) pcmn->pwszClientUnicodeMenuName); 01580 01581 default: 01582 /* 01583 * All other indexes go here... 01584 */ 01585 index -= INDEX_OFFSET; 01586 01587 /* 01588 * Only let valid indices go through; if aiClassOffset is zero 01589 * then we have no mapping for this negative index so it must 01590 * be a bogus index 01591 */ 01592 if ((index < 0) || (aiClassOffset[index] == 0)) { 01593 RIPERR0(ERROR_INVALID_INDEX, RIP_WARNING, "GetClassLong: invalid index"); 01594 return 0; 01595 } 01596 01597 pcls = pcls->pclsBase; 01598 pb = ((BYTE *)pcls) + aiClassOffset[index]; 01599 01600 if (afClassDWord[index] == sizeof(DWORD)) { 01601 dwOld = *(DWORD *)pb; 01602 *(DWORD *)pb = (DWORD)dwData; 01603 } else if (afClassDWord[index] == sizeof(ULONG_PTR)) { 01604 dwOld = *(ULONG_PTR *)pb; 01605 *(ULONG_PTR *)pb = dwData; 01606 } else { 01607 dwOld = (DWORD)*(WORD *)pb; 01608 *(WORD *)pb = (WORD)dwData; 01609 } 01610 01611 pcls = pcls->pclsClone; 01612 while (pcls != NULL) { 01613 pb = ((BYTE *)pcls) + aiClassOffset[index]; 01614 01615 if (afClassDWord[index] == sizeof(DWORD)) { 01616 dwOld = *(DWORD *)pb; 01617 *(DWORD *)pb = (DWORD)dwData; 01618 } else if (afClassDWord[index] == sizeof(ULONG_PTR)) { 01619 dwOld = *(ULONG_PTR *)pb; 01620 *(ULONG_PTR *)pb = dwData; 01621 } else { 01622 dwOld = (DWORD)*(WORD *)pb; 01623 *(WORD *)pb = (WORD)dwData; 01624 } 01625 pcls = pcls->pclsNext; 01626 } 01627 01628 return dwOld; 01629 } 01630 01631 return 0; 01632 }

ULONG_PTR xxxSetClassLongPtr PWND  pwnd,
int  index,
ULONG_PTR  value,
BOOL  bAnsi
 

Definition at line 909 of file class.c.

References BYTE, CheckCritIn, CheckLock, GETPTI, NULL, tagWND::pcls, tagCLS::pclsBase, tagCLS::pclsClone, tagCLS::pclsNext, PpiCurrent, and xxxSetClassData().

00914 { 00915 ULONG_PTR dwOld; 00916 PCLS pcls; 00917 00918 CheckLock(pwnd); 00919 CheckCritIn(); 00920 00921 if (GETPTI(pwnd)->ppi != PpiCurrent()) { 00922 RIPERR1(ERROR_ACCESS_DENIED, RIP_WARNING, "SetClassLongPtr: different process: index 0x%lx", index); 00923 return 0; 00924 } 00925 00926 if (index < 0) { 00927 return xxxSetClassData(pwnd, index, value, bAnsi); 00928 } else { 00929 pcls = pwnd->pcls->pclsBase; 00930 if (index + (int)sizeof(ULONG_PTR) > pcls->cbclsExtra) { 00931 RIPERR0(ERROR_INVALID_INDEX, RIP_WARNING, "SetClassLongPtr: invalid index"); 00932 return 0; 00933 } else { 00934 ULONG_PTR UNALIGNED *pudw; 00935 pudw = (ULONG_PTR UNALIGNED *)((BYTE *)(pcls + 1) + index); 00936 dwOld = *pudw; 00937 *pudw = value; 00938 pcls = pcls->pclsClone; 00939 while (pcls != NULL) { 00940 pudw = (ULONG_PTR UNALIGNED *)((BYTE *)(pcls + 1) + index); 00941 *pudw = value; 00942 pcls = pcls->pclsNext; 00943 } 00944 return dwOld; 00945 } 00946 } 00947 }


Variable Documentation

CONST BYTE afClassDWord[]
 

Initial value:

{ FIELD_SIZE(CLS, spicnSm), 0, FIELD_SIZE(CLS, atomClassName), 0, 0, 0, 0, 0, FIELD_SIZE(CLS, style), 0, FIELD_SIZE(CLS, lpfnWndProc), 0, 0, 0, FIELD_SIZE(CLS, cbclsExtra), 0, FIELD_SIZE(CLS, cbwndExtra), 0, FIELD_SIZE(CLS, hModule), 0, FIELD_SIZE(CLS, spicn), 0, FIELD_SIZE(CLS, spcur), 0, FIELD_SIZE(CLS, hbrBackground), 0, FIELD_SIZE(CLS, lpszMenuName) }

Definition at line 24 of file class.c.

CONST BYTE aiClassOffset[]
 

Initial value:

{ FIELD_OFFSET(CLS, spicnSm), 0, FIELD_OFFSET(CLS, atomClassName), 0, 0, 0, 0, 0, FIELD_OFFSET(CLS, style), 0, FIELD_OFFSET(CLS, lpfnWndProc), 0, 0, 0, FIELD_OFFSET(CLS, cbclsExtra), 0, FIELD_OFFSET(CLS, cbwndExtra), 0, FIELD_OFFSET(CLS, hModule), 0, FIELD_OFFSET(CLS, spicn), 0, FIELD_OFFSET(CLS, spcur), 0, FIELD_OFFSET(CLS, hbrBackground), 0, FIELD_OFFSET(CLS, lpszMenuName) }

Definition at line 54 of file class.c.


Generated on Sat May 15 19:43:04 2004 for test by doxygen 1.3.7