Beispiel #1
0
// start event dispatching
NTSTATUS
DokanEventStart(__in PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp) {
  ULONG outBufferLen;
  ULONG inBufferLen;
  PIO_STACK_LOCATION irpSp = NULL;
  PEVENT_START eventStart = NULL;
  PEVENT_DRIVER_INFO driverInfo = NULL;
  PDOKAN_GLOBAL dokanGlobal = NULL;
  PDokanDCB dcb = NULL;
  NTSTATUS status;
  DEVICE_TYPE deviceType;
  ULONG deviceCharacteristics = 0;
  WCHAR *baseGuidString;
  GUID baseGuid = DOKAN_BASE_GUID;
  UNICODE_STRING unicodeGuid;
  ULONG deviceNamePos;
  BOOLEAN useMountManager = FALSE;
  BOOLEAN mountGlobally = TRUE;
  BOOLEAN fileLockUserMode = FALSE;

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

  dokanGlobal = DeviceObject->DeviceExtension;
  if (GetIdentifierType(dokanGlobal) != DGL) {
    return STATUS_INVALID_PARAMETER;
  }

  irpSp = IoGetCurrentIrpStackLocation(Irp);

  outBufferLen = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
  inBufferLen = irpSp->Parameters.DeviceIoControl.InputBufferLength;

  eventStart = ExAllocatePool(sizeof(EVENT_START));
  baseGuidString = ExAllocatePool(64 * sizeof(WCHAR));

  if (outBufferLen != sizeof(EVENT_DRIVER_INFO) ||
      inBufferLen != sizeof(EVENT_START) || eventStart == NULL ||
      baseGuidString == NULL) {
    if (eventStart)
      ExFreePool(eventStart);
    if (baseGuidString)
      ExFreePool(baseGuidString);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  RtlCopyMemory(eventStart, Irp->AssociatedIrp.SystemBuffer,
                sizeof(EVENT_START));
  driverInfo = Irp->AssociatedIrp.SystemBuffer;

  if (eventStart->UserVersion != DOKAN_DRIVER_VERSION) {
    driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;
    driverInfo->Status = DOKAN_START_FAILED;
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);
    ExFreePool(eventStart);
    ExFreePool(baseGuidString);
    return STATUS_SUCCESS;
  }

  switch (eventStart->DeviceType) {
  case DOKAN_DISK_FILE_SYSTEM:
    deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
    break;
  case DOKAN_NETWORK_FILE_SYSTEM:
    deviceType = FILE_DEVICE_NETWORK_FILE_SYSTEM;
    deviceCharacteristics |= FILE_REMOTE_DEVICE;
    break;
  default:
    DDbgPrint("  Unknown device type: %d\n", eventStart->DeviceType);
    deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
  }

  if (eventStart->Flags & DOKAN_EVENT_REMOVABLE) {
    DDbgPrint("  DeviceCharacteristics |= FILE_REMOVABLE_MEDIA\n");
    deviceCharacteristics |= FILE_REMOVABLE_MEDIA;
  }

  if (eventStart->Flags & DOKAN_EVENT_WRITE_PROTECT) {
    DDbgPrint("  DeviceCharacteristics |= FILE_READ_ONLY_DEVICE\n");
    deviceCharacteristics |= FILE_READ_ONLY_DEVICE;
  }

  if (eventStart->Flags & DOKAN_EVENT_MOUNT_MANAGER) {
    DDbgPrint("  Using Mount Manager\n");
    useMountManager = TRUE;
  }

  if (eventStart->Flags & DOKAN_EVENT_CURRENT_SESSION) {
    DDbgPrint("  Mounting on current session only\n");
    mountGlobally = FALSE;
  }

  if (eventStart->Flags & DOKAN_EVENT_FILELOCK_USER_MODE) {
    DDbgPrint("  FileLock in User Mode\n");
    fileLockUserMode = TRUE;
  }

  KeEnterCriticalRegion();
  ExAcquireResourceExclusiveLite(&dokanGlobal->Resource, TRUE);

  DOKAN_CONTROL dokanControl;
  RtlZeroMemory(&dokanControl, sizeof(dokanControl));
  RtlStringCchCopyW(dokanControl.MountPoint, MAXIMUM_FILENAME_LENGTH,
                    L"\\DosDevices\\");
  if (wcslen(eventStart->MountPoint) == 1) {
    dokanControl.MountPoint[12] = towupper(eventStart->MountPoint[0]);
    dokanControl.MountPoint[13] = L':';
    dokanControl.MountPoint[14] = L'\0';
  } else {
    RtlStringCchCatW(dokanControl.MountPoint, MAXIMUM_FILENAME_LENGTH,
                     eventStart->MountPoint);
  }

  DDbgPrint("  Checking for MountPoint %ls \n", dokanControl.MountPoint);
  PMOUNT_ENTRY foundEntry = FindMountEntry(dokanGlobal, &dokanControl, FALSE);
  if (foundEntry != NULL) {
    DDbgPrint("  MountPoint exists already %ls \n", dokanControl.MountPoint);
    driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;
    driverInfo->Status = DOKAN_START_FAILED;
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);
    ExReleaseResourceLite(&dokanGlobal->Resource);
    KeLeaveCriticalRegion();
    ExFreePool(eventStart);
    ExFreePool(baseGuidString);
    return STATUS_SUCCESS;
  }

  baseGuid.Data2 = (USHORT)(dokanGlobal->MountId & 0xFFFF) ^ baseGuid.Data2;
  baseGuid.Data3 = (USHORT)(dokanGlobal->MountId >> 16) ^ baseGuid.Data3;

  status = RtlStringFromGUID(&baseGuid, &unicodeGuid);
  if (!NT_SUCCESS(status)) {
    ExReleaseResourceLite(&dokanGlobal->Resource);
    KeLeaveCriticalRegion();
    ExFreePool(eventStart);
    ExFreePool(baseGuidString);
    return status;
  }
  RtlZeroMemory(baseGuidString, 64 * sizeof(WCHAR));
  RtlStringCchCopyW(baseGuidString, 64,
                    unicodeGuid.Buffer);
  RtlFreeUnicodeString(&unicodeGuid);

  InterlockedIncrement((LONG *)&dokanGlobal->MountId);

  status = DokanCreateDiskDevice(
      DeviceObject->DriverObject, dokanGlobal->MountId, eventStart->MountPoint,
      eventStart->UNCName, baseGuidString, dokanGlobal, deviceType,
      deviceCharacteristics, mountGlobally, useMountManager, &dcb);

  if (!NT_SUCCESS(status)) {
    ExReleaseResourceLite(&dokanGlobal->Resource);
    KeLeaveCriticalRegion();
    ExFreePool(eventStart);
    ExFreePool(baseGuidString);
    return status;
  }

  dcb->FileLockInUserMode = fileLockUserMode;

  DDbgPrint("  MountId:%d\n", dcb->MountId);
  driverInfo->DeviceNumber = dokanGlobal->MountId;
  driverInfo->MountId = dokanGlobal->MountId;
  driverInfo->Status = DOKAN_MOUNTED;
  driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;

  // SymbolicName is
  // \\DosDevices\\Global\\Volume{D6CC17C5-1734-4085-BCE7-964F1E9F5DE9}
  // Finds the last '\' and copy into DeviceName.
  // DeviceName is \Volume{D6CC17C5-1734-4085-BCE7-964F1E9F5DE9}
  deviceNamePos = dcb->SymbolicLinkName->Length / sizeof(WCHAR) - 1;
  for (; dcb->SymbolicLinkName->Buffer[deviceNamePos] != L'\\'; --deviceNamePos)
    ;
  RtlStringCchCopyW(driverInfo->DeviceName,
                    sizeof(driverInfo->DeviceName) / sizeof(WCHAR),
                    &(dcb->SymbolicLinkName->Buffer[deviceNamePos]));

  // Set the irp timeout in milliseconds
  // If the IrpTimeout is 0, we assume that the value was not changed
  dcb->IrpTimeout = DOKAN_IRP_PENDING_TIMEOUT;
  if (eventStart->IrpTimeout > 0) {
    if (eventStart->IrpTimeout > DOKAN_IRP_PENDING_TIMEOUT_RESET_MAX) {
      eventStart->IrpTimeout = DOKAN_IRP_PENDING_TIMEOUT_RESET_MAX;
    }

    if (eventStart->IrpTimeout < DOKAN_IRP_PENDING_TIMEOUT) {
      eventStart->IrpTimeout = DOKAN_IRP_PENDING_TIMEOUT;
    }
    dcb->IrpTimeout = eventStart->IrpTimeout;
  }

  DDbgPrint("  DeviceName:%ws\n", driverInfo->DeviceName);

  dcb->UseAltStream = 0;
  if (eventStart->Flags & DOKAN_EVENT_ALTERNATIVE_STREAM_ON) {
    DDbgPrint("  ALT_STREAM_ON\n");
    dcb->UseAltStream = 1;
  }

  DokanStartEventNotificationThread(dcb);

  ExReleaseResourceLite(&dokanGlobal->Resource);
  KeLeaveCriticalRegion();

  IoVerifyVolume(dcb->DeviceObject, FALSE);

  Irp->IoStatus.Status = STATUS_SUCCESS;
  Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);

  ExFreePool(eventStart);
  ExFreePool(baseGuidString);

  DDbgPrint("<== DokanEventStart\n");

  return Irp->IoStatus.Status;
}
Beispiel #2
0
// start event dispatching
NTSTATUS
DokanEventStart(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
   )
{
	ULONG				outBufferLen;
	ULONG				inBufferLen;
	PVOID				buffer;
	PIO_STACK_LOCATION	irpSp;
	EVENT_START			eventStart;
	PEVENT_DRIVER_INFO	driverInfo;
	PDOKAN_GLOBAL		dokanGlobal;
	PDokanDCB			dcb;
	NTSTATUS			status;
	DEVICE_TYPE			deviceType;
	ULONG				deviceCharacteristics;
	WCHAR				baseGuidString[64];
	GUID				baseGuid = DOKAN_BASE_GUID;
	UNICODE_STRING		unicodeGuid;
	ULONG				deviceNamePos;
	

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

	dokanGlobal = DeviceObject->DeviceExtension;
	if (GetIdentifierType(dokanGlobal) != DGL) {
		return STATUS_INVALID_PARAMETER;
	}

	irpSp = IoGetCurrentIrpStackLocation(Irp);

	outBufferLen = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
	inBufferLen = irpSp->Parameters.DeviceIoControl.InputBufferLength;

	if (outBufferLen != sizeof(EVENT_DRIVER_INFO) ||
		inBufferLen != sizeof(EVENT_START)) {
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	RtlCopyMemory(&eventStart, Irp->AssociatedIrp.SystemBuffer, sizeof(EVENT_START));
	driverInfo = Irp->AssociatedIrp.SystemBuffer;

	if (eventStart.UserVersion != DOKAN_DRIVER_VERSION) {
		driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;
		driverInfo->Status = DOKAN_START_FAILED;
		Irp->IoStatus.Status = STATUS_SUCCESS;
		Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);
		return STATUS_SUCCESS;
	}

	deviceCharacteristics = FILE_DEVICE_IS_MOUNTED;

	switch (eventStart.DeviceType) {
	case DOKAN_DISK_FILE_SYSTEM:
		deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
		break;
	case DOKAN_NETWORK_FILE_SYSTEM:
		deviceType = FILE_DEVICE_NETWORK_FILE_SYSTEM;
		deviceCharacteristics |= FILE_REMOTE_DEVICE;
		break;
	default:
		DDbgPrint("  Unknown device type: %d\n", eventStart.DeviceType);
		deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
	}

	if (eventStart.Flags & DOKAN_EVENT_REMOVABLE) {
		DDbgPrint("  DeviceCharacteristics |= FILE_REMOVABLE_MEDIA\n");
		deviceCharacteristics |= FILE_REMOVABLE_MEDIA;
	}

	baseGuid.Data2 = (USHORT)(dokanGlobal->MountId & 0xFFFF) ^ baseGuid.Data2;
	baseGuid.Data3 = (USHORT)(dokanGlobal->MountId >> 16) ^ baseGuid.Data3;

	status = RtlStringFromGUID(&baseGuid, &unicodeGuid);
	if (!NT_SUCCESS(status)) {
		return status;
	}
	RtlZeroMemory(baseGuidString, sizeof(baseGuidString));
	RtlStringCchCopyW(baseGuidString, sizeof(baseGuidString) / sizeof(WCHAR), unicodeGuid.Buffer);
	RtlFreeUnicodeString(&unicodeGuid);

	InterlockedIncrement(&dokanGlobal->MountId);

	KeEnterCriticalRegion();
	ExAcquireResourceExclusiveLite(&dokanGlobal->Resource, TRUE);

	status = DokanCreateDiskDevice(
				DeviceObject->DriverObject,
				dokanGlobal->MountId,
				baseGuidString,
				dokanGlobal,
				deviceType,
				deviceCharacteristics,
				&dcb);

	if (!NT_SUCCESS(status)) {
		ExReleaseResourceLite(&dokanGlobal->Resource);
		KeLeaveCriticalRegion();
		return status;
	}

	DDbgPrint("  MountId:%d\n", dcb->MountId);
	driverInfo->DeviceNumber = dokanGlobal->MountId;
	driverInfo->MountId = dokanGlobal->MountId;
	driverInfo->Status = DOKAN_MOUNTED;
	driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;

	// SymbolicName is \\DosDevices\\Global\\Volume{D6CC17C5-1734-4085-BCE7-964F1E9F5DE9}
	// Finds the last '\' and copy into DeviceName.
	// DeviceName is \Volume{D6CC17C5-1734-4085-BCE7-964F1E9F5DE9}
	deviceNamePos = dcb->SymbolicLinkName->Length / sizeof(WCHAR) - 1;
	for (; dcb->SymbolicLinkName->Buffer[deviceNamePos] != L'\\'; --deviceNamePos)
		;
	RtlStringCchCopyW(driverInfo->DeviceName,
			sizeof(driverInfo->DeviceName) / sizeof(WCHAR),
			&(dcb->SymbolicLinkName->Buffer[deviceNamePos]));

	DDbgPrint("  DeviceName:%ws\n", driverInfo->DeviceName);
	DokanUpdateTimeout(&dcb->TickCount, DOKAN_KEEPALIVE_TIMEOUT);

	dcb->UseAltStream = 0;
	if (eventStart.Flags & DOKAN_EVENT_ALTERNATIVE_STREAM_ON) {
		DDbgPrint("  ALT_STREAM_ON\n");
		dcb->UseAltStream = 1;
	}
	dcb->UseKeepAlive = 0;
	if (eventStart.Flags & DOKAN_EVENT_KEEP_ALIVE_ON) {
		DDbgPrint("  KEEP_ALIVE_ON\n");
		dcb->UseKeepAlive = 1;
	}
	dcb->Mounted = 1;

	DokanStartEventNotificationThread(dcb);
	DokanStartCheckThread(dcb);

	ExReleaseResourceLite(&dokanGlobal->Resource);
	KeLeaveCriticalRegion();

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);

	DDbgPrint("<== DokanEventStart\n");

	return Irp->IoStatus.Status;
}
Beispiel #3
0
// start event dispatching
NTSTATUS
DokanEventStart(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
   )
{
	ULONG				outBufferLen;
	ULONG				inBufferLen;
	PVOID				buffer;
	PIO_STACK_LOCATION	irpSp;
	EVENT_START			eventStart;
	PEVENT_DRIVER_INFO	driverInfo;
	PDOKAN_GLOBAL		dokanGlobal;
	PDokanDCB			dcb;
	NTSTATUS			status;
	DEVICE_TYPE			deviceType;
	ULONG				deviceCharacteristics;

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

	dokanGlobal = DeviceObject->DeviceExtension;
	if (GetIdentifierType(dokanGlobal) != DGL) {
		return STATUS_INVALID_PARAMETER;
	}

	irpSp = IoGetCurrentIrpStackLocation(Irp);

	outBufferLen = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
	inBufferLen = irpSp->Parameters.DeviceIoControl.InputBufferLength;

	if (outBufferLen != sizeof(EVENT_DRIVER_INFO) ||
		inBufferLen != sizeof(EVENT_START)) {
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	RtlCopyMemory(&eventStart, Irp->AssociatedIrp.SystemBuffer, sizeof(EVENT_START));
	driverInfo = Irp->AssociatedIrp.SystemBuffer;

	if (eventStart.UserVersion != DOKAN_VERSION) {
		driverInfo->DriverVersion = DOKAN_VERSION;
		driverInfo->Status = DOKAN_START_FAILED;
		Irp->IoStatus.Status = STATUS_SUCCESS;
		Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);
		return STATUS_SUCCESS;
	}

	deviceCharacteristics = FILE_DEVICE_IS_MOUNTED;

	switch (eventStart.DeviceType) {
	case DOKAN_DISK_FILE_SYSTEM:
		deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
		break;
	case DOKAN_NETWORK_FILE_SYSTEM:
		deviceType = FILE_DEVICE_NETWORK_FILE_SYSTEM;
		deviceCharacteristics |= FILE_REMOTE_DEVICE;
		break;
	default:
		DDbgPrint("  Unknown device type: %d\n", eventStart.DeviceType);
		deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
	}

	if (eventStart.Flags & DOKAN_EVENT_REMOVABLE) {
		DDbgPrint("  DeviceCharacteristics |= FILE_REMOVABLE_MEDIA\n");
		deviceCharacteristics |= FILE_REMOVABLE_MEDIA;
	}

	KeEnterCriticalRegion();
	ExAcquireResourceExclusiveLite(&dokanGlobal->Resource, TRUE);

	status = DokanCreateDiskDevice(
				DeviceObject->DriverObject,
				dokanGlobal->MountId,
				dokanGlobal,
				deviceType,
				deviceCharacteristics,
				&dcb);

	if (!NT_SUCCESS(status)) {
		ExReleaseResourceLite(&dokanGlobal->Resource);
		KeLeaveCriticalRegion();
		return status;
	}

	DDbgPrint("  MountId:%d\n", dcb->MountId);
	driverInfo->DeviceNumber = dokanGlobal->MountId;
	driverInfo->MountId = dokanGlobal->MountId;
	driverInfo->Status = DOKAN_MOUNTED;
	driverInfo->DriverVersion = DOKAN_VERSION;
	dcb->Mounted = eventStart.DriveLetter;
	DokanUpdateTimeout(&dcb->TickCount, DOKAN_KEEPALIVE_TIMEOUT);

	dcb->UseAltStream = 0;
	if (eventStart.Flags & DOKAN_EVENT_ALTERNATIVE_STREAM_ON) {
		DDbgPrint("  ALT_STREAM_ON\n");
		dcb->UseAltStream = 1;
	}
	dcb->UseKeepAlive = 0;
	if (eventStart.Flags & DOKAN_EVENT_KEEP_ALIVE_ON) {
		DDbgPrint("  KEEP_ALIVE_ON\n");
		dcb->UseKeepAlive = 1;
	}
	DokanStartEventNotificationThread(dcb);
	DokanStartCheckThread(dcb);

	ExReleaseResourceLite(&dokanGlobal->Resource);
	KeLeaveCriticalRegion();

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);

	InterlockedIncrement(&dokanGlobal->MountId);

	DDbgPrint("<== DokanEventStart\n");

	return Irp->IoStatus.Status;
}