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

ex.c

Go to the documentation of this file.
00001 /**************************** Module Header ********************************\ 00002 * Module Name: ex.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * Executive support routines 00007 * 00008 * History: 00009 * 03-04-95 JimA Created. 00010 \***************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 00016 NTSTATUS 00017 OpenEffectiveToken( 00018 PHANDLE phToken) 00019 { 00020 NTSTATUS Status; 00021 00022 /* 00023 * Open the client's token. 00024 */ 00025 Status = ZwOpenThreadToken( 00026 NtCurrentThread(), 00027 TOKEN_QUERY, 00028 (BOOLEAN)TRUE, // OpenAsSelf 00029 phToken 00030 ); 00031 if (Status == STATUS_NO_TOKEN) { 00032 00033 /* 00034 * Client wasn't impersonating anyone. Open its process token. 00035 */ 00036 Status = ZwOpenProcessToken( 00037 NtCurrentProcess(), 00038 TOKEN_QUERY, 00039 phToken 00040 ); 00041 } 00042 00043 if (!NT_SUCCESS(Status)) { 00044 RIPMSG1(RIP_WARNING, "Can't open client's token! - Status = %lx", Status); 00045 } 00046 return Status; 00047 } 00048 00049 NTSTATUS 00050 GetProcessLuid( 00051 PETHREAD Thread, 00052 PLUID LuidProcess 00053 ) 00054 { 00055 PACCESS_TOKEN UserToken = NULL; 00056 BOOLEAN fCopyOnOpen; 00057 BOOLEAN fEffectiveOnly; 00058 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; 00059 NTSTATUS Status; 00060 00061 if (Thread == NULL) 00062 Thread = PsGetCurrentThread(); 00063 00064 // 00065 // Check for a thread token first 00066 // 00067 00068 UserToken = PsReferenceImpersonationToken(Thread, 00069 &fCopyOnOpen, &fEffectiveOnly, &ImpersonationLevel); 00070 00071 if (UserToken == NULL) { 00072 00073 // 00074 // No thread token, go to the process 00075 // 00076 00077 UserToken = PsReferencePrimaryToken(Thread->ThreadsProcess); 00078 if (UserToken == NULL) 00079 return STATUS_NO_TOKEN; 00080 } 00081 00082 Status = SeQueryAuthenticationIdToken(UserToken, LuidProcess); 00083 00084 // 00085 // We're finished with the token 00086 // 00087 00088 ObDereferenceObject(UserToken); 00089 00090 return Status; 00091 } 00092 00093 00094 BOOLEAN 00095 IsRestricted( 00096 PETHREAD Thread 00097 ) 00098 { 00099 PACCESS_TOKEN UserToken; 00100 BOOLEAN fCopyOnOpen; 00101 BOOLEAN fEffectiveOnly; 00102 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; 00103 BOOLEAN fRestricted = FALSE; 00104 00105 /* 00106 * Check for a thread token first. 00107 */ 00108 UserToken = PsReferenceImpersonationToken(Thread, 00109 &fCopyOnOpen, &fEffectiveOnly, &ImpersonationLevel); 00110 00111 /* 00112 * If no thread token, go to the process. 00113 */ 00114 if (UserToken == NULL) { 00115 UserToken = PsReferencePrimaryToken(Thread->ThreadsProcess); 00116 } 00117 00118 /* 00119 * If we got a token, is it restricted? 00120 */ 00121 if (UserToken != NULL) { 00122 fRestricted = SeTokenIsRestricted(UserToken); 00123 ObDereferenceObject(UserToken); 00124 } 00125 00126 return fRestricted; 00127 } 00128 00129 00130 NTSTATUS 00131 CreateSystemThread( 00132 PKSTART_ROUTINE lpThreadAddress, 00133 PVOID pvContext, 00134 PHANDLE phThread) 00135 { 00136 NTSTATUS Status; 00137 OBJECT_ATTRIBUTES Obja; 00138 HANDLE hProcess; 00139 00140 CheckCritOut(); 00141 00142 InitializeObjectAttributes(&Obja, 00143 NULL, 00144 0, 00145 NULL, 00146 NULL); 00147 00148 /* 00149 * On WinFrame WIN32K.SYS is in WINSTATION SPACE. We can not 00150 * allow any system threads to access WIN32K.SYS since 00151 * this space is not mapped into the system process. 00152 * 00153 * We need to access the CSRSS 00154 * process regardless of who our caller is. IE: We could be called from 00155 * a CSRSS client who does not have a handle to the CSRSS process in 00156 * its handle table. 00157 */ 00158 UserAssert(gpepCSRSS != NULL); 00159 00160 Status = ObOpenObjectByPointer( 00161 gpepCSRSS, 00162 0, 00163 NULL, 00164 PROCESS_CREATE_THREAD, 00165 NULL, 00166 KernelMode, 00167 &hProcess); 00168 00169 if (!NT_SUCCESS(Status)) { 00170 return Status; 00171 } 00172 00173 UserAssert(hProcess != NULL); 00174 00175 Status = PsCreateSystemThread( 00176 phThread, 00177 THREAD_ALL_ACCESS, 00178 &Obja, 00179 hProcess, 00180 NULL, 00181 lpThreadAddress, 00182 pvContext); 00183 00184 ZwClose(hProcess); 00185 00186 return Status; 00187 } 00188 00189 00190 NTSTATUS 00191 InitSystemThread( 00192 PUNICODE_STRING pstrThreadName) 00193 { 00194 PETHREAD pEThread; 00195 PEPROCESS Process; 00196 PTHREADINFO pti; 00197 NTSTATUS Status; 00198 00199 CheckCritOut(); 00200 00201 pEThread = PsGetCurrentThread(); 00202 Process = pEThread->ThreadsProcess; 00203 00204 ValidateThreadSessionId(pEThread); 00205 00206 /* 00207 * check to see if process is already set, if not, we 00208 * need to set it up as well 00209 */ 00210 if (Process->Win32Process == NULL) { 00211 Status = W32pProcessCallout(Process, TRUE); 00212 if (!NT_SUCCESS(Status)) { 00213 return Status; 00214 } 00215 } 00216 00217 /* 00218 * We have the W32 process (or don't need one). Now get the thread data 00219 * and the kernel stack 00220 */ 00221 Status = AllocateW32Thread(pEThread); 00222 if (!NT_SUCCESS(Status)) { 00223 return Status; 00224 } 00225 00226 EnterCrit(); 00227 00228 /* 00229 * Allocate a pti for this thread 00230 * 00231 * Flag this as a system thread 00232 */ 00233 Status = xxxCreateThreadInfo(pEThread, TRUE); 00234 if (!NT_SUCCESS(Status)) { 00235 FreeW32Thread(pEThread); 00236 LeaveCrit(); 00237 return Status; 00238 } 00239 00240 pti = PtiCurrentShared(); 00241 if (pstrThreadName) { 00242 if (pti->pstrAppName != NULL) 00243 UserFreePool(pti->pstrAppName); 00244 pti->pstrAppName = UserAllocPoolWithQuota(sizeof(UNICODE_STRING) + 00245 pstrThreadName->Length + sizeof(WCHAR), TAG_TEXT); 00246 if (pti->pstrAppName != NULL) { 00247 pti->pstrAppName->Buffer = (PWCHAR)(pti->pstrAppName + 1); 00248 RtlCopyMemory(pti->pstrAppName->Buffer, pstrThreadName->Buffer, 00249 pstrThreadName->Length); 00250 pti->pstrAppName->Buffer[pstrThreadName->Length / sizeof(WCHAR)] = 0; 00251 pti->pstrAppName->MaximumLength = pstrThreadName->Length + sizeof(WCHAR); 00252 pti->pstrAppName->Length = pstrThreadName->Length; 00253 } 00254 } 00255 00256 /* 00257 * Need to clear the W32PF_APPSTARTING bit so that windows created by 00258 * the RIT don't cause the cursor to change to the app starting 00259 * cursor. 00260 */ 00261 if ((pti->ppi != NULL) && (pti->ppi->W32PF_Flags & W32PF_APPSTARTING)) { 00262 ClearAppStarting(pti->ppi); 00263 } 00264 00265 LeaveCrit(); 00266 00267 return STATUS_SUCCESS; 00268 } 00269 00270 VOID 00271 UserRtlRaiseStatus( 00272 NTSTATUS Status) 00273 { 00274 ExRaiseStatus(Status); 00275 } 00276 00277 NTSTATUS 00278 CommitReadOnlyMemory( 00279 HANDLE hSection, 00280 PSIZE_T pCommitSize, 00281 DWORD dwCommitOffset, 00282 int* pdCommit) 00283 { 00284 SIZE_T ulViewSize; 00285 LARGE_INTEGER liOffset; 00286 PEPROCESS Process; 00287 PVOID pUserBase, pvt; 00288 NTSTATUS Status; 00289 00290 ulViewSize = 0; 00291 pUserBase = NULL; 00292 liOffset.QuadPart = 0; 00293 Process = PsGetCurrentProcess(); 00294 00295 Status = MmMapViewOfSection( 00296 hSection, 00297 Process, 00298 &pUserBase, 00299 0, 00300 PAGE_SIZE, 00301 &liOffset, 00302 &ulViewSize, 00303 ViewUnmap, 00304 SEC_NO_CHANGE, 00305 PAGE_EXECUTE_READ); 00306 00307 if (NT_SUCCESS(Status)) { 00308 00309 /* 00310 * Commit the memory 00311 */ 00312 pUserBase = pvt = (PVOID)((PBYTE)pUserBase + dwCommitOffset); 00313 00314 Status = ZwAllocateVirtualMemory( 00315 NtCurrentProcess(), 00316 &pUserBase, 00317 0, 00318 pCommitSize, 00319 MEM_COMMIT, 00320 PAGE_EXECUTE_READ); 00321 00322 if (pdCommit) { 00323 *pdCommit = (int)((PBYTE)pUserBase - (PBYTE)pvt); 00324 } 00325 #if DBG 00326 else { 00327 UserAssert(pvt == pUserBase); 00328 } 00329 #endif 00330 00331 MmUnmapViewOfSection(Process, pUserBase); 00332 } 00333 return Status; 00334 } 00335 00336 /***************************************************************************\ 00337 * CreateKernelEvent 00338 * 00339 * Creates a kernel event. This is used when reference counted events 00340 * created by ZwCreateEvent are not needed. 00341 * 00342 * History: 00343 * 06-26-95 JimA Created. 00344 \***************************************************************************/ 00345 00346 PKEVENT CreateKernelEvent( 00347 IN EVENT_TYPE Type, 00348 IN BOOLEAN State) 00349 { 00350 PKEVENT pEvent; 00351 00352 pEvent = UserAllocPoolNonPaged(sizeof(KEVENT), TAG_SYSTEM); 00353 if (pEvent != NULL) { 00354 KeInitializeEvent(pEvent, Type, State); 00355 } 00356 return pEvent; 00357 } 00358 00359 /***************************************************************************\ 00360 * LockObjectAssignment 00361 * 00362 * References an object into a data structure 00363 * 00364 * History: 00365 * 06-26-95 JimA Created. 00366 \***************************************************************************/ 00367 00368 VOID LockObjectAssignment( 00369 PVOID *pplock, 00370 PVOID pobject 00371 #ifdef LOGDESKTOPLOCKS 00372 ,DWORD tag, 00373 ULONG_PTR extra 00374 #endif 00375 ) 00376 { 00377 PVOID pobjectOld; 00378 00379 /* 00380 * Save old object to dereference AFTER the new object is 00381 * referenced. This will avoid problems with relocking 00382 * the same object. 00383 */ 00384 pobjectOld = *pplock; 00385 00386 /* 00387 * Reference the new object. 00388 */ 00389 if (pobject != NULL) { 00390 ObReferenceObject(pobject); 00391 #ifdef LOGDESKTOPLOCKS 00392 if (OBJECT_TO_OBJECT_HEADER(pobject)->Type == *ExDesktopObjectType) { 00393 LogDesktop(pobject, tag, TRUE, extra); 00394 } 00395 #endif 00396 } 00397 *pplock = pobject; 00398 00399 /* 00400 * Dereference the old object 00401 */ 00402 if (pobjectOld != NULL) { 00403 #ifdef LOGDESKTOPLOCKS 00404 if (OBJECT_TO_OBJECT_HEADER(pobjectOld)->Type == *ExDesktopObjectType) { 00405 LogDesktop(pobjectOld, tag, FALSE, extra); 00406 } 00407 #endif 00408 ObDereferenceObject(pobjectOld); 00409 } 00410 } 00411 00412 /***************************************************************************\ 00413 * UnlockObjectAssignment 00414 * 00415 * Dereferences an object locked into a data structure 00416 * 00417 * History: 00418 * 06-26-95 JimA Created. 00419 \***************************************************************************/ 00420 00421 VOID UnlockObjectAssignment( 00422 PVOID *pplock 00423 #ifdef LOGDESKTOPLOCKS 00424 ,DWORD tag, 00425 ULONG_PTR extra 00426 #endif 00427 ) 00428 { 00429 if (*pplock != NULL) { 00430 #ifdef LOGDESKTOPLOCKS 00431 if (OBJECT_TO_OBJECT_HEADER(*pplock)->Type == *ExDesktopObjectType) { 00432 LogDesktop(*pplock, tag, FALSE, extra); 00433 } 00434 #endif 00435 ObDereferenceObject(*pplock); 00436 *pplock = NULL; 00437 } 00438 } 00439 00440 /***************************************************************************\ 00441 * UserDereferenceObject 00442 * 00443 * We need this for thread locking stuff since ObDereferenceObject is a macro. 00444 * 00445 * 09-21-98 JerrySh Created. 00446 \***************************************************************************/ 00447 00448 VOID UserDereferenceObject( 00449 PVOID pobj) 00450 { 00451 ObDereferenceObject(pobj); 00452 } 00453 00454 00455 /***************************************************************************\ 00456 * ProtectHandle 00457 * 00458 * This api is used set and clear close protection on handles used 00459 * by the kernel. 00460 * 00461 * 08-18-95 JimA Created. 00462 \***************************************************************************/ 00463 00464 NTSTATUS ProtectHandle( 00465 IN HANDLE Handle, 00466 IN BOOLEAN Protect) 00467 { 00468 OBJECT_HANDLE_FLAG_INFORMATION HandleInfo; 00469 NTSTATUS Status; 00470 00471 Status = ZwQueryObject( 00472 Handle, 00473 ObjectHandleFlagInformation, 00474 &HandleInfo, 00475 sizeof(HandleInfo), 00476 NULL); 00477 if (NT_SUCCESS(Status)) { 00478 HandleInfo.ProtectFromClose = Protect; 00479 00480 Status = ZwSetInformationObject( 00481 Handle, 00482 ObjectHandleFlagInformation, 00483 &HandleInfo, 00484 sizeof(HandleInfo)); 00485 } 00486 00487 return Status; 00488 } 00489 00490 #ifdef LOGDESKTOPLOCKS 00491 00492 /***************************************************************************\ 00493 * LogDesktop 00494 * 00495 * Log the lock/unlock calls for desktop objects 00496 * 00497 * Dec-2-97 clupu Created. 00498 \***************************************************************************/ 00499 00500 #define LOG_DELTA 8 00501 00502 PLogD GrowLogIfNecessary( 00503 PDESKTOP pdesk) 00504 { 00505 if (pdesk->nLogCrt < pdesk->nLogMax) { 00506 UserAssert(pdesk->pLog != NULL); 00507 return pdesk->pLog; 00508 } 00509 00510 /* 00511 * Grow the buffer 00512 */ 00513 if (pdesk->pLog == NULL) { 00514 00515 UserAssert(pdesk->nLogMax == 0 && pdesk->nLogCrt == 0); 00516 00517 pdesk->pLog = (PLogD)UserAllocPool(LOG_DELTA * sizeof(LogD), TAG_LOGDESKTOP); 00518 00519 } else { 00520 pdesk->pLog = (PLogD)UserReAllocPool(pdesk->pLog, 00521 pdesk->nLogCrt * sizeof(LogD), 00522 (pdesk->nLogCrt + LOG_DELTA) * sizeof(LogD), 00523 TAG_LOGDESKTOP); 00524 } 00525 00526 UserAssert(pdesk->pLog != NULL); 00527 00528 pdesk->nLogMax += LOG_DELTA; 00529 00530 return pdesk->pLog; 00531 } 00532 00533 00534 void LogDesktop( 00535 PDESKTOP pdesk, 00536 DWORD tag, 00537 BOOL bLock, 00538 ULONG_PTR extra) 00539 { 00540 DWORD tag1 = 0, tag2 = 0; 00541 PLogD pLog; 00542 00543 if (pdesk == NULL) { 00544 return; 00545 } 00546 00547 /* 00548 * the tag stored in LogD structure is actually a WORD 00549 */ 00550 UserAssert(HIWORD(tag) == 0); 00551 00552 if (bLock) { 00553 00554 ULONG hash; 00555 00556 (pdesk->nLockCount)++; 00557 00558 growAndAdd: 00559 /* 00560 * grow the table if necessary and add the new 00561 * lock/unlock information to it 00562 */ 00563 pLog = GrowLogIfNecessary(pdesk); 00564 00565 pLog += pdesk->nLogCrt; 00566 00567 pLog->tag = (WORD)tag; 00568 pLog->type = (WORD)bLock; 00569 pLog->extra = extra; 00570 00571 RtlZeroMemory(pLog->trace, 6 * sizeof(PVOID)); 00572 00573 GetStackTrace(2, 00574 6, 00575 pLog->trace, 00576 &hash); 00577 00578 (pdesk->nLogCrt)++; 00579 return; 00580 } 00581 00582 /* 00583 * It's an unlock. 00584 * First search for a matching lock 00585 */ 00586 UserAssert(pdesk->nLockCount > 0); 00587 00588 switch (tag) { 00589 case LDU_CLS_DESKPARENT1: 00590 tag1 = LDL_CLS_DESKPARENT1; 00591 break; 00592 case LDU_CLS_DESKPARENT2: 00593 tag1 = LDL_CLS_DESKPARENT1; 00594 tag2 = LDL_CLS_DESKPARENT2; 00595 break; 00596 case LDU_FN_DESTROYCLASS: 00597 tag1 = LDL_FN_DESTROYCLASS; 00598 break; 00599 case LDU_FN_DESTROYMENU: 00600 tag1 = LDL_FN_DESTROYMENU; 00601 break; 00602 case LDU_FN_DESTROYTHREADINFO: 00603 tag1 = LDL_FN_DESTROYTHREADINFO; 00604 break; 00605 case LDU_FN_DESTROYWINDOWSTATION: 00606 tag1 = LDL_FN_DESTROYWINDOWSTATION; 00607 break; 00608 case LDU_DESKDISCONNECT: 00609 tag1 = LDL_DESKDISCONNECT; 00610 break; 00611 case LDU_DESK_DESKNEXT: 00612 tag1 = LDL_DESK_DESKNEXT1; 00613 break; 00614 case LDU_OBJ_DESK: 00615 tag1 = LDL_OBJ_DESK; 00616 tag2 = LDL_MOTHERDESK_DESK1; 00617 break; 00618 case LDL_PTI_DESK: 00619 tag1 = LDL_PTI_DESK; 00620 tag2 = LDL_DT_DESK; 00621 break; 00622 case LDU_PTI_DESK: 00623 tag1 = LDL_PTI_DESK; 00624 break; 00625 case LDU_PPI_DESKSTARTUP1: 00626 case LDU_PPI_DESKSTARTUP2: 00627 case LDU_PPI_DESKSTARTUP3: 00628 tag1 = LDL_PPI_DESKSTARTUP1; 00629 tag2 = LDL_PPI_DESKSTARTUP2; 00630 break; 00631 case LDU_DESKLOGON: 00632 tag1 = LDL_DESKLOGON; 00633 break; 00634 00635 case LDUT_FN_FREEWINDOW: 00636 tag1 = LDLT_FN_FREEWINDOW; 00637 break; 00638 case LDUT_FN_DESKTOPTHREAD_DESK: 00639 tag1 = LDLT_FN_DESKTOPTHREAD_DESK; 00640 break; 00641 case LDUT_FN_DESKTOPTHREAD_DESKTEMP: 00642 tag1 = LDLT_FN_DESKTOPTHREAD_DESKTEMP; 00643 break; 00644 case LDUT_FN_SETDESKTOP: 00645 tag1 = LDLT_FN_SETDESKTOP; 00646 break; 00647 case LDUT_FN_NTUSERSWITCHDESKTOP: 00648 tag1 = LDLT_FN_NTUSERSWITCHDESKTOP; 00649 break; 00650 case LDUT_FN_SENDMESSAGEBSM1: 00651 case LDUT_FN_SENDMESSAGEBSM2: 00652 tag1 = LDLT_FN_SENDMESSAGEBSM; 00653 break; 00654 case LDUT_FN_SYSTEMBROADCASTMESSAGE: 00655 tag1 = LDLT_FN_SYSTEMBROADCASTMESSAGE; 00656 break; 00657 case LDUT_FN_CTXREDRAWSCREEN: 00658 tag1 = LDLT_FN_CTXREDRAWSCREEN; 00659 break; 00660 case LDUT_FN_CTXDISABLESCREEN: 00661 tag1 = LDLT_FN_CTXDISABLESCREEN; 00662 break; 00663 00664 case LD_DEREF_FN_CREATEDESKTOP1: 00665 case LD_DEREF_FN_CREATEDESKTOP2: 00666 case LD_DEREF_FN_CREATEDESKTOP3: 00667 tag1 = LD_REF_FN_CREATEDESKTOP; 00668 break; 00669 case LD_DEREF_FN_OPENDESKTOP: 00670 tag1 = LD_REF_FN_OPENDESKTOP; 00671 break; 00672 case LD_DEREF_FN_SETDESKTOP: 00673 tag1 = LD_REF_FN_SETDESKTOP; 00674 break; 00675 case LD_DEREF_FN_GETTHREADDESKTOP: 00676 tag1 = LD_REF_FN_GETTHREADDESKTOP; 00677 break; 00678 case LD_DEREF_FN_CLOSEDESKTOP1: 00679 case LD_DEREF_FN_CLOSEDESKTOP2: 00680 tag1 = LD_REF_FN_CLOSEDESKTOP; 00681 break; 00682 case LD_DEREF_FN_RESOLVEDESKTOP: 00683 tag1 = LD_REF_FN_RESOLVEDESKTOP; 00684 break; 00685 case LD_DEREF_VALIDATE_HDESK1: 00686 case LD_DEREF_VALIDATE_HDESK2: 00687 case LD_DEREF_VALIDATE_HDESK3: 00688 case LD_DEREF_VALIDATE_HDESK4: 00689 tag1 = LDL_VALIDATE_HDESK; 00690 break; 00691 case LDUT_FN_CREATETHREADINFO1: 00692 case LDUT_FN_CREATETHREADINFO2: 00693 tag1 = LDLT_FN_CREATETHREADINFO; 00694 break; 00695 case LD_DEREF_FN_SETCSRSSTHREADDESKTOP1: 00696 case LD_DEREF_FN_SETCSRSSTHREADDESKTOP2: 00697 tag1 = LD_REF_FN_SETCSRSSTHREADDESKTOP; 00698 break; 00699 case LD_DEREF_FN_CONSOLECONTROL1: 00700 tag1 = LD_REF_FN_CONSOLECONTROL1; 00701 break; 00702 case LD_DEREF_FN_CONSOLECONTROL2: 00703 tag1 = LD_REF_FN_CONSOLECONTROL2; 00704 break; 00705 case LD_DEREF_FN_GETUSEROBJECTINFORMATION: 00706 tag1 = LD_REF_FN_GETUSEROBJECTINFORMATION; 00707 break; 00708 case LD_DEREF_FN_SETUSEROBJECTINFORMATION: 00709 tag1 = LD_REF_FN_SETUSEROBJECTINFORMATION; 00710 break; 00711 case LD_DEREF_FN_CREATEWINDOWSTATION: 00712 tag1 = LD_REF_FN_CREATEWINDOWSTATION; 00713 break; 00714 00715 case LDL_TERM_DESKDESTROY1: 00716 tag1 = LDL_TERM_DESKDESTROY2; 00717 break; 00718 case LDL_MOTHERDESK_DESK1: 00719 tag1 = LDL_MOTHERDESK_DESK1; 00720 tag2 = LDL_MOTHERDESK_DESK2; 00721 break; 00722 case LDL_WINSTA_DESKLIST2: 00723 tag1 = LDL_WINSTA_DESKLIST1; 00724 break; 00725 case LDL_DESKRITINPUT: 00726 case LDU_DESKRITINPUT: 00727 tag1 = LDL_DESKRITINPUT; 00728 break; 00729 } 00730 00731 if (tag1 != 0) { 00732 00733 int ind; 00734 00735 /* 00736 * this is an unlock we know about. Let's find the 00737 * matching lock in the table. We start searching 00738 * the table backwords. 00739 */ 00740 for (ind = pdesk->nLogCrt - 1; ind >= 0; ind--) { 00741 pLog = pdesk->pLog + ind; 00742 00743 if (pLog->type == 1 && 00744 (pLog->tag == tag1 || pLog->tag == tag2) && 00745 pLog->extra == extra) { 00746 00747 /* 00748 * match found. remove the lock 00749 */ 00750 RtlMoveMemory(pdesk->pLog + ind, 00751 pdesk->pLog + ind + 1, 00752 (pdesk->nLogCrt - ind - 1) * sizeof(LogD)); 00753 00754 (pdesk->nLogCrt)--; 00755 00756 (pdesk->nLockCount)--; 00757 00758 if (pdesk->nLockCount == 0) { 00759 RIPMSG1(RIP_VERBOSE, "Lock count 0 for pdesk %#p\n", pdesk); 00760 } 00761 00762 return; 00763 } 00764 } 00765 00766 /* 00767 * We didn't find the matching lock and we were supposed to. 00768 * Just add it to the table and we'll look at it. 00769 */ 00770 RIPMSG3(RIP_WARNING, "Didn't find matching lock for pdesk %#p tag %d extra %lx\n", 00771 pdesk, tag, extra); 00772 } 00773 (pdesk->nLockCount)--; 00774 00775 goto growAndAdd; 00776 00777 return; 00778 } 00779 00780 #endif // LOGDESKTOPLOCKS

Generated on Sat May 15 19:39:57 2004 for test by doxygen 1.3.7