mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[MOUNTMGR] Introduce MountMgrSendSyncDeviceIoCtl() to replace repeated code (#6960)
See https://www.osr.com/blog/2018/02/14/beware-iobuilddeviceiocontrolrequest/ for some details about IRQL requirements.
This commit is contained in:
parent
50271949e7
commit
ab0e04c81d
5 changed files with 234 additions and 448 deletions
|
@ -330,11 +330,8 @@ MountMgrCheckUnprocessedVolumes(IN PDEVICE_EXTENSION DeviceExtension,
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
IsFtVolume(IN PUNICODE_STRING SymbolicName)
|
IsFtVolume(IN PUNICODE_STRING SymbolicName)
|
||||||
{
|
{
|
||||||
PIRP Irp;
|
|
||||||
KEVENT Event;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
PARTITION_INFORMATION PartitionInfo;
|
PARTITION_INFORMATION PartitionInfo;
|
||||||
PDEVICE_OBJECT DeviceObject, FileDeviceObject;
|
PDEVICE_OBJECT DeviceObject, FileDeviceObject;
|
||||||
|
|
||||||
|
@ -344,9 +341,7 @@ IsFtVolume(IN PUNICODE_STRING SymbolicName)
|
||||||
&FileObject,
|
&FileObject,
|
||||||
&DeviceObject);
|
&DeviceObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
/* Get attached device */
|
/* Get attached device */
|
||||||
FileDeviceObject = FileObject->DeviceObject;
|
FileDeviceObject = FileObject->DeviceObject;
|
||||||
|
@ -363,34 +358,17 @@ IsFtVolume(IN PUNICODE_STRING SymbolicName)
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
/* Get partition information */
|
/* Get partition information */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_DISK_GET_PARTITION_INFO,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO,
|
DeviceObject,
|
||||||
DeviceObject,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
&PartitionInfo,
|
||||||
&PartitionInfo,
|
sizeof(PartitionInfo),
|
||||||
sizeof(PartitionInfo),
|
NULL);
|
||||||
FALSE,
|
|
||||||
&Event,
|
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(DeviceObject);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
Status = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObDereferenceObject(DeviceObject);
|
ObDereferenceObject(DeviceObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if this is a FT volume */
|
/* Check if this is a FT volume */
|
||||||
return IsFTPartition(PartitionInfo.PartitionType);
|
return IsFTPartition(PartitionInfo.PartitionType);
|
||||||
|
|
|
@ -179,6 +179,17 @@ extern LONG Unloading;
|
||||||
CODE_SEG("INIT")
|
CODE_SEG("INIT")
|
||||||
DRIVER_INITIALIZE DriverEntry;
|
DRIVER_INITIALIZE DriverEntry;
|
||||||
|
|
||||||
|
_IRQL_requires_(PASSIVE_LEVEL)
|
||||||
|
NTSTATUS
|
||||||
|
MountMgrSendSyncDeviceIoCtl(
|
||||||
|
_In_ ULONG IoControlCode,
|
||||||
|
_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer,
|
||||||
|
_In_ ULONG InputBufferLength,
|
||||||
|
_Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer,
|
||||||
|
_In_ ULONG OutputBufferLength,
|
||||||
|
_In_opt_ PFILE_OBJECT FileObject);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MountMgrCancel(
|
MountMgrCancel(
|
||||||
|
|
|
@ -39,6 +39,90 @@ LONG Unloading;
|
||||||
static const WCHAR Cunc[] = L"\\??\\C:";
|
static const WCHAR Cunc[] = L"\\??\\C:";
|
||||||
#define Cunc_LETTER_POSITION 4
|
#define Cunc_LETTER_POSITION 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
* Sends a synchronous IOCTL to the specified device object.
|
||||||
|
*
|
||||||
|
* @param[in] IoControlCode
|
||||||
|
* The IOCTL to send to the device.
|
||||||
|
*
|
||||||
|
* @param[in] DeviceObject
|
||||||
|
* Pointer to the device object that will handle the IOCTL.
|
||||||
|
*
|
||||||
|
* @param[in] InputBuffer
|
||||||
|
* Optional pointer to a buffer containing input data for the IOCTL.
|
||||||
|
* When specified, the buffer should be at least of InputBufferLength size.
|
||||||
|
*
|
||||||
|
* @param[in] InputBufferLength
|
||||||
|
* Size in bytes, of the buffer pointed by InputBuffer.
|
||||||
|
*
|
||||||
|
* @param[out] OutputBuffer
|
||||||
|
* Optional pointer to a buffer that will receive output data from the IOCTL.
|
||||||
|
* When specified, the buffer should be at least of OutputBufferLength size.
|
||||||
|
*
|
||||||
|
* @param[in] OutputBufferLength
|
||||||
|
* Size in bytes, of the buffer pointed by OutputBuffer.
|
||||||
|
*
|
||||||
|
* @param[in] FileObject
|
||||||
|
* Optional pointer to a file object that may be necessary for the IOCTL.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* An NTSTATUS code indicating success or failure of this function.
|
||||||
|
*
|
||||||
|
* @note
|
||||||
|
* Must be called at PASSIVE_LEVEL with all APCs enabled.
|
||||||
|
**/
|
||||||
|
_IRQL_requires_(PASSIVE_LEVEL)
|
||||||
|
NTSTATUS
|
||||||
|
MountMgrSendSyncDeviceIoCtl(
|
||||||
|
_In_ ULONG IoControlCode,
|
||||||
|
_In_ PDEVICE_OBJECT DeviceObject,
|
||||||
|
_In_reads_bytes_opt_(InputBufferLength) PVOID InputBuffer,
|
||||||
|
_In_ ULONG InputBufferLength,
|
||||||
|
_Out_writes_bytes_opt_(OutputBufferLength) PVOID OutputBuffer,
|
||||||
|
_In_ ULONG OutputBufferLength,
|
||||||
|
_In_opt_ PFILE_OBJECT FileObject)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
KEVENT Event;
|
||||||
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
PIRP Irp;
|
||||||
|
|
||||||
|
/* We must be at passive level as we are using an on-stack event, and
|
||||||
|
* APCs must be enabled for allowing the Special Kernel APC queued by
|
||||||
|
* the IO Manager to run for completing the IRP */
|
||||||
|
ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
|
||||||
|
ASSERT(!KeAreAllApcsDisabled());
|
||||||
|
|
||||||
|
/* Initialize the on-stack notification event and build the threaded IRP */
|
||||||
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
Irp = IoBuildDeviceIoControlRequest(IoControlCode,
|
||||||
|
DeviceObject,
|
||||||
|
InputBuffer,
|
||||||
|
InputBufferLength,
|
||||||
|
OutputBuffer,
|
||||||
|
OutputBufferLength,
|
||||||
|
FALSE,
|
||||||
|
&Event,
|
||||||
|
&IoStatusBlock);
|
||||||
|
if (!Irp)
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
|
/* Set up the FileObject for the IOCTL if required */
|
||||||
|
if (FileObject)
|
||||||
|
IoGetNextIrpStackLocation(Irp)->FileObject = FileObject;
|
||||||
|
|
||||||
|
/* Finally, call the driver and wait for IRP completion if necessary */
|
||||||
|
Status = IoCallDriver(DeviceObject, Irp);
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
Status = IoStatusBlock.Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -196,17 +280,13 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
IN OUT LPGUID StableGuid OPTIONAL,
|
IN OUT LPGUID StableGuid OPTIONAL,
|
||||||
OUT PBOOLEAN Valid OPTIONAL)
|
OUT PBOOLEAN Valid OPTIONAL)
|
||||||
{
|
{
|
||||||
PIRP Irp;
|
NTSTATUS Status;
|
||||||
USHORT Size;
|
USHORT Size;
|
||||||
KEVENT Event;
|
|
||||||
BOOLEAN IsRemovable;
|
BOOLEAN IsRemovable;
|
||||||
PMOUNTDEV_NAME Name;
|
PMOUNTDEV_NAME Name;
|
||||||
PMOUNTDEV_UNIQUE_ID Id;
|
PMOUNTDEV_UNIQUE_ID Id;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PIO_STACK_LOCATION Stack;
|
|
||||||
NTSTATUS Status, IntStatus;
|
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
PARTITION_INFORMATION_EX PartitionInfo;
|
PARTITION_INFORMATION_EX PartitionInfo;
|
||||||
STORAGE_DEVICE_NUMBER StorageDeviceNumber;
|
STORAGE_DEVICE_NUMBER StorageDeviceNumber;
|
||||||
VOLUME_GET_GPT_ATTRIBUTES_INFORMATION GptAttributes;
|
VOLUME_GET_GPT_ATTRIBUTES_INFORMATION GptAttributes;
|
||||||
|
@ -247,30 +327,21 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
if (!IsRemovable)
|
if (!IsRemovable)
|
||||||
{
|
{
|
||||||
/* Query the GPT attributes */
|
/* Query the GPT attributes */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_VOLUME_GET_GPT_ATTRIBUTES,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_VOLUME_GET_GPT_ATTRIBUTES,
|
DeviceObject,
|
||||||
DeviceObject,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
&GptAttributes,
|
||||||
&GptAttributes,
|
sizeof(GptAttributes),
|
||||||
sizeof(GptAttributes),
|
NULL);
|
||||||
FALSE,
|
#if 0
|
||||||
&Event,
|
if (Status == STATUS_INSUFFICIENT_RESOURCES)
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
{
|
||||||
ObDereferenceObject(DeviceObject);
|
ObDereferenceObject(DeviceObject);
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return Status;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
Status = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In case of failure, don't fail, that's no vital */
|
/* In case of failure, don't fail, that's no vital */
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -293,30 +364,21 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
if (!IsRemovable)
|
if (!IsRemovable)
|
||||||
{
|
{
|
||||||
/* Query partitions information */
|
/* Query partitions information */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_DISK_GET_PARTITION_INFO_EX,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO_EX,
|
DeviceObject,
|
||||||
DeviceObject,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
&PartitionInfo,
|
||||||
&PartitionInfo,
|
sizeof(PartitionInfo),
|
||||||
sizeof(PartitionInfo),
|
NULL);
|
||||||
FALSE,
|
#if 0
|
||||||
&Event,
|
if (Status == STATUS_INSUFFICIENT_RESOURCES)
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
{
|
||||||
ObDereferenceObject(DeviceObject);
|
ObDereferenceObject(DeviceObject);
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return Status;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
Status = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Once again here, failure isn't major */
|
/* Once again here, failure isn't major */
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -332,38 +394,25 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
/* It looks correct, ensure it is & query device number */
|
/* It looks correct, ensure it is & query device number */
|
||||||
if (*Valid)
|
if (*Valid)
|
||||||
{
|
{
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_STORAGE_GET_DEVICE_NUMBER,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_STORAGE_GET_DEVICE_NUMBER,
|
DeviceObject,
|
||||||
DeviceObject,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
&StorageDeviceNumber,
|
||||||
&StorageDeviceNumber,
|
sizeof(StorageDeviceNumber),
|
||||||
sizeof(StorageDeviceNumber),
|
NULL);
|
||||||
FALSE,
|
#if 0
|
||||||
&Event,
|
if (Status == STATUS_INSUFFICIENT_RESOURCES)
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
{
|
||||||
ObDereferenceObject(DeviceObject);
|
ObDereferenceObject(DeviceObject);
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return Status;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
Status = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
*Valid = FALSE;
|
*Valid = FALSE;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -381,35 +430,14 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Query device name */
|
/* Query device name */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
|
DeviceObject,
|
||||||
DeviceObject,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
Name,
|
||||||
Name,
|
sizeof(MOUNTDEV_NAME),
|
||||||
sizeof(MOUNTDEV_NAME),
|
FileObject);
|
||||||
FALSE,
|
/* Retry with appropriate length */
|
||||||
&Event,
|
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
FreePool(Name);
|
|
||||||
ObDereferenceObject(DeviceObject);
|
|
||||||
ObDereferenceObject(FileObject);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack = IoGetNextIrpStackLocation(Irp);
|
|
||||||
Stack->FileObject = FileObject;
|
|
||||||
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
Status = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now, we've got the correct length */
|
|
||||||
if (Status == STATUS_BUFFER_OVERFLOW)
|
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||||
{
|
{
|
||||||
Size = Name->NameLength + sizeof(MOUNTDEV_NAME);
|
Size = Name->NameLength + sizeof(MOUNTDEV_NAME);
|
||||||
|
@ -426,33 +454,13 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And query name (for real that time) */
|
/* And query name (for real that time) */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
|
DeviceObject,
|
||||||
DeviceObject,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
Name,
|
||||||
Name,
|
Size,
|
||||||
Size,
|
FileObject);
|
||||||
FALSE,
|
|
||||||
&Event,
|
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
FreePool(Name);
|
|
||||||
ObDereferenceObject(DeviceObject);
|
|
||||||
ObDereferenceObject(FileObject);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack = IoGetNextIrpStackLocation(Irp);
|
|
||||||
Stack->FileObject = FileObject;
|
|
||||||
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
Status = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
|
@ -495,34 +503,13 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Query unique ID length */
|
/* Query unique ID length */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_UNIQUE_ID,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_UNIQUE_ID,
|
DeviceObject,
|
||||||
DeviceObject,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
Id,
|
||||||
Id,
|
sizeof(MOUNTDEV_UNIQUE_ID),
|
||||||
sizeof(MOUNTDEV_UNIQUE_ID),
|
FileObject);
|
||||||
FALSE,
|
|
||||||
&Event,
|
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
FreePool(Id);
|
|
||||||
ObDereferenceObject(DeviceObject);
|
|
||||||
ObDereferenceObject(FileObject);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack = IoGetNextIrpStackLocation(Irp);
|
|
||||||
Stack->FileObject = FileObject;
|
|
||||||
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
Status = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Retry with appropriate length */
|
/* Retry with appropriate length */
|
||||||
if (Status == STATUS_BUFFER_OVERFLOW)
|
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||||
{
|
{
|
||||||
|
@ -540,33 +527,13 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Query unique ID */
|
/* Query unique ID */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_UNIQUE_ID,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_UNIQUE_ID,
|
DeviceObject,
|
||||||
DeviceObject,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
Id,
|
||||||
Id,
|
Size,
|
||||||
Size,
|
FileObject);
|
||||||
FALSE,
|
|
||||||
&Event,
|
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
FreePool(Id);
|
|
||||||
ObDereferenceObject(DeviceObject);
|
|
||||||
ObDereferenceObject(FileObject);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack = IoGetNextIrpStackLocation(Irp);
|
|
||||||
Stack->FileObject = FileObject;
|
|
||||||
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
Status = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hands back unique ID */
|
/* Hands back unique ID */
|
||||||
|
@ -579,13 +546,10 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
/* In case of failure, also free the rest */
|
/* In case of failure, also free the rest */
|
||||||
FreePool(Id);
|
FreePool(Id);
|
||||||
if (DeviceName->Length)
|
if (DeviceName->Length)
|
||||||
{
|
|
||||||
FreePool(DeviceName->Buffer);
|
FreePool(DeviceName->Buffer);
|
||||||
}
|
|
||||||
|
|
||||||
ObDereferenceObject(DeviceObject);
|
ObDereferenceObject(DeviceObject);
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -594,33 +558,14 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
||||||
if (HasGuid)
|
if (HasGuid)
|
||||||
{
|
{
|
||||||
/* Query device stable GUID */
|
/* Query device stable GUID */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
NTSTATUS IntStatus;
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_STABLE_GUID,
|
IntStatus = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_STABLE_GUID,
|
||||||
DeviceObject,
|
DeviceObject,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
StableGuid,
|
StableGuid,
|
||||||
sizeof(GUID),
|
sizeof(GUID),
|
||||||
FALSE,
|
FileObject);
|
||||||
&Event,
|
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
ObDereferenceObject(DeviceObject);
|
|
||||||
ObDereferenceObject(FileObject);
|
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack = IoGetNextIrpStackLocation(Irp);
|
|
||||||
Stack->FileObject = FileObject;
|
|
||||||
|
|
||||||
IntStatus = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (IntStatus == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
IntStatus = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
*HasGuid = NT_SUCCESS(IntStatus);
|
*HasGuid = NT_SUCCESS(IntStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,7 +736,7 @@ MountMgrFreeSavedLink(IN PSAVED_LINK_INFORMATION SavedLinkInformation)
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
MountMgrUnload(IN struct _DRIVER_OBJECT *DriverObject)
|
MountMgrUnload(IN PDRIVER_OBJECT DriverObject)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY NextEntry;
|
PLIST_ENTRY NextEntry;
|
||||||
PUNIQUE_ID_WORK_ITEM WorkItem;
|
PUNIQUE_ID_WORK_ITEM WorkItem;
|
||||||
|
|
|
@ -37,13 +37,9 @@
|
||||||
VOID
|
VOID
|
||||||
SendOnlineNotification(IN PUNICODE_STRING SymbolicName)
|
SendOnlineNotification(IN PUNICODE_STRING SymbolicName)
|
||||||
{
|
{
|
||||||
PIRP Irp;
|
|
||||||
KEVENT Event;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PIO_STACK_LOCATION Stack;
|
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
|
|
||||||
/* Get device object */
|
/* Get device object */
|
||||||
Status = IoGetDeviceObjectPointer(SymbolicName,
|
Status = IoGetDeviceObjectPointer(SymbolicName,
|
||||||
|
@ -51,40 +47,21 @@ SendOnlineNotification(IN PUNICODE_STRING SymbolicName)
|
||||||
&FileObject,
|
&FileObject,
|
||||||
&DeviceObject);
|
&DeviceObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* And attached device object */
|
/* And attached device object */
|
||||||
DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
|
DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
|
||||||
|
|
||||||
/* And send VOLUME_ONLINE */
|
/* And send VOLUME_ONLINE */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_VOLUME_ONLINE,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_VOLUME_ONLINE,
|
DeviceObject,
|
||||||
DeviceObject,
|
NULL, 0,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
NULL, 0,
|
FileObject);
|
||||||
FALSE,
|
UNREFERENCED_PARAMETER(Status);
|
||||||
&Event,
|
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
goto Cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack = IoGetNextIrpStackLocation(Irp);
|
|
||||||
Stack->FileObject = FileObject;
|
|
||||||
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Cleanup:
|
|
||||||
ObDereferenceObject(DeviceObject);
|
ObDereferenceObject(DeviceObject);
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -168,15 +168,11 @@ GlobalDeleteSymbolicLink(IN PUNICODE_STRING DosName)
|
||||||
VOID
|
VOID
|
||||||
SendLinkCreated(IN PUNICODE_STRING SymbolicName)
|
SendLinkCreated(IN PUNICODE_STRING SymbolicName)
|
||||||
{
|
{
|
||||||
PIRP Irp;
|
|
||||||
KEVENT Event;
|
|
||||||
ULONG NameSize;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
ULONG NameSize;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PIO_STACK_LOCATION Stack;
|
|
||||||
PMOUNTDEV_NAME Name = NULL;
|
PMOUNTDEV_NAME Name = NULL;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
|
|
||||||
/* Get the device associated with the name */
|
/* Get the device associated with the name */
|
||||||
Status = IoGetDeviceObjectPointer(SymbolicName,
|
Status = IoGetDeviceObjectPointer(SymbolicName,
|
||||||
|
@ -184,22 +180,18 @@ SendLinkCreated(IN PUNICODE_STRING SymbolicName)
|
||||||
&FileObject,
|
&FileObject,
|
||||||
&DeviceObject);
|
&DeviceObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* Get attached device (will notify it) */
|
/* Get attached device (will notify it) */
|
||||||
DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
|
DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
|
||||||
|
|
||||||
/* NameSize is the size of the whole MOUNTDEV_NAME struct */
|
/* NameSize is the size of the whole MOUNTDEV_NAME structure */
|
||||||
NameSize = sizeof(USHORT) + SymbolicName->Length;
|
NameSize = sizeof(USHORT) + SymbolicName->Length;
|
||||||
Name = AllocatePool(NameSize);
|
Name = AllocatePool(NameSize);
|
||||||
if (!Name)
|
if (!Name)
|
||||||
{
|
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize struct */
|
/* Initialize structure */
|
||||||
Name->NameLength = SymbolicName->Length;
|
Name->NameLength = SymbolicName->Length;
|
||||||
RtlCopyMemory(Name->Name, SymbolicName->Buffer, SymbolicName->Length);
|
RtlCopyMemory(Name->Name, SymbolicName->Buffer, SymbolicName->Length);
|
||||||
|
|
||||||
|
@ -207,61 +199,30 @@ SendLinkCreated(IN PUNICODE_STRING SymbolicName)
|
||||||
* (with limited access) first. If this fails, the called driver may be
|
* (with limited access) first. If this fails, the called driver may be
|
||||||
* for an older NT version, and so, we send again the notification using
|
* for an older NT version, and so, we send again the notification using
|
||||||
* the old (Windows 2000) IOCTL definition (with any access). */
|
* the old (Windows 2000) IOCTL definition (with any access). */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_LINK_CREATED,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_LINK_CREATED,
|
DeviceObject,
|
||||||
DeviceObject,
|
Name,
|
||||||
Name,
|
NameSize,
|
||||||
NameSize,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
FileObject);
|
||||||
FALSE,
|
|
||||||
&Event,
|
|
||||||
&IoStatusBlock);
|
|
||||||
/* This one can fail, no one matters */
|
/* This one can fail, no one matters */
|
||||||
if (Irp)
|
UNREFERENCED_PARAMETER(Status);
|
||||||
{
|
|
||||||
Stack = IoGetNextIrpStackLocation(Irp);
|
|
||||||
Stack->FileObject = FileObject;
|
|
||||||
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if (NTDDI_VERSION >= NTDDI_WS03)
|
#if (NTDDI_VERSION >= NTDDI_WS03)
|
||||||
/* Then, second one */
|
/* Then, second one */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_LINK_CREATED_UNSECURE_DEPRECATED,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_LINK_CREATED_UNSECURE_DEPRECATED,
|
DeviceObject,
|
||||||
DeviceObject,
|
Name,
|
||||||
Name,
|
NameSize,
|
||||||
NameSize,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
FileObject);
|
||||||
FALSE,
|
UNREFERENCED_PARAMETER(Status);
|
||||||
&Event,
|
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
goto Cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack = IoGetNextIrpStackLocation(Irp);
|
|
||||||
Stack->FileObject = FileObject;
|
|
||||||
|
|
||||||
/* Really notify */
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
}
|
|
||||||
#endif // (NTDDI_VERSION >= NTDDI_WS03)
|
#endif // (NTDDI_VERSION >= NTDDI_WS03)
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
if (Name)
|
if (Name)
|
||||||
{
|
|
||||||
FreePool(Name);
|
FreePool(Name);
|
||||||
}
|
|
||||||
|
|
||||||
ObDereferenceObject(DeviceObject);
|
ObDereferenceObject(DeviceObject);
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
|
@ -276,15 +237,11 @@ VOID
|
||||||
SendLinkDeleted(IN PUNICODE_STRING DeviceName,
|
SendLinkDeleted(IN PUNICODE_STRING DeviceName,
|
||||||
IN PUNICODE_STRING SymbolicName)
|
IN PUNICODE_STRING SymbolicName)
|
||||||
{
|
{
|
||||||
PIRP Irp;
|
|
||||||
KEVENT Event;
|
|
||||||
ULONG NameSize;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
ULONG NameSize;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PIO_STACK_LOCATION Stack;
|
|
||||||
PMOUNTDEV_NAME Name = NULL;
|
PMOUNTDEV_NAME Name = NULL;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
|
|
||||||
/* Get the device associated with the name */
|
/* Get the device associated with the name */
|
||||||
Status = IoGetDeviceObjectPointer(DeviceName,
|
Status = IoGetDeviceObjectPointer(DeviceName,
|
||||||
|
@ -292,22 +249,18 @@ SendLinkDeleted(IN PUNICODE_STRING DeviceName,
|
||||||
&FileObject,
|
&FileObject,
|
||||||
&DeviceObject);
|
&DeviceObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
/* Get attached device (will notify it) */
|
/* Get attached device (will notify it) */
|
||||||
DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
|
DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
|
||||||
|
|
||||||
/* NameSize is the size of the whole MOUNTDEV_NAME struct */
|
/* NameSize is the size of the whole MOUNTDEV_NAME structure */
|
||||||
NameSize = sizeof(USHORT) + SymbolicName->Length;
|
NameSize = sizeof(USHORT) + SymbolicName->Length;
|
||||||
Name = AllocatePool(NameSize);
|
Name = AllocatePool(NameSize);
|
||||||
if (!Name)
|
if (!Name)
|
||||||
{
|
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize struct */
|
/* Initialize structure */
|
||||||
Name->NameLength = SymbolicName->Length;
|
Name->NameLength = SymbolicName->Length;
|
||||||
RtlCopyMemory(Name->Name, SymbolicName->Buffer, SymbolicName->Length);
|
RtlCopyMemory(Name->Name, SymbolicName->Buffer, SymbolicName->Length);
|
||||||
|
|
||||||
|
@ -315,61 +268,30 @@ SendLinkDeleted(IN PUNICODE_STRING DeviceName,
|
||||||
* (with limited access) first. If this fails, the called driver may be
|
* (with limited access) first. If this fails, the called driver may be
|
||||||
* for an older NT version, and so, we send again the notification using
|
* for an older NT version, and so, we send again the notification using
|
||||||
* the old (Windows 2000) IOCTL definition (with any access). */
|
* the old (Windows 2000) IOCTL definition (with any access). */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_LINK_DELETED,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_LINK_DELETED,
|
DeviceObject,
|
||||||
DeviceObject,
|
Name,
|
||||||
Name,
|
NameSize,
|
||||||
NameSize,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
FileObject);
|
||||||
FALSE,
|
|
||||||
&Event,
|
|
||||||
&IoStatusBlock);
|
|
||||||
/* This one can fail, no one matters */
|
/* This one can fail, no one matters */
|
||||||
if (Irp)
|
UNREFERENCED_PARAMETER(Status);
|
||||||
{
|
|
||||||
Stack = IoGetNextIrpStackLocation(Irp);
|
|
||||||
Stack->FileObject = FileObject;
|
|
||||||
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if (NTDDI_VERSION >= NTDDI_WS03)
|
#if (NTDDI_VERSION >= NTDDI_WS03)
|
||||||
/* Then, second one */
|
/* Then, second one */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_LINK_DELETED_UNSECURE_DEPRECATED,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_LINK_DELETED_UNSECURE_DEPRECATED,
|
DeviceObject,
|
||||||
DeviceObject,
|
Name,
|
||||||
Name,
|
NameSize,
|
||||||
NameSize,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
FileObject);
|
||||||
FALSE,
|
UNREFERENCED_PARAMETER(Status);
|
||||||
&Event,
|
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
goto Cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stack = IoGetNextIrpStackLocation(Irp);
|
|
||||||
Stack->FileObject = FileObject;
|
|
||||||
|
|
||||||
/* Really notify */
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
|
||||||
}
|
|
||||||
#endif // (NTDDI_VERSION >= NTDDI_WS03)
|
#endif // (NTDDI_VERSION >= NTDDI_WS03)
|
||||||
|
|
||||||
Cleanup:
|
Cleanup:
|
||||||
if (Name)
|
if (Name)
|
||||||
{
|
|
||||||
FreePool(Name);
|
FreePool(Name);
|
||||||
}
|
|
||||||
|
|
||||||
ObDereferenceObject(DeviceObject);
|
ObDereferenceObject(DeviceObject);
|
||||||
ObDereferenceObject(FileObject);
|
ObDereferenceObject(FileObject);
|
||||||
|
@ -700,14 +622,10 @@ QuerySuggestedLinkName(IN PUNICODE_STRING SymbolicName,
|
||||||
OUT PUNICODE_STRING SuggestedLinkName,
|
OUT PUNICODE_STRING SuggestedLinkName,
|
||||||
OUT PBOOLEAN UseOnlyIfThereAreNoOtherLinks)
|
OUT PBOOLEAN UseOnlyIfThereAreNoOtherLinks)
|
||||||
{
|
{
|
||||||
PIRP Irp;
|
|
||||||
KEVENT Event;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
USHORT NameLength;
|
USHORT NameLength;
|
||||||
PFILE_OBJECT FileObject;
|
PFILE_OBJECT FileObject;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
|
||||||
PIO_STACK_LOCATION IoStackLocation;
|
|
||||||
PMOUNTDEV_SUGGESTED_LINK_NAME IoCtlSuggested;
|
PMOUNTDEV_SUGGESTED_LINK_NAME IoCtlSuggested;
|
||||||
|
|
||||||
/* First, get device */
|
/* First, get device */
|
||||||
|
@ -732,35 +650,14 @@ QuerySuggestedLinkName(IN PUNICODE_STRING SymbolicName,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prepare request */
|
/* Prepare request */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME,
|
DeviceObject,
|
||||||
DeviceObject,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
IoCtlSuggested,
|
||||||
IoCtlSuggested,
|
sizeof(MOUNTDEV_SUGGESTED_LINK_NAME),
|
||||||
sizeof(MOUNTDEV_SUGGESTED_LINK_NAME),
|
FileObject);
|
||||||
FALSE,
|
/* Retry with appropriate length */
|
||||||
&Event,
|
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto Release;
|
|
||||||
}
|
|
||||||
|
|
||||||
IoStackLocation = IoGetNextIrpStackLocation(Irp);
|
|
||||||
IoStackLocation->FileObject = FileObject;
|
|
||||||
|
|
||||||
/* And ask */
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode,
|
|
||||||
FALSE, NULL);
|
|
||||||
Status = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Overflow? Normal */
|
|
||||||
if (Status == STATUS_BUFFER_OVERFLOW)
|
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||||
{
|
{
|
||||||
/* Reallocate big enough buffer */
|
/* Reallocate big enough buffer */
|
||||||
|
@ -774,39 +671,17 @@ QuerySuggestedLinkName(IN PUNICODE_STRING SymbolicName,
|
||||||
goto Dereference;
|
goto Dereference;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* And reask */
|
/* And re-ask */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME,
|
||||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME,
|
DeviceObject,
|
||||||
DeviceObject,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
IoCtlSuggested,
|
||||||
IoCtlSuggested,
|
NameLength,
|
||||||
NameLength,
|
FileObject);
|
||||||
FALSE,
|
|
||||||
&Event,
|
|
||||||
&IoStatusBlock);
|
|
||||||
if (!Irp)
|
|
||||||
{
|
|
||||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
||||||
goto Release;
|
|
||||||
}
|
|
||||||
|
|
||||||
IoStackLocation = IoGetNextIrpStackLocation(Irp);
|
|
||||||
IoStackLocation->FileObject = FileObject;
|
|
||||||
|
|
||||||
Status = IoCallDriver(DeviceObject, Irp);
|
|
||||||
if (Status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode,
|
|
||||||
FALSE, NULL);
|
|
||||||
Status = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
|
||||||
goto Release;
|
goto Release;
|
||||||
}
|
|
||||||
|
|
||||||
/* Now we have suggested name, copy it */
|
/* Now we have suggested name, copy it */
|
||||||
SuggestedLinkName->Length = IoCtlSuggested->NameLength;
|
SuggestedLinkName->Length = IoCtlSuggested->NameLength;
|
||||||
|
|
Loading…
Reference in a new issue