ULONG SymGetSymbolCount(void) { ASSERTMSG("SymbolEngine must be initialized prior to this call", bIsSymEngineInitialized == TRUE); // immediately acquire mutex, because of current count query ASSERTMSG("Fast mutex acquire must occur at or below APC_LEVEL", KeGetCurrentIrql() <= APC_LEVEL); ExAcquireFastMutex(&SymbolsListMutex); if(uSymbolCount != 0) { ASSERTMSG("Fast mutex release must occur at APC_LEVEL", KeGetCurrentIrql() == APC_LEVEL); ExReleaseFastMutex(&SymbolsListMutex); return uSymbolCount; } PLIST_ENTRY symbolListEntry = SymbolsListHead.Flink; ULONG uTmpSymbolCount = 0; // iterate through symbols list while(symbolListEntry != &SymbolsListHead) { ++uTmpSymbolCount; symbolListEntry = symbolListEntry->Flink; } // release the spinlock and return the count uSymbolCount = uTmpSymbolCount; ASSERTMSG("Fast mutex release must occur at APC_LEVEL", KeGetCurrentIrql() == APC_LEVEL); ExReleaseFastMutex(&SymbolsListMutex); return uTmpSymbolCount; }
BOOLEAN SymUpdateSymbol(IN PINTERNAL_SYMBOL pSymbol) { ASSERTMSG("Passed symbol cannot be NULL", pSymbol != NULL); ASSERTMSG("SymbolEngine must be initialized prior to this call", bIsSymEngineInitialized == TRUE); PSYMBOL_ENTRY pWantedSymbol = SympFindSymbol(pSymbol->name); ASSERTMSG("Fast mutex acquire must occur at or below APC_LEVEL", KeGetCurrentIrql() <= APC_LEVEL); ExAcquireFastMutex(&SymbolsListMutex); if(pWantedSymbol == NULL) { KdPrint(("[DEBUG] ERROR - %s private symbol does not exist!\n", pSymbol->name)); ASSERTMSG("Fast mutex release must occur at APC_LEVEL", KeGetCurrentIrql() == APC_LEVEL); ExReleaseFastMutex(&SymbolsListMutex); return FALSE; } // update all symbol fields pWantedSymbol->Symbol.u64address = pSymbol->u64address; pWantedSymbol->Symbol.uOffset = pSymbol->uOffset; pWantedSymbol->Symbol.uBitPosition = pSymbol->uBitPosition; pWantedSymbol->Symbol.uBitLength = pSymbol->uBitLength; ASSERTMSG("Fast mutex release must occur at APC_LEVEL", KeGetCurrentIrql() == APC_LEVEL); ExReleaseFastMutex(&SymbolsListMutex); return TRUE; }
_Use_decl_annotations_ NTSTATUS NotificationCopy( PVOID Buffer, ULONG BufferSize, PULONG BytesRead ) { PLIST_ENTRY pListEntry; PNOTIFICATION_ENTRY pEntry; if (BufferSize < sizeof(OBSERVER_NOTIFICATION)) { return STATUS_BUFFER_TOO_SMALL; } ExAcquireFastMutex(&NotificationListMutex); if (IsListEmpty(&NotificationList)) { ExReleaseFastMutex(&NotificationListMutex); *BytesRead = 0; return STATUS_MORE_PROCESSING_REQUIRED; } pListEntry = RemoveHeadList(&NotificationList); ExReleaseFastMutex(&NotificationListMutex); pEntry = CONTAINING_RECORD(pListEntry, NOTIFICATION_ENTRY, ListEntry); RtlCopyMemory(Buffer, &pEntry->Data, sizeof(OBSERVER_NOTIFICATION)); *BytesRead = sizeof(OBSERVER_NOTIFICATION); NOTIFICATION_FREE(pEntry); return STATUS_SUCCESS; }
PVOID ExAllocateFromPagedLookasideList( IN PPAGED_LOOKASIDE_LIST Lookaside ) /*++ Routine Description: This function removes (pops) the first entry from the specified paged lookaside list. Arguments: Lookaside - Supplies a pointer to a paged lookaside list structure. Return Value: If an entry is removed from the specified lookaside list, then the address of the entry is returned as the function value. Otherwise, NULL is returned. --*/ { PVOID Entry; Lookaside->L.TotalAllocates += 1; if (Isx86FeaturePresent(KF_CMPXCHG8B)) { if ((Entry = ExInterlockedPopEntrySList(&Lookaside->L.ListHead, NULL)) == NULL) { Lookaside->L.AllocateMisses += 1; Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, Lookaside->L.Size, Lookaside->L.Tag); } return Entry; } ExAcquireFastMutex(&Lookaside->Lock); Entry = PopEntryList(&Lookaside->L.ListHead.Next); if (Entry == NULL) { ExReleaseFastMutex(&Lookaside->Lock); Lookaside->L.AllocateMisses += 1; Entry = (Lookaside->L.Allocate)(Lookaside->L.Type, Lookaside->L.Size, Lookaside->L.Tag); } else { Lookaside->L.ListHead.Depth -= 1; ExReleaseFastMutex(&Lookaside->Lock); } return Entry; }
VOID ExFreeToPagedLookasideList( IN PPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry ) /*++ Routine Description: This function inserts (pushes) the specified entry into the specified paged lookaside list. Arguments: Lookaside - Supplies a pointer to a paged lookaside list structure. Entry - Supples a pointer to the entry that is inserted in the lookaside list. Return Value: None. --*/ { Lookaside->L.TotalFrees += 1; if (Isx86FeaturePresent(KF_CMPXCHG8B)) { if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { Lookaside->L.FreeMisses += 1; (Lookaside->L.Free)(Entry); } else { ExInterlockedPushEntrySList(&Lookaside->L.ListHead, (PSINGLE_LIST_ENTRY)Entry, NULL); } return; } ExAcquireFastMutex(&Lookaside->Lock); if (ExQueryDepthSList(&Lookaside->L.ListHead) >= Lookaside->L.Depth) { ExReleaseFastMutex(&Lookaside->Lock); Lookaside->L.FreeMisses += 1; (Lookaside->L.Free)(Entry); } else { PushEntryList(&Lookaside->L.ListHead.Next, (PSINGLE_LIST_ENTRY)Entry); Lookaside->L.ListHead.Depth += 1; ExReleaseFastMutex(&Lookaside->Lock); } return; }
VOID LockLcxlMutexRead(PMultiReadMutex pMutex)//加锁读互斥 { ExAcquireFastMutex(&pMutex->z); ExAcquireFastMutex(&pMutex->kReadMutex); if (pMutex->iReadCount == 0) { KeWaitForSingleObject(&pMutex->kRWMutex, Executive, KernelMode, FALSE, NULL); } pMutex->iReadCount++; ExReleaseFastMutex(&pMutex->kReadMutex); ExReleaseFastMutex(&pMutex->z); }
PNDAS_CCB ReadonlyLookUpCcbByReadonlyFileObject ( IN PFILESPY_DEVICE_EXTENSION DevExt, IN PFILE_OBJECT ReadonlyFileObject ) { PNDAS_CCB ccb = NULL; PLIST_ENTRY listEntry; ExAcquireFastMutex( &DevExt->LfsDeviceExt.Readonly->CcbQMutex ); for (listEntry = DevExt->LfsDeviceExt.Readonly->CcbQueue.Flink; listEntry != &DevExt->LfsDeviceExt.Readonly->CcbQueue; listEntry = listEntry->Flink) { ccb = CONTAINING_RECORD( listEntry, NDAS_CCB, ListEntry ); if (ccb->ReadonlyFileObject == ReadonlyFileObject) break; ccb = NULL; } ExReleaseFastMutex( &DevExt->LfsDeviceExt.Readonly->CcbQMutex ); return ccb; }
PNDAS_CCB ReadonlyLookUpCcb ( IN PREADONLY Readonly, IN PFILE_OBJECT FileObject ) { PNDAS_CCB ccb = NULL; PLIST_ENTRY listEntry; ExAcquireFastMutex( &Readonly->CcbQMutex ); for (listEntry = Readonly->CcbQueue.Flink; listEntry != &Readonly->CcbQueue; listEntry = listEntry->Flink) { ccb = CONTAINING_RECORD( listEntry, NDAS_CCB, ListEntry ); if (ccb->FileObject == FileObject) break; ccb = NULL; } ExReleaseFastMutex( &Readonly->CcbQMutex ); return ccb; }
VOID ReadonlyFreeCcb ( IN PFILESPY_DEVICE_EXTENSION DevExt, IN PNDAS_CCB Ccb ) { PLIST_ENTRY listEntry; ASSERT( Ccb->ListEntry.Flink == Ccb->ListEntry.Blink ); ExAcquireFastMutex( &DevExt->LfsDeviceExt.Readonly->CcbQMutex ); for (listEntry = DevExt->LfsDeviceExt.Readonly->CcbQueue.Flink; listEntry != &DevExt->LfsDeviceExt.Readonly->CcbQueue; listEntry = listEntry->Flink) { PNDAS_CCB childCcb; childCcb = CONTAINING_RECORD( listEntry, NDAS_CCB, ListEntry ); if (childCcb->CreateContext.RelatedFileHandle == Ccb->ReadonlyFileHandle) childCcb->RelatedFileObjectClosed = TRUE; } ExReleaseFastMutex( &DevExt->LfsDeviceExt.Readonly->CcbQMutex ); InterlockedDecrement( &DevExt->LfsDeviceExt.Readonly->CcbCount ); ExFreePoolWithTag( Ccb, LFS_CCB_TAG ); }
// // Find a thread exemption in the list of exemptions and return its pointer // PTHREAD_EXEMPTION FindThreadExemption( IN PVOID Thread, IN BOOLEAN LockList) { PTHREAD_EXEMPTION Exemption = NULL; PLIST_ENTRY Current; if (LockList) ExAcquireFastMutex( &ThreadExemptionListMutex); for (Current = ThreadExemptionList.Flink; Current != &ThreadExemptionList; Current = Current->Flink) { PTHREAD_EXEMPTION CurrentExemption = (PTHREAD_EXEMPTION)Current; // // If the current entry's thread matches the one that is requested, return // its pointer // if (CurrentExemption->Thread == Thread) { Exemption = CurrentExemption; break; } } if (LockList) ExReleaseFastMutex( &ThreadExemptionListMutex); return Exemption; }
static NTSTATUS CfixkrsRegisterChildThreadFilament( __in PCFIXKRP_FILAMENT Filament, __in HANDLE Thread ) { NTSTATUS Status; ASSERT( Filament ); ASSERT( Thread ); ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); ExAcquireFastMutex( &Filament->ChildThreads.Lock ); if ( Filament->ChildThreads.ThreadCount == _countof( Filament->ChildThreads.Threads ) ) { Status = STATUS_ALLOTTED_SPACE_EXCEEDED; goto Cleanup; } Filament->ChildThreads.Threads[ Filament->ChildThreads.ThreadCount++ ] = Thread; Status = STATUS_SUCCESS; Cleanup: ExReleaseFastMutex( &Filament->ChildThreads.Lock ); return Status; }
static VOID XenvbdTargetStop(ULONG target_id) { PXHBD_TARGET_INFO targetInfo; KIRQL irql; TraceNotice(("target %d: %s\n", target_id, __FUNCTION__)); irql = acquire_irqsafe_lock(XenvbdTargetInfoLock); targetInfo = XenvbdTargetInfo[target_id]; XM_ASSERT(targetInfo != NULL); targetInfo->References++; release_irqsafe_lock(XenvbdTargetInfoLock, irql); XM_ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); ExAcquireFastMutex(&targetInfo->StateLock); targetInfo->Started = FALSE; ExReleaseFastMutex(&targetInfo->StateLock); irql = acquire_irqsafe_lock(XenvbdTargetInfoLock); XM_ASSERT(targetInfo->References != 0); targetInfo->References--; release_irqsafe_lock(XenvbdTargetInfoLock, irql); }
// // Increment the reference count to a PDO. // PPDO_DEVICE_DATA LookupPdoData( PFDO_DEVICE_DATA FdoData, ULONG SystemIoBusNumber ) { PPDO_DEVICE_DATA pdoData = NULL; PLIST_ENTRY entry; PAGED_CODE (); KeEnterCriticalRegion(); ExAcquireFastMutex (&FdoData->Mutex); for (entry = FdoData->ListOfPDOs.Flink; entry != &FdoData->ListOfPDOs; entry = entry->Flink) { pdoData = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link); if(pdoData->SlotNo == SystemIoBusNumber) break; pdoData = NULL; } if(pdoData) { // // increment the reference count to the PDO. // ObReferenceObject(pdoData->Self); } ExReleaseFastMutex (&FdoData->Mutex); KeLeaveCriticalRegion(); return pdoData; }
NTSTATUS NTAPI CompBattDisableStatusNotify(IN PCOMPBATT_DEVICE_EXTENSION DeviceExtension) { PCOMPBATT_BATTERY_DATA BatteryData; PLIST_ENTRY ListHead, NextEntry; if (CompBattDebug & 0x100) DbgPrint("CompBatt: ENTERING DisableStatusNotify\n"); /* Loop the battery list */ ExAcquireFastMutex(&DeviceExtension->Lock); ListHead = &DeviceExtension->BatteryList; NextEntry = ListHead->Flink; while (NextEntry != ListHead) { /* Get the battery information and clear capacity data */ BatteryData = CONTAINING_RECORD(NextEntry, COMPBATT_BATTERY_DATA, BatteryLink); BatteryData->WaitStatus.LowCapacity = 0; BatteryData->WaitStatus.HighCapacity = 0x7FFFFFFF; NextEntry = NextEntry->Flink; } /* Done */ ExReleaseFastMutex(&DeviceExtension->Lock); if (CompBattDebug & 0x100) DbgPrint("CompBatt: EXITING DisableStatusNotify\n"); return STATUS_SUCCESS; }
BOOLEAN SymRemoveSymbol(IN PCHAR pszSymbolName) { ASSERTMSG("Passed symbol name is NULL", pszSymbolName != NULL); ASSERTMSG("SymbolEngine must be initialized prior to this call", bIsSymEngineInitialized == TRUE); // try to find the symbol to remove PSYMBOL_ENTRY pSymbolEntry = SympFindSymbol(pszSymbolName); // if symbol not found, return NULL if(pSymbolEntry == NULL) { return FALSE; } // symbol found, so we remove it from the list... ASSERTMSG("Fast mutex acquire must occur at or below APC_LEVEL", KeGetCurrentIrql() <= APC_LEVEL); ExAcquireFastMutex(&SymbolsListMutex); RemoveEntryList(&pSymbolEntry->ListEntry); // decrease symbol count (do it inside guarded block!) --uSymbolCount; // and free allocated memory ExFreeToNPagedLookasideList(&SymbolsLookasideList, pSymbolEntry); ASSERTMSG("Fast mutex release must occur at APC_LEVEL", KeGetCurrentIrql() == APC_LEVEL); ExReleaseFastMutex(&SymbolsListMutex); return TRUE; }
NTSTATUS CfixkrpJoinChildThreadsFilament( __in PCFIXKRP_FILAMENT Filament, __in_opt PLARGE_INTEGER Timeout ) { NTSTATUS Status; ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL ); ExAcquireFastMutex( &Filament->ChildThreads.Lock ); if ( Filament->ChildThreads.ThreadCount > 0 ) { KWAIT_BLOCK WaitBlocks[ CFIX_MAX_THREADS ]; Status = KeWaitForMultipleObjects( Filament->ChildThreads.ThreadCount, Filament->ChildThreads.Threads, WaitAll, Executive, KernelMode, FALSE, Timeout, WaitBlocks ); } else { Status = STATUS_SUCCESS; } ExReleaseFastMutex( &Filament->ChildThreads.Lock ); return Status; }
NTSTATUS NTAPI BeepClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension; /* Acquire the mutex and decrease reference count */ ExAcquireFastMutex(&DeviceExtension->Mutex); if (!(--DeviceExtension->ReferenceCount)) { /* Check for active timer */ if (DeviceExtension->TimerActive) { /* Cancel it */ if (KeCancelTimer(&DeviceExtension->Timer)) { /* Mark it as cancelled */ InterlockedDecrement(&DeviceExtension->TimerActive); } } /* Page the driver */ MmUnlockPagableImageSection(DeviceExtension->SectionHandle); } /* Release the lock */ ExReleaseFastMutex(&DeviceExtension->Mutex); /* Complete the request */ Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
PLFS_CCB Secondary_LookUpCcb ( IN PSECONDARY Secondary, IN PFILE_OBJECT FileObject ) { PLFS_CCB ccb = NULL; PLIST_ENTRY listEntry; ExAcquireFastMutex( &Secondary->CcbQMutex ); for (listEntry = Secondary->CcbQueue.Flink; listEntry != &Secondary->CcbQueue; listEntry = listEntry->Flink) { ccb = CONTAINING_RECORD( listEntry, LFS_CCB, ListEntry ); if (ccb->FileObject == FileObject) { break; } ccb = NULL; } ExReleaseFastMutex( &Secondary->CcbQMutex ); return ccb; }
VOID FreeCcb ( IN PSECONDARY Secondary, IN PLFS_CCB Ccb ) { PLIST_ENTRY listEntry; ASSERT( Ccb->ListEntry.Flink == Ccb->ListEntry.Blink ); ExAcquireFastMutex( &Secondary->CcbQMutex ); for (listEntry = Secondary->CcbQueue.Flink; listEntry != &Secondary->CcbQueue; listEntry = listEntry->Flink) { PLFS_CCB childCcb; childCcb = CONTAINING_RECORD( listEntry, LFS_CCB, ListEntry ); if (childCcb->CreateContext.RelatedFileHandle == Ccb->PrimaryFileHandle) childCcb->RelatedFileObjectClosed = TRUE; } ExReleaseFastMutex( &Secondary->CcbQMutex ); InterlockedDecrement( &Secondary->CcbCount ); ExFreePoolWithTag( Ccb, LFS_CCB_TAG ); }
static void hook_dump_entry() { PLDR_DATA_TABLE_ENTRY table; entry_hook *ehook; ExAcquireFastMutex(&dump_sync); if (dump_imgbase != NULL && (table = find_image(dump_imgbase))) { if (table->BaseDllName.Buffer != NULL && table->EntryPoint != NULL && img_cmp(&table->BaseDllName, L"dump_") || img_cmp(&table->BaseDllName, L"hiber_")) { if (ehook = mm_alloc(sizeof(entry_hook), 0)) { memcpy(ehook->code, jmp_code, sizeof(jmp_code)); ppv(ehook->code + DEST_OFF)[0] = dump_driver_entry; ppv(ehook->code + PARM_OFF)[0] = ehook; ehook->old_entry = table->EntryPoint; table->EntryPoint = pv(ehook->code); } } dump_imgbase = NULL; } ExReleaseFastMutex(&dump_sync); }
NTSTATUS bus_get_ports_status(ioctl_usbvbus_get_ports_status * st, PFDO_DEVICE_DATA fdodata, ULONG *info) { PDEVICE_OBJECT pdo; PPDO_DEVICE_DATA pdodata; NTSTATUS status; PLIST_ENTRY entry; PAGED_CODE (); Bus_KdPrint (fdodata, BUS_DBG_PNP_INFO, ("get ports status\n")); RtlZeroMemory(st, sizeof(*st)); ExAcquireFastMutex (&fdodata->Mutex); for (entry = fdodata->ListOfPDOs.Flink; entry != &fdodata->ListOfPDOs; entry = entry->Flink) { pdodata = CONTAINING_RECORD (entry, PDO_DEVICE_DATA, Link); if (pdodata->SerialNo > 127 || pdodata->SerialNo == 0){ KdPrint(("strange error")); } if(st->max_used_port < (int)pdodata->SerialNo) st->max_used_port = (int)pdodata->SerialNo; st->port_status[pdodata->SerialNo]=1; } ExReleaseFastMutex (&fdodata->Mutex); *info=sizeof(*st); return STATUS_SUCCESS; }
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- SetIntClkFreq -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- // static NTSTATUS SetIntClkFreq( IN Channel* pChannel, IN Int64 frequency) // dHz { Dta1xxSpiGen* pSpiReg; // Pointer to SPI general register block #if LOG_LEVEL_SPI > 1 DTA1XX_LOG(KERN_INFO, "[%d] SetIntClkFreq: frequency %ld", pChannel->m_PortIndex, (long int)frequency); #endif // Check parameter if ((frequency < 0) || (frequency > 1890000000LL)) { DTA1XX_LOG(KERN_INFO, "[%d] SetIntClkFreq: invalid parameter frequency %ld", pChannel->m_PortIndex, (long int)frequency); return STATUS_INVALID_PARAMETER; } // Get pointer pSpiReg = pChannel->m_pSpiReg; // Set DSS ExAcquireFastMutex(&pChannel->m_DssMutex); // Protect access to DSS pChannel->m_DssFreq = DssFrequency(pSpiReg,(UInt32)frequency); // Set frequency DssUpdate(pSpiReg); // update DSS ExReleaseFastMutex(&pChannel->m_DssMutex); // Release access to DSS return STATUS_SUCCESS; } // SetIntClkFreq()
static VOID XenvbdTargetStart(ULONG target_id, char *backend_path, SUSPEND_TOKEN token) { PXHBD_TARGET_INFO targetInfo; KIRQL irql; NTSTATUS status; TraceNotice(("target %d: %s\n", target_id, __FUNCTION__)); irql = acquire_irqsafe_lock(XenvbdTargetInfoLock); targetInfo = XenvbdTargetInfo[target_id]; XM_ASSERT(targetInfo != NULL); targetInfo->References++; release_irqsafe_lock(XenvbdTargetInfoLock, irql); XM_ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); ExAcquireFastMutex(&targetInfo->StateLock); XM_ASSERT(!targetInfo->Started); status = PrepareBackendForReconnect(targetInfo, backend_path, token); if (!NT_SUCCESS(status)) goto fail1; targetInfo->Started = TRUE; ExReleaseFastMutex(&targetInfo->StateLock); irql = acquire_irqsafe_lock(XenvbdTargetInfoLock); XM_ASSERT(targetInfo->References != 0); targetInfo->References--; release_irqsafe_lock(XenvbdTargetInfoLock, irql); return; fail1: TraceError(("%s: fail1 (0x%08x)\n", __FUNCTION__, status)); ExReleaseFastMutex(&targetInfo->StateLock); irql = acquire_irqsafe_lock(XenvbdTargetInfoLock); XM_ASSERT(targetInfo->References != 0); targetInfo->References--; release_irqsafe_lock(XenvbdTargetInfoLock, irql); }
BOOLEAN SympAddSymbol(IN PCHAR pszSymbolName, IN ULONG64 uSymbolAddress, IN ULONG uOffset, IN ULONG uBitPosition, IN ULONG uBitLength) { ASSERTMSG("Cannot add symbol with NULL name", pszSymbolName != NULL); ASSERTMSG("SymbolEngine must be initialized prior to this call", bIsSymEngineInitialized == TRUE); // it is possible that we got symbol with zero address, offset -1, bit position -1, and length -1 if the symbol was not found during // enumeration in user mode. In that case, and only in that case, we return error! // NOTE: uSymbolAddress of -1 is used when symbols are initialized in order to send the array of wanted symbols to the user mode if(uSymbolAddress == 0 && uOffset == -1 && uBitPosition == -1 && uBitLength == -1) { KdPrint(("[DEBUG] WARNING - Symbol was probably not found in user mode, cannot add symbol with unknown address and unknown offset\n")); return FALSE; } // if symbol with this name already exists if(SympFindSymbol(pszSymbolName) != NULL) { // don't want to "update" the address -- use SymUpdateSymbol function instead KdPrint(("[DEBUG] WARNING - Symbol %s with address 0x%x already exists -- use SymUpdateFunction() to update the address\n", pszSymbolName, uSymbolAddress)); return TRUE; } // get memory from lookaside list PSYMBOL_ENTRY pSymbolEntry = (PSYMBOL_ENTRY) ExAllocateFromNPagedLookasideList(&SymbolsLookasideList); if(pSymbolEntry == NULL) { KdPrint(("[DEBUG] ERROR - Not enough memory in lookaside list to allocate new symbol entry\n")); return FALSE; } // copy string from passed parameter if(RtlStringCbCopyA(pSymbolEntry->Symbol.name, MAX_SYM_NAME, pszSymbolName) == STATUS_INVALID_PARAMETER) { KdPrint(("[DEBUG] ERROR - Error while copying symbol name to SYMBOL_ENTRY structure\n")); return FALSE; } // copy address from the passed parameter pSymbolEntry->Symbol.u64address = uSymbolAddress; // copy offset from the passed parameter pSymbolEntry->Symbol.uOffset = uOffset; // copy bit position from the passed parameter pSymbolEntry->Symbol.uBitPosition = uBitPosition; // copy bit length from the passed parameter pSymbolEntry->Symbol.uBitLength = uBitLength; // insert it to list (thread safe) ASSERTMSG("Fast mutex acquire must occur at or below APC_LEVEL", KeGetCurrentIrql() <= APC_LEVEL); ExAcquireFastMutex(&SymbolsListMutex); InsertHeadList(&SymbolsListHead, &pSymbolEntry->ListEntry); ++uSymbolCount; ASSERTMSG("Fast mutex release must occur at APC_LEVEL", KeGetCurrentIrql() == APC_LEVEL); ExReleaseFastMutex(&SymbolsListMutex); return TRUE; }
VOID NTAPI ExSwapinWorkerThreads(IN BOOLEAN AllowSwap) { KEVENT Event; PETHREAD CurrentThread = PsGetCurrentThread(), Thread; PEPROCESS Process = PsInitialSystemProcess; KAPC Apc; PAGED_CODE(); /* Initialize an event so we know when we're done */ KeInitializeEvent(&Event, NotificationEvent, FALSE); /* Lock this routine */ ExAcquireFastMutex(&ExpWorkerSwapinMutex); /* New threads cannot swap anymore */ ExpWorkersCanSwap = AllowSwap; /* Loop all threads in the system process */ Thread = PsGetNextProcessThread(Process, NULL); while (Thread) { /* Skip threads with explicit permission to do this */ if (Thread->ExWorkerCanWaitUser) goto Next; /* Check if we reached ourselves */ if (Thread == CurrentThread) { /* Do it inline */ KeSetKernelStackSwapEnable(AllowSwap); } else { /* Queue an APC */ KeInitializeApc(&Apc, &Thread->Tcb, InsertApcEnvironment, ExpSetSwappingKernelApc, NULL, NULL, KernelMode, &AllowSwap); if (KeInsertQueueApc(&Apc, &Event, NULL, 3)) { /* Wait for the APC to run */ KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); KeClearEvent(&Event); } } /* Next thread */ Next: Thread = PsGetNextProcessThread(Process, Thread); } /* Release the lock */ ExReleaseFastMutex(&ExpWorkerSwapinMutex); }
/* adds the given swapchain to the context's swapchain list * @return true on success */ BOOLEAN vboxWddmSwapchainCtxAdd(PVBOXMP_DEVEXT pDevExt, PVBOXWDDM_CONTEXT pContext, PVBOXWDDM_SWAPCHAIN pSwapchain) { BOOLEAN bRc; ExAcquireFastMutex(&pDevExt->ContextMutex); bRc = vboxWddmSwapchainCtxAddLocked(pDevExt, pContext, pSwapchain); ExReleaseFastMutex(&pDevExt->ContextMutex); return bRc; }
VOID PiUnload( IN PDRIVER_OBJECT DriverObject ) /*++ Routine Description: This routine cleans up all of the memory associated with any of the devices belonging to the driver. Arguments: DriverObject - Supplies a pointer to the driver object controling all of the devices. Return Value: None. --*/ { PVOID lockPtr; // // Lock the pageable code section // lockPtr = MmLockPagableCodeSection(PiUnload); ExAcquireFastMutex (&PipMutex); ObDereferenceObject(PipBusExtension->BusHandler->DeviceObject); // // Delete all the device info structures and card info structures // PipInvalidateCards(PipBusExtension); PipDeleteCards(PipBusExtension); // // Finally remove the bus handler reference. // HalDereferenceBusHandler (PipBusExtension->BusHandler); ExReleaseFastMutex (&PipMutex); // // Unlock pageable code section // MmUnlockPagableImageSection(lockPtr); }
FORCEINLINE NTSTATUS QueueingSecondaryRequest ( IN PSECONDARY Secondary, IN PSECONDARY_REQUEST SecondaryRequest ) { NTSTATUS status; ASSERT( SecondaryRequest->ListEntry.Flink == SecondaryRequest->ListEntry.Blink ); ExAcquireFastMutex( &Secondary->FastMutex ); if (FlagOn(Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_START) && !FlagOn(Secondary->Thread.Flags, SECONDARY_THREAD_FLAG_STOPED)) { ExInterlockedInsertTailList( &Secondary->RequestQueue, &SecondaryRequest->ListEntry, &Secondary->RequestQSpinLock ); ExReleaseFastMutex( &Secondary->FastMutex ); KeSetEvent( &Secondary->RequestEvent, IO_DISK_INCREMENT, FALSE ); status = STATUS_SUCCESS; } else { ExReleaseFastMutex( &Secondary->FastMutex ); status = STATUS_UNSUCCESSFUL; } if (status == STATUS_UNSUCCESSFUL) { SecondaryRequest->ExecuteStatus = STATUS_IO_DEVICE_ERROR; if (SecondaryRequest->Synchronous == TRUE) KeSetEvent( &SecondaryRequest->CompleteEvent, IO_DISK_INCREMENT, FALSE ); else DereferenceSecondaryRequest( SecondaryRequest ); } return status; }
VOID UnlockLcxlMutexRead(PMultiReadMutex pMutex)//解锁读互斥 { ExAcquireFastMutex(&pMutex->kReadMutex); pMutex->iReadCount--; if (pMutex->iReadCount == 0) { KeReleaseMutex(&pMutex->kRWMutex, FALSE); } ExReleaseFastMutex(&pMutex->kReadMutex); }
NTSTATUS SetCipherOpts(PGUID pDiskId, ECipherAlgo Algorithm, PVOID pCipherOpts) { NTSTATUS status = STATUS_SUCCESS; CipherOptsEntry *pOptsNode = NULL, *pThisNode = NULL; ExAcquireFastMutex(&g_pCipherOptsMutex); switch (Algorithm) { case ECipherAlgo_Disabled: case ECipherAlgo_AesXts: case ECipherAlgo_TwofishXts: case ECipherAlgo_SerpentXts: // Try find existing opts in a list for (pOptsNode = g_pCipherOptsHead; pOptsNode; pOptsNode = pOptsNode->Next) { if (0 == memcmp(&pOptsNode->DiskId, pDiskId, sizeof(GUID))) { pThisNode = pOptsNode; break; } } if (!pThisNode) { pThisNode = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(CipherOptsEntry), CipherPoolTag); if (pThisNode) { pThisNode->Next = g_pCipherOptsHead; g_pCipherOptsHead = pThisNode; } else status = STATUS_NO_MEMORY; } if (pThisNode) { memcpy(&pThisNode->DiskId, pDiskId, sizeof(GUID)); pThisNode->Algorithm = Algorithm; switch (Algorithm) { case ECipherAlgo_AesXts: case ECipherAlgo_TwofishXts: case ECipherAlgo_SerpentXts: memcpy(&pThisNode->Opts.Xts256, pCipherOpts, sizeof(Xts256CipherOptions)); break; } } break; default: status = STATUS_INVALID_PARAMETER; } ExReleaseFastMutex(&g_pCipherOptsMutex); return status; }