Пример #1
0
NTSTATUS EXTERNAL
HbtnAddDevice(
    __in PDRIVER_OBJECT DrvObj,
    __in PDEVICE_OBJECT DevObj
    )
{
    NTSTATUS            status = STATUS_SUCCESS;
    PDEVICE_EXTENSION   devext = NULL;

    PAGED_CODE ();
    TEnter(Func,("(DrvObj=%p,DevObj=%p)\n", DrvObj, DevObj));
    
    UNREFERENCED_PARAMETER(DrvObj);

    devext = GET_MINIDRIVER_DEVICE_EXTENSION(DevObj);
    RtlZeroMemory(devext, sizeof(*devext));
    devext->self = DevObj;
    devext->LowerDevObj = GET_NEXT_DEVICE_OBJECT(DevObj);
    IoInitializeRemoveLock(&devext->RemoveLock, HBTN_POOL_TAG, 0, 10);
    KeInitializeSpinLock(&devext->QueueLock);
    KeInitializeSpinLock(&devext->DataLock);
    InitializeListHead(&devext->PendingIrpList);
    IoCsqInitialize(&devext->IrpQueue, HbtnInsertIrp, HbtnRemoveIrp, 
        HbtnPeekNextIrp, HbtnAcquireLock, HbtnReleaseLock, HbtnCompleteCancelledIrp);

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

    TExit(Func,("=%x\n", status));
    return status;
}       //HbtnAddDevice
Пример #2
0
NTSTATUS VolumeFilterAddDevice (PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo)
{
	VolumeFilterExtension *Extension;
	NTSTATUS status;
	PDEVICE_OBJECT filterDeviceObject = NULL;
	PDEVICE_OBJECT attachedDeviceObject;

	Dump ("VolumeFilterAddDevice pdo=%p\n", pdo);

	attachedDeviceObject = IoGetAttachedDeviceReference (pdo);
	status = IoCreateDevice (driverObject, sizeof (VolumeFilterExtension), NULL, attachedDeviceObject->DeviceType, 0, FALSE, &filterDeviceObject);

	ObDereferenceObject (attachedDeviceObject);

	if (!NT_SUCCESS (status))
	{
		filterDeviceObject = NULL;
		goto err;
	}

	Extension = (VolumeFilterExtension *) filterDeviceObject->DeviceExtension;
	memset (Extension, 0, sizeof (VolumeFilterExtension));

	status = IoAttachDeviceToDeviceStackSafe (filterDeviceObject, pdo, &(Extension->LowerDeviceObject));
	if (status != STATUS_SUCCESS)
	{
		goto err;
	}

	if (!Extension->LowerDeviceObject)
	{
		status = STATUS_DEVICE_REMOVED;
		goto err;
	}

	Extension->IsVolumeFilterDevice = TRUE;
	Extension->DeviceObject = filterDeviceObject;
	Extension->Pdo = pdo;

	IoInitializeRemoveLock (&Extension->Queue.RemoveLock, 'LRCV', 0, 0);

	filterDeviceObject->Flags |= Extension->LowerDeviceObject->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO | DO_POWER_PAGABLE);
	filterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

	return status;

err:
	if (filterDeviceObject)
	{
		if (Extension->LowerDeviceObject)
			IoDetachDevice (Extension->LowerDeviceObject);

		IoDeleteDevice (filterDeviceObject);
	}

	return status;
}
Пример #3
0
NTSTATUS 
ulkAddDevice(
  PDRIVER_OBJECT driverObject,
  PDEVICE_OBJECT pdo)
{
    NTSTATUS status;

    PDEVICE_OBJECT fdo = NULL;
    PULK_DEV_EXT devExt;

    PAGED_CODE();
#ifdef DBG
    DbgPrint("[ulk] AddDevice(0x%x)\n", pdo);
#endif
    __try {
        status = IoCreateDevice(driverObject, 
                                sizeof(ULK_DEV_EXT), 
                                NULL, 
                                pdo->DeviceType, 
                                0, 
                                FALSE, 
                                &fdo);
        if(!NT_SUCCESS(status)) {
            DbgPrint("[ulk] ERROR ulkAddDevice:IoCreateDevice(%s)\n", 
                    OsrNTStatusToString(status));
            __leave;
        }
        
        devExt = (PULK_DEV_EXT)fdo->DeviceExtension;
        RtlZeroMemory(devExt, sizeof(ULK_DEV_EXT));

        IoInitializeRemoveLock(&devExt->removeLock, DEV_EXT_TAG, 0, 0);
        
        devExt->pdo = pdo;
        devExt->lowerDevice = IoAttachDeviceToDeviceStack(fdo, pdo);
        if (!devExt->lowerDevice) {
            DbgPrint("[ulk] ERROR ulkAddDevice:IoAttachDeviceToDeviceStack\n");
            status = STATUS_INTERNAL_ERROR;
            __leave;
        }

        fdo->Flags = pdo->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_INRUSH | DO_POWER_PAGABLE);
        fdo->Flags &= ~DO_DEVICE_INITIALIZING;
    } __finally {
        if (!NT_SUCCESS(status)) {
            if (fdo) {
                ulkDeleteDevice(fdo);
            }
        }
    }
    return STATUS_SUCCESS;
}
Пример #4
0
NTSTATUS VBoxDrvAddDevice(IN PDRIVER_OBJECT Driver, IN PDEVICE_OBJECT PDO)
{
    NTSTATUS rc;
    PDEVICE_OBJECT pDO, pDOParent;
    PVBOXMOUSE_DEVEXT pDevExt;

    PAGED_CODE();
    LOGF_ENTER();

    rc = IoCreateDevice(Driver, sizeof(VBOXMOUSE_DEVEXT), NULL, FILE_DEVICE_MOUSE, 0, FALSE, &pDO);
    if (!NT_SUCCESS(rc))
    {
        WARN(("IoCreateDevice failed with %#x", rc));
        return rc;
    }

    pDevExt = (PVBOXMOUSE_DEVEXT) pDO->DeviceExtension;
    RtlZeroMemory(pDevExt, sizeof(VBOXMOUSE_DEVEXT));

    IoInitializeRemoveLock(&pDevExt->RemoveLock, VBOXUSB_RLTAG, 1, 100);

    rc = IoAcquireRemoveLock(&pDevExt->RemoveLock, pDevExt);
    if (!NT_SUCCESS(rc))
    {
        WARN(("IoAcquireRemoveLock failed with %#x", rc));
        IoDeleteDevice(pDO);
        return rc;
    }

    pDOParent = IoAttachDeviceToDeviceStack(pDO, PDO);
    if (!pDOParent)
    {
        IoReleaseRemoveLockAndWait(&pDevExt->RemoveLock, pDevExt);

        WARN(("IoAttachDeviceToDeviceStack failed"));
        IoDeleteDevice(pDO);
        return STATUS_DEVICE_NOT_CONNECTED;
    }

    pDevExt->pdoMain   = PDO;
    pDevExt->pdoSelf   = pDO;
    pDevExt->pdoParent = pDOParent;

    VBoxDeviceAdded(pDevExt);

    pDO->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
    pDO->Flags &= ~DO_DEVICE_INITIALIZING;

    LOGF_LEAVE();
    return rc;
}
Пример #5
0
NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo)
{							// AddDevice
	PAGED_CODE();
	NTSTATUS status;

	PDEVICE_OBJECT fido;
	status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL,
		GetDeviceTypeToUse(pdo), 0, FALSE, &fido);
	if (!NT_SUCCESS(status))
	{						// can't create device object
		KdPrint((DRIVERNAME " - IoCreateDevice failed - %X\n", status));
		return status;
	}						// can't create device object
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;

	do
	{						// finish initialization
		IoInitializeRemoveLock(&pdx->RemoveLock, 0, 0, 0);
		pdx->DeviceObject = fido;
		pdx->Pdo = pdo;
		//将过滤驱动附加在底层驱动之上
		PDEVICE_OBJECT fdo = IoAttachDeviceToDeviceStack(fido, pdo);
		if (!fdo)
		{					// can't attach								 
			KdPrint((DRIVERNAME " - IoAttachDeviceToDeviceStack failed\n"));
			status = STATUS_DEVICE_REMOVED;
			break;
		}					// can't attach
		//记录底层驱动
		pdx->LowerDeviceObject = fdo;
		//由于不知道底层驱动是直接IO还是BufferIO,因此将标志都置上
		fido->Flags |= fdo->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO | DO_POWER_PAGABLE);
		// Clear the "initializing" flag so that we can get IRPs
		fido->Flags &= ~DO_DEVICE_INITIALIZING;
	}	while (FALSE);					// finish initialization

	if (!NT_SUCCESS(status))
	{					// need to cleanup
		if (pdx->LowerDeviceObject)
			IoDetachDevice(pdx->LowerDeviceObject);
		IoDeleteDevice(fido);
	}					// need to cleanup

	return status;
}							// AddDevice
Пример #6
0
GENERICAPI NTSTATUS GENERIC_EXPORT InitializeGenericExtension(PGENERIC_EXTENSION pdx, PGENERIC_INIT_STRUCT isp)
	{							// InitializeGenericExtension
	if (isp->Size < FIELD_OFFSET(GENERIC_INIT_STRUCT, Flags)
		|| !isp->DeviceObject
		|| !isp->Ldo
		|| !isp->Pdo
		|| !isp->StartDevice
		|| !isp->StopDevice
		|| !isp->RemoveDevice
		|| isp->DeviceQueue && !isp->StartIo)

		return STATUS_INVALID_PARAMETER;

	RtlZeroMemory(pdx, sizeof(GENERIC_EXTENSION));

	pdx->DeviceObject = isp->DeviceObject;
	pdx->LowerDeviceObject = isp->Ldo;
	pdx->Pdo = isp->Pdo;
	pdx->StartDevice = isp->StartDevice;
	pdx->StopDevice = isp->StopDevice;
	pdx->RemoveDevice = isp->RemoveDevice;

	if (isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, OkayToRemove) + sizeof(PQUERYFUNCTION))
		{						// set OkayToStop & OkayToRemove pointers
		pdx->OkayToStop = isp->OkayToStop;
		pdx->OkayToRemove = isp->OkayToRemove;
		}						// set OkayToStop & OkayToRemove pointers

	if ((pdx->dqReadWrite = isp->DeviceQueue))
		{						// queue reads & writes
		if (!isp->StartIo)
			return STATUS_INVALID_PARAMETER;
		InitializeQueue(pdx->dqReadWrite, isp->StartIo);
		}						// queue reads & writes

	if ((pdx->RemoveLock = isp->RemoveLock))
		IoInitializeRemoveLock(pdx->RemoveLock, 0, 0, 0);

	pdx->state = STOPPED;
	
	pdx->devpower = PowerDeviceD0;
	pdx->syspower = PowerSystemWorking;
	POWER_STATE state;
	state.DeviceState = PowerDeviceD0;
	PoSetPowerState(pdx->DeviceObject, DevicePowerState, state);

	// Capture the mini-driver name for messages. This needs to be in ANSI because
	// unicode conversions at or above DISPATCH_LEVEL are not allowed

	if (!isp->DebugName.Length)
		strcpy(pdx->DebugName, "GENERIC");
	else
		{						// convert debug name
		ANSI_STRING asname = {0, sizeof(pdx->DebugName) - 1, pdx->DebugName};
		RtlUnicodeStringToAnsiString(&asname, &isp->DebugName, FALSE);
		pdx->DebugName[asname.Length] = 0;
		}						// convert debug name

	if (isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, Flags) + sizeof(ULONG))
		pdx->Flags = isp->Flags & GENERIC_CLIENT_FLAGS;

	if (isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, RestoreDeviceContext) + sizeof(PCONTEXTFUNCTION))
		{						// get power helper functions
		pdx->QueryPower = isp->QueryPower;
		pdx->SaveDeviceContext = isp->SaveDeviceContext;
		pdx->RestoreDeviceContext = isp->RestoreDeviceContext;
		}						// get power helper functions

	if (isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, PerfBoundary) + sizeof(DEVICE_POWER_STATE))
		pdx->PerfBoundary = isp->PerfBoundary;
	else
		pdx->PerfBoundary = PowerDeviceUnspecified;

	if (pdx->PerfBoundary == PowerDeviceUnspecified)
		pdx->PerfBoundary = PowerDeviceMaximum; // inhibit POWER_SEQUENCE optimization

	// Initialize variables related to asynchrounous IOCTL management.

	if (pdx->Flags & GENERIC_PENDING_IOCTLS)
		{						// driver may cache asyncronous IOCTLs
		InitializeListHead(&pdx->PendingIoctlList);
		pdx->IoctlAbortStatus = 0;

		// We need to initialize our IOCTL spin lock sometime, but just once.
		// Acquiring the cancel spin lock to guard this operation is a bit of
		// a hack, I suppose, but note that a class driver like this one never
		// gets an actual chance to initialize, so it's not my fault...

		KIRQL oldirql;
		IoAcquireCancelSpinLock(&oldirql);	// any global spin lock would do
		if (!IoctlListLockInitialized)
			{					// initialize global lock
			IoctlListLockInitialized = TRUE;
			KeInitializeSpinLock(&IoctlListLock);
			}					// initialize global lock
		IoReleaseCancelSpinLock(oldirql);
		}						// driver may cache asynchronous IOCTLs

	// Initialize to manage registered device interfaces

	ExInitializeFastMutex(&pdx->iflock);
	InitializeListHead(&pdx->iflist);

	// Indicate we handle power IRPs at PASSIVE_LEVEL

	pdx->DeviceObject->Flags |= DO_POWER_PAGABLE;

	KdPrint(("GENERIC - Initializing for %s\n", pdx->DebugName));

	// If requested to do so, register an AutoLaunch interface

	if (pdx->Flags & GENERIC_AUTOLAUNCH)
		GenericRegisterInterface(pdx, &GUID_AUTOLAUNCH_NOTIFY);

	// Register a power management interface

	GenericRegisterInterface(pdx, &GUID_GENERIC_POWER);

#ifdef _X86_
	win98 = IsWin98();
#endif

	return STATUS_SUCCESS;
	}							// InitializeGenericExtension
//========================================================================================
// Function:	WDMAddDevice
// Purpose:
// Return Value:
//========================================================================================
NTSTATUS
WDMAddDevice(
	IN PDRIVER_OBJECT dro,
	IN PDEVICE_OBJECT pdo
	)
{
	NTSTATUS ntStatus = STATUS_SUCCESS;
	PDEVICE_OBJECT fido = NULL;
	PDEVICE_EXTENSION dx;
	UNICODE_STRING devNameU;
	UNICODE_STRING win32NameU;

	PAGED_CODE();

	RtlInitUnicodeString(&devNameU, NT_DEVICE_NAME);

	// Note:
	//	It will crash the system if it has more than one PCI bus,
	//	device name should change to PciBusFilter01, 02, ... 
	ntStatus = IoCreateDevice(dro,
		sizeof(DEVICE_EXTENSION),
		&devNameU,
		FILE_DEVICE_UNKNOWN,
		FILE_DEVICE_SECURE_OPEN,
		FALSE,
		&fido);

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

	RtlInitUnicodeString(&win32NameU, DOS_DEVICE_NAME);

	ntStatus = IoCreateSymbolicLink(&win32NameU, &devNameU);
	if (!NT_SUCCESS(ntStatus))    // If we we couldn't create the link then abort installation.
	{
		IoDeleteDevice(fido);
		KdPrint(("<-- "__FUNCTION__"() IoCreateSymbolicLink() Status code: 0x%08x\n", ntStatus));
		return ntStatus;
	}

	dx = (PDEVICE_EXTENSION)fido->DeviceExtension;

	IoInitializeRemoveLock(&dx->rmLock, DEV_TAG, 1, 5);
	
	dx->lowerdo = IoAttachDeviceToDeviceStack(fido, pdo);	//attach to PCI bus driver
	if(dx->lowerdo == NULL)
	{
		//Failure for attachment is an indication of a broken plug & play system.
		IoDeleteDevice(fido);
		return STATUS_UNSUCCESSFUL;
	}

	//flags needs inherit from lower device object(pci bus driver)
	fido->Flags|=(dx->lowerdo->Flags & (DO_BUFFERED_IO|DO_DIRECT_IO|DO_POWER_PAGABLE));

	//update device type
	fido->DeviceType = dx->lowerdo->DeviceType;

	//update device characteristics
	fido->Characteristics = dx->lowerdo->Characteristics;

	//save physical device object
	dx->pdo = pdo;

	//set the initial state of the Filter DO
	INITIALIZE_PNP_STATE(dx);

	KdPrint(("PCI pdo=0x%x, fdo=0x%x, fido=0x%x", pdo, dx->lowerdo, fido));

	fido->Flags &= ~DO_DEVICE_INITIALIZING;
	return STATUS_SUCCESS;
}
Пример #8
0
NTSTATUS
PdoCreate(
    PXENFILT_FDO                    Fdo,
    PDEVICE_OBJECT                  PhysicalDeviceObject,
    XENFILT_EMULATED_OBJECT_TYPE    Type
    )
{
    PDEVICE_OBJECT                  LowerDeviceObject;
    ULONG                           DeviceType;
    PDEVICE_OBJECT                  FilterDeviceObject;
    PXENFILT_DX                     Dx;
    PXENFILT_PDO                    Pdo;
    NTSTATUS                        status;

    LowerDeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
    DeviceType = LowerDeviceObject->DeviceType;
    ObDereferenceObject(LowerDeviceObject);

#pragma prefast(suppress:28197) // Possibly leaking memory 'PhysicalDeviceObject'
    status = IoCreateDevice(DriverGetDriverObject(),
                            sizeof(XENFILT_DX),
                            NULL,
                            DeviceType,
                            FILE_DEVICE_SECURE_OPEN,
                            FALSE,
                            &FilterDeviceObject);
    if (!NT_SUCCESS(status))
        goto fail1;

    Dx = (PXENFILT_DX)FilterDeviceObject->DeviceExtension;
    RtlZeroMemory(Dx, sizeof (XENFILT_DX));

    Dx->Type = PHYSICAL_DEVICE_OBJECT;
    Dx->DeviceObject = FilterDeviceObject;
    Dx->DevicePnpState = Present;
    Dx->SystemPowerState = PowerSystemShutdown;
    Dx->DevicePowerState = PowerDeviceD3;

    IoInitializeRemoveLock(&Dx->RemoveLock, PDO_TAG, 0, 0);

    Pdo = __PdoAllocate(sizeof (XENFILT_PDO));

    status = STATUS_NO_MEMORY;
    if (Pdo == NULL)
        goto fail2;

    LowerDeviceObject = IoAttachDeviceToDeviceStack(FilterDeviceObject,
                                                    PhysicalDeviceObject);

    status = STATUS_UNSUCCESSFUL;
    if (LowerDeviceObject == NULL)
        goto fail3;

    Pdo->Dx = Dx;
    Pdo->PhysicalDeviceObject = PhysicalDeviceObject;
    Pdo->LowerDeviceObject = LowerDeviceObject;

    status = ThreadCreate(PdoSystemPower, Pdo, &Pdo->SystemPowerThread);
    if (!NT_SUCCESS(status))
        goto fail4;

    status = ThreadCreate(PdoDevicePower, Pdo, &Pdo->DevicePowerThread);
    if (!NT_SUCCESS(status))
        goto fail5;

    Pdo->EmulatedInterface = FdoGetEmulatedInterface(Fdo);

    status = EmulatedAddObject(__PdoGetEmulatedInterface(Pdo),
                               Type,
                               FdoGetPrefix(Fdo),
                               Pdo->LowerDeviceObject,
                               &Pdo->EmulatedObject);
    if (!NT_SUCCESS(status))
        goto fail6;

    __PdoSetName(Pdo);

    Info("%p (%s)\n",
          FilterDeviceObject,
          __PdoGetName(Pdo));

    Dx->Pdo = Pdo;

#pragma prefast(suppress:28182) // Dereferencing NULL pointer
    FilterDeviceObject->DeviceType = LowerDeviceObject->DeviceType;
    FilterDeviceObject->Characteristics = LowerDeviceObject->Characteristics;

    FilterDeviceObject->Flags |= LowerDeviceObject->Flags;
    FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    __PdoLink(Pdo, Fdo);

    return STATUS_SUCCESS;

fail6:
    Error("fail6\n");

    ThreadAlert(Pdo->DevicePowerThread);
    ThreadJoin(Pdo->DevicePowerThread);
    Pdo->DevicePowerThread = NULL;

fail5:
    Error("fail5\n");

    ThreadAlert(Pdo->SystemPowerThread);
    ThreadJoin(Pdo->SystemPowerThread);
    Pdo->SystemPowerThread = NULL;

fail4:
    Error("fail4\n");

    Pdo->PhysicalDeviceObject = NULL;
    Pdo->LowerDeviceObject = NULL;
    Pdo->Dx = NULL;

    IoDetachDevice(LowerDeviceObject);

fail3:
    Error("fail3\n");

    ASSERT(IsZeroMemory(Pdo, sizeof (XENFILT_PDO)));
    __PdoFree(Pdo);

fail2:
    Error("fail2\n");

    IoDeleteDevice(FilterDeviceObject);

fail1:
    Error("fail1 (%08x)\n", status);

    return status;
}
Пример #9
0
// IRP_MJ_CREATE/IRP_MJ_CLOSE处理函数
NTSTATUS DispatchCreateClose(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
    )
{
    PIO_STACK_LOCATION irpStack;
    NTSTATUS            status;
    PFILE_CONTEXT       fileContext;

    UNREFERENCED_PARAMETER(DeviceObject);

    PAGED_CODE();

    irpStack = IoGetCurrentIrpStackLocation(Irp);

    ASSERT(irpStack->FileObject != NULL);    

    switch (irpStack->MajorFunction)
    {
	case IRP_MJ_CREATE:
		{
			DebugPrint(("IRP_MJ_CREATE\n"));

			fileContext = (PFILE_CONTEXT)ExAllocatePoolWithQuotaTag(
				NonPagedPool, 
				sizeof(FILE_CONTEXT),
				TAG);

			if (NULL == fileContext) 
			{
				status =  STATUS_INSUFFICIENT_RESOURCES;
				break;
			}

			IoInitializeRemoveLock(&fileContext->FileRundownLock, TAG, 0, 0);

			ASSERT(irpStack->FileObject->FsContext == NULL);
			irpStack->FileObject->FsContext = (PVOID) fileContext;

			status = STATUS_SUCCESS;
			break;
		}

	case IRP_MJ_CLOSE:
		{
			DebugPrint(("IRP_MJ_CLOSE\n"));

			fileContext = irpStack->FileObject->FsContext;
			IoAcquireRemoveLock(&fileContext->FileRundownLock, 0);
			IoReleaseRemoveLockAndWait(&fileContext->FileRundownLock, 0);

			ExFreePoolWithTag(fileContext, TAG);

			status = STATUS_SUCCESS;
			break;
		}

	default:
		ASSERT(FALSE);  // should never hit this
		status = STATUS_NOT_IMPLEMENTED;
		break;
    }

    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    return status;
}
Пример #10
0
////////////////////////////////////////////////////////////////////////////
// Functions to attach and detach target device object
//
NTSTATUS DkCreateAndAttachTgt(PDEVICE_EXTENSION pParentDevExt, PDEVICE_OBJECT pTgtDevObj)
{
    NTSTATUS           ntStat = STATUS_SUCCESS;
    PDEVICE_OBJECT     pDeviceObject = NULL;
    PDEVICE_EXTENSION  pDevExt = NULL;

    // 1. Create filter object for target device object
    ntStat = IoCreateDevice(pParentDevExt->pDrvObj,
                            sizeof(DEVICE_EXTENSION), NULL,
                            pTgtDevObj->DeviceType, 0,
                            FALSE, &pDeviceObject);
    if (!NT_SUCCESS(ntStat))
    {
        DkDbgVal("Error create target device!", ntStat);
        return ntStat;
    }

    if (pDeviceObject == NULL)
    {
        DkDbgStr("IoCreateDevice() succeeded but pDeviceObject was not set.");
        return ntStat;
    }

    pDevExt = (PDEVICE_EXTENSION) pDeviceObject->DeviceExtension;
    pDevExt->deviceMagic = USBPCAP_MAGIC_DEVICE;
    pDevExt->pThisDevObj = pDeviceObject;
    pDevExt->parentRemoveLock = &pParentDevExt->removeLock;
    pDevExt->pDrvObj = pParentDevExt->pDrvObj;

    ntStat = USBPcapAllocateDeviceData(pDevExt, pParentDevExt);
    if (!NT_SUCCESS(ntStat))
    {
        goto EndAttDev;
    }

    // 2. Initilize remove lock for filter object of target device
    IoInitializeRemoveLock(&pDevExt->removeLock, 0, 0, 0);

    // 3. Attach to target device
    pDevExt->pNextDevObj = NULL;
    pDevExt->pNextDevObj = IoAttachDeviceToDeviceStack(pDevExt->pThisDevObj, pTgtDevObj);
    if (pDevExt->pNextDevObj == NULL)
    {
        DkDbgStr("Error attach target device!");
        ntStat = STATUS_NO_SUCH_DEVICE;
        goto EndAttDev;
    }


    // 4. Set up some filter device object flags
    pDevExt->pThisDevObj->Flags |=
        (pDevExt->pNextDevObj->Flags & (DO_BUFFERED_IO | DO_POWER_PAGABLE | DO_DIRECT_IO));
    pDevExt->pThisDevObj->Flags &= ~DO_DEVICE_INITIALIZING;

    IoAcquireRemoveLock(pDevExt->parentRemoveLock, NULL);

EndAttDev:
    if (!NT_SUCCESS(ntStat))
    {
        USBPcapFreeDeviceData(pDevExt);
        if (pDeviceObject)
        {
            IoDeleteDevice(pDeviceObject);
            pDeviceObject = NULL;
        }
    }

    return ntStat;
}
Пример #11
0
NTSTATUS
FilterAddDevice(
    __in PDRIVER_OBJECT DriverObject,
    __in PDEVICE_OBJECT PhysicalDeviceObject
    )
/*++

Routine Description:

    The Plug & Play subsystem is handing us a brand new PDO, for which we
    (by means of INF registration) have been asked to provide a driver.

    We need to determine if we need to be in the driver stack for the device.
    Create a function device object to attach to the stack
    Initialize that device object
    Return status success.

    Remember: We can NOT actually send ANY non pnp IRPS to the given driver
    stack, UNTIL we have received an IRP_MN_START_DEVICE.

Arguments:

    DeviceObject - pointer to a device object.

    PhysicalDeviceObject -  pointer to a device object created by the
                            underlying bus driver.

Return Value:

    NT status code.

--*/
{
    NTSTATUS                status = STATUS_SUCCESS;
    PDEVICE_OBJECT          deviceObject = NULL;
    PDEVICE_EXTENSION       deviceExtension;
    ULONG                   deviceType = FILE_DEVICE_UNKNOWN;

    PAGED_CODE ();


    //
    // IoIsWdmVersionAvailable(1, 0x20) returns TRUE on os after Windows 2000.
    //
    if (RtlIsNtDdiVersionAvailable(NTDDI_WINXP)) {
        //
        // Win2K system bugchecks if the filter attached to a storage device
        // doesn't specify the same DeviceType as the device it's attaching
        // to. This bugcheck happens in the filesystem when you disable
        // the devicestack whose top level deviceobject doesn't have a VPB.
        // To workaround we will get the toplevel object's DeviceType and
        // specify that in IoCreateDevice.
        //
        deviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
        deviceType = deviceObject->DeviceType;
        ObDereferenceObject(deviceObject);
    }

    //
    // Create a filter device object.
    //

    status = IoCreateDevice (DriverObject,
                             sizeof (DEVICE_EXTENSION),
                             NULL,  // No Name
                             deviceType,
                             FILE_DEVICE_SECURE_OPEN,
                             FALSE,
                             &deviceObject);


    if (!NT_SUCCESS (status)) {
        //
        // Returning failure here prevents the entire stack from functioning,
        // but most likely the rest of the stack will not be able to create
        // device objects either, so it is still OK.
        //
        return status;
    }

    DebugPrint (("AddDevice PDO (0x%p) FDO (0x%p)\n",
                    PhysicalDeviceObject, deviceObject));

    deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;

    deviceExtension->Common.Type = DEVICE_TYPE_FIDO;

    deviceExtension->NextLowerDriver = IoAttachDeviceToDeviceStack (
                                       deviceObject,
                                       PhysicalDeviceObject);
    //
    // Failure for attachment is an indication of a broken plug & play system.
    //

    if (NULL == deviceExtension->NextLowerDriver) {

        IoDeleteDevice(deviceObject);
        return STATUS_UNSUCCESSFUL;
    }

    deviceObject->Flags |= deviceExtension->NextLowerDriver->Flags &
                            (DO_BUFFERED_IO | DO_DIRECT_IO |
                            DO_POWER_PAGABLE );


    deviceObject->DeviceType = deviceExtension->NextLowerDriver->DeviceType;

    deviceObject->Characteristics =
                          deviceExtension->NextLowerDriver->Characteristics;

    deviceExtension->Self = deviceObject;

    //
    // Let us use remove lock to keep count of IRPs so that we don't 
    // deteach and delete our deviceobject until all pending I/Os in our
    // devstack are completed. Remlock is required to protect us from
    // various race conditions where our driver can get unloaded while we
    // are still running dispatch or completion code.
    //
    
    IoInitializeRemoveLock (&deviceExtension->RemoveLock , 
                            POOL_TAG,
                            1, // MaxLockedMinutes 
                            100); // HighWatermark, this parameter is 
                                // used only on checked build. Specifies 
                                // the maximum number of outstanding 
                                // acquisitions allowed on the lock
                                

    //
    // Set the initial state of the Filter DO
    //

    INITIALIZE_PNP_STATE(deviceExtension);

    DebugPrint(("AddDevice: %p to %p->%p \n", deviceObject,
                       deviceExtension->NextLowerDriver,
                       PhysicalDeviceObject));

    deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;

    return STATUS_SUCCESS;

}
Пример #12
0
NTSTATUS
CsampCreateClose(
    __in PDEVICE_OBJECT DeviceObject,
    __in PIRP Irp
    )
/*++

Routine Description:

   Process the Create and close IRPs sent to this device.

Arguments:

   DeviceObject - pointer to a device object.

   Irp - pointer to an I/O Request Packet.

Return Value:

      NT Status code

--*/
{
    PIO_STACK_LOCATION  irpStack;
    NTSTATUS            status = STATUS_SUCCESS;
    PFILE_CONTEXT       fileContext;

    UNREFERENCED_PARAMETER(DeviceObject);

    PAGED_CODE ();

    CSAMP_KDPRINT(("CsampCreateClose Enter\n"));

    irpStack = IoGetCurrentIrpStackLocation(Irp);

    ASSERT(irpStack->FileObject != NULL);    

    switch(irpStack->MajorFunction)
    {
        case IRP_MJ_CREATE:

            //
            // The dispatch routine for IRP_MJ_CREATE is called when a
            // file object associated with the device is created.
            // This is typically because of a call to CreateFile() in
            // a user-mode program or because a another driver is
            // layering itself over a this driver. A driver is
            // required to supply a dispatch routine for IRP_MJ_CREATE.
            //
            fileContext = ExAllocatePoolWithQuotaTag(NonPagedPool, 
                                              sizeof(FILE_CONTEXT),
                                              TAG);

            if (NULL == fileContext) {
                status =  STATUS_INSUFFICIENT_RESOURCES;
                break;
            }

            IoInitializeRemoveLock(&fileContext->FileRundownLock, TAG, 0, 0);

            //
            // Make sure nobody is using the FsContext scratch area.
            //
            ASSERT(irpStack->FileObject->FsContext == NULL);    

            //
            // Store the context in the FileObject's scratch area.
            //
            irpStack->FileObject->FsContext = (PVOID) fileContext;
            
            CSAMP_KDPRINT(("IRP_MJ_CREATE\n"));
            break;

        case IRP_MJ_CLOSE:
            //
            // The IRP_MJ_CLOSE dispatch routine is called when a file object
            // opened on the driver is being removed from the system; that is,
            // all file object handles have been closed and the reference count
            // of the file object is down to 0.
            //
            fileContext = irpStack->FileObject->FsContext;
            
            ExFreePoolWithTag(fileContext, TAG);

            CSAMP_KDPRINT(("IRP_MJ_CLOSE\n"));
            break;

        default:
            CSAMP_KDPRINT((" Invalid CreateClose Parameter\n"));
            status = STATUS_INVALID_PARAMETER;
            break;
    }

    //
    // Save Status for return and complete Irp
    //
    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    CSAMP_KDPRINT((" CsampCreateClose Exit = %x\n", status));

    return status;
}
Пример #13
0
NTSTATUS USBPcapCreateRootHubControlDevice(IN PDEVICE_EXTENSION hubExt,
                                           OUT PDEVICE_OBJECT *control,
                                           OUT USHORT *busId)
{
    UNICODE_STRING     ntDeviceName;
    UNICODE_STRING     symbolicLinkName;
    PDEVICE_OBJECT     controlDevice = NULL;
    PDEVICE_EXTENSION  controlExt = NULL;
    NTSTATUS           status;
    USHORT             id;
    PWCHAR             ntNameBuffer[MAX_NTNAME_LEN];
    PWCHAR             symbolicNameBuffer[MAX_SYMBOLIC_LEN];

    ASSERT(hubExt->deviceMagic == USBPCAP_MAGIC_ROOTHUB);

    /* Acquire the control device ID */
    id = (USHORT) InterlockedIncrement(&g_controlId);

    ntDeviceName.Length = 0;
    ntDeviceName.MaximumLength = MAX_NTNAME_LEN;
    ntDeviceName.Buffer = (PWSTR)ntNameBuffer;

    symbolicLinkName.Length = 0;
    symbolicLinkName.MaximumLength = MAX_SYMBOLIC_LEN;
    symbolicLinkName.Buffer = (PWSTR)symbolicNameBuffer;

    status = RtlUnicodeStringPrintf(&ntDeviceName,
                                    NTNAME_PREFIX L"%hu", id);
    if (!NT_SUCCESS(status))
    {
        return status;
    }

    status = RtlUnicodeStringPrintf(&symbolicLinkName,
                                    SYMBOLIC_PREFIX L"%hu", id);
    if (!NT_SUCCESS(status))
    {
        return status;
    }

    KdPrint(("Creating device %wZ (%wZ)\n",
            &ntDeviceName, &symbolicLinkName));

    status = IoCreateDeviceSecure(hubExt->pDrvObj,
                                  sizeof(DEVICE_EXTENSION),
                                  &ntDeviceName,
                                  FILE_DEVICE_UNKNOWN,
                                  FILE_DEVICE_SECURE_OPEN,
                                  TRUE, /* Exclusive device */
                                  &SDDL_DEVOBJ_SYS_ALL_ADM_ALL_EVERYONE_ANY,
                                  NULL,
                                  &controlDevice);

    if (NT_SUCCESS(status))
    {
        controlDevice->Flags |= DO_DIRECT_IO;

        status = IoCreateSymbolicLink(&symbolicLinkName, &ntDeviceName);

        if (!NT_SUCCESS(status))
        {
            IoDeleteDevice(controlDevice);
            KdPrint(("IoCreateSymbolicLink failed %x\n", status));
            return status;
        }

        controlExt = (PDEVICE_EXTENSION)controlDevice->DeviceExtension;
        controlExt->deviceMagic      = USBPCAP_MAGIC_CONTROL;
        controlExt->pThisDevObj      = controlDevice;
        controlExt->pNextDevObj      = NULL;
        controlExt->pDrvObj          = hubExt->pDrvObj;

        IoInitializeRemoveLock(&controlExt->removeLock, 0, 0, 0);
        controlExt->parentRemoveLock = &hubExt->removeLock;

        /* Initialize USBPcap control context */
        controlExt->context.control.id             = id;
        controlExt->context.control.pRootHubObject = hubExt->pThisDevObj;


        KeInitializeSpinLock(&controlExt->context.control.csqSpinLock);
        InitializeListHead(&controlExt->context.control.lePendIrp);
        status = IoCsqInitialize(&controlExt->context.control.ioCsq,
                                 DkCsqInsertIrp, DkCsqRemoveIrp,
                                 DkCsqPeekNextIrp, DkCsqAcquireLock,
                                 DkCsqReleaseLock, DkCsqCompleteCanceledIrp);
        if (!NT_SUCCESS(status))
        {
            DkDbgVal("Error initialize Cancel-safe queue!", status);
            goto End;
        }

        controlDevice->Flags &= ~DO_DEVICE_INITIALIZING;
    }
    else
    {
        KdPrint(("IoCreateDevice failed %x\n", status));
    }

End:
    if ((!NT_SUCCESS(status)) || (controlExt == NULL))
    {
        if (controlDevice != NULL)
        {
            IoDeleteSymbolicLink(&symbolicLinkName);
            IoDeleteDevice(controlDevice);
        }
    }
    else
    {
        IoAcquireRemoveLock(controlExt->parentRemoveLock, NULL);
        *control = controlDevice;
        *busId = id;
    }

    return status;
}
Пример #14
0
static NTSTATUS
V4vAddDevice(PDRIVER_OBJECT driverObject, PDEVICE_OBJECT pdo)
{
    NTSTATUS          status = STATUS_SUCCESS;
    UNICODE_STRING    deviceName;
    PDEVICE_OBJECT    fdo = NULL;
    PXENV4V_EXTENSION pde = NULL;
    LONG              val;
    BOOLEAN           symlink = FALSE;
    LARGE_INTEGER     seed;
    WCHAR            *szSddl = NULL;
    UNICODE_STRING    sddlString;
    CHAR             *szFpath = NULL;

    TraceVerbose(("====> '%s'.\n", __FUNCTION__));

    // We only allow one instance of this device type. If more than on pdo is created we need
    val = InterlockedCompareExchange(&g_deviceCreated, 1, 0);
    if (val != 0) {
        TraceWarning(("cannot instantiate more that one v4v device node.\n"));
        return STATUS_UNSUCCESSFUL;
    }

    do {
        // Create our device
        RtlInitUnicodeString(&deviceName, V4V_DEVICE_NAME);
        szSddl = g_win5Sddl;
        RtlInitUnicodeString(&sddlString, szSddl);

        status = 
            IoCreateDeviceSecure(driverObject,
                                 sizeof(XENV4V_EXTENSION),
                                 &deviceName,
                                 FILE_DEVICE_UNKNOWN,
                                 FILE_DEVICE_SECURE_OPEN,
                                 FALSE,
                                 &sddlString,
                                 (LPCGUID)&GUID_SD_XENV4V_CONTROL_OBJECT,
                                 &fdo);
        if (!NT_SUCCESS(status)) {
            TraceError(("failed to create device object - error: 0x%x\n", status));
            fdo = NULL;
            break;
        }

        pde = (PXENV4V_EXTENSION)fdo->DeviceExtension;
        RtlZeroMemory(pde, sizeof(XENV4V_EXTENSION));
        RtlStringCchCopyW(pde->symbolicLinkText, XENV4V_SYM_NAME_LEN, V4V_SYMBOLIC_NAME);
        RtlInitUnicodeString(&pde->symbolicLink, pde->symbolicLinkText);

        // Create our symbolic link
        status = IoCreateSymbolicLink(&pde->symbolicLink, &deviceName);
        if (!NT_SUCCESS(status)) {
            TraceError(("failed to create symbolic - error: 0x%x\n", status));
            break;
        }
        symlink = TRUE;       

        // Get our xenstore path
        szFpath = xenbus_find_frontend(pdo);
        if (szFpath == NULL) {
            status = STATUS_NO_SUCH_DEVICE;
            TraceError(("failed to locate XenStore front end path\n"));
            break;
        }

        // Setup the extension
        pde->magic = XENV4V_MAGIC;
        pde->pdo = pdo;
        pde->fdo = fdo;
        IoInitializeRemoveLock(&pde->removeLock, 'v4vx', 0, 0);
        pde->frontendPath = szFpath;
        szFpath = NULL;
        pde->state = XENV4V_DEV_STOPPED; // wait for start
        pde->lastPoState = PowerSystemWorking;
        pde->virqPort = null_EVTCHN_PORT();
        KeInitializeDpc(&pde->virqDpc, V4vVirqNotifyDpc, fdo);
        KeInitializeSpinLock(&pde->virqLock);
        KeInitializeSpinLock(&pde->dpcLock);
        KeInitializeTimerEx(&pde->timer, NotificationTimer);
        KeInitializeDpc(&pde->timerDpc,
                        V4vConnectTimerDpc,
                        fdo);
        KeInitializeSpinLock(&pde->timerLock);
        pde->timerCounter = 0;
        InitializeListHead(&pde->contextList);
        KeInitializeSpinLock(&pde->contextLock);
        pde->contextCount = 0;
        InitializeListHead(&pde->ringList);
        KeInitializeSpinLock(&pde->ringLock);
        InitializeListHead(&pde->pendingIrpQueue);
        pde->pendingIrpCount = 0;
        KeInitializeSpinLock(&pde->queueLock);
        IoCsqInitializeEx(&pde->csqObject,
                          V4vCsqInsertIrpEx,
                          V4vCsqRemoveIrp,
                          V4vCsqPeekNextIrp,
                          V4vCsqAcquireLock,
                          V4vCsqReleaseLock,
                          V4vCsqCompleteCanceledIrp);
        InitializeListHead(&pde->destList);
        pde->destCount = 0;
        ExInitializeNPagedLookasideList(&pde->destLookasideList,
                                        NULL,
                                        NULL,
                                        0,
                                        sizeof(XENV4V_DESTINATION),
                                        XENV4V_TAG,
                                        0);
        KeQueryTickCount(&seed);
        pde->seed = seed.u.LowPart;

        // Now attach us to the stack
        pde->ldo = IoAttachDeviceToDeviceStack(fdo, pdo);
        if (pde->ldo == NULL) {
            TraceError(("failed to attach device to stack - error: 0x%x\n", status));
            status = STATUS_NO_SUCH_DEVICE;
            break;
        }

        // Use direct IO and let the IO manager directly map user buffers; clear the init flag
        fdo->Flags |= DO_DIRECT_IO;
        fdo->Flags &= ~DO_DEVICE_INITIALIZING;        

        // Made it here, go to connected state to be consistent
        xenbus_change_state(XBT_NIL, pde->frontendPath, "state", XENBUS_STATE_CONNECTED);
    } while (FALSE);

    if (!NT_SUCCESS(status)) {
        if (fdo != NULL) {         
            if ((pde != NULL)&&(pde->ldo != NULL)) {
                IoDetachDevice(pde->ldo);
            }
            if (szFpath != NULL) {
                XmFreeMemory(szFpath);
            }
            if (symlink) {
                IoDeleteSymbolicLink(&pde->symbolicLink);
            }
            IoDeleteDevice(fdo);
        }
    }

    TraceVerbose(("<==== '%s'.\n", __FUNCTION__));

    return status;
}
GENERICAPI NTSTATUS  InitializeGenericExtension(PGENERIC_EXTENSION pdx, PGENERIC_INIT_STRUCT isp)
    {                            // InitializeGenericExtension
    if(isp->Size < FIELD_OFFSET(GENERIC_INIT_STRUCT, Flags)
        || !isp->DeviceObject
        || !isp->Ldo
        || !isp->Pdo
        || !isp->StartDevice
        || !isp->StopDevice
        || !isp->RemoveDevice
        || isp->DeviceQueue && !isp->StartIo)

        return STATUS_INVALID_PARAMETER;

    RtlZeroMemory(pdx, sizeof(GENERIC_EXTENSION));

    pdx->DeviceObject = isp->DeviceObject;
    pdx->LowerDeviceObject = isp->Ldo;
    pdx->Pdo = isp->Pdo;
    pdx->StartDevice = isp->StartDevice;
    pdx->StopDevice = isp->StopDevice;
    pdx->RemoveDevice = isp->RemoveDevice;

    if(isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, OkayToRemove) + sizeof(PQUERYFUNCTION))
        {                        // set OkayToStop & OkayToRemove pointers
        pdx->OkayToStop = isp->OkayToStop;
        pdx->OkayToRemove = isp->OkayToRemove;
        }                        // set OkayToStop & OkayToRemove pointers

    if((pdx->RemoveLock = isp->RemoveLock))
        IoInitializeRemoveLock(pdx->RemoveLock, 0, 0, 0);

    pdx->state = STOPPED;
    
    pdx->devpower = PowerDeviceD0;
    pdx->syspower = PowerSystemWorking;
    POWER_STATE state;
    state.DeviceState = PowerDeviceD0;
    PoSetPowerState(pdx->DeviceObject, DevicePowerState, state);

    // In version 1.3, I added support for multiple IRP queues

    if(isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, NumberOfQueues) + sizeof(ULONG)
        && isp->NumberOfQueues)
        {                        // multiple queues
        ULONG i;
        if(isp->DeviceQueue || isp->StartIo)
            return STATUS_INVALID_PARAMETER;    // can't mix new and old ways of identifying queues
        if(isp->Size < FIELD_OFFSET(GENERIC_INIT_STRUCT, Queues) + isp->NumberOfQueues * 2 * sizeof(PVOID))
            return STATUS_INVALID_PARAMETER;    // init structure not big enough
        for (i = 0; i < isp->NumberOfQueues; ++i)
            if(!isp->Queues[i].DeviceQueue || !isp->Queues[i].StartIo)
                return STATUS_INVALID_PARAMETER;    // none of the entries can be NULL

        pdx->nqueues = isp->NumberOfQueues;
        pdx->queues = (PDEVQUEUE*) ExAllocatePoolWithTag(NonPagedPool, isp->NumberOfQueues * sizeof(PDEVQUEUE), SPOT_TAG);
        if(!pdx->queues)
            return STATUS_INSUFFICIENT_RESOURCES;

        for (i = 0; i < isp->NumberOfQueues; ++i)
            {                    // for each queue
            pdx->queues[i] = isp->Queues[i].DeviceQueue;
            InitializeQueue(pdx->queues[i], isp->Queues[i].StartIo);
            }                    // for each queue
        }                        // multiple queues

    else if(isp->DeviceQueue)
        {                        // single queue
        pdx->nqueues = 1;
        pdx->queues = (PDEVQUEUE*) ExAllocatePoolWithTag(NonPagedPool, sizeof(PDEVQUEUE), SPOT_TAG);
        if(!pdx->queues)
            return STATUS_INSUFFICIENT_RESOURCES;
        pdx->queues[0] = isp->DeviceQueue;
        InitializeQueue(pdx->queues[0], isp->StartIo);
        }                        // single queue

    // In version 1.9, I added support for FlushPendingIo.
    // In version 1.10, GetDevicePowerState

    if(isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, Queues))
        {                        // additional reserved fields
        pdx->FlushPendingIo = isp->FlushPendingIo;
        pdx->GetDevicePowerState = isp->GetDevicePowerState;
        }                        // additional reserved fields

    // Capture the mini-driver name for messages. This needs to be in ANSI because
    // unicode conversions at or above DISPATCH_LEVEL are not allowed. In retrospect, I
    // should have made the field in the INIT struct be in ANSI to start with...

    if(!isp->DebugName.Length)
        strcpy(pdx->DebugName, "GENERIC");
    else
        {                        // convert debug name
        ANSI_STRING asname = {0, sizeof(pdx->DebugName) - 1, pdx->DebugName};
        RtlUnicodeStringToAnsiString(&asname, &isp->DebugName, FALSE);
        pdx->DebugName[asname.Length] = 0;
        }                        // convert debug name

    if(isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, Flags) + sizeof(ULONG))
        pdx->Flags = isp->Flags & GENERIC_CLIENT_FLAGS;

    if(isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, RestoreDeviceContext) + sizeof(PCONTEXTFUNCTION))
        {                        // get power helper functions
        pdx->QueryPower = isp->QueryPower;
        pdx->SaveDeviceContext = isp->SaveDeviceContext;
        pdx->RestoreDeviceContext = isp->RestoreDeviceContext;
        }                        // get power helper functions

    if(isp->Size >= FIELD_OFFSET(GENERIC_INIT_STRUCT, PerfBoundary) + sizeof(DEVICE_POWER_STATE))
        pdx->PerfBoundary = isp->PerfBoundary;
    else
        pdx->PerfBoundary = PowerDeviceUnspecified;

    if(pdx->PerfBoundary == PowerDeviceUnspecified)
        pdx->PerfBoundary = PowerDeviceMaximum; // inhibit POWER_SEQUENCE optimization

    // Initialize variables related to asynchrounous IOCTL management. In version 2.0, this
    // is now always done rather than depending on a flag in the init struct.

    InitializeListHead(&pdx->PendingIoctlList);
    pdx->IoctlAbortStatus = 0;
    KeInitializeSpinLock(&pdx->IoctlListLock);

    // Initialize to manage registered device interfaces

    KeInitializeEvent(&pdx->iflock, SynchronizationEvent, TRUE);
    InitializeListHead(&pdx->iflist);

    // Indicate we handle power IRPs at PASSIVE_LEVEL

    pdx->DeviceObject->Flags |= DO_POWER_PAGABLE;

    KdPrint(("GENERIC - Initializing for %s\n", pdx->DebugName));

    // If device honors paging-path notifications, initialize a synchronization
    // event in the signalled state to act as a simple mutex (SP-7)

    if(pdx->Flags & GENERIC_USAGE_PAGING)
        KeInitializeEvent(&pdx->evPagingPath, SynchronizationEvent, TRUE);

    // If requested to do so, register an AutoLaunch interface

    if(pdx->Flags & GENERIC_AUTOLAUNCH)
        GenericRegisterInterface(pdx, &GUID_AUTOLAUNCH_NOTIFY);

    // Register a power management interface

    GenericRegisterInterface(pdx, &GUID_GENERIC_POWER);

#ifdef _X86_
    win98 = IsWin98();
#endif

    return STATUS_SUCCESS;
    }                            // InitializeGenericExtension
Пример #16
0
NTSTATUS AddDevice(
    IN PDRIVER_OBJECT  DriverObject,
    IN PDEVICE_OBJECT  PhysicalDeviceObject 
    )
{
	ULONG DeviceExtensionSize;
	PDEVICE_EXTENSION pCtx;
	PDEVICE_OBJECT ptr_PDO;
	NTSTATUS status;
	ULONG IdxPwrState;

	RtlInitUnicodeString(
		&Global_sz_DeviceName,
		L"\\DosDevices\\PSDOBUFDVC");
	//Get DEVICE_EXTENSION required memory space
	DeviceExtensionSize = sizeof(DEVICE_EXTENSION);
	status = IoCreateDevice(
		DriverObject,
		DeviceExtensionSize,
		&Global_sz_DeviceName,
		FILE_DEVICE_UNKNOWN,
		FILE_DEVICE_SECURE_OPEN, 
		FALSE,
		&ptr_PDO
    );

	if (NT_SUCCESS(status)) {
		ptr_PDO->Flags &= ~DO_DEVICE_INITIALIZING;
		ptr_PDO->Flags |= DO_BUFFERED_IO;
		pCtx = ptr_PDO->DeviceExtension;
		pCtx->DeviceObject = ptr_PDO;
		RtlInitUnicodeString(
			&pCtx->Device_Description,
			L"This is a Buffered I/O Driver for Pseudo Device\r\n"
			L"Created by mjtsai 2003/8/1\r\n");
		IoInitializeRemoveLock(
			&pCtx->RemoveLock,
			'KCOL',
			0,
			0
		);
		pCtx->DataBuffer = ExAllocatePool(
			NonPagedPool, 1024);
		RtlZeroMemory(
			pCtx->DataBuffer,
			1024);
		//Initialize driver power state
		pCtx->SysPwrState = PowerSystemWorking;
		pCtx->DevPwrState = PowerDeviceD0;
		
		//Initialize device power information
		Global_PowerInfo_Ptr = ExAllocatePool(
			NonPagedPool, sizeof(DEVICE_POWER_INFORMATION));
		RtlZeroMemory(
			Global_PowerInfo_Ptr,
			sizeof(DEVICE_POWER_INFORMATION));
		Global_PowerInfo_Ptr->SupportQueryCapability = FALSE;
		Global_PowerInfo_Ptr->DeviceD1 = 0;
		Global_PowerInfo_Ptr->DeviceD2 = 0;
		Global_PowerInfo_Ptr->WakeFromD0 = 0;
		Global_PowerInfo_Ptr->WakeFromD1 = 0;
		Global_PowerInfo_Ptr->WakeFromD2 = 0;
		Global_PowerInfo_Ptr->WakeFromD3 = 0;
		Global_PowerInfo_Ptr->DeviceWake = 0;
		Global_PowerInfo_Ptr->SystemWake = 0;
		for (IdxPwrState = 0;
			IdxPwrState < PowerSystemMaximum;
			IdxPwrState++)
		{
			Global_PowerInfo_Ptr->DeviceState[IdxPwrState] = 0;
		}
		//Store next-layered device object
		//Attach device object to device stack
		pCtx->NextDeviceObject = 
			IoAttachDeviceToDeviceStack(ptr_PDO, PhysicalDeviceObject);
	}

	return status;
}
Пример #17
0
NTSTATUS
FPFilterAddDevice(
    IN PDRIVER_OBJECT DriverObject,
    IN PDEVICE_OBJECT PhysicalDeviceObject
    )
{
    NTSTATUS                status;
    PDEVICE_OBJECT          filterDeviceObject;
    ULONG                   registrationFlag = 0;
    PDEVICE_EXTENSION       pDevExtFilter;
    PDEVICE_OBJECT          controlDeviceObject;
    PDEVICE_EXTENSION2      pDevExtControl;
	WCHAR					deviceNamestr[32];
	WCHAR					linkNamestr[32];
	UNICODE_STRING			deviceName;
	UNICODE_STRING			linkName;
	ULONG					n;
    PDEVICE_OBJECT          TempDeviceObject;
	ULONG					DeviceType = FILE_DEVICE_UNKNOWN;


    KdPrint(("LPCFILTER: FPFilterAddDevice: Driver %p Device %p\n", DriverObject, PhysicalDeviceObject));


	//
	//  Create a single control device object. This can be opened by user mode apps to do usefull things with
	//

	if(gCtlDevNum == 0)
	{

		RtlStringCbPrintfW(deviceNamestr,   64, L"\\Device\\SFltrl%d", gCtlDevNum);  // the symbollic link that can be opened by CreateFile() in user mode.
		RtlStringCbPrintfW(linkNamestr,   64, L"\\DosDevices\\SFltrl%d", gCtlDevNum);

		RtlInitUnicodeString(&deviceName,	deviceNamestr);

		RtlInitUnicodeString(&linkName,	linkNamestr);

		gStatus = IoCreateDevice(DriverObject,
								sizeof(DEVICE_EXTENSION2), // this allocates a chunk of memory in the device obhect of this size
								&deviceName,
								FILE_DEVICE_UNKNOWN,
								0,
								FALSE,
								&controlDeviceObject);

		if (!NT_SUCCESS(gStatus))
		{
			KdPrint(("LPCFILTER: FPFilterAddDevice: Cannot create control DeviceObject\n"));
			goto EndCONTROLdeviceCreate;
		}


		// point our device extension to the chunk of memory allocated for us
		pDevExtControl					= (PDEVICE_EXTENSION2) controlDeviceObject->DeviceExtension;

		// and set up some usefull values in it...
		RtlZeroMemory(pDevExtControl, sizeof(PDEVICE_EXTENSION2));

		pDevExtControl->DeviceObject	= controlDeviceObject;

		pDevExtControl->Type			= CONTROL;

		pDevExtControl->DeviceObject->Flags |= DO_DIRECT_IO;

		pDevExtControl->DeviceObject->Flags  &= ~DO_POWER_PAGABLE;



		status = IoCreateSymbolicLink(&linkName, &deviceName);

		if (!NT_SUCCESS(status)) 
		{
			KdPrint(("LPCFILTER: FPFilterAddDevice: Cannot create symbolic link\n"));
			IoDeleteDevice(pDevExtControl->DeviceObject);
			goto EndCONTROLdeviceCreate;
		}


		RtlStringCbCopyW(pDevExtControl->linkNamestr, 64, linkNamestr);
		
		RtlInitUnicodeString(&pDevExtControl->linkName, pDevExtControl->linkNamestr);

		KeInitializeSpinLock(&pDevExtControl->AppLock);


		//
		// set some default values
		//

		pDevExtControl->Config.StayAliveFailureLimit	= 50;

		pDevExtControl->Config.ThreadDelay				= 20;

		pDevExtControl->Config.StatsSampleRate			= 1;  // basic sampling rate

		// KeQueryTimeIncrement returns the number of 100 nano seconds intervals per tick,
		// Convert it to milliseconds (normally about 15 ms per tick, but this can be adjusted)
		pDevExtControl->MillisPerTick =  KeQueryTimeIncrement() / 10000;
		

		KdPrint(("LPCFILTER: FPFilterAddDevice: control Device Object: 0x%X \n		Created device %S \n", controlDeviceObject, deviceNamestr));

		// Clear the DO_DEVICE_INITIALIZING flag, if you dont, you cant open the device from user mode.
		// Yep, how many times have I forgotten to do that.... :)
		CLEAR_FLAG(controlDeviceObject->Flags, DO_DEVICE_INITIALIZING);
	}
EndCONTROLdeviceCreate:

	


    //
    // Create a filter device object for this device.
	// This is the device that actually sits in the CPU stack.
	// Because declared this device as a lower filter to the normal CPU driver, 
	// ie, we are above acpi and below intelppmm when we cal IoAttachDeviceToDeviceStack() 
	// we get attached to acpi and get a pointer to its device object for the CPU (actually called a Physical Device Object) 
    //

	// get a temp ref to the lower device so we can copy the device type
	TempDeviceObject = IoGetAttachedDeviceReference(PhysicalDeviceObject);
    DeviceType = TempDeviceObject->DeviceType;
    ObDereferenceObject(TempDeviceObject);

	KdPrint(("LPCFILTER: FPFilterAddDevice: device type is %d\n", DeviceType));

    status = IoCreateDevice(DriverObject,
                            sizeof(DEVICE_EXTENSION),
                            NULL,
                            DeviceType,
                            0,
                            FALSE,
                            &filterDeviceObject);

    if (!NT_SUCCESS(status)) {
        KdPrint(("LPCFILTER: FPFilterAddDevice: Cannot create filterDeviceObject\n"));
		IoDeleteSymbolicLink(&linkName);
		IoDeleteDevice(controlDeviceObject);
        return status;
    }

    pDevExtFilter = (PDEVICE_EXTENSION) filterDeviceObject->DeviceExtension;

    RtlZeroMemory(pDevExtFilter, sizeof(DEVICE_EXTENSION));



    //
    // Attach the device object to the highest device object in the chain and
    // return the previously highest device object, which is passed to
    // IoCallDriver when we pass IRPs down the device stack
    //

	// we use TargetDeviceObject to send IOCTLs to  to get information on ACPI objects
    pDevExtFilter->TargetDeviceObject = IoAttachDeviceToDeviceStack(filterDeviceObject, PhysicalDeviceObject);

    if (pDevExtFilter->TargetDeviceObject == NULL) 
	{
 		IoDeleteSymbolicLink(&linkName);
		IoDeleteDevice(controlDeviceObject);
        IoDeleteDevice(filterDeviceObject);
        KdPrint(("LPCFILTER: FPFilterAddDevice: Unable to attach %X to target %X\n", filterDeviceObject, PhysicalDeviceObject));
        return STATUS_NO_SUCH_DEVICE;
    }

    // Save the filter device object in the device extension
    pDevExtFilter->DeviceObject = filterDeviceObject;

	pDevExtFilter->Type			= FILTER;

	// copy the flags and other stuff off the lower device 
	pDevExtFilter->DeviceObject->Flags |= 
					pDevExtFilter->TargetDeviceObject->Flags &
					(DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE );

	pDevExtFilter->DeviceObject->Characteristics	= pDevExtFilter->TargetDeviceObject->Characteristics;
	pDevExtFilter->DeviceObject->DeviceType			= pDevExtFilter->TargetDeviceObject->DeviceType;

	KdPrint(("LPCFILTER: FPFilterAddDevice: Lowerdo type is %d\n", pDevExtFilter->DeviceObject->DeviceType));
    KdPrint(("LPCFILTER: FPFilterAddDevice: Lowerdo flags are: 0x%X\n",  pDevExtFilter->DeviceObject->Flags));

    // if it is the first FILTER device we created and we sucessfully created a CONTROL device...
	if((gCtlDevNum == 0) && (NT_SUCCESS(gStatus)))
	{
		// reference each other device extensions
		// we do this so when the CONTROL device object gets caled frodm user mode we can interact with the acpi PhsicalDevice Object
		pDevExtControl->pOtherExt = pDevExtFilter;
		pDevExtFilter->pOtherExt = pDevExtControl;
	}
		
    //
    // Initialize the remove lock
    //
    IoInitializeRemoveLock(&pDevExtFilter->RemoveLock,
                           0,
                           0,
                           0);

    // Clear the DO_DEVICE_INITIALIZING flag
    CLEAR_FLAG(filterDeviceObject->Flags, DO_DEVICE_INITIALIZING);

	gCtlDevNum = 1; // we created our control device object, so even though AddDevice 
	// gets called again on a multi processor system, we set this so we dont create any more

    return STATUS_SUCCESS;
} 
//------------------------------------------------------------------------------
NTSTATUS powerlinkCreate(PDEVICE_OBJECT pDeviceObject_p,
                         PIRP pIrp_p)
{
    NDIS_TIMER_CHARACTERISTICS  timerChars;
    tFileContext*               pFileContext;
    PIO_STACK_LOCATION          irpStack;
    NDIS_STATUS                 status;

    UNUSED_PARAMETER(pDeviceObject_p);

    DEBUG_LVL_ALWAYS_TRACE("PLK: + %s() ...\n", __func__);

    if (pIrp_p == NULL)
        return NDIS_STATUS_RESOURCES;

    irpStack = IoGetCurrentIrpStackLocation(pIrp_p);

    pFileContext = ExAllocatePoolWithQuotaTag(NonPagedPool,
                                              sizeof(tFileContext),
                                              PLK_MEM_TAG);
    if (pFileContext == NULL)
    {
        DEBUG_LVL_ERROR_TRACE("PLK: Failed to create file context\n");
    }

    IoInitializeRemoveLock(&pFileContext->driverAccessLock, PLK_MEM_TAG, 0, 0);

    irpStack->FileObject->FsContext = (void*)pFileContext;

    if (!plkDriverInstance_l.fInitialized)
    {
        NdisZeroMemory(&timerChars, sizeof(timerChars));

        C_ASSERT(NDIS_SIZEOF_TIMER_CHARACTERISTICS_REVISION_1 <= sizeof(timerChars));
        timerChars.Header.Type = NDIS_OBJECT_TYPE_TIMER_CHARACTERISTICS;
        timerChars.Header.Size = NDIS_SIZEOF_TIMER_CHARACTERISTICS_REVISION_1;
        timerChars.Header.Revision = NDIS_TIMER_CHARACTERISTICS_REVISION_1;

        timerChars.TimerFunction = increaseHeartbeatCb;
        timerChars.FunctionContext = NULL;
        timerChars.AllocationTag = PLK_MEM_TAG;

        status = NdisAllocateTimerObject(plkDriverInstance_l.driverHandle,
                                         &timerChars,
                                         &heartbeatTimer_l);
        if (status != NDIS_STATUS_SUCCESS)
        {
            DEBUG_LVL_ERROR_TRACE("%s() Timer Creation Failed %x\n", __func__, status);
            return STATUS_SUCCESS;
        }

        if (ctrlk_init(NULL) != kErrorOk)
        {
            return NDIS_STATUS_RESOURCES;
        }

        startHeartbeatTimer(20);
        plkDriverInstance_l.fInitialized = TRUE;
    }

    // Increase the count for open instances
    plkDriverInstance_l.instanceCount++;

    pIrp_p->IoStatus.Information = 0;
    pIrp_p->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(pIrp_p, IO_NO_INCREMENT);

    DEBUG_LVL_ALWAYS_TRACE("PLK: + %s() - OK\n", __func__);

    return STATUS_SUCCESS;
}
Пример #19
0
NTSTATUS AddDevice(IN PDRIVER_OBJECT pDrvObj,
                   IN PDEVICE_OBJECT pTgtDevObj)
{
    NTSTATUS          ntStat = STATUS_SUCCESS;
    UNICODE_STRING    usTgtName;
    PDEVICE_OBJECT    pHubFilter = NULL;
    PDEVICE_EXTENSION pDevExt = NULL;
    BOOLEAN           isRootHub;

    // 1. Check if device is Root Hub
    isRootHub = USBPcapIsDeviceRootHub(pTgtDevObj);
    if (isRootHub == FALSE)
    {
        /* Do not attach to non-RootHub devices */
        return STATUS_SUCCESS;
    }

    // 2. Create filter object
    ntStat = IoCreateDevice(pDrvObj,
                            sizeof(DEVICE_EXTENSION), NULL,
                            GetDeviceTypeToUse(pTgtDevObj), 0,
                            FALSE, &pHubFilter);
    if (!NT_SUCCESS(ntStat))
    {
        DkDbgVal("Error create Hub Filter!", ntStat);
        goto EndFunc;
    }

    pDevExt = (PDEVICE_EXTENSION) pHubFilter->DeviceExtension;
    pDevExt->deviceMagic = USBPCAP_MAGIC_ROOTHUB;
    pDevExt->pThisDevObj = pHubFilter;
    pDevExt->pDrvObj = pDrvObj;
    pDevExt->parentRemoveLock = NULL;

    IoInitializeRemoveLock(&pDevExt->removeLock, 0, 0, 0);

    ntStat = USBPcapAllocateDeviceData(pDevExt, NULL);
    if (!NT_SUCCESS(ntStat))
    {
        goto EndFunc;
    }

    // 3. Attach to bus driver
    pDevExt->pNextDevObj = NULL;
    pDevExt->pNextDevObj = IoAttachDeviceToDeviceStack(pHubFilter, pTgtDevObj);
    if (pDevExt->pNextDevObj == NULL)
    {
        ntStat = STATUS_NO_SUCH_DEVICE;
        DkDbgStr("Error attach device!");
        goto EndFunc;
    }

    pHubFilter->Flags |=
        (pDevExt->pNextDevObj->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE));

    pHubFilter->Flags &= ~DO_DEVICE_INITIALIZING;

    if (NT_SUCCESS(ntStat))
    {
        PDEVICE_OBJECT         control = NULL;
        PUSBPCAP_ROOTHUB_DATA  pRootData;
        USHORT                 id;

        ntStat = USBPcapCreateRootHubControlDevice(pDevExt,
                                                   &control,
                                                   &id);

        pRootData = pDevExt->context.usb.pDeviceData->pRootData;
        pRootData->controlDevice = control;
        pRootData->busId = id;
    }

EndFunc:

    // If something bad happened
    if (!NT_SUCCESS(ntStat))
    {
        USBPcapFreeDeviceData(pDevExt);
        if (pHubFilter)
        {
            IoDeleteDevice(pHubFilter);
            pHubFilter = NULL;
        }
    }

    return ntStat;
}