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
|
||||
IsFtVolume(IN PUNICODE_STRING SymbolicName)
|
||||
{
|
||||
PIRP Irp;
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
PFILE_OBJECT FileObject;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PARTITION_INFORMATION PartitionInfo;
|
||||
PDEVICE_OBJECT DeviceObject, FileDeviceObject;
|
||||
|
||||
|
@ -344,9 +341,7 @@ IsFtVolume(IN PUNICODE_STRING SymbolicName)
|
|||
&FileObject,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get attached device */
|
||||
FileDeviceObject = FileObject->DeviceObject;
|
||||
|
@ -363,34 +358,17 @@ IsFtVolume(IN PUNICODE_STRING SymbolicName)
|
|||
ObDereferenceObject(FileObject);
|
||||
|
||||
/* Get partition information */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
&PartitionInfo,
|
||||
sizeof(PartitionInfo),
|
||||
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;
|
||||
}
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_DISK_GET_PARTITION_INFO,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
&PartitionInfo,
|
||||
sizeof(PartitionInfo),
|
||||
NULL);
|
||||
|
||||
ObDereferenceObject(DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Check if this is a FT volume */
|
||||
return IsFTPartition(PartitionInfo.PartitionType);
|
||||
|
|
|
@ -179,6 +179,17 @@ extern LONG Unloading;
|
|||
CODE_SEG("INIT")
|
||||
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
|
||||
NTAPI
|
||||
MountMgrCancel(
|
||||
|
|
|
@ -39,6 +39,90 @@ LONG Unloading;
|
|||
static const WCHAR Cunc[] = L"\\??\\C:";
|
||||
#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
|
||||
*/
|
||||
|
@ -196,17 +280,13 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
IN OUT LPGUID StableGuid OPTIONAL,
|
||||
OUT PBOOLEAN Valid OPTIONAL)
|
||||
{
|
||||
PIRP Irp;
|
||||
NTSTATUS Status;
|
||||
USHORT Size;
|
||||
KEVENT Event;
|
||||
BOOLEAN IsRemovable;
|
||||
PMOUNTDEV_NAME Name;
|
||||
PMOUNTDEV_UNIQUE_ID Id;
|
||||
PFILE_OBJECT FileObject;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
NTSTATUS Status, IntStatus;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PARTITION_INFORMATION_EX PartitionInfo;
|
||||
STORAGE_DEVICE_NUMBER StorageDeviceNumber;
|
||||
VOLUME_GET_GPT_ATTRIBUTES_INFORMATION GptAttributes;
|
||||
|
@ -247,30 +327,21 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
if (!IsRemovable)
|
||||
{
|
||||
/* Query the GPT attributes */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_VOLUME_GET_GPT_ATTRIBUTES,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
&GptAttributes,
|
||||
sizeof(GptAttributes),
|
||||
FALSE,
|
||||
&Event,
|
||||
&IoStatusBlock);
|
||||
if (!Irp)
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_VOLUME_GET_GPT_ATTRIBUTES,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
&GptAttributes,
|
||||
sizeof(GptAttributes),
|
||||
NULL);
|
||||
#if 0
|
||||
if (Status == STATUS_INSUFFICIENT_RESOURCES)
|
||||
{
|
||||
ObDereferenceObject(DeviceObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* In case of failure, don't fail, that's no vital */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -293,30 +364,21 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
if (!IsRemovable)
|
||||
{
|
||||
/* Query partitions information */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO_EX,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
&PartitionInfo,
|
||||
sizeof(PartitionInfo),
|
||||
FALSE,
|
||||
&Event,
|
||||
&IoStatusBlock);
|
||||
if (!Irp)
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_DISK_GET_PARTITION_INFO_EX,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
&PartitionInfo,
|
||||
sizeof(PartitionInfo),
|
||||
NULL);
|
||||
#if 0
|
||||
if (Status == STATUS_INSUFFICIENT_RESOURCES)
|
||||
{
|
||||
ObDereferenceObject(DeviceObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Once again here, failure isn't major */
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -332,38 +394,25 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
/* It looks correct, ensure it is & query device number */
|
||||
if (*Valid)
|
||||
{
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_STORAGE_GET_DEVICE_NUMBER,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
&StorageDeviceNumber,
|
||||
sizeof(StorageDeviceNumber),
|
||||
FALSE,
|
||||
&Event,
|
||||
&IoStatusBlock);
|
||||
if (!Irp)
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_STORAGE_GET_DEVICE_NUMBER,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
&StorageDeviceNumber,
|
||||
sizeof(StorageDeviceNumber),
|
||||
NULL);
|
||||
#if 0
|
||||
if (Status == STATUS_INSUFFICIENT_RESOURCES)
|
||||
{
|
||||
ObDereferenceObject(DeviceObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
#endif
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
*Valid = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -381,35 +430,14 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
}
|
||||
|
||||
/* Query device name */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
Name,
|
||||
sizeof(MOUNTDEV_NAME),
|
||||
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;
|
||||
}
|
||||
|
||||
/* Now, we've got the correct length */
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
Name,
|
||||
sizeof(MOUNTDEV_NAME),
|
||||
FileObject);
|
||||
/* Retry with appropriate length */
|
||||
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||
{
|
||||
Size = Name->NameLength + sizeof(MOUNTDEV_NAME);
|
||||
|
@ -426,33 +454,13 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
}
|
||||
|
||||
/* And query name (for real that time) */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
Name,
|
||||
Size,
|
||||
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;
|
||||
}
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_DEVICE_NAME,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
Name,
|
||||
Size,
|
||||
FileObject);
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
|
@ -495,34 +503,13 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
}
|
||||
|
||||
/* Query unique ID length */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_UNIQUE_ID,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
Id,
|
||||
sizeof(MOUNTDEV_UNIQUE_ID),
|
||||
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;
|
||||
}
|
||||
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_UNIQUE_ID,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
Id,
|
||||
sizeof(MOUNTDEV_UNIQUE_ID),
|
||||
FileObject);
|
||||
/* Retry with appropriate length */
|
||||
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||
{
|
||||
|
@ -540,33 +527,13 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
}
|
||||
|
||||
/* Query unique ID */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_UNIQUE_ID,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
Id,
|
||||
Size,
|
||||
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;
|
||||
}
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_UNIQUE_ID,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
Id,
|
||||
Size,
|
||||
FileObject);
|
||||
}
|
||||
|
||||
/* Hands back unique ID */
|
||||
|
@ -579,13 +546,10 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
/* In case of failure, also free the rest */
|
||||
FreePool(Id);
|
||||
if (DeviceName->Length)
|
||||
{
|
||||
FreePool(DeviceName->Buffer);
|
||||
}
|
||||
|
||||
ObDereferenceObject(DeviceObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
@ -594,33 +558,14 @@ QueryDeviceInformation(IN PUNICODE_STRING SymbolicName,
|
|||
if (HasGuid)
|
||||
{
|
||||
/* Query device stable GUID */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_STABLE_GUID,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
StableGuid,
|
||||
sizeof(GUID),
|
||||
FALSE,
|
||||
&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;
|
||||
}
|
||||
|
||||
NTSTATUS IntStatus;
|
||||
IntStatus = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_STABLE_GUID,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
StableGuid,
|
||||
sizeof(GUID),
|
||||
FileObject);
|
||||
*HasGuid = NT_SUCCESS(IntStatus);
|
||||
}
|
||||
|
||||
|
@ -791,7 +736,7 @@ MountMgrFreeSavedLink(IN PSAVED_LINK_INFORMATION SavedLinkInformation)
|
|||
*/
|
||||
VOID
|
||||
NTAPI
|
||||
MountMgrUnload(IN struct _DRIVER_OBJECT *DriverObject)
|
||||
MountMgrUnload(IN PDRIVER_OBJECT DriverObject)
|
||||
{
|
||||
PLIST_ENTRY NextEntry;
|
||||
PUNIQUE_ID_WORK_ITEM WorkItem;
|
||||
|
|
|
@ -37,13 +37,9 @@
|
|||
VOID
|
||||
SendOnlineNotification(IN PUNICODE_STRING SymbolicName)
|
||||
{
|
||||
PIRP Irp;
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
PFILE_OBJECT FileObject;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
/* Get device object */
|
||||
Status = IoGetDeviceObjectPointer(SymbolicName,
|
||||
|
@ -51,40 +47,21 @@ SendOnlineNotification(IN PUNICODE_STRING SymbolicName)
|
|||
&FileObject,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* And attached device object */
|
||||
DeviceObject = IoGetAttachedDeviceReference(FileObject->DeviceObject);
|
||||
|
||||
/* And send VOLUME_ONLINE */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_VOLUME_ONLINE,
|
||||
DeviceObject,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
FALSE,
|
||||
&Event,
|
||||
&IoStatusBlock);
|
||||
if (!Irp)
|
||||
{
|
||||
goto Cleanup;
|
||||
}
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_VOLUME_ONLINE,
|
||||
DeviceObject,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
FileObject);
|
||||
UNREFERENCED_PARAMETER(Status);
|
||||
|
||||
Stack = IoGetNextIrpStackLocation(Irp);
|
||||
Stack->FileObject = FileObject;
|
||||
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
}
|
||||
|
||||
Cleanup:
|
||||
ObDereferenceObject(DeviceObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -168,15 +168,11 @@ GlobalDeleteSymbolicLink(IN PUNICODE_STRING DosName)
|
|||
VOID
|
||||
SendLinkCreated(IN PUNICODE_STRING SymbolicName)
|
||||
{
|
||||
PIRP Irp;
|
||||
KEVENT Event;
|
||||
ULONG NameSize;
|
||||
NTSTATUS Status;
|
||||
ULONG NameSize;
|
||||
PFILE_OBJECT FileObject;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PMOUNTDEV_NAME Name = NULL;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
/* Get the device associated with the name */
|
||||
Status = IoGetDeviceObjectPointer(SymbolicName,
|
||||
|
@ -184,22 +180,18 @@ SendLinkCreated(IN PUNICODE_STRING SymbolicName)
|
|||
&FileObject,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get attached device (will notify it) */
|
||||
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;
|
||||
Name = AllocatePool(NameSize);
|
||||
if (!Name)
|
||||
{
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Initialize struct */
|
||||
/* Initialize structure */
|
||||
Name->NameLength = 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
|
||||
* for an older NT version, and so, we send again the notification using
|
||||
* the old (Windows 2000) IOCTL definition (with any access). */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_LINK_CREATED,
|
||||
DeviceObject,
|
||||
Name,
|
||||
NameSize,
|
||||
NULL,
|
||||
0,
|
||||
FALSE,
|
||||
&Event,
|
||||
&IoStatusBlock);
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_LINK_CREATED,
|
||||
DeviceObject,
|
||||
Name,
|
||||
NameSize,
|
||||
NULL,
|
||||
0,
|
||||
FileObject);
|
||||
/* This one can fail, no one matters */
|
||||
if (Irp)
|
||||
{
|
||||
Stack = IoGetNextIrpStackLocation(Irp);
|
||||
Stack->FileObject = FileObject;
|
||||
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
}
|
||||
}
|
||||
UNREFERENCED_PARAMETER(Status);
|
||||
#if (NTDDI_VERSION >= NTDDI_WS03)
|
||||
/* Then, second one */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_LINK_CREATED_UNSECURE_DEPRECATED,
|
||||
DeviceObject,
|
||||
Name,
|
||||
NameSize,
|
||||
NULL,
|
||||
0,
|
||||
FALSE,
|
||||
&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);
|
||||
}
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_LINK_CREATED_UNSECURE_DEPRECATED,
|
||||
DeviceObject,
|
||||
Name,
|
||||
NameSize,
|
||||
NULL,
|
||||
0,
|
||||
FileObject);
|
||||
UNREFERENCED_PARAMETER(Status);
|
||||
#endif // (NTDDI_VERSION >= NTDDI_WS03)
|
||||
|
||||
Cleanup:
|
||||
if (Name)
|
||||
{
|
||||
FreePool(Name);
|
||||
}
|
||||
|
||||
ObDereferenceObject(DeviceObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
|
@ -276,15 +237,11 @@ VOID
|
|||
SendLinkDeleted(IN PUNICODE_STRING DeviceName,
|
||||
IN PUNICODE_STRING SymbolicName)
|
||||
{
|
||||
PIRP Irp;
|
||||
KEVENT Event;
|
||||
ULONG NameSize;
|
||||
NTSTATUS Status;
|
||||
ULONG NameSize;
|
||||
PFILE_OBJECT FileObject;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PMOUNTDEV_NAME Name = NULL;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
|
||||
/* Get the device associated with the name */
|
||||
Status = IoGetDeviceObjectPointer(DeviceName,
|
||||
|
@ -292,22 +249,18 @@ SendLinkDeleted(IN PUNICODE_STRING DeviceName,
|
|||
&FileObject,
|
||||
&DeviceObject);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get attached device (will notify it) */
|
||||
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;
|
||||
Name = AllocatePool(NameSize);
|
||||
if (!Name)
|
||||
{
|
||||
goto Cleanup;
|
||||
}
|
||||
|
||||
/* Initialize struct */
|
||||
/* Initialize structure */
|
||||
Name->NameLength = 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
|
||||
* for an older NT version, and so, we send again the notification using
|
||||
* the old (Windows 2000) IOCTL definition (with any access). */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_LINK_DELETED,
|
||||
DeviceObject,
|
||||
Name,
|
||||
NameSize,
|
||||
NULL,
|
||||
0,
|
||||
FALSE,
|
||||
&Event,
|
||||
&IoStatusBlock);
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_LINK_DELETED,
|
||||
DeviceObject,
|
||||
Name,
|
||||
NameSize,
|
||||
NULL,
|
||||
0,
|
||||
FileObject);
|
||||
/* This one can fail, no one matters */
|
||||
if (Irp)
|
||||
{
|
||||
Stack = IoGetNextIrpStackLocation(Irp);
|
||||
Stack->FileObject = FileObject;
|
||||
|
||||
Status = IoCallDriver(DeviceObject, Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||
}
|
||||
}
|
||||
UNREFERENCED_PARAMETER(Status);
|
||||
#if (NTDDI_VERSION >= NTDDI_WS03)
|
||||
/* Then, second one */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_LINK_DELETED_UNSECURE_DEPRECATED,
|
||||
DeviceObject,
|
||||
Name,
|
||||
NameSize,
|
||||
NULL,
|
||||
0,
|
||||
FALSE,
|
||||
&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);
|
||||
}
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_LINK_DELETED_UNSECURE_DEPRECATED,
|
||||
DeviceObject,
|
||||
Name,
|
||||
NameSize,
|
||||
NULL,
|
||||
0,
|
||||
FileObject);
|
||||
UNREFERENCED_PARAMETER(Status);
|
||||
#endif // (NTDDI_VERSION >= NTDDI_WS03)
|
||||
|
||||
Cleanup:
|
||||
if (Name)
|
||||
{
|
||||
FreePool(Name);
|
||||
}
|
||||
|
||||
ObDereferenceObject(DeviceObject);
|
||||
ObDereferenceObject(FileObject);
|
||||
|
@ -700,14 +622,10 @@ QuerySuggestedLinkName(IN PUNICODE_STRING SymbolicName,
|
|||
OUT PUNICODE_STRING SuggestedLinkName,
|
||||
OUT PBOOLEAN UseOnlyIfThereAreNoOtherLinks)
|
||||
{
|
||||
PIRP Irp;
|
||||
KEVENT Event;
|
||||
NTSTATUS Status;
|
||||
USHORT NameLength;
|
||||
PFILE_OBJECT FileObject;
|
||||
PDEVICE_OBJECT DeviceObject;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PIO_STACK_LOCATION IoStackLocation;
|
||||
PMOUNTDEV_SUGGESTED_LINK_NAME IoCtlSuggested;
|
||||
|
||||
/* First, get device */
|
||||
|
@ -732,35 +650,14 @@ QuerySuggestedLinkName(IN PUNICODE_STRING SymbolicName,
|
|||
}
|
||||
|
||||
/* Prepare request */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
IoCtlSuggested,
|
||||
sizeof(MOUNTDEV_SUGGESTED_LINK_NAME),
|
||||
FALSE,
|
||||
&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 */
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
IoCtlSuggested,
|
||||
sizeof(MOUNTDEV_SUGGESTED_LINK_NAME),
|
||||
FileObject);
|
||||
/* Retry with appropriate length */
|
||||
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||
{
|
||||
/* Reallocate big enough buffer */
|
||||
|
@ -774,39 +671,17 @@ QuerySuggestedLinkName(IN PUNICODE_STRING SymbolicName,
|
|||
goto Dereference;
|
||||
}
|
||||
|
||||
/* And reask */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
Irp = IoBuildDeviceIoControlRequest(IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
IoCtlSuggested,
|
||||
NameLength,
|
||||
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;
|
||||
}
|
||||
/* And re-ask */
|
||||
Status = MountMgrSendSyncDeviceIoCtl(IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME,
|
||||
DeviceObject,
|
||||
NULL,
|
||||
0,
|
||||
IoCtlSuggested,
|
||||
NameLength,
|
||||
FileObject);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
goto Release;
|
||||
}
|
||||
|
||||
/* Now we have suggested name, copy it */
|
||||
SuggestedLinkName->Length = IoCtlSuggested->NameLength;
|
||||
|
|
Loading…
Reference in a new issue