* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/vpb.c
* PURPOSE: Volume Parameter Block managment
- *
+ *
* PROGRAMMERS: David Welch (welch@mcmail.com)
*/
static KSPIN_LOCK IoVpbLock;
-#define TAG_VPB TAG('V', 'P', 'B', ' ')
-#define TAG_SYSB TAG('S', 'Y', 'S', 'B')
-
/* FUNCTIONS *****************************************************************/
VOID INIT_FUNCTION
IopAttachVpb(PDEVICE_OBJECT DeviceObject)
{
PVPB Vpb;
-
+
/* Allocate the Vpb */
Vpb = ExAllocatePoolWithTag(NonPagedPool,
sizeof(VPB),
TAG_VPB);
if (Vpb == NULL) return(STATUS_UNSUCCESSFUL);
-
+
/* Clear it so we don't waste time manually */
RtlZeroMemory(Vpb, sizeof(VPB));
-
+
/* Set the Header and Device Field */
Vpb->Type = IO_TYPE_VPB;
Vpb->Size = sizeof(VPB);
/*
* FUNCTION: Queries the volume information
- * ARGUMENTS:
+ * ARGUMENTS:
* FileHandle = Handle to a file object on the target volume
* ReturnLength = DataWritten
- * FsInformation = Caller should supply storage for the information
+ * FsInformation = Caller should supply storage for the information
* structure.
* Length = Size of the information structure
* FsInformationClass = Index to a information structure
* FileFsSizeInformation FILE_FS_SIZE_INFORMATION
* FileFsDeviceInformation FILE_FS_DEVICE_INFORMATION
* FileFsAttributeInformation FILE_FS_ATTRIBUTE_INFORMATION
- * FileFsControlInformation
+ * FileFsControlInformation
* FileFsQuotaQueryInformation --
* FileFsQuotaSetInformation --
- * FileFsMaximumInformation
+ * FileFsMaximumInformation
*
* RETURNS: Status
*
PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
- NTSTATUS Status;
+ NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION StackPtr;
PVOID SystemBuffer;
KPROCESSOR_MODE PreviousMode;
-
- ASSERT(IoStatusBlock != NULL);
- ASSERT(FsInformation != NULL);
-
+
DPRINT("FsInformation %p\n", FsInformation);
PreviousMode = ExGetPreviousMode();
+
+ if (PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ if (IoStatusBlock != NULL)
+ {
+ ProbeForWrite(IoStatusBlock,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ }
+
+ if (Length != 0)
+ {
+ ProbeForWrite(FsInformation,
+ Length,
+ 1);
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ else
+ {
+ ASSERT(IoStatusBlock != NULL);
+ ASSERT(FsInformation != NULL);
+ }
Status = ObReferenceObjectByHandle(FileHandle,
0, /* FIXME - depends on the information class! */
{
return(Status);
}
-
+
DeviceObject = FileObject->DeviceObject;
-
+
Irp = IoAllocateIrp(DeviceObject->StackSize,
TRUE);
if (Irp == NULL)
ObDereferenceObject(FileObject);
return(STATUS_INSUFFICIENT_RESOURCES);
}
-
+
SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
ObDereferenceObject(FileObject);
return(STATUS_INSUFFICIENT_RESOURCES);
}
-
+
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->UserEvent = &FileObject->Event;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
+
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
StackPtr->MinorFunction = 0;
StackPtr->Parameters.QueryVolume.Length = Length;
StackPtr->Parameters.QueryVolume.FsInformationClass =
FsInformationClass;
-
+
Status = IoCallDriver(DeviceObject,
Irp);
if (Status == STATUS_PENDING)
Status = IoStatusBlock->Status;
}
DPRINT("Status %x\n", Status);
-
+
if (NT_SUCCESS(Status))
{
- DPRINT("Information %lu\n", IoStatusBlock->Information);
- MmSafeCopyToUser(FsInformation,
- SystemBuffer,
- IoStatusBlock->Information);
+ _SEH_TRY
+ {
+ DPRINT("Information %lu\n", IoStatusBlock->Information);
+ RtlCopyMemory(FsInformation,
+ SystemBuffer,
+ IoStatusBlock->Information);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
}
ExFreePool(SystemBuffer);
-
+
return(Status);
}
PDEVICE_OBJECT DeviceObject;
PIRP Irp;
NTSTATUS Status;
-
+
ASSERT(FsInformation != NULL);
-
+
DPRINT("FsInformation %p\n", FsInformation);
-
+
Status = ObReferenceObjectByPointer(FileObject,
FILE_READ_ATTRIBUTES,
IoFileObjectType,
{
return(Status);
}
-
+
DeviceObject = FileObject->DeviceObject;
-
+
Irp = IoAllocateIrp(DeviceObject->StackSize,
TRUE);
if (Irp == NULL)
Irp->UserEvent = &FileObject->Event;
Irp->UserIosb = &IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
+
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
StackPtr->MinorFunction = 0;
StackPtr->Parameters.QueryVolume.Length = Length;
StackPtr->Parameters.QueryVolume.FsInformationClass =
FsInformationClass;
-
+
Status = IoCallDriver(DeviceObject,
Irp);
if (Status == STATUS_PENDING)
Status = IoStatusBlock.Status;
}
DPRINT("Status %x\n", Status);
-
+
if (ReturnedLength != NULL)
{
*ReturnedLength = IoStatusBlock.Information;
}
-
+
return(Status);
}
PVOID SystemBuffer;
KPROCESSOR_MODE PreviousMode;
- ASSERT(IoStatusBlock != NULL);
- ASSERT(FsInformation != NULL);
-
PreviousMode = ExGetPreviousMode();
+
+ if (PreviousMode != KernelMode)
+ {
+ Status = STATUS_SUCCESS;
+ _SEH_TRY
+ {
+ if (IoStatusBlock != NULL)
+ {
+ ProbeForWrite(IoStatusBlock,
+ sizeof(IO_STATUS_BLOCK),
+ sizeof(ULONG));
+ }
+
+ if (Length != 0)
+ {
+ ProbeForRead(FsInformation,
+ Length,
+ 1);
+ }
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+ }
+ else
+ {
+ ASSERT(IoStatusBlock != NULL);
+ ASSERT(FsInformation != NULL);
+ }
Status = ObReferenceObjectByHandle(FileHandle,
FILE_WRITE_ATTRIBUTES,
{
return(Status);
}
-
+
DeviceObject = FileObject->DeviceObject;
-
+
Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
if (Irp == NULL)
{
ObDereferenceObject(FileObject);
return(STATUS_INSUFFICIENT_RESOURCES);
}
-
+
SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
Length,
TAG_SYSB);
if (SystemBuffer == NULL)
{
- IoFreeIrp(Irp);
- ObDereferenceObject(FileObject);
- return(STATUS_INSUFFICIENT_RESOURCES);
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto failfreeirp;
}
-
- MmSafeCopyFromUser(SystemBuffer,
- FsInformation,
- Length);
-
+
+ if (PreviousMode != KernelMode)
+ {
+ _SEH_TRY
+ {
+ /* no need to probe again */
+ RtlCopyMemory(SystemBuffer,
+ FsInformation,
+ Length);
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
+
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(SystemBuffer,
+ TAG_SYSB);
+failfreeirp:
+ IoFreeIrp(Irp);
+ ObDereferenceObject(FileObject);
+ return Status;
+ }
+ }
+ else
+ {
+ RtlCopyMemory(SystemBuffer,
+ FsInformation,
+ Length);
+ }
+
/* Trigger FileObject/Event dereferencing */
Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode;
Irp->UserEvent = &FileObject->Event;
Irp->UserIosb = IoStatusBlock;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
-
+
StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_SET_VOLUME_INFORMATION;
StackPtr->MinorFunction = 0;
StackPtr->Parameters.SetVolume.Length = Length;
StackPtr->Parameters.SetVolume.FsInformationClass =
FsInformationClass;
-
+
Status = IoCallDriver(DeviceObject,Irp);
if (Status == STATUS_PENDING)
{
PreviousMode,
FALSE,
NULL);
- Status = IoStatusBlock->Status;
+ _SEH_TRY
+ {
+ Status = IoStatusBlock->Status;
+ }
+ _SEH_HANDLE
+ {
+ Status = _SEH_GetExceptionCode();
+ }
+ _SEH_END;
}
ExFreePool(SystemBuffer);
-
+
return(Status);
}