test: loadbits.c File Reference

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

# loadbits.c File Reference

`#include "precomp.h"`
`#include <wchar.h>`

Go to the source code of this file.

## Functions

HCURSOR | _CreateEmptyCursorObject (BOOL fPublic)
VOID | UnlinkCursor (PCURSOR pcur)
VOID | DestroyEmptyCursorObject (PCURSOR pcur)
VOID | ZombieCursor (PCURSOR pcur)
BOOL | ResStrCmp (PUNICODE_STRING cczpstr1, PUNICODE_STRING pstr2)
PCURSOR | SearchIconCache (PCURSOR pCursorCache, ATOM atomModName, PUNICODE_STRING cczpstrResName, PCURSOR pcurSrc, PCURSORFIND pcfSearch)
PCURSOR | _FindExistingCursorIcon (ATOM atomModName, PUNICODE_STRING cczpstrResName, PCURSOR pcurSrc, PCURSORFIND pcfSearch)
BOOL | _InternalGetIconInfo (IN PCURSOR pcur, OUT PICONINFO ccxpiconinfo, OUT OPTIONAL PUNICODE_STRING pstrInstanceName, OUT OPTIONAL PUNICODE_STRING pstrResName, OUT OPTIONAL LPDWORD ccxpbpp, IN BOOL fInternalCursor)
BOOL | _DestroyCursor (PCURSOR pcur, DWORD cmdDestroy)
void | DestroyUnlockedCursor (void *pv)
BOOL | _SetCursorContents (PCURSOR pcur, PCURSOR pcurNew)

## Function Documentation

HCURSOR _CreateEmptyCursorObject | ( | BOOL | fPublic | ) |

Definition at line 26 of file loadbits.c.

References ACON, HMAllocObject(), max, NULL, PtiCurrent, PtoH, TIF_CSRSSTHREAD, TIF_SYSTEMTHREAD, and TYPE_CURSOR.

    00028 {
    00029     PCURSOR pcurT;
    00030
    00031     /*
    00032      * Create the cursor object.
    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 }

BOOL _DestroyCursor | ( | PCURSOR | pcur,
|  | DWORD | cmdDestroy
| ) |

Definition at line 539 of file loadbits.c.

References BOOL, CCACHEDCAPTIONS, CURSOR_ALWAYSDESTROY, CURSOR_CALLFROMCLIENT, CURSOR_THREADCLEANUP, CURSORF_ACON, CURSORF_FROMRESOURCE, CURSORF_LRSHARED, CURSORF_SECRET, DestroyAniIcon(), DestroyEmptyCursorObject(), FALSE, gcachedCaptions, GETPPI, HMMarkObjectDestroy(), NULL, pacon, PpiCurrent, tagCAPTIONCACHE::spcursor, TRUE, Unlock, and UserDeleteAtom().

Referenced by _SetCursorContents(), DestroyAniIcon(), DestroyClassSmIcon(), DestroyUnlockedCursor(), DestroyWindowSmIcon(), NtUserDestroyCursor(), xxxDWP_SetIcon(), and zzzSetSystemImage().

    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      * Remove this icon from the caption icon cache.
    00557      */
    00558     for (i = 0; i < CCACHEDCAPTIONS; i++) {
    00559         if (gcachedCaptions[i].spcursor == pcur) {
    00560             Unlock( &(gcachedCaptions[i].spcursor) );
    00561         }
    00562     }
    00563
    00564     /*
    00565      * First step in destroying an cursor
    00566      */
    00567     switch (cmdDestroy) {
    00568
    00569     case CURSOR_ALWAYSDESTROY:
    00570
    00571         /*
    00572          * Always destroy? then don't do any checking...
    00573          */
    00574         break;
    00575
    00576     case CURSOR_CALLFROMCLIENT:
    00577
    00578         /*
    00579          * Can't destroy public cursors/icons.
    00580          */
    00581         if (ppiCursor == NULL)
    00582             /*
    00583              * Fake success if its a resource loaded icon because
    00584              * this is how win95 responded.
    00585              */
    00586             return !!(pcur->CURSORF_flags & CURSORF_FROMRESOURCE);
    00587
    00588         /*
    00589          * If this cursor was loaded from a resource, don't free it till the
    00590          * process exits.  This is the way we stay compatible with win3.0's
    00591          * cursors which were actually resources.  Resources under win3 have
    00592          * reference counting and other "features" like handle values that
    00593          * never change.  Read more in the comment in
    00594          * ServerLoadCreateCursorIcon().
    00595          */
    00596         if (pcur->CURSORF_flags & (CURSORF_LRSHARED | CURSORF_SECRET)) {
    00597             return TRUE;
    00598         }
    00599
    00600         /*
    00601          * One thread can't destroy the objects created by another.
    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          * fall through.
    00610          */
    00611
    00612     case CURSOR_THREADCLEANUP:
    00613
    00614         /*
    00615          * Don't destroy public objects either (pretend it worked though).
    00616          */
    00617         if (ppiCursor == NULL)
    00618             return TRUE;
    00619         break;
    00620     }
    00621
    00622     /*
    00623      * First mark the object for destruction.  This tells the locking code that
    00624      * we want to destroy this object when the lock count goes to 0.  If this
    00625      * returns FALSE, we can't destroy the object yet.
    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      * If this is an ACON call its special routine to destroy it.
    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              * This is an internal GDI object, and so not covered by quota.
    00655              */
    00656             GreDeleteObject(pcur->hbmAlpha);
    00657         }
    00658     }
    00659
    00660     /*
    00661      * Ok to destroy...  Free the handle (which will free the object and the
    00662      * handle).
    00663      */
    00664     DestroyEmptyCursorObject(pcur);
    00665     return TRUE;
    00666 }

PCURSOR _FindExistingCursorIcon | ( | ATOM | atomModName,
|  | PUNICODE_STRING | cczpstrResName,
|  | PCURSOR | pcurSrc,
|  | PCURSORFIND | pcfSearch
| ) |

Definition at line 357 of file loadbits.c.

References gpcurFirst, NULL, PpiCurrent, tagCURSORFIND::rt, and SearchIconCache().

Referenced by NtUserFindExistingCursorIcon().

    00362 {
    00363     PCURSOR pcurT = NULL;
    00364
    00365     /*
    00366      * If rt is zero we're doing an indirect create, so matching with
    00367      * a previously loaded cursor/icon would be inappropriate.
    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 }

BOOL _InternalGetIconInfo | ( | IN PCURSOR | pcur,
|  | OUT PICONINFO | ccxpiconinfo,
|  | OUT OPTIONAL PUNICODE_STRING | pstrInstanceName,
|  | OUT OPTIONAL PUNICODE_STRING | pstrResName,
|  | OUT OPTIONAL LPDWORD | ccxpbpp,
|  | IN BOOL | fInternalCursor
| ) |

Definition at line 395 of file loadbits.c.

References BOOL, CURSORF_ACON, FALSE, ghdcMem, ghdcMem2, HDCBITS, IS_PTR, NULL, PTR_TO_ID, RtlCopyUnicodeString(), TRUE, UserGetAtomName(), and USHORT.

Referenced by GetCursorHeight(), and NtUserGetIconInfo().

    00402 {
    00403     HBITMAP hbmBitsT;
    00404     HBITMAP hbmDstT;
    00405     HBITMAP hbmMask;
    00406     HBITMAP hbmColor;
    00407
    00408     /*
    00409      * Note -- while the STRING structures are in kernel mode memory, the
    00410      * buffers are in user-mode memory.  So all use of the buffers should
    00411      * be protected bytry blocks.
    00412      */
    00413
    00414     /*
    00415      * If this is an animated cursor, just grab the first frame and return
    00416      * the info for it.
    00417      */
    00418     if (pcur->CURSORF_flags & CURSORF_ACON)
    00419         pcur = ((PACON)pcur)->aspcur[0];
    00420
    00421     /*
    00422      * Make copies of the bitmaps
    00423      *
    00424      * If the color bitmap is around, then there is no XOR mask in the
    00425      * hbmMask bitmap.
    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      * Fill in the iconinfo structure.  make copies of the bitmaps.
    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 }

BOOL _SetCursorContents | ( | PCURSOR | pcur,
|  | PCURSOR | pcurNew
| ) |

Definition at line 695 of file loadbits.c.

References _DestroyCursor(), BOOL, CURSOR_THREADCLEANUP, CURSORF_ACON, and TRUE.

Referenced by NtUserSetCursorContents().

    00698 {
    00699     HBITMAP hbmpT;
    00700
    00701     if (!(pcur->CURSORF_flags & CURSORF_ACON)) {
    00702
    00703         /*
    00704          * Swap bitmaps.
    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          * Remember hotspot info and size info
    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      * Destroy the cursor we copied from.
    00725      */
    00726     _DestroyCursor(pcurNew, CURSOR_THREADCLEANUP);
    00727
    00728     return (BOOL)TRUE;
    00729 }

VOID DestroyEmptyCursorObject | ( | PCURSOR | pcur | ) |

Definition at line 138 of file loadbits.c.

References CURSORF_LINKED, HMFreeObject(), UnlinkCursor(), and VOID().

Referenced by _DestroyCursor().

    00140 {
    00141     if (pcur->CURSORF_flags & CURSORF_LINKED) {
    00142         UnlinkCursor(pcur);
    00143     }
    00144
    00145     HMFreeObject(pcur);
    00146 }

void DestroyUnlockedCursor | ( | void * | pv | ) |

Definition at line 680 of file loadbits.c.

References _DestroyCursor(), and CURSOR_THREADCLEANUP.

    00681 {
    00682     _DestroyCursor((PCURSOR)pv, CURSOR_THREADCLEANUP);
    00683 }

BOOL ResStrCmp | ( | PUNICODE_STRING | cczpstr1,
|  | PUNICODE_STRING | pstr2
| ) |

Definition at line 190 of file loadbits.c.

References BOOL, FALSE, RtlEqualUnicodeString(), RtlUnicodeStringToInteger(), and TRUE.

Referenced by SearchIconCache().

    00193 {
    00194     BOOL retval = FALSE;
    00195     /*
    00196      * pstr1 is a STRING that is in kernel space, but the buffer may
    00197      * be in client space.
    00198      */
    00199
    00200     if (cczpstr1->Length == 0) {
    00201
    00202         /*
    00203          * pstr1 is a resource ID, so just compare the values.
    00204          */
    00205         if (cczpstr1->Buffer == pstr2->Buffer)
    00206             return TRUE;
    00207
    00208     } else {
    00209
    00210         try {
    00211         /*
    00212          * pstr1 is a string.  if pstr2 is an actual string compare the
    00213          * string values; if pstr2 is not a string then pstr1 may be an
    00214          * "integer string" of the form "#123456". so convert it to an
    00215          * integer and compare the integers.
    00216          * Before calling lstrcmp(), make sure pstr2 is an actual
    00217          * string, not a resource ID.
    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 }

PCURSOR SearchIconCache | ( | PCURSOR | pCursorCache,
|  | ATOM | atomModName,
|  | PUNICODE_STRING | cczpstrResName,
|  | PCURSOR | pcurSrc,
|  | PCURSORFIND | pcfSearch
| ) |

Definition at line 254 of file loadbits.c.

References tagCURSORFIND::bpp, CURSORF_ACON, CURSORF_LRSHARED, tagCURSORFIND::cx, tagCURSORFIND::cy, NULL, ResStrCmp(), and tagCURSORFIND::rt.

Referenced by _FindExistingCursorIcon().

    00260 {
    00261     /*
    00262      * Run through the list of 'resource' objects created,
    00263      * and see if the cursor requested has already been loaded.
    00264      * If so just return it.  We do this to be consistent with
    00265      * Win 3.0 where they simply return a pointer to the res-data
    00266      * for a cursor/icon handle.  Many apps count on this and
    00267      * call LoadCursor/Icon() often.
    00268      *
    00269      * LR_SHARED implies:
    00270      *   1) icons never get deleted till process (LATER or WOW module)
    00271      *      goes away.
    00272      *   2) This cache is consulted before trying to load a res.
    00273      */
    00274     for (; pCursorCache != NULL; pCursorCache = pCursorCache->pcurNext) {
    00275
    00276         /*
    00277          * If we are given a specific cursor to look for, then
    00278          * search for that first.
    00279          */
    00280         if (pcurSrc && (pCursorCache == pcurSrc))
    00281             return pcurSrc;
    00282
    00283         /*
    00284          * No need to look further if the module name doesn't match.
    00285          */
    00286         if (atomModName != pCursorCache->atomModName)
    00287             continue;
    00288
    00289         /*
    00290          * We only return images that cannot be destroyed by the app.
    00291          * so we don't have to deal with ref counts.  This is owned
    00292          * by us, but not LR_SHARED.
    00293          */
    00294         if (!(pCursorCache->CURSORF_flags & CURSORF_LRSHARED))
    00295             continue;
    00296
    00297         /*
    00298          * Check the other distinguishing search criteria for
    00299          * a match.
    00300          */
    00301         if ((pCursorCache->rt == LOWORD(pcfSearch->rt)) &&
    00302             ResStrCmp(cczpstrResName, &pCursorCache->strName)) {
    00303
    00304             /*
    00305              * Acons don't have a size per se because each frame
    00306              * can be a different size.  We always make it a hit
    00307              * on acons so replacement of system icons is possible.
    00308              */
    00309             if (pCursorCache->CURSORF_flags & CURSORF_ACON)
    00310                 return pCursorCache;
    00311
    00312             /*
    00313              * First hit wins.  Nothing fancy here.  Apps that use
    00314              * LR_SHARED have to watch out for this.
    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 }

VOID UnlinkCursor | ( | PCURSOR | pcur | ) |

Definition at line 57 of file loadbits.c.

References tagSHAREDINFO::aheList, BOOL, _HANDLEENTRY::bType, CURSORF_LINKED, FALSE, giheLast, gpcurFirst, gSharedInfo, NULL, _HANDLEENTRY::phead, _HANDLEENTRY::pOwner, PpiCurrent, TRUE, TYPE_CURSOR, and VOID().

Referenced by DestroyEmptyCursorObject(), and ZombieCursor().

    00059 {
    00060     PCURSOR *ppcurT;
    00061     BOOL    fTriedPublicCache;
    00062     BOOL    fTriedThisProcessCache = FALSE;
    00063
    00064     /*
    00065      * First unlink this cursor object from the cursor list (it will be the
    00066      * first one in the list, so this'll be fast...  but just in case, make
    00067      * it a loop).
    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      * If we get here, it means that the cursor used to be public but
    00089      * got assigned to the current thread due to being unlocked.  We
    00090      * have to look for it in the public cache.
    00091      */
    00092     if (!fTriedPublicCache) {
    00093         ppcurT = &gpcurFirst;
    00094         fTriedPublicCache = TRUE;
    00095         goto LookAgain;
    00096     }
    00097
    00098     /*
    00099      * If we got here, it means that it was locked during process
    00100      * cleanup and got assigned to no owner.  Try the current process
    00101      * cache.
    00102      */
    00103     if (!fTriedThisProcessCache) {
    00104         ppcurT = &PpiCurrent()->pCursorCache;
    00105         fTriedThisProcessCache = TRUE;
    00106         goto LookAgain;
    00107     }
    00108
    00109     /*
    00110      * Getting Desperate here...  Look through every cursor and process
    00111      * cache for it.
    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 }

VOID ZombieCursor | ( | PCURSOR | pcur | ) |

Definition at line 156 of file loadbits.c.

References CURSORF_LINKED, gptiRit, HMChangeOwnerProcess, HMPheFromObject, ISTS, NULL, _HANDLEENTRY::pOwner, UnlinkCursor(), and VOID().

Referenced by DestroyProcessesObjects().

    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 }