PCURSOR _FindExistingCursorIcon( ATOM atomModName, PUNICODE_STRING pstrResName, PCURSOR pcurSrc, PCURSORFIND pcfSearch) { PCURSOR pcurT = NULL; /* * If rt is zero we're doing an indirect create, so matching with * a previously loaded cursor/icon would be inappropriate. */ if (pcfSearch->rt && atomModName) { pcurT = SearchIconCache(PpiCurrent()->pCursorCache, atomModName, pstrResName, pcurSrc, pcfSearch); if (pcurT == NULL) { pcurT = SearchIconCache(gpcurFirst, atomModName, pstrResName, pcurSrc, pcfSearch); } } return pcurT; }
BOOL xxxRegisterUserHungAppHandlers( PFNW32ET pfnW32EndTask, HANDLE hEventWowExec) { BOOL bRetVal; PPROCESSINFO ppi; PWOWPROCESSINFO pwpi; // // Allocate the per wow process info stuff // ensuring the memory is Zero init. // pwpi = (PWOWPROCESSINFO) UserAllocPoolWithQuota(sizeof(WOWPROCESSINFO), TAG_WOW); if (!pwpi) return FALSE; RtlZeroMemory(pwpi, sizeof(*pwpi)); // // Reference the WowExec event for kernel access // bRetVal = NT_SUCCESS(ObReferenceObjectByHandle( hEventWowExec, EVENT_ALL_ACCESS, NULL, UserMode, &pwpi->pEventWowExec, NULL )); // // if sucess then intialize the pwpi, ppi structs // else free allocated memory // if (bRetVal) { pwpi->hEventWowExecClient = hEventWowExec; pwpi->lpfnWowExitTask = (DWORD)pfnW32EndTask; ppi = PpiCurrent(); ppi->pwpi = pwpi; // add to the list, order doesn't matter pwpi->pwpiNext = gpwpiFirstWow; gpwpiFirstWow = pwpi; } else { UserFreePool(pwpi); } return bRetVal; }
/***************************************************************************\ * * _GetListBoxInfo() * * Currently returns back the # of items per column. There is no way to get * or calculate this info any other way in a multicolumn list. * * For now, no structure is returned. If we ever need one more thing, make one. * * Since I have to run on multiple platforms, I can't define a message. * To do so would require that * * I make changes to the thunk table * * I make sure the 32-bit define doesn't collide with some NT new msg * * I use a different value on Win '95 vs Memphis due to additions * * I test apps extensively since many of them pass on bogus valued * messages to the listbox handler which checks to see if they * are in range. In other words, any value I pick is probably * going to flake out MSVC++ 4.0. * * Ergo an API instead. * \***************************************************************************/ DWORD WINAPI _GetListBoxInfo(PWND pwnd) { PCLS pcls; DWORD dwRet = 0; BOOL fOtherProcess; /* * Make sure it is a combobox or a dropdown */ pcls = pwnd->pcls; if ((pcls->atomClassName != gpsi->atomSysClass[ICLS_LISTBOX]) && (GETFNID(pwnd) != FNID_LISTBOX)) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "pwnd %#p is not a listbox", pwnd); return 0; } if (fOtherProcess = (GETPTI(pwnd)->ppi != PpiCurrent())) { KeAttachProcess(&GETPTI(pwnd)->ppi->Process->Pcb); } try { PLBIV ccxPlbSnap; /* * Snap and probe the pointer to the LBIV, since it is client-side. */ ccxPlbSnap = ((PLBWND)pwnd)->pLBIV; if (!ccxPlbSnap) { goto errorexit; } ProbeForRead(ccxPlbSnap, sizeof(LBIV), DATAALIGN); if (ccxPlbSnap->fMultiColumn) { dwRet = ccxPlbSnap->itemsPerColumn; } else { dwRet = ccxPlbSnap->cMac; } } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { dwRet = 0; } errorexit: if (fOtherProcess) { KeDetachProcess(); } return dwRet; }
VOID SetDialogPointer(PWND pwnd, LONG_PTR lPtr) { if ((pwnd->cbwndExtra < DLGWINDOWEXTRA) || TestWF(pwnd, WFSERVERSIDEPROC) || (PpiCurrent() != GETPTI(pwnd)->ppi)) { RIPMSG1(RIP_WARNING, "SetDialogPointer: Unexpected pwnd:%#p", pwnd); return; } ((PDIALOG)pwnd)->pdlg = (PDLG)lPtr; if (lPtr == 0) { pwnd->fnid |= FNID_CLEANEDUP_BIT; ClrWF(pwnd, WFDIALOGWINDOW); } else { if (pwnd->fnid == 0) { pwnd->fnid = FNID_DIALOG; } SetWF(pwnd, WFDIALOGWINDOW); } }
VOID DestroyEmptyCursorObject( PCURSOR pcur) { PCURSOR *ppcurT; BOOL fTriedPublicCache; BOOL fTriedThisProcessCache; /* * Acon frames and non LR_SHARED private cursors aren't cached */ if (!(pcur->CURSORF_flags & CURSORF_LINKED)) { HMFreeObject(pcur); return; } /* * First unlink this cursor object from the cursor list (it will be the * first one in the list, so this'll be fast... but just in case, make * it a loop). */ if (fTriedPublicCache = (pcur->head.ppi == NULL)) { ppcurT = &gpcurFirst; } else { ppcurT = &pcur->head.ppi->pCursorCache; } LookAgain: for (; *ppcurT != NULL; ppcurT = &((*ppcurT)->pcurNext)) { if (*ppcurT == pcur) { *ppcurT = pcur->pcurNext; FreeIt: #ifdef DEBUG pcur->CURSORF_flags &= ~CURSORF_LINKED; #endif HMFreeObject(pcur); return; } } /* * If we get here, it means that the cursor used to be public but * got assigned to the current thread due to being unlocked. We * have to look for it in the public cache. */ if (!fTriedPublicCache) { ppcurT = &gpcurFirst; fTriedPublicCache = TRUE; goto LookAgain; } /* * If we got here, it means that it was locked during process * cleanup and got assigned to no owner. Try the current process * cache. */ if (!fTriedThisProcessCache) { ppcurT = &PpiCurrent()->pCursorCache; fTriedThisProcessCache = TRUE; goto LookAgain; } /* * Getting Desperate here... Look through every cursor and process * cache for it. */ { PHE pheMax, pheT; pheMax = &gSharedInfo.aheList[giheLast]; for (pheT = gSharedInfo.aheList; pheT <= pheMax; pheT++) { if (pheT->bType == TYPE_CURSOR) { if (((PCURSOR)pheT->phead)->pcurNext == pcur) { ((PCURSOR)pheT->phead)->pcurNext = pcur->pcurNext; goto FreeIt; } else if (pheT->pOwner && ((PPROCESSINFO)pheT->pOwner)->pCursorCache == pcur) { ((PPROCESSINFO)pheT->pOwner)->pCursorCache = pcur->pcurNext; goto FreeIt; } } } } UserAssert(FALSE); }
BOOL _DestroyCursor( PCURSOR pcur, DWORD cmdDestroy) { PPROCESSINFO ppi; PPROCESSINFO ppiCursor; int i; extern BOOL DestroyAniIcon(PACON pacon); if (pcur == NULL) { UserAssert(FALSE); return(TRUE); } ppi = PpiCurrent(); ppiCursor = GETPPI(pcur); /* * Remove this icon from the caption icon cache. */ for (i = 0; i < CCACHEDCAPTIONS; i++) { if (cachedCaptions[i].spcursor == pcur) { Unlock( &(cachedCaptions[i].spcursor) ); } } /* * First step in destroying an cursor */ switch (cmdDestroy) { case CURSOR_ALWAYSDESTROY: /* * Always destroy? then don't do any checking... */ break; case CURSOR_CALLFROMCLIENT: /* * Can't destroy public cursors/icons. */ if (ppiCursor == NULL) /* * Fake success if its a resource loaded icon because * this is how win95 responded. */ return !!(pcur->CURSORF_flags & CURSORF_FROMRESOURCE); /* * If this cursor was loaded from a resource, don't free it till the * process exits. This is the way we stay compatible with win3.0's * cursors which were actually resources. Resources under win3 have * reference counting and other "features" like handle values that * never change. Read more in the comment in * ServerLoadCreateCursorIcon(). */ if (pcur->CURSORF_flags & (CURSORF_LRSHARED | CURSORF_SECRET)) { return TRUE; } /* * One thread can't destroy the objects created by another. */ if (ppiCursor != ppi) { RIPERR0(ERROR_DESTROY_OBJECT_OF_OTHER_THREAD, RIP_VERBOSE, ""); return FALSE; } /* * fall through. */ case CURSOR_THREADCLEANUP: /* * Don't destroy public objects either (pretend it worked though). */ if (ppiCursor == NULL) return TRUE; break; } /* * First mark the object for destruction. This tells the locking code that * we want to destroy this object when the lock count goes to 0. If this * returns FALSE, we can't destroy the object yet. */ if (!HMMarkObjectDestroy((PHEAD)pcur)) return FALSE; if (pcur->strName.Length != 0) { UserFreePool((LPSTR)pcur->strName.Buffer); } if (pcur->atomModName != 0) { DeleteAtom(pcur->atomModName); } /* * If this is an ACON call its special routine to destroy it. */ if (pcur->CURSORF_flags & CURSORF_ACON) { DestroyAniIcon((PACON)pcur); } else { if (pcur->hbmMask != NULL) { GreDeleteObject(pcur->hbmMask); } if (pcur->hbmColor != NULL) { GreDeleteObject(pcur->hbmColor); } } /* * Ok to destroy... Free the handle (which will free the object and the * handle). */ DestroyEmptyCursorObject(pcur); return TRUE; }
NTSTATUS UserCommitMemory( PVOID pBase, PVOID *ppCommit, PULONG pCommitSize) { PDESKTOPVIEW pdv; DWORD dwCommitOffset; PWINDOWSTATION pwinsta; PDESKTOP pdesk; PBYTE pUserBase; NTSTATUS Status; /* * If this is a system thread, we have no view of the desktop * and must map it in. Fortunately, this does not happen often. */ if (IS_SYSTEM_THREAD(PsGetCurrentThread())) { /* * Find the desktop that owns the section. */ for (pwinsta = grpwinstaList; pwinsta; pwinsta = pwinsta->rpwinstaNext) { for (pdesk = pwinsta->rpdeskList; pdesk; pdesk = pdesk->rpdeskNext) { if (pdesk->pDeskInfo->pvDesktopBase == pBase) goto FoundIt; } } FoundIt: if (pwinsta == NULL) return STATUS_NO_MEMORY; /* * Map the section into the current process and commit the * first page of the section. */ dwCommitOffset = (ULONG)((PBYTE)*ppCommit - (PBYTE)pBase); Status = CommitReadOnlyMemory(pdesk->hsectionDesktop, PAGE_SIZE, dwCommitOffset); } else { /* * Find the current process' view of the desktop */ for (pdv = PpiCurrent()->pdvList; pdv != NULL; pdv = pdv->pdvNext) { if (pdv->pdesk->pDeskInfo->pvDesktopBase == pBase) break; } UserAssert(pdv); /* * Commit the memory */ pUserBase = (PVOID)((PBYTE)*ppCommit - pdv->ulClientDelta); Status = ZwAllocateVirtualMemory(NtCurrentProcess(), &pUserBase, 0, pCommitSize, MEM_COMMIT, PAGE_EXECUTE_READ ); if (NT_SUCCESS(Status)) *ppCommit = (PVOID)((PBYTE)pUserBase + pdv->ulClientDelta); } return Status; }
/***************************************************************************\ * * _GetComboBoxInfo() * * This returns combobox information for either a combo or its dropdown * list. * \***************************************************************************/ BOOL WINAPI _GetComboBoxInfo(PWND pwnd, PCOMBOBOXINFO pcbi) { PCLS pcls; COMBOBOXINFO cbi = { sizeof cbi, }; BOOL fOtherProcess; BOOL bRetval = FALSE; WORD wWindowType = 0; /* * Make sure it is a combobox or a dropdown */ pcls = pwnd->pcls; if ((GETFNID(pwnd) == FNID_COMBOBOX) || (pcls->atomClassName == gpsi->atomSysClass[ICLS_COMBOBOX])) { wWindowType = FNID_COMBOBOX; } else if ((GETFNID(pwnd) == FNID_COMBOLISTBOX) || (pcls->atomClassName == gpsi->atomSysClass[ICLS_COMBOLISTBOX])) { wWindowType = FNID_COMBOLISTBOX; } else { RIPERR1(ERROR_WINDOW_NOT_COMBOBOX, RIP_WARNING, "pwnd %#p not a combobox or dropdown", pwnd); return FALSE; } /* * Validate combo structure */ if (pcbi->cbSize != sizeof(COMBOBOXINFO)) { RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "COMBOBOXINFO.cbSize %d is wrong", pcbi->cbSize); return FALSE; } if (fOtherProcess = (GETPTI(pwnd)->ppi != PpiCurrent())) { KeAttachProcess(&GETPTI(pwnd)->ppi->Process->Pcb); } try { PCBOX ccxPcboxSnap; PWND ccxPwndSnap; HWND ccxHwndSnap; /* * Snap and probe the CBOX structure, since it is client side. */ if (wWindowType == FNID_COMBOBOX) { ccxPcboxSnap = ((PCOMBOWND)pwnd)->pcbox; } else { PLBIV ccxPlbSnap; /* * If this is a listbox, we must snap and probe the LBIV structure * in order to get to the CBOX structure. */ ccxPlbSnap = ((PLBWND)pwnd)->pLBIV; if (!ccxPlbSnap) { goto errorexit; } ProbeForRead(ccxPlbSnap, sizeof(LBIV), DATAALIGN); ccxPcboxSnap = ccxPlbSnap->pcbox; } if (!ccxPcboxSnap) { goto errorexit; } ProbeForRead(ccxPcboxSnap, sizeof(CBOX), DATAALIGN); /* * Get the combo information now */ /* * Snap and probe the client side pointer to the Combo window */ ccxPwndSnap = ccxPcboxSnap->spwnd; ProbeForRead(ccxPwndSnap, sizeof(HEAD), DATAALIGN); cbi.hwndCombo = HWCCX(ccxPwndSnap); /* * Snap & probe the client side pointer to the Edit window. * To compare spwndEdit and pwnd, we should compare handles * since spwndEdit is a client-side address and pwnd is a * kernel-mode address, */ ccxPwndSnap = ccxPcboxSnap->spwndEdit; /* * If combobox is not fully initialized and spwndEdit is NULL, * we should fail. */ ProbeForRead(ccxPwndSnap, sizeof(HEAD), DATAALIGN); ccxHwndSnap = HWCCX(ccxPwndSnap); if (ccxHwndSnap == HW(pwnd)) { /* * ComboBox doesn't have Edit control. */ cbi.hwndItem = NULL; } else { cbi.hwndItem = HWCCX(ccxPwndSnap); } /* * Snap and probe the client side pointer to the List window */ ccxPwndSnap = ccxPcboxSnap->spwndList; /* * If combobox is not fully initialized and spwndList is NULL, * we should fail. */ ProbeForRead(ccxPwndSnap, sizeof(HEAD), DATAALIGN); cbi.hwndList = HWCCX(ccxPwndSnap); /* * Snap the rest of the combo information. * We don't need to probe any of these, since there are no more indirections. */ cbi.rcItem = ccxPcboxSnap->editrc; cbi.rcButton = ccxPcboxSnap->buttonrc; /* * Button state */ cbi.stateButton = 0; if (ccxPcboxSnap->CBoxStyle == CBS_SIMPLE) { cbi.stateButton |= STATE_SYSTEM_INVISIBLE; } if (ccxPcboxSnap->fButtonPressed) { cbi.stateButton |= STATE_SYSTEM_PRESSED; } } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { goto errorexit; } *pcbi = cbi; bRetval = TRUE; errorexit: if (fOtherProcess) { KeDetachProcess(); } return bRetval; }