⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdiousb.cpp

📁 <windows驱动开发技术详解>源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                   IN ULONG Length,
                   IN BOOLEAN WriteToDevice,
                   OUT PULONG BytesRead
                   )
{
    PDEVICE_EXTENSION pdx = 
    	(PDEVICE_EXTENSION)deviceObject->DeviceExtension; 

    SDBUS_REQUEST_PACKET sdrp;
    SD_RW_EXTENDED_ARGUMENT extendedArgument;
    NTSTATUS                 status;
    const SDCMD_DESCRIPTOR ReadIoExtendedDesc =
    {SDCMD_IO_RW_EXTENDED, SDCC_STANDARD, SDTD_READ, SDTT_SINGLE_BLOCK, SDRT_5};

    const SDCMD_DESCRIPTOR WriteIoExtendedDesc =
    {SDCMD_IO_RW_EXTENDED, SDCC_STANDARD, SDTD_WRITE, SDTT_SINGLE_BLOCK, SDRT_5};

    //PAGED_CODE();

    RtlZeroMemory(&sdrp, sizeof(SDBUS_REQUEST_PACKET));

    sdrp.RequestFunction = SDRF_DEVICE_COMMAND;
    sdrp.Parameters.DeviceCommand.Mdl = Mdl;

    extendedArgument.u.AsULONG = 0;
    extendedArgument.u.bits.Function = Function;
    extendedArgument.u.bits.OpCode = 1;             // increment address
    extendedArgument.u.bits.BlockMode = pdx->BlockMode;
    extendedArgument.u.bits.Address = Address;

    if (WriteToDevice) {
        extendedArgument.u.bits.WriteToDevice = 1;
        sdrp.Parameters.DeviceCommand.CmdDesc  = WriteIoExtendedDesc;
    } else {
        sdrp.Parameters.DeviceCommand.CmdDesc  = ReadIoExtendedDesc;
    }

    if (pdx->BlockMode == 1) {
        sdrp.Parameters.DeviceCommand.CmdDesc.TransferType = SDTT_MULTI_BLOCK_NO_CMD12;
    }

    sdrp.Parameters.DeviceCommand.Argument = extendedArgument.u.AsULONG;
    sdrp.Parameters.DeviceCommand.Length   = Length;

    //
    // Send the IO request down to the bus driver
    //

    status = SdBusSubmitRequest(pdx->InterfaceStandard.Context, &sdrp);
    *BytesRead = (ULONG)sdrp.Information;
    return status;

}

NTSTATUS
SdioReadWriteByte(IN PDEVICE_OBJECT deviceObject,
                 IN ULONG Function,
                 IN PUCHAR Data,
                 IN ULONG Address,
                 IN BOOLEAN WriteToDevice
                 )
{
    PDEVICE_EXTENSION pdx = 
    	(PDEVICE_EXTENSION)deviceObject->DeviceExtension; 
    NTSTATUS	status;
    SDBUS_REQUEST_PACKET	sdrp;
    SD_RW_DIRECT_ARGUMENT	directArgument;

    const SDCMD_DESCRIPTOR	ReadIoDirectDesc =
    {SDCMD_IO_RW_DIRECT, SDCC_STANDARD, SDTD_READ, SDTT_CMD_ONLY, SDRT_5};

    const SDCMD_DESCRIPTOR WriteIoDirectDesc =
    {SDCMD_IO_RW_DIRECT, SDCC_STANDARD, SDTD_WRITE, SDTT_CMD_ONLY, SDRT_5};

    PAGED_CODE();
    //
    // get an SD request packet
    //

    RtlZeroMemory(&sdrp, sizeof(SDBUS_REQUEST_PACKET));

    sdrp.RequestFunction = SDRF_DEVICE_COMMAND;

    directArgument.u.AsULONG = 0;
    directArgument.u.bits.Function = Function;
    directArgument.u.bits.Address = Address;


    if (WriteToDevice) 
    {
        directArgument.u.bits.WriteToDevice = 1;
        directArgument.u.bits.Data = *Data;
        sdrp.Parameters.DeviceCommand.CmdDesc  = WriteIoDirectDesc;
    } else {
        sdrp.Parameters.DeviceCommand.CmdDesc  = ReadIoDirectDesc;
    }

    sdrp.Parameters.DeviceCommand.Argument = directArgument.u.AsULONG;

    //
    // Send the IO request down to the bus driver
    //

    status = SdBusSubmitRequest(pdx->InterfaceStandard.Context, &sdrp);

	if(!NT_SUCCESS(status))
	{
		KdPrint(("SdioReadWriteByte failed\n"));
	}

    if (NT_SUCCESS(status) && !WriteToDevice) 
    {
        *Data = sdrp.ResponseData.AsUCHAR[0];
    }
    return status;
}


NTSTATUS
SdioGetProperty(IN PDEVICE_OBJECT deviceObject,
				IN SDBUS_PROPERTY Property,
				IN PVOID Buffer,
				IN ULONG Length)
{
    PDEVICE_EXTENSION pdx;
    SDBUS_REQUEST_PACKET sdrp;

    pdx = (PDEVICE_EXTENSION)deviceObject->DeviceExtension; 
    RtlZeroMemory(&sdrp, sizeof(SDBUS_REQUEST_PACKET));

    sdrp.RequestFunction = SDRF_GET_PROPERTY;
    sdrp.Parameters.GetSetProperty.Property = Property;
    sdrp.Parameters.GetSetProperty.Buffer = Buffer;
    sdrp.Parameters.GetSetProperty.Length = Length;

    return SdBusSubmitRequest(pdx->InterfaceStandard.Context, &sdrp);
}

NTSTATUS
SdioSetProperty(IN PDEVICE_OBJECT deviceObject,
				IN SDBUS_PROPERTY Property,
				IN PVOID Buffer,
				IN ULONG Length)
{
    PDEVICE_EXTENSION pdx;
    SDBUS_REQUEST_PACKET sdrp;

    pdx = (PDEVICE_EXTENSION)deviceObject->DeviceExtension; 

    RtlZeroMemory(&sdrp, sizeof(SDBUS_REQUEST_PACKET));

    sdrp.RequestFunction = SDRF_SET_PROPERTY;
    sdrp.Parameters.GetSetProperty.Property = Property;
    sdrp.Parameters.GetSetProperty.Buffer = Buffer;
    sdrp.Parameters.GetSetProperty.Length = Length;

    return SdBusSubmitRequest(pdx->InterfaceStandard.Context, &sdrp);
}

VOID
MyDriverCallback(
  IN PVOID  CallbackRoutineContext,
  IN ULONG  InterruptType
  )
{
	static ULONG i=0;

	NTSTATUS status;

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) CallbackRoutineContext;

	KdPrint(("Enter MyDriverCallback\n"));
	
	UCHAR ucRegVal = 0;
	status = SdioReadWriteByte(pdx->FunctionalDeviceObject,pdx->FunctionNumber,&ucRegVal,IFDevice_INT0_STATUS,FALSE);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("SdioReadWriteByte fail:%x\n",status));
		goto done;
	}

    if(IFDevice_INT0_STATUS_MASK&ucRegVal)
    {
		KdPrint(("Enter MyDriverCallback %d\n",i++));
    }

done:
	pdx->InterfaceStandard.AcknowledgeInterrupt(pdx->InterfaceStandard.Context);
}

NTSTATUS
SdioClientDrv_AddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
{
	NTSTATUS ntStatus;
	PDEVICE_OBJECT deviceObject = NULL;
	PDEVICE_EXTENSION pdx = NULL;
	// POWER_STATE state;
	// KIRQL oldIrql;
	
	KdPrint(("Enter SdioClientDrv_AddDevice\n"));
	
	ntStatus = IoCreateDevice(
		DriverObject, // our driver object
		sizeof(DEVICE_EXTENSION), // extension size for us
		NULL, // name for this device
		FILE_DEVICE_UNKNOWN,
		FILE_DEVICE_SECURE_OPEN , // device characteristics
		FALSE, // Not exclusive
		&deviceObject); // Our device object
	
	if(!NT_SUCCESS(ntStatus))
	{
		KdPrint(("AddDevice:device obj not created\n"));
		return ntStatus;
	}
	KdPrint(("AddDevice: device obj created\n"));
	
	//
	// Initialize the device extension
	//
	
	ntStatus = STATUS_SUCCESS;
	
	// Initialize the device extension
	//
	pdx = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
	// Set all Device Extension pointers to NULL and all variable to zero
	//
	RtlZeroMemory(pdx, sizeof(DEVICE_EXTENSION));
	pdx->FunctionalDeviceObject = deviceObject;
	pdx->PhysicalDeviceObject = PhysicalDeviceObject;
	deviceObject->Flags |= DO_DIRECT_IO;
	//
	//initialize OpenHandleCount
	//
	pdx->OpenHandleCount = 0;
	
	//
	// Initialize the selective suspend variables
	//
	KeInitializeSpinLock(&pdx->IdleReqStateLock);
	pdx->IdleReqPend = 0;
	pdx->PendingIdleIrp = NULL;
	
	//
	// set the flags as underlying PDO
	//
	
	if(PhysicalDeviceObject->Flags & DO_POWER_PAGABLE) 
	{
		deviceObject->Flags |= DO_POWER_PAGABLE;
	}
	
	//
	// attach our driver to device stack
	// The return value of IoAttachDeviceToDeviceStack is the top of the
	// attachment chain. This is where all the IRPs should be routed.
	//
	
	pdx->TopOfStackDeviceObject = 
		IoAttachDeviceToDeviceStack(deviceObject,PhysicalDeviceObject);
	
	if(NULL == pdx->TopOfStackDeviceObject) 
	{
		KdPrint(("AddDevice: IoAttachDeviceToDeviceStack failed"));
		IoDeleteDevice(deviceObject);
		return STATUS_NO_SUCH_DEVICE;
	}
	
	ntStatus = IoRegisterDeviceInterface(
		PhysicalDeviceObject,
		(LPGUID) &GUID_DEVINTERFACE_SDIO_DEVICE,
		NULL,
		&pdx->InterfaceName);

	if (!NT_SUCCESS (ntStatus)) 
	{
		KdPrint(("AddDevice: IoRegisterDeviceInterface failed %x", ntStatus));
		IoDetachDevice(pdx->TopOfStackDeviceObject);
		IoDeleteDevice(deviceObject);
		return ntStatus;
	}

	KdPrint(("%wZ\n",&pdx->InterfaceName));
	IoSetDeviceInterfaceState(&pdx->InterfaceName, TRUE);
	
	//Open the SD Bus Interface
	//Lib routine returns ptr to the
	ntStatus = SdBusOpenInterface (
		pdx->PhysicalDeviceObject,
		&pdx->InterfaceStandard,
		sizeof(SDBUS_INTERFACE_STANDARD),
		SDBUS_INTERFACE_VERSION);
	
	KdPrint(("AddDevive: SDBusOpenInterface-ntStatus 0x%x",ntStatus));
	
	if (NT_SUCCESS(ntStatus)) 
	{
		SDBUS_INTERFACE_PARAMETERS interfaceParameters = {0};
		KdPrint(("Sd Bus initialization success\n"));
		interfaceParameters.Size = sizeof(SDBUS_INTERFACE_PARAMETERS);
		interfaceParameters.TargetObject = pdx->TopOfStackDeviceObject;
		interfaceParameters.DeviceGeneratesInterrupts = TRUE;
		interfaceParameters.CallbackAtDpcLevel = FALSE;
		interfaceParameters.CallbackRoutine  = MyDriverCallback;
		interfaceParameters.CallbackRoutineContext = pdx;

		ntStatus = STATUS_UNSUCCESSFUL;
		if (pdx->InterfaceStandard.InitializeInterface) 
		{
			ntStatus = (pdx->InterfaceStandard.InitializeInterface)
				(pdx->InterfaceStandard.Context, &interfaceParameters);

			if (NT_SUCCESS(ntStatus)) 
			{
				KdPrint(("Execute InterfaceStandard.InitializeInterface\n"));
			}
		}
	}
	
 	ntStatus = SdioGetProperty(deviceObject,
		SDP_FUNCTION_NUMBER,
		&pdx->FunctionNumber,
		sizeof(pdx->FunctionNumber));
	if (!NT_SUCCESS(ntStatus)) 
	{
		return ntStatus;
	}
	KdPrint(("FunctionNumber:%d\n",pdx->FunctionNumber));
	
    pdx->DriverVersion = SDBUS_DRIVER_VERSION_1;

    SdioGetProperty(deviceObject,
                    SDP_BUS_DRIVER_VERSION,
                    &pdx->DriverVersion,
                    sizeof(pdx->DriverVersion));

    pdx->BlockMode = 0;
	
	KdPrint(("DriverVersion:%x\n",pdx->DriverVersion));
	
	if (!NT_SUCCESS(ntStatus)) 
	{
		return ntStatus;
	}

	// Clear the DO_DEVICE_INITIALIZING flag.
	deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
	
	ntStatus = STATUS_SUCCESS;
	KdPrint(("Leave SdioClientDrv_AddDevice\n"));
	return ntStatus;
}

void
SdioClientDrv_DriverUnload(
IN PDRIVER_OBJECT DriverObject
)
{
	KdPrint(("SdioClientDrv_DriverUnload\n"));
}

NTSTATUS HelloWDMDeviceIOControl(IN PDEVICE_OBJECT pDevObj,
								 IN PIRP pIrp)
{
	NTSTATUS status = STATUS_SUCCESS;
	KdPrint(("Enter HelloWDMDeviceIOControl\n"));

	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) pDevObj->DeviceExtension;

	//得到当前堆栈
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
	//得到输入缓冲区大小
	ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
	//得到输出缓冲区大小
	ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
	//得到IOCTL码
	ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;

	ULONG info = 0;

	switch (code)
	{						// process request
		case IOCTL_ENABLE_INT:
		{
			KdPrint(("IOCTL_ENABLE_INT\n"));
			status = EnableInt(pdx);
			break;
		}
		case IOCTL_DISABLE_INT:
		{
			KdPrint(("IOCTL_DISABLE_INT\n"));
			status = DisableInt(pdx);
			break;
		}
		default:
			status = STATUS_INVALID_VARIANT;
	}

	// 完成IRP
	pIrp->IoStatus.Status = status;
	pIrp->IoStatus.Information = info;	// bytes xfered
	IoCompleteRequest( pIrp, IO_NO_INCREMENT );

	KdPrint(("Leave HelloWDMDeviceIOControl\n"));

	return status;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -