[NTOS:PNP]
authorThomas Faber <thomas.faber@reactos.org>
Fri, 10 Apr 2015 10:10:28 +0000 (10:10 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Fri, 10 Apr 2015 10:10:28 +0000 (10:10 +0000)
- Add missing SEH/Probe in NtGetPlugPlayEvent and IopGetInterfaceDeviceList, and correctly copy the interface list. Patch by Stephan Röger.
CORE-9498 #resolve

svn path=/trunk/; revision=67129

reactos/ntoskrnl/io/pnpmgr/plugplay.c

index 86f3f5f..25791eb 100644 (file)
@@ -214,22 +214,23 @@ static NTSTATUS
 IopGetInterfaceDeviceList(PPLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA DeviceList)
 {
     NTSTATUS Status;
+    PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA StackList;
     UNICODE_STRING DeviceInstance;
     PDEVICE_OBJECT DeviceObject = NULL;
-    ULONG BufferSize = 0;
     GUID FilterGuid;
     PZZWSTR SymbolicLinkList = NULL, LinkList;
-    ULONG TotalLength = 0;
+    ULONG TotalLength;
 
     _SEH2_TRY
     {
-        ProbeForRead(DeviceList->FilterGuid, sizeof(GUID), sizeof(UCHAR));
-        RtlCopyMemory(&FilterGuid, DeviceList->FilterGuid, sizeof(GUID));
+        RtlCopyMemory(&StackList, DeviceList, sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA));
 
-        if (DeviceList->Buffer != NULL && DeviceList->BufferSize != 0)
+        ProbeForRead(StackList.FilterGuid, sizeof(GUID), sizeof(UCHAR));
+        RtlCopyMemory(&FilterGuid, StackList.FilterGuid, sizeof(GUID));
+
+        if (StackList.Buffer != NULL && StackList.BufferSize != 0)
         {
-            BufferSize = DeviceList->BufferSize;
-            ProbeForWrite(DeviceList->Buffer, BufferSize, sizeof(UCHAR));
+            ProbeForWrite(StackList.Buffer, StackList.BufferSize, sizeof(UCHAR));
         }
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -238,8 +239,7 @@ IopGetInterfaceDeviceList(PPLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA DeviceLis
     }
     _SEH2_END;
 
-
-    Status = IopCaptureUnicodeString(&DeviceInstance, &DeviceList->DeviceInstance);
+    Status = IopCaptureUnicodeString(&DeviceInstance, &StackList.DeviceInstance);
     if (NT_SUCCESS(Status))
     {
         /* Get the device object */
@@ -247,7 +247,7 @@ IopGetInterfaceDeviceList(PPLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA DeviceLis
         ExFreePool(DeviceInstance.Buffer);
     }
 
-    Status = IoGetDeviceInterfaces(&FilterGuid, DeviceObject, DeviceList->Flags, &SymbolicLinkList);
+    Status = IoGetDeviceInterfaces(&FilterGuid, DeviceObject, StackList.Flags, &SymbolicLinkList);
     ObDereferenceObject(DeviceObject);
 
     if (!NT_SUCCESS(Status))
@@ -259,16 +259,28 @@ IopGetInterfaceDeviceList(PPLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA DeviceLis
     LinkList = SymbolicLinkList;
     while (*SymbolicLinkList != UNICODE_NULL)
     {
-        TotalLength += (wcslen(SymbolicLinkList) + 1) * sizeof(WCHAR);
         SymbolicLinkList += wcslen(SymbolicLinkList) + (sizeof(UNICODE_NULL) / sizeof(WCHAR));
     }
-    TotalLength += sizeof(UNICODE_NULL);
+    TotalLength = ((SymbolicLinkList - LinkList + 1) * sizeof(WCHAR));
 
-    if (BufferSize >= TotalLength)
+    _SEH2_TRY
     {
-        RtlCopyMemory(DeviceList->Buffer, SymbolicLinkList, TotalLength * sizeof(WCHAR));
+        if (StackList.Buffer != NULL &&
+            StackList.BufferSize >= TotalLength)
+        {
+            // We've already probed the buffer for writing above.
+            RtlCopyMemory(StackList.Buffer, LinkList, TotalLength);
+        }
+
+        DeviceList->BufferSize = TotalLength;
     }
-    DeviceList->BufferSize = TotalLength;
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        ExFreePool(LinkList);
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
+    }
+    _SEH2_END;
+
     ExFreePool(LinkList);
     return STATUS_SUCCESS;
 }
@@ -831,9 +843,20 @@ NtGetPlugPlayEvent(IN ULONG Reserved1,
     }
 
     /* Copy event data to the user buffer */
-    memcpy(Buffer,
-           &Entry->Event,
-           Entry->Event.TotalSize);
+    _SEH2_TRY
+    {
+        ProbeForWrite(Buffer,
+                      Entry->Event.TotalSize,
+                      sizeof(UCHAR));
+        RtlCopyMemory(Buffer,
+                      &Entry->Event,
+                      Entry->Event.TotalSize);
+    }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        _SEH2_YIELD(return _SEH2_GetExceptionCode());
+    }
+    _SEH2_END;
 
     DPRINT("NtGetPlugPlayEvent() done\n");