Example #1
0
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");
}
Example #2
0
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;
}