NTSTATUS PvfsListRemoveHead( PPVFS_LIST pList, PLW_LIST_LINKS *ppItem ) { NTSTATUS ntError = STATUS_UNSUCCESSFUL; BAIL_ON_INVALID_PTR(pList, ntError); BAIL_ON_INVALID_PTR(ppItem, ntError); if (PvfsListIsEmpty(pList)) { ntError = STATUS_NOT_FOUND; BAIL_ON_NT_STATUS(ntError); } *ppItem = LwListRemoveHead(&pList->DataList); pList->CurrentSize--; ntError = STATUS_SUCCESS; cleanup: return ntError; error: goto cleanup; }
VOID RdrNotifyContextList( PLW_LIST_LINKS pList, BOOLEAN bLocked, pthread_mutex_t* pMutex, NTSTATUS status, PVOID pParam ) { LW_LIST_LINKS List; PLW_LIST_LINKS pLink = NULL; BOOLEAN bWasLocked = bLocked; LWIO_LOCK_MUTEX(bLocked, pMutex); LwListInit(&List); while ((pLink = LwListRemoveHead(pList))) { LwListInsertTail(&List, pLink); } LWIO_UNLOCK_MUTEX(bLocked, pMutex); RdrContinueContextList(&List, status, pParam); LWIO_LOCK_MUTEX(bLocked, pMutex); while ((pLink = LwListRemoveHead(&List))) { LwListInsertTail(pList, pLink); } if (!bWasLocked) { LWIO_UNLOCK_MUTEX(bLocked, pMutex); } }
VOID IopIrpFreeZctIrpList( IN OUT PIO_FILE_OBJECT pFileObject ) { PLW_LIST_LINKS pLinks = NULL;; PIRP_INTERNAL irpInternal = NULL; PIRP pIrp = NULL; while (!LwListIsEmpty(&pFileObject->ZctCompletionIrpList)) { pLinks = LwListRemoveHead(&pFileObject->ZctCompletionIrpList); irpInternal = LW_STRUCT_FROM_FIELD(pLinks, IRP_INTERNAL, CancelLinks); pIrp = &irpInternal->Irp; LWIO_ASSERT(1 == irpInternal->ReferenceCount); LWIO_ASSERT(!pIrp->FileHandle); IopIrpDereference(&pIrp); } }
NTSTATUS IopDeviceRundown( IN PIO_DEVICE_OBJECT pDeviceObject ) { NTSTATUS status = 0; int EE = 0; BOOLEAN isLocked = FALSE; PLW_LIST_LINKS pLinks = NULL; LW_LIST_LINKS rundownList = { 0 }; LwListInit(&rundownList); IopDeviceLock(pDeviceObject); isLocked = TRUE; if (IsSetFlag(pDeviceObject->Flags, IO_DEVICE_OBJECT_FLAG_RUNDOWN)) { // TODO: Perhaps wait if currently running down. status = STATUS_SUCCESS; GOTO_CLEANUP_EE(EE); } SetFlag(pDeviceObject->Flags, IO_DEVICE_OBJECT_FLAG_RUNDOWN); // Gather rundown list for (pLinks = pDeviceObject->FileObjectsList.Next; pLinks != &pDeviceObject->FileObjectsList; pLinks = pLinks->Next) { PIO_FILE_OBJECT pFileObject = LW_STRUCT_FROM_FIELD(pLinks, IO_FILE_OBJECT, DeviceLinks); IopFileObjectReference(pFileObject); LwListInsertTail(&rundownList, &pFileObject->RundownLinks); } IopDeviceUnlock(pDeviceObject); isLocked = FALSE; // Now, actually run down every file w/o holding the device lock. while (!LwListIsEmpty(&rundownList)) { PIO_FILE_OBJECT pFileObject = NULL; pLinks = LwListRemoveHead(&rundownList); pFileObject = LW_STRUCT_FROM_FIELD(pLinks, IO_FILE_OBJECT, RundownLinks); IopFileObjectRundown(pFileObject); } IopRootRemoveDevice(pDeviceObject->Driver->Root, &pDeviceObject->RootLinks); cleanup: if (isLocked) { IopDeviceUnlock(pDeviceObject); } IO_LOG_LEAVE_ON_STATUS_EE(status, EE); return status; }
VOID IopIrpCancelFileObject( IN PIO_FILE_OBJECT pFileObject, IN BOOLEAN IsForRundown ) { BOOLEAN isLocked = FALSE; PLW_LIST_LINKS pLinks = NULL; PIRP_INTERNAL irpInternal = NULL; LW_LIST_LINKS cancelList = { 0 }; PIRP pIrp = NULL; LwListInit(&cancelList); // Gather IRPs we want to cancel while holding FO lock. IopFileObjectLock(pFileObject); isLocked = TRUE; if (IsSetFlag(pFileObject->Flags, FILE_OBJECT_FLAG_CANCELLED)) { GOTO_CLEANUP(); } if (IsForRundown) { SetFlag(pFileObject->Flags, FILE_OBJECT_FLAG_CANCELLED); } // gather list of IRPs for (pLinks = pFileObject->IrpList.Next; pLinks != &pFileObject->IrpList; pLinks = pLinks->Next) { irpInternal = LW_STRUCT_FROM_FIELD(pLinks, IRP_INTERNAL, FileObjectLinks); LWIO_ASSERT(irpInternal->Irp.FileHandle == pFileObject); // Verify that this IRP is not already being cancelled. if (!irpInternal->CancelLinks.Next) { IopIrpReference(&irpInternal->Irp); LwListInsertTail(&cancelList, &irpInternal->CancelLinks); } } IopFileObjectUnlock(pFileObject); isLocked = FALSE; // Iterate over list, calling IopIrpCancel as appropriate. while (!LwListIsEmpty(&cancelList)) { pLinks = LwListRemoveHead(&cancelList); irpInternal = LW_STRUCT_FROM_FIELD(pLinks, IRP_INTERNAL, CancelLinks); pIrp = &irpInternal->Irp; IopIrpCancel(pIrp); IopIrpDereference(&pIrp); } cleanup: if (isLocked) { IopFileObjectUnlock(pFileObject); } }