mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 02:10:07 +00:00
[NTOSKRNL]
Implement IoVolumeDeviceToDosName(), taking advantage of newcomer in the branch, MountMgr :-). This implementation will in fact don't work as MountMgr doesn't implement that part... But the day it's ready, this function will be! svn path=/branches/usb-bringup-trunk/; revision=55354
This commit is contained in:
parent
277b8f0871
commit
69e98d5671
|
@ -31,6 +31,7 @@
|
|||
#include <ntifs.h>
|
||||
#include <wdmguid.h>
|
||||
#include <arc/arc.h>
|
||||
#include <mountmgr.h>
|
||||
#undef NTHALAPI
|
||||
#define NTHALAPI __declspec(dllimport)
|
||||
#include <ndk/asm.h>
|
||||
|
|
|
@ -1269,15 +1269,165 @@ IoSetSystemPartition(IN PUNICODE_STRING VolumeNameString)
|
|||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IoVolumeDeviceToDosName(IN PVOID VolumeDeviceObject,
|
||||
OUT PUNICODE_STRING DosName)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
PIRP Irp;
|
||||
ULONG Length;
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
PFILE_OBJECT FileObject;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
UNICODE_STRING MountMgrDevice;
|
||||
MOUNTMGR_VOLUME_PATHS VolumePath;
|
||||
PMOUNTMGR_VOLUME_PATHS VolumePathPtr;
|
||||
/*
|
||||
* This variable with be required to query device name.
|
||||
* It's based on MOUNTDEV_NAME (mountmgr.h).
|
||||
* Doing it that way will prevent dyn memory allocation.
|
||||
* Device name won't be longer.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
USHORT NameLength;
|
||||
WCHAR DeviceName[256];
|
||||
} DeviceName;
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
/* First step, getting device name */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
|
||||
VolumeDeviceObject, NULL, 0,
|
||||
&DeviceName, sizeof(DeviceName),
|
||||
FALSE, &Event, &IoStatusBlock);
|
||||
if (!Irp)
|
||||
{
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Status = IoCallDriver(VolumeDeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Now that we have the device name, we can query the MountMgr
|
||||
* So, get its device object first.
|
||||
*/
|
||||
RtlInitUnicodeString(&MountMgrDevice, MOUNTMGR_DEVICE_NAME);
|
||||
Status = IoGetDeviceObjectPointer(&MountMgrDevice, FILE_READ_ATTRIBUTES,
|
||||
&FileObject, &DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Then, use the proper IOCTL to query the DOS name */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH,
|
||||
DeviceObject, &DeviceName, sizeof(DeviceName),
|
||||
&VolumePath, sizeof(VolumePath),
|
||||
FALSE, &Event, &IoStatusBlock);
|
||||
if (!Irp)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto DereferenceFO;
|
||||
}
|
||||
|
||||
Status = IoCallDriver(VolumeDeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
/* Only tolerated failure here is buffer too small, which is
|
||||
* expected.
|
||||
*/
|
||||
if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW)
|
||||
{
|
||||
goto DereferenceFO;
|
||||
}
|
||||
|
||||
/* Compute needed size to store DOS name.
|
||||
* Even if MOUNTMGR_VOLUME_PATHS allows bigger
|
||||
* name lengths than MAXUSHORT, we can't use
|
||||
* them, because we have to return this in an UNICODE_STRING
|
||||
* that stores length on USHORT.
|
||||
*/
|
||||
Length = VolumePath.MultiSzLength + sizeof(VolumePath);
|
||||
if (Length > MAXUSHORT)
|
||||
{
|
||||
Status = STATUS_INVALID_BUFFER_SIZE;
|
||||
goto DereferenceFO;
|
||||
}
|
||||
|
||||
/* Reallocate memory, even in case of success, because
|
||||
* that's the buffer that will be returned to caller
|
||||
*/
|
||||
VolumePathPtr = ExAllocatePoolWithTag(PagedPool, Length, 'D2d ');
|
||||
if (!VolumePathPtr)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto DereferenceFO;
|
||||
}
|
||||
|
||||
/* Requery DOS path with proper size */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH,
|
||||
DeviceObject, &DeviceName, sizeof(DeviceName),
|
||||
VolumePathPtr, Length,
|
||||
FALSE, &Event, &IoStatusBlock);
|
||||
if (!Irp)
|
||||
{
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
goto ReleaseMemory;
|
||||
}
|
||||
|
||||
Status = IoCallDriver(VolumeDeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
goto ReleaseMemory;
|
||||
}
|
||||
|
||||
/* Set output string */
|
||||
DosName->Length = VolumePathPtr->MultiSzLength;
|
||||
DosName->MaximumLength = VolumePathPtr->MultiSzLength + sizeof(UNICODE_NULL);
|
||||
/* Our MOUNTMGR_VOLUME_PATHS will be used as output buffer */
|
||||
DosName->Buffer = (PWSTR)VolumePathPtr;
|
||||
/* Move name at the begin, RtlMoveMemory is OK with overlapping */
|
||||
RtlMoveMemory(DosName->Buffer, VolumePathPtr->MultiSz, VolumePathPtr->MultiSzLength);
|
||||
DosName->Buffer[DosName->Length / sizeof(WCHAR)] = UNICODE_NULL;
|
||||
|
||||
/* DON'T release buffer, just dereference FO, and return success */
|
||||
Status = STATUS_SUCCESS;
|
||||
goto DereferenceFO;
|
||||
|
||||
ReleaseMemory:
|
||||
ExFreePoolWithTag(VolumePathPtr, 'D2d ');
|
||||
|
||||
DereferenceFO:
|
||||
ObDereferenceObject(FileObject);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue