659 lines
20 KiB
C
659 lines
20 KiB
C
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
HID.c
|
|
|
|
Abstract:
|
|
|
|
WinDbg Extension Api
|
|
|
|
Author:
|
|
|
|
Kenneth D. Ray (kenray) June 1997
|
|
|
|
Environment:
|
|
|
|
User Mode.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
typedef union _HID_PPD_FLAGS {
|
|
struct {
|
|
ULONG InputChannels : 1;
|
|
ULONG OutputChannels : 1;
|
|
ULONG FeatureChannels : 1;
|
|
ULONG LinkCollections : 1;
|
|
ULONG FullChannelListing : 1;
|
|
ULONG ReportLocation : 1;
|
|
ULONG Reserved : 25;
|
|
ULONG IgnoreSignature : 1;
|
|
};
|
|
ULONG64 Flags;
|
|
} HID_PPD_FLAGS;
|
|
|
|
typedef union _HID_FLAGS {
|
|
struct {
|
|
ULONG FullListing : 1;
|
|
ULONG PowerListing : 1;
|
|
ULONG HidPDeviceDesc : 1;
|
|
ULONG FileListing : 1;
|
|
ULONG Reserved : 27;
|
|
};
|
|
ULONG64 Flags;
|
|
} HID_FLAGS;
|
|
|
|
#define PRINT_FLAGS(value, flag) \
|
|
if ((value) & (flag)) { \
|
|
dprintf (#flag " "); \
|
|
}
|
|
|
|
|
|
//
|
|
// Local function declarations
|
|
//
|
|
|
|
VOID HID_DumpPpd (ULONG64 Ppd, HID_PPD_FLAGS Flags);
|
|
VOID HID_DumpFDOExt (ULONG64 Fdo);
|
|
VOID HID_DumpPDOExt (ULONG64 Pdo);
|
|
|
|
|
|
DECLARE_API( hidppd )
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps a HID Preparsed Data blob
|
|
|
|
Arguments:
|
|
|
|
args - Address flags
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG64 memLoc=0;
|
|
ULONG result;
|
|
ULONG size;
|
|
HID_PPD_FLAGS flags;
|
|
ULONG InSize;
|
|
|
|
flags.Flags = 0;
|
|
|
|
if (!*args) {
|
|
dprintf ("hidppd <address> [flags]\n");
|
|
} else {
|
|
if (GetExpressionEx(args, &memLoc, &args)) {
|
|
GetExpressionEx(args, &(flags.Flags), &args);
|
|
}
|
|
}
|
|
|
|
dprintf ("Dump Ppd %p %x \n", memLoc, (ULONG)flags.Flags);
|
|
|
|
//
|
|
// Get the preparsed data
|
|
//
|
|
|
|
if (GetFieldValue (memLoc, "hidparse!_HIDP_PREPARSED_DATA", "Input.Size", InSize)) {
|
|
dprintf ("Could not read hidparse!_HIDP_PREPARSED_DATA @%p\n", memLoc);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
InitTypeRead(memLoc, hidparse!_HIDP_PREPARSED_DATA);
|
|
|
|
size = GetTypeSize ("hidparse!_HIDP_PREPARSED_DATA")
|
|
+ (GetTypeSize ("hidparse!_HIDP_CHANNEL_DESC")
|
|
* ((ULONG) ReadField(Input.Size) + (ULONG) ReadField(Output.Size) + (ULONG) ReadField(Feature.Size)))
|
|
+ (GetTypeSize ("hidparse!_HIDP_LINK_COLLECTION_NODE")
|
|
* (ULONG) ReadField(LinkCollectionArrayLength));
|
|
|
|
dprintf ("TOT Size: %x\n", size);
|
|
|
|
HID_DumpPpd (memLoc, flags);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
VOID
|
|
HID_DumpChannel (
|
|
ULONG64 Channel,
|
|
HID_PPD_FLAGS Flags
|
|
)
|
|
{
|
|
InitTypeRead(Channel, hidparse!_HIDP_CHANNEL_DESC);
|
|
|
|
dprintf ("-------CHANNEL---------\n");
|
|
dprintf ("P %x ID %x Col %x Sz %x Cnt %x UMin %x UMax %x ",
|
|
(ULONG) ReadField(UsagePage),
|
|
(ULONG) ReadField(ReportID),
|
|
(ULONG) ReadField(LinkCollection),
|
|
(ULONG) ReadField(ReportSize),
|
|
(ULONG) ReadField(ReportCount),
|
|
(ULONG) ReadField(Range.UsageMin),
|
|
(ULONG) ReadField(Range.UsageMax));
|
|
|
|
if (ReadField(MoreChannels)) {
|
|
dprintf ("MoreChannels ");
|
|
}
|
|
if (ReadField(IsConst)) {
|
|
dprintf ("Const ");
|
|
}
|
|
if (ReadField(IsButton)) {
|
|
dprintf ("Button ");
|
|
} else {
|
|
dprintf ("Value ");
|
|
}
|
|
if (ReadField(IsAbsolute)) {
|
|
dprintf ("Absolute ");
|
|
}
|
|
if (ReadField(IsAlias)) {
|
|
dprintf ("ALIAS! ");
|
|
}
|
|
|
|
dprintf ("\n");
|
|
|
|
if (Flags.FullChannelListing) {
|
|
dprintf ("LinkUP %x LinkU %x SMin %x SMax %x "
|
|
"DMin %x DMax %x IndexMin %x IndexMax %x\n",
|
|
(ULONG) ReadField(LinkUsagePage),
|
|
(ULONG) ReadField(LinkUsage),
|
|
(ULONG) ReadField(Range.StringMin),
|
|
(ULONG) ReadField(Range.StringMax),
|
|
(ULONG) ReadField(Range.DesignatorMin),
|
|
(ULONG) ReadField(Range.DesignatorMax),
|
|
(ULONG) ReadField(Range.DataIndexMin),
|
|
(ULONG) ReadField(Range.DataIndexMax));
|
|
|
|
if (!ReadField(IsButton)) {
|
|
if (ReadField(Data.HasNull)) {
|
|
dprintf ("Has Null ");
|
|
}
|
|
dprintf ("LMin %x LMax %x PMin %x PMax %x \n",
|
|
(ULONG) ReadField(Data.LogicalMin),
|
|
(ULONG) ReadField(Data.LogicalMax),
|
|
(ULONG) ReadField(Data.PhysicalMin),
|
|
(ULONG) ReadField(Data.PhysicalMax));
|
|
}
|
|
}
|
|
|
|
if (Flags.ReportLocation) {
|
|
dprintf ("ByteOffset %x BitOffset %x BitLength %x ByteEnd %x\n",
|
|
(ULONG) ReadField(ByteOffset),
|
|
(ULONG) ReadField(BitOffset),
|
|
(ULONG) ReadField(BitLength),
|
|
(ULONG) ReadField(ByteEnd));
|
|
}
|
|
}
|
|
|
|
VOID
|
|
HID_DumpLink (
|
|
ULONG LinkNo,
|
|
ULONG64 Node
|
|
)
|
|
{
|
|
InitTypeRead(Node, hidparse!_HIDP_LINK_COLLECTION_NODE);
|
|
|
|
dprintf ("Link %x: U %x P %x Par %p #C %x NxSib %p 1stC %p ",
|
|
LinkNo,
|
|
(ULONG) ReadField(LinkUsage),
|
|
(ULONG) ReadField(LinkUsagePage),
|
|
ReadField(Parent),
|
|
(ULONG) ReadField(NumberOfChildren),
|
|
ReadField(NextSibling),
|
|
ReadField(FirstChild));
|
|
|
|
if (ReadField(IsAlias)) {
|
|
dprintf (" ALIAS\n");
|
|
} else {
|
|
dprintf ("\n");
|
|
}
|
|
}
|
|
|
|
VOID
|
|
HID_DumpPpd (
|
|
ULONG64 Ppd,
|
|
HID_PPD_FLAGS Flags
|
|
)
|
|
{
|
|
ULONG i;
|
|
ULONG64 channel;
|
|
ULONG64 node;
|
|
ULONG SizeOfChannels, DataOff;
|
|
|
|
if (InitTypeRead(Ppd, hidparse!_HIDP_PREPARSED_DATA)) {
|
|
dprintf("Cannot read type hidparse!_HIDP_PREPARSED_DATA at %p\n", Ppd);
|
|
return;
|
|
}
|
|
|
|
if (!Flags.IgnoreSignature) {
|
|
if ((HIDP_PREPARSED_DATA_SIGNATURE1 != (ULONG) ReadField(Signature1)) ||
|
|
(HIDP_PREPARSED_DATA_SIGNATURE2 != (ULONG) ReadField(Signature2))) {
|
|
|
|
dprintf("Preparsed Data signature does not match, probably aint\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
SizeOfChannels = GetTypeSize("hidparse!_HIDP_CHANNEL_DESC");
|
|
GetFieldOffset("hidparse!_HIDP_CHANNEL_DESC", "Data", &DataOff);
|
|
|
|
if (Flags.InputChannels) {
|
|
dprintf ("\n========== Input Channels =========\n");
|
|
for (i = (ULONG) ReadField(Input.Offset); i < (ULONG) ReadField(Input.Index); i++) {
|
|
channel = Ppd + DataOff + SizeOfChannels * i;
|
|
HID_DumpChannel (channel, Flags);
|
|
}
|
|
} else {
|
|
dprintf ("Input channels: off %x sz %x indx %x bytelen %x\n",
|
|
(ULONG) ReadField(Input.Offset),
|
|
(ULONG) ReadField(Input.Size),
|
|
(ULONG) ReadField(Input.Index),
|
|
(ULONG) ReadField(Input.ByteLen));
|
|
}
|
|
|
|
if (Flags.OutputChannels) {
|
|
dprintf ("\n========== Output Channels =========\n");
|
|
for (i = (ULONG) ReadField(Output.Offset); i < (ULONG) ReadField(Output.Index); i++) {
|
|
channel = Ppd + DataOff + SizeOfChannels * i;
|
|
HID_DumpChannel (channel, Flags);
|
|
}
|
|
} else {
|
|
dprintf ("Output channels: off %x sz %x indx %x bytelen %x\n",
|
|
(ULONG) ReadField(Output.Offset),
|
|
(ULONG) ReadField(Output.Size),
|
|
(ULONG) ReadField(Output.Index),
|
|
(ULONG) ReadField(Output.ByteLen));
|
|
}
|
|
|
|
if (Flags.FeatureChannels) {
|
|
dprintf ("\n========== Feature Channels =========\n");
|
|
for (i = (ULONG) ReadField(Feature.Offset); i < (ULONG) ReadField(Feature.Index); i++) {
|
|
channel = Ppd + DataOff + SizeOfChannels * i;
|
|
HID_DumpChannel (channel, Flags);
|
|
}
|
|
|
|
} else {
|
|
dprintf ("Feature channels: off %x sz %x indx %x bytelen %x\n",
|
|
(ULONG) ReadField(Feature.Offset),
|
|
(ULONG) ReadField(Feature.Size),
|
|
(ULONG) ReadField(Feature.Index),
|
|
(ULONG) ReadField(Feature.ByteLen));
|
|
}
|
|
|
|
if (Flags.LinkCollections) {
|
|
ULONG NodeSize;
|
|
|
|
dprintf ("\n========== Link Collections =========\n");
|
|
node = (ReadField(RawBytes) + ReadField(LinkCollectionArrayOffset));
|
|
NodeSize = GetTypeSize("hidparse!_HIDP_LINK_COLLECTION_NODE");
|
|
|
|
for (i = 0; i < (ULONG) ReadField(LinkCollectionArrayLength); i++, node+=NodeSize) {
|
|
HID_DumpLink (i, node);
|
|
}
|
|
|
|
} else {
|
|
dprintf ("Link Collections: %x \n",
|
|
(ULONG) ReadField(LinkCollectionArrayLength));
|
|
}
|
|
dprintf ("\n");
|
|
}
|
|
|
|
VOID
|
|
HID_DumpHidPDeviceDesc (
|
|
ULONG64 Desc,
|
|
HID_FLAGS Flags
|
|
)
|
|
{
|
|
HID_PPD_FLAGS ppdFlags;
|
|
ULONG result;
|
|
ULONG i;
|
|
ULONG size;
|
|
PVOID col;
|
|
PVOID rep;
|
|
ULONG CollectionDescLength, ReportIDsLength;
|
|
ULONG64 ReportIDs, CollectionDesc;
|
|
ULONG SizeofDesc, SizeofRep;
|
|
|
|
UNREFERENCED_PARAMETER (Flags);
|
|
|
|
dprintf ("\n*** HID Device Descripton ***\n");
|
|
|
|
InitTypeRead(Desc, hidparse!_HIDP_DEVICE_DESC);
|
|
CollectionDesc = ReadField(CollectionDesc);
|
|
ReportIDs = ReadField(ReportIDs);
|
|
CollectionDescLength = (ULONG) ReadField(CollectionDescLength);
|
|
ReportIDsLength = (ULONG) ReadField(ReportIDsLength);
|
|
|
|
dprintf ("Col len: %x Report ID Len: %x\n",
|
|
CollectionDescLength,
|
|
ReportIDsLength);
|
|
|
|
SizeofDesc = GetTypeSize("hidparse!_HIDP_COLLECTION_DESC");
|
|
if (!SizeofDesc) {
|
|
dprintf("Cannot find type hidparse!_HIDP_COLLECTION_DESC.\n");
|
|
return;
|
|
}
|
|
|
|
SizeofRep = GetTypeSize("hidparse!_HIDP_REPORT_IDS");
|
|
if (!SizeofRep) {
|
|
dprintf("Cannot find type hidparse!_HIDP_REPORT_IDS.\n");
|
|
return;
|
|
}
|
|
|
|
size = CollectionDescLength * SizeofDesc;
|
|
col = LocalAlloc (LPTR, size);
|
|
if (NULL == col) {
|
|
dprintf ("Could not allocate the memory\n");
|
|
return;
|
|
}
|
|
|
|
if (!ReadMemory (CollectionDesc, col, size, &result)) {
|
|
dprintf ("Could not read Ppd\n");
|
|
LocalFree (col);
|
|
return;
|
|
}
|
|
|
|
size = ReportIDsLength * SizeofRep;
|
|
rep = LocalAlloc (LPTR, size);
|
|
if (NULL == rep) {
|
|
dprintf ("Could not allocate the memory\n");
|
|
LocalFree (col);
|
|
return;
|
|
}
|
|
|
|
if (!ReadMemory (ReportIDs, rep, size, &result)) {
|
|
dprintf ("Could not read Ppd\n");
|
|
LocalFree (col);
|
|
LocalFree (rep);
|
|
return;
|
|
}
|
|
LocalFree (col);
|
|
LocalFree (rep);
|
|
|
|
dprintf ("--- Top Collections -----\n");
|
|
for (i=0; i < CollectionDescLength; i++) {
|
|
InitTypeRead(CollectionDesc + i*SizeofDesc, hidparse!_HIDP_COLLECTION_DESC);
|
|
|
|
dprintf ("%x: U %x UP %x ColNum %x In %x Out %x Fea %x Ppd %x\n",
|
|
i,
|
|
(ULONG) ReadField(.Usage),
|
|
(ULONG) ReadField(.UsagePage),
|
|
(ULONG) ReadField(.CollectionNumber),
|
|
(ULONG) ReadField(.InputLength),
|
|
(ULONG) ReadField(.OutputLength),
|
|
(ULONG) ReadField(.FeatureLength),
|
|
(ULONG) ReadField(.PreparsedData));
|
|
}
|
|
|
|
dprintf ("--- Report IDs -----\n");
|
|
for (i=0; i < ReportIDsLength; i++) {
|
|
InitTypeRead(ReportIDs + i*SizeofRep, hidparse!_HIDP_REPORT_IDS);
|
|
|
|
dprintf ("%x: ID %x ColNum %x In %x Out %x Fea %x\n",
|
|
i,
|
|
(ULONG) ReadField(.ReportID),
|
|
(ULONG) ReadField(.CollectionNumber),
|
|
(ULONG) ReadField(.InputLength),
|
|
(ULONG) ReadField(.OutputLength),
|
|
(ULONG) ReadField(.FeatureLength));
|
|
}
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
HID_DumpPDOExt (
|
|
ULONG64 Pdo
|
|
)
|
|
{
|
|
InitTypeRead(Pdo, hidparse!_HIDCLASS_DEVICE_EXTENSION);
|
|
dprintf("\n");
|
|
dprintf ("Collection Num %x Collection Index %x PDO %x Name %x \n"
|
|
"Fdo Extension %x\n",
|
|
(ULONG) ReadField(pdoExt.collectionNum),
|
|
(ULONG) ReadField(pdoExt.collectionIndex),
|
|
(ULONG) ReadField(pdoExt.pdo),
|
|
(ULONG) ReadField(pdoExt.name),
|
|
(ULONG) ReadField(pdoExt.deviceFdoExt));
|
|
dprintf ("\n");
|
|
}
|
|
|
|
VOID
|
|
HID_DumpFDOExt (
|
|
ULONG64 Fdo
|
|
)
|
|
{
|
|
ULONG64 object;
|
|
ULONG64 fdoExt;
|
|
ULONG size;
|
|
ULONG i;
|
|
ULONG result;
|
|
ULONG64 loc;
|
|
ULONG64 startLoc;
|
|
HID_FLAGS Flags;
|
|
ULONG FdoExtOffset;
|
|
PVOID collection;
|
|
ULONG PtrSize;
|
|
ULONG SizeOfClassColl;
|
|
ULONG CollectionDescLength;
|
|
ULONG64 classCollectionArray, deviceRelations;
|
|
ULONG fileExtListOff, fileListOff;
|
|
ULONG devCapOff;
|
|
|
|
InitTypeRead(Fdo, hidparse!_HIDCLASS_DEVICE_EXTENSION);
|
|
|
|
dprintf("\n");
|
|
dprintf("Fdo %p => PDO: %p NextDO %p \n"
|
|
"MiniDeviceExt %p DriveExt %p\n",
|
|
ReadField(fdoExt.fdo),
|
|
ReadField(hidExt.PhysicalDeviceObject),
|
|
ReadField(hidExt.NextDeviceObject),
|
|
ReadField(hidExt.MiniDeviceExtension),
|
|
ReadField(fdoExt.driverExt));
|
|
|
|
switch ((ULONG) ReadField(fdoExt.state)) {
|
|
case DEVICE_STATE_INITIALIZED:
|
|
dprintf ("DEVICE_STATE_INITIALIZED: \n");
|
|
break;
|
|
case DEVICE_STATE_STARTING:
|
|
dprintf ("DEVICE_STATE_STARTING: \n");
|
|
break;
|
|
case DEVICE_STATE_START_SUCCESS:
|
|
dprintf ("DEVICE_STATE_START_SUCCESS: \n");
|
|
break;
|
|
case DEVICE_STATE_START_FAILURE:
|
|
dprintf ("DEVICE_STATE_START_FAILURE: \n");
|
|
break;
|
|
case DEVICE_STATE_STOPPED:
|
|
dprintf ("DEVICE_STATE_STOPPED: \n");
|
|
break;
|
|
case DEVICE_STATE_REMOVING:
|
|
dprintf ("DEVICE_STATE_REMOVING: \n");
|
|
break;
|
|
case DEVICE_STATE_REMOVED:
|
|
dprintf ("DEVICE_STATE_REMOVED: \n");
|
|
break;
|
|
case DEVICE_STATE_SUSPENDED:
|
|
dprintf ("DEVICE_STATE_SUSPENDED: \n");
|
|
break;
|
|
}
|
|
|
|
dprintf("\nHidDescriptor:: len %x bcd %x numDesc %x repleng %x \n",
|
|
(ULONG) ReadField(fdoExt.hidDescriptor.bLength),
|
|
(ULONG) ReadField(fdoExt.hidDescriptor.bcdHID),
|
|
(ULONG) ReadField(fdoExt.hidDescriptor.bNumDescriptors),
|
|
(ULONG) ReadField(fdoExt.hidDescriptor.DescriptorList[0].wReportLength));
|
|
|
|
dprintf("Raw Desriptor: %x length: %x \n",
|
|
(ULONG) ReadField(fdoExt.rawReportDescription),
|
|
(ULONG) ReadField(fdoExt.rawReportDescriptionLength));
|
|
|
|
dprintf("HIDP_DEVICE_DESC: %x\n", (ULONG) ReadField(fdoExt.deviceDesc));
|
|
dprintf("Collections: %x Report IDs: %x\n",
|
|
(CollectionDescLength = (ULONG) ReadField(fdoExt.deviceDesc.CollectionDescLength)),
|
|
(ULONG) ReadField(fdoExt.deviceDesc.ReportIDsLength));
|
|
|
|
dprintf("Device Relations Array: %p\n", (deviceRelations = ReadField(fdoExt.deviceRelations)));
|
|
dprintf("Class Collection Array: %p\n", (classCollectionArray = ReadField(fdoExt.classCollectionArray)));
|
|
|
|
Flags.Flags = 0x0F;
|
|
|
|
HID_DumpHidPDeviceDesc (ReadField(fdoExt.deviceDesc), Flags);
|
|
|
|
PtrSize = DBG_PTR_SIZE;
|
|
SizeOfClassColl = GetTypeSize ("HIDCLASS_COLLECTION");
|
|
size = (CollectionDescLength) * SizeOfClassColl;
|
|
|
|
collection = LocalAlloc (0, size);
|
|
if (!collection) {
|
|
dprintf ("Could not allocate the memory\n");
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Read entire array so that its cached for each element
|
|
//
|
|
if (!ReadMemory (classCollectionArray,
|
|
collection,
|
|
size,
|
|
&result)) {
|
|
dprintf ("Could not read Collection array\n");
|
|
LocalFree (collection);
|
|
return;
|
|
}
|
|
|
|
size = (CollectionDescLength + 1)* PtrSize;
|
|
|
|
GetFieldOffset("HIDCLASS_COLLECTION", "FileExtensionList", &fileExtListOff);
|
|
GetFieldOffset("HIDCLASS_FILE_EXTENSION", "FileList", &fileListOff);
|
|
|
|
dprintf ("------ Children -----\n");
|
|
for (i = 0; i < CollectionDescLength; i++) {
|
|
ULONG64 objAddr;
|
|
|
|
ReadPointer(deviceRelations + i* PtrSize, &objAddr);
|
|
|
|
InitTypeRead(classCollectionArray + i*SizeOfClassColl, hidparse!_HIDCLASS_COLLECTION);
|
|
|
|
dprintf ("DO: %p: ColNum %x ColIndx %x DevExt %x\n"
|
|
" # Opens %x, FileExtList.Flink %p \n"
|
|
" PollInterval ms %x, PolledDeviceReadQueue.Flink %p\n"
|
|
" SymLinName %x Ppd %x PowerIrp %x\n",
|
|
objAddr,
|
|
(ULONG) ReadField(CollectionNumber),
|
|
(ULONG) ReadField(CollectionIndex),
|
|
(ULONG) ReadField(DeviceExtension),
|
|
(ULONG) ReadField(NumOpens),
|
|
ReadField(FileExtensionList.Flink),
|
|
(ULONG) ReadField(PollInterval_msec),
|
|
ReadField(polledDeviceReadQueue.Flink),
|
|
(ULONG) ReadField(SymbolicLinkName.Buffer),
|
|
(ULONG) ReadField(phidDescriptor),
|
|
(ULONG) ReadField(powerEventIrp));
|
|
|
|
dprintf (" DescSize %x polled %x VID %x PID %x Version %x\n",
|
|
(ULONG) ReadField(hidCollectionInfo.DescriptorSize),
|
|
(ULONG) ReadField(hidCollectionInfo.Polled),
|
|
(ULONG) ReadField(hidCollectionInfo.VendorID),
|
|
(ULONG) ReadField(hidCollectionInfo.ProductID),
|
|
(ULONG) ReadField(hidCollectionInfo.VersionNumber));
|
|
|
|
loc = ReadField(FileExtensionList.Flink);
|
|
startLoc = classCollectionArray + fileExtListOff;
|
|
|
|
dprintf (" File List %x\n", startLoc);
|
|
|
|
i=0;
|
|
while ((loc != startLoc) && (i++ < 100)) {
|
|
ULONG64 Flink;
|
|
|
|
loc = (loc - fileListOff);
|
|
|
|
if (GetFieldValue(loc, "hidparse!_HIDCLASS_FILE_EXTENSION", "FileList.Flink", Flink)) {
|
|
dprintf ("could not read hidparse!_HIDCLASS_FILE_EXTENSION at %p\n", loc);
|
|
LocalFree (collection);
|
|
return;
|
|
}
|
|
|
|
InitTypeRead(loc, hidparse!_HIDCLASS_COLLECTION);
|
|
dprintf (" FileExt %p ColNum %x fdoExt %x\n"
|
|
" PendingIrp.Flink %x Reports.Flink %x\n"
|
|
" FILE %x Closing? %x \n",
|
|
loc,
|
|
(ULONG) ReadField(CollectionNumber),
|
|
(ULONG) ReadField(fdoExt),
|
|
(ULONG) ReadField(PendingIrpList.Flink),
|
|
(ULONG) ReadField(ReportList.Flink),
|
|
(ULONG) ReadField(FileObject),
|
|
(ULONG) ReadField(Closing));
|
|
|
|
loc = Flink;
|
|
}
|
|
}
|
|
|
|
GetFieldOffset("hidparse!_HIDCLASS_DEVICE_EXTENSION", "fdoExt.deviceCapabilities", &devCapOff);
|
|
DumpDeviceCapabilities (Fdo + devCapOff);
|
|
|
|
LocalFree (collection);
|
|
dprintf ("\n");
|
|
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
DevExtHID(
|
|
ULONG64 MemLocPtr
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dump a HID Device extension.
|
|
|
|
Arguments:
|
|
|
|
Extension Address of the extension to be dumped.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ULONG isClientPdo, Signature;
|
|
ULONG64 MemLoc = MemLocPtr;
|
|
|
|
dprintf ("Dump HID Extension: %p\n", MemLoc);
|
|
|
|
if (GetFieldValue (MemLoc, "HIDCLASS_DEVICE_EXTENSION", "isClientPdo", isClientPdo)) {
|
|
dprintf ("Could not read HID Extension\n");
|
|
}
|
|
|
|
GetFieldValue (MemLoc, "HIDCLASS_DEVICE_EXTENSION", "Signature", Signature);
|
|
if (HID_DEVICE_EXTENSION_SIG != Signature) {
|
|
|
|
dprintf("HID Extension Signature does not match, probably aint\n");
|
|
return;
|
|
}
|
|
|
|
if (isClientPdo)
|
|
{
|
|
HID_DumpPDOExt(MemLoc);
|
|
}
|
|
else
|
|
{
|
|
HID_DumpFDOExt(MemLoc);
|
|
}
|
|
|
|
return;
|
|
}
|