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

validate.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: validate.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * This module contains functions for validating windows, menus, cursors, etc. 00007 * 00008 * History: 00009 * 01-02-91 DarrinM Created. 00010 \***************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 #include <ntsdexts.h> 00015 00016 /* 00017 * these defines are used for using the validation macros 00018 * StartValidateHandleMacro and EndValidateHandleMacro 00019 */ 00020 #define ClientSharedInfo() (&gSharedInfo) 00021 #define ServerInfo() (gpsi) 00022 00023 #include "wow.h" 00024 00025 #if DBG 00026 #if defined(_X86_) 00027 CRITSTACK gCritStack; 00028 #endif // defined(_X86_) 00029 #endif // DBG 00030 00031 /* 00032 * Globals used only in his file. 00033 */ 00034 __int64 gCSTimeExclusiveWhenEntering; 00035 00036 /***************************************************************************\ 00037 * ValidateHwinsta 00038 * 00039 * Validate windowstation handle 00040 * 00041 * History: 00042 * 03-29-91 JimA Created. 00043 * 06-20-95 JimA Kernel-mode objects. 00044 \***************************************************************************/ 00045 00046 NTSTATUS ValidateHwinsta( 00047 HWINSTA hwinsta, 00048 KPROCESSOR_MODE AccessMode, 00049 ACCESS_MASK amDesired, 00050 PWINDOWSTATION* ppwinsta) 00051 { 00052 NTSTATUS Status; 00053 00054 Status = ObReferenceObjectByHandle( 00055 hwinsta, 00056 amDesired, 00057 *ExWindowStationObjectType, 00058 AccessMode, 00059 ppwinsta, 00060 NULL); 00061 00062 if (!NT_SUCCESS(Status)) { 00063 RIPNTERR1(Status, RIP_VERBOSE, "ValidateHwinsta failed for %#p", hwinsta); 00064 00065 } else if ((*ppwinsta)->dwSessionId != gSessionId) { 00066 00067 RIPNTERR3(STATUS_INVALID_HANDLE, RIP_WARNING, 00068 "SessionId %d. Wrong session id %d for pwinsta %#p", 00069 gSessionId, (*ppwinsta)->dwSessionId, *ppwinsta); 00070 00071 ObDereferenceObject(*ppwinsta); 00072 #if DBG 00073 *ppwinsta = NULL; 00074 #endif // DBG 00075 00076 return STATUS_INVALID_HANDLE; 00077 } 00078 00079 return Status; 00080 } 00081 00082 /***************************************************************************\ 00083 * ValidateHdesk 00084 * 00085 * Validate desktop handle 00086 * 00087 * History: 00088 * 03-29-91 JimA Created. 00089 * 06-20-95 JimA Kernel-mode objects. 00090 \***************************************************************************/ 00091 00092 NTSTATUS ValidateHdesk( 00093 HDESK hdesk, 00094 KPROCESSOR_MODE AccessMode, 00095 ACCESS_MASK amDesired, 00096 PDESKTOP* ppdesk) 00097 { 00098 NTSTATUS Status; 00099 00100 Status = ObReferenceObjectByHandle( 00101 hdesk, 00102 amDesired, 00103 *ExDesktopObjectType, 00104 AccessMode, 00105 ppdesk, 00106 NULL); 00107 00108 if (NT_SUCCESS(Status)) { 00109 00110 if ((*ppdesk)->dwSessionId != gSessionId) { 00111 00112 RIPNTERR3(STATUS_INVALID_HANDLE, RIP_WARNING, 00113 "SessionId %d. Wrong session id %d for pdesk %#p", 00114 gSessionId, (*ppdesk)->dwSessionId, *ppdesk); 00115 00116 goto Error; 00117 } 00118 00119 LogDesktop(*ppdesk, LDL_VALIDATE_HDESK, TRUE, (ULONG_PTR)PtiCurrent()); 00120 00121 if ((*ppdesk)->dwDTFlags & (DF_DESTROYED | DF_DESKWNDDESTROYED | DF_DYING)) { 00122 RIPNTERR1(STATUS_INVALID_HANDLE, RIP_ERROR, 00123 "ValidateHdesk: destroyed desktop %#p", 00124 *ppdesk); 00125 Error: 00126 ObDereferenceObject(*ppdesk); 00127 #if DBG 00128 *ppdesk = NULL; 00129 #endif // DBG 00130 00131 return STATUS_INVALID_HANDLE; 00132 } 00133 } else { 00134 RIPNTERR1(Status, RIP_VERBOSE, "ValidateHdesk failed for %#p", hdesk); 00135 } 00136 00137 return Status; 00138 } 00139 00140 /***************************************************************************\ 00141 * UserValidateCopyRgn 00142 * 00143 * Validates a region-handle. This essentially tries to copy the region 00144 * in order to verify the region is valid. If hrgn isn't a valid region, 00145 * then the combine will fail. We return a copy of the region. 00146 * 00147 * History: 00148 * 24=Jan-1996 ChrisWil Created. 00149 \***************************************************************************/ 00150 00151 HRGN UserValidateCopyRgn( 00152 HRGN hrgn) 00153 { 00154 HRGN hrgnCopy = NULL; 00155 00156 00157 if (hrgn && (GreValidateServerHandle(hrgn, RGN_TYPE))) { 00158 00159 hrgnCopy = CreateEmptyRgn(); 00160 00161 if (CopyRgn(hrgnCopy, hrgn) == ERROR) { 00162 00163 GreDeleteObject(hrgnCopy); 00164 00165 hrgnCopy = NULL; 00166 } 00167 } 00168 00169 return hrgnCopy; 00170 } 00171 00172 /***************************************************************************\ 00173 * ValidateHmenu 00174 * 00175 * Validate menu handle and open it 00176 * 00177 * History: 00178 * 03-29-91 JimA Created. 00179 \***************************************************************************/ 00180 00181 PMENU ValidateHmenu( 00182 HMENU hmenu) 00183 { 00184 PTHREADINFO pti = PtiCurrentShared(); 00185 PMENU pmenuRet; 00186 00187 pmenuRet = (PMENU)HMValidateHandle(hmenu, TYPE_MENU); 00188 00189 if (pmenuRet != NULL && 00190 ((pti->rpdesk != NULL && // hack so console initialization works. 00191 pmenuRet->head.rpdesk != pti->rpdesk))) { 00192 RIPERR1(ERROR_INVALID_MENU_HANDLE, RIP_WARNING, "Invalid menu handle (%#p)", hmenu); 00193 return NULL; 00194 } 00195 00196 return pmenuRet; 00197 } 00198 00199 00200 00201 /***************************************************************************\ 00202 * ValidateHmonitor 00203 * 00204 * Validate monitor handle and open it. 00205 * 00206 * History: 00207 * 03-29-91 JimA Created. 00208 \***************************************************************************/ 00209 00210 PMONITOR ValidateHmonitor( 00211 HMONITOR hmonitor) 00212 { 00213 return (PMONITOR)HMValidateSharedHandle(hmonitor, TYPE_MONITOR); 00214 } 00215 00216 /* 00217 * The handle validation routines should be optimized for time, not size, 00218 * since they get called so often. 00219 */ 00220 #pragma optimize("t", on) 00221 00222 /***************************************************************************\ 00223 * IsHandleEntrySecure 00224 * 00225 * Validate a user handle for a restricted process bypassing the routine to 00226 * get the handle entry. 00227 * 00228 * History: 00229 * August 22, 97 CLupu Created. 00230 \***************************************************************************/ 00231 00232 BOOL IsHandleEntrySecure( 00233 HANDLE h, 00234 PHE phe) 00235 { 00236 DWORD bCreateFlags; 00237 PPROCESSINFO ppiOwner; 00238 PPROCESSINFO ppiCurrent; 00239 PW32JOB pW32Job; 00240 DWORD ind; 00241 PULONG_PTR pgh; 00242 00243 /* 00244 * get the current process 00245 */ 00246 ppiCurrent = PpiCurrent(); 00247 00248 if (ppiCurrent == NULL) 00249 return TRUE; 00250 00251 UserAssert(ppiCurrent->pW32Job != NULL); 00252 00253 UserAssert(ppiCurrent->W32PF_Flags & W32PF_RESTRICTED); 00254 00255 /* 00256 * get the process that owns the handle 00257 */ 00258 00259 bCreateFlags = gahti[phe->bType].bObjectCreateFlags; 00260 00261 ppiOwner = NULL; 00262 00263 if (bCreateFlags & OCF_PROCESSOWNED) { 00264 ppiOwner = (PPROCESSINFO)phe->pOwner; 00265 } else if (bCreateFlags & OCF_THREADOWNED) { 00266 00267 PTHREADINFO pti; 00268 00269 pti = (PTHREADINFO)phe->pOwner; 00270 00271 if (pti != NULL) { 00272 ppiOwner = pti->ppi; 00273 } 00274 } 00275 00276 /* 00277 * if the owner is NULL then consider the handle secure 00278 */ 00279 if (ppiOwner == NULL) 00280 return FALSE; 00281 00282 00283 /* 00284 * if the handle is owned by a process in the same job, then it's secure 00285 */ 00286 if (ppiOwner->pW32Job == ppiCurrent->pW32Job) 00287 return TRUE; 00288 00289 /* 00290 * the handle is not owned by the current process 00291 */ 00292 00293 pW32Job = ppiCurrent->pW32Job; 00294 00295 if (pW32Job->pgh == NULL) 00296 return FALSE; 00297 00298 pgh = pW32Job->pgh; 00299 00300 UserAssert(pW32Job->ughCrt <= pW32Job->ughMax); 00301 00302 for (ind = 0; ind < pW32Job->ughCrt; ind++) { 00303 if (*(pgh + ind) == (ULONG_PTR)h) { 00304 return TRUE; 00305 } 00306 } 00307 00308 return FALSE; 00309 } 00310 00311 00312 /***************************************************************************\ 00313 * ValidateHandleSecure 00314 * 00315 * Validate a user handle for a restricted process. 00316 * 00317 * History: 00318 * July 29, 97 CLupu Created. 00319 \***************************************************************************/ 00320 00321 BOOL ValidateHandleSecure( 00322 HANDLE h) 00323 { 00324 PVOID pobj; 00325 00326 CheckCritInShared(); 00327 00328 StartValidateHandleMacro(h) 00329 BeginTypeValidateHandleMacro(pobj, TYPE_GENERIC) 00330 00331 if (IsHandleEntrySecure(h, phe)) { 00332 return TRUE; 00333 } 00334 00335 EndTypeValidateHandleMacro 00336 EndValidateHandleMacro 00337 00338 return FALSE; 00339 } 00340 00341 /***************************************************************************\ 00342 * ValidateHwnd 00343 * 00344 * History: 00345 * 08-Feb-1991 mikeke 00346 \***************************************************************************/ 00347 00348 PWND FASTCALL ValidateHwnd( 00349 HWND hwnd) 00350 { 00351 StartValidateHandleMacro(hwnd) 00352 00353 /* 00354 * Now make sure the app is 00355 * passing the right handle 00356 * type for this api. If the 00357 * handle is TYPE_FREE, this'll 00358 * catch it. 00359 */ 00360 if (phe->bType == TYPE_WINDOW) { 00361 00362 PTHREADINFO pti = PtiCurrentShared(); 00363 00364 /* 00365 * This is called from thunks for routines in the shared critsec. 00366 */ 00367 PWND pwndRet = (PWND)phe->phead; 00368 00369 /* 00370 * This test establishes that the window belongs to the current 00371 * 'desktop'.. The two exceptions are for the desktop-window of 00372 * the current desktop, which ends up belonging to another desktop, 00373 * and when pti->rpdesk is NULL. This last case happens for 00374 * initialization of TIF_SYSTEMTHREAD threads (ie. console windows). 00375 * IanJa doesn't know if we should be test TIF_CSRSSTHREAD here, but 00376 * JohnC thinks the whole test below is no longer required ??? LATER 00377 */ 00378 00379 if (pwndRet != NULL) { 00380 if (phe->bFlags & HANDLEF_DESTROY) { 00381 RIPERR2(ERROR_INVALID_WINDOW_HANDLE, 00382 RIP_WARNING,"ValidateHwnd, hwnd %#p, pwnd %#p already destroyed\n", 00383 hwnd, pwndRet); 00384 return NULL; 00385 } 00386 if (GETPTI(pwndRet) == pti || 00387 ( 00388 (pwndRet->head.rpdesk == pti->rpdesk || 00389 (pti->TIF_flags & TIF_SYSTEMTHREAD) || // | TIF_CSRSSTHREAD I think 00390 GetDesktopView(pti->ppi, pwndRet->head.rpdesk) != 00391 NULL))) { 00392 00393 if (IS_THREAD_RESTRICTED(pti, JOB_OBJECT_UILIMIT_HANDLES)) { 00394 00395 /* 00396 * make sure this window belongs to this process 00397 */ 00398 if (!IsHandleEntrySecure(hwnd, phe)) { 00399 RIPERR1(ERROR_INVALID_WINDOW_HANDLE, 00400 RIP_WARNING, 00401 "ValidateHwnd: Invalid hwnd (%#p) for restricted process\n", 00402 hwnd); 00403 pwndRet = NULL; 00404 } 00405 } 00406 return pwndRet; 00407 } 00408 } 00409 } 00410 00411 EndValidateHandleMacro 00412 00413 RIPERR1(ERROR_INVALID_WINDOW_HANDLE, 00414 RIP_WARNING, 00415 "ValidateHwnd: Invalid hwnd (%#p)", 00416 hwnd); 00417 return NULL; 00418 } 00419 00420 /* 00421 * Switch back to default optimization. 00422 */ 00423 #pragma optimize("", on) 00424 00425 /******************************Public*Routine******************************\ 00426 * 00427 * UserCritSec routines 00428 * 00429 * Exposes an opaque interface to the user critical section for 00430 * the WNDOBJ code in GRE 00431 * 00432 * Exposed as functions because they aren't time critical and it 00433 * insulates GRE from rebuilding if the definitions of Enter/LeaveCrit change 00434 * 00435 * History: 00436 * Wed Sep 20 11:19:14 1995 -by- Drew Bliss [drewb] 00437 * Created 00438 * 00439 \**************************************************************************/ 00440 00441 #if DBG 00442 00443 #if defined(_X86_) 00444 00445 #define GetCallStack() \ 00446 { \ 00447 ULONG Hash; \ 00448 \ 00449 gCritStack.thread = PsGetCurrentThread(); \ 00450 gCritStack.nFrames = GetStackTrace(1, \ 00451 MAX_STACK_CALLS, \ 00452 gCritStack.trace, \ 00453 &Hash); \ 00454 } 00455 00456 #define FlushCallStack() \ 00457 { \ 00458 gCritStack.thread = NULL; \ 00459 gCritStack.nFrames = 0; \ 00460 } 00461 00462 #else // defined(_X86_) 00463 00464 #define GetCallStack() 00465 #define FlushCallStack() 00466 00467 #endif // defined(_X86_) 00468 00469 00470 #endif // DBG 00471 00472 VOID UserEnterUserCritSec(VOID) 00473 { 00474 EnterCrit(); 00475 } 00476 00477 VOID UserLeaveUserCritSec(VOID) 00478 { 00479 LeaveCrit(); 00480 } 00481 00482 #if DBG 00483 VOID UserAssertUserCritSecIn(VOID) 00484 { 00485 _AssertCritInShared(); 00486 } 00487 00488 VOID UserAssertUserCritSecOut(VOID) 00489 { 00490 _AssertCritOut(); 00491 } 00492 #endif // DBG 00493 00494 BOOL UserGetCurrentDesktopId(DWORD* pdwDesktopId) 00495 { 00496 PDESKTOP pdesktop; 00497 00498 CheckCritIn(); 00499 00500 /* 00501 * PtiCurrent()->rpdesk can be NULL !!! (in the case of thread shutdown). 00502 */ 00503 00504 pdesktop = PtiCurrent()->rpdesk; 00505 00506 if (pdesktop != grpdeskRitInput) { 00507 RIPMSG0(RIP_WARNING, "UserGetCurrentDesktopId on wrong desktop pdesk\n"); 00508 return FALSE; 00509 } 00510 00511 *pdwDesktopId = pdesktop->dwDesktopId; 00512 00513 return TRUE; 00514 } 00515 00516 #if 0 00517 00518 // 00519 // Temporary arrays used to track critsec frees 00520 // 00521 00522 #define ARRAY_SIZE 20 00523 #define LEAVE_TYPE 0xf00d0000 00524 #define ENTER_TYPE 0x0000dead 00525 00526 typedef struct _DEBUG_STASHCS { 00527 RTL_CRITICAL_SECTION Lock; 00528 DWORD Type; 00529 } DEBUG_STASHCS, *PDEBUG_STASHCS; 00530 00531 DEBUG_STASHCS UserSrvArray[ARRAY_SIZE]; 00532 00533 ULONG UserSrvIndex; 00534 00535 VOID 00536 DumpArray( 00537 HANDLE hCurrentProcess, 00538 HANDLE hCurrentThread, 00539 DWORD dwCurrentPc, 00540 PNTSD_EXTENSION_APIS lpExtensionApis, 00541 LPSTR lpArgumentString, 00542 LPDWORD IndexAddress, 00543 LPDWORD ArrayAddress 00544 ) 00545 { 00546 PNTSD_OUTPUT_ROUTINE Print; 00547 PNTSD_GET_EXPRESSION EvalExpression; 00548 PNTSD_GET_SYMBOL GetSymbol; 00549 00550 DWORD History; 00551 int InitialIndex; 00552 PDEBUG_STASHCS Array; 00553 BOOL b; 00554 PRTL_CRITICAL_SECTION CriticalSection; 00555 CHAR Symbol[64], Symbol2[64]; 00556 DWORD Displacement, Displacement2; 00557 int Position; 00558 LPSTR p; 00559 00560 DBG_UNREFERENCED_PARAMETER(hCurrentThread); 00561 DBG_UNREFERENCED_PARAMETER(dwCurrentPc); 00562 00563 Print = lpExtensionApis->lpOutputRoutine; 00564 EvalExpression = lpExtensionApis->lpGetExpressionRoutine; 00565 GetSymbol = lpExtensionApis->lpGetSymbolRoutine; 00566 00567 p = lpArgumentString; 00568 00569 History = 0; 00570 00571 if ( *p ) { 00572 History = EvalExpression(p); 00573 } 00574 if ( History == 0 || History >= ARRAY_SIZE ) { 00575 History = 10; 00576 } 00577 00578 // 00579 // Get the Current Index and the array. 00580 // 00581 00582 b = ReadProcessMemory( 00583 hCurrentProcess, 00584 (LPVOID)IndexAddress, 00585 &InitialIndex, 00586 sizeof(InitialIndex), 00587 NULL 00588 ); 00589 if ( !b ) { 00590 return; 00591 } 00592 00593 Array = RtlAllocateHeap(RtlProcessHeap(), 0, sizeof(UserSrvArray)); 00594 if ( !Array ) { 00595 return; 00596 } 00597 00598 b = ReadProcessMemory( 00599 hCurrentProcess, 00600 (LPVOID)ArrayAddress, 00601 Array, 00602 sizeof(UserSrvArray), 00603 NULL 00604 ); 00605 if ( !b ) { 00606 RtlFreeHeap(RtlProcessHeap(), 0, Array); 00607 return; 00608 } 00609 00610 Position = 0; 00611 while ( History ) { 00612 InitialIndex--; 00613 if ( InitialIndex < 0 ) { 00614 InitialIndex = ARRAY_SIZE-1; 00615 } 00616 00617 if (Array[InitialIndex].Type == LEAVE_TYPE ) { 00618 (Print)("\n(%d) LEAVING Critical Section \n", Position); 00619 } else { 00620 (Print)("\n(%d) ENTERING Critical Section \n", Position); 00621 } 00622 00623 CriticalSection = &Array[InitialIndex].Lock; 00624 00625 if ( CriticalSection->LockCount == -1) { 00626 (Print)("\tLockCount NOT LOCKED\n"); 00627 } else { 00628 (Print)("\tLockCount %ld\n", CriticalSection->LockCount); 00629 } 00630 (Print)("\tRecursionCount %ld\n", CriticalSection->RecursionCount); 00631 (Print)("\tOwningThread %lx\n", CriticalSection->OwningThread ); 00632 #if DBG 00633 (GetSymbol)(CriticalSection->OwnerBackTrace[ 0 ], Symbol, &Displacement); 00634 (GetSymbol)(CriticalSection->OwnerBackTrace[ 1 ], Symbol2, &Displacement2); 00635 (Print)("\tCalling Address %s+%lx\n", Symbol, Displacement); 00636 (Print)("\tCallers Caller %s+%lx\n", Symbol2, Displacement2); 00637 #endif // DBG 00638 Position--; 00639 History--; 00640 } 00641 RtlFreeHeap(RtlProcessHeap(), 0, Array); 00642 } 00643 00644 00645 VOID 00646 dsrv( 00647 HANDLE hCurrentProcess, 00648 HANDLE hCurrentThread, 00649 DWORD dwCurrentPc, 00650 PNTSD_EXTENSION_APIS lpExtensionApis, 00651 LPSTR lpArgumentString 00652 ) 00653 { 00654 DumpArray( 00655 hCurrentProcess, 00656 hCurrentThread, 00657 dwCurrentPc, 00658 lpExtensionApis, 00659 lpArgumentString, 00660 &UserSrvIndex, 00661 (LPDWORD)&UserSrvArray[0] 00662 ); 00663 } 00664 00665 #endif // if 0 00666 00667 #if DBG 00668 00669 #ifdef EXTRAHEAPCHECKING 00670 00671 VOID ValidateUserHeaps( VOID ) 00672 { 00673 PWINDOWSTATION pwinsta; 00674 PDESKTOP pdesk; 00675 00676 for (pwinsta = grpwinstaList; pwinsta; pwinsta = pwinsta->rpwinstaNext) { 00677 for (pdesk = pwinsta->rpdeskList; pdesk; pdesk = pdesk->rpdeskNext) { 00678 if (!wcscmp(pdesk->lpszDeskName, L"Default")) { 00679 RtlValidateHeap(Win32HeapGetHandle(pdesk->pheapDesktop), 0, NULL); // desktop heaps 00680 } 00681 } 00682 } 00683 } 00684 00685 #endif // EXTRAHEAPCHECKING 00686 00687 /***************************************************************************\ 00688 * _EnterCrit 00689 * _LeaveCrit 00690 * 00691 * These are temporary routines that are used by USER.DLL until the critsect, 00692 * validation, mapping code is moved to the server-side stubs generated by 00693 * SMeans' Thank compiler. 00694 * 00695 * History: 00696 * 01-02-91 DarrinM Created. 00697 \***************************************************************************/ 00698 00699 void _AssertCritIn() 00700 { 00701 UserAssert(gpresUser != NULL); 00702 UserAssert(ExIsResourceAcquiredExclusiveLite(gpresUser) == TRUE); 00703 } 00704 00705 void _AssertDeviceInfoListCritIn() 00706 { 00707 UserAssert(gpresDeviceInfoList != NULL); 00708 UserAssert(ExIsResourceAcquiredExclusiveLite(gpresDeviceInfoList) == TRUE); 00709 } 00710 00711 void _AssertCritInShared() 00712 { 00713 UserAssert(gpresUser != NULL); 00714 UserAssert( (ExIsResourceAcquiredExclusiveLite(gpresUser) == TRUE) || 00715 (ExIsResourceAcquiredSharedLite(gpresUser) == TRUE)); 00716 } 00717 00718 00719 void _AssertCritOut() 00720 { 00721 UserAssert(gpresUser != NULL); 00722 UserAssert(ExIsResourceAcquiredExclusiveLite(gpresUser) == FALSE); 00723 } 00724 00725 void _AssertDeviceInfoListCritOut() 00726 { 00727 UserAssert(gpresDeviceInfoList != NULL); 00728 UserAssert(ExIsResourceAcquiredExclusiveLite(gpresDeviceInfoList) == FALSE); 00729 } 00730 00731 /***************************************************************************\ 00732 * BeginAtomicCheck() 00733 * EndAtomicCheck() 00734 * 00735 * Routine that verify we never leave the critical section and that an 00736 * operation is truely atomic with the possiblity of other code being run 00737 * because we left the critical section 00738 * 00739 \***************************************************************************/ 00740 00741 void BeginAtomicCheck() 00742 { 00743 gdwInAtomicOperation++; 00744 } 00745 00746 void EndAtomicCheck() 00747 { 00748 UserAssert(gdwInAtomicOperation > 0); 00749 gdwInAtomicOperation--; 00750 } 00751 00752 void BeginAtomicDeviceInfoListCheck() 00753 { 00754 gdwInAtomicDeviceInfoListOperation++; 00755 } 00756 00757 void EndAtomicDeviceInfoListCheck() 00758 { 00759 UserAssert(gdwInAtomicDeviceInfoListOperation > 0); 00760 gdwInAtomicDeviceInfoListOperation--; 00761 } 00762 00763 #define INCCRITSECCOUNT (gdwCritSecUseCount++) 00764 #define INCDEVICEINFOLISTCRITSECCOUNT (gdwDeviceInfoListCritSecUseCount++) 00765 00766 #else // else DBG 00767 00768 #define INCCRITSECCOUNT 00769 #define INCDEVICEINFOLISTCRITSECCOUNT 00770 00771 #endif // endif DBG 00772 00773 BOOL UserIsUserCritSecIn() 00774 { 00775 UserAssert(gpresUser != NULL); 00776 return( (ExIsResourceAcquiredExclusiveLite(gpresUser) == TRUE) || 00777 (ExIsResourceAcquiredSharedLite(gpresUser) == TRUE)); 00778 00779 return(TRUE); 00780 } 00781 00782 #if DBG 00783 void CheckDevLockOut() 00784 { 00785 /* 00786 * gpDispInfo can be NULL if Win32UserInitialize fails before allocationg it. 00787 * hDev is initialized later in InitVideo, after the critical section has been 00788 * released at least once; so we better check it too. 00789 */ 00790 if ((gpDispInfo != NULL) && (gpDispInfo->hDev != NULL)) { 00791 UserAssert(!GreIsDisplayLocked(gpDispInfo->hDev)); 00792 } 00793 } 00794 #else 00795 #define CheckDevLockOut() 00796 #endif 00797 00798 void EnterCrit(void) 00799 { 00800 CheckCritOut(); 00801 CheckDeviceInfoListCritOut(); 00802 KeEnterCriticalRegion(); 00803 ExAcquireResourceExclusiveLite(gpresUser, TRUE); 00804 CheckDevLockOut(); 00805 UserAssert(!ISATOMICCHECK()); 00806 UserAssert(gptiCurrent == NULL); 00807 gptiCurrent = ((PTHREADINFO)(W32GetCurrentThread())); 00808 INCCRITSECCOUNT; 00809 #if defined (USER_PERFORMANCE) 00810 { 00811 __int64 i64Frecv; 00812 *(LARGE_INTEGER*)(&gCSTimeExclusiveWhenEntering) = KeQueryPerformanceCounter((LARGE_INTEGER*)&i64Frecv); 00813 InterlockedIncrement(&gCSStatistics.cExclusive); 00814 } 00815 #endif // (USER_PERFORMANCE) 00816 00817 #if DBG 00818 GetCallStack(); 00819 #endif // DBG 00820 } 00821 00822 #if DBG 00823 void EnterDeviceInfoListCrit(void) 00824 { 00825 CheckDeviceInfoListCritOut(); 00826 KeEnterCriticalRegion(); 00827 ExAcquireResourceExclusiveLite(gpresDeviceInfoList, TRUE); 00828 UserAssert(!ISATOMICDEVICEINFOLISTCHECK()); 00829 INCDEVICEINFOLISTCRITSECCOUNT; 00830 } 00831 #endif // DBG 00832 00833 void EnterSharedCrit(void) 00834 { 00835 KeEnterCriticalRegion(); 00836 ExAcquireResourceSharedLite(gpresUser, TRUE); 00837 CheckDevLockOut(); 00838 UserAssert(!ISATOMICCHECK()); 00839 #if defined (USER_PERFORMANCE) 00840 InterlockedIncrement(&gCSStatistics.cShared); 00841 #endif // (USER_PERFORMANCE) 00842 00843 INCCRITSECCOUNT; 00844 } 00845 00846 void LeaveCrit(void) 00847 { 00848 INCCRITSECCOUNT; 00849 #if DBG 00850 UserAssert(!ISATOMICCHECK()); 00851 UserAssert(IsWinEventNotifyDeferredOK()); 00852 CheckDevLockOut(); 00853 FlushCallStack(); 00854 gptiCurrent = NULL; 00855 #endif // DBG 00856 00857 #if defined (USER_PERFORMANCE) 00858 /* 00859 * A non null gCSTimeExclusiveWhenEntering means the 00860 * critical section is owned exclusive 00861 */ 00862 if (gCSTimeExclusiveWhenEntering) { 00863 __int64 i64Temp, i64Frecv; 00864 00865 *(LARGE_INTEGER*)(&i64Temp) = KeQueryPerformanceCounter((LARGE_INTEGER*)&i64Frecv); 00866 gCSStatistics.i64TimeExclusive += i64Temp - gCSTimeExclusiveWhenEntering; 00867 gCSTimeExclusiveWhenEntering = 0; 00868 } 00869 #endif // (USER_PERFORMANCE) 00870 ExReleaseResource(gpresUser); 00871 KeLeaveCriticalRegion(); 00872 CheckCritOut(); 00873 } 00874 00875 #if DBG 00876 void _LeaveDeviceInfoListCrit(void) 00877 { 00878 INCDEVICEINFOLISTCRITSECCOUNT; 00879 UserAssert(!ISATOMICDEVICEINFOLISTCHECK()); 00880 00881 ExReleaseResource(gpresDeviceInfoList); 00882 KeLeaveCriticalRegion(); 00883 CheckDeviceInfoListCritOut(); 00884 } 00885 #endif // DBG 00886 00887 VOID ChangeAcquireResourceType( 00888 VOID) 00889 { 00890 #if DBG 00891 FlushCallStack(); 00892 CheckDevLockOut(); 00893 UserAssert(!ISATOMICCHECK()); 00894 #endif // DBG 00895 ExReleaseResource(gpresUser); 00896 ExAcquireResourceExclusiveLite(gpresUser, TRUE); 00897 gptiCurrent = ((PTHREADINFO)(W32GetCurrentThread())); 00898 #if DBG 00899 GetCallStack(); 00900 #endif // DBG 00901 } 00902 00903 00904 #if DBG 00905 00906 PTHREADINFO _ptiCrit(void) 00907 { 00908 UserAssert(gpresUser); 00909 UserAssert(ExIsResourceAcquiredExclusiveLite(gpresUser) == TRUE); 00910 UserAssert(gptiCurrent); 00911 UserAssert(gptiCurrent == ((PTHREADINFO)(W32GetCurrentThread()))); 00912 UserAssert(gptiCurrent); 00913 return gptiCurrent; 00914 } 00915 00916 PTHREADINFO _ptiCritShared(void) 00917 { 00918 UserAssert(W32GetCurrentThread()); 00919 return ((PTHREADINFO)(W32GetCurrentThread())); 00920 } 00921 00922 #undef KeUserModeCallback 00923 00924 NTSTATUS 00925 _KeUserModeCallback ( 00926 IN ULONG ApiNumber, 00927 IN PVOID InputBuffer, 00928 IN ULONG InputLength, 00929 OUT PVOID *OutputBuffer, 00930 OUT PULONG OutputLength 00931 ) 00932 { 00933 00934 UserAssert(ExIsResourceAcquiredExclusiveLite(gpresUser) == FALSE); 00935 00936 /* 00937 * Added this so we can detect an erroneous user mode callback 00938 * with a checked win32k on top of a free system. 00939 */ 00940 ASSERT(KeGetPreviousMode() == UserMode); 00941 00942 return KeUserModeCallback( ApiNumber, InputBuffer, InputLength, 00943 OutputBuffer, OutputLength); 00944 } 00945 00946 #endif

Generated on Sat May 15 19:42:21 2004 for test by doxygen 1.3.7