📄 sdiousb.cpp
字号:
#include "Sdiomain.h"
#include "SdioDev.h"
#include "Ioctls.h"
SDIOGLOBALS SdioGlobals;
NTSTATUS HelloWDMRead(IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
KdPrint(("Enter HelloWDMRead\n"));
PAGED_CODE();
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
KdPrint(("MDL:%x\n",Irp->MdlAddress));
status = SdioReadBufferFromDevice(pdx->FunctionalDeviceObject,
pdx->FunctionNumber,
Irp->MdlAddress,
IFDevice_SDIO_DATA_REG,
pdx->Channel0_Length,
&Irp->IoStatus.Information);
Irp->IoStatus.Status = status;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
KdPrint(("Leave HelloWDMRead\n"));
return STATUS_SUCCESS;
}
NTSTATUS HelloWDMDispatchRoutine(IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
PAGED_CODE();
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; // no bytes xfered
IoCompleteRequest( Irp, IO_NO_INCREMENT );
KdPrint(("Leave HelloWDMDispatchRoutine\n"));
return STATUS_SUCCESS;
}
NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp)
{
PAGED_CODE();
KdPrint(("Enter DefaultPnpHandler\n"));
IoSkipCurrentIrpStackLocation(Irp);
KdPrint(("Leave DefaultPnpHandler\n"));
return IoCallDriver(pdx->TopOfStackDeviceObject, Irp);
}
NTSTATUS OnRequestComplete(PDEVICE_OBJECT junk, PIRP Irp, PKEVENT pev)
{ // OnRequestComplete
//在完成例程中设置等待事件
KeSetEvent(pev, 0, FALSE);
//标志本IRP还需要再次被完成
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS ForwardAndWait(PDEVICE_EXTENSION pdx, PIRP Irp)
{ // ForwardAndWait
PAGED_CODE();
KEVENT event;
//初始化事件
KeInitializeEvent(&event, NotificationEvent, FALSE);
//将本层堆栈拷贝到下一层堆栈
IoCopyCurrentIrpStackLocationToNext(Irp);
//设置完成例程
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) OnRequestComplete,
(PVOID) &event, TRUE, TRUE, TRUE);
//调用底层驱动,即PDO
IoCallDriver(pdx->TopOfStackDeviceObject, Irp);
//等待PDO完成
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
return Irp->IoStatus.Status;
} // ForwardAndWait
NTSTATUS HandleStartDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
PAGED_CODE();
KdPrint(("Enter HandleStartDevice\n"));
pdx->Channel0_Length = 0;
//转发IRP并等待返回
NTSTATUS status = ForwardAndWait(pdx,Irp);
if (!NT_SUCCESS(status))
{
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
UCHAR ucRegVal = 0;
status = SdioReadWriteByte(pdx->FunctionalDeviceObject,0,&ucRegVal,REG_CCCR_IENx,FALSE);
if (!NT_SUCCESS(status))
{
KdPrint(("SdioReadWriteByte fail:%x\n",status));
return status;
}
KdPrint(("REG_CCCR_IENx:%x\n",ucRegVal));
//Set Bus Width to 4 bits
status = SdioReadWriteByte(pdx->FunctionalDeviceObject,0,&ucRegVal,REG_CCCR_BUS_INTERFACE_CTRL,FALSE);
if (!NT_SUCCESS(status))
{
KdPrint(("Get REG_CCCR_BUS_INTERFACE_CTRL failed:%x\n",status));
return status;
}
KdPrint(("Previous REG_CCCR_BUS_INTERFACE_CTRL:%x\n",ucRegVal));
ucRegVal = ucRegVal | 0x2;
status = SdioReadWriteByte(pdx->FunctionalDeviceObject,0,&ucRegVal,REG_CCCR_BUS_INTERFACE_CTRL,TRUE);
if (!NT_SUCCESS(status))
{
KdPrint(("Set Bus Width to 4 bits failed:%x\n",status));
return status;
}
KdPrint(("Set Bus Width to 4 bits successfully!\n"));
//完成IRP
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
KdPrint(("Leave HandleStartDevice\n"));
return status;
}
NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
PAGED_CODE();
KdPrint(("Enter HandleRemoveDevice\n"));
if (pdx->InterfaceStandard.InterfaceDereference)
{
(pdx->InterfaceStandard.InterfaceDereference)(pdx->InterfaceStandard.Context);
pdx->InterfaceStandard.InterfaceDereference = NULL;
}
Irp->IoStatus.Status = STATUS_SUCCESS;
NTSTATUS status = DefaultPnpHandler(pdx, Irp);
IoSetDeviceInterfaceState(&pdx->InterfaceName, FALSE);
//调用IoDetachDevice()把fdo从设备栈中脱开:
if (pdx->TopOfStackDeviceObject)
IoDetachDevice(pdx->TopOfStackDeviceObject);
//删除fdo:
IoDeleteDevice(pdx->FunctionalDeviceObject);
KdPrint(("Leave HandleRemoveDevice\n"));
return status;
}
NTSTATUS HelloWDMPnp(IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
PAGED_CODE();
KdPrint(("Enter HelloWDMPnp\n"));
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
static NTSTATUS (*fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp) =
{
HandleStartDevice, // IRP_MN_START_DEVICE
DefaultPnpHandler, // IRP_MN_QUERY_REMOVE_DEVICE
HandleRemoveDevice, // IRP_MN_REMOVE_DEVICE
DefaultPnpHandler, // IRP_MN_CANCEL_REMOVE_DEVICE
DefaultPnpHandler, // IRP_MN_STOP_DEVICE
DefaultPnpHandler, // IRP_MN_QUERY_STOP_DEVICE
DefaultPnpHandler, // IRP_MN_CANCEL_STOP_DEVICE
DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_RELATIONS
DefaultPnpHandler, // IRP_MN_QUERY_INTERFACE
DefaultPnpHandler, // IRP_MN_QUERY_CAPABILITIES
DefaultPnpHandler, // IRP_MN_QUERY_RESOURCES
DefaultPnpHandler, // IRP_MN_QUERY_RESOURCE_REQUIREMENTS
DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_TEXT
DefaultPnpHandler, // IRP_MN_FILTER_RESOURCE_REQUIREMENTS
DefaultPnpHandler, //
DefaultPnpHandler, // IRP_MN_READ_CONFIG
DefaultPnpHandler, // IRP_MN_WRITE_CONFIG
DefaultPnpHandler, // IRP_MN_EJECT
DefaultPnpHandler, // IRP_MN_SET_LOCK
DefaultPnpHandler, // IRP_MN_QUERY_ID
DefaultPnpHandler, // IRP_MN_QUERY_PNP_DEVICE_STATE
DefaultPnpHandler, // IRP_MN_QUERY_BUS_INFORMATION
DefaultPnpHandler, // IRP_MN_DEVICE_USAGE_NOTIFICATION
DefaultPnpHandler, // IRP_MN_SURPRISE_REMOVAL
};
ULONG fcn = stack->MinorFunction;
if (fcn >= arraysize(fcntab))
{ // 未知的子功能代码
status = DefaultPnpHandler(pdx, Irp); // some function we don't know about
return status;
}
#if DBG
static char* fcnname[] =
{
"IRP_MN_START_DEVICE",
"IRP_MN_QUERY_REMOVE_DEVICE",
"IRP_MN_REMOVE_DEVICE",
"IRP_MN_CANCEL_REMOVE_DEVICE",
"IRP_MN_STOP_DEVICE",
"IRP_MN_QUERY_STOP_DEVICE",
"IRP_MN_CANCEL_STOP_DEVICE",
"IRP_MN_QUERY_DEVICE_RELATIONS",
"IRP_MN_QUERY_INTERFACE",
"IRP_MN_QUERY_CAPABILITIES",
"IRP_MN_QUERY_RESOURCES",
"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
"IRP_MN_QUERY_DEVICE_TEXT",
"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
"",
"IRP_MN_READ_CONFIG",
"IRP_MN_WRITE_CONFIG",
"IRP_MN_EJECT",
"IRP_MN_SET_LOCK",
"IRP_MN_QUERY_ID",
"IRP_MN_QUERY_PNP_DEVICE_STATE",
"IRP_MN_QUERY_BUS_INFORMATION",
"IRP_MN_DEVICE_USAGE_NOTIFICATION",
"IRP_MN_SURPRISE_REMOVAL",
};
KdPrint(("PNP Request (%s)\n", fcnname[fcn]));
#endif // DBG
status = (*fcntab[fcn])(pdx, Irp);
KdPrint(("Leave HelloWDMPnp\n"));
return status;
}
NTSTATUS
DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING UniRegistryPath
)
{
NTSTATUS ntStatus;
PUNICODE_STRING pregistryPath = &SdioGlobals.Sdio_RegistryPath;
KdPrint(("Enter DriverEntry\n"));
//
// Allocate pool to hold a null-terminated copy of the path.
// Safe in paged pool since all registry routines execute at
// PASSIVE_LEVEL.
//
pregistryPath->MaximumLength = UniRegistryPath->Length + sizeof(UNICODE_NULL);
pregistryPath->Length = UniRegistryPath->Length;
pregistryPath->Buffer = (PWSTR )ExAllocatePool(PagedPool,pregistryPath->MaximumLength);
if (!(pregistryPath->Buffer))
{
KdPrint(("DriverEntry: Failed to allocate memory for registryPath\n"));
ntStatus = STATUS_INSUFFICIENT_RESOURCES;
goto DriverEntry_Exit;
}
RtlZeroMemory (pregistryPath->Buffer,
pregistryPath->MaximumLength);
RtlMoveMemory (pregistryPath->Buffer,
UniRegistryPath->Buffer,
UniRegistryPath->Length);
ntStatus = STATUS_SUCCESS;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HelloWDMDeviceIOControl;
DriverObject->MajorFunction[IRP_MJ_POWER] = HelloWDMDispatchRoutine;
DriverObject->MajorFunction[IRP_MJ_PNP] = HelloWDMPnp;
DriverObject->MajorFunction[IRP_MJ_CREATE] = HelloWDMDispatchRoutine;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloWDMDispatchRoutine;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = HelloWDMDispatchRoutine;
DriverObject->MajorFunction[IRP_MJ_READ] = HelloWDMRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = HelloWDMDispatchRoutine;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HelloWDMDispatchRoutine;
DriverObject->DriverUnload = SdioClientDrv_DriverUnload;
DriverObject->DriverExtension->AddDevice = (PDRIVER_ADD_DEVICE) SdioClientDrv_AddDevice;
DriverEntry_Exit:
KdPrint(("Leave DriverEntry\n"));
return ntStatus;
}
NTSTATUS EnableInt(PDEVICE_EXTENSION pdx)
{
NTSTATUS status;
UCHAR ucRegVal;
//Enable CCCR interrupt
status = SdioReadWriteByte(pdx->FunctionalDeviceObject,0,&ucRegVal,REG_CCCR_IENx,FALSE);
if (!NT_SUCCESS(status))
{
KdPrint(("Get REG_CCCR_IENx failed:%x\n",status));
return status;
}
KdPrint(("Previous REG_CCCR_IENx:%x\n",ucRegVal));
ucRegVal = ucRegVal | 1;
ucRegVal = ucRegVal | (1<<pdx->FunctionNumber);
status = SdioReadWriteByte(pdx->FunctionalDeviceObject,0,&ucRegVal,REG_CCCR_IENx,TRUE);
if (!NT_SUCCESS(status))
{
KdPrint(("Enable CCCR interrupt failed:%x\n",status));
return status;
}
KdPrint(("Enable CCCR interrupt successfully!\n"));
//Enable Device interrupt
ucRegVal = 0x07;
status = SdioReadWriteByte(pdx->FunctionalDeviceObject,pdx->FunctionNumber,&ucRegVal,IFDevice_INT0_ENABLE,TRUE);
if (!NT_SUCCESS(status))
{
KdPrint(("Enable Device interrupt failed:%x\n",status));
return status;
}
KdPrint(("Enable Device interrupt successfully!\n"));
status = SdioReadWriteByte(pdx->FunctionalDeviceObject,pdx->FunctionNumber,&ucRegVal,IFDevice_INT0_ENABLE,FALSE);
if (NT_SUCCESS(status))
{
KdPrint(("IFDevice_INT0_ENABLE:%x\n",ucRegVal));
}
return status;
}
NTSTATUS DisableInt(PDEVICE_EXTENSION pdx)
{
NTSTATUS status;
//Disable Device interrupt
UCHAR ucRegVal = 0x0;
status = SdioReadWriteByte(pdx->FunctionalDeviceObject,pdx->FunctionNumber,&ucRegVal,IFDevice_INT0_ENABLE,TRUE);
if (!NT_SUCCESS(status))
{
KdPrint(("Disable Device interrupt failed:%x\n",status));
return status;
}
KdPrint(("Disable Device interrupt successfully!\n"));
status = SdioReadWriteByte(pdx->FunctionalDeviceObject,pdx->FunctionNumber,&ucRegVal,IFDevice_INT0_ENABLE,FALSE);
if (NT_SUCCESS(status))
{
KdPrint(("IFDevice_INT0_ENABLE:%x\n",ucRegVal));
}
return status;
}
NTSTATUS
SdioReadBufferFromDevice(IN PDEVICE_OBJECT deviceObject,
IN ULONG Function,
IN PMDL Mdl,
IN ULONG Address,
IN ULONG Length,
OUT PULONG BytesRead
)
{
PDEVICE_EXTENSION pdx =
(PDEVICE_EXTENSION)deviceObject->DeviceExtension;
//disable interrput
DisableInt(pdx);
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};
//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 = 0; // non-increment address
extendedArgument.u.bits.BlockMode = 0;
extendedArgument.u.bits.Address = Address;
sdrp.Parameters.DeviceCommand.CmdDesc = ReadIoExtendedDesc;
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;
//enable interrput
EnableInt(pdx);
return status;
}
NTSTATUS
SdioReadWriteBuffer(IN PDEVICE_OBJECT deviceObject,
IN ULONG Function,
IN PMDL Mdl,
IN ULONG Address,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -