Ejemplo n.º 1
0
NTSTATUS
NdasPortExtBuildSymbolicLinkName(
	__inout PUNICODE_STRING SymbolicLinkName,
	__in CONST GUID* ExternalTypeGuid)
{
	NTSTATUS status;
	UNICODE_STRING guidString;

	status = RtlStringFromGUID(ExternalTypeGuid, &guidString);
	if (!NT_SUCCESS(status))
	{
		return status;
	}

	status = RtlUnicodeStringCopyString(
		SymbolicLinkName, L"\\Device\\NdasPort_");
	if (!NT_SUCCESS(status))
	{
		return status;
	}

	status = RtlUnicodeStringCatUnicodeString(
		SymbolicLinkName, 
		&guidString);

	RtlFreeUnicodeString(&guidString);

	if (!NT_SUCCESS(status))
	{
		return status;
	}

	return STATUS_SUCCESS;
}
Ejemplo n.º 2
0
void kull_m_string_displayGUID(IN LPCGUID pGuid)
{
	UNICODE_STRING uString;
	if(NT_SUCCESS(RtlStringFromGUID(pGuid, &uString)))
	{
		kprintf(L"%wZ", &uString);
		RtlFreeUnicodeString(&uString);
	}
}
Ejemplo n.º 3
0
NTSTATUS
NTAPI
CPortTopology::QueryInterface(
    IN  REFIID refiid,
    OUT PVOID* Output)
{
    UNICODE_STRING GuidString;

    DPRINT("IPortTopology_fnQueryInterface\n");

    if (IsEqualGUIDAligned(refiid, IID_IPortTopology) ||
        IsEqualGUIDAligned(refiid, IID_IPort) ||
        IsEqualGUIDAligned(refiid, IID_IUnknown))
    {
        *Output = PVOID(PUNKNOWN((IPortTopology*)this));
        PUNKNOWN(*Output)->AddRef();
        return STATUS_SUCCESS;
    }
    else if (IsEqualGUIDAligned(refiid, IID_IPortEvents))
    {
        *Output = PVOID(PPORTEVENTS(this));
        PUNKNOWN(*Output)->AddRef();
        return STATUS_SUCCESS;
    }
    else if (IsEqualGUIDAligned(refiid, IID_ISubdevice))
    {
        *Output = PVOID(PSUBDEVICE(this));
        PUNKNOWN(*Output)->AddRef();
        return STATUS_SUCCESS;
    }
    else if (IsEqualGUIDAligned(refiid, IID_IPortClsVersion))
    {
        return NewPortClsVersion((PPORTCLSVERSION*)Output);
    }
    else if (IsEqualGUIDAligned(refiid, IID_IDrmPort) ||
             IsEqualGUIDAligned(refiid, IID_IDrmPort2))
    {
        return NewIDrmPort((PDRMPORT2*)Output);
    }
    else if (IsEqualGUIDAligned(refiid, IID_IUnregisterSubdevice))
    {
        return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output);
    }
    else if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection))
    {
        return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output);
    }

    if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
    {
        DPRINT1("IPortTopology_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer);
        RtlFreeUnicodeString(&GuidString);
    }
    return STATUS_UNSUCCESSFUL;
}
Ejemplo n.º 4
0
NTSTATUS
BcdOpenObject (
    _In_ HANDLE BcdHandle,
    _In_ PGUID ObjectId,
    _Out_ PHANDLE ObjectHandle
    )
{
    NTSTATUS Status;
    GUID LocalGuid;
    UNICODE_STRING GuidString;
    HANDLE RootObjectHandle;

    /* Assume failure */
    *ObjectHandle = NULL;

    /* Initialize GUID string */
    GuidString.Buffer = NULL;

    /* Open the root "Objects" handle */
    RootObjectHandle = NULL;
    Status = BiOpenKey(BcdHandle, L"Objects", &RootObjectHandle);
    if (!NT_SUCCESS(Status))
    {
        goto Quickie;
    }

    /* Capture the object ID and convert it into a string */
    LocalGuid = *ObjectId;
    Status = RtlStringFromGUID(&LocalGuid, &GuidString);
    if (!NT_SUCCESS(Status))
    {
        goto Quickie;
    }

    /* Now open the key containing this object ID */
    Status = BiOpenKey(RootObjectHandle, GuidString.Buffer, ObjectHandle);

Quickie:
    /* Free the GUID string if we had one allocated */
    if (GuidString.Buffer)
    {
        RtlFreeUnicodeString(&GuidString);
    }

    /* Close the root handle if it was open */
    if (RootObjectHandle)
    {
        BiCloseKey(RootObjectHandle);
    }

    /* Return the final status */
    return Status;
}
Ejemplo n.º 5
0
/*
 * @implemented
 */
VOID
CreateNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
{
    UUID Guid;
    PWCHAR String;
    UNICODE_STRING GuidString;

    /* Entry with no drive letter are made that way:
     * Instead of having a path with the letter,
     * you have GUID with the unique ID.
     */
    if (!NT_SUCCESS(ExUuidCreate(&Guid)))
    {
        return;
    }

    /* Convert to string */
    if (!NT_SUCCESS(RtlStringFromGUID(&Guid, &GuidString)))
    {
        return;
    }

    /* No letter entries must start with #, so allocate a proper string */
    String = AllocatePool(GuidString.Length + 2 * sizeof(WCHAR));
    if (!String)
    {
        ExFreePoolWithTag(GuidString.Buffer, 0);
        return;
    }

    /* Write the complete string */
    String[0] = L'#';
    RtlCopyMemory(String + 1, GuidString.Buffer, GuidString.Length);
    String[GuidString.Length / sizeof(WCHAR)] = UNICODE_NULL;

    /* Don't need that one anymore */
    ExFreePoolWithTag(GuidString.Buffer, 0);

    /* Write the entry */
    RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
                          DatabasePath,
                          String,
                          REG_BINARY,
                          UniqueId->UniqueId,
                          UniqueId->UniqueIdLength);

    FreePool(String);

    return;
}
Ejemplo n.º 6
0
/*
 * @implemented
 */
NTSTATUS
CreateNewVolumeName(OUT PUNICODE_STRING VolumeName,
                    IN PGUID VolumeGuid OPTIONAL)
{
    GUID Guid;
    NTSTATUS Status;
    UNICODE_STRING GuidString;

    /* If no GUID was provided, then create one */
    if (!VolumeGuid)
    {
        Status = ExUuidCreate(&Guid);
        if (!NT_SUCCESS(Status))
        {
            return Status;
        }
    }
    else
    {
        RtlCopyMemory(&Guid, VolumeGuid, sizeof(GUID));
    }

    /* Convert GUID to string */
    Status = RtlStringFromGUID(&Guid, &GuidString);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* Size for volume namespace, litteral GUID, and null char */
    VolumeName->MaximumLength = 0x14 + 0x4C + sizeof(UNICODE_NULL);
    VolumeName->Buffer = AllocatePool(0x14 + 0x4C + sizeof(UNICODE_NULL));
    if (!VolumeName->Buffer)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
    }
    else
    {
        RtlCopyUnicodeString(VolumeName, &Volume);
        RtlAppendUnicodeStringToString(VolumeName, &GuidString);
        VolumeName->Buffer[VolumeName->Length / sizeof(WCHAR)] = UNICODE_NULL;
        Status = STATUS_SUCCESS;
    }

    ExFreePoolWithTag(GuidString.Buffer, 0);

    return Status;
}
Ejemplo n.º 7
0
NTSTATUS
NTAPI
PcNewPort(
    OUT PPORT* OutPort,
    IN  REFCLSID ClassId)
{
    NTSTATUS Status;
    UNICODE_STRING GuidString;

    DPRINT("PcNewPort entered\n");

    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (!OutPort)
    {
        DPRINT("PcNewPort was supplied a NULL OutPort parameter\n");
        return STATUS_INVALID_PARAMETER;
    }

    if (IsEqualGUIDAligned(ClassId, CLSID_PortMidi))
        Status = NewPortDMus(OutPort);
    else if (IsEqualGUIDAligned(ClassId, CLSID_PortDMus))
        Status = NewPortDMus(OutPort);
    else if (IsEqualGUIDAligned(ClassId, CLSID_PortTopology))
        Status = NewPortTopology(OutPort);
    else if (IsEqualGUIDAligned(ClassId, CLSID_PortWaveCyclic))
        Status = NewPortWaveCyclic(OutPort);
    else if (IsEqualGUIDAligned(ClassId, CLSID_PortWavePci))
        Status = NewPortWavePci(OutPort);
    else if (IsEqualGUIDAligned(ClassId, CLSID_PortWaveRT))
        Status = NewPortWaveRT(OutPort);
    else
    {

        if (RtlStringFromGUID(ClassId, &GuidString) == STATUS_SUCCESS)
        {
            DPRINT("unknown interface %S\n", GuidString.Buffer);
            RtlFreeUnicodeString(&GuidString);
        }

        Status = STATUS_NOT_SUPPORTED;
        return Status;
     }
    DPRINT("PcNewPort Status %lx\n", Status);

    return Status;
}
Ejemplo n.º 8
0
MIXER_STATUS
MMixerGetDeviceNameWithComponentId(
    IN PMIXER_CONTEXT MixerContext,
    IN HANDLE hMixer,
    OUT LPWSTR OutDeviceName)
{
    MIXER_STATUS Status;
    KSPROPERTY Property;
    KSCOMPONENTID ComponentId;
    ULONG Length;
    UNICODE_STRING GuidString;
    ULONG ResultLength, KeyType;
    HANDLE hMediaKey, hGuidKey;
    LPWSTR DeviceName;

    /* prepare property */
    Property.Flags = KSPROPERTY_TYPE_GET;
    Property.Set = KSPROPSETID_General;
    Property.Id = KSPROPERTY_GENERAL_COMPONENTID;

    /* try get component id */
    Status = MixerContext->Control(hMixer, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), &ComponentId, sizeof(KSCOMPONENTID), &Length);

    if (Status == MM_STATUS_SUCCESS)
    {
        Status = MixerContext->OpenKey(NULL, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories", KEY_READ, &hMediaKey);
        if (Status == MM_STATUS_SUCCESS)
        {
            RtlStringFromGUID(&ComponentId.Name, &GuidString);
            Status = MixerContext->OpenKey(hMediaKey, GuidString.Buffer, KEY_READ, &hGuidKey);
            RtlFreeUnicodeString(&GuidString);
            if (Status == MM_STATUS_SUCCESS)
            {
                Status = MixerContext->QueryKeyValue(hGuidKey, L"Name", (PVOID*)&DeviceName, &ResultLength, &KeyType);
                if (Status == MM_STATUS_SUCCESS)
                {
                    MixerContext->Copy(OutDeviceName, DeviceName, min(ResultLength, (MAXPNAMELEN-1)*2));
                }

                MixerContext->CloseKey(hGuidKey);
            }
            MixerContext->CloseKey(hMediaKey);
        }
    }
    return Status;
}
Ejemplo n.º 9
0
NTSTATUS
NTAPI
CPortPinWavePci::HandleKsProperty(
    IN PIRP Irp)
{
    //PKSPROPERTY Property;
    NTSTATUS Status;
    //UNICODE_STRING GuidString;
    PIO_STACK_LOCATION IoStack;

    //DPRINT("IPortPinWave_HandleKsProperty entered\n");

    IoStack = IoGetCurrentIrpStackLocation(Irp);

    if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
    {
        //DPRINT("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength);
        
        Irp->IoStatus.Status = STATUS_SUCCESS;

        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return STATUS_SUCCESS;
    }

    Status = PcHandlePropertyWithTable(Irp,  m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor);

    if (Status == STATUS_NOT_FOUND)
    {
        //Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
#if 0
        RtlStringFromGUID(Property->Set, &GuidString);
        //DPRINT("Unhandled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
        RtlFreeUnicodeString(&GuidString);
#endif
    }

    if (Status != STATUS_PENDING)
    {
        Irp->IoStatus.Status = Status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }

    return Status;
}
Ejemplo n.º 10
0
NTSTATUS
NTAPI
IKsClock_DispatchDeviceIoControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN  PIRP Irp)
{
    PIO_STACK_LOCATION IoStack;
    UNICODE_STRING GuidString;
    PKSPROPERTY Property;
    NTSTATUS Status;

    DPRINT("IKsClock_DispatchDeviceIoControl\n");

    /* get current io stack */
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    /* FIXME support events */
    ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);

    /* sanity check */
    ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSPROPERTY));

    /* call property handler */
    Status = KsPropertyHandler(Irp, 1, ClockPropertySet);

    /* get property from input buffer */
    Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;

    RtlStringFromGUID(&Property->Set, &GuidString);
    DPRINT("IKsClock_DispatchDeviceIoControl property Set |%S| Id %u Flags %x Status %lx ResultLength %lu\n", GuidString.Buffer, Property->Id, Property->Flags, Status, Irp->IoStatus.Information);
    RtlFreeUnicodeString(&GuidString);


    Irp->IoStatus.Status = STATUS_SUCCESS;
    CompleteRequest(Irp, IO_NO_INCREMENT);

    return STATUS_SUCCESS;
}
Ejemplo n.º 11
0
NTSTATUS
NdasPortFdoGetExtendedInterface(
	CONST GUID* ExternalTypeGuid,
	PFILE_OBJECT* ExternalFileObject,
	PDEVICE_OBJECT* ExternalDeviceObject,
	PNDAS_LU_QUERY_NDAS_LOGICALUNIT_INTERFACE* LogicalUnitInterface)
{
	NTSTATUS status;
	UNICODE_STRING externalDeviceTypeGuidString;
	WCHAR externalDeviceNameBuffer[64];
	UNICODE_STRING externalDeviceName;
	PIRP irp;
	KEVENT event;
	IO_STATUS_BLOCK ioStatus;
	NDASPORT_EXTERNAL_TYPE_GET_INTERFACE externalTypeGetInterface;

	PAGED_CODE();

	*ExternalFileObject = NULL;
	*ExternalDeviceObject = NULL;

	RtlInitEmptyUnicodeString(
		&externalDeviceName,
		externalDeviceNameBuffer,
		sizeof(externalDeviceNameBuffer));

	status = RtlStringFromGUID(
		ExternalTypeGuid,
		&externalDeviceTypeGuidString);

	if (!NT_SUCCESS(status))
	{
		return status;
	}

	status = RtlUnicodeStringCopyString(
		&externalDeviceName,
		L"\\Device\\NdasPort_");

	ASSERT(NT_SUCCESS(status));
	if (!NT_SUCCESS(status))
	{
		return status;
	}

	status = RtlUnicodeStringCat(
		&externalDeviceName,
		&externalDeviceTypeGuidString);

	RtlFreeUnicodeString(&externalDeviceTypeGuidString);

	ASSERT(NT_SUCCESS(status));
	if (!NT_SUCCESS(status))
	{
		return status;
	}

	status = IoGetDeviceObjectPointer(
		&externalDeviceName,
		FILE_ALL_ACCESS,
		ExternalFileObject,
		ExternalDeviceObject);

	if (!NT_SUCCESS(status))
	{
		return status;
	}

	KeInitializeEvent(&event, NotificationEvent, FALSE);

	externalTypeGetInterface.Size = sizeof(NDASPORT_EXTERNAL_TYPE_GET_INTERFACE);
	externalTypeGetInterface.Version = NDASPORT_EXTERNAL_TYPE_GET_INTERFACE_VERSION;
	externalTypeGetInterface.ExternalTypeGuid = *ExternalTypeGuid;
	externalTypeGetInterface.GetInterfaceFunction = NULL;
	
	irp = IoBuildDeviceIoControlRequest(
		NDASPORTEXT_IOCTL_GET_LOGICALUNIT_INTERFACE,
		*ExternalDeviceObject,
		&externalTypeGetInterface, sizeof(NDASPORT_EXTERNAL_TYPE_GET_INTERFACE),
		&externalTypeGetInterface, sizeof(NDASPORT_EXTERNAL_TYPE_GET_INTERFACE),
		TRUE,
		&event,
		&ioStatus);

	if (NULL == irp)
	{
		status = STATUS_INSUFFICIENT_RESOURCES;
		goto error1;
	}

	status = IoCallDriver(*ExternalDeviceObject, irp);

	if (!NT_SUCCESS(status))
	{
		goto error2;
	}

	KeWaitForSingleObject(
		&event, 
		Executive, 
		KernelMode, 
		FALSE, 
		NULL);

	status = ioStatus.Status;

	if (!NT_SUCCESS(status))
	{
		goto error3;
	}
	
	*LogicalUnitInterface = externalTypeGetInterface.GetInterfaceFunction;

	return status;

error3:
error2:
error1:

	ObDereferenceObject(*ExternalFileObject);
	*ExternalDeviceObject = NULL;
	*ExternalFileObject = NULL;

	return status;
}
Ejemplo n.º 12
0
VOID
DumpAutomationTable(
    IN PPCAUTOMATION_TABLE AutomationTable,
    IN LPCWSTR DebugPrefix,
    IN LPCWSTR DebugIdentation)
{
    PPCPROPERTY_ITEM PropertyItem;
    PPCEVENT_ITEM EventItem;
    PPCMETHOD_ITEM MethodItem;
    ULONG Index;
    UNICODE_STRING GuidString;

    if (!AutomationTable)
    {
        // no table
        return;
    }

    DPRINT("=====================================================================\n");
    DPRINT("%S%S AutomationTable %p\n", DebugIdentation, DebugPrefix, AutomationTable);
    DPRINT("%S%S PropertyCount %lu\n", DebugIdentation, DebugPrefix, AutomationTable->PropertyCount);
    DPRINT("%S%S EventCount %lu\n", DebugIdentation, DebugPrefix, AutomationTable->EventCount);
    DPRINT("%S%S MethodCount %lu\n", DebugIdentation, DebugPrefix, AutomationTable->MethodCount);

    // print properties
    if (AutomationTable->PropertyCount)
    {
        if (AutomationTable->PropertyItemSize >= sizeof(PCPROPERTY_ITEM))
        {
            // get property item
            PropertyItem = (PPCPROPERTY_ITEM)AutomationTable->Properties;

            // sanity check
            ASSERT(PropertyItem);

            // display all properties associated
            for(Index = 0; Index < AutomationTable->PropertyCount; Index++)
            {
                // convert to printable string
                RtlStringFromGUID(*PropertyItem->Set, &GuidString);
                DPRINT("%SPropertyItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIdentation, Index, PropertyItem, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags);
                RtlFreeUnicodeString(&GuidString);
                // move to next item
                PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + AutomationTable->PropertyItemSize);
            }

        }
        else
        {
            DPRINT1("DRIVER BUG: property item must be at least %lu but got %lu\n", sizeof(PCPROPERTY_ITEM), AutomationTable->PropertyItemSize);
        }
    }

    // print events
    if (AutomationTable->EventCount)
    {
        if (AutomationTable->EventItemSize >= sizeof(PCEVENT_ITEM))
        {
            // get first event item
            EventItem = (PPCEVENT_ITEM)AutomationTable->Events;

            // sanity check
            ASSERT(EventItem);

            for(Index = 0; Index < AutomationTable->EventCount; Index++)
            {
                // convert to printable string
                RtlStringFromGUID(*EventItem->Set, &GuidString);
                DPRINT("%SEventItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIdentation, Index, EventItem, GuidString.Buffer, EventItem->Id, EventItem->Flags);
                RtlFreeUnicodeString(&GuidString);

                // move to next item
                EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + AutomationTable->EventItemSize);
            }
        }
        else
        {
            DPRINT1("DRIVER BUG: event item must be at least %lu but got %lu\n", sizeof(PCEVENT_ITEM), AutomationTable->EventItemSize);
        }
    }

    // print methods
    if (AutomationTable->MethodCount)
    {
        if (AutomationTable->MethodItemSize >= sizeof(PCMETHOD_ITEM))
        {
            // get first event item
            MethodItem = (PPCMETHOD_ITEM)AutomationTable->Methods;

            // sanity check
            ASSERT(MethodItem);

            for(Index = 0; Index < AutomationTable->MethodCount; Index++)
            {
                // convert to printable string
                RtlStringFromGUID(*MethodItem->Set, &GuidString);
                DPRINT("%SMethodItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIdentation, Index, MethodItem, GuidString.Buffer, MethodItem->Id, MethodItem->Flags);
                RtlFreeUnicodeString(&GuidString);

                // move to next item
                MethodItem = (PPCMETHOD_ITEM)((ULONG_PTR)MethodItem + AutomationTable->MethodItemSize);
            }

        }
        else
        {
            DPRINT1("DRIVER BUG: method item must be at least %lu but got %lu\n", sizeof(PCEVENT_ITEM), AutomationTable->MethodItemSize);
        }
    }
    DPRINT("=====================================================================\n");
}
Ejemplo n.º 13
0
NTSTATUS
NTAPI
PropertyItemDispatch(
    IN PIRP Irp,
    IN PKSIDENTIFIER  Request,
    IN OUT PVOID  Data)
{
    PPCPROPERTY_REQUEST PropertyRequest;
    PSUBDEVICE_DESCRIPTOR Descriptor;
    PKSPROPERTY Property;
    PPCNODE_DESCRIPTOR NodeDescriptor;
    PKSNODEPROPERTY NodeProperty;
    PKSPROPERTY_SET PropertySet;
    PPCPROPERTY_ITEM PropertyItem;
    PPCAUTOMATION_TABLE NodeAutomation;
    PIO_STACK_LOCATION IoStack;
    ULONG InstanceSize, ValueSize, Index;
    PVOID Instance;
    NTSTATUS Status;

    // allocate a property request
    PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS);
    if (!PropertyRequest)
        return STATUS_INSUFFICIENT_RESOURCES;

    // grab device descriptor
    Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);

    // get current irp stack
    IoStack = IoGetCurrentIrpStackLocation(Irp);

    // get input property request
    Property = (PKSPROPERTY)Request;

    // get property set
    PropertySet = (PKSPROPERTY_SET)KSPROPERTY_SET_IRP_STORAGE(Irp);

    // sanity check
    PC_ASSERT(Descriptor);
    PC_ASSERT(Descriptor->UnknownMiniport);

    // get instance / value size
    InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength;
    Instance = Request;
    ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength;

    // initialize property request
    PropertyRequest->MajorTarget = Descriptor->UnknownMiniport;
    PropertyRequest->MinorTarget = Descriptor->UnknownStream;
    PropertyRequest->Irp = Irp;
    PropertyRequest->Verb = Property->Flags;


    // check if this is filter / pin property request
    if (!(Property->Flags & KSPROPERTY_TYPE_TOPOLOGY))
    {
        // adjust input buffer size
        InstanceSize -= sizeof(KSPROPERTY);
        Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSPROPERTY));

        // filter / pin property request dont use node field
        PropertyRequest->Node = MAXULONG;
    }
    else if (InstanceSize >= sizeof(KSNODEPROPERTY))
    {
        // request is for a node
        InstanceSize -= sizeof(KSNODEPROPERTY);
        Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSNODEPROPERTY));

        // cast node property request
        NodeProperty = (PKSNODEPROPERTY)Request;

        // store node id
        PropertyRequest->Node = NodeProperty->NodeId;
    }
    else
    {
        // invalid buffer size
        return STATUS_INVALID_BUFFER_SIZE;
    }

    // store instance size
    PropertyRequest->InstanceSize = InstanceSize;
    PropertyRequest->Instance = (InstanceSize != 0 ? Instance : NULL);

    // store value size
    PropertyRequest->ValueSize = ValueSize;
    PropertyRequest->Value = Data;

    // now scan the property set for the attached property set item stored in Relations member
    if (PropertySet)
    {
        // sanity check
        PC_ASSERT(IsEqualGUIDAligned(Property->Set, *PropertySet->Set));

        for(Index = 0; Index < PropertySet->PropertiesCount; Index++)
        {
            // check if they got the same property id
            if (PropertySet->PropertyItem[Index].PropertyId == Property->Id)
            {
                // found item
                PropertyRequest->PropertyItem = (const PCPROPERTY_ITEM*)PropertySet->PropertyItem[Index].Relations;

                // done
                break;
            }
        }
    }

    // check if there has been a property set item attached
    if (!PropertyRequest->PropertyItem)
    {
        // is topology node id valid
        if (PropertyRequest->Node < Descriptor->DeviceDescriptor->NodeCount)
        {
            // get node descriptor
            NodeDescriptor = (PPCNODE_DESCRIPTOR) ((ULONG_PTR)Descriptor->DeviceDescriptor->Nodes + PropertyRequest->Node * Descriptor->DeviceDescriptor->NodeSize);

            // get node automation table
            NodeAutomation = (PPCAUTOMATION_TABLE)NodeDescriptor->AutomationTable;

            // has it got a automation table
            if (NodeAutomation)
            {
                // now scan the properties and check if it supports this request
                PropertyItem = (PPCPROPERTY_ITEM)NodeAutomation->Properties;
                for(Index = 0; Index < NodeAutomation->PropertyCount; Index++)
                {
                    // are they same property
                    if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Set))
                    {
                        if (PropertyItem->Id == Property->Id)
                        {
                            // found match
                            PropertyRequest->PropertyItem = PropertyItem;
                            DPRINT("Using property item %p\n", PropertyItem);
                            // done
                            break;
                        }
                    }

                    // move to next property item
                    PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeAutomation->PropertyItemSize);
                }
            }
        }
    }

    if (PropertyRequest->PropertyItem && PropertyRequest->PropertyItem->Handler)
    {
        // now call the handler
        UNICODE_STRING GuidBuffer;
        RtlStringFromGUID(Property->Set, &GuidBuffer);
        DPRINT("Calling Node %lu MajorTarget %p MinorTarget %p PropertySet %S PropertyId %lu PropertyFlags %lx InstanceSize %lu ValueSize %lu Handler %p PropertyRequest %p PropertyItemFlags %lx PropertyItemId %lu\n",
               PropertyRequest->Node, PropertyRequest->MajorTarget, PropertyRequest->MinorTarget, GuidBuffer.Buffer, Property->Id, Property->Flags, PropertyRequest->InstanceSize, PropertyRequest->ValueSize,
               PropertyRequest->PropertyItem->Handler, PropertyRequest, PropertyRequest->PropertyItem->Flags, PropertyRequest->PropertyItem->Id);
        RtlFreeUnicodeString(&GuidBuffer);
        Status = PropertyRequest->PropertyItem->Handler(PropertyRequest);
        DPRINT("Status %lx ValueSize %lu Information %lu\n", Status, PropertyRequest->ValueSize, Irp->IoStatus.Information);
        Irp->IoStatus.Information = PropertyRequest->ValueSize;

        if (Status != STATUS_PENDING)
        {
            // free property request
            FreeItem(PropertyRequest, TAG_PORTCLASS);
        }
    }
    else
    {
        FreeItem(PropertyRequest, TAG_PORTCLASS);
        Status = STATUS_NOT_FOUND;
    }

    /* done */
    return Status;
}
Ejemplo n.º 14
0
NTSTATUS
NTAPI
IntCreateNewRegistryPath(
    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension)
{
    static UNICODE_STRING VideoIdValueName = RTL_CONSTANT_STRING(L"VideoId");
    static UNICODE_STRING ControlVideoPathName =
        RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\");
    HANDLE DevInstRegKey, SettingsKey, NewKey;
    UCHAR VideoIdBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + GUID_STRING_LENGTH];
    UNICODE_STRING VideoIdString;
    UUID VideoId;
    PKEY_VALUE_PARTIAL_INFORMATION ValueInformation ;
    NTSTATUS Status;
    ULONG ResultLength;
    USHORT KeyMaxLength;
    OBJECT_ATTRIBUTES ObjectAttributes;

    /* Open the hardware key: HKLM\System\CurrentControlSet\Enum\... */
    Status = IoOpenDeviceRegistryKey(DeviceExtension->PhysicalDeviceObject,
                                     PLUGPLAY_REGKEY_DEVICE,
                                     KEY_ALL_ACCESS,
                                     &DevInstRegKey);
    if (Status != STATUS_SUCCESS)
    {
        ERR_(VIDEOPRT, "IoOpenDeviceRegistryKey failed: status 0x%lx\n", Status);
        return Status;
    }

    /* Query the VideoId value */
    ValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)VideoIdBuffer;
    Status = ZwQueryValueKey(DevInstRegKey,
                             &VideoIdValueName,
                             KeyValuePartialInformation,
                             ValueInformation,
                             sizeof(VideoIdBuffer),
                             &ResultLength);
    if (!NT_SUCCESS(Status))
    {
        /* Create a new video Id */
        Status = ExUuidCreate(&VideoId);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "ExUuidCreate failed: status 0x%lx\n", Status);
            ObCloseHandle(DevInstRegKey, KernelMode);
            return Status;
        }

        /* Convert the GUID into a string */
        Status = RtlStringFromGUID(&VideoId, &VideoIdString);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "RtlStringFromGUID failed: status 0x%lx\n", Status);
            ObCloseHandle(DevInstRegKey, KernelMode);
            return Status;
        }

        /* Copy the GUID String to our buffer */
        ValueInformation->DataLength = min(VideoIdString.Length, GUID_STRING_LENGTH);
        RtlCopyMemory(ValueInformation->Data,
                      VideoIdString.Buffer,
                      ValueInformation->DataLength);

        /* Free the GUID string */
        RtlFreeUnicodeString(&VideoIdString);

        /* Write the VideoId registry value */
        Status = ZwSetValueKey(DevInstRegKey,
                               &VideoIdValueName,
                               0,
                               REG_SZ,
                               ValueInformation->Data,
                               ValueInformation->DataLength);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "ZwSetValueKey failed: status 0x%lx\n", Status);
            ObCloseHandle(DevInstRegKey, KernelMode);
            return Status;
        }
    }

    /* Initialize the VideoId string from the registry data */
    VideoIdString.Buffer = (PWCHAR)ValueInformation->Data;
    VideoIdString.Length = (USHORT)ValueInformation->DataLength;
    VideoIdString.MaximumLength = VideoIdString.Length;

    /* Close the hardware key */
    ObCloseHandle(DevInstRegKey, KernelMode);

    /* Calculate the size needed for the new registry path name */
    KeyMaxLength = ControlVideoPathName.Length +
                   VideoIdString.Length +
                   sizeof(L"\\0000");

    /* Allocate the path name buffer */
    DeviceExtension->NewRegistryPath.Length = 0;
    DeviceExtension->NewRegistryPath.MaximumLength = KeyMaxLength;
    DeviceExtension->NewRegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool,
                                                                    KeyMaxLength,
                                                                    TAG_VIDEO_PORT);
    if (DeviceExtension->NewRegistryPath.Buffer == NULL)
    {
        ERR_(VIDEOPRT, "Failed to allocate key name buffer.\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Copy the root key name and append the VideoId string */
    RtlCopyUnicodeString(&DeviceExtension->NewRegistryPath,
                         &ControlVideoPathName);
    RtlAppendUnicodeStringToString(&DeviceExtension->NewRegistryPath,
                                   &VideoIdString);

    /* Check if we have the key already */
    Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE,
                                 DeviceExtension->NewRegistryPath.Buffer);
    if (Status != STATUS_SUCCESS)
    {
        /* Try to create the new key */
        Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE,
                                      DeviceExtension->NewRegistryPath.Buffer);
    }

    /* Append a the instance path */ /// \todo HACK
    RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"\\");
    RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"0000");

    /* Check this key again */
    Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE,
                                 DeviceExtension->NewRegistryPath.Buffer);
    if (Status != STATUS_SUCCESS)
    {
        /* Try to create the new key */
        Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE,
                                      DeviceExtension->NewRegistryPath.Buffer);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "Failed create key '%wZ'\n", &DeviceExtension->NewRegistryPath);
            return Status;
        }

        /* Open the new key */
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DeviceExtension->NewRegistryPath,
                                   OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                   NULL,
                                   NULL);
        Status = ZwOpenKey(&NewKey, KEY_READ, &ObjectAttributes);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status);
            return Status;
        }

        /* Open the device profile key */
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DeviceExtension->RegistryPath,
                                   OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                   NULL,
                                   NULL);
        Status = ZwOpenKey(&SettingsKey, KEY_READ, &ObjectAttributes);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status);
            ObCloseHandle(NewKey, KernelMode);
            return Status;
        }

        /* Copy the registry data from the legacy key */
        Status = IntCopyRegistryKey(SettingsKey, NewKey);
    }


    return Status;
}
Ejemplo n.º 15
0
NTSTATUS NTAPI
PdoDispatchPnp(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
{
    ULONG MinorFunction;
    PIO_STACK_LOCATION Stack;
    ULONG_PTR Information = Irp->IoStatus.Information;
    NTSTATUS Status = Irp->IoStatus.Status;
    PDEVICE_CAPABILITIES DeviceCapabilities;
    ULONG i;

    Stack = IoGetCurrentIrpStackLocation(Irp);
    MinorFunction = Stack->MinorFunction;

    switch (MinorFunction)
    {
    case IRP_MN_QUERY_REMOVE_DEVICE:
    case IRP_MN_REMOVE_DEVICE:
    case IRP_MN_CANCEL_REMOVE_DEVICE:
    case IRP_MN_STOP_DEVICE:
    case IRP_MN_QUERY_STOP_DEVICE:
    case IRP_MN_CANCEL_STOP_DEVICE:
    case IRP_MN_QUERY_DEVICE_TEXT:
    case IRP_MN_SURPRISE_REMOVAL:
    case IRP_MN_QUERY_RESOURCES:
    case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
    case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
    {
        Status = STATUS_SUCCESS;
        break;
    }

    case IRP_MN_START_DEVICE:
    {
        PUSB_DEVICE RootHubDevice;
        PPDO_DEVICE_EXTENSION PdoDeviceExtension;
        PFDO_DEVICE_EXTENSION FdoDeviceExtension;
        UNICODE_STRING InterfaceSymLinkName;

        DPRINT1("Ehci: PDO StartDevice\n");
        PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
        FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;

        /* Create the root hub */
        RootHubDevice = InternalCreateUsbDevice(1, 0, NULL, TRUE);

        RtlCopyMemory(&RootHubDevice->DeviceDescriptor,
                      ROOTHUB2_DEVICE_DESCRIPTOR,
                      sizeof(ROOTHUB2_DEVICE_DESCRIPTOR));

        RootHubDevice->DeviceDescriptor.idVendor = FdoDeviceExtension->VendorId;
        RootHubDevice->DeviceDescriptor.idProduct = FdoDeviceExtension->DeviceId;

        /* Here config, interfaces and descriptors are stored. This was duplicated from XEN PV Usb Drivers implementation.
           Not sure that it is really needed as the information can be queueried from the device. */

        RootHubDevice->Configs = ExAllocatePoolWithTag(NonPagedPool,
                                 sizeof(PVOID) * RootHubDevice->DeviceDescriptor.bNumConfigurations,
                                 USB_POOL_TAG);

        RootHubDevice->Configs[0] = ExAllocatePoolWithTag(NonPagedPool,
                                    sizeof(USB_CONFIGURATION) + sizeof(PVOID) * ROOTHUB2_CONFIGURATION_DESCRIPTOR[4],
                                    USB_POOL_TAG);

        RootHubDevice->Configs[0]->Interfaces[0] = ExAllocatePoolWithTag(NonPagedPool,
                sizeof(USB_INTERFACE) + sizeof(PVOID) * ROOTHUB2_INTERFACE_DESCRIPTOR[4],
                USB_POOL_TAG);

        RootHubDevice->Configs[0]->Interfaces[0]->EndPoints[0] = ExAllocatePoolWithTag(NonPagedPool,
                sizeof(USB_ENDPOINT),
                USB_POOL_TAG);

        RootHubDevice->ActiveConfig = RootHubDevice->Configs[0];
        RootHubDevice->ActiveInterface = RootHubDevice->ActiveConfig->Interfaces[0];

        RtlCopyMemory(&RootHubDevice->ActiveConfig->ConfigurationDescriptor,
                      ROOTHUB2_CONFIGURATION_DESCRIPTOR,
                      sizeof(ROOTHUB2_CONFIGURATION_DESCRIPTOR));

        RtlCopyMemory(&RootHubDevice->ActiveConfig->Interfaces[0]->InterfaceDescriptor,
                      ROOTHUB2_INTERFACE_DESCRIPTOR,
                      sizeof(ROOTHUB2_INTERFACE_DESCRIPTOR));

        RtlCopyMemory(&RootHubDevice->ActiveConfig->Interfaces[0]->EndPoints[0]->EndPointDescriptor,
                      ROOTHUB2_ENDPOINT_DESCRIPTOR,
                      sizeof(ROOTHUB2_ENDPOINT_DESCRIPTOR));
        RootHubDevice->DeviceSpeed = UsbHighSpeed;
        RootHubDevice->DeviceType = Usb20Device;

        PdoDeviceExtension->UsbDevices[0] = RootHubDevice;

        Status = IoRegisterDeviceInterface(DeviceObject, &GUID_DEVINTERFACE_USB_HUB, NULL, &InterfaceSymLinkName);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Failed to register interface\n");
            return Status;
        }
        else
        {
            Status = IoSetDeviceInterfaceState(&InterfaceSymLinkName, TRUE);
            if (!NT_SUCCESS(Status))
                return Status;
        }

        Status = STATUS_SUCCESS;
        break;
    }
    case IRP_MN_QUERY_DEVICE_RELATIONS:
    {
        DPRINT1("Ehci: PDO QueryDeviceRelations\n");
        switch (Stack->Parameters.QueryDeviceRelations.Type)
        {
        case TargetDeviceRelation:
        {
            PDEVICE_RELATIONS DeviceRelations = NULL;
            Status = PdoQueryDeviceRelations(DeviceObject, &DeviceRelations);
            Information = (ULONG_PTR)DeviceRelations;
            break;
        }
        case BusRelations:
        {
            PPDO_DEVICE_EXTENSION PdoDeviceExtension;
            PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

            DPRINT("BusRelations!!!!!\n");

            /* The hub driver has created the new device object and reported to pnp, as a result the pnp manager
               has sent this IRP and type, so leave the next SCE request pending until a new device arrives.
               Is there a better way to do this? */
            ExAcquireFastMutex(&PdoDeviceExtension->ListLock);
            PdoDeviceExtension->HaltQueue = TRUE;
            ExReleaseFastMutex(&PdoDeviceExtension->ListLock);
        }
        case RemovalRelations:
        case EjectionRelations:
        {
            /* Ignore the request */
            Information = Irp->IoStatus.Information;
            Status = Irp->IoStatus.Status;
            break;

        }
        default:
        {
            DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unhandled type 0x%lx\n",
                    Stack->Parameters.QueryDeviceRelations.Type);
            Status = STATUS_NOT_SUPPORTED;
            break;
        }
        }
        break;
    }
    case IRP_MN_QUERY_CAPABILITIES:
    {
        DPRINT("Ehci: PDO Query Capabilities\n");

        DeviceCapabilities = (PDEVICE_CAPABILITIES)Stack->Parameters.DeviceCapabilities.Capabilities;

        DeviceCapabilities->LockSupported = FALSE;
        DeviceCapabilities->EjectSupported = FALSE;
        DeviceCapabilities->Removable = FALSE;
        DeviceCapabilities->DockDevice = FALSE;
        DeviceCapabilities->UniqueID = FALSE;
        DeviceCapabilities->SilentInstall = FALSE;
        DeviceCapabilities->RawDeviceOK = FALSE;
        DeviceCapabilities->SurpriseRemovalOK = FALSE;
        DeviceCapabilities->Address = 0;
        DeviceCapabilities->UINumber = 0;
        DeviceCapabilities->DeviceD2 = 1;

        /* FIXME: Verify these settings are correct */
        DeviceCapabilities->HardwareDisabled = FALSE;
        //DeviceCapabilities->NoDisplayInUI = FALSE;
        DeviceCapabilities->DeviceState[0] = PowerDeviceD0;
        for (i = 0; i < PowerSystemMaximum; i++)
            DeviceCapabilities->DeviceState[i] = PowerDeviceD3;
        DeviceCapabilities->DeviceWake = 0;
        DeviceCapabilities->D1Latency = 0;
        DeviceCapabilities->D2Latency = 0;
        DeviceCapabilities->D3Latency = 0;
        Information = 0;
        Status = STATUS_SUCCESS;
        break;
    }
    /*case IRP_MN_QUERY_DEVICE_TEXT:
    {
        Status = STATUS_NOT_SUPPORTED;
        break;
    }*/

    case IRP_MN_QUERY_ID:
    {
        DPRINT("Ehci: PDO Query ID\n");
        Status = PdoQueryId(DeviceObject, Irp, &Information);
        break;
    }
    case IRP_MN_QUERY_INTERFACE:
    {
        UNICODE_STRING GuidString;
        PUSB_BUS_INTERFACE_HUB_V5 InterfaceHub;
        PUSB_BUS_INTERFACE_USBDI_V2 InterfaceDI;
        PPDO_DEVICE_EXTENSION PdoDeviceExtension;
        PFDO_DEVICE_EXTENSION FdoDeviceExtension;

        DPRINT("Ehci: PDO Query Interface\n");

        PdoDeviceExtension = (PPDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
        FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)PdoDeviceExtension->ControllerFdo->DeviceExtension;

        Status = RtlStringFromGUID(Stack->Parameters.QueryInterface.InterfaceType, &GuidString);
        if (!NT_SUCCESS(Status))
        {
            DPRINT1("Failed to create string from GUID!\n");
        }

        /* Assume success */
        Status = STATUS_SUCCESS;
        Information = 0;

        if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_HUB_GUID))
        {
            InterfaceHub = (PUSB_BUS_INTERFACE_HUB_V5)Stack->Parameters.QueryInterface.Interface;
            InterfaceHub->Version = Stack->Parameters.QueryInterface.Version;
            if (Stack->Parameters.QueryInterface.Version >= 0)
            {
                InterfaceHub->Size = Stack->Parameters.QueryInterface.Size;
                InterfaceHub->BusContext = PdoDeviceExtension->DeviceObject;
                InterfaceHub->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
                InterfaceHub->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
            }
            if (Stack->Parameters.QueryInterface.Version >= 1)
            {
                InterfaceHub->CreateUsbDevice = CreateUsbDevice;
                InterfaceHub->InitializeUsbDevice = InitializeUsbDevice;
                InterfaceHub->GetUsbDescriptors = GetUsbDescriptors;
                InterfaceHub->RemoveUsbDevice = RemoveUsbDevice;
                InterfaceHub->RestoreUsbDevice = RestoreUsbDevice;
                InterfaceHub->GetPortHackFlags = GetPortHackFlags;
                InterfaceHub->QueryDeviceInformation = QueryDeviceInformation;
            }
            if (Stack->Parameters.QueryInterface.Version >= 2)
            {
                InterfaceHub->GetControllerInformation = GetControllerInformation;
                InterfaceHub->ControllerSelectiveSuspend = ControllerSelectiveSuspend;
                InterfaceHub->GetExtendedHubInformation = GetExtendedHubInformation;
                InterfaceHub->GetRootHubSymbolicName = GetRootHubSymbolicName;
                InterfaceHub->GetDeviceBusContext = GetDeviceBusContext;
                InterfaceHub->Initialize20Hub = Initialize20Hub;

            }
            if (Stack->Parameters.QueryInterface.Version >= 3)
            {
                InterfaceHub->RootHubInitNotification = RootHubInitNotification;
            }
            if (Stack->Parameters.QueryInterface.Version >= 4)
            {
                InterfaceHub->FlushTransfers = FlushTransfers;
            }
            if (Stack->Parameters.QueryInterface.Version >= 5)
            {
                InterfaceHub->SetDeviceHandleData = SetDeviceHandleData;
            }
            if (Stack->Parameters.QueryInterface.Version >= 6)
            {
                DPRINT1("USB_BUS_INTERFACE_HUB_GUID version not supported!\n");
            }
            break;
        }

        if (IsEqualGUIDAligned(Stack->Parameters.QueryInterface.InterfaceType, &USB_BUS_INTERFACE_USBDI_GUID))
        {
            InterfaceDI = (PUSB_BUS_INTERFACE_USBDI_V2) Stack->Parameters.QueryInterface.Interface;
            InterfaceDI->Version = Stack->Parameters.QueryInterface.Version;
            if (Stack->Parameters.QueryInterface.Version >= 0)
            {
                //InterfaceDI->Size = sizeof(USB_BUS_INTERFACE_USBDI_V2);
                InterfaceDI->Size = Stack->Parameters.QueryInterface.Size;
                InterfaceDI->BusContext = PdoDeviceExtension->DeviceObject;
                InterfaceDI->InterfaceReference = (PINTERFACE_REFERENCE)InterfaceReference;
                InterfaceDI->InterfaceDereference = (PINTERFACE_DEREFERENCE)InterfaceDereference;
                InterfaceDI->GetUSBDIVersion = GetUSBDIVersion;
                InterfaceDI->QueryBusTime = QueryBusTime;
                InterfaceDI->SubmitIsoOutUrb = SubmitIsoOutUrb;
                InterfaceDI->QueryBusInformation = QueryBusInformation;
            }
            if (Stack->Parameters.QueryInterface.Version >= 1)
            {
                InterfaceDI->IsDeviceHighSpeed = IsDeviceHighSpeed;
            }
            if (Stack->Parameters.QueryInterface.Version >= 2)
            {
                InterfaceDI->EnumLogEntry = EnumLogEntry;
            }

            if (Stack->Parameters.QueryInterface.Version >= 3)
            {
                DPRINT1("SB_BUS_INTERFACE_USBDI_GUID version not supported!\n");
            }
            break;
        }

        DPRINT1("GUID Not Supported\n");
        Status = Irp->IoStatus.Status;
        Information = Irp->IoStatus.Information;

        break;
    }
    case IRP_MN_QUERY_BUS_INFORMATION:
    {
        PPNP_BUS_INFORMATION BusInfo;

        BusInfo = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION));
        if (!BusInfo)
            Status = STATUS_INSUFFICIENT_RESOURCES;
        else
        {
            /* FIXME */
            /*RtlCopyMemory(
                &BusInfo->BusTypeGuid,
                &GUID_DEVINTERFACE_XXX,
                sizeof(GUID));*/

            BusInfo->LegacyBusType = PNPBus;
            BusInfo->BusNumber = 0;
            Information = (ULONG_PTR)BusInfo;
            Status = STATUS_SUCCESS;
        }
        break;
    }
    default:
    {
        /* We are the PDO. So ignore */
        DPRINT1("IRP_MJ_PNP / Unknown minor function 0x%lx\n", MinorFunction);
        break;
    }
    }

    Irp->IoStatus.Information = Information;
    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return Status;
}
Ejemplo n.º 16
0
// start event dispatching
NTSTATUS
DokanEventStart(__in PDEVICE_OBJECT DeviceObject, _Inout_ PIRP Irp) {
  ULONG outBufferLen;
  ULONG inBufferLen;
  PIO_STACK_LOCATION irpSp = NULL;
  PEVENT_START eventStart = NULL;
  PEVENT_DRIVER_INFO driverInfo = NULL;
  PDOKAN_GLOBAL dokanGlobal = NULL;
  PDokanDCB dcb = NULL;
  NTSTATUS status;
  DEVICE_TYPE deviceType;
  ULONG deviceCharacteristics = 0;
  WCHAR *baseGuidString;
  GUID baseGuid = DOKAN_BASE_GUID;
  UNICODE_STRING unicodeGuid;
  ULONG deviceNamePos;
  BOOLEAN useMountManager = FALSE;
  BOOLEAN mountGlobally = TRUE;
  BOOLEAN fileLockUserMode = FALSE;

  DDbgPrint("==> DokanEventStart\n");

  dokanGlobal = DeviceObject->DeviceExtension;
  if (GetIdentifierType(dokanGlobal) != DGL) {
    return STATUS_INVALID_PARAMETER;
  }

  irpSp = IoGetCurrentIrpStackLocation(Irp);

  outBufferLen = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
  inBufferLen = irpSp->Parameters.DeviceIoControl.InputBufferLength;

  eventStart = ExAllocatePool(sizeof(EVENT_START));
  baseGuidString = ExAllocatePool(64 * sizeof(WCHAR));

  if (outBufferLen != sizeof(EVENT_DRIVER_INFO) ||
      inBufferLen != sizeof(EVENT_START) || eventStart == NULL ||
      baseGuidString == NULL) {
    if (eventStart)
      ExFreePool(eventStart);
    if (baseGuidString)
      ExFreePool(baseGuidString);
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  RtlCopyMemory(eventStart, Irp->AssociatedIrp.SystemBuffer,
                sizeof(EVENT_START));
  driverInfo = Irp->AssociatedIrp.SystemBuffer;

  if (eventStart->UserVersion != DOKAN_DRIVER_VERSION) {
    driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;
    driverInfo->Status = DOKAN_START_FAILED;
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);
    ExFreePool(eventStart);
    ExFreePool(baseGuidString);
    return STATUS_SUCCESS;
  }

  switch (eventStart->DeviceType) {
  case DOKAN_DISK_FILE_SYSTEM:
    deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
    break;
  case DOKAN_NETWORK_FILE_SYSTEM:
    deviceType = FILE_DEVICE_NETWORK_FILE_SYSTEM;
    deviceCharacteristics |= FILE_REMOTE_DEVICE;
    break;
  default:
    DDbgPrint("  Unknown device type: %d\n", eventStart->DeviceType);
    deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
  }

  if (eventStart->Flags & DOKAN_EVENT_REMOVABLE) {
    DDbgPrint("  DeviceCharacteristics |= FILE_REMOVABLE_MEDIA\n");
    deviceCharacteristics |= FILE_REMOVABLE_MEDIA;
  }

  if (eventStart->Flags & DOKAN_EVENT_WRITE_PROTECT) {
    DDbgPrint("  DeviceCharacteristics |= FILE_READ_ONLY_DEVICE\n");
    deviceCharacteristics |= FILE_READ_ONLY_DEVICE;
  }

  if (eventStart->Flags & DOKAN_EVENT_MOUNT_MANAGER) {
    DDbgPrint("  Using Mount Manager\n");
    useMountManager = TRUE;
  }

  if (eventStart->Flags & DOKAN_EVENT_CURRENT_SESSION) {
    DDbgPrint("  Mounting on current session only\n");
    mountGlobally = FALSE;
  }

  if (eventStart->Flags & DOKAN_EVENT_FILELOCK_USER_MODE) {
    DDbgPrint("  FileLock in User Mode\n");
    fileLockUserMode = TRUE;
  }

  KeEnterCriticalRegion();
  ExAcquireResourceExclusiveLite(&dokanGlobal->Resource, TRUE);

  DOKAN_CONTROL dokanControl;
  RtlZeroMemory(&dokanControl, sizeof(dokanControl));
  RtlStringCchCopyW(dokanControl.MountPoint, MAXIMUM_FILENAME_LENGTH,
                    L"\\DosDevices\\");
  if (wcslen(eventStart->MountPoint) == 1) {
    dokanControl.MountPoint[12] = towupper(eventStart->MountPoint[0]);
    dokanControl.MountPoint[13] = L':';
    dokanControl.MountPoint[14] = L'\0';
  } else {
    RtlStringCchCatW(dokanControl.MountPoint, MAXIMUM_FILENAME_LENGTH,
                     eventStart->MountPoint);
  }

  DDbgPrint("  Checking for MountPoint %ls \n", dokanControl.MountPoint);
  PMOUNT_ENTRY foundEntry = FindMountEntry(dokanGlobal, &dokanControl, FALSE);
  if (foundEntry != NULL) {
    DDbgPrint("  MountPoint exists already %ls \n", dokanControl.MountPoint);
    driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;
    driverInfo->Status = DOKAN_START_FAILED;
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);
    ExReleaseResourceLite(&dokanGlobal->Resource);
    KeLeaveCriticalRegion();
    ExFreePool(eventStart);
    ExFreePool(baseGuidString);
    return STATUS_SUCCESS;
  }

  baseGuid.Data2 = (USHORT)(dokanGlobal->MountId & 0xFFFF) ^ baseGuid.Data2;
  baseGuid.Data3 = (USHORT)(dokanGlobal->MountId >> 16) ^ baseGuid.Data3;

  status = RtlStringFromGUID(&baseGuid, &unicodeGuid);
  if (!NT_SUCCESS(status)) {
    ExReleaseResourceLite(&dokanGlobal->Resource);
    KeLeaveCriticalRegion();
    ExFreePool(eventStart);
    ExFreePool(baseGuidString);
    return status;
  }
  RtlZeroMemory(baseGuidString, 64 * sizeof(WCHAR));
  RtlStringCchCopyW(baseGuidString, 64,
                    unicodeGuid.Buffer);
  RtlFreeUnicodeString(&unicodeGuid);

  InterlockedIncrement((LONG *)&dokanGlobal->MountId);

  status = DokanCreateDiskDevice(
      DeviceObject->DriverObject, dokanGlobal->MountId, eventStart->MountPoint,
      eventStart->UNCName, baseGuidString, dokanGlobal, deviceType,
      deviceCharacteristics, mountGlobally, useMountManager, &dcb);

  if (!NT_SUCCESS(status)) {
    ExReleaseResourceLite(&dokanGlobal->Resource);
    KeLeaveCriticalRegion();
    ExFreePool(eventStart);
    ExFreePool(baseGuidString);
    return status;
  }

  dcb->FileLockInUserMode = fileLockUserMode;

  DDbgPrint("  MountId:%d\n", dcb->MountId);
  driverInfo->DeviceNumber = dokanGlobal->MountId;
  driverInfo->MountId = dokanGlobal->MountId;
  driverInfo->Status = DOKAN_MOUNTED;
  driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;

  // SymbolicName is
  // \\DosDevices\\Global\\Volume{D6CC17C5-1734-4085-BCE7-964F1E9F5DE9}
  // Finds the last '\' and copy into DeviceName.
  // DeviceName is \Volume{D6CC17C5-1734-4085-BCE7-964F1E9F5DE9}
  deviceNamePos = dcb->SymbolicLinkName->Length / sizeof(WCHAR) - 1;
  for (; dcb->SymbolicLinkName->Buffer[deviceNamePos] != L'\\'; --deviceNamePos)
    ;
  RtlStringCchCopyW(driverInfo->DeviceName,
                    sizeof(driverInfo->DeviceName) / sizeof(WCHAR),
                    &(dcb->SymbolicLinkName->Buffer[deviceNamePos]));

  // Set the irp timeout in milliseconds
  // If the IrpTimeout is 0, we assume that the value was not changed
  dcb->IrpTimeout = DOKAN_IRP_PENDING_TIMEOUT;
  if (eventStart->IrpTimeout > 0) {
    if (eventStart->IrpTimeout > DOKAN_IRP_PENDING_TIMEOUT_RESET_MAX) {
      eventStart->IrpTimeout = DOKAN_IRP_PENDING_TIMEOUT_RESET_MAX;
    }

    if (eventStart->IrpTimeout < DOKAN_IRP_PENDING_TIMEOUT) {
      eventStart->IrpTimeout = DOKAN_IRP_PENDING_TIMEOUT;
    }
    dcb->IrpTimeout = eventStart->IrpTimeout;
  }

  DDbgPrint("  DeviceName:%ws\n", driverInfo->DeviceName);

  dcb->UseAltStream = 0;
  if (eventStart->Flags & DOKAN_EVENT_ALTERNATIVE_STREAM_ON) {
    DDbgPrint("  ALT_STREAM_ON\n");
    dcb->UseAltStream = 1;
  }

  DokanStartEventNotificationThread(dcb);

  ExReleaseResourceLite(&dokanGlobal->Resource);
  KeLeaveCriticalRegion();

  IoVerifyVolume(dcb->DeviceObject, FALSE);

  Irp->IoStatus.Status = STATUS_SUCCESS;
  Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);

  ExFreePool(eventStart);
  ExFreePool(baseGuidString);

  DDbgPrint("<== DokanEventStart\n");

  return Irp->IoStatus.Status;
}
Ejemplo n.º 17
0
/*++
 * @name IopOpenInterfaceKey
 *
 * Returns the alias device interface of the specified device interface
 *
 * @param InterfaceClassGuid
 *        FILLME
 *
 * @param DesiredAccess
 *        FILLME
 *
 * @param pInterfaceKey
 *        FILLME
 *
 * @return Usual NTSTATUS
 *
 * @remarks None
 *
 *--*/
static NTSTATUS
IopOpenInterfaceKey(IN CONST GUID *InterfaceClassGuid,
                    IN ACCESS_MASK DesiredAccess,
                    OUT HANDLE *pInterfaceKey)
{
    UNICODE_STRING LocalMachine = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\");
    UNICODE_STRING GuidString;
    UNICODE_STRING KeyName;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE InterfaceKey = INVALID_HANDLE_VALUE;
    NTSTATUS Status;

    GuidString.Buffer = KeyName.Buffer = NULL;

    Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }

    KeyName.Length = 0;
    KeyName.MaximumLength = LocalMachine.Length + ((USHORT)wcslen(REGSTR_PATH_DEVICE_CLASSES) + 1) * sizeof(WCHAR) + GuidString.Length;
    KeyName.Buffer = ExAllocatePool(PagedPool, KeyName.MaximumLength);
    if (!KeyName.Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        Status = STATUS_INSUFFICIENT_RESOURCES;
        goto cleanup;
    }

    Status = RtlAppendUnicodeStringToString(&KeyName, &LocalMachine);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }
    Status = RtlAppendUnicodeToString(&KeyName, REGSTR_PATH_DEVICE_CLASSES);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }
    Status = RtlAppendUnicodeToString(&KeyName, L"\\");
    if (!NT_SUCCESS(Status))
    {
        DPRINT("RtlAppendUnicodeToString() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }
    Status = RtlAppendUnicodeStringToString(&KeyName, &GuidString);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("RtlAppendUnicodeStringToString() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }

    InitializeObjectAttributes(
        &ObjectAttributes,
        &KeyName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);
    Status = ZwOpenKey(
        &InterfaceKey,
        DesiredAccess,
        &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwOpenKey() failed with status 0x%08lx\n", Status);
        goto cleanup;
    }

    *pInterfaceKey = InterfaceKey;
    Status = STATUS_SUCCESS;

cleanup:
    if (!NT_SUCCESS(Status))
    {
        if (InterfaceKey != INVALID_HANDLE_VALUE)
            ZwClose(InterfaceKey);
    }
    RtlFreeUnicodeString(&GuidString);
    RtlFreeUnicodeString(&KeyName);
    return Status;
}
Ejemplo n.º 18
0
NTSTATUS
AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                 IN PIRP Irp)
{

    NTSTATUS            ntStatus = STATUS_SUCCESS;
    FILE_OBJECT        *pFileObject = NULL;
    IO_STACK_LOCATION  *pIrpSp;
    AFSDeviceExt       *pDeviceExt = NULL;
    AFSDeviceExt       *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
    GUID               *pAuthGroup = NULL;
    UNICODE_STRING uniGUIDString;

    __Enter
    {

        pIrpSp = IoGetCurrentIrpStackLocation( Irp);
        pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
        pFileObject = pIrpSp->FileObject;

        uniGUIDString.Buffer = NULL;
        uniGUIDString.Length = 0;
        uniGUIDString.MaximumLength = 0;

        //
        // Validate the process entry
        //

        pAuthGroup = AFSValidateProcessEntry();

        if( pAuthGroup != NULL)
        {

            RtlStringFromGUID( *pAuthGroup,
                               &uniGUIDString);

            AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s (%08lX) Located AuthGroup %wZ after validation\n",
                          __FUNCTION__,
                          Irp,
                          &uniGUIDString);

        }
        else
        {
            AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s (%08lX) Failed to locate AuthGroup\n",
                          __FUNCTION__,
                          Irp);
        }

        //
        // Root open?
        //

        if( pFileObject == NULL ||
            pFileObject->FileName.Buffer == NULL)
        {

            AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "AFSCommonCreate (%08lX) Processing volume open request\n",
                          Irp);

            ntStatus = AFSOpenRedirector( Irp);

            AFSCompleteRequest( Irp,
                                ntStatus);

            try_return( ntStatus);
        }


        //
        // Check the state of the library
        //

        ntStatus = AFSCheckLibraryState( Irp);

        if( !NT_SUCCESS( ntStatus) ||
            ntStatus == STATUS_PENDING)
        {

            if( ntStatus != STATUS_PENDING)
            {
                AFSCompleteRequest( Irp, ntStatus);
            }

            try_return( ntStatus);
        }

        IoSkipCurrentIrpStackLocation( Irp);

        ntStatus = IoCallDriver( pControlDevExt->Specific.Control.LibraryDeviceObject,
                                 Irp);

        //
        // Indicate the library is done with the request
        //

        AFSClearLibraryRequest();

try_exit:

        if ( pFileObject) {
            AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s (%08lX) File \"%wZ\" AuthGroup '%wZ' ntStatus %08lX\n",
                          __FUNCTION__,
                          Irp,
                          &pFileObject->FileName,
                          &uniGUIDString,
                          ntStatus);
        }

        if( uniGUIDString.Buffer != NULL)
        {
            RtlFreeUnicodeString( &uniGUIDString);
        }
    }

    return ntStatus;
}
Ejemplo n.º 19
0
GUID *
AFSValidateProcessEntry( IN HANDLE  ProcessId,
                         IN BOOLEAN bProcessTreeLocked)
{

    GUID *pAuthGroup = NULL;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSProcessCB *pProcessCB = NULL, *pParentProcessCB = NULL;
    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
    ULONGLONG ullProcessID = (ULONGLONG)ProcessId;
    UNICODE_STRING uniSIDString;
    ULONG ulSIDHash = 0;
    AFSSIDEntryCB *pSIDEntryCB = NULL;
    ULONG ulSessionId = 0;
    ULONGLONG ullTableHash = 0;
    AFSThreadCB *pParentThreadCB = NULL;
    UNICODE_STRING uniGUID;
    BOOLEAN bImpersonation = FALSE;

    __Enter
    {

        uniSIDString.Length = 0;
        uniSIDString.MaximumLength = 0;
        uniSIDString.Buffer = NULL;

        if ( !bProcessTreeLocked)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "AFSValidateProcessEntry Acquiring Control ProcessTree.TreeLock lock %p SHARED %08lX\n",
                          pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                          PsGetCurrentThread()));

            AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                              TRUE);
        }

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Entry for ProcessID %I64X\n",
                      __FUNCTION__,
                      ullProcessID));

        ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
                                       ullProcessID,
                                       (AFSBTreeEntry **)&pProcessCB);

        if( !NT_SUCCESS( ntStatus) ||
            pProcessCB == NULL)
        {

            if ( !bProcessTreeLocked)
            {

                AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);

                AFSAcquireExcl( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                                TRUE);
            }

            ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
                                           ullProcessID,
                                           (AFSBTreeEntry **)&pProcessCB);

            if( !NT_SUCCESS( ntStatus) ||
                pProcessCB == NULL)
            {

                AFSProcessCreate( 0,
                                  ProcessId,
                                  0,
                                  0);
            }

            if( !NT_SUCCESS( ntStatus) ||
                pProcessCB == NULL)
            {

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_ERROR,
                              "%s Failed to locate process entry for ProcessID %I64X\n",
                              __FUNCTION__,
                              ullProcessID));

                try_return( ntStatus = STATUS_UNSUCCESSFUL);
            }

            if ( !bProcessTreeLocked)
            {

                AFSConvertToShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
            }
        }

        //
        // Locate and lock the ParentProcessCB if we have one
        //

        if( pProcessCB->ParentProcessId != 0)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s Locating process entry for Parent ProcessID %I64X\n",
                          __FUNCTION__,
                          pProcessCB->ParentProcessId));

            ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
                                           (ULONGLONG)pProcessCB->ParentProcessId,
                                           (AFSBTreeEntry **)&pParentProcessCB);

            if( NT_SUCCESS( ntStatus) &&
                pParentProcessCB != NULL)
            {
                AFSAcquireExcl( &pParentProcessCB->Lock,
                                TRUE);

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s Located process entry for Parent ProcessID %I64X\n",
                              __FUNCTION__,
                              pProcessCB->ParentProcessId));
            }
        }
        else
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s No parent ID for ProcessID %I64X\n",
                          __FUNCTION__,
                          ullProcessID));
        }

        AFSAcquireExcl( &pProcessCB->Lock,
                        TRUE);

#if defined(_WIN64)

        //
        // Mark the process as 64-bit if it is.
        //

        if( !IoIs32bitProcess( NULL))
        {

            SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT);
        }
        else
        {

            ClearFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT);
        }
#endif

        //
        // Locate the SID for the caller
        //

        ntStatus = AFSGetCallerSID( &uniSIDString, &bImpersonation);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "%s Failed to locate callers SID for ProcessID %I64X\n",
                          __FUNCTION__,
                          ullProcessID));

            try_return( ntStatus);
        }

        ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation);

        if( ulSessionId == (ULONG)-1)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "%s Failed to retrieve session ID for ProcessID %I64X\n",
                          __FUNCTION__,
                          ullProcessID));

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Retrieved callers SID %wZ for ProcessID %I64X Session %08lX\n",
                      __FUNCTION__,
                      &uniSIDString,
                      ullProcessID,
                      ulSessionId));

        //
        // If there is an Auth Group for the current process,
        // our job is finished.
        //

        if ( bImpersonation == FALSE)
        {
            pAuthGroup = pProcessCB->ActiveAuthGroup;

            if( pAuthGroup != NULL &&
                !AFSIsNoPAGAuthGroup( pAuthGroup))
            {

                uniGUID.Buffer = NULL;

                RtlStringFromGUID( *pAuthGroup,
                                   &uniGUID);

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s Located valid AuthGroup GUID %wZ for SID %wZ ProcessID %I64X Session %08lX\n",
                              __FUNCTION__,
                              &uniGUID,
                              &uniSIDString,
                              ullProcessID,
                              ulSessionId));

                if( uniGUID.Buffer != NULL)
                {
                    RtlFreeUnicodeString( &uniGUID);
                }

                try_return( ntStatus = STATUS_SUCCESS);
            }

            //
            // The current process does not yet have an Auth Group.  Try to inherit
            // one from the parent process thread that created this process.
            //

            if( pParentProcessCB != NULL)
            {

                for ( pParentThreadCB = pParentProcessCB->ThreadList;
                      pParentThreadCB != NULL;
                      pParentThreadCB = pParentThreadCB->Next)
                {

                    if( pParentThreadCB->ThreadId == pProcessCB->CreatingThreadId)
                    {
                        break;
                    }
                }

                //
                // If the creating thread was found and it has a thread specific
                // Auth Group, use that even if it is the No PAG
                //

                if( pParentThreadCB != NULL &&
                    pParentThreadCB->ActiveAuthGroup != NULL &&
                    !AFSIsNoPAGAuthGroup( pParentThreadCB->ActiveAuthGroup))
                {
                    pProcessCB->ActiveAuthGroup = pParentThreadCB->ActiveAuthGroup;

                    uniGUID.Buffer = NULL;

                    RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                                       &uniGUID);

                    AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "%s PID %I64X Session %08lX inherited Active AuthGroup %wZ from thread %I64X\n",
                                  __FUNCTION__,
                                  ullProcessID,
                                  ulSessionId,
                                  &uniGUID,
                                  pParentThreadCB->ThreadId));

                    if( uniGUID.Buffer != NULL)
                    {
                        RtlFreeUnicodeString( &uniGUID);
                    }
                }

                //
                // If the parent thread was not found or does not have an auth group
                //

                else if( pParentProcessCB->ActiveAuthGroup != NULL &&
                         !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup))
                {
                    pProcessCB->ActiveAuthGroup = pParentProcessCB->ActiveAuthGroup;

                    uniGUID.Buffer = NULL;

                    RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                                       &uniGUID);

                    AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "%s PID %I64X Session %08lX inherited Active AuthGroup %wZ from parent PID %I64X\n",
                                  __FUNCTION__,
                                  ullProcessID,
                                  ulSessionId,
                                  &uniGUID,
                                  pParentProcessCB->TreeEntry.HashIndex));

                    if( uniGUID.Buffer != NULL)
                    {
                        RtlFreeUnicodeString( &uniGUID);
                    }
                }

                //
                // If an Auth Group was inherited, set it to be the active group
                //

                if( pProcessCB->ActiveAuthGroup != NULL &&
                    !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup))
                {
                    pAuthGroup = pProcessCB->ActiveAuthGroup;

                    uniGUID.Buffer = NULL;

                    RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                                       &uniGUID);

                    AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "%s Returning(1) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n",
                                  __FUNCTION__,
                                  &uniGUID,
                                  &uniSIDString,
                                  ullProcessID,
                                  ulSessionId));

                    if( uniGUID.Buffer != NULL)
                    {
                        RtlFreeUnicodeString( &uniGUID);
                    }

                    try_return( ntStatus);
                }
            }
        }

        //
        // If no Auth Group was inherited, assign one based upon the Session and SID
        //

        ntStatus = RtlHashUnicodeString( &uniSIDString,
                                         TRUE,
                                         HASH_STRING_ALGORITHM_DEFAULT,
                                         &ulSIDHash);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "%s Failed to hash SID %wZ for PID %I64X Session %08lX Status %08lX\n",
                          __FUNCTION__,
                          &uniSIDString,
                          ullProcessID,
                          ulSessionId,
                          ntStatus));

            try_return( ntStatus);
        }

        ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash);

        AFSAcquireShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
                          TRUE);

        ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
                                       (ULONGLONG)ullTableHash,
                                       (AFSBTreeEntry **)&pSIDEntryCB);

        if( !NT_SUCCESS( ntStatus) ||
            pSIDEntryCB == NULL)
        {

            AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);

            AFSAcquireExcl( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
                            TRUE);

            ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
                                           (ULONGLONG)ullTableHash,
                                           (AFSBTreeEntry **)&pSIDEntryCB);

            if( !NT_SUCCESS( ntStatus) ||
                pSIDEntryCB == NULL)
            {

                pSIDEntryCB = (AFSSIDEntryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
                                                                         sizeof( AFSSIDEntryCB),
                                                                         AFS_AG_ENTRY_CB_TAG);

                if( pSIDEntryCB == NULL)
                {

                    AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);

                    try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
                }

                RtlZeroMemory( pSIDEntryCB,
                               sizeof( AFSSIDEntryCB));

                pSIDEntryCB->TreeEntry.HashIndex = (ULONGLONG)ullTableHash;

                while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY);

                uniGUID.Buffer = NULL;

                RtlStringFromGUID( pSIDEntryCB->AuthGroup,
                                   &uniGUID);

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s  SID %wZ PID %I64X Session %08lX generated NEW AG %wZ\n",
                              __FUNCTION__,
                              &uniSIDString,
                              ullProcessID,
                              ulSessionId,
                              &uniGUID));

                if( uniGUID.Buffer != NULL)
                {
                    RtlFreeUnicodeString( &uniGUID);
                }

                if( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead == NULL)
                {
                    pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = (AFSBTreeEntry *)pSIDEntryCB;
                }
                else
                {
                    AFSInsertHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
                                        &pSIDEntryCB->TreeEntry);
                }
            }

            AFSConvertToShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
        }


        AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);

        //
        // Store the auth group into the process cb
        //

        pProcessCB->ActiveAuthGroup = &pSIDEntryCB->AuthGroup;

        uniGUID.Buffer = NULL;

        RtlStringFromGUID( pSIDEntryCB->AuthGroup,
                           &uniGUID);

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s SID %wZ PID %I64X Session %08lX assigned AG %wZ\n",
                      __FUNCTION__,
                      &uniSIDString,
                      ullProcessID,
                      ulSessionId,
                      &uniGUID));

        if( uniGUID.Buffer != NULL)
        {
            RtlFreeUnicodeString( &uniGUID);
        }

        //
        // Set the AFS_PROCESS_LOCAL_SYSTEM_AUTH flag if the process SID
        // is LOCAL_SYSTEM
        //

        if( AFSIsLocalSystemSID( &uniSIDString))
        {
            SetFlag( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH);

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s Setting PID %I64X Session %08lX with LOCAL SYSTEM AUTHORITY\n",
                          __FUNCTION__,
                          ullProcessID,
                          ulSessionId));
        }

        //
        // Return the auth group
        //

        pAuthGroup = pProcessCB->ActiveAuthGroup;

        uniGUID.Buffer = NULL;

        RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                           &uniGUID);

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Returning(2) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n",
                      __FUNCTION__,
                      &uniGUID,
                      &uniSIDString,
                      ullProcessID,
                      ulSessionId));

        if( uniGUID.Buffer != NULL)
        {
            RtlFreeUnicodeString( &uniGUID);
        }

try_exit:

        if( pProcessCB != NULL)
        {

            if( bImpersonation == FALSE &&
                !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET) &&
                NT_SUCCESS( ntStatus))
            {
                ntStatus = AFSProcessSetProcessDacl( pProcessCB);

                if( !NT_SUCCESS( ntStatus))
                {
                    pAuthGroup = NULL;
                }
                else
                {
                    SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET);
                }
            }

            AFSReleaseResource( &pProcessCB->Lock);
        }

        if( pParentProcessCB != NULL)
        {
            AFSReleaseResource( &pParentProcessCB->Lock);
        }

        if( uniSIDString.Length > 0)
        {
            RtlFreeUnicodeString( &uniSIDString);
        }

        if ( !bProcessTreeLocked)
        {

            AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
        }
    }

    return pAuthGroup;
}
Ejemplo n.º 20
0
NTSTATUS
NTAPI
PciQueryInterface(IN PPCI_FDO_EXTENSION DeviceExtension,
                  IN CONST GUID* InterfaceType,
                  IN ULONG Size,
                  IN ULONG Version,
                  IN PVOID InterfaceData,
                  IN PINTERFACE Interface,
                  IN BOOLEAN LastChance)
{
    UNICODE_STRING GuidString;
    NTSTATUS Status;
    PPCI_INTERFACE *InterfaceList;
    PPCI_INTERFACE PciInterface;
    RtlStringFromGUID(InterfaceType, &GuidString);
    DPRINT1("PCI - PciQueryInterface TYPE = %wZ\n", &GuidString);
    RtlFreeUnicodeString(&GuidString);
    DPRINT1("      Size = %u, Version = %u, InterfaceData = %p, LastChance = %s\n",
            Size,
            Version,
            InterfaceData,
            LastChance ? "TRUE" : "FALSE");

    /* Loop all the available interfaces */
    for (InterfaceList = LastChance ? PciInterfacesLastResort : PciInterfaces;
         *InterfaceList;
         InterfaceList++)
    {
        /* Get the current interface */
        PciInterface = *InterfaceList;

        /* For debugging, construct the GUID string */
        RtlStringFromGUID(PciInterface->InterfaceType, &GuidString);

        /* Check if this is an FDO or PDO */
        if (DeviceExtension->ExtensionType == PciFdoExtensionType)
        {
            /* Check if the interface is for FDOs */
            if (!(PciInterface->Flags & PCI_INTERFACE_FDO))
            {
                /* This interface is not for FDOs, skip it */
                DPRINT1("PCI - PciQueryInterface: guid = %wZ only for FDOs\n",
                        &GuidString);
                RtlFreeUnicodeString(&GuidString);
                continue;
            }

            /* Check if the interface is for root FDO only */
            if ((PciInterface->Flags & PCI_INTERFACE_ROOT) &&
                (!PCI_IS_ROOT_FDO(DeviceExtension)))
            {
                /* This FDO isn't the root, skip the interface */
                DPRINT1("PCI - PciQueryInterface: guid = %wZ only for ROOT\n",
                        &GuidString);
                RtlFreeUnicodeString(&GuidString);
                continue;
            }
        }
        else
        {
            /* This is a PDO, check if the interface is for PDOs too */
            if (!(PciInterface->Flags & PCI_INTERFACE_PDO))
            {
                /* It isn't, skip it */
                DPRINT1("PCI - PciQueryInterface: guid = %wZ only for PDOs\n",
                        &GuidString);
                RtlFreeUnicodeString(&GuidString);
                continue;
            }
        }

        /* Print the GUID for debugging, and then free the string */
        DPRINT1("PCI - PciQueryInterface looking at guid = %wZ\n", &GuidString);
        RtlFreeUnicodeString(&GuidString);

        /* Check if the GUID, version, and size all match */
        if ((IsEqualGUIDAligned(PciInterface->InterfaceType, InterfaceType)) &&
            (Version >= PciInterface->MinVersion) &&
            (Version <= PciInterface->MaxVersion) &&
            (Size >= PciInterface->MinSize))
        {
            /* Call the interface's constructor */
            Status = PciInterface->Constructor(DeviceExtension,
                                               PciInterface,
                                               InterfaceData,
                                               Version,
                                               Size,
                                               Interface);
            if (!NT_SUCCESS(Status))
            {
                /* This interface was not initialized correctly, skip it */
                DPRINT1("PCI - PciQueryInterface - Contructor %p = %08lx\n",
                        PciInterface->Constructor, Status);
                continue;
            }

            /* Reference the interface and return success, all is good */
            Interface->InterfaceReference(Interface->Context);
            DPRINT1("PCI - PciQueryInterface returning SUCCESS\n");
            return Status;
        }
    }

    /* An interface of this type, and for this device, could not be found */
    DPRINT1("PCI - PciQueryInterface FAILED TO FIND INTERFACE\n");
    return STATUS_NOT_SUPPORTED;
}
Ejemplo n.º 21
0
/*++
 * @name IoRegisterDeviceInterface
 * @implemented
 *
 * Registers a device interface class, if it has not been previously registered,
 * and creates a new instance of the interface class, which a driver can
 * subsequently enable for use by applications or other system components.
 * Documented in WDK.
 *
 * @param PhysicalDeviceObject
 *        Points to an optional PDO that narrows the search to only the
 *        device interfaces of the device represented by the PDO
 *
 * @param InterfaceClassGuid
 *        Points to a class GUID specifying the device interface class
 *
 * @param ReferenceString
 *        Optional parameter, pointing to a unicode string. For a full
 *        description of this rather rarely used param (usually drivers
 *        pass NULL here) see WDK
 *
 * @param SymbolicLinkName
 *        Pointer to the resulting unicode string
 *
 * @return Usual NTSTATUS
 *
 * @remarks Must be called at IRQL = PASSIVE_LEVEL in the context of a
 *          system thread
 *
 *--*/
NTSTATUS
NTAPI
IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject,
                          IN CONST GUID *InterfaceClassGuid,
                          IN PUNICODE_STRING ReferenceString OPTIONAL,
                          OUT PUNICODE_STRING SymbolicLinkName)
{
    PUNICODE_STRING InstancePath;
    UNICODE_STRING GuidString;
    UNICODE_STRING SubKeyName;
    UNICODE_STRING InterfaceKeyName;
    UNICODE_STRING BaseKeyName;
    UCHAR PdoNameInfoBuffer[sizeof(OBJECT_NAME_INFORMATION) + (256 * sizeof(WCHAR))];
    POBJECT_NAME_INFORMATION PdoNameInfo = (POBJECT_NAME_INFORMATION)PdoNameInfoBuffer;
    UNICODE_STRING DeviceInstance = RTL_CONSTANT_STRING(L"DeviceInstance");
    UNICODE_STRING SymbolicLink = RTL_CONSTANT_STRING(L"SymbolicLink");
    HANDLE ClassKey;
    HANDLE InterfaceKey;
    HANDLE SubKey;
    ULONG StartIndex;
    OBJECT_ATTRIBUTES ObjectAttributes;
    ULONG i;
    NTSTATUS Status, SymLinkStatus;
    PEXTENDED_DEVOBJ_EXTENSION DeviceObjectExtension;

    ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    DPRINT("IoRegisterDeviceInterface(): PDO %p, RefString: %wZ\n",
        PhysicalDeviceObject, ReferenceString);

    /* Parameters must pass three border of checks */
    DeviceObjectExtension = (PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension;

    /* 1st level: Presence of a Device Node */
    if (DeviceObjectExtension->DeviceNode == NULL)
    {
        DPRINT("PhysicalDeviceObject 0x%p doesn't have a DeviceNode\n", PhysicalDeviceObject);
        return STATUS_INVALID_DEVICE_REQUEST;
    }

    /* 2nd level: Presence of an non-zero length InstancePath */
    if (DeviceObjectExtension->DeviceNode->InstancePath.Length == 0)
    {
        DPRINT("PhysicalDeviceObject 0x%p's DOE has zero-length InstancePath\n", PhysicalDeviceObject);
        return STATUS_INVALID_DEVICE_REQUEST;
    }

    /* 3rd level: Optional, based on WDK documentation */
    if (ReferenceString != NULL)
    {
        /* Reference string must not contain path-separator symbols */
        for (i = 0; i < ReferenceString->Length / sizeof(WCHAR); i++)
        {
            if ((ReferenceString->Buffer[i] == '\\') ||
                (ReferenceString->Buffer[i] == '/'))
                return STATUS_INVALID_DEVICE_REQUEST;
        }
    }

    Status = RtlStringFromGUID(InterfaceClassGuid, &GuidString);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("RtlStringFromGUID() failed with status 0x%08lx\n", Status);
        return Status;
    }

    /* Create Pdo name: \Device\xxxxxxxx (unnamed device) */
    Status = ObQueryNameString(
        PhysicalDeviceObject,
        PdoNameInfo,
        sizeof(PdoNameInfoBuffer),
        &i);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("ObQueryNameString() failed with status 0x%08lx\n", Status);
        return Status;
    }
    ASSERT(PdoNameInfo->Name.Length);

    /* Create base key name for this interface: HKLM\SYSTEM\CurrentControlSet\Control\DeviceClasses\{GUID} */
    ASSERT(((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode);
    InstancePath = &((PEXTENDED_DEVOBJ_EXTENSION)PhysicalDeviceObject->DeviceObjectExtension)->DeviceNode->InstancePath;
    BaseKeyName.Length = (USHORT)wcslen(BaseKeyString) * sizeof(WCHAR);
    BaseKeyName.MaximumLength = BaseKeyName.Length
        + GuidString.Length;
    BaseKeyName.Buffer = ExAllocatePool(
        PagedPool,
        BaseKeyName.MaximumLength);
    if (!BaseKeyName.Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    wcscpy(BaseKeyName.Buffer, BaseKeyString);
    RtlAppendUnicodeStringToString(&BaseKeyName, &GuidString);

    /* Create BaseKeyName key in registry */
    InitializeObjectAttributes(
        &ObjectAttributes,
        &BaseKeyName,
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE | OBJ_OPENIF,
        NULL, /* RootDirectory */
        NULL); /* SecurityDescriptor */

    Status = ZwCreateKey(
        &ClassKey,
        KEY_WRITE,
        &ObjectAttributes,
        0, /* TileIndex */
        NULL, /* Class */
        REG_OPTION_VOLATILE,
        NULL); /* Disposition */

    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
        ExFreePool(BaseKeyName.Buffer);
        return Status;
    }

    /* Create key name for this interface: ##?#ACPI#PNP0501#1#{GUID} */
    InterfaceKeyName.Length = 0;
    InterfaceKeyName.MaximumLength =
        4 * sizeof(WCHAR) + /* 4  = size of ##?# */
        InstancePath->Length +
        sizeof(WCHAR) +     /* 1  = size of # */
        GuidString.Length;
    InterfaceKeyName.Buffer = ExAllocatePool(
        PagedPool,
        InterfaceKeyName.MaximumLength);
    if (!InterfaceKeyName.Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlAppendUnicodeToString(&InterfaceKeyName, L"##?#");
    StartIndex = InterfaceKeyName.Length / sizeof(WCHAR);
    RtlAppendUnicodeStringToString(&InterfaceKeyName, InstancePath);
    for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++)
    {
        if (InterfaceKeyName.Buffer[StartIndex + i] == '\\')
            InterfaceKeyName.Buffer[StartIndex + i] = '#';
    }
    RtlAppendUnicodeToString(&InterfaceKeyName, L"#");
    RtlAppendUnicodeStringToString(&InterfaceKeyName, &GuidString);

    /* Create the interface key in registry */
    InitializeObjectAttributes(
        &ObjectAttributes,
        &InterfaceKeyName,
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE | OBJ_OPENIF,
        ClassKey,
        NULL); /* SecurityDescriptor */

    Status = ZwCreateKey(
        &InterfaceKey,
        KEY_WRITE,
        &ObjectAttributes,
        0, /* TileIndex */
        NULL, /* Class */
        REG_OPTION_VOLATILE,
        NULL); /* Disposition */

    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
        ZwClose(ClassKey);
        ExFreePool(BaseKeyName.Buffer);
        return Status;
    }

    /* Write DeviceInstance entry. Value is InstancePath */
    Status = ZwSetValueKey(
        InterfaceKey,
        &DeviceInstance,
        0, /* TileIndex */
        REG_SZ,
        InstancePath->Buffer,
        InstancePath->Length);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwSetValueKey() failed with status 0x%08lx\n", Status);
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        return Status;
    }

    /* Create subkey. Name is #ReferenceString */
    SubKeyName.Length = 0;
    SubKeyName.MaximumLength = sizeof(WCHAR);
    if (ReferenceString && ReferenceString->Length)
        SubKeyName.MaximumLength += ReferenceString->Length;
    SubKeyName.Buffer = ExAllocatePool(
        PagedPool,
        SubKeyName.MaximumLength);
    if (!SubKeyName.Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlAppendUnicodeToString(&SubKeyName, L"#");
    if (ReferenceString && ReferenceString->Length)
        RtlAppendUnicodeStringToString(&SubKeyName, ReferenceString);

    /* Create SubKeyName key in registry */
    InitializeObjectAttributes(
        &ObjectAttributes,
        &SubKeyName,
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
        InterfaceKey, /* RootDirectory */
        NULL); /* SecurityDescriptor */

    Status = ZwCreateKey(
        &SubKey,
        KEY_WRITE,
        &ObjectAttributes,
        0, /* TileIndex */
        NULL, /* Class */
        REG_OPTION_VOLATILE,
        NULL); /* Disposition */

    if (!NT_SUCCESS(Status))
    {
        DPRINT("ZwCreateKey() failed with status 0x%08lx\n", Status);
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        return Status;
    }

    /* Create symbolic link name: \??\ACPI#PNP0501#1#{GUID}\ReferenceString */
    SymbolicLinkName->Length = 0;
    SymbolicLinkName->MaximumLength = SymbolicLinkName->Length
        + 4 * sizeof(WCHAR) /* 4 = size of \??\ */
        + InstancePath->Length
        + sizeof(WCHAR)     /* 1  = size of # */
        + GuidString.Length
        + sizeof(WCHAR);    /* final NULL */
    if (ReferenceString && ReferenceString->Length)
        SymbolicLinkName->MaximumLength += sizeof(WCHAR) + ReferenceString->Length;
    SymbolicLinkName->Buffer = ExAllocatePool(
        PagedPool,
        SymbolicLinkName->MaximumLength);
    if (!SymbolicLinkName->Buffer)
    {
        DPRINT("ExAllocatePool() failed\n");
        ZwClose(SubKey);
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(SubKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlAppendUnicodeToString(SymbolicLinkName, L"\\??\\");
    StartIndex = SymbolicLinkName->Length / sizeof(WCHAR);
    RtlAppendUnicodeStringToString(SymbolicLinkName, InstancePath);
    for (i = 0; i < InstancePath->Length / sizeof(WCHAR); i++)
    {
        if (SymbolicLinkName->Buffer[StartIndex + i] == '\\')
            SymbolicLinkName->Buffer[StartIndex + i] = '#';
    }
    RtlAppendUnicodeToString(SymbolicLinkName, L"#");
    RtlAppendUnicodeStringToString(SymbolicLinkName, &GuidString);
    SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0';

    /* Create symbolic link */
    DPRINT("IoRegisterDeviceInterface(): creating symbolic link %wZ -> %wZ\n", SymbolicLinkName, &PdoNameInfo->Name);
    SymLinkStatus = IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);

    /* If the symbolic link already exists, return an informational success status */
    if (SymLinkStatus == STATUS_OBJECT_NAME_COLLISION)
    {
        /* HACK: Delete the existing symbolic link and update it to the new PDO name */
        IoDeleteSymbolicLink(SymbolicLinkName);
        IoCreateSymbolicLink(SymbolicLinkName, &PdoNameInfo->Name);
        SymLinkStatus = STATUS_OBJECT_NAME_EXISTS;
    }

    if (!NT_SUCCESS(SymLinkStatus))
    {
        DPRINT1("IoCreateSymbolicLink() failed with status 0x%08lx\n", SymLinkStatus);
        ZwClose(SubKey);
        ZwClose(InterfaceKey);
        ZwClose(ClassKey);
        ExFreePool(SubKeyName.Buffer);
        ExFreePool(InterfaceKeyName.Buffer);
        ExFreePool(BaseKeyName.Buffer);
        ExFreePool(SymbolicLinkName->Buffer);
        return SymLinkStatus;
    }

    if (ReferenceString && ReferenceString->Length)
    {
        RtlAppendUnicodeToString(SymbolicLinkName, L"\\");
        RtlAppendUnicodeStringToString(SymbolicLinkName, ReferenceString);
    }
    SymbolicLinkName->Buffer[SymbolicLinkName->Length/sizeof(WCHAR)] = L'\0';

    /* Write symbolic link name in registry */
    SymbolicLinkName->Buffer[1] = '\\';
    Status = ZwSetValueKey(
        SubKey,
        &SymbolicLink,
        0, /* TileIndex */
        REG_SZ,
        SymbolicLinkName->Buffer,
        SymbolicLinkName->Length);
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("ZwSetValueKey() failed with status 0x%08lx\n", Status);
        ExFreePool(SymbolicLinkName->Buffer);
    }
    else
    {
        SymbolicLinkName->Buffer[1] = '?';
    }

    ZwClose(SubKey);
    ZwClose(InterfaceKey);
    ZwClose(ClassKey);
    ExFreePool(SubKeyName.Buffer);
    ExFreePool(InterfaceKeyName.Buffer);
    ExFreePool(BaseKeyName.Buffer);

    return NT_SUCCESS(Status) ? SymLinkStatus : Status;
}
Ejemplo n.º 22
0
NTSTATUS
KspReadMediaCategory(
    IN LPGUID Category,
    PKEY_VALUE_PARTIAL_INFORMATION *OutInformation)
{
    UNICODE_STRING MediaPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories\\");
    UNICODE_STRING Name = RTL_CONSTANT_STRING(L"Name");
    UNICODE_STRING GuidString, Path;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE hKey;
    ULONG Size;
    PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;

    /* convert the guid to string */
    Status = RtlStringFromGUID(Category, &GuidString);
    if (!NT_SUCCESS(Status))
        return Status;

    /* allocate buffer for the registry key */
    Path.Length = 0;
    Path.MaximumLength = MediaPath.MaximumLength + GuidString.MaximumLength;
    Path.Buffer = AllocateItem(NonPagedPool, Path.MaximumLength);
    if (!Path.Buffer)
    {
        /* not enough memory */
        RtlFreeUnicodeString(&GuidString);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    RtlAppendUnicodeStringToString(&Path, &MediaPath);
    RtlAppendUnicodeStringToString(&Path, &GuidString);

    /* free guid string */
    RtlFreeUnicodeString(&GuidString);

    /* initialize object attributes */
    InitializeObjectAttributes(&ObjectAttributes, &Path, OBJ_CASE_INSENSITIVE, NULL, NULL);

    /* open the key */
    Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes);

    DPRINT("ZwOpenKey() status 0x%08lx %wZ\n", Status, &Path);

    /* free path buffer */
    FreeItem(Path.Buffer);

    /* check for success */
    if (!NT_SUCCESS(Status))
    {
        DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
        return Status;
    }

    /* query the name size */
    Status = ZwQueryValueKey(hKey, &Name, KeyValuePartialInformation, NULL, 0, &Size);
    if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
    {
        /* failed to query for name key */
        ZwClose(hKey);
        return Status;
    }

    /* allocate buffer to read key info */
    KeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION) AllocateItem(NonPagedPool, Size);
    if (!KeyInfo)
    {
        /* not enough memory */
        ZwClose(hKey);
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* now read the info */
    Status = ZwQueryValueKey(hKey, &Name, KeyValuePartialInformation, (PVOID)KeyInfo, Size, &Size);

    /* close the key */
    ZwClose(hKey);

    if (!NT_SUCCESS(Status))
    {
        /* failed to read key */
        FreeItem(KeyInfo);
        return Status;
    }

    /* store key information */
    *OutInformation = KeyInfo;
    return Status;
}
Ejemplo n.º 23
0
// start event dispatching
NTSTATUS
DokanEventStart(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
   )
{
	ULONG				outBufferLen;
	ULONG				inBufferLen;
	PVOID				buffer;
	PIO_STACK_LOCATION	irpSp;
	EVENT_START			eventStart;
	PEVENT_DRIVER_INFO	driverInfo;
	PDOKAN_GLOBAL		dokanGlobal;
	PDokanDCB			dcb;
	NTSTATUS			status;
	DEVICE_TYPE			deviceType;
	ULONG				deviceCharacteristics;
	WCHAR				baseGuidString[64];
	GUID				baseGuid = DOKAN_BASE_GUID;
	UNICODE_STRING		unicodeGuid;
	ULONG				deviceNamePos;
	

	DDbgPrint("==> DokanEventStart\n");

	dokanGlobal = DeviceObject->DeviceExtension;
	if (GetIdentifierType(dokanGlobal) != DGL) {
		return STATUS_INVALID_PARAMETER;
	}

	irpSp = IoGetCurrentIrpStackLocation(Irp);

	outBufferLen = irpSp->Parameters.DeviceIoControl.OutputBufferLength;
	inBufferLen = irpSp->Parameters.DeviceIoControl.InputBufferLength;

	if (outBufferLen != sizeof(EVENT_DRIVER_INFO) ||
		inBufferLen != sizeof(EVENT_START)) {
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	RtlCopyMemory(&eventStart, Irp->AssociatedIrp.SystemBuffer, sizeof(EVENT_START));
	driverInfo = Irp->AssociatedIrp.SystemBuffer;

	if (eventStart.UserVersion != DOKAN_DRIVER_VERSION) {
		driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;
		driverInfo->Status = DOKAN_START_FAILED;
		Irp->IoStatus.Status = STATUS_SUCCESS;
		Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);
		return STATUS_SUCCESS;
	}

	deviceCharacteristics = FILE_DEVICE_IS_MOUNTED;

	switch (eventStart.DeviceType) {
	case DOKAN_DISK_FILE_SYSTEM:
		deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
		break;
	case DOKAN_NETWORK_FILE_SYSTEM:
		deviceType = FILE_DEVICE_NETWORK_FILE_SYSTEM;
		deviceCharacteristics |= FILE_REMOTE_DEVICE;
		break;
	default:
		DDbgPrint("  Unknown device type: %d\n", eventStart.DeviceType);
		deviceType = FILE_DEVICE_DISK_FILE_SYSTEM;
	}

	if (eventStart.Flags & DOKAN_EVENT_REMOVABLE) {
		DDbgPrint("  DeviceCharacteristics |= FILE_REMOVABLE_MEDIA\n");
		deviceCharacteristics |= FILE_REMOVABLE_MEDIA;
	}

	baseGuid.Data2 = (USHORT)(dokanGlobal->MountId & 0xFFFF) ^ baseGuid.Data2;
	baseGuid.Data3 = (USHORT)(dokanGlobal->MountId >> 16) ^ baseGuid.Data3;

	status = RtlStringFromGUID(&baseGuid, &unicodeGuid);
	if (!NT_SUCCESS(status)) {
		return status;
	}
	RtlZeroMemory(baseGuidString, sizeof(baseGuidString));
	RtlStringCchCopyW(baseGuidString, sizeof(baseGuidString) / sizeof(WCHAR), unicodeGuid.Buffer);
	RtlFreeUnicodeString(&unicodeGuid);

	InterlockedIncrement(&dokanGlobal->MountId);

	KeEnterCriticalRegion();
	ExAcquireResourceExclusiveLite(&dokanGlobal->Resource, TRUE);

	status = DokanCreateDiskDevice(
				DeviceObject->DriverObject,
				dokanGlobal->MountId,
				baseGuidString,
				dokanGlobal,
				deviceType,
				deviceCharacteristics,
				&dcb);

	if (!NT_SUCCESS(status)) {
		ExReleaseResourceLite(&dokanGlobal->Resource);
		KeLeaveCriticalRegion();
		return status;
	}

	DDbgPrint("  MountId:%d\n", dcb->MountId);
	driverInfo->DeviceNumber = dokanGlobal->MountId;
	driverInfo->MountId = dokanGlobal->MountId;
	driverInfo->Status = DOKAN_MOUNTED;
	driverInfo->DriverVersion = DOKAN_DRIVER_VERSION;

	// SymbolicName is \\DosDevices\\Global\\Volume{D6CC17C5-1734-4085-BCE7-964F1E9F5DE9}
	// Finds the last '\' and copy into DeviceName.
	// DeviceName is \Volume{D6CC17C5-1734-4085-BCE7-964F1E9F5DE9}
	deviceNamePos = dcb->SymbolicLinkName->Length / sizeof(WCHAR) - 1;
	for (; dcb->SymbolicLinkName->Buffer[deviceNamePos] != L'\\'; --deviceNamePos)
		;
	RtlStringCchCopyW(driverInfo->DeviceName,
			sizeof(driverInfo->DeviceName) / sizeof(WCHAR),
			&(dcb->SymbolicLinkName->Buffer[deviceNamePos]));

	DDbgPrint("  DeviceName:%ws\n", driverInfo->DeviceName);
	DokanUpdateTimeout(&dcb->TickCount, DOKAN_KEEPALIVE_TIMEOUT);

	dcb->UseAltStream = 0;
	if (eventStart.Flags & DOKAN_EVENT_ALTERNATIVE_STREAM_ON) {
		DDbgPrint("  ALT_STREAM_ON\n");
		dcb->UseAltStream = 1;
	}
	dcb->UseKeepAlive = 0;
	if (eventStart.Flags & DOKAN_EVENT_KEEP_ALIVE_ON) {
		DDbgPrint("  KEEP_ALIVE_ON\n");
		dcb->UseKeepAlive = 1;
	}
	dcb->Mounted = 1;

	DokanStartEventNotificationThread(dcb);
	DokanStartCheckThread(dcb);

	ExReleaseResourceLite(&dokanGlobal->Resource);
	KeLeaveCriticalRegion();

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = sizeof(EVENT_DRIVER_INFO);

	DDbgPrint("<== DokanEventStart\n");

	return Irp->IoStatus.Status;
}
Ejemplo n.º 24
0
KSDDKAPI
NTSTATUS
NTAPI
KspPinPropertyHandler(
    IN  PIRP Irp,
    IN  PKSPROPERTY Property,
    IN  OUT PVOID Data,
    IN  ULONG DescriptorsCount,
    IN  const KSPIN_DESCRIPTOR* Descriptors,
    IN  ULONG DescriptorSize)
{
    KSP_PIN * Pin;
    KSMULTIPLE_ITEM * Item;
    PIO_STACK_LOCATION IoStack;
    ULONG Size, Index;
    PVOID Buffer;
    PKSDATARANGE_AUDIO *WaveFormatOut;
    PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn;
    PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
    const KSPIN_DESCRIPTOR *Descriptor;
    NTSTATUS Status = STATUS_NOT_SUPPORTED;
    ULONG Count;
    const PKSDATARANGE* DataRanges;
    LPGUID Guid;

    IoStack = IoGetCurrentIrpStackLocation(Irp);
    Buffer = Data;

    //DPRINT("KsPinPropertyHandler Irp %p Property %p Data %p DescriptorsCount %u Descriptor %p OutputLength %u Id %u\n", Irp, Property, Data, DescriptorsCount, Descriptor, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Property->Id);

    /* convert to PKSP_PIN */
    Pin = (KSP_PIN*)Property;

    if (Property->Id != KSPROPERTY_PIN_CTYPES)
    {
        if (Pin->PinId >= DescriptorsCount)
        {
            /* invalid parameter */
            return STATUS_INVALID_PARAMETER;
        }
    }
    else
    {
        (*(PULONG)Buffer) = DescriptorsCount;
        Irp->IoStatus.Information = sizeof(ULONG);
        return STATUS_SUCCESS;
    }


    if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR))
    {
        /* it is simple pin descriptor */
        Descriptor = &Descriptors[Pin->PinId];
    }
    else
    {
        /* get offset to pin descriptor */
        Descriptor = &(((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + Pin->PinId * DescriptorSize))->PinDescriptor);
    }

    switch(Property->Id)
    {
        case KSPROPERTY_PIN_DATAFLOW:

            Size = sizeof(KSPIN_DATAFLOW);
            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
            {
                Irp->IoStatus.Information = Size;
                Status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            *((KSPIN_DATAFLOW*)Buffer) = Descriptor->DataFlow;
            Irp->IoStatus.Information = sizeof(KSPIN_DATAFLOW);
            Status = STATUS_SUCCESS;
            break;

        case KSPROPERTY_PIN_DATARANGES:
        case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:

            Size = sizeof(KSMULTIPLE_ITEM);
            DPRINT("Id %lu PinId %lu DataRangesCount %lu ConstrainedDataRangesCount %lu\n", Property->Id, Pin->PinId, Descriptor->DataRangesCount, Descriptor->ConstrainedDataRangesCount);

            if (Property->Id == KSPROPERTY_PIN_DATARANGES || Descriptor->ConstrainedDataRangesCount == 0)
            {
                DataRanges = Descriptor->DataRanges;
                Count = Descriptor->DataRangesCount;
            }
            else
            {
                DataRanges = Descriptor->ConstrainedDataRanges;
                Count = Descriptor->ConstrainedDataRangesCount;
            }

            for (Index = 0; Index < Count; Index++)
            {
                Size += ((DataRanges[Index]->FormatSize + 0x7) & ~0x7);
            }

            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == 0)
            {
                /* buffer too small */
                Irp->IoStatus.Information = Size;
                Status = STATUS_BUFFER_OVERFLOW;
                break;
            }

            Item = (KSMULTIPLE_ITEM*)Buffer;

            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(ULONG))
            {
                /* store the result size */
                Item->Size = Size;
                Irp->IoStatus.Information = sizeof(ULONG);
                Status = STATUS_SUCCESS;
                break;
            }

            /* store descriptor size */
            Item->Size = Size;
            Item->Count = Count;

            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength == sizeof(KSMULTIPLE_ITEM))
            {
                Irp->IoStatus.Information = sizeof(KSMULTIPLE_ITEM);
                Status = STATUS_SUCCESS;
                break;
            }

            /* now copy all dataranges */
            Data = (PUCHAR)(Item +1);

            /* alignment assert */
            ASSERT(((ULONG_PTR)Data & 0x7) == 0);

            for (Index = 0; Index < Count; Index++)
            {
                UNICODE_STRING GuidString;
                /* convert the guid to string */
                RtlStringFromGUID(&DataRanges[Index]->MajorFormat, &GuidString);
                DPRINT("Index %lu MajorFormat %S\n", Index, GuidString.Buffer);
                RtlStringFromGUID(&DataRanges[Index]->SubFormat, &GuidString);
                DPRINT("Index %lu SubFormat %S\n", Index, GuidString.Buffer);
                RtlStringFromGUID(&DataRanges[Index]->Specifier, &GuidString);
                DPRINT("Index %lu Specifier %S\n", Index, GuidString.Buffer);
                RtlStringFromGUID(&DataRanges[Index]->Specifier, &GuidString);
                DPRINT("Index %lu FormatSize %lu Flags %lu SampleSize %lu Reserved %lu KSDATAFORMAT %lu\n", Index,
                       DataRanges[Index]->FormatSize, DataRanges[Index]->Flags, DataRanges[Index]->SampleSize, DataRanges[Index]->Reserved, sizeof(KSDATAFORMAT));

                RtlMoveMemory(Data, DataRanges[Index], DataRanges[Index]->FormatSize);
                Data = ((PUCHAR)Data + DataRanges[Index]->FormatSize);
                /* alignment assert */
                ASSERT(((ULONG_PTR)Data & 0x7) == 0);
                Data = (PVOID)(((ULONG_PTR)Data + 0x7) & ~0x7);
            }

            Status = STATUS_SUCCESS;
            Irp->IoStatus.Information = Size;
            break;
        case KSPROPERTY_PIN_INTERFACES:

            if (Descriptor->Interfaces)
            {
                /* use mediums provided by driver */
                return KsHandleSizedListQuery(Irp, Descriptor->InterfacesCount, sizeof(KSPIN_MEDIUM), Descriptor->Interfaces);
            }
            else
            {
                /* use standard medium */
                return KsHandleSizedListQuery(Irp, 1, sizeof(KSPIN_INTERFACE), &StandardPinInterface);
            }
            break;

        case KSPROPERTY_PIN_MEDIUMS:

            if (Descriptor->MediumsCount)
            {
                /* use mediums provided by driver */
                return KsHandleSizedListQuery(Irp, Descriptor->MediumsCount, sizeof(KSPIN_MEDIUM), Descriptor->Mediums);
            }
            else
            {
                /* use standard medium */
                return KsHandleSizedListQuery(Irp, 1, sizeof(KSPIN_MEDIUM), &StandardPinMedium);
            }
            break;

        case KSPROPERTY_PIN_COMMUNICATION:

            Size = sizeof(KSPIN_COMMUNICATION);
            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
            {
                Irp->IoStatus.Information = Size;
                Status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            *((KSPIN_COMMUNICATION*)Buffer) = Descriptor->Communication;

            Status = STATUS_SUCCESS;
            Irp->IoStatus.Information = Size;
            break;

        case KSPROPERTY_PIN_CATEGORY:

            if (!Descriptor->Category)
            {
                /* no pin category */
                return STATUS_NOT_FOUND;
            }

            /* check size */
            Size = sizeof(GUID);
            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
            {
                /* buffer too small */
                Irp->IoStatus.Information = Size;
                Status = STATUS_BUFFER_TOO_SMALL;
                break;
            }

            /* copy category guid */
            RtlMoveMemory(Buffer, Descriptor->Category, sizeof(GUID));

            /* save result */
            Status = STATUS_SUCCESS;
            Irp->IoStatus.Information = Size;
            break;

        case KSPROPERTY_PIN_NAME:

            if (Descriptor->Name)
            {
                /* use pin name */
                Guid = (LPGUID)Descriptor->Name;
            }
            else
            {
                /* use pin category as fallback */
                Guid = (LPGUID)Descriptor->Category;
            }

            if (!Guid)
            {
                /* no friendly name available */
                return STATUS_NOT_FOUND;
            }

            /* read friendly name category name */
            Status = KspReadMediaCategory(Guid, &KeyInfo);
            if (!NT_SUCCESS(Status))
            {
                /* failed to read category */
                Irp->IoStatus.Information = 0;
                break;
            }

            /* store required length */
            Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR);

            /* check if buffer is too small */
            if (KeyInfo->DataLength + sizeof(WCHAR) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
            {
                /* buffer too small */
                Status = STATUS_BUFFER_OVERFLOW;
                FreeItem(KeyInfo);
                break;
            }

            /* copy result */
            RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, &KeyInfo->Data, KeyInfo->DataLength);

            /* null terminate name */
            ((LPWSTR)Irp->AssociatedIrp.SystemBuffer)[KeyInfo->DataLength / sizeof(WCHAR)] = L'\0';

            /* free key info */
            FreeItem(KeyInfo);
            break;
        case KSPROPERTY_PIN_PROPOSEDATAFORMAT:
            Size = sizeof(KSDATAFORMAT);
            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
            {
                Irp->IoStatus.Information = Size;
                Status = STATUS_BUFFER_TOO_SMALL;
                break;
            }
            if (IoStack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(KSDATAFORMAT_WAVEFORMATEX))
            {
                UNIMPLEMENTED;
                Status = STATUS_NOT_IMPLEMENTED;
                Irp->IoStatus.Information = 0;
                break;
            }

            WaveFormatIn = (PKSDATAFORMAT_WAVEFORMATEX)Buffer;
            if (!Descriptor->DataRanges || !Descriptor->DataRangesCount)
            {
                Status = STATUS_UNSUCCESSFUL;
                Irp->IoStatus.Information = 0;
                break;
            }
            WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor->DataRanges;
            for(Index = 0; Index < Descriptor->DataRangesCount; Index++)
            {
                if (WaveFormatOut[Index]->DataRange.FormatSize != sizeof(KSDATARANGE_AUDIO))
                {
                    UNIMPLEMENTED;
                    continue;
                }

                if (WaveFormatOut[Index]->MinimumSampleFrequency > WaveFormatIn->WaveFormatEx.nSamplesPerSec ||
                    WaveFormatOut[Index]->MaximumSampleFrequency < WaveFormatIn->WaveFormatEx.nSamplesPerSec ||
                    WaveFormatOut[Index]->MinimumBitsPerSample > WaveFormatIn->WaveFormatEx.wBitsPerSample ||
                    WaveFormatOut[Index]->MaximumBitsPerSample < WaveFormatIn->WaveFormatEx.wBitsPerSample ||
                    WaveFormatOut[Index]->MaximumChannels < WaveFormatIn->WaveFormatEx.nChannels)
                {
                    Irp->IoStatus.Status = STATUS_NO_MATCH;
                    Irp->IoStatus.Information = 0;
                    return STATUS_NO_MATCH;
                }
                else
                {
                    Irp->IoStatus.Status = STATUS_SUCCESS;
                    Irp->IoStatus.Information = 0;
                    return STATUS_SUCCESS;
                }
            }
            Status = STATUS_NO_MATCH;
            Irp->IoStatus.Information = 0;
            break;
        default:
            DPRINT1("Unhandled property request %x\n", Property->Id);
            Status = STATUS_NOT_IMPLEMENTED;
            Irp->IoStatus.Information = 0;
    }

    return Status;
}
Ejemplo n.º 25
0
NTSTATUS
KspValidateConnectRequest(
    IN PIRP Irp,
    IN ULONG DescriptorsCount,
    IN PVOID Descriptors,
    IN ULONG DescriptorSize,
    OUT PKSPIN_CONNECT* Connect)
{
    PKSPIN_CONNECT ConnectDetails;
    PKSPIN_INTERFACE Interface;
    PKSPIN_MEDIUM Medium;
    ULONG Size;
    NTSTATUS Status;
    ULONG Index;
    ULONG Count;
    BOOLEAN Found;
    PKSPIN_DESCRIPTOR Descriptor;
    UNICODE_STRING GuidString2;

    /* did the caller miss the connect parameter */
    if (!Connect)
        return STATUS_INVALID_PARAMETER;

    /* set create param  size */
    Size = sizeof(KSPIN_CONNECT);

    /* fetch create parameters */
    Status = KspCopyCreateRequest(Irp,
                                  KSSTRING_Pin,
                                  &Size,
                                  (PVOID*)&ConnectDetails);

    /* check for success */
    if (!NT_SUCCESS(Status))
        return Status;

    /* is pin id out of bounds */
    if (ConnectDetails->PinId >= DescriptorsCount)
    {
        FreeItem(ConnectDetails);
        return STATUS_INVALID_PARAMETER;
    }

    if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR))
    {
        /* standard pin descriptor */
        Descriptor = (PKSPIN_DESCRIPTOR)((ULONG_PTR)Descriptors + sizeof(KSPIN_DESCRIPTOR) * ConnectDetails->PinId);
    }
    else
    {
        /* extended / variable pin descriptor */
        Descriptor = &((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + DescriptorSize * ConnectDetails->PinId))->PinDescriptor;
    }


    /* does the pin have interface details filled in */
    if (Descriptor->InterfacesCount && Descriptor->Interfaces)
    {
        /* use provided pin interface count */
        Count = Descriptor->InterfacesCount;
        Interface = (PKSPIN_INTERFACE)Descriptor->Interfaces;
    }
    else
    {
        /* use standard pin interface */
        Count = 1;
        Interface = &StandardPinInterface;
    }

    /* now check the interface */
    Found = FALSE;
    Index = 0;
    RtlStringFromGUID(&ConnectDetails->Interface.Set, &GuidString2);
    do
    {
        UNICODE_STRING GuidString;
        RtlStringFromGUID(&Interface[Index].Set, &GuidString);

        DPRINT("Driver Interface %S Id %u\n", GuidString.Buffer, Interface[Index].Id);
        DPRINT("Connect Interface %S Id %u\n", GuidString2.Buffer, ConnectDetails->Interface.Id);

        RtlFreeUnicodeString(&GuidString);

        if (IsEqualGUIDAligned(&Interface[Index].Set, &ConnectDetails->Interface.Set) &&
                               Interface[Index].Id == ConnectDetails->Interface.Id)
        {
            /* found a matching interface */
            Found = TRUE;
            break;
        }
        /* iterate to next interface */
        Index++;
    }while(Index < Count);
    RtlFreeUnicodeString(&GuidString2);

    if (!Found)
    {
        /* pin doesnt support this interface */
        FreeItem(ConnectDetails);
        return STATUS_NO_MATCH;
    }

    /* does the pin have medium details filled in */
    if (Descriptor->MediumsCount && Descriptor->Mediums)
    {
        /* use provided pin interface count */
        Count = Descriptor->MediumsCount;
        Medium = (PKSPIN_MEDIUM)Descriptor->Mediums;
    }
    else
    {
        /* use standard pin interface */
        Count = 1;
        Medium = &StandardPinMedium;
    }

    /* now check the interface */
    Found = FALSE;
    Index = 0;
    RtlStringFromGUID(&ConnectDetails->Medium.Set, &GuidString2);
    do
    {
        UNICODE_STRING GuidString;
        RtlStringFromGUID(&Medium[Index].Set, &GuidString);

        DPRINT("Driver Medium %S Id %u\n", GuidString.Buffer, Medium[Index].Id);
        DPRINT("Connect Medium %S Id %u\n", GuidString2.Buffer, ConnectDetails->Medium.Id);

        RtlFreeUnicodeString(&GuidString);

        if (IsEqualGUIDAligned(&Medium[Index].Set, &ConnectDetails->Medium.Set) &&
                               Medium[Index].Id == ConnectDetails->Medium.Id)
        {
            /* found a matching interface */
            Found = TRUE;
            break;
        }

        /* iterate to next medium */
        Index++;
    }while(Index < Count);
    RtlFreeUnicodeString(&GuidString2);

    if (!Found)
    {
        /* pin doesnt support this medium */
        FreeItem(ConnectDetails);
        return STATUS_NO_MATCH;
    }

    /// FIXME
    /// implement format checking

    *Connect = ConnectDetails;
    return STATUS_SUCCESS;
}
Ejemplo n.º 26
0
VOID Driver_Load()
{
    NTSTATUS status;

    status = SlLoadDriver(
        L"PUSH",
        L"push0.sys",
        L"Push Kernel-Mode Driver",
        L"\\\\.\\Push",
        TRUE,
        &R0DriverHandle
        );

    if (!NT_SUCCESS(status))
    {
        if (status == STATUS_OBJECT_NAME_NOT_FOUND)
        {
            MessageBoxW(NULL, L"Driver file not found!", L"Error", 0);
        }

        if (status == STATUS_DRIVER_BLOCKED_CRITICAL)
        {
            // Probably wrong driver. Overwrite.

            DeleteFileW(L"push0.sys");
            Driver_Extract();

            // Try again.
            Driver_Load();
        }

        if (status == STATUS_INVALID_IMAGE_HASH)
        {
            INT32 msgId;

            // Prompt user to enable test-signing.
            msgId = MessageBoxW(
                NULL,
                L"The driver failed to load because it isn't signed. "
                L"It is required for Push to work correctly. "
                L"Do you want to enable test-signing to be able to use driver functions?",
                L"Driver Signing",
                MB_ICONQUESTION | MB_YESNO
                );

            if (msgId == IDYES)
            {
                HANDLE keyHandle;
                DWORD size = 255;
                WCHAR buffer[255];
                BYTE value = 0x01;
                UNICODE_STRING valueName;
                SYSTEM_BOOT_ENVIRONMENT_INFORMATION bootEnvironmentInformation;
                UINT32 returnLength;
                UNICODE_STRING guidAsUnicodeString;
                WCHAR guidAsWideChar[40];
                ULONG bufferLength = 20;
                OBJECT_ATTRIBUTES objectAttributes;
                UNICODE_STRING keyName;
                ULONG disposition;

                // Get boot GUID.

                NtQuerySystemInformation(
                    SystemBootEnvironmentInformation,
                    &bootEnvironmentInformation,
                    sizeof(SYSTEM_BOOT_ENVIRONMENT_INFORMATION),
                    &returnLength
                    );

                RtlStringFromGUID(
                    &bootEnvironmentInformation.BootIdentifier,
                    &guidAsUnicodeString
                    );

                String::CopyN(guidAsWideChar, guidAsUnicodeString.Buffer, 39);

                guidAsWideChar[39] = L'\0';

                swprintf(
                    buffer,
                    255,
                    L"\\Registry\\Machine\\BCD00000000\\Objects\\%s\\Elements",
                    guidAsWideChar
                    );

                // Change key permissions to allow us to create sub keys.
                StripPermissions(buffer);

                // Enable test-signing mode.

                String::Concatenate(buffer, L"\\16000049");

                // Change key permissions (if it already exists) to allow us to set values.
                StripPermissions(buffer);

                UnicodeString::Init(&keyName, buffer);
                UnicodeString::Init(&valueName, L"Element");

                objectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
                objectAttributes.RootDirectory = NULL;
                objectAttributes.ObjectName = &keyName;
                objectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
                objectAttributes.SecurityDescriptor = NULL;
                objectAttributes.SecurityQualityOfService = NULL;

                // Create(NtCreateKey) the key not open(NtOpenKey) it because the key isn't
                // always there.
                NtCreateKey(
                    &keyHandle,
                    KEY_WRITE,
                    &objectAttributes,
                    0,
                    NULL,
                    0,
                    &disposition
                    );

                NtSetValueKey(keyHandle, &valueName, 0, REG_BINARY, &value, sizeof(BYTE));
                NtClose(keyHandle);

                MessageBoxW(
                    NULL,
                    L"Restart your computer to load driver",
                    L"Restart required",
                    NULL
                    );
            }
        }
    }
}