182 lines
5 KiB
C
182 lines
5 KiB
C
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dev2dos.c
|
|
|
|
Abstract:
|
|
|
|
This module implements the device object to DOS name routine.
|
|
|
|
Author:
|
|
|
|
Norbert Kusters (norbertk) 21-Oct-1998
|
|
Nar Ganapathy (narg) 1-April-2000 - Moved the code to IO manager
|
|
|
|
Environment:
|
|
|
|
Kernel Mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <iomgr.h>
|
|
#include <mountdev.h>
|
|
|
|
#ifdef POOL_TAGGING
|
|
#undef ExAllocatePool
|
|
#undef ExAllocatePoolWithQuota
|
|
#define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,' d2D')
|
|
#define ExAllocatePoolWithQuota(a,b) ExAllocatePoolWithQuotaTag(a,b,' d2D')
|
|
#endif
|
|
|
|
NTSTATUS
|
|
IoVolumeDeviceToDosName(
|
|
IN PVOID VolumeDeviceObject,
|
|
OUT PUNICODE_STRING DosName
|
|
);
|
|
|
|
#if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME)
|
|
#pragma alloc_text(PAGE,IoVolumeDeviceToDosName)
|
|
#pragma alloc_text(PAGE,IopQueryNetworkUncName)
|
|
#endif
|
|
|
|
NTSTATUS
|
|
IoVolumeDeviceToDosName(
|
|
IN PVOID VolumeDeviceObject,
|
|
OUT PUNICODE_STRING DosName
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine returns a valid DOS path for the given device object.
|
|
This caller of this routine must call ExFreePool on DosName->Buffer
|
|
when it is no longer needed.
|
|
|
|
Arguments:
|
|
|
|
VolumeDeviceObject - Supplies the volume device object.
|
|
|
|
DosName - Returns the DOS name for the volume
|
|
|
|
Return Value:
|
|
|
|
NTSTATUS
|
|
|
|
--*/
|
|
|
|
{
|
|
PDEVICE_OBJECT volumeDeviceObject = VolumeDeviceObject;
|
|
PMOUNTDEV_NAME name;
|
|
CHAR output[512], out[sizeof(MOUNTMGR_VOLUME_PATHS)];
|
|
KEVENT event;
|
|
PIRP irp;
|
|
IO_STATUS_BLOCK ioStatus;
|
|
NTSTATUS status;
|
|
UNICODE_STRING mountmgrName;
|
|
PFILE_OBJECT fileObject;
|
|
PDEVICE_OBJECT deviceObject;
|
|
PMOUNTMGR_VOLUME_PATHS paths;
|
|
ULONG len;
|
|
|
|
//
|
|
// We are using a stack event and so must be at passive.
|
|
//
|
|
|
|
ASSERT( KeGetCurrentIrql() == PASSIVE_LEVEL );
|
|
|
|
name = (PMOUNTDEV_NAME) output;
|
|
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
|
irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
|
|
volumeDeviceObject, NULL, 0, name, 512,
|
|
FALSE, &event, &ioStatus);
|
|
if (!irp) {
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
status = IoCallDriver(volumeDeviceObject, irp);
|
|
if (status == STATUS_PENDING) {
|
|
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
|
|
status = ioStatus.Status;
|
|
}
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
RtlInitUnicodeString(&mountmgrName, MOUNTMGR_DEVICE_NAME);
|
|
status = IoGetDeviceObjectPointer(&mountmgrName, FILE_READ_ATTRIBUTES,
|
|
&fileObject, &deviceObject);
|
|
if (!NT_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
|
|
paths = (PMOUNTMGR_VOLUME_PATHS) out;
|
|
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
|
irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH,
|
|
deviceObject, name, 512,
|
|
paths, sizeof(MOUNTMGR_VOLUME_PATHS),
|
|
FALSE, &event, &ioStatus);
|
|
if (!irp) {
|
|
ObDereferenceObject(fileObject);
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
status = IoCallDriver(deviceObject, irp);
|
|
if (status == STATUS_PENDING) {
|
|
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
|
|
status = ioStatus.Status;
|
|
}
|
|
|
|
if (!NT_SUCCESS(status) && status != STATUS_BUFFER_OVERFLOW) {
|
|
ObDereferenceObject(fileObject);
|
|
return status;
|
|
}
|
|
|
|
len = sizeof(MOUNTMGR_VOLUME_PATHS) + paths->MultiSzLength;
|
|
paths = ExAllocatePool(PagedPool, len);
|
|
if (!paths) {
|
|
ObDereferenceObject(fileObject);
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
|
irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH,
|
|
deviceObject, name, 512,
|
|
paths, len, FALSE, &event, &ioStatus);
|
|
if (!irp) {
|
|
ExFreePool(paths);
|
|
ObDereferenceObject(fileObject);
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
status = IoCallDriver(deviceObject, irp);
|
|
if (status == STATUS_PENDING) {
|
|
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
|
|
status = ioStatus.Status;
|
|
}
|
|
|
|
if (!NT_SUCCESS(status)) {
|
|
ExFreePool(paths);
|
|
ObDereferenceObject(fileObject);
|
|
return status;
|
|
}
|
|
|
|
DosName->Length = (USHORT) paths->MultiSzLength - 2*sizeof(WCHAR);
|
|
DosName->MaximumLength = DosName->Length + sizeof(WCHAR);
|
|
DosName->Buffer = (PWCHAR) paths;
|
|
|
|
RtlCopyMemory(paths, paths->MultiSz, DosName->Length);
|
|
DosName->Buffer[DosName->Length/sizeof(WCHAR)] = 0;
|
|
|
|
ObDereferenceObject(fileObject);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|