00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
#include "precomp.h"
00016
#pragma hdrstop
00017
00018
00019
00020
00021
00022
00023
00024 CONST
BYTE afClassDWord[] = {
00025
FIELD_SIZE(
CLS, spicnSm),
00026 0,
00027
FIELD_SIZE(
CLS, atomClassName),
00028 0,
00029 0,
00030 0,
00031 0,
00032 0,
00033
FIELD_SIZE(
CLS, style),
00034 0,
00035
FIELD_SIZE(
CLS, lpfnWndProc),
00036 0,
00037 0,
00038 0,
00039
FIELD_SIZE(
CLS, cbclsExtra),
00040 0,
00041
FIELD_SIZE(
CLS, cbwndExtra),
00042 0,
00043
FIELD_SIZE(
CLS, hModule),
00044 0,
00045
FIELD_SIZE(
CLS, spicn),
00046 0,
00047
FIELD_SIZE(
CLS, spcur),
00048 0,
00049
FIELD_SIZE(
CLS, hbrBackground),
00050 0,
00051
FIELD_SIZE(
CLS, lpszMenuName)
00052 };
00053
00054 CONST
BYTE aiClassOffset[] = {
00055 FIELD_OFFSET(
CLS, spicnSm),
00056 0,
00057 FIELD_OFFSET(
CLS, atomClassName),
00058 0,
00059 0,
00060 0,
00061 0,
00062 0,
00063 FIELD_OFFSET(
CLS, style),
00064 0,
00065 FIELD_OFFSET(
CLS, lpfnWndProc),
00066 0,
00067 0,
00068 0,
00069 FIELD_OFFSET(
CLS, cbclsExtra),
00070 0,
00071 FIELD_OFFSET(
CLS, cbwndExtra),
00072 0,
00073 FIELD_OFFSET(
CLS, hModule),
00074 0,
00075 FIELD_OFFSET(
CLS, spicn),
00076 0,
00077 FIELD_OFFSET(
CLS, spcur),
00078 0,
00079 FIELD_OFFSET(
CLS, hbrBackground),
00080 0,
00081 FIELD_OFFSET(
CLS, lpszMenuName)
00082 };
00083
00084
00085
00086
00087 #define INDEX_OFFSET GCLP_HICONSM
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 ATOM
xxxRegisterClassEx(
00102 LPWNDCLASSEX cczpwc,
00103
PCLSMENUNAME pcmn,
00104 WORD fnid,
00105 DWORD dwFlags,
00106 LPDWORD pdwWOW )
00107 {
00108
PCLS pcls;
00109
PTHREADINFO ptiCurrent =
PtiCurrent();
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
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
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
00149
00150
00151
return pcls->
atomClassName;
00152 }
else {
00153
return 0;
00154 }
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 PVOID
ClassAlloc(
00170
PDESKTOP pdesk,
00171 DWORD cbAlloc)
00172 {
00173 PVOID pvalloc;
00174
00175
if (pdesk)
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 pvalloc = (
PCLS)
DesktopAllocAlways(pdesk, cbAlloc,
DTAG_CLASS);
00186
else {
00187 pvalloc = (
PCLS)UserAllocPoolWithQuotaZInit(cbAlloc, TAG_CLASS);
00188 }
00189
00190
return pvalloc;
00191 }
00192
00193 VOID ClassFree(
00194
PDESKTOP pdesk,
00195 PVOID pvfree)
00196 {
00197
if (pdesk !=
NULL)
00198
DesktopFree(pdesk, pvfree);
00199
else
00200 UserFreePool(pvfree);
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 BOOL ValidateAndLockCursor (
PCURSOR * ppcursor, BOOL fIs40Compat)
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 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 PCLS InternalRegisterClassEx(
00245 LPWNDCLASSEX cczlpwndcls,
00246 WORD fnid,
00247 DWORD CSF_flags
00248 )
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
00264
00265
00266
CheckCritIn();
00267
00268 ptiCurrent =
PtiCurrent();
00269
00270
00271
00272
00273
00274
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
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
00295
00296 atomT =
FindClassAtom(cczlpwndcls->lpszClassName);
00297
00298
if (atomT != 0 && !(CSF_flags &
CSF_SERVERSIDEPROC)) {
00299
00300
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
00310
00311
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
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
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
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
00355
00356
00357 ptiCurrent->
pClientInfo->
CI_flags &= ~
CI_REGISTERCLASSES;
00358 }
00359 }
00360
00361
00362
00363
00364
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
00377
00378
00379
00380
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
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
00413
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;
00428 }
00429
00430
00431
00432
00433
00434 pcls->lpszAnsiClassName = (LPSTR)
ClassAlloc(pdesk, cch);
00435
if (pcls->lpszAnsiClassName ==
NULL) {
00436
goto MemError2;
00437 }
00438
00439
00440
00441
00442
if (
IS_PTR(cczlpwndcls->lpszClassName)) {
00443
00444
00445
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
00459
00460 pcls->lpszAnsiClassName[0] =
L'#';
00461
RtlIntegerToChar(
PTR_TO_ID(cczlpwndcls->lpszClassName), 10, cch - 1,
00462 &pcls->lpszAnsiClassName[1]);
00463 }
00464
00465
00466
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
00481
00482 pcls->lpszMenuName =
NULL;
00483 }
else {
00484 UNICODE_STRING strMenuName;
00485
00486
00487
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
00526
00527
00528
00529
return pcls;
00530 }
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 BOOL _UnregisterClass(
00556 LPCWSTR ccxlpszClassName,
00557 HANDLE hModule,
00558
PCLSMENUNAME pcmn)
00559 {
00560 ATOM atomT;
00561
PPCLS ppcls;
00562
PTHREADINFO ptiCurrent;
00563
00564
CheckCritIn();
00565
00566 ptiCurrent =
PtiCurrent();
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 atomT =
FindClassAtom(ccxlpszClassName);
00579
00580 ppcls =
_InnerGetClassPtr(atomT, &ptiCurrent->
ppi->
pclsPrivateList, hModule);
00581
if (ppcls ==
NULL) {
00582
00583
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
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
00602
00603 pcmn->
pszClientAnsiMenuName = (*ppcls)->lpszClientAnsiMenuName;
00604 pcmn->
pwszClientUnicodeMenuName = (*ppcls)->lpszClientUnicodeMenuName;
00605 pcmn->
pusMenuName =
NULL;
00606
00607
00608
00609
00610
DestroyClass(ppcls);
00611
00612
return TRUE;
00613 }
00614
00615
00616 PCLS _GetWOWClass(
00617 HANDLE hModule,
00618 LPCWSTR ccxlpszClassName)
00619 {
00620
PCLS pcls;
00621
PPCLS ppcls =
NULL;
00622 ATOM atomT;
00623
PTHREADINFO ptiCurrent;
00624
00625
CheckCritInShared();
00626
00627 ptiCurrent =
PtiCurrentShared();
00628
00629
00630
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 }
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 ATOM
_GetClassInfoEx(
00679 HANDLE hModule,
00680 LPCWSTR ccxlpszClassName,
00681 LPWNDCLASSEX pwc,
00682 LPWSTR *ppszMenuName,
00683 BOOL bAnsi)
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
00697
00698
00699
00700 pwc->lpszMenuName =
NULL;
00701 pwc->lpszClassName =
NULL;
00702
00703
00704
00705
00706
00707
00708
00709
00710 atomT =
FindClassAtom(ccxlpszClassName);
00711
00712
00713
00714
00715
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
00733
00734
00735
00736
00737
00738
00739
00740 pwc->style = pcls->style & CS_VALID;
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
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
00765
00766
00767
00768
if (LOWORD(ptiCurrent->
dwExpWinVer) >=
VER40) {
00769
00770
00771
00772
00773
00774
if (hModule ==
hModClient) {
00775 pwc->hInstance =
NULL;
00776 }
else {
00777 pwc->hInstance = hModule;
00778 }
00779 }
else {
00780
00781
00782
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
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
00806
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
00816
00817
00818
if (pwc->lpfnWndProc == (WNDPROC)pcls->lpfnWndProc) {
00819
00820
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
00842
00843
if (bAnsi) {
00844 *ppszMenuName = (LPWSTR)pcls->
lpszClientAnsiMenuName;
00845 }
else {
00846 *ppszMenuName = pcls->
lpszClientUnicodeMenuName;
00847 }
00848
return pcls->
atomClassName;
00849 }
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863 WORD
_SetClassWord(
00864
PWND pwnd,
00865
int index,
00866 WORD value)
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 }
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909 ULONG_PTR
xxxSetClassLongPtr(
00910
PWND pwnd,
00911
int index,
00912 ULONG_PTR value,
00913 BOOL bAnsi)
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 }
00948
00949
00950
#ifdef _WIN64
00951
DWORD xxxSetClassLong(
00952
PWND pwnd,
00953
int index,
00954 DWORD value,
00955 BOOL bAnsi)
00956 {
00957
DWORD dwOld;
00958
PCLS pcls;
00959
00960
CheckLock(pwnd);
00961
CheckCritIn();
00962
00963
if (
GETPTI(pwnd)->ppi !=
PpiCurrent()) {
00964 RIPERR1(ERROR_ACCESS_DENIED, RIP_WARNING,
"SetClassLong: different process: index 0x%lx", index);
00965
return 0;
00966 }
00967
00968
if (index < 0) {
00969
if (index <
INDEX_OFFSET ||
afClassDWord[index -
INDEX_OFFSET] >
sizeof(
DWORD)) {
00970 RIPERR1(ERROR_INVALID_INDEX, RIP_WARNING,
"SetClassLong: invalid index %d", index);
00971
return 0;
00972 }
00973
return (
DWORD)
xxxSetClassData(pwnd, index, value, bAnsi);
00974 }
else {
00975 pcls = pwnd->
pcls->
pclsBase;
00976
if (index + (
int)
sizeof(
DWORD) > pcls->cbclsExtra) {
00977 RIPERR0(ERROR_INVALID_INDEX, RIP_WARNING,
"SetClassLong: invalid index");
00978
return 0;
00979 }
else {
00980
DWORD UNALIGNED *pudw;
00981 pudw = (
DWORD UNALIGNED *)((
BYTE *)(pcls + 1) + index);
00982 dwOld = *pudw;
00983 *pudw = value;
00984 pcls = pcls->
pclsClone;
00985
while (pcls !=
NULL) {
00986 pudw = (
DWORD UNALIGNED *)((
BYTE *)(pcls + 1) + index);
00987 *pudw = value;
00988 pcls = pcls->
pclsNext;
00989 }
00990
return dwOld;
00991 }
00992 }
00993 }
00994
#endif
00995
00996
00997 PPCLS _InnerGetClassPtr(
00998 ATOM atom,
00999
PPCLS ppcls,
01000 HANDLE hModule)
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 }
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036 PPCLS GetClassPtr(
01037 ATOM atom,
01038
PPROCESSINFO ppi,
01039 HANDLE hModule)
01040 {
01041
PPCLS ppcls;
01042
01043
01044
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
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
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
01078
01079 ppcls =
_InnerGetClassPtr(atom, &
gpclsList,
NULL);
01080
return ppcls;
01081 }
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092 VOID UnlockAndFreeCPDs(
01093
PCALLPROCDATA *ppCPD)
01094 {
01095
PCALLPROCDATA pCPD;
01096
01097
while ((pCPD = *ppCPD) !=
NULL) {
01098
01099
01100
01101 *ppCPD = pCPD->
spcpdNext;
01102 pCPD->
spcpdNext =
NULL;
01103
01104
01105
01106
01107
if (!
HMIsMarkDestroy(pCPD)) {
01108
HMMarkObjectDestroy(pCPD);
01109 }
01110
01111
01112
01113
01114
Unlock(&pCPD);
01115 }
01116 }
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128 void DestroyClassBrush(
01129
PCLS pcls)
01130 {
01131
PPROCESSINFO ppi =
PpiCurrent();
01132
PCLS pclsWalk;
01133
int nInd;
01134
BOOL bRet;
01135
01136
01137
01138
if (pcls->hbrBackground <= (HBRUSH)(COLOR_MAX))
01139
return;
01140
01141
01142
01143
01144
for (nInd = 0; nInd < COLOR_MAX; nInd++) {
01145
if (pcls->hbrBackground ==
SYSHBRUSH(nInd))
01146
return;
01147 }
01148
01149
01150
01151
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
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
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
}
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207 void DestroyClass(
01208
PPCLS ppcls)
01209 {
01210
PPCLS ppclsClone;
01211
PCLS pcls;
01212
PDESKTOP rpdesk;
01213
01214 pcls = *ppcls;
01215
01216 UserAssert(pcls->
cWndReferenceCount == 0);
01217
01218
01219
01220
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
01232
01233
if (
IS_PTR(pcls->lpszMenuName)) {
01234 UserFreePool(pcls->lpszMenuName);
01235 }
01236
01237
01238
01239
01240
if (pcls->
pdce !=
NULL)
01241
DestroyCacheDC(
NULL, pcls->
pdce->
hdc);
01242
01243
01244
01245
01246
01247
DestroyClassBrush(pcls);
01248 }
01249
01250
01251
01252
01253
DestroyClassSmIcon(pcls);
01254
01255
01256
01257
01258
Unlock(&pcls->spicn);
01259
Unlock(&pcls->spicnSm);
01260
Unlock(&pcls->spcur);
01261
01262
01263
01264
01265
if (pcls->
spcpdFirst) {
01266
UnlockAndFreeCPDs(&pcls->
spcpdFirst);
01267 }
01268
01269
01270
01271
01272 *ppcls = pcls->
pclsNext;
01273
01274
01275
01276
01277
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 }
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297 PCURSOR GetClassIcoCur(
PWND pwnd,
int index)
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 }
01323
01324
01325
01326
01327
01328
01329 ULONG_PTR
SetClassCursor(
01330
PWND pwnd,
01331
PCLS pcls,
01332 DWORD index,
01333 ULONG_PTR dwData)
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
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
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 }
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399 ULONG_PTR
xxxSetClassData(
01400
PWND pwnd,
01401
int index,
01402 ULONG_PTR dwData,
01403 BOOL bAnsi)
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
01420
01421
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
01436
01437
01438
if (dwOld == (ULONG_PTR)pcls->lpfnWndProc) {
01439
01440
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
01462
01463
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
01474
01475
01476
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
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
01536
01537
01538 dwOld = (ULONG_PTR) pcls->lpszMenuName;
01539
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
01547
if (UString.Length == 0) {
01548 pcls->lpszMenuName =
NULL;
01549 }
else {
01550
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
01560 pcls->lpszMenuName = pcmn->
pusMenuName->Buffer;
01561 }
01562
01563 pcmn->
pusMenuName =
NULL;
01564
01565
01566
if (
IS_PTR(dwOld)) {
01567 UserFreePool((PVOID)dwOld);
01568 }
01569
01570
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
01584
01585 index -=
INDEX_OFFSET;
01586
01587
01588
01589
01590
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 }
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645 BOOL ReferenceClass(
01646
PCLS pcls,
01647
PWND pwnd)
01648 {
01649
DWORD cbName;
01650
PCLS pclsClone;
01651
PDESKTOP pdesk;
01652
01653
01654
01655
01656
01657
if (pcls->
rpdeskParent == pwnd->
head.rpdesk) {
01658 pcls->
cWndReferenceCount++;
01659
return TRUE;
01660 }
01661
01662
01663
01664
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
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
01694
01695
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
01716
01717 pcls->
cWndReferenceCount++;
01718 pclsClone->
cWndReferenceCount++;
01719 pwnd->
pcls = pclsClone;
01720
01721
return TRUE;
01722 }
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735 VOID DereferenceClass(
01736
PWND pwnd)
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 }
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768 VOID DestroyProcessesClasses(
01769
PPROCESSINFO ppi)
01770 {
01771
PPCLS ppcls;
01772
01773
01774
01775
01776 ppcls = &(ppi->
pclsPrivateList);
01777
while (*ppcls !=
NULL) {
01778
DestroyClass(ppcls);
01779 }
01780
01781
01782
01783
01784 ppcls = &(ppi->
pclsPublicList);
01785
while (*ppcls !=
NULL) {
01786
DestroyClass(ppcls);
01787 }
01788 }