Allocated buffers from non paged pool for all user buffers.
Modified: trunk/reactos/ntoskrnl/io/plugplay.c

Modified: trunk/reactos/ntoskrnl/io/plugplay.c
--- trunk/reactos/ntoskrnl/io/plugplay.c	2005-10-15 21:17:52 UTC (rev 18486)
+++ trunk/reactos/ntoskrnl/io/plugplay.c	2005-10-15 21:41:48 UTC (rev 18487)
@@ -388,30 +388,126 @@
 
 }
 
+static NTSTATUS
+IopCaptureUnicodeString(PUNICODE_STRING DstName, PUNICODE_STRING SrcName)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    UNICODE_STRING Name;
 
+    Name.Buffer = NULL;
+    _SEH_TRY
+    {
+	Name.Length = SrcName->Length;
+	Name.MaximumLength = SrcName->MaximumLength;
+	if (Name.Length > Name.MaximumLength)
+	{
+	    Status = STATUS_INVALID_PARAMETER;
+	    _SEH_LEAVE;
+	}
+	if (Name.MaximumLength)
+	{
+	    ProbeForRead(SrcName->Buffer,
+		         Name.MaximumLength,
+			 sizeof(WCHAR));
+	    Name.Buffer = ExAllocatePool(NonPagedPool, Name.MaximumLength);
+	    if (Name.Buffer == NULL)
+	    {
+		Status = STATUS_INSUFFICIENT_RESOURCES;
+		_SEH_LEAVE;
+	    }
+	    memcpy(Name.Buffer, SrcName->Buffer, Name.MaximumLength);
+	}
+	*DstName = Name;
+    }
+    _SEH_HANDLE
+    {
+        Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if (!NT_SUCCESS(Status) && Name.Buffer)
+    {   
+	ExFreePool(Name.Buffer);
+    }
+    return Status;
+}
 
 static NTSTATUS
 IopGetDeviceProperty(PPLUGPLAY_CONTROL_PROPERTY_DATA PropertyData)
 {
     PDEVICE_OBJECT DeviceObject = NULL;
-    NTSTATUS Status;
+    NTSTATUS Status = STATUS_SUCCESS;
+    UNICODE_STRING DeviceInstance;
+    ULONG BufferSize;
+    ULONG Property = 0;
+    PVOID Buffer;
 
     DPRINT("IopGetDeviceProperty() called\n");
     DPRINT("Device name: %wZ\n", &PropertyData->DeviceInstance);
 
+    Status = IopCaptureUnicodeString(&DeviceInstance, &PropertyData->DeviceInstance);
+    if (!NT_SUCCESS(Status))
+    {
+	return Status;
+    }
+
+    _SEH_TRY
+    {
+	Property = PropertyData->Property;
+        BufferSize = PropertyData->BufferSize;
+        ProbeForWrite(PropertyData->Buffer,
+                      BufferSize,
+                      sizeof(UCHAR));
+    }
+    _SEH_HANDLE
+    {
+        Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+    
+    if (!NT_SUCCESS(Status))
+    {
+	ExFreePool(DeviceInstance.Buffer);
+	return Status;
+    }
+
     /* Get the device object */
     DeviceObject = IopGetDeviceObjectFromDeviceInstance(&PropertyData->DeviceInstance);
+    ExFreePool(DeviceInstance.Buffer);
     if (DeviceObject == NULL)
+    {
         return STATUS_NO_SUCH_DEVICE;
+    }
 
+    Buffer = ExAllocatePool(NonPagedPool, BufferSize);
+    if (Buffer == NULL)
+    {
+	return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+
     Status = IoGetDeviceProperty(DeviceObject,
-                                 PropertyData->Property,
-                                 PropertyData->BufferSize,
-                                 PropertyData->Buffer,
-                                 &PropertyData->BufferSize);
+                                 Property,
+                                 BufferSize,
+                                 Buffer,
+                                 &BufferSize);
 
     ObDereferenceObject(DeviceObject);
 
+    if (NT_SUCCESS(Status))
+    {
+	_SEH_TRY
+	{
+	    memcpy(Buffer, PropertyData->Buffer, BufferSize);
+	    PropertyData->BufferSize = BufferSize;
+	}
+	_SEH_HANDLE
+	{
+	    Status = _SEH_GetExceptionCode();
+	}
+	_SEH_END;
+    }
+    ExFreePool(Buffer);
     return Status;
 }
 
@@ -423,29 +519,61 @@
     PDEVICE_OBJECT DeviceObject = NULL;
     PDEVICE_NODE DeviceNode = NULL;
     PDEVICE_NODE RelatedDeviceNode;
+    UNICODE_STRING TargetDeviceInstance;
+    NTSTATUS Status = STATUS_SUCCESS;
+    ULONG Relation = 0;
+    ULONG MaximumLength = 0;
 
     DPRINT("IopGetRelatedDevice() called\n");
     DPRINT("Device name: %wZ\n", &RelatedDeviceData->TargetDeviceInstance);
 
+    Status = IopCaptureUnicodeString(&TargetDeviceInstance, &RelatedDeviceData->TargetDeviceInstance);
+    if (!NT_SUCCESS(Status))
+    {
+	return Status;
+    }
+
+    _SEH_TRY
+    {
+	Relation = RelatedDeviceData->Relation;
+	MaximumLength = RelatedDeviceData->RelatedDeviceInstance.MaximumLength;
+	ProbeForWrite(RelatedDeviceData->RelatedDeviceInstance.Buffer,
+	              MaximumLength,
+		      sizeof(WCHAR));
+    }
+    _SEH_HANDLE
+    {
+        Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+
+    if (!NT_SUCCESS(Status))
+    {
+        ExFreePool(TargetDeviceInstance.Buffer);
+	return Status;
+    }
+
     RtlInitUnicodeString(&RootDeviceName,
                          L"HTREE\\ROOT\\0");
-    if (RtlEqualUnicodeString(&RelatedDeviceData->TargetDeviceInstance,
+    if (RtlEqualUnicodeString(&TargetDeviceInstance,
                               &RootDeviceName,
                               TRUE))
     {
         DeviceNode = IopRootDeviceNode;
+	ExFreePool(TargetDeviceInstance.Buffer);
     }
     else
     {
         /* Get the device object */
-        DeviceObject = IopGetDeviceObjectFromDeviceInstance(&RelatedDeviceData->TargetDeviceInstance);
+        DeviceObject = IopGetDeviceObjectFromDeviceInstance(&TargetDeviceInstance);
+	ExFreePool(TargetDeviceInstance.Buffer);
         if (DeviceObject == NULL)
             return STATUS_NO_SUCH_DEVICE;
 
         DeviceNode = ((PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension)->DeviceNode;
     }
 
-    switch (RelatedDeviceData->Relation)
+    switch (Relation)
     {
         case PNP_GET_PARENT_DEVICE:
             RelatedDeviceNode = DeviceNode->Parent;
@@ -478,8 +606,7 @@
         return STATUS_NO_SUCH_DEVICE;
     }
 
-    if (RelatedDeviceNode->InstancePath.Length >
-        RelatedDeviceData->RelatedDeviceInstance.MaximumLength)
+    if (RelatedDeviceNode->InstancePath.Length > MaximumLength)
     {
         if (DeviceObject)
         {
@@ -490,11 +617,18 @@
     }
 
     /* Copy related device instance name */
-    RtlCopyMemory(RelatedDeviceData->RelatedDeviceInstance.Buffer,
-                  RelatedDeviceNode->InstancePath.Buffer,
-                  RelatedDeviceNode->InstancePath.Length);
-    RelatedDeviceData->RelatedDeviceInstance.Length =
-        RelatedDeviceNode->InstancePath.Length;
+    _SEH_TRY
+    {
+        RtlCopyMemory(RelatedDeviceData->RelatedDeviceInstance.Buffer,
+                      RelatedDeviceNode->InstancePath.Buffer,
+                      RelatedDeviceNode->InstancePath.Length);
+        RelatedDeviceData->RelatedDeviceInstance.Length = RelatedDeviceNode->InstancePath.Length;
+    }
+    _SEH_HANDLE
+    {
+        Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
 
     if (DeviceObject != NULL)
     {
@@ -503,7 +637,7 @@
 
     DPRINT("IopGetRelatedDevice() done\n");
 
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 
@@ -512,29 +646,65 @@
 {
     PDEVICE_OBJECT DeviceObject;
     PDEVICE_NODE DeviceNode;
+    ULONG Operation = 0;
+    ULONG DeviceStatus = 0;
+    ULONG DeviceProblem = 0;
+    UNICODE_STRING DeviceInstance;
+    NTSTATUS Status = STATUS_SUCCESS;
 
     DPRINT("IopDeviceStatus() called\n");
     DPRINT("Device name: %wZ\n", &StatusData->DeviceInstance);
 
+    Status = IopCaptureUnicodeString(&DeviceInstance, &StatusData->DeviceInstance);
+    if (!NT_SUCCESS(Status))
+    {
+	return Status;
+    }
+
+    _SEH_TRY
+    {
+	Operation = StatusData->Operation;
+	if (Operation == PNP_SET_DEVICE_STATUS)
+	{
+	    DeviceStatus = StatusData->DeviceStatus;
+	    DeviceProblem = StatusData->DeviceProblem;
+	}
+    }
+    _SEH_HANDLE
+    {
+        Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+
+    if (!NT_SUCCESS(Status))
+    {
+	if (DeviceInstance.Buffer)
+	{
+	    ExFreePool(DeviceInstance.Buffer);
+	}
+	return Status;
+    }
+
     /* Get the device object */
     DeviceObject = IopGetDeviceObjectFromDeviceInstance(&StatusData->DeviceInstance);
+    ExFreePool(DeviceInstance.Buffer);
     if (DeviceObject == NULL)
         return STATUS_NO_SUCH_DEVICE;
 
     DeviceNode = ((PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension)->DeviceNode;
 
-    switch (StatusData->Operation)
+    switch (Operation)
     {
         case PNP_GET_DEVICE_STATUS:
             DPRINT("Get status data\n");
-            StatusData->DeviceStatus = DeviceNode->Flags;
-            StatusData->DeviceProblem = DeviceNode->Problem;
+            DeviceStatus = DeviceNode->Flags;
+            DeviceProblem = DeviceNode->Problem;
             break;
 
         case PNP_SET_DEVICE_STATUS:
             DPRINT("Set status data\n");
-            DeviceNode->Flags = StatusData->DeviceStatus;
-            DeviceNode->Problem = StatusData->DeviceProblem;
+            DeviceNode->Flags = DeviceStatus;
+            DeviceNode->Problem = DeviceProblem;
             break;
 
         case PNP_CLEAR_DEVICE_STATUS:
@@ -544,7 +714,21 @@
 
     ObDereferenceObject(DeviceObject);
 
-    return STATUS_SUCCESS;
+    if (Operation == PNP_GET_DEVICE_STATUS)
+    {
+	_SEH_TRY
+	{
+	    StatusData->DeviceStatus = DeviceStatus;
+	    StatusData->DeviceProblem = DeviceProblem;
+	}
+	_SEH_HANDLE
+	{
+	    Status = _SEH_GetExceptionCode();
+	}
+	_SEH_END;
+    }
+
+    return Status;
 }
 
 
@@ -553,12 +737,21 @@
 {
     PDEVICE_OBJECT DeviceObject;
     PDEVICE_NODE DeviceNode;
+    UNICODE_STRING DeviceInstance;
+    NTSTATUS Status = STATUS_SUCCESS;
 
     DPRINT("IopGetDeviceDepth() called\n");
     DPRINT("Device name: %wZ\n", &DepthData->DeviceInstance);
 
+    Status = IopCaptureUnicodeString(&DeviceInstance, &DepthData->DeviceInstance);
+    if (!NT_SUCCESS(Status))
+    {
+	return Status;
+    }
+
     /* Get the device object */
     DeviceObject = IopGetDeviceObjectFromDeviceInstance(&DepthData->DeviceInstance);
+    ExFreePool(DeviceInstance.Buffer);
     if (DeviceObject == NULL)
         return STATUS_NO_SUCH_DEVICE;
 
@@ -568,7 +761,17 @@
 
     ObDereferenceObject(DeviceObject);
 
-    return STATUS_SUCCESS;
+    _SEH_TRY
+    {
+	DepthData->Depth = DeviceNode->Level;
+    }
+    _SEH_HANDLE
+    {
+        Status = _SEH_GetExceptionCode();
+    }
+    _SEH_END;
+
+    return Status;
 }
 
 
@@ -577,13 +780,21 @@
 {
     PDEVICE_OBJECT DeviceObject;
     PDEVICE_NODE DeviceNode;
-    NTSTATUS Status;
+    NTSTATUS Status = STATUS_SUCCESS;
+    UNICODE_STRING DeviceInstance;
 
     DPRINT("IopResetDevice() called\n");
     DPRINT("Device name: %wZ\n", &ResetDeviceData->DeviceInstance);
 
+    Status = IopCaptureUnicodeString(&DeviceInstance, &ResetDeviceData->DeviceInstance);
+    if (!NT_SUCCESS(Status))
+    {
+	return Status;
+    }
+
     /* Get the device object */
-    DeviceObject = IopGetDeviceObjectFromDeviceInstance(&ResetDeviceData->DeviceInstance);
+    DeviceObject = IopGetDeviceObjectFromDeviceInstance(&DeviceInstance);
+    ExFreePool(DeviceInstance.Buffer);
     if (DeviceObject == NULL)
         return STATUS_NO_SUCH_DEVICE;