VOID DokanCompleteCreate( __in PIRP_ENTRY IrpEntry, __in PEVENT_INFORMATION EventInfo ) { PIRP irp; PIO_STACK_LOCATION irpSp; NTSTATUS status; ULONG info; PDokanCCB ccb; PDokanFCB fcb; irp = IrpEntry->Irp; irpSp = IrpEntry->IrpSp; DDbgPrint("==> DokanCompleteCreate\n"); ccb = IrpEntry->FileObject->FsContext2; ASSERT(ccb != NULL); fcb = ccb->Fcb; ASSERT(fcb != NULL); DDbgPrint(" FileName:%wZ\n", &fcb->FileName); ccb->UserContext = EventInfo->Context; //DDbgPrint(" set Context %X\n", (ULONG)ccb->UserContext); status = EventInfo->Status; info = EventInfo->Create.Information; switch (info) { case FILE_OPENED: DDbgPrint(" FILE_OPENED\n"); break; case FILE_CREATED: DDbgPrint(" FILE_CREATED\n"); break; case FILE_OVERWRITTEN: DDbgPrint(" FILE_OVERWRITTEN\n"); break; case FILE_DOES_NOT_EXIST: DDbgPrint(" FILE_DOES_NOT_EXIST\n"); break; case FILE_EXISTS: DDbgPrint(" FILE_EXISTS\n"); break; default: DDbgPrint(" info = %d\n", info); break; } ExAcquireResourceExclusiveLite(&fcb->Resource, TRUE); if (NT_SUCCESS(status) && (irpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE || EventInfo->Create.Flags & DOKAN_FILE_DIRECTORY)) { if (irpSp->Parameters.Create.Options & FILE_DIRECTORY_FILE) { DDbgPrint(" FILE_DIRECTORY_FILE %p\n", fcb); } else { DDbgPrint(" DOKAN_FILE_DIRECTORY %p\n", fcb); } fcb->Flags |= DOKAN_FILE_DIRECTORY; } ExReleaseResourceLite(&fcb->Resource); ExAcquireResourceExclusiveLite(&ccb->Resource, TRUE); if (NT_SUCCESS(status)) { ccb->Flags |= DOKAN_FILE_OPENED; } ExReleaseResourceLite(&ccb->Resource); if (NT_SUCCESS(status)) { if (info == FILE_CREATED) { if (fcb->Flags & DOKAN_FILE_DIRECTORY) { DokanNotifyReportChange(fcb, FILE_NOTIFY_CHANGE_DIR_NAME, FILE_ACTION_ADDED); } else { DokanNotifyReportChange(fcb, FILE_NOTIFY_CHANGE_FILE_NAME, FILE_ACTION_ADDED); } } } else { DDbgPrint(" IRP_MJ_CREATE failed. Free CCB:%X\n", ccb); DokanFreeCCB(ccb); DokanFreeFCB(fcb); } irp->IoStatus.Status = status; irp->IoStatus.Information = info; IoCompleteRequest(irp, IO_NO_INCREMENT); DokanPrintNTStatus(status); DDbgPrint("<== DokanCompleteCreate\n"); }
NTSTATUS DokanDispatchClose( __in PDEVICE_OBJECT DeviceObject, __in PIRP Irp ) /*++ Routine Description: This device control dispatcher handles create & close IRPs. Arguments: DeviceObject - Context for the activity. Irp - The device control argument block. Return Value: NTSTATUS --*/ { PDokanVCB vcb; PIO_STACK_LOCATION irpSp; NTSTATUS status = STATUS_INVALID_PARAMETER; PFILE_OBJECT fileObject; PDokanCCB ccb; PEVENT_CONTEXT eventContext; ULONG eventLength; PDokanFCB fcb; //PAGED_CODE(); __try { FsRtlEnterFileSystem(); DDbgPrint("==> DokanClose"); irpSp = IoGetCurrentIrpStackLocation(Irp); fileObject = irpSp->FileObject; if (fileObject == NULL) { DDbgPrint(" fileObject is NULL"); status = STATUS_SUCCESS; __leave; } DDbgPrint(" ProcessId %lu\n", IoGetRequestorProcessId(Irp)); DokanPrintFileName(fileObject); vcb = DeviceObject->DeviceExtension; if (GetIdentifierType(vcb) != VCB || !DokanCheckCCB(vcb->Dcb, fileObject->FsContext2)) { if (fileObject->FsContext2) { ccb = fileObject->FsContext2; ASSERT(ccb != NULL); fcb = ccb->Fcb; ASSERT(fcb != NULL); DDbgPrint(" Free CCB:%X\n", ccb); DokanFreeCCB(ccb); DokanFreeFCB(fcb); } status = STATUS_SUCCESS; __leave; } ccb = fileObject->FsContext2; ASSERT(ccb != NULL); fcb = ccb->Fcb; ASSERT(fcb != NULL); eventLength = sizeof(EVENT_CONTEXT) + fcb->FileName.Length; eventContext = AllocateEventContext(vcb->Dcb, Irp, eventLength, ccb); if (eventContext == NULL) { //status = STATUS_INSUFFICIENT_RESOURCES; DDbgPrint(" eventContext == NULL"); DDbgPrint(" Free CCB:%X\n", ccb); DokanFreeCCB(ccb); DokanFreeFCB(fcb); status = STATUS_SUCCESS; __leave; } eventContext->Context = ccb->UserContext; DDbgPrint(" UserContext:%X\n", (ULONG)ccb->UserContext); // copy the file name to be closed eventContext->Close.FileNameLength = fcb->FileName.Length; RtlCopyMemory(eventContext->Close.FileName, fcb->FileName.Buffer, fcb->FileName.Length); DDbgPrint(" Free CCB:%X\n", ccb); DokanFreeCCB(ccb); DokanFreeFCB(fcb); // Close can not be pending status // don't register this IRP //status = DokanRegisterPendingIrp(DeviceObject, Irp, eventContext->SerialNumber, 0); // inform it to user-mode DokanEventNotification(&vcb->Dcb->NotifyEvent, eventContext); status = STATUS_SUCCESS; } __finally { if (status != STATUS_PENDING) { Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); } DDbgPrint("<== DokanClose"); FsRtlExitFileSystem(); } return status; }