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)
}
_SEH2_END;
-
- Status = IopCaptureUnicodeString(&DeviceInstance, &DeviceList->DeviceInstance);
+ Status = IopCaptureUnicodeString(&DeviceInstance, &StackList.DeviceInstance);
if (NT_SUCCESS(Status))
{
/* Get the device object */
ExFreePool(DeviceInstance.Buffer);
}
- Status = IoGetDeviceInterfaces(&FilterGuid, DeviceObject, DeviceList->Flags, &SymbolicLinkList);
+ Status = IoGetDeviceInterfaces(&FilterGuid, DeviceObject, StackList.Flags, &SymbolicLinkList);
ObDereferenceObject(DeviceObject);
if (!NT_SUCCESS(Status))
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;
}
}
/* 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");