00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#include "precomp.h"
00015
#pragma hdrstop
00016
#include <wchar.h>
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 HCURSOR
_CreateEmptyCursorObject(
00027 BOOL fPublic)
00028 {
00029
PCURSOR pcurT;
00030
00031
00032
00033
00034 pcurT = (
PCURSOR)
HMAllocObject(
PtiCurrent(),
00035
NULL,
00036
TYPE_CURSOR,
00037
max(
sizeof(
CURSOR),
00038
sizeof(
ACON)));
00039
00040
if (fPublic && (pcurT !=
NULL)) {
00041 pcurT->head.ppi =
NULL;
00042 UserAssert(
PtiCurrent()->TIF_flags & (
TIF_CSRSSTHREAD |
TIF_SYSTEMTHREAD));
00043 }
00044
00045
return (HCURSOR)
PtoH(pcurT);
00046 }
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 VOID UnlinkCursor(
00058
PCURSOR pcur)
00059 {
00060
PCURSOR *ppcurT;
00061
BOOL fTriedPublicCache;
00062
BOOL fTriedThisProcessCache =
FALSE;
00063
00064
00065
00066
00067
00068
00069
if (fTriedPublicCache = (pcur->head.ppi ==
NULL)) {
00070 ppcurT = &
gpcurFirst;
00071 }
else {
00072 ppcurT = &pcur->head.ppi->pCursorCache;
00073 }
00074
00075 LookAgain:
00076
00077
for (; *ppcurT !=
NULL; ppcurT = &((*ppcurT)->pcurNext)) {
00078
if (*ppcurT == pcur) {
00079 *ppcurT = pcur->pcurNext;
00080 FreeIt:
00081 pcur->pcurNext =
NULL;
00082 pcur->CURSORF_flags &= ~
CURSORF_LINKED;
00083
return;
00084 }
00085 }
00086
00087
00088
00089
00090
00091
00092
if (!fTriedPublicCache) {
00093 ppcurT = &
gpcurFirst;
00094 fTriedPublicCache =
TRUE;
00095
goto LookAgain;
00096 }
00097
00098
00099
00100
00101
00102
00103
if (!fTriedThisProcessCache) {
00104 ppcurT = &
PpiCurrent()->pCursorCache;
00105 fTriedThisProcessCache =
TRUE;
00106
goto LookAgain;
00107 }
00108
00109
00110
00111
00112
00113 {
00114
PHE pheMax, pheT;
00115
00116 pheMax = &
gSharedInfo.
aheList[
giheLast];
00117
for (pheT =
gSharedInfo.
aheList; pheT <= pheMax; pheT++) {
00118
if (pheT->
bType ==
TYPE_CURSOR) {
00119
if (((
PCURSOR)pheT->
phead)->pcurNext == pcur) {
00120 ((
PCURSOR)pheT->
phead)->pcurNext = pcur->pcurNext;
00121
goto FreeIt;
00122 }
else if (pheT->
pOwner && ((
PPROCESSINFO)pheT->
pOwner)->pCursorCache == pcur) {
00123 ((
PPROCESSINFO)pheT->
pOwner)->pCursorCache = pcur->pcurNext;
00124
goto FreeIt;
00125 }
00126 }
00127 }
00128 }
00129
00130 UserAssert(
FALSE);
00131 }
00132
00133
00134
00135
00136
00137
00138 VOID DestroyEmptyCursorObject(
00139
PCURSOR pcur)
00140 {
00141
if (pcur->CURSORF_flags &
CURSORF_LINKED) {
00142
UnlinkCursor(pcur);
00143 }
00144
00145
HMFreeObject(pcur);
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 VOID ZombieCursor(
PCURSOR pcur)
00157 {
00158
if (pcur->CURSORF_flags &
CURSORF_LINKED) {
00159
UnlinkCursor(pcur);
00160 }
00161
00162
#if DBG
00163
if (
ISTS()) {
00164
PHE phe;
00165 phe =
HMPheFromObject(pcur);
00166
00167
if (phe->
pOwner ==
NULL) {
00168 RIPMSG2(RIP_ERROR,
"NULL owner for cursor %x phe %x\n",
00169 pcur, phe);
00170 }
00171 }
00172
#endif // DBG
00173
00174
HMChangeOwnerProcess(pcur,
gptiRit);
00175
00176 RIPMSG1(RIP_WARNING,
"ZombieCursor: 0x%08X became a zombie", pcur);
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 BOOL ResStrCmp(
00191 PUNICODE_STRING cczpstr1,
00192 PUNICODE_STRING pstr2)
00193 {
00194
BOOL retval =
FALSE;
00195
00196
00197
00198
00199
00200
if (cczpstr1->Length == 0) {
00201
00202
00203
00204
00205
if (cczpstr1->Buffer == pstr2->Buffer)
00206
return TRUE;
00207
00208 }
else {
00209
00210
try {
00211
00212
00213
00214
00215
00216
00217
00218
00219
if (pstr2->Length != 0) {
00220
00221
if (
RtlEqualUnicodeString(cczpstr1, pstr2,
TRUE))
00222 retval =
TRUE;
00223
00224 }
else if (cczpstr1->Buffer[0] ==
'#') {
00225
00226 UNICODE_STRING strId;
00227
int id;
00228
00229 strId.Length = cczpstr1->Length -
sizeof(WCHAR);
00230 strId.MaximumLength = strId.Length;
00231 strId.Buffer = cczpstr1->Buffer + 1;
00232
RtlUnicodeStringToInteger(&strId, 10, (PULONG)&
id);
00233
00234
if (
id == (LONG_PTR)pstr2->Buffer)
00235 retval =
TRUE;
00236 }
00237 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00238 }
00239 }
00240
00241
return retval;
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 PCURSOR SearchIconCache(
00255
PCURSOR pCursorCache,
00256 ATOM atomModName,
00257 PUNICODE_STRING cczpstrResName,
00258
PCURSOR pcurSrc,
00259
PCURSORFIND pcfSearch)
00260 {
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
for (; pCursorCache !=
NULL; pCursorCache = pCursorCache->pcurNext) {
00275
00276
00277
00278
00279
00280
if (pcurSrc && (pCursorCache == pcurSrc))
00281
return pcurSrc;
00282
00283
00284
00285
00286
if (atomModName != pCursorCache->atomModName)
00287
continue;
00288
00289
00290
00291
00292
00293
00294
if (!(pCursorCache->CURSORF_flags &
CURSORF_LRSHARED))
00295
continue;
00296
00297
00298
00299
00300
00301
if ((pCursorCache->rt == LOWORD(pcfSearch->
rt)) &&
00302
ResStrCmp(cczpstrResName, &pCursorCache->strName)) {
00303
00304
00305
00306
00307
00308
00309
if (pCursorCache->CURSORF_flags &
CURSORF_ACON)
00310
return pCursorCache;
00311
00312
00313
00314
00315
00316
if ((!pcfSearch->
cx || (pCursorCache->cx == pcfSearch->
cx)) &&
00317 (!pcfSearch->
cy || ((pCursorCache->cy / 2) == pcfSearch->
cy)) &&
00318 (!pcfSearch->
bpp || (pCursorCache->bpp == pcfSearch->
bpp))) {
00319
00320
return pCursorCache;
00321 }
00322 }
00323 }
00324
00325
return NULL;
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 PCURSOR _FindExistingCursorIcon(
00358 ATOM atomModName,
00359 PUNICODE_STRING cczpstrResName,
00360
PCURSOR pcurSrc,
00361
PCURSORFIND pcfSearch)
00362 {
00363
PCURSOR pcurT =
NULL;
00364
00365
00366
00367
00368
00369
if (pcfSearch->
rt && atomModName) {
00370
00371 pcurT =
SearchIconCache(
PpiCurrent()->pCursorCache,
00372 atomModName,
00373 cczpstrResName,
00374 pcurSrc,
00375 pcfSearch);
00376
if (pcurT ==
NULL) {
00377 pcurT =
SearchIconCache(
gpcurFirst,
00378 atomModName,
00379 cczpstrResName,
00380 pcurSrc,
00381 pcfSearch);
00382 }
00383 }
00384
00385
return pcurT;
00386 }
00387
00388
00389
00390
00391
00392
00393
00394
00395 BOOL _InternalGetIconInfo(
00396 IN
PCURSOR pcur,
00397 OUT PICONINFO ccxpiconinfo,
00398 OUT OPTIONAL PUNICODE_STRING pstrInstanceName,
00399 OUT OPTIONAL PUNICODE_STRING pstrResName,
00400 OUT OPTIONAL LPDWORD ccxpbpp,
00401 IN BOOL fInternalCursor)
00402 {
00403 HBITMAP hbmBitsT;
00404 HBITMAP hbmDstT;
00405 HBITMAP hbmMask;
00406 HBITMAP hbmColor;
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
if (pcur->CURSORF_flags &
CURSORF_ACON)
00419 pcur = ((
PACON)pcur)->aspcur[0];
00420
00421
00422
00423
00424
00425
00426
00427 hbmMask = GreCreateBitmap(
00428 pcur->cx,
00429 (pcur->hbmColor && !fInternalCursor) ? pcur->cy / 2 : pcur->cy,
00430 1,
00431 1,
00432
NULL);
00433
00434
if (hbmMask ==
NULL)
00435
return FALSE;
00436
00437
00438 hbmColor =
NULL;
00439
00440
if (pcur->hbmColor !=
NULL) {
00441
00442 hbmColor = GreCreateCompatibleBitmap(
HDCBITS(),
00443 pcur->cx,
00444 pcur->cy / 2);
00445
00446
if (hbmColor ==
NULL) {
00447 GreDeleteObject(hbmMask);
00448
return FALSE;
00449 }
00450 }
00451
00452 hbmBitsT = GreSelectBitmap(
ghdcMem2, pcur->hbmMask);
00453 hbmDstT = GreSelectBitmap(
ghdcMem, hbmMask);
00454
00455 GreBitBlt(
ghdcMem,
00456 0,
00457 0,
00458 pcur->cx,
00459 (pcur->hbmColor && !fInternalCursor) ? pcur->cy / 2 : pcur->cy,
00460
ghdcMem2,
00461 0,
00462 0,
00463 SRCCOPY,
00464 0x00ffffff);
00465
00466
if (hbmColor !=
NULL) {
00467
00468 GreSelectBitmap(
ghdcMem2, pcur->hbmColor);
00469 GreSelectBitmap(
ghdcMem, hbmColor);
00470
00471 GreBitBlt(
ghdcMem,
00472 0,
00473 0,
00474 pcur->cx,
00475 pcur->cy / 2,
00476
ghdcMem2,
00477 0,
00478 0,
00479 SRCCOPY,
00480 0);
00481 }
00482
00483 GreSelectBitmap(
ghdcMem2, hbmBitsT);
00484 GreSelectBitmap(
ghdcMem, hbmDstT);
00485
00486
00487
00488
00489
try {
00490
00491 ccxpiconinfo->fIcon = (pcur->rt ==
PTR_TO_ID(RT_ICON));
00492 ccxpiconinfo->xHotspot = pcur->xHotspot;
00493 ccxpiconinfo->yHotspot = pcur->yHotspot;
00494 ccxpiconinfo->hbmMask = hbmMask;
00495 ccxpiconinfo->hbmColor = hbmColor;
00496
00497
if (pstrInstanceName !=
NULL) {
00498
00499
if (pcur->atomModName) {
00500 pstrInstanceName->Length = (
USHORT)
00501
UserGetAtomName(pcur->atomModName,
00502 pstrInstanceName->Buffer,
00503 (
int) (pstrInstanceName->MaximumLength /
sizeof(WCHAR))
00504 *
sizeof(WCHAR));
00505 }
else {
00506 pstrInstanceName->Length = 0;
00507 }
00508 }
00509
00510
if (pstrResName !=
NULL) {
00511
00512
if (
IS_PTR(pcur->strName.Buffer)) {
00513
RtlCopyUnicodeString(pstrResName, &pcur->strName);
00514 }
else {
00515 *pstrResName = pcur->strName;
00516 }
00517 }
00518
00519
if (ccxpbpp)
00520 *ccxpbpp = pcur->bpp;
00521
00522 } except (W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00523 GreDeleteObject(hbmMask);
00524 GreDeleteObject(hbmColor);
00525
return FALSE;
00526 }
00527
00528
return TRUE;
00529 }
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 BOOL _DestroyCursor(
00540
PCURSOR pcur,
00541 DWORD cmdDestroy)
00542 {
00543
PPROCESSINFO ppi;
00544
PPROCESSINFO ppiCursor;
00545
int i;
00546
extern BOOL DestroyAniIcon(
PACON pacon);
00547
00548
if (pcur ==
NULL) {
00549 UserAssert(
FALSE);
00550
return(
TRUE);
00551 }
00552 ppi =
PpiCurrent();
00553 ppiCursor =
GETPPI(pcur);
00554
00555
00556
00557
00558
for (i = 0; i <
CCACHEDCAPTIONS; i++) {
00559
if (
gcachedCaptions[i].
spcursor == pcur) {
00560
Unlock( &(
gcachedCaptions[i].spcursor) );
00561 }
00562 }
00563
00564
00565
00566
00567
switch (cmdDestroy) {
00568
00569
case CURSOR_ALWAYSDESTROY:
00570
00571
00572
00573
00574
break;
00575
00576
case CURSOR_CALLFROMCLIENT:
00577
00578
00579
00580
00581
if (ppiCursor ==
NULL)
00582
00583
00584
00585
00586
return !!(pcur->CURSORF_flags &
CURSORF_FROMRESOURCE);
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
if (pcur->CURSORF_flags & (
CURSORF_LRSHARED |
CURSORF_SECRET)) {
00597
return TRUE;
00598 }
00599
00600
00601
00602
00603
if (ppiCursor != ppi) {
00604 RIPERR0(ERROR_DESTROY_OBJECT_OF_OTHER_THREAD, RIP_ERROR,
"DestroyCursor: cursor belongs to another process");
00605
return FALSE;
00606 }
00607
00608
00609
00610
00611
00612
case CURSOR_THREADCLEANUP:
00613
00614
00615
00616
00617
if (ppiCursor ==
NULL)
00618
return TRUE;
00619
break;
00620 }
00621
00622
00623
00624
00625
00626
00627
if (!
HMMarkObjectDestroy((
PHEAD)pcur))
00628
return FALSE;
00629
00630
if (pcur->strName.Length != 0) {
00631 UserFreePool((LPSTR)pcur->strName.Buffer);
00632 }
00633
00634
if (pcur->atomModName != 0) {
00635
UserDeleteAtom(pcur->atomModName);
00636 }
00637
00638
00639
00640
00641
if (pcur->CURSORF_flags &
CURSORF_ACON) {
00642
DestroyAniIcon((
PACON)pcur);
00643 }
else {
00644
if (pcur->hbmMask !=
NULL) {
00645 GreDeleteObject(pcur->hbmMask);
00646 GreDecQuotaCount((PW32PROCESS)(pcur->head.ppi));
00647 }
00648
if (pcur->hbmColor !=
NULL) {
00649 GreDeleteObject(pcur->hbmColor);
00650 GreDecQuotaCount((PW32PROCESS)(pcur->head.ppi));
00651 }
00652
if (pcur->hbmAlpha !=
NULL) {
00653
00654
00655
00656 GreDeleteObject(pcur->hbmAlpha);
00657 }
00658 }
00659
00660
00661
00662
00663
00664
DestroyEmptyCursorObject(pcur);
00665
return TRUE;
00666 }
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
void
00680 DestroyUnlockedCursor(
void * pv)
00681 {
00682
_DestroyCursor((
PCURSOR)pv,
CURSOR_THREADCLEANUP);
00683 }
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695 BOOL _SetCursorContents(
00696
PCURSOR pcur,
00697
PCURSOR pcurNew)
00698 {
00699 HBITMAP hbmpT;
00700
00701
if (!(pcur->CURSORF_flags &
CURSORF_ACON)) {
00702
00703
00704
00705
00706 hbmpT = pcur->hbmMask;
00707 pcur->hbmMask = pcurNew->hbmMask;
00708 pcurNew->hbmMask = hbmpT;
00709
00710 hbmpT = pcur->hbmColor;
00711 pcur->hbmColor = pcurNew->hbmColor;
00712 pcurNew->hbmColor = hbmpT;
00713
00714
00715
00716
00717 pcur->xHotspot = pcurNew->xHotspot;
00718 pcur->yHotspot = pcurNew->yHotspot;
00719 pcur->cx = pcurNew->cx;
00720 pcur->cy = pcurNew->cy;
00721 }
00722
00723
00724
00725
00726
_DestroyCursor(pcurNew,
CURSOR_THREADCLEANUP);
00727
00728
return (
BOOL)
TRUE;
00729 }