NTSTATUS IopIrpCreate( OUT PIRP* ppIrp, IN IRP_TYPE Type, IN PIO_FILE_OBJECT pFileObject ) { NTSTATUS status = 0; int EE = 0; PIRP pIrp = NULL; status = IopIrpCreateDetached(&pIrp); GOTO_CLEANUP_ON_STATUS_EE(status, EE); status = IopIrpAttach(pIrp, Type, pFileObject); GOTO_CLEANUP_ON_STATUS_EE(status, EE); cleanup: if (status) { IopIrpDereference(&pIrp); } *ppIrp = pIrp; IO_LOG_LEAVE_ON_STATUS_EE(status, EE); return status; }
static NTSTATUS IopContinueAsyncCloseFile( IN PIO_FILE_OBJECT FileHandle, IN OPTIONAL PIO_ASYNC_COMPLETE_CALLBACK Callback, IN OPTIONAL PVOID CallbackContext, OUT PIO_STATUS_BLOCK IoStatusBlock ) { NTSTATUS status = STATUS_SUCCESS; int EE = 0; PIRP pIrp = NULL; IO_ASYNC_CONTROL_BLOCK asyncControlBlock = { 0 }; PIO_ASYNC_CONTROL_BLOCK useAsyncControlBlock = NULL; BOOLEAN isOpen = FALSE; // // If the create never completed successfully, we do not want // to send a CLOSE IRP. // // TODO -- There is probably still a small race window // wrt create and device rundown. The fix may involve // changing when IopFileObjectRemoveDispatched() is called // from IopIrpCompleteInternal() so that it is called // after the switch on the IRP type. IopFileObjectLock(FileHandle); isOpen = IsSetFlag(FileHandle->Flags, FILE_OBJECT_FLAG_CREATE_DONE); IopFileObjectUnlock(FileHandle); if (!isOpen) { status = STATUS_SUCCESS; GOTO_CLEANUP_EE(EE); } // // The file was actually opened, so do rest of close cleanup. // status = IopFileObjectGetCloseIrp(FileHandle, &pIrp); GOTO_CLEANUP_ON_STATUS_EE(status, EE); status = IopIrpAttach(pIrp, IRP_TYPE_CLOSE, FileHandle); GOTO_CLEANUP_ON_STATUS_EE(status, EE); if (Callback) { asyncControlBlock.Callback = Callback; asyncControlBlock.CallbackContext = CallbackContext; useAsyncControlBlock = &asyncControlBlock; } status = IopIrpDispatch( pIrp, useAsyncControlBlock, IoStatusBlock); if (STATUS_PENDING == status) { IoDereferenceAsyncCancelContext(&asyncControlBlock.AsyncCancelContext); } GOTO_CLEANUP_ON_STATUS_EE(status, EE); cleanup: IopIrpDereference(&pIrp); if (!useAsyncControlBlock && IoStatusBlock && (STATUS_PENDING != status)) { IO_STATUS_BLOCK ioStatusBlock = { 0 }; ioStatusBlock.Status = status; *IoStatusBlock = ioStatusBlock; } IO_LOG_LEAVE_ON_STATUS_EE(status, EE); return status; }