static NTSTATUS IopDeviceStatus(PPLUGPLAY_CONTROL_STATUS_DATA StatusData) { PDEVICE_OBJECT DeviceObject; PDEVICE_NODE DeviceNode; ULONG Operation = 0; ULONG DeviceStatus = 0; ULONG DeviceProblem = 0; UNICODE_STRING DeviceInstance; NTSTATUS Status; DPRINT("IopDeviceStatus() called\n"); Status = IopCaptureUnicodeString(&DeviceInstance, &StatusData->DeviceInstance); if (!NT_SUCCESS(Status)) { return Status; } DPRINT("Device name: '%wZ'\n", &DeviceInstance); _SEH2_TRY { Operation = StatusData->Operation; if (Operation == PNP_SET_DEVICE_STATUS) { DeviceStatus = StatusData->DeviceStatus; DeviceProblem = StatusData->DeviceProblem; } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExFreePool(DeviceInstance.Buffer); _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; /* Get the device object */ DeviceObject = IopGetDeviceObjectFromDeviceInstance(&DeviceInstance); ExFreePool(DeviceInstance.Buffer); if (DeviceObject == NULL) { return STATUS_NO_SUCH_DEVICE; } DeviceNode = IopGetDeviceNode(DeviceObject); switch (Operation) { case PNP_GET_DEVICE_STATUS: DPRINT("Get status data\n"); DeviceStatus = IopGetDeviceNodeStatus(DeviceNode); DeviceProblem = DeviceNode->Problem; break; case PNP_SET_DEVICE_STATUS: DPRINT1("Set status data is NOT SUPPORTED\n"); break; case PNP_CLEAR_DEVICE_STATUS: DPRINT1("FIXME: Clear status data!\n"); break; } ObDereferenceObject(DeviceObject); if (Operation == PNP_GET_DEVICE_STATUS) { _SEH2_TRY { StatusData->DeviceStatus = DeviceStatus; StatusData->DeviceProblem = DeviceProblem; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; }
static NTSTATUS IopGetRelatedDevice(PPLUGPLAY_CONTROL_RELATED_DEVICE_DATA RelatedDeviceData) { UNICODE_STRING RootDeviceName; 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; } _SEH2_TRY { Relation = RelatedDeviceData->Relation; MaximumLength = RelatedDeviceData->RelatedDeviceInstanceLength; ProbeForWrite(RelatedDeviceData->RelatedDeviceInstance, MaximumLength, sizeof(WCHAR)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExFreePool(TargetDeviceInstance.Buffer); _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; RtlInitUnicodeString(&RootDeviceName, L"HTREE\\ROOT\\0"); if (RtlEqualUnicodeString(&TargetDeviceInstance, &RootDeviceName, TRUE)) { DeviceNode = IopRootDeviceNode; ExFreePool(TargetDeviceInstance.Buffer); } else { /* Get the device object */ DeviceObject = IopGetDeviceObjectFromDeviceInstance(&TargetDeviceInstance); ExFreePool(TargetDeviceInstance.Buffer); if (DeviceObject == NULL) return STATUS_NO_SUCH_DEVICE; DeviceNode = ((PEXTENDED_DEVOBJ_EXTENSION)DeviceObject->DeviceObjectExtension)->DeviceNode; } switch (Relation) { case PNP_GET_PARENT_DEVICE: RelatedDeviceNode = DeviceNode->Parent; break; case PNP_GET_CHILD_DEVICE: RelatedDeviceNode = DeviceNode->Child; break; case PNP_GET_SIBLING_DEVICE: RelatedDeviceNode = DeviceNode->Sibling; break; default: if (DeviceObject != NULL) { ObDereferenceObject(DeviceObject); } return STATUS_INVALID_PARAMETER; } if (RelatedDeviceNode == NULL) { if (DeviceObject) { ObDereferenceObject(DeviceObject); } return STATUS_NO_SUCH_DEVICE; } if (RelatedDeviceNode->InstancePath.Length > MaximumLength) { if (DeviceObject) { ObDereferenceObject(DeviceObject); } return STATUS_BUFFER_TOO_SMALL; } /* Copy related device instance name */ _SEH2_TRY { RtlCopyMemory(RelatedDeviceData->RelatedDeviceInstance, RelatedDeviceNode->InstancePath.Buffer, RelatedDeviceNode->InstancePath.Length); RelatedDeviceData->RelatedDeviceInstanceLength = RelatedDeviceNode->InstancePath.Length; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; if (DeviceObject != NULL) { ObDereferenceObject(DeviceObject); } DPRINT("IopGetRelatedDevice() done\n"); return Status; }
static NTSTATUS IopGetInterfaceDeviceList(PPLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA DeviceList) { NTSTATUS Status; UNICODE_STRING DeviceInstance; PDEVICE_OBJECT DeviceObject = NULL; ULONG BufferSize = 0; GUID FilterGuid; PZZWSTR SymbolicLinkList = NULL, LinkList; ULONG TotalLength = 0; _SEH2_TRY { ProbeForRead(DeviceList->FilterGuid, sizeof(GUID), sizeof(UCHAR)); RtlCopyMemory(&FilterGuid, DeviceList->FilterGuid, sizeof(GUID)); if (DeviceList->Buffer != NULL && DeviceList->BufferSize != 0) { BufferSize = DeviceList->BufferSize; ProbeForWrite(DeviceList->Buffer, BufferSize, sizeof(UCHAR)); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; Status = IopCaptureUnicodeString(&DeviceInstance, &DeviceList->DeviceInstance); if (NT_SUCCESS(Status)) { /* Get the device object */ DeviceObject = IopGetDeviceObjectFromDeviceInstance(&DeviceInstance); ExFreePool(DeviceInstance.Buffer); } Status = IoGetDeviceInterfaces(&FilterGuid, DeviceObject, DeviceList->Flags, &SymbolicLinkList); ObDereferenceObject(DeviceObject); if (!NT_SUCCESS(Status)) { /* failed */ return 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); if (BufferSize >= TotalLength) { RtlCopyMemory(DeviceList->Buffer, SymbolicLinkList, TotalLength * sizeof(WCHAR)); } DeviceList->BufferSize = TotalLength; ExFreePool(LinkList); return STATUS_SUCCESS; }
static NTSTATUS IopGetDeviceProperty(PPLUGPLAY_CONTROL_PROPERTY_DATA PropertyData) { PDEVICE_OBJECT DeviceObject = NULL; NTSTATUS Status; 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; } _SEH2_TRY { Property = PropertyData->Property; BufferSize = PropertyData->BufferSize; ProbeForWrite(PropertyData->Buffer, BufferSize, sizeof(UCHAR)); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExFreePool(DeviceInstance.Buffer); _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; /* Get the device object */ DeviceObject = IopGetDeviceObjectFromDeviceInstance(&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, Property, BufferSize, Buffer, &BufferSize); ObDereferenceObject(DeviceObject); if (NT_SUCCESS(Status)) { _SEH2_TRY { memcpy(PropertyData->Buffer, Buffer, BufferSize); PropertyData->BufferSize = BufferSize; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Status = _SEH2_GetExceptionCode(); } _SEH2_END; } ExFreePool(Buffer); return Status; }
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; GUID FilterGuid; PZZWSTR SymbolicLinkList = NULL, LinkList; SIZE_T TotalLength; _SEH2_TRY { RtlCopyMemory(&StackList, DeviceList, sizeof(PLUGPLAY_CONTROL_INTERFACE_DEVICE_LIST_DATA)); ProbeForRead(StackList.FilterGuid, sizeof(GUID), sizeof(UCHAR)); RtlCopyMemory(&FilterGuid, StackList.FilterGuid, sizeof(GUID)); if (StackList.Buffer != NULL && StackList.BufferSize != 0) { ProbeForWrite(StackList.Buffer, StackList.BufferSize, sizeof(UCHAR)); } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; Status = IopCaptureUnicodeString(&DeviceInstance, &StackList.DeviceInstance); if (NT_SUCCESS(Status)) { /* Get the device object */ DeviceObject = IopGetDeviceObjectFromDeviceInstance(&DeviceInstance); if (DeviceInstance.Buffer != NULL) { ExFreePool(DeviceInstance.Buffer); } } Status = IoGetDeviceInterfaces(&FilterGuid, DeviceObject, StackList.Flags, &SymbolicLinkList); ObDereferenceObject(DeviceObject); if (!NT_SUCCESS(Status)) { /* failed */ return Status; } LinkList = SymbolicLinkList; while (*SymbolicLinkList != UNICODE_NULL) { SymbolicLinkList += wcslen(SymbolicLinkList) + (sizeof(UNICODE_NULL) / sizeof(WCHAR)); } TotalLength = ((SymbolicLinkList - LinkList + 1) * sizeof(WCHAR)); _SEH2_TRY { if (StackList.Buffer != NULL && StackList.BufferSize >= TotalLength) { // We've already probed the buffer for writing above. RtlCopyMemory(StackList.Buffer, LinkList, TotalLength); } DeviceList->BufferSize = TotalLength; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExFreePool(LinkList); _SEH2_YIELD(return _SEH2_GetExceptionCode()); } _SEH2_END; ExFreePool(LinkList); return STATUS_SUCCESS; }