wy_t29
驱动牛犊
驱动牛犊
  • 注册日期2002-03-06
  • 最后登录2009-01-07
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望10点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
阅读:2103回复:1

在Kernel态如何访问HID设备?

楼主#
更多 发布于:2005-01-28 17:06
我在做一个NT式驱动,想要访问HID设备。必须要经过哪些步骤?
我的做法是先用IoRegisterPlugPlayNotification来判断HID设备的插入,然后在回调函数中IoGetDeviceObjectPointer取得设备对象,再向他发出IOCTL_HID_GET_COLLECTION_INFORMATION请求取得PID、VID来判断是否是自己需要访问的设备,再向他发送IOCTL_HID_SET_FEATURE请求时不能成功,不知是否有遗漏之处,请大虾指点,最好给出访问HID设备或如何使用IOCTL_HID_SET_FEATURE的代码片段。
wy_t29
驱动牛犊
驱动牛犊
  • 注册日期2002-03-06
  • 最后登录2009-01-07
  • 粉丝0
  • 关注0
  • 积分3分
  • 威望10点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-01-28 17:13
下面是我写的代码片段:
NTSTATUS CallHidIoctl(
 IN PDEVICE_OBJECT HidDevice,
 IN ULONG IoControlCode,
 OUT PVOID Output,
 IN ULONG OutputLen,
 IN PVOID Input,
 IN ULONG InputLen
 )
{
IO_STATUS_BLOCK IoStatus;
KEVENT event;

KeInitializeEvent(&event, NotificationEvent, FALSE);

PIRP Irp = IoBuildDeviceIoControlRequest(
IoControlCode,
HidDevice,
Input,
InputLen,
Output,
OutputLen,
FALSE,
&event,
&IoStatus
);

BYTE tmp[6];
DWORD tmplen = IoGetNextIrpStackLocation(Irp)->Parameters.DeviceIoControl.InputBufferLength;
tmp[0] = ((BYTE*)Irp->AssociatedIrp.SystemBuffer)[0];
tmp[1] = ((BYTE*)Irp->AssociatedIrp.SystemBuffer)[1];
tmp[2] = ((BYTE*)Irp->AssociatedIrp.SystemBuffer)[2];
tmp[3] = ((BYTE*)Irp->AssociatedIrp.SystemBuffer)[3];
tmp[4] = ((BYTE*)Irp->AssociatedIrp.SystemBuffer)[4];
tmp[5] = ((BYTE*)Irp->AssociatedIrp.SystemBuffer)[5];

NTSTATUS status = IoCallDriver( HidDevice, Irp);
if (status == STATUS_PENDING)
{
status = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
}
else
{
IoStatus.Status = status;
}

status = IoStatus.Status;
return status;
}

NTSTATUS HidCallbackRoutine(IN PVOID NotificationStructure, IN PVOID Context)
{
NTSTATUS ntStatus = STATUS_SUCCESS;
PDEVICE_INTERFACE_CHANGE_NOTIFICATION pdicn = (PDEVICE_INTERFACE_CHANGE_NOTIFICATION)NotificationStructure;
PDRIVER_OBJECT DriverObject = (PDRIVER_OBJECT)Context;
PDEVICE_OBJECT fdo = DriverObject->DeviceObject;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
PSMARTCARD_EXTENSION psx = &pdx->SmartcardExtension;
KIRQL Irql;

if(IsEqualGUID(pdicn->Event, GUID_DEVICE_INTERFACE_ARRIVAL))
{
if(pdx->HidObjContext.DeviceObject)
{
return STATUS_SUCCESS;
}

PFILE_OBJECT HidFileObject;
PDEVICE_OBJECT HidDevice;
HID_COLLECTION_INFORMATION HidCi;
PIRP pIrp;
PIO_STACK_LOCATION pStackLocation;
KEVENT Event;
IO_STATUS_BLOCK IoStatusBlock;

ntStatus = IoGetDeviceObjectPointer(pdicn->SymbolicLinkName, FILE_ALL_ACCESS, &HidFileObject, &HidDevice);
if(!NT_SUCCESS(ntStatus))
{
return STATUS_SUCCESS;
}
ObDereferenceObject(HidFileObject);

ntStatus = ObReferenceObjectByPointer(HidDevice, FILE_ALL_ACCESS, NULL, KernelMode);
/*
KeInitializeEvent(&Event, NotificationEvent, FALSE);
pIrp = IoBuildDeviceIoControlRequest(
0,
HidDevice,
NULL,
0,
NULL,
0,
FALSE,
&Event,
&IoStatusBlock
);
if(pIrp == NULL)
{
return STATUS_SUCCESS;
}
pStackLocation = IoGetNextIrpStackLocation(pIrp);
pStackLocation->MajorFunction = IRP_MJ_CREATE;
pStackLocation->Parameters.Create.SecurityContext = NULL;
pStackLocation->Parameters.Create.Options = 0;
pStackLocation->Parameters.Create.FileAttributes = 0;
pStackLocation->Parameters.Create.ShareAccess = 0;
pStackLocation->Parameters.Create.EaLength = 0;
ntStatus = IoCallDriver(HidDevice, pIrp);
if(ntStatus == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
ntStatus = IoStatusBlock.Status;
}
if(!NT_SUCCESS(ntStatus))
{
return STATUS_SUCCESS;
}
*/
ntStatus = CallHidIoctl(HidDevice, IOCTL_HID_GET_COLLECTION_INFORMATION, &HidCi, sizeof(HidCi));
if(!NT_SUCCESS(ntStatus))
{
return STATUS_SUCCESS;
}

if((HidCi.VendorID == 0x04B4) && (HidCi.ProductID == 0xA112))
{
BYTE *CmdBuffer;
int CmdLen;
int i;

CmdBuffer = (BYTE*)ExAllocatePool(NonPagedPool, 256);
if(CmdBuffer == NULL)
{
return STATUS_SUCCESS;
}
RtlZeroMemory(CmdBuffer, 256);

CmdBuffer[1] = 0x21;
CmdBuffer[2] = 0xA2;
CmdBuffer[3] = 0x00;
CmdBuffer[4] = 0x00;
for(i=1; i<=3; ++i)
{
CmdBuffer[4] ^= CmdBuffer;
}
//下面的这一条语句运行后会瘫痪
ntStatus = CallHidIoctl(HidDevice, IOCTL_HID_SET_FEATURE, NULL, 0, CmdBuffer, 0x41);
if(!NT_SUCCESS(ntStatus))
{
ExFreePool(CmdBuffer);
return STATUS_SUCCESS;
}

RtlZeroMemory(CmdBuffer, 256);
ntStatus = CallHidIoctl(HidDevice, IOCTL_HID_GET_FEATURE, CmdBuffer, 0x41);
if(!NT_SUCCESS(ntStatus))
{
ExFreePool(CmdBuffer);
return STATUS_SUCCESS;
}
if(CmdBuffer[1] != 0x12)
{
ExFreePool(CmdBuffer);
return STATUS_SUCCESS;
}
CmdLen = 0;
for(i=1; i<CmdBuffer[3]+5; ++i)
{
CmdLen ^= CmdBuffer;
}
if(CmdLen != 0)
{
ExFreePool(CmdBuffer);
return STATUS_SUCCESS;
}
if(CmdBuffer[4] != 0x90)
{
ExFreePool(CmdBuffer);
return STATUS_SUCCESS;
}

ExFreePool(CmdBuffer);

pdx->HidObjContext.DeviceObject = HidDevice;
pdx->HidObjContext.SymbolicLinkName.Length = pdicn->SymbolicLinkName->Length;
pdx->HidObjContext.SymbolicLinkName.MaximumLength = pdicn->SymbolicLinkName->MaximumLength;
pdx->HidObjContext.SymbolicLinkName.Buffer = (PWSTR)ExAllocatePool(
PagedPool,
pdicn->SymbolicLinkName->Length + sizeof(WCHAR)
);
RtlCopyUnicodeString(&pdx->HidObjContext.SymbolicLinkName, pdicn->SymbolicLinkName);

KeAcquireSpinLock(&psx->OsData->SpinLock, &Irql);
psx->ReaderCapabilities.CurrentState = SCARD_PRESENT;
psx->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
psx->CardCapabilities.ATR.Length = 0;
KeReleaseSpinLock(&psx->OsData->SpinLock, Irql);
HidCompleteTracking(psx);
}
}
else if(IsEqualGUID(pdicn->Event, GUID_DEVICE_INTERFACE_REMOVAL))
{
if(!pdx->HidObjContext.DeviceObject)
{
return STATUS_SUCCESS;
}

if(RtlCompareUnicodeString(pdicn->SymbolicLinkName, &pdx->HidObjContext.SymbolicLinkName, FALSE))
{
return STATUS_SUCCESS;
}

KeAcquireSpinLock(&psx->OsData->SpinLock, &Irql);
psx->ReaderCapabilities.CurrentState = SCARD_ABSENT;
psx->CardCapabilities.Protocol.Selected = SCARD_PROTOCOL_UNDEFINED;
psx->CardCapabilities.ATR.Length = 0;
KeReleaseSpinLock(&psx->OsData->SpinLock, Irql);
HidCompleteTracking(psx);

if(pdx->HidObjContext.SymbolicLinkName.Buffer != NULL)
{
RtlFreeUnicodeString(&pdx->HidObjContext.SymbolicLinkName);
pdx->HidObjContext.SymbolicLinkName.Buffer = NULL;
}

ObDereferenceObject(pdx->HidObjContext.DeviceObject);
pdx->HidObjContext.DeviceObject = NULL;
}

return ntStatus;
}
游客

返回顶部