Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
5.0 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. dev2dos.c
  5. Abstract:
  6. This module implements the device object to DOS name routine.
  7. Author:
  8. Norbert Kusters (norbertk) 21-Oct-1998
  9. Nar Ganapathy (narg) 1-April-2000 - Moved the code to IO manager
  10. Environment:
  11. Kernel Mode.
  12. Revision History:
  13. --*/
  14. #include <iomgr.h>
  15. #include <mountdev.h>
  16. #ifdef POOL_TAGGING
  17. #undef ExAllocatePool
  18. #undef ExAllocatePoolWithQuota
  19. #define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,' d2D')
  20. #define ExAllocatePoolWithQuota(a,b) ExAllocatePoolWithQuotaTag(a,b,' d2D')
  21. #endif
  22. NTSTATUS
  23. IoVolumeDeviceToDosName(
  24. IN PVOID VolumeDeviceObject,
  25. OUT PUNICODE_STRING DosName
  26. );
  27. #if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
  28. #pragma alloc_text(PAGE,IoVolumeDeviceToDosName)
  29. #pragma alloc_text(PAGE,IopQueryNetworkUncName)
  30. #endif
  31. NTSTATUS
  32. IoVolumeDeviceToDosName(
  33. IN PVOID VolumeDeviceObject,
  34. OUT PUNICODE_STRING DosName
  35. )
  36. /*++
  37. Routine Description:
  38. This routine returns a valid DOS path for the given device object.
  39. This caller of this routine must call ExFreePool on DosName->Buffer
  40. when it is no longer needed.
  41. Arguments:
  42. VolumeDeviceObject - Supplies the volume device object.
  43. DosName - Returns the DOS name for the volume
  44. Return Value:
  45. NTSTATUS
  46. --*/
  47. {
  48. PDEVICE_OBJECT volumeDeviceObject = VolumeDeviceObject;
  49. PMOUNTDEV_NAME name;
  50. CHAR output[512], out[sizeof(MOUNTMGR_VOLUME_PATHS)];
  51. KEVENT event;
  52. PIRP irp;
  53. IO_STATUS_BLOCK ioStatus;
  54. NTSTATUS status;
  55. UNICODE_STRING mountmgrName;
  56. PFILE_OBJECT fileObject;
  57. PDEVICE_OBJECT deviceObject;
  58. PMOUNTMGR_VOLUME_PATHS paths;
  59. ULONG len;
  60. //
  61. // We are using a stack event and so must be at passive.
  62. //
  63. ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
  64. name = (PMOUNTDEV_NAME) output;
  65. KeInitializeEvent(&event, NotificationEvent, FALSE);
  66. irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
  67. volumeDeviceObject, NULL, 0, name, 512,
  68. FALSE, &event, &ioStatus);
  69. if (!irp) {
  70. return STATUS_INSUFFICIENT_RESOURCES;
  71. }
  72. status = IoCallDriver(volumeDeviceObject, irp);
  73. if (status == STATUS_PENDING) {
  74. KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
  75. status = ioStatus.Status;
  76. }
  77. if (!NT_SUCCESS(status)) {
  78. return status;
  79. }
  80. RtlInitUnicodeString(&mountmgrName, MOUNTMGR_DEVICE_NAME);
  81. status = IoGetDeviceObjectPointer(&mountmgrName, FILE_READ_ATTRIBUTES,
  82. &fileObject, &deviceObject);
  83. if (!NT_SUCCESS(status)) {
  84. return status;
  85. }
  86. paths = (PMOUNTMGR_VOLUME_PATHS) out;
  87. KeInitializeEvent(&event, NotificationEvent, FALSE);
  88. irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH,
  89. deviceObject, name, 512,
  90. paths, sizeof(MOUNTMGR_VOLUME_PATHS),
  91. FALSE, &event, &ioStatus);
  92. if (!irp) {
  93. ObDereferenceObject(fileObject);
  94. return STATUS_INSUFFICIENT_RESOURCES;
  95. }
  96. status = IoCallDriver(deviceObject, irp);
  97. if (status == STATUS_PENDING) {
  98. KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
  99. status = ioStatus.Status;
  100. }
  101. if (!NT_SUCCESS(status) && status != STATUS_BUFFER_OVERFLOW) {
  102. ObDereferenceObject(fileObject);
  103. return status;
  104. }
  105. len = sizeof(MOUNTMGR_VOLUME_PATHS) + paths->MultiSzLength;
  106. paths = ExAllocatePool(PagedPool, len);
  107. if (!paths) {
  108. ObDereferenceObject(fileObject);
  109. return STATUS_INSUFFICIENT_RESOURCES;
  110. }
  111. KeInitializeEvent(&event, NotificationEvent, FALSE);
  112. irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH,
  113. deviceObject, name, 512,
  114. paths, len, FALSE, &event, &ioStatus);
  115. if (!irp) {
  116. ExFreePool(paths);
  117. ObDereferenceObject(fileObject);
  118. return STATUS_INSUFFICIENT_RESOURCES;
  119. }
  120. status = IoCallDriver(deviceObject, irp);
  121. if (status == STATUS_PENDING) {
  122. KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
  123. status = ioStatus.Status;
  124. }
  125. if (!NT_SUCCESS(status)) {
  126. ExFreePool(paths);
  127. ObDereferenceObject(fileObject);
  128. return status;
  129. }
  130. DosName->Length = (USHORT) paths->MultiSzLength - 2*sizeof(WCHAR);
  131. DosName->MaximumLength = DosName->Length + sizeof(WCHAR);
  132. DosName->Buffer = (PWCHAR) paths;
  133. RtlCopyMemory(paths, paths->MultiSz, DosName->Length);
  134. DosName->Buffer[DosName->Length/sizeof(WCHAR)] = 0;
  135. ObDereferenceObject(fileObject);
  136. return STATUS_SUCCESS;
  137. }