Ejemplo n.º 1
0
//
//	Process DevicePropertyInstallState and DevicePropertyRemovalPolicy on Windows 2000
//
NTSTATUS
DrGetDeviceProperty_ExtW2K(
	IN PDEVICE_OBJECT  DeviceObject,
    IN DEVICE_REGISTRY_PROPERTY  DeviceProperty,
    IN ULONG  BufferLength,
    OUT PVOID  PropertyBuffer,
    OUT PULONG  ResultLength
) {
	NTSTATUS status;

	switch(DevicePropertyInstallState) {
		case DevicePropertyInstallState:
			status = DrGetDevicePropertyInstallState(
							DeviceObject,
							BufferLength,
							PropertyBuffer,
							ResultLength
						);
			break;
		default:
			status = IoGetDeviceProperty(
							DeviceObject,
							DeviceProperty,
							BufferLength,
							PropertyBuffer,
							ResultLength
						);
	}

	return status;
}
NTSTATUS
RosKmAdapter::AddAdapter(
    IN_CONST_PDEVICE_OBJECT     PhysicalDeviceObject,
    OUT_PPVOID                  MiniportDeviceContext)
{
    NTSTATUS status;
    WCHAR deviceID[512];
    ULONG dataLen;

    status = IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyHardwareID, sizeof(deviceID), deviceID, &dataLen);

    if (status != STATUS_SUCCESS)
        return status;

    RosKmAdapter  *pRosKmAdapter = nullptr;
    if (wcscmp(deviceID, L"ACPI\\VEN_BCM&DEV_2850") == 0)
    {
        pRosKmAdapter = new RosKmdRapAdapter(PhysicalDeviceObject, MiniportDeviceContext);
    }
    else
    {
        pRosKmAdapter = new RosKmdSoftAdapter(PhysicalDeviceObject, MiniportDeviceContext);
    }

    if (!pRosKmAdapter)
    {
        return STATUS_NO_MEMORY;
    }

    return STATUS_SUCCESS;
}
Ejemplo n.º 3
0
NTSTATUS vboxWddmRegQueryDrvKeyName(PVBOXMP_DEVEXT pDevExt, ULONG cbBuf, PWCHAR pBuf, PULONG pcbResult)
{
    WCHAR fallBackBuf[2];
    PWCHAR pSuffix;
    bool bFallback = false;

    if (cbBuf > sizeof(VBOXWDDM_REG_DRVKEY_PREFIX))
    {
        memcpy(pBuf, VBOXWDDM_REG_DRVKEY_PREFIX, sizeof (VBOXWDDM_REG_DRVKEY_PREFIX));
        pSuffix = pBuf + (sizeof (VBOXWDDM_REG_DRVKEY_PREFIX)-2)/2;
        cbBuf -= sizeof (VBOXWDDM_REG_DRVKEY_PREFIX)-2;
    }
    else
    {
        pSuffix = fallBackBuf;
        cbBuf = sizeof (fallBackBuf);
        bFallback = true;
    }

    NTSTATUS Status = IoGetDeviceProperty (pDevExt->pPDO,
                                           DevicePropertyDriverKeyName,
                                           cbBuf,
                                           pSuffix,
                                           &cbBuf);
    if (Status == STATUS_SUCCESS && bFallback)
        Status = STATUS_BUFFER_TOO_SMALL;
    if (Status == STATUS_BUFFER_TOO_SMALL)
        *pcbResult = cbBuf + sizeof (VBOXWDDM_REG_DRVKEY_PREFIX)-2;

    return Status;
}
Ejemplo n.º 4
0
// 
// 实现我们自己的AddDevice函数
//
NTSTATUS myAddDevice(
					 IN PDRIVER_OBJECT  DriverObject,
					 IN PDEVICE_OBJECT  PhysicalDeviceObject 
					 )
{
	if(gDeviceObject != NULL)
	{
		// 在这里面创建我们自己的设备对象,或者申请所需要的资源。
		// 为了区分不同实例,将设备对象名构造成:”MyNdisDevice”+HardwareID。
		UNICODE_STRING nameString; 
		WCHAR wcsName[256];
		UNICODE_STRING preName = RTL_CONSTANT_STRING(L"\\Device\\MyNdisDevice");

		// 首先取得设备的HDID。
		ULONG nameLength = 0;
		WCHAR wcsHardwareID[256]; //足够大了
		NTSTATUS status = IoGetDeviceProperty (PhysicalDeviceObject,
			DevicePropertyHardwareID,
			256,
			wcsHardwareID,
			&nameLength);
		if(status != STATUS_SUCCESS){
			KdPrint(("Failed to get hardware ID %x\n", status));
			return status;
		}

		// 下面构造设备对象的名字,根据上面的规则:“MyNdisDevice”+ HardwareID。
		RtlInitEmptyUnicodeString( &nameString, wcsName, 256*2);
		RtlCopyUnicodeString( &nameString, &preName);
		//RtlUnicodeStringPrintf(&nameString, L"%wZ_%d_", &preName, 0);
		RtlAppendUnicodeToString( &nameString, wcsHardwareID);

		status = IoCreateDevice(DriverObject,
			0,
			&nameString,
			FILE_DEVICE_UNKNOWN,
			FILE_DEVICE_SECURE_OPEN,
			FALSE,
			&gDeviceObject); 

		// 如果创建失败了,我们有权利让函数以失败返回
		// 但这样我们的驱动加载也就失败了
		if(status != STATUS_SUCCESS){
			KdPrint(("Failed to create device %ws\n", nameString));
			return status;
		}
	}

	//ExAllocatePoolWithTag(); //申请资源及其他

	// 
	// 还可以加入其他正确的操作
	//

	// 现在调用保存的Ndis库中的AddDevice实现
	// 千万不要忘记,否则就会大错特错了
	return systemAddDevice(DriverObject, PhysicalDeviceObject);
}
Ejemplo n.º 5
0
NTSTATUS myAddDevice(
	IN PDRIVER_OBJECT  DriverObject,
	IN PDEVICE_OBJECT  PhysicalDeviceObject)
{
	DbgBreakPoint();
	WCHAR classname[100];
	ULONG longret;
	IoGetDeviceProperty(PhysicalDeviceObject, DevicePropertyClassName, 100, classname, &longret);
	DbgPrint("class name:%ws\n", classname);
	return sysadddevfunc(DriverObject, PhysicalDeviceObject);
}
Ejemplo n.º 6
0
NTSTATUS
NTAPI
CPortWaveCyclic::GetDeviceProperty(
    IN DEVICE_REGISTRY_PROPERTY  DeviceRegistryProperty,
    IN ULONG  BufferLength,
    OUT PVOID  PropertyBuffer,
    OUT PULONG  ReturnLength)
{
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    return IoGetDeviceProperty(m_pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength);
}
Ejemplo n.º 7
0
NTSTATUS MrQueryString(
    IN PDEVICE_OBJECT           d,
    IN DEVICE_REGISTRY_PROPERTY c,
    IN OUT PUNICODE_STRING      n
    )
{
    PWCHAR data = NULL;
    ULONG len = 0;
    NTSTATUS status;

    data = MrAlloc(1024);
    if (NULL == data) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto errorout;
    }

    RtlZeroMemory(n, sizeof(UNICODE_STRING));
    status = IoGetDeviceProperty(d,
                                 c,
                                 1024,
                                 data,
                                 &len);

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

    len = wcslen(data) * sizeof(WCHAR);
    if (0 == len) {
        goto errorout;
    }
    n->MaximumLength = (USHORT)len + sizeof(WCHAR);
    n->Buffer = MrAlloc(n->MaximumLength);
    if (NULL == n->Buffer) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto errorout;
    }
    RtlCopyMemory(n->Buffer, data, len);
    n->Length = (USHORT)len;

errorout:

    if (data)
        MrFree(data);

    return status;
}
Ejemplo n.º 8
0
//
//	Complement Windows 2000's IoGetDeviceProperty()
//
NTSTATUS
DrGetDeviceProperty(
	IN PDEVICE_OBJECT  DeviceObject,
    IN DEVICE_REGISTRY_PROPERTY  DeviceProperty,
    IN ULONG	BufferLength,
    OUT PVOID	PropertyBuffer,
    OUT PULONG  ResultLength,
	IN BOOLEAN	Win2K
) {
	NTSTATUS	status;

	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

	if(!DeviceObject)
		return STATUS_INVALID_PARAMETER;
	if(Win2K) {
		status = DrGetDeviceProperty_ExtW2K(
							DeviceObject,
							DeviceProperty,
							BufferLength,
							PropertyBuffer,
							ResultLength
			);
	} else {

		__try {

			status = IoGetDeviceProperty(
							DeviceObject,
							DeviceProperty,
							BufferLength,
							PropertyBuffer,
							ResultLength
						);

		}  __except (EXCEPTION_EXECUTE_HANDLER) {

			status = GetExceptionCode();
			KDPrint(1, ("IoGetDeviceProperty() Exception: %08lx\n", status));

		}

	}


	return status;
}
Ejemplo n.º 9
0
NTSTATUS MrQueryBinary(
    IN PDEVICE_OBJECT           d,
    IN DEVICE_REGISTRY_PROPERTY c,
    IN OUT PVOID                p,
    IN ULONG                    l
    )
{
    NTSTATUS status;

    RtlZeroMemory(p, l);
    status = IoGetDeviceProperty(d,
                                 c,
                                 l,
                                 p,
                                 &l);
    return status;
}
Ejemplo n.º 10
0
NTSTATUS
NTAPI
CPortDMus::GetDeviceProperty(
    IN DEVICE_REGISTRY_PROPERTY  DeviceRegistryProperty,
    IN ULONG  BufferLength,
    OUT PVOID  PropertyBuffer,
    OUT PULONG  ReturnLength)
{
    PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);

    if (!m_bInitialized)
    {
        DPRINT("IPortDMus_fnNewRegistryKey called w/o initialized\n");
        return STATUS_UNSUCCESSFUL;
    }

    return IoGetDeviceProperty(m_pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength);
}
Ejemplo n.º 11
0
//
//	Complement Windows 2000's IoGetDeviceProperty()
//
NTSTATUS
DrGetDeviceProperty(
	IN PDEVICE_OBJECT  DeviceObject,
    IN DEVICE_REGISTRY_PROPERTY  DeviceProperty,
    IN ULONG	BufferLength,
    OUT PVOID	PropertyBuffer,
    OUT PULONG  ResultLength,
	IN BOOLEAN	Win2K
) {
	NTSTATUS	status;

	ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);

	if(!DeviceObject)
		return STATUS_INVALID_PARAMETER;
	if(Win2K) {
		status = DrGetDeviceProperty_ExtW2K(
							DeviceObject,
							DeviceProperty,
							BufferLength,
							PropertyBuffer,
							ResultLength
			);
	} else {
		status = IoGetDeviceProperty(
							DeviceObject,
							DeviceProperty,
							BufferLength,
							PropertyBuffer,
							ResultLength
						);
	}


	return status;
}
Ejemplo n.º 12
0
NTSTATUS
Bus_AddDevice(
    __in PDRIVER_OBJECT DriverObject,
    __in PDEVICE_OBJECT PhysicalDeviceObject
    )
/*++
Routine Description.

    Our Toaster bus has been found.  Attach our FDO to it.
    Allocate any required resources.  Set things up.
    And be prepared for the ``start device''

Arguments:

    DriverObject - pointer to driver object.

    PhysicalDeviceObject  - Device object representing the bus to which we
                            will attach a new FDO.

--*/
{
    NTSTATUS            status;
    PDEVICE_OBJECT      deviceObject = NULL;
    PFDO_DEVICE_DATA    deviceData = NULL;
    PWCHAR              deviceName = NULL;
    ULONG               nameLength;
    PKTIMER		timer;
    PKDPC		dpc;

    PAGED_CODE ();

    Bus_KdPrint_Def (BUS_DBG_SS_TRACE, ("Add Device: 0x%p\n",
                                          PhysicalDeviceObject));

    status = IoCreateDevice (
                    DriverObject,               // our driver object
                    sizeof (FDO_DEVICE_DATA),   // device object extension size
                    NULL,                       // FDOs do not have names
                    FILE_DEVICE_BUS_EXTENDER,   // We are a bus
                    FILE_DEVICE_SECURE_OPEN,    //
                    TRUE,                       // our FDO is exclusive
                    &deviceObject);             // The device object created

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

    deviceData = (PFDO_DEVICE_DATA) deviceObject->DeviceExtension;
    RtlZeroMemory (deviceData, sizeof (FDO_DEVICE_DATA));

    //
    // Set the initial state of the FDO
    //

    INITIALIZE_PNP_STATE(deviceData);

    deviceData->DebugLevel = BusEnumDebugLevel;

    deviceData->IsFDO = TRUE;

    deviceData->Self = deviceObject;

    ExInitializeFastMutex (&deviceData->Mutex);

    InitializeListHead (&deviceData->ListOfPDOs);

    // Set the PDO for use with PlugPlay functions

    deviceData->UnderlyingPDO = PhysicalDeviceObject;

    //
    // Set the initial powerstate of the FDO
    //

    deviceData->DevicePowerState = PowerDeviceUnspecified;
    deviceData->SystemPowerState = PowerSystemWorking;


    //
    // Biased to 1. Transition to zero during remove device
    // means IO is finished. Transition to 1 means the device
    // can be stopped.
    //

    deviceData->OutstandingIO = 1;

    //
    // Initialize the remove event to Not-Signaled.  This event
    // will be set when the OutstandingIO will become 0.
    //

    KeInitializeEvent(&deviceData->RemoveEvent,
                  SynchronizationEvent,
                  FALSE);
    //
    // Initialize the stop event to Signaled:
    // there are no Irps that prevent the device from being
    // stopped. This event will be set when the OutstandingIO
    // will become 0.
    //

    KeInitializeEvent(&deviceData->StopEvent,
                      SynchronizationEvent,
                      TRUE);

    deviceObject->Flags |= DO_POWER_PAGABLE|DO_BUFFERED_IO;

    //
    // Tell the Plug & Play system that this device will need a
    // device interface.
    //

    status = IoRegisterDeviceInterface (
                PhysicalDeviceObject,
                (LPGUID) &GUID_DEVINTERFACE_BUSENUM_TOASTER,
                NULL,
                &deviceData->InterfaceName);

    if (!NT_SUCCESS (status)) {
        Bus_KdPrint (deviceData, BUS_DBG_SS_ERROR,
                      ("AddDevice: IoRegisterDeviceInterface failed (%x)", status));
        goto End;
    }

    //
    // Attach our FDO to the device stack.
    // The return value of IoAttachDeviceToDeviceStack is the top of the
    // attachment chain.  This is where all the IRPs should be routed.
    //

    deviceData->NextLowerDriver = IoAttachDeviceToDeviceStack (
                                    deviceObject,
                                    PhysicalDeviceObject);

    if (NULL == deviceData->NextLowerDriver) {

        status = STATUS_NO_SUCH_DEVICE;
        goto End;
    }


#if DBG
    //
    // We will demonstrate here the step to retrieve the name of the PDO
    //

    status = IoGetDeviceProperty (PhysicalDeviceObject,
                                  DevicePropertyPhysicalDeviceObjectName,
                                  0,
                                  NULL,
                                  &nameLength);

    if (status != STATUS_BUFFER_TOO_SMALL)
    {
        Bus_KdPrint (deviceData, BUS_DBG_SS_ERROR,
                      ("AddDevice:IoGDP failed (0x%x)\n", status));
        goto End;
    }

    deviceName = ExAllocatePoolWithTag (NonPagedPool,
                            nameLength, BUSENUM_POOL_TAG);

    if (NULL == deviceName) {
        Bus_KdPrint (deviceData, BUS_DBG_SS_ERROR,
        ("AddDevice: no memory to alloc for deviceName(0x%x)\n", nameLength));
        status =  STATUS_INSUFFICIENT_RESOURCES;
        goto End;
    }

    status = IoGetDeviceProperty (PhysicalDeviceObject,
                         DevicePropertyPhysicalDeviceObjectName,
                         nameLength,
                         deviceName,
                         &nameLength);

    if (!NT_SUCCESS (status)) {

        Bus_KdPrint (deviceData, BUS_DBG_SS_ERROR,
                      ("AddDevice:IoGDP(2) failed (0x%x)", status));
        goto End;
    }

    Bus_KdPrint (deviceData, BUS_DBG_SS_TRACE,
                  ("AddDevice: %p to %p->%p (%ws) \n",
                   deviceObject,
                   deviceData->NextLowerDriver,
                   PhysicalDeviceObject,
                   deviceName));

#endif

    //
    // We are done with initializing, so let's indicate that and return.
    // This should be the final step in the AddDevice process.
    //
    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

End:
    if (deviceName){
        ExFreePool(deviceName);
    }

    if (!NT_SUCCESS(status) && deviceObject){
        if (deviceData && deviceData->NextLowerDriver){
            IoDetachDevice (deviceData->NextLowerDriver);
        }
        IoDeleteDevice (deviceObject);
    }

    return status;

}
Ejemplo n.º 13
0
NTSTATUS
StartDevice(PDEVICE_OBJECT DeviceObject, PCM_PARTIAL_RESOURCE_LIST raw, PCM_PARTIAL_RESOURCE_LIST translated)
{
    PFDO_DEVICE_EXTENSION FdoDeviceExtension;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR resource;
    DEVICE_DESCRIPTION DeviceDescription;
    PEHCI_HOST_CONTROLLER hcd;
    ULONG NumberResources;
    ULONG iCount;
    ULONG DeviceAddress;
    ULONG PropertySize;
    ULONG BusNumber;
    NTSTATUS Status;

    FdoDeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    hcd = &FdoDeviceExtension->hcd;

    /* Sanity Checks */
    Status = IoGetDeviceProperty(FdoDeviceExtension->LowerDevice,
                                 DevicePropertyAddress,
                                 sizeof(ULONG),
                                 &DeviceAddress,
                                 &PropertySize);

    Status = IoGetDeviceProperty(FdoDeviceExtension->LowerDevice,
                                 DevicePropertyBusNumber,
                                 sizeof(ULONG),
                                 &BusNumber,
                                 &PropertySize);


    /* Get the resources the PNP Manager gave */
    NumberResources = translated->Count;
    DPRINT("NumberResources %d\n", NumberResources);
    for (iCount = 0; iCount < NumberResources; iCount++)
    {
        DPRINT("Resource Info %d:\n", iCount);
        resource = &translated->PartialDescriptors[iCount];
        switch(resource->Type)
        {
            case CmResourceTypePort:
            {
                DPRINT("Port Start: %x\n", resource->u.Port.Start);
                DPRINT("Port Length %d\n", resource->u.Port.Length);
                /* FIXME: Handle Ports */
                break;
            }
            case CmResourceTypeInterrupt:
            {
                DPRINT("Interrupt Vector: %x\n", resource->u.Interrupt.Vector);
                FdoDeviceExtension->Vector = resource->u.Interrupt.Vector;
                FdoDeviceExtension->Irql = resource->u.Interrupt.Level;
                FdoDeviceExtension->Affinity = resource->u.Interrupt.Affinity;
                FdoDeviceExtension->Mode = (resource->Flags == CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive;
                FdoDeviceExtension->IrqShared = resource->ShareDisposition == CmResourceShareShared;
                break;
            }
            case CmResourceTypeMemory:
            {
                PVOID ResourceBase = 0;

                DPRINT("Mem Start: %x\n", resource->u.Memory.Start);
                DPRINT("Mem Length: %d\n", resource->u.Memory.Length);

                ResourceBase = MmMapIoSpace(resource->u.Memory.Start, resource->u.Memory.Length, FALSE);
                DPRINT("ResourceBase %x\n", ResourceBase);
                if (ResourceBase  == NULL)
                {
                    DPRINT1("MmMapIoSpace failed!!!!!!!!!\n");
                }

                GetCapabilities(&FdoDeviceExtension->hcd.ECHICaps, (ULONG)ResourceBase);
                DPRINT1("hcd.ECHICaps.Length %x\n", FdoDeviceExtension->hcd.ECHICaps.Length);
                FdoDeviceExtension->hcd.OpRegisters = (ULONG)((ULONG)ResourceBase + FdoDeviceExtension->hcd.ECHICaps.Length);
                break;
            }
            case CmResourceTypeDma:
            {
                DPRINT("Dma Channel: %x\n", resource->u.Dma.Channel);
                DPRINT("Dma Port: %d\n", resource->u.Dma.Port);
                break;
            }
            case CmResourceTypeDevicePrivate:
            {
                /* Windows does this. */
                DPRINT1("CmResourceTypeDevicePrivate not handled\n");
                break;
            }
            default:
            {
                DPRINT1("PNP Manager gave resource type not handled!! Notify Developers!\n");
                break;
            }
        }
    }

    for (iCount = 0; iCount < hcd->ECHICaps.HCSParams.PortCount; iCount++)
    {
        hcd->Ports[iCount].PortStatus = 0x8000;
        hcd->Ports[iCount].PortChange = 0;
        
        if (hcd->ECHICaps.HCSParams.PortPowerControl)
            hcd->Ports[iCount].PortStatus |= USB_PORT_STATUS_POWER;
    }

    KeInitializeDpc(&FdoDeviceExtension->DpcObject,
                    EhciDefferedRoutine,
                    FdoDeviceExtension);

    RtlZeroMemory(&DeviceDescription, sizeof(DEVICE_DESCRIPTION));

    DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
    DeviceDescription.Master = TRUE;
    DeviceDescription.ScatterGather = TRUE;
    DeviceDescription.Dma32BitAddresses = TRUE;
    DeviceDescription.DmaWidth = 2;
    DeviceDescription.InterfaceType = PCIBus;
    DeviceDescription.MaximumLength = EHCI_MAX_SIZE_TRANSFER;

    hcd->pDmaAdapter = IoGetDmaAdapter(FdoDeviceExtension->LowerDevice,
                                       &DeviceDescription,
                                       &hcd->MapRegisters);

    if (hcd->pDmaAdapter == NULL)
    {
        DPRINT1("Ehci: IoGetDmaAdapter failed!\n");
        ASSERT(FALSE);
    }

    DPRINT1("MapRegisters %x\n", hcd->MapRegisters);

    /* Allocate Common Buffer for Periodic Frame List */
    FdoDeviceExtension->PeriodicFrameList.VirtualAddr =
        hcd->pDmaAdapter->DmaOperations->AllocateCommonBuffer(hcd->pDmaAdapter,
                                                              sizeof(ULONG) * 1024,
                                                              &FdoDeviceExtension->PeriodicFrameList.PhysicalAddr,
                                                              FALSE);

    if (FdoDeviceExtension->PeriodicFrameList.VirtualAddr == NULL)
    {
        DPRINT1("Ehci: FdoDeviceExtension->PeriodicFramList is null\n");
        return STATUS_UNSUCCESSFUL;
    }

    /* Zeroize it */
    RtlZeroMemory(FdoDeviceExtension->PeriodicFrameList.VirtualAddr, sizeof(ULONG) * 1024);

    ExInitializeFastMutex(&FdoDeviceExtension->FrameListMutex);

    /* Allocate initial page for queueheads and descriptors */
    FdoDeviceExtension->hcd.CommonBufferVA[0] =
        hcd->pDmaAdapter->DmaOperations->AllocateCommonBuffer(hcd->pDmaAdapter,
                                                              PAGE_SIZE,
                                                              &FdoDeviceExtension->hcd.CommonBufferPA[0],
                                                              FALSE);

    if (FdoDeviceExtension->hcd.CommonBufferVA[0] == 0)
    {
        DPRINT1("Ehci: Failed to allocate common buffer!\n");
        return STATUS_UNSUCCESSFUL;
    }

    hcd->CommonBufferSize = PAGE_SIZE * 16;

    /* Zeroize it */
    RtlZeroMemory(FdoDeviceExtension->hcd.CommonBufferVA[0],
                  PAGE_SIZE);

    /* Init SpinLock for host controller device lock */
    KeInitializeSpinLock(&hcd->Lock);

    /* Reserved a Queue Head that will always be in the AsyncList Address Register. By setting it as the Head of Reclamation
       the controller can know when it has reached the end of the QueueHead list */
    hcd->AsyncListQueue = CreateQueueHead(hcd);

    hcd->AsyncListQueue->HorizontalLinkPointer = hcd->AsyncListQueue->PhysicalAddr | QH_TYPE_QH;
    hcd->AsyncListQueue->EndPointCharacteristics.QEDTDataToggleControl = FALSE;
    hcd->AsyncListQueue->Token.Bits.InterruptOnComplete = FALSE;
    hcd->AsyncListQueue->EndPointCharacteristics.HeadOfReclamation = TRUE;
    hcd->AsyncListQueue->Token.Bits.Halted = TRUE;
    hcd->AsyncListQueue->NextQueueHead = hcd->AsyncListQueue;
    hcd->AsyncListQueue->PreviousQueueHead = hcd->AsyncListQueue;
    
    /* Reserve a Queue Head thats only purpose is for linking completed Queue Heads.
       Completed QueueHeads are moved to this temporary. As the memory must still be valid
       up until the controllers doorbell is rang to let it know info has been removed from QueueHead list */
    hcd->CompletedListQueue = CreateQueueHead(hcd);
    hcd->CompletedListQueue->NextQueueHead = hcd->CompletedListQueue;
    hcd->CompletedListQueue->PreviousQueueHead = hcd->CompletedListQueue;
    
    /* Ensure the controller is stopped */
    StopEhci(hcd);
    
    SetAsyncListQueueRegister(hcd, hcd->AsyncListQueue->PhysicalAddr);

    /* FIXME: Implement Periodic Frame List */

    Status = IoConnectInterrupt(&FdoDeviceExtension->EhciInterrupt,
                                InterruptService,
                                FdoDeviceExtension->DeviceObject,
                                NULL,
                                FdoDeviceExtension->Vector,
                                FdoDeviceExtension->Irql,
                                FdoDeviceExtension->Irql,
                                FdoDeviceExtension->Mode,
                                FdoDeviceExtension->IrqShared,
                                FdoDeviceExtension->Affinity,
                                FALSE);

    StartEhci(hcd);
    FdoDeviceExtension->DeviceState = DEVICESTARTED;
    return STATUS_SUCCESS;
}
Ejemplo n.º 14
0
static NTSTATUS
IopGetDeviceProperty(PPLUGPLAY_CONTROL_PROPERTY_DATA PropertyData)
{
    PDEVICE_OBJECT DeviceObject = NULL;
    NTSTATUS Status;
    UNICODE_STRING DeviceInstance;
    ULONG BufferSize;
    ULONG Property = 0;
    PVOID Buffer;

    DPRINT("IopGetDeviceProperty() called\n");
    DPRINT("Device name: %wZ\n", &PropertyData->DeviceInstance);

    Status = IopCaptureUnicodeString(&DeviceInstance, &PropertyData->DeviceInstance);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    _SEH2_TRY
    {
        Property = PropertyData->Property;
        BufferSize = PropertyData->BufferSize;
        ProbeForWrite(PropertyData->Buffer,
                      BufferSize,
                      sizeof(UCHAR));
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
        ExFreePool(DeviceInstance.Buffer);
        _SEH2_YIELD(return _SEH2_GetExceptionCode());
    }
    _SEH2_END;

    /* Get the device object */
    DeviceObject = IopGetDeviceObjectFromDeviceInstance(&DeviceInstance);
    ExFreePool(DeviceInstance.Buffer);
    if (DeviceObject == NULL)
    {
        return STATUS_NO_SUCH_DEVICE;
    }

    Buffer = ExAllocatePool(NonPagedPool, BufferSize);
    if (Buffer == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    Status = IoGetDeviceProperty(DeviceObject,
                                 Property,
                                 BufferSize,
                                 Buffer,
                                 &BufferSize);

    ObDereferenceObject(DeviceObject);

    if (NT_SUCCESS(Status))
    {
        _SEH2_TRY
        {
            memcpy(PropertyData->Buffer, Buffer, BufferSize);
            PropertyData->BufferSize = BufferSize;
        }
        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
        {
            Status = _SEH2_GetExceptionCode();
        }
        _SEH2_END;
    }

    ExFreePool(Buffer);
    return Status;
}
VOID VBoxDeviceAdded(PVBOXMOUSE_DEVEXT pDevExt)
{
    LOGF_ENTER();
    LONG callCnt = InterlockedIncrement(&g_ctx.cDevicesStarted);

    /* One time Vbgl initialization */
    if (callCnt == 1)
    {
        if (!vboxIsVBGLInited() && !vboxIsVBGLInitFailed())
        {
            int rc = VbglInit();

            if (RT_SUCCESS(rc))
            {
                InterlockedExchange(&g_ctx.fVBGLInited, TRUE);
                LOG(("VBGL init OK"));
            }
            else
            {
                InterlockedExchange (&g_ctx.fVBGLInitFailed, TRUE);
                WARN(("VBGL init failed with rc=%#x", rc));
            }
        }
    }

    vboxNewProtDeviceAdded(pDevExt);

    if (!vboxIsHostMouseFound())
    {
        NTSTATUS rc;
        UCHAR buffer[512];
        CM_RESOURCE_LIST *pResourceList = (CM_RESOURCE_LIST *)&buffer[0];
        ULONG cbWritten=0;
        BOOLEAN bDetected = FALSE;

        rc = IoGetDeviceProperty(pDevExt->pdoMain, DevicePropertyBootConfiguration,
                                 sizeof(buffer), &buffer[0], &cbWritten);
        if (!NT_SUCCESS(rc))
        {
            WARN(("IoGetDeviceProperty failed with rc=%#x", rc));
            return;
        }

        LOG(("Number of descriptors: %d", pResourceList->Count));

        /* Check if device claims IO port 0x60 or int12 */
        for (ULONG i=0; i<pResourceList->Count; ++i)
        {
            CM_FULL_RESOURCE_DESCRIPTOR *pFullDescriptor = &pResourceList->List[i];

            LOG(("FullDescriptor[%i]: IfType %d, Bus %d, Ver %d, Rev %d, Count %d",
                 i, pFullDescriptor->InterfaceType, pFullDescriptor->BusNumber,
                 pFullDescriptor->PartialResourceList.Version, pFullDescriptor->PartialResourceList.Revision,
                 pFullDescriptor->PartialResourceList.Count));

            for (ULONG j=0; j<pFullDescriptor->PartialResourceList.Count; ++j)
            {
                CM_PARTIAL_RESOURCE_DESCRIPTOR *pPartialDescriptor = &pFullDescriptor->PartialResourceList.PartialDescriptors[j];
                LOG(("PartialDescriptor[%d]: type %d, ShareDisposition %d, Flags 0x%04X, Start 0x%llx, length 0x%x",
                     j, pPartialDescriptor->Type, pPartialDescriptor->ShareDisposition, pPartialDescriptor->Flags,
                     pPartialDescriptor->u.Generic.Start.QuadPart, pPartialDescriptor->u.Generic.Length));

                switch(pPartialDescriptor->Type)
                {
                    case CmResourceTypePort:
                    {
                        LOG(("CmResourceTypePort %#x", pPartialDescriptor->u.Port.Start.QuadPart));
                        if (pPartialDescriptor->u.Port.Start.QuadPart == 0x60)
                        {
                            bDetected = TRUE;
                        }
                        break;
                    }
                    case CmResourceTypeInterrupt:
                    {
                        LOG(("CmResourceTypeInterrupt %ld", pPartialDescriptor->u.Interrupt.Vector));
                        if (pPartialDescriptor->u.Interrupt.Vector == 0xC)
                        {
                            bDetected = TRUE;
                        }
                        break;
                    }
                    default:
                    {
                        break;
                    }
                }
            }
        }

        if (bDetected)
        {
            /* It's the emulated 8042 PS/2 mouse/kbd device, so mark it as the Host one.
             * For this device the filter will query absolute mouse coords from the host.
             */
            InterlockedExchange(&g_ctx.fHostMouseFound, TRUE);

            pDevExt->bHostMouse = TRUE;
            LOG(("Host mouse found"));
        }
    }
    LOGF_LEAVE();
}
Ejemplo n.º 16
0
NTSTATUS
NTAPI
Bus_AddDevice(
    PDRIVER_OBJECT DriverObject,
    PDEVICE_OBJECT PhysicalDeviceObject
    )

{
    NTSTATUS            status;
    PDEVICE_OBJECT      deviceObject = NULL;
    PFDO_DEVICE_DATA    deviceData = NULL;
    PWCHAR              deviceName = NULL;
#ifndef NDEBUG
    ULONG               nameLength;
#endif

    PAGED_CODE ();

    DPRINT("Add Device: 0x%p\n",  PhysicalDeviceObject);

    DPRINT("#################### Bus_CreateClose Creating FDO Device ####################\n");
    status = IoCreateDevice(DriverObject,
                      sizeof(FDO_DEVICE_DATA),
                      NULL,
                      FILE_DEVICE_ACPI,
                      FILE_DEVICE_SECURE_OPEN,
                      TRUE,
                      &deviceObject);
    if (!NT_SUCCESS(status))
    {
        DPRINT1("IoCreateDevice() failed with status 0x%X\n", status);
        goto End;
    }

    deviceData = (PFDO_DEVICE_DATA) deviceObject->DeviceExtension;
    RtlZeroMemory (deviceData, sizeof (FDO_DEVICE_DATA));

    //
    // Set the initial state of the FDO
    //

    INITIALIZE_PNP_STATE(deviceData->Common);

    deviceData->Common.IsFDO = TRUE;

    deviceData->Common.Self = deviceObject;

    ExInitializeFastMutex (&deviceData->Mutex);

    InitializeListHead (&deviceData->ListOfPDOs);

    // Set the PDO for use with PlugPlay functions

    deviceData->UnderlyingPDO = PhysicalDeviceObject;

    //
    // Set the initial powerstate of the FDO
    //

    deviceData->Common.DevicePowerState = PowerDeviceUnspecified;
    deviceData->Common.SystemPowerState = PowerSystemWorking;

    deviceObject->Flags |= DO_POWER_PAGABLE;

    //
    // Attach our FDO to the device stack.
    // The return value of IoAttachDeviceToDeviceStack is the top of the
    // attachment chain.  This is where all the IRPs should be routed.
    //

    deviceData->NextLowerDriver = IoAttachDeviceToDeviceStack (
                                    deviceObject,
                                    PhysicalDeviceObject);

    if (NULL == deviceData->NextLowerDriver) {

        status = STATUS_NO_SUCH_DEVICE;
        goto End;
    }


#ifndef NDEBUG
    //
    // We will demonstrate here the step to retrieve the name of the PDO
    //

    status = IoGetDeviceProperty (PhysicalDeviceObject,
                                  DevicePropertyPhysicalDeviceObjectName,
                                  0,
                                  NULL,
                                  &nameLength);

    if (status != STATUS_BUFFER_TOO_SMALL)
    {
        DPRINT1("AddDevice:IoGDP failed (0x%x)\n", status);
        goto End;
    }

    deviceName = ExAllocatePoolWithTag (NonPagedPool,
                            nameLength, 'IPCA');

    if (NULL == deviceName) {
        DPRINT1("AddDevice: no memory to alloc for deviceName(0x%x)\n", nameLength);
        status =  STATUS_INSUFFICIENT_RESOURCES;
        goto End;
    }

    status = IoGetDeviceProperty (PhysicalDeviceObject,
                         DevicePropertyPhysicalDeviceObjectName,
                         nameLength,
                         deviceName,
                         &nameLength);

    if (!NT_SUCCESS (status)) {

        DPRINT1("AddDevice:IoGDP(2) failed (0x%x)", status);
        goto End;
    }

    DPRINT("AddDevice: %p to %p->%p (%ws) \n",
                   deviceObject,
                   deviceData->NextLowerDriver,
                   PhysicalDeviceObject,
                   deviceName);

#endif

    //
    // We are done with initializing, so let's indicate that and return.
    // This should be the final step in the AddDevice process.
    //
    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

End:
    if (deviceName){
        ExFreePool(deviceName);
    }
    if (!NT_SUCCESS(status) && deviceObject){
        if (deviceData && deviceData->NextLowerDriver){
            IoDetachDevice (deviceData->NextLowerDriver);
        }
        IoDeleteDevice (deviceObject);
    }
    return status;

}
Ejemplo n.º 17
0
//-------------------------------------------------------------------------------------------------
NTSTATUS
CHCDController::HandleDeviceControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp)
{
    PIO_STACK_LOCATION IoStack;
    PCOMMON_DEVICE_EXTENSION DeviceExtension;
    NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
    PUSB_HCD_DRIVERKEY_NAME DriverKey;
    ULONG ResultLength;

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

    //
    // get device extension
    //
    DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    //
    // sanity check
    //
    PC_ASSERT(DeviceExtension->IsFDO);

    DPRINT1("[%s] HandleDeviceControl>Type: IoCtl %x InputBufferLength %lu OutputBufferLength %lu\n", m_USBType,
        IoStack->Parameters.DeviceIoControl.IoControlCode,
        IoStack->Parameters.DeviceIoControl.InputBufferLength,
        IoStack->Parameters.DeviceIoControl.OutputBufferLength);

    //
    // perform ioctl for FDO
    //
    if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_HCD_DRIVERKEY_NAME)
    {
        //
        // check if sizee is at least >= USB_HCD_DRIVERKEY_NAME
        //
        if(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(USB_HCD_DRIVERKEY_NAME))
        {
            //
            // get device property size
            //
            Status = IoGetDeviceProperty(m_PhysicalDeviceObject, DevicePropertyDriverKeyName, 0, NULL, &ResultLength);

            //
            // get input buffer
            //
            DriverKey = (PUSB_HCD_DRIVERKEY_NAME)Irp->AssociatedIrp.SystemBuffer;

            //
            // check result
            //
            if (Status == STATUS_BUFFER_TOO_SMALL)
            {
                //
                // does the caller provide enough buffer space
                //
                if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= ResultLength)
                {
                    //
                    // it does
                    //
                    Status = IoGetDeviceProperty(m_PhysicalDeviceObject, DevicePropertyDriverKeyName, IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG), DriverKey->DriverKeyName, &ResultLength);
                }

                //
                // store result
                //
                DriverKey->ActualLength = ResultLength + FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + sizeof(WCHAR);
                Irp->IoStatus.Information = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
                Status = STATUS_SUCCESS;
            }
        }
        else
        {
            //
            // buffer is certainly too small
            //
            Status = STATUS_BUFFER_OVERFLOW;
            Irp->IoStatus.Information = sizeof(USB_HCD_DRIVERKEY_NAME);
        }
    }
    else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_ROOT_HUB_NAME)
    {
        //
        // check if sizee is at least >= USB_HCD_DRIVERKEY_NAME
        //
        if(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(USB_HCD_DRIVERKEY_NAME))
        {
            //
            // sanity check
            //
            PC_ASSERT(m_HubController);

            //
            // get input buffer
            //
            DriverKey = (PUSB_HCD_DRIVERKEY_NAME)Irp->AssociatedIrp.SystemBuffer;

            //
            // get symbolic link
            //
            Status = m_HubController->GetHubControllerSymbolicLink(IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG), DriverKey->DriverKeyName, &ResultLength);


            if (NT_SUCCESS(Status))
            {
                //
                // null terminate it
                //
                PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG) - sizeof(WCHAR) >= ResultLength);

                DriverKey->DriverKeyName[ResultLength / sizeof(WCHAR)] = L'\0';
            }

            //
            // store result
            //
            DriverKey->ActualLength = ResultLength + FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + sizeof(WCHAR);
            Irp->IoStatus.Information = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
            Status = STATUS_SUCCESS;
        }
        else
        {
            //
            // buffer is certainly too small
            //
            Status = STATUS_BUFFER_OVERFLOW;
            Irp->IoStatus.Information = sizeof(USB_HCD_DRIVERKEY_NAME);
        }
    }

    //
    // complete the request
    //
    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    //
    // done
    //
    return Status;
}
Ejemplo n.º 18
0
/*
 * @implemented
 */
PDMA_ADAPTER
NTAPI
IoGetDmaAdapter(IN PDEVICE_OBJECT PhysicalDeviceObject,
                IN PDEVICE_DESCRIPTION DeviceDescription,
                IN OUT PULONG NumberOfMapRegisters)
{
    NTSTATUS Status;
    ULONG ResultLength;
    BUS_INTERFACE_STANDARD BusInterface;
    IO_STATUS_BLOCK IoStatusBlock;
    IO_STACK_LOCATION Stack;
    DEVICE_DESCRIPTION PrivateDeviceDescription;
    PDMA_ADAPTER Adapter = NULL;

    DPRINT("IoGetDmaAdapter called\n");


    /* Try to create DMA adapter through bus driver */
    if (PhysicalDeviceObject)
    {
        if (DeviceDescription->InterfaceType == PNPBus ||
            DeviceDescription->InterfaceType == InterfaceTypeUndefined)
        {
            RtlCopyMemory(&PrivateDeviceDescription,
                          DeviceDescription,
                          sizeof(DEVICE_DESCRIPTION));

            Status = IoGetDeviceProperty(PhysicalDeviceObject,
                                         DevicePropertyLegacyBusType,
                                         sizeof(INTERFACE_TYPE),
                                         &PrivateDeviceDescription.InterfaceType,
                                         &ResultLength);

            if (!NT_SUCCESS(Status))
                PrivateDeviceDescription.InterfaceType = Internal;

            DeviceDescription = &PrivateDeviceDescription;
        }

        Stack.Parameters.QueryInterface.Size = sizeof(BUS_INTERFACE_STANDARD);
        Stack.Parameters.QueryInterface.Version = 1;
        Stack.Parameters.QueryInterface.Interface = (PINTERFACE)&BusInterface;
        Stack.Parameters.QueryInterface.InterfaceType =
            &GUID_BUS_INTERFACE_STANDARD;

        Status = IopInitiatePnpIrp(PhysicalDeviceObject,
                                   &IoStatusBlock,
                                   IRP_MN_QUERY_INTERFACE,
                                   &Stack);

        if (NT_SUCCESS(Status))
        {
            Adapter = BusInterface.GetDmaAdapter(BusInterface.Context,
                                                 DeviceDescription,
                                                 NumberOfMapRegisters);

            BusInterface.InterfaceDereference(BusInterface.Context);
            if (Adapter) return Adapter;
        }
    }

    /* Fall back to HAL */
    return HalGetDmaAdapter(PhysicalDeviceObject,
                            DeviceDescription,
                            NumberOfMapRegisters);
}
Ejemplo n.º 19
0
// Called at <= DISPATCH_LEVEL
static NDIS_STATUS
XenNet_Init(
  OUT PNDIS_STATUS OpenErrorStatus,
  OUT PUINT SelectedMediumIndex,
  IN PNDIS_MEDIUM MediumArray,
  IN UINT MediumArraySize,
  IN NDIS_HANDLE MiniportAdapterHandle,
  IN NDIS_HANDLE WrapperConfigurationContext
  )
{
  NDIS_STATUS status;
  BOOLEAN medium_found = FALSE;
  struct xennet_info *xi = NULL;
  UINT nrl_length;
  PNDIS_RESOURCE_LIST nrl;
  PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
  KIRQL irq_level = 0;
  ULONG irq_vector = 0;
  ULONG irq_mode = 0;
  NDIS_HANDLE config_handle;
  NDIS_STRING config_param_name;
  PNDIS_CONFIGURATION_PARAMETER config_param;
  ULONG i;
  PUCHAR ptr;
  UCHAR type;
  PCHAR setting, value;
  ULONG length;
  //CHAR buf[128];
  PVOID network_address;
  UINT network_address_length;
  BOOLEAN qemu_hide_filter = FALSE;
  ULONG qemu_hide_flags_value = 0;
  
  UNREFERENCED_PARAMETER(OpenErrorStatus);

  FUNCTION_ENTER();

  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));

  /* deal with medium stuff */
  for (i = 0; i < MediumArraySize; i++)
  {
    if (MediumArray[i] == NdisMedium802_3)
    {
      medium_found = TRUE;
      break;
    }
  }
  if (!medium_found)
  {
    KdPrint(("NIC_MEDIA_TYPE not in MediumArray\n"));
    return NDIS_STATUS_UNSUPPORTED_MEDIA;
  }
  *SelectedMediumIndex = i;

  /* Alloc memory for adapter private info */
  status = NdisAllocateMemoryWithTag((PVOID)&xi, sizeof(*xi), XENNET_POOL_TAG);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("NdisAllocateMemoryWithTag failed with 0x%x\n", status));
    status = NDIS_STATUS_RESOURCES;
    goto err;
  }
  RtlZeroMemory(xi, sizeof(*xi));
  xi->adapter_handle = MiniportAdapterHandle;
  xi->rx_target     = RX_DFL_MIN_TARGET;
  xi->rx_min_target = RX_DFL_MIN_TARGET;
  xi->rx_max_target = RX_MAX_TARGET;
  xi->inactive      = TRUE;
  NdisMSetAttributesEx(xi->adapter_handle, (NDIS_HANDLE) xi, 0, 0 /* the last zero is to give the next | something to | with */
#ifdef NDIS51_MINIPORT
    |NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS
#endif
    |NDIS_ATTRIBUTE_DESERIALIZE
    |NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK,
    NdisInterfaceInternal); /* PnpBus option doesn't exist... */
  xi->multicast_list_size = 0;
  xi->current_lookahead = MIN_LOOKAHEAD_LENGTH;

  nrl_length = 0;
  NdisMQueryAdapterResources(&status, WrapperConfigurationContext,
    NULL, (PUINT)&nrl_length);
  KdPrint((__DRIVER_NAME "     nrl_length = %d\n", nrl_length));
  status = NdisAllocateMemoryWithTag((PVOID)&nrl, nrl_length, XENNET_POOL_TAG);
  if (status != NDIS_STATUS_SUCCESS)
  {
    KdPrint((__DRIVER_NAME "     Could not get allocate memory for Adapter Resources 0x%x\n", status));
    return NDIS_STATUS_RESOURCES;
  }
  NdisMQueryAdapterResources(&status, WrapperConfigurationContext,
    nrl, (PUINT)&nrl_length);
  if (status != NDIS_STATUS_SUCCESS)
  {
    KdPrint((__DRIVER_NAME "     Could not get Adapter Resources 0x%x\n", status));
    return NDIS_STATUS_RESOURCES;
  }
  xi->event_channel = 0;
  xi->config_csum = 1;
  xi->config_csum_rx_check = 1;
  xi->config_sg = 1;
  xi->config_gso = 61440;
  xi->config_page = NULL;
  xi->config_rx_interrupt_moderation = 0;
  
  for (i = 0; i < nrl->Count; i++)
  {
    prd = &nrl->PartialDescriptors[i];

    switch(prd->Type)
    {
    case CmResourceTypeInterrupt:
      irq_vector = prd->u.Interrupt.Vector;
      irq_level = (KIRQL)prd->u.Interrupt.Level;
      irq_mode = (prd->Flags & CM_RESOURCE_INTERRUPT_LATCHED)?NdisInterruptLatched:NdisInterruptLevelSensitive;
      KdPrint((__DRIVER_NAME "     irq_vector = %03x, irq_level = %03x, irq_mode = %s\n", irq_vector, irq_level,
        (irq_mode == NdisInterruptLatched)?"NdisInterruptLatched":"NdisInterruptLevelSensitive"));
      break;
    case CmResourceTypeMemory:
      if (xi->config_page)
      {
        KdPrint(("More than one memory range\n"));
        return NDIS_STATUS_RESOURCES;
      }
      else
      {
        status = NdisMMapIoSpace(&xi->config_page, MiniportAdapterHandle, prd->u.Memory.Start, prd->u.Memory.Length);
        if (!NT_SUCCESS(status))
        {
          KdPrint(("NdisMMapIoSpace failed with 0x%x\n", status));
          NdisFreeMemory(nrl, nrl_length, 0);
          return NDIS_STATUS_RESOURCES;
        }
      }
      break;
    }
  }
  NdisFreeMemory(nrl, nrl_length, 0);
  if (!xi->config_page)
  {
    KdPrint(("No config page given\n"));
    return NDIS_STATUS_RESOURCES;
  }

  KeInitializeDpc(&xi->suspend_dpc, XenNet_SuspendResume, xi);
  KeInitializeSpinLock(&xi->resume_lock);

  KeInitializeDpc(&xi->rxtx_dpc, XenNet_RxTxDpc, xi);
  KeSetTargetProcessorDpc(&xi->rxtx_dpc, 0);
  KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance);

  NdisMGetDeviceProperty(MiniportAdapterHandle, &xi->pdo, &xi->fdo,
    &xi->lower_do, NULL, NULL);
  xi->packet_filter = 0;

  status = IoGetDeviceProperty(xi->pdo, DevicePropertyDeviceDescription,
    NAME_SIZE, xi->dev_desc, &length);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("IoGetDeviceProperty failed with 0x%x\n", status));
    status = NDIS_STATUS_FAILURE;
    goto err;
  }

  ptr = xi->config_page;
  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value)) != XEN_INIT_TYPE_END)
  {
    switch(type)
    {
    case XEN_INIT_TYPE_VECTORS:
      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
      {
        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
        FUNCTION_EXIT();
        return NDIS_STATUS_FAILURE;
      }
      else
        memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
      break;
    case XEN_INIT_TYPE_STATE_PTR:
      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
      xi->device_state = (PXENPCI_DEVICE_STATE)value;
      break;
    case XEN_INIT_TYPE_QEMU_HIDE_FLAGS:
      qemu_hide_flags_value = PtrToUlong(value);
      break;
    case XEN_INIT_TYPE_QEMU_HIDE_FILTER:
      qemu_hide_filter = TRUE;
      break;
    default:
      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
      break;
    }
  }

  if ((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) || qemu_hide_filter)
    xi->inactive = FALSE;

  xi->power_state = NdisDeviceStateD0;
  xi->power_workitem = IoAllocateWorkItem(xi->fdo);

  // now build config page
  
  NdisOpenConfiguration(&status, &config_handle, WrapperConfigurationContext);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not open config in registry (%08x)\n", status));
    status = NDIS_STATUS_RESOURCES;
    goto err;
  }

  NdisInitUnicodeString(&config_param_name, L"ScatterGather");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read ScatterGather value (%08x)\n", status));
    xi->config_sg = 1;
  }
  else
  {
    KdPrint(("ScatterGather = %d\n", config_param->ParameterData.IntegerData));
    xi->config_sg = config_param->ParameterData.IntegerData;
  }
  
  NdisInitUnicodeString(&config_param_name, L"LargeSendOffload");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read LargeSendOffload value (%08x)\n", status));
    xi->config_gso = 0;
  }
  else
  {
    KdPrint(("LargeSendOffload = %d\n", config_param->ParameterData.IntegerData));
    xi->config_gso = config_param->ParameterData.IntegerData;
    if (xi->config_gso > 61440)
    {
      xi->config_gso = 61440;
      KdPrint(("(clipped to %d)\n", xi->config_gso));
    }
  }

  NdisInitUnicodeString(&config_param_name, L"ChecksumOffload");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read ChecksumOffload value (%08x)\n", status));
    xi->config_csum = 1;
  }
  else
  {
    KdPrint(("ChecksumOffload = %d\n", config_param->ParameterData.IntegerData));
    xi->config_csum = !!config_param->ParameterData.IntegerData;
  }

  NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadRxCheck");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read ChecksumOffloadRxCheck value (%08x)\n", status));
    xi->config_csum_rx_check = 1;
  }
  else
  {
    KdPrint(("ChecksumOffloadRxCheck = %d\n", config_param->ParameterData.IntegerData));
    xi->config_csum_rx_check = !!config_param->ParameterData.IntegerData;
  }

  NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadDontFix");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read ChecksumOffloadDontFix value (%08x)\n", status));
    xi->config_csum_rx_dont_fix = 0;
  }
  else
  {
    KdPrint(("ChecksumOffloadDontFix = %d\n", config_param->ParameterData.IntegerData));
    xi->config_csum_rx_dont_fix = !!config_param->ParameterData.IntegerData;
  }
  
  
  
  NdisInitUnicodeString(&config_param_name, L"MTU");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);  
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read MTU value (%08x)\n", status));
    xi->config_mtu = 1500;
  }
  else
  {
    KdPrint(("MTU = %d\n", config_param->ParameterData.IntegerData));
    xi->config_mtu = config_param->ParameterData.IntegerData;
  }

  NdisInitUnicodeString(&config_param_name, L"RxInterruptModeration");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);  
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read RxInterruptModeration value (%08x)\n", status));
    xi->config_rx_interrupt_moderation = 1500;
  }
  else
  {
    KdPrint(("RxInterruptModeration = %d\n", config_param->ParameterData.IntegerData));
    xi->config_rx_interrupt_moderation = config_param->ParameterData.IntegerData;
  }
  

  NdisReadNetworkAddress(&status, &network_address, &network_address_length, config_handle);
  if (!NT_SUCCESS(status) || network_address_length != ETH_ALEN || ((((PUCHAR)network_address)[0] & 0x03) != 0x02))
  {
    KdPrint(("Could not read NetworkAddress value (%08x) or value is invalid\n", status));
    memset(xi->curr_mac_addr, 0, ETH_ALEN);
  }
  else
  {
    memcpy(xi->curr_mac_addr, network_address, ETH_ALEN);
    KdPrint(("     Set MAC address from registry to %02X:%02X:%02X:%02X:%02X:%02X\n",
      xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], 
      xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]));
  }

  xi->config_max_pkt_size = max(xi->config_mtu + XN_HDR_SIZE, xi->config_gso + XN_HDR_SIZE);
  
  NdisCloseConfiguration(config_handle);

  status = XenNet_D0Entry(xi);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Failed to go to D0 (%08x)\n", status));
    goto err;
  }
  return NDIS_STATUS_SUCCESS;
  
err:
  NdisFreeMemory(xi, 0, 0);
  *OpenErrorStatus = status;
  FUNCTION_EXIT_STATUS(status);
  return status;
}
Ejemplo n.º 20
0
NTSTATUS
UsbhubDeviceControlFdo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    PIO_STACK_LOCATION Stack;
    ULONG IoControlCode;
    PHUB_DEVICE_EXTENSION DeviceExtension;
    ULONG LengthIn, LengthOut;
    ULONG_PTR Information = 0;
    PVOID BufferIn, BufferOut;
    NTSTATUS Status = STATUS_UNSUCCESSFUL;

    Stack = IoGetCurrentIrpStackLocation(Irp);
    LengthIn = Stack->Parameters.DeviceIoControl.InputBufferLength;
    LengthOut = Stack->Parameters.DeviceIoControl.OutputBufferLength;
    DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    IoControlCode = Stack->Parameters.DeviceIoControl.IoControlCode;
    UsbhubGetUserBuffers(Irp, IoControlCode, &BufferIn, &BufferOut);

    switch (IoControlCode)
    {
        case IOCTL_USB_GET_NODE_INFORMATION:
        {
            //PUSB_NODE_INFORMATION NodeInformation;

            DPRINT1("Usbhub: IOCTL_USB_GET_NODE_INFORMATION\n");
            if (LengthOut < sizeof(USB_NODE_INFORMATION))
                Status = STATUS_BUFFER_TOO_SMALL;
            else if (BufferOut == NULL)
                Status = STATUS_INVALID_PARAMETER;
            else
            {
                /*NodeInformation = (PUSB_NODE_INFORMATION)BufferOut;
                dev = ((PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->dev;
                NodeInformation->NodeType = UsbHub;
                RtlCopyMemory(
                    &NodeInformation->u.HubInformation.HubDescriptor,
                    ((struct usb_hub *)usb_get_intfdata(to_usb_interface(&dev->actconfig->interface[0].dev)))->descriptor,
                    sizeof(USB_HUB_DESCRIPTOR));
                NodeInformation->u.HubInformation.HubIsBusPowered = dev->actconfig->desc.bmAttributes & 0x80;
                Information = sizeof(USB_NODE_INFORMATION);*/
                Status = STATUS_SUCCESS;
            }
            break;
        }
        case IOCTL_USB_GET_NODE_CONNECTION_NAME:
        {
            PHUB_DEVICE_EXTENSION DeviceExtension;
            PUSB_NODE_CONNECTION_NAME ConnectionName;
            DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
            ConnectionName = (PUSB_NODE_CONNECTION_NAME)BufferOut;

            DPRINT1("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_NAME\n");
            if (LengthOut < sizeof(USB_NODE_CONNECTION_NAME))
                Status = STATUS_BUFFER_TOO_SMALL;
            else if (BufferOut == NULL)
                Status = STATUS_INVALID_PARAMETER;
            else if (ConnectionName->ConnectionIndex < 1
                || ConnectionName->ConnectionIndex > USB_MAXCHILDREN)
                Status = STATUS_INVALID_PARAMETER;
            else if (DeviceExtension->Children[ConnectionName->ConnectionIndex - 1] == NULL)
                Status = STATUS_INVALID_PARAMETER;
            else
            {
                ULONG NeededStructureSize;
                DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceExtension->Children[ConnectionName->ConnectionIndex - 1]->DeviceExtension;
                NeededStructureSize = DeviceExtension->SymbolicLinkName.Length + sizeof(UNICODE_NULL) + FIELD_OFFSET(USB_NODE_CONNECTION_NAME, NodeName);
                if (ConnectionName->ActualLength < NeededStructureSize / sizeof(WCHAR)
                    || LengthOut < NeededStructureSize)
                {
                    /* Buffer too small */
                    ConnectionName->ActualLength = NeededStructureSize / sizeof(WCHAR);
                    Information = sizeof(USB_NODE_CONNECTION_NAME);
                    Status = STATUS_BUFFER_TOO_SMALL;
                }
                else
                {
                    RtlCopyMemory(
                        ConnectionName->NodeName,
                        DeviceExtension->SymbolicLinkName.Buffer,
                        DeviceExtension->SymbolicLinkName.Length);
                    ConnectionName->NodeName[DeviceExtension->SymbolicLinkName.Length / sizeof(WCHAR)] = UNICODE_NULL;
                    DPRINT1("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_NAME returns '%S'\n", ConnectionName->NodeName);
                    ConnectionName->ActualLength = NeededStructureSize / sizeof(WCHAR);
                    Information = NeededStructureSize;
                    Status = STATUS_SUCCESS;
                }
                Information = LengthOut;
            }
            break;
        }
        case IOCTL_USB_GET_NODE_CONNECTION_INFORMATION:
        {
            PUSB_NODE_CONNECTION_INFORMATION ConnectionInformation;
/*
            ULONG i, j, k;
            struct usb_device* dev;
            ULONG NumberOfOpenPipes = 0;
            ULONG SizeOfOpenPipesArray;
*/
            ConnectionInformation = (PUSB_NODE_CONNECTION_INFORMATION)BufferOut;

            DPRINT1("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_INFORMATION\n");
            if (LengthOut < sizeof(USB_NODE_CONNECTION_INFORMATION))
                Status = STATUS_BUFFER_TOO_SMALL;
            else if (BufferOut == NULL)
                Status = STATUS_INVALID_PARAMETER;
            else if (ConnectionInformation->ConnectionIndex < 1
                || ConnectionInformation->ConnectionIndex > USB_MAXCHILDREN)
                Status = STATUS_INVALID_PARAMETER;
            else
            {
                DPRINT1("Usbhub: We should succeed\n");
            }
            break;
        }
        case IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION:
        {
            //PUSB_DESCRIPTOR_REQUEST Descriptor;
            DPRINT1("Usbhub: IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION\n");
            Information = 0;
            Status = STATUS_NOT_IMPLEMENTED;
            break;
        }
        case IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME:
        {
            PHUB_DEVICE_EXTENSION DeviceExtension;
            PUSB_NODE_CONNECTION_DRIVERKEY_NAME StringDescriptor;
            DPRINT1("Usbhub: IOCTL_USB_GET_NODE_CONNECTION_DRIVERKEY_NAME\n");
            DeviceExtension = (PHUB_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
            StringDescriptor = (PUSB_NODE_CONNECTION_DRIVERKEY_NAME)BufferOut;
            if (LengthOut < sizeof(USB_NODE_CONNECTION_DRIVERKEY_NAME))
                Status = STATUS_BUFFER_TOO_SMALL;
            else if (StringDescriptor == NULL)
                Status = STATUS_INVALID_PARAMETER;
            else if (StringDescriptor->ConnectionIndex < 1
                || StringDescriptor->ConnectionIndex > USB_MAXCHILDREN)
                Status = STATUS_INVALID_PARAMETER;
            else if (DeviceExtension->Children[StringDescriptor->ConnectionIndex - 1] == NULL)
                Status = STATUS_INVALID_PARAMETER;
            else
            {
                ULONG StringSize;
                Status = IoGetDeviceProperty(
                    DeviceExtension->Children[StringDescriptor->ConnectionIndex - 1],
                    DevicePropertyDriverKeyName,
                    LengthOut - FIELD_OFFSET(USB_NODE_CONNECTION_DRIVERKEY_NAME, DriverKeyName),
                    StringDescriptor->DriverKeyName,
                    &StringSize);
                if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_TOO_SMALL)
                {
                    StringDescriptor->ActualLength = StringSize + FIELD_OFFSET(USB_NODE_CONNECTION_DRIVERKEY_NAME, DriverKeyName);
                    Information = LengthOut;
                    Status = STATUS_SUCCESS;
                }
            }
            break;
        }
        default:
        {
            /* Pass Irp to lower driver */
            DPRINT1("Usbhub: Unknown IOCTL code 0x%lx\n", Stack->Parameters.DeviceIoControl.IoControlCode);
            return ForwardIrpAndForget(DeviceObject, Irp);
        }
    }

    Irp->IoStatus.Information = Information;
    Irp->IoStatus.Status = Status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return Status;
}
Ejemplo n.º 21
0
NTSTATUS
CCaptureDevice::
PnpStart (
    IN PCM_RESOURCE_LIST TranslatedResourceList,
    IN PCM_RESOURCE_LIST UntranslatedResourceList
    )

/*++

Routine Description:

    Called at Pnp start.  We start up our virtual hardware simulation.

Arguments:

    TranslatedResourceList -
        The translated resource list from Pnp

    UntranslatedResourceList -
        The untranslated resource list from Pnp

Return Value:

    Success / Failure

--*/

{

    PAGED_CODE();

    //
    // Normally, we'd do things here like parsing the resource lists and
    // connecting our interrupt.  Since this is a simulation, there isn't
    // much to parse.  The parsing and connection should be the same as
    // any WDM driver.  The sections that will differ are illustrated below
    // in setting up a simulated DMA.
    //

    NTSTATUS Status = STATUS_SUCCESS;

    if (!m_Device -> Started) {
        // Create the Filter for the device
        KsAcquireDevice(m_Device);
        Status = KsCreateFilterFactory( m_Device->FunctionalDeviceObject,
                                        &CaptureFilterDescriptor,
                                        L"GLOBAL",
                                        NULL,
                                        KSCREATE_ITEM_FREEONSTOP,
                                        NULL,
                                        NULL,
                                        NULL );
        KsReleaseDevice(m_Device);

    }
    //
    // By PnP, it's possible to receive multiple starts without an intervening
    // stop (to reevaluate resources, for example).  Thus, we only perform
    // creations of the simulation on the initial start and ignore any 
    // subsequent start.  Hardware drivers with resources should evaluate
    // resources and make changes on 2nd start.
    //
    if (NT_SUCCESS(Status) && (!m_Device -> Started)) {

        m_HardwareSimulation = new (NonPagedPool) CHardwareSimulation (this);
        if (!m_HardwareSimulation) {
            //
            // If we couldn't create the hardware simulation, fail.
            //
            Status = STATUS_INSUFFICIENT_RESOURCES;
    
        } else {
            Status = KsAddItemToObjectBag (
                m_Device -> Bag,
                reinterpret_cast <PVOID> (m_HardwareSimulation),
                reinterpret_cast <PFNKSFREE> (CHardwareSimulation::Cleanup)
                );

            if (!NT_SUCCESS (Status)) {
                delete m_HardwareSimulation;
            }
        }
#if defined(_X86_)
        //
        // DMA operations illustrated in this sample are applicable only for 32bit platform.
        //
        INTERFACE_TYPE InterfaceBuffer;
        ULONG InterfaceLength;
        DEVICE_DESCRIPTION DeviceDescription;

        if (NT_SUCCESS (Status)) {
            //
            // Set up DMA...
            //
            // Ordinarilly, we'd be using InterfaceBuffer or 
            // InterfaceTypeUndefined if !NT_SUCCESS (IfStatus) as the 
            // InterfaceType below; however, for the purposes of this sample, 
            // we lie and say we're on the PCI Bus.  Otherwise, we're using map
            // registers on x86 32 bit physical to 32 bit logical and this isn't
            // what I want to show in this sample.
            //
            //
            // NTSTATUS IfStatus = 

            IoGetDeviceProperty (
                m_Device -> PhysicalDeviceObject,
                DevicePropertyLegacyBusType,
                sizeof (INTERFACE_TYPE),
                &InterfaceBuffer,
                &InterfaceLength
                );

            //
            // Initialize our fake device description.  We claim to be a 
            // bus-mastering 32-bit scatter/gather capable piece of hardware.
            //
            DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
            DeviceDescription.DmaChannel = ((ULONG) ~0);
            DeviceDescription.InterfaceType = PCIBus;
            DeviceDescription.DmaWidth = Width32Bits;
            DeviceDescription.DmaSpeed = Compatible;
            DeviceDescription.ScatterGather = TRUE;
            DeviceDescription.Master = TRUE;
            DeviceDescription.Dma32BitAddresses = TRUE;
            DeviceDescription.AutoInitialize = FALSE;
            DeviceDescription.MaximumLength = (ULONG) -1;
    
            //
            // Get a DMA adapter object from the system.
            //
            m_DmaAdapterObject = IoGetDmaAdapter (
                m_Device -> PhysicalDeviceObject,
                &DeviceDescription,
                &m_NumberOfMapRegisters
                );
    
            if (!m_DmaAdapterObject) {
                Status = STATUS_UNSUCCESSFUL;
            }
    
        }
    
        if (NT_SUCCESS (Status)) {
            //
            // Initialize our DMA adapter object with AVStream.  This is 
            // **ONLY** necessary **IF** you are doing DMA directly into
            // capture buffers as this sample does.  For this,
            // KSPIN_FLAG_GENERATE_MAPPINGS must be specified on a queue.
            //
    
            //
            // The (1 << 20) below is the maximum size of a single s/g mapping
            // that this hardware can handle.  Note that I have pulled this
            // number out of thin air for the "fake" hardware.
            //
            KsDeviceRegisterAdapterObject (
                m_Device,
                m_DmaAdapterObject,
                (1 << 20),
                sizeof (KSMAPPING)
                );
    
        }
#endif
    }
    
    return Status;

}
Ejemplo n.º 22
0
NTSTATUS
IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2Key)
{
  NTSTATUS Status;
  ULONG Disposition;
  HANDLE PnpMgrLevel1, PnpMgrLevel2, ResourceMapKey;
  UNICODE_STRING KeyName;
  OBJECT_ATTRIBUTES ObjectAttributes;

  RtlInitUnicodeString(&KeyName,
               L"\\Registry\\Machine\\HARDWARE\\RESOURCEMAP");
  InitializeObjectAttributes(&ObjectAttributes,
                 &KeyName,
                 OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
                 0,
                 NULL);
  Status = ZwCreateKey(&ResourceMapKey,
               KEY_ALL_ACCESS,
               &ObjectAttributes,
               0,
               NULL,
               REG_OPTION_VOLATILE,
               &Disposition);
  if (!NT_SUCCESS(Status))
      return Status;

  RtlInitUnicodeString(&KeyName, Level1Key);
  InitializeObjectAttributes(&ObjectAttributes,
                 &KeyName,
                 OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
                 ResourceMapKey,
                 NULL);
  Status = ZwCreateKey(&PnpMgrLevel1,
                       KEY_ALL_ACCESS,
                       &ObjectAttributes,
                       0,
                       NULL,
                       REG_OPTION_VOLATILE,
                       &Disposition);
  ZwClose(ResourceMapKey);
  if (!NT_SUCCESS(Status))
      return Status;

  RtlInitUnicodeString(&KeyName, Level2Key);
  InitializeObjectAttributes(&ObjectAttributes,
                 &KeyName,
                 OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
                 PnpMgrLevel1,
                 NULL);
  Status = ZwCreateKey(&PnpMgrLevel2,
                       KEY_ALL_ACCESS,
                       &ObjectAttributes,
                       0,
                       NULL,
                       REG_OPTION_VOLATILE,
                       &Disposition);
  ZwClose(PnpMgrLevel1);
  if (!NT_SUCCESS(Status))
      return Status;

  if (DeviceNode->ResourceList)
  {
      UNICODE_STRING NameU;
      UNICODE_STRING RawSuffix, TranslatedSuffix;
      ULONG OldLength = 0;

      ASSERT(DeviceNode->ResourceListTranslated);
      
      RtlInitUnicodeString(&TranslatedSuffix, L".Translated");
      RtlInitUnicodeString(&RawSuffix, L".Raw");

      Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject,
                                   DevicePropertyPhysicalDeviceObjectName,
                                   0,
                                   NULL,
                                   &OldLength);
      if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL)
      {
          ASSERT(OldLength);
          
          NameU.Buffer = ExAllocatePool(PagedPool, OldLength + TranslatedSuffix.Length);
          if (!NameU.Buffer)
          {
              ZwClose(PnpMgrLevel2);
              return STATUS_INSUFFICIENT_RESOURCES;
          }
          
          NameU.Length = 0;
          NameU.MaximumLength = (USHORT)OldLength + TranslatedSuffix.Length;
          
          Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject,
                                       DevicePropertyPhysicalDeviceObjectName,
                                       NameU.MaximumLength,
                                       NameU.Buffer,
                                       &OldLength);
          if (!NT_SUCCESS(Status))
          {
              ZwClose(PnpMgrLevel2);
              ExFreePool(NameU.Buffer);
              return Status;
          }
      }
      else if (!NT_SUCCESS(Status))
      {
          /* Some failure */
          ZwClose(PnpMgrLevel2);
          return Status;
      }
      else
      {
          /* This should never happen */
          ASSERT(FALSE);
      }
      
      NameU.Length = (USHORT)OldLength;

      RtlAppendUnicodeStringToString(&NameU, &RawSuffix);

      Status = ZwSetValueKey(PnpMgrLevel2,
                             &NameU,
                             0,
                             REG_RESOURCE_LIST,
                             DeviceNode->ResourceList,
                             PnpDetermineResourceListSize(DeviceNode->ResourceList));
      if (!NT_SUCCESS(Status))
      {
          ZwClose(PnpMgrLevel2);
          ExFreePool(NameU.Buffer);
          return Status;
      }

      /* "Remove" the suffix by setting the length back to what it used to be */
      NameU.Length = (USHORT)OldLength;

      RtlAppendUnicodeStringToString(&NameU, &TranslatedSuffix);

      Status = ZwSetValueKey(PnpMgrLevel2,
                             &NameU,
                             0,
                             REG_RESOURCE_LIST,
                             DeviceNode->ResourceListTranslated,
                             PnpDetermineResourceListSize(DeviceNode->ResourceListTranslated));
      ZwClose(PnpMgrLevel2);
      ExFreePool(NameU.Buffer);

      if (!NT_SUCCESS(Status))
          return Status;
  }
  else
  {
      ZwClose(PnpMgrLevel2);
  }

  return STATUS_SUCCESS;
}
Ejemplo n.º 23
0
NTSTATUS
GetPhyDeviceName(
	PDEVICE_OBJECT	PhysicalDeviceObject,
	PWCHAR			*DeviceName,
	PUSHORT			DeviceNameLen

){
	PWCHAR              deviceName = NULL;
	ULONG               nameLength;
	NTSTATUS			status;


	status = IoGetDeviceProperty (	PhysicalDeviceObject,
									DevicePropertyPhysicalDeviceObjectName,
									0,
									NULL,
									&nameLength);

	if (status != STATUS_BUFFER_TOO_SMALL)
	{
		Bus_KdPrint_Def(BUS_DBG_SS_ERROR,("IoGetDeviceProperty failed (0x%x)\n", status));
		goto Error;
	}

	deviceName = ExAllocatePoolWithTag (NonPagedPool, nameLength, BUSENUM_POOL_TAG);

	if (NULL == deviceName) {
		Bus_KdPrint_Def(BUS_DBG_SS_ERROR,
			("no memory to alloc for deviceName(0x%x)\n", nameLength));
		status =  STATUS_INSUFFICIENT_RESOURCES;
		goto Error;
	}

	status = IoGetDeviceProperty (	PhysicalDeviceObject,
									DevicePropertyPhysicalDeviceObjectName,
									nameLength,
									deviceName,
									&nameLength);

	if (!NT_SUCCESS (status)) {

		Bus_KdPrint_Def(BUS_DBG_SS_ERROR, ("IoGetDeviceProperty(2) failed (0x%x)", status));
		goto Error;
	}

	Bus_KdPrint_Def(BUS_DBG_SS_INFO, ("%x (%ws) \n",
					PhysicalDeviceObject,
					deviceName));

	//
	//	Set return values
	//
	*DeviceName = deviceName;
	*DeviceNameLen = (USHORT)nameLength;


Error:
	if(!NT_SUCCESS(status)) {
		if(deviceName)
			ExFreePool(deviceName);
	}

	return status;
}
Ejemplo n.º 24
0
Archivo: pnp.c Proyecto: kcrazy/winekit
NTSTATUS
Serenum_AddDevice(IN PDRIVER_OBJECT DriverObject,
                  IN PDEVICE_OBJECT BusPhysicalDeviceObject)
/*++
Routine Description.
    A bus has been found.  Attach our FDO to it.
    Allocate any required resources.  Set things up.  And be prepared for the
    first ``start device.''

Arguments:
    BusPhysicalDeviceObject - Device object representing the bus.  That to which
        we attach a new FDO.

    DriverObject - This very self referenced driver.

--*/
{
    NTSTATUS status;
    PDEVICE_OBJECT deviceObject;
    PFDO_DEVICE_DATA pDeviceData;
    HANDLE keyHandle;
    ULONG actualLength;

    PAGED_CODE();

    Serenum_KdPrint_Def(SER_DBG_PNP_TRACE, ("Add Device: 0x%x\n",
                                            BusPhysicalDeviceObject));
    //
    // Create our FDO
    //

    status = IoCreateDevice(DriverObject, sizeof(FDO_DEVICE_DATA), NULL,
                            FILE_DEVICE_BUS_EXTENDER, 0, TRUE, &deviceObject);

    if (NT_SUCCESS(status)) {
        pDeviceData = (PFDO_DEVICE_DATA)deviceObject->DeviceExtension;
        RtlFillMemory (pDeviceData, sizeof (FDO_DEVICE_DATA), 0);

        pDeviceData->IsFDO = TRUE;
        pDeviceData->DebugLevel = SER_DEFAULT_DEBUG_OUTPUT_LEVEL;
        pDeviceData->Self = deviceObject;
        pDeviceData->AttachedPDO = NULL;
        pDeviceData->NumPDOs = 0;
        pDeviceData->DeviceState = PowerDeviceD0;
        pDeviceData->SystemState = PowerSystemWorking;
        pDeviceData->PDOForcedRemove = FALSE;

        pDeviceData->SystemWake=PowerSystemUnspecified;
        pDeviceData->DeviceWake=PowerDeviceUnspecified;

        pDeviceData->Removed = FALSE;

        //
        // Set the PDO for use with PlugPlay functions
        //

        pDeviceData->UnderlyingPDO = BusPhysicalDeviceObject;


        //
        // Attach our filter driver to the device stack.
        // the return value of IoAttachDeviceToDeviceStack is the top of the
        // attachment chain.  This is where all the IRPs should be routed.
        //
        // Our filter will send IRPs to the top of the stack and use the PDO
        // for all PlugPlay functions.
        //

        pDeviceData->TopOfStack
            = IoAttachDeviceToDeviceStack(deviceObject, BusPhysicalDeviceObject);

        if (!pDeviceData->TopOfStack) {
            Serenum_KdPrint(pDeviceData, SER_DBG_PNP_ERROR,
                            ("AddDevice: IoAttach failed (%x)", status));
            IoDeleteDevice(deviceObject);
            return STATUS_UNSUCCESSFUL;
        }

        //
        // Set the type of IO we do
        //

        if (pDeviceData->TopOfStack->Flags & DO_BUFFERED_IO) {
            deviceObject->Flags |= DO_BUFFERED_IO;
        } else if (pDeviceData->TopOfStack->Flags & DO_DIRECT_IO) {
            deviceObject->Flags |= DO_DIRECT_IO;
        }

        //
        // Bias outstanding request to 1 so that we can look for a
        // transition to zero when processing the remove device PlugPlay IRP.
        //

        pDeviceData->OutstandingIO = 1;

        KeInitializeEvent(&pDeviceData->RemoveEvent, SynchronizationEvent,
                          FALSE);
        KeInitializeSemaphore(&pDeviceData->CreateSemaphore, 1, 1);
        KeInitializeSpinLock(&pDeviceData->EnumerationLock);



        //
        // Tell the PlugPlay system that this device will need an interface
        // device class shingle.
        //
        // It may be that the driver cannot hang the shingle until it starts
        // the device itself, so that it can query some of its properties.
        // (Aka the shingles guid (or ref string) is based on the properties
        // of the device.)
        //

        status = IoRegisterDeviceInterface(BusPhysicalDeviceObject,
                                           (LPGUID)&GUID_SERENUM_BUS_ENUMERATOR,
                                           NULL,
                                           &pDeviceData->DevClassAssocName);

        if (!NT_SUCCESS(status)) {
            Serenum_KdPrint(pDeviceData, SER_DBG_PNP_ERROR,
                            ("AddDevice: IoRegisterDCA failed (%x)", status));
            IoDetachDevice(pDeviceData->TopOfStack);
            IoDeleteDevice(deviceObject);
            return status;
        }

        //
        // If for any reason you need to save values in a safe location that
        // clients of this DeviceClassAssociate might be interested in reading
        // here is the time to do so, with the function
        // IoOpenDeviceClassRegistryKey
        // the symbolic link name used is was returned in
        // pDeviceData->DevClassAssocName (the same name which is returned by
        // IoGetDeviceClassAssociations and the SetupAPI equivs.
        //

#if DBG
        {
            PWCHAR deviceName = NULL;
            ULONG nameLength = 0;

            status = IoGetDeviceProperty(BusPhysicalDeviceObject,
                                         DevicePropertyPhysicalDeviceObjectName, 0,
                                         NULL, &nameLength);

            if ((nameLength != 0) && (status == STATUS_BUFFER_TOO_SMALL)) {
                deviceName = ExAllocatePool(NonPagedPool, nameLength);

                if (NULL == deviceName) {
                    goto someDebugStuffExit;
                }

                IoGetDeviceProperty(BusPhysicalDeviceObject,
                                    DevicePropertyPhysicalDeviceObjectName,
                                    nameLength, deviceName, &nameLength);

                Serenum_KdPrint(pDeviceData, SER_DBG_PNP_TRACE,
                                ("AddDevice: %x to %x->%x (%ws) \n", deviceObject,
                                 pDeviceData->TopOfStack, BusPhysicalDeviceObject,
                                 deviceName));
            }

someDebugStuffExit:
            ;
            if (deviceName != NULL) {
                ExFreePool(deviceName);
            }
        }
#endif // DBG

        //
        // Turn on the shingle and point it to the given device object.
        //
        status = IoSetDeviceInterfaceState(&pDeviceData->DevClassAssocName,
                                           TRUE);

        if (!NT_SUCCESS(status)) {
            Serenum_KdPrint(pDeviceData, SER_DBG_PNP_ERROR,
                            ("AddDevice: IoSetDeviceClass failed (%x)", status));
            return status;
        }

        //
        // Open the registry and read in our settings
        //

        status = IoOpenDeviceRegistryKey(pDeviceData->UnderlyingPDO,
                                         PLUGPLAY_REGKEY_DEVICE,
                                         STANDARD_RIGHTS_READ, &keyHandle);

        if (status == STATUS_SUCCESS) {
            status
                = Serenum_GetRegistryKeyValue(keyHandle, L"SkipEnumerations",
                                              sizeof(L"SkipEnumerations"),
                                              &pDeviceData->SkipEnumerations,
                                              sizeof(pDeviceData->SkipEnumerations),
                                              &actualLength);

            if ((status != STATUS_SUCCESS)
                    || (actualLength != sizeof(pDeviceData->SkipEnumerations))) {
                pDeviceData->SkipEnumerations = 0;
                status = STATUS_SUCCESS;

            }

            ZwClose(keyHandle);
        }
    }

    if (NT_SUCCESS(status)) {
        deviceObject->Flags |= DO_POWER_PAGABLE;
        deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
    }

    return status;
}