📄 sdiousb.cpp
字号:
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 + -