Beispiel #1
0
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;
    }
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}