Example #1
0
VOID DokanUnmount(__in PDokanDCB Dcb) {
  ULONG eventLength;
  PEVENT_CONTEXT eventContext;
  PDRIVER_EVENT_CONTEXT driverEventContext;
  PKEVENT completedEvent;
  LARGE_INTEGER timeout;
  PDokanVCB vcb = Dcb->Vcb;
  ULONG deviceNamePos;

  DDbgPrint("==> DokanUnmount\n");

  eventLength = sizeof(EVENT_CONTEXT);
  eventContext = AllocateEventContextRaw(eventLength);

  if (eventContext == NULL) {
    ; // STATUS_INSUFFICIENT_RESOURCES;
    DDbgPrint(" Not able to allocate eventContext.\n");
    if (vcb) {
      DokanEventRelease(vcb->DeviceObject);
    }
    return;
  }

  driverEventContext =
      CONTAINING_RECORD(eventContext, DRIVER_EVENT_CONTEXT, EventContext);
  completedEvent = ExAllocatePool(sizeof(KEVENT));
  if (completedEvent) {
    KeInitializeEvent(completedEvent, NotificationEvent, FALSE);
    driverEventContext->Completed = completedEvent;
  }

  deviceNamePos = Dcb->SymbolicLinkName->Length / sizeof(WCHAR) - 1;
  for (; Dcb->SymbolicLinkName->Buffer[deviceNamePos] != L'\\'; --deviceNamePos)
    ;
  RtlStringCchCopyW(eventContext->Operation.Unmount.DeviceName,
                    sizeof(eventContext->Operation.Unmount.DeviceName) /
                        sizeof(WCHAR),
                    &(Dcb->SymbolicLinkName->Buffer[deviceNamePos]));

  DDbgPrint("  Send Unmount to Service : %ws\n",
            eventContext->Operation.Unmount.DeviceName);

  DokanEventNotification(&Dcb->Global->NotifyService, eventContext);

  if (completedEvent) {
    timeout.QuadPart = -1 * 10 * 1000 * 10; // 10 sec
    KeWaitForSingleObject(completedEvent, Executive, KernelMode, FALSE,
                          &timeout);
  }

  if (vcb) {
    DokanEventRelease(vcb->DeviceObject);
  }

  if (completedEvent) {
    ExFreePool(completedEvent);
  }

  DDbgPrint("<== DokanUnmount\n");
}
Example #2
0
NTSTATUS
DokanRegisterPendingIrp(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP			Irp,
	__in PEVENT_CONTEXT	EventContext,
	__in ULONG			Flags
    )
{
	PDokanVCB vcb = DeviceObject->DeviceExtension;
	NTSTATUS status;

	if (GetIdentifierType(vcb) != VCB) {
		DbgPrint("  Type != VCB\n");
		return STATUS_INVALID_PARAMETER;
	}

	status = RegisterPendingIrpMain(
		DeviceObject,
		Irp,
		EventContext->SerialNumber,
		&vcb->Dcb->PendingIrp,
		Flags,
		TRUE);

	if (status == STATUS_PENDING) {
		DokanEventNotification(&vcb->Dcb->NotifyEvent, EventContext);
	} else {
		DokanFreeEventContext(EventContext);
	}
	return status;
}
Example #3
0
VOID
DokanCheckKeepAlive(
	PDEVICE_EXTENSION	DeviceExtension)
{
	LARGE_INTEGER		tickCount;
	ULONG				eventLength;
	PEVENT_CONTEXT		eventContext;
	ULONG				mounted;

	//DDbgPrint("==> DokanCheckKeepAlive\n");

	KeQueryTickCount(&tickCount);
	ExAcquireResourceSharedLite(&DeviceExtension->Resource, TRUE);

	if ( (tickCount.QuadPart - DeviceExtension->TickCount.QuadPart) * KeQueryTimeIncrement()
		> DOKAN_KEEPALIVE_TIMEOUT * 10000 * 1000) {
	

		mounted = DeviceExtension->Mounted;

		ExReleaseResourceLite(&DeviceExtension->Resource);


		DDbgPrint("  Force to umount\n");

		if (!mounted) {
			// not mounted
			return;
		}

		eventLength = sizeof(EVENT_CONTEXT);
		eventContext = ExAllocatePool(eventLength);
				
		if (eventContext == NULL) {
			;//STATUS_INSUFFICIENT_RESOURCES;
			DokanEventRelease(DeviceExtension->DeviceObject);
			return;
		}

		RtlZeroMemory(eventContext, eventLength);
		eventContext->Length = eventLength;

		// set drive letter
		eventContext->Flags = mounted;

		DokanEventNotification(&DeviceExtension->Global->NotifyService, eventContext);

		DokanEventRelease(DeviceExtension->DeviceObject);

	} else {
		ExReleaseResourceLite(&DeviceExtension->Resource);
	}

	//DDbgPrint("<== DokanCheckKeepAlive\n");
}
Example #4
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;
}