我们转换Descriptor + Descriptor-> SerialNumberOffset时序列号枚举失败

我有一个内核驱动程序,用于查找存储设备的序列号,但驱动程序存在问题。 Descriptor->SerialNumberOffset103但是(LPCSTR)(UINT_PTR)Descriptor+(DWORD32)Descriptor->SerialNumberOffset为NULL

这是我的代码

 NTSTATUS GetDeviceTypeAndUniqueID(IN PDEVICE_OBJECT StorageStackDeviceObject, cwDevices *lDeviceTypeArg, char *pszUidArg) { DWORRD lDeviceType=0; STORAGE_PROPERTY_QUERY Query; STORAGE_DEVICE_DESCRIPTOR Buffer[4]; NTSTATUS Status = STATUS_SUCCESS; ULONG uBusType=BusTypeUnknown; PSTORAGE_DEVICE_DESCRIPTOR Descriptor=NULL; PIRP NewIrp2=NULL; PIO_STACK_LOCATION NextIrpStack=NULL; IO_STATUS_BLOCK IoStatus; char szSptr[2]={'_','\0'}; Query.PropertyId = StorageDeviceProperty;// first set the query properties Query.QueryType = PropertyStandardQuery; lDeviceType=0; if (KeGetCurrentIrql() > PASSIVE_LEVEL) { return STATUS_SUCCESS; } if(StorageStackDeviceObject == NULL) { return STATUS_SUCCESS; } if((StorageStackDeviceObject->DeviceType != FILE_DEVICE_DISK) && (StorageStackDeviceObject->DeviceType != FILE_DEVICE_CD_ROM)&& (StorageStackDeviceObject->DeviceType != FILE_DEVICE_DVD)&& (StorageStackDeviceObject->DeviceType !=FILE_DEVICE_TAPE) ) { return STATUS_SUCCESS; } KeInitializeEvent(&WaitEvent_newIrp, NotificationEvent, TRUE);// initialize the waitable event __try { NewIrp2=IoBuildDeviceIoControlRequest(IOCTL_STORAGE_QUERY_PROPERTY, StorageStackDeviceObject, (PVOID)&Query,sizeof(STORAGE_PROPERTY_QUERY), (PVOID)Buffer,sizeof(STORAGE_DEVICE_DESCRIPTOR)*4, FALSE,&WaitEvent_newIrp,&IoStatus); if(NewIrp2==NULL) { return STATUS_SUCCESS; } Status = IoCallDriver(StorageStackDeviceObject, NewIrp2);// send this irp to the storage device if (Status == STATUS_PENDING) { KeWaitForSingleObject(&WaitEvent_newIrp, Executive, KernelMode, FALSE, NULL); Status =IoStatus.Status; } } __finally { if(NT_SUCCESS(Status)) { if (NT_SUCCESS(Status)) { if(Buffer!=NULL) { char szStart[256]; Descriptor = (PSTORAGE_DEVICE_DESCRIPTOR)Buffer; uBusType = Descriptor->BusType; //Get the bus type. if(Descriptor->SerialNumberOffset!=0)//Is Valid SerialNumberOffset, returns 103 { strcpy(szStart,(char*)(UINT_PTR)Descriptor+(DWORD32)Descriptor->SerialNumberOffset); //szStart is null } } NewIrp2 = NULL; } } } } 

请分享如何解决这个问题

你错了OutputBufferLength – 为什么你认为sizeof(STORAGE_DEVICE_DESCRIPTOR)*4就够了? 为什么不以5* sizeof(STORAGE_DEVICE_DESCRIPTOR)为例? 确实OutputBufferLength必须是未知的 – 您需要在循环中调用此查询并将当前的OutputBufferLengthSTORAGE_DEVICE_DESCRIPTOR.Size进行比较 – 如果OutputBufferLength < STORAGE_DEVICE_DESCRIPTOR.Size - 您必须再次使用OutputBufferLength = STORAGE_DEVICE_DESCRIPTOR.Size发送IOCTL_STORAGE_QUERY_PROPERTY 。 代码可以看起来像。

  STORAGE_PROPERTY_QUERY spq = { StorageDeviceProperty, PropertyStandardQuery }; union { PVOID buf; PSTR psz; PSTORAGE_DEVICE_DESCRIPTOR psdd; }; ULONG size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 0x100; NTSTATUS status = STATUS_INSUFFICIENT_RESOURCES; do { status = STATUS_INSUFFICIENT_RESOURCES; if (buf = ExAllocatePool(PagedPool, size)) { switch (status = (NtDeviceIoControlFile(hFile, 0, 0, 0, &iosb, IOCTL_STORAGE_QUERY_PROPERTY, &spq, sizeof(spq), buf, size))) { case STATUS_SUCCESS: case STATUS_BUFFER_OVERFLOW: if (psdd->Version == sizeof(STORAGE_DEVICE_DESCRIPTOR)) { if (psdd->Size > size) { size = psdd->Size; status = STATUS_BUFFER_OVERFLOW; } else { if (psdd->SerialNumberOffset) { DbgPrint("SerialNumber = %s\n", psz + psdd->SerialNumberOffset); } } } else { status = STATUS_INVALID_PARAMETER; } break; } ExFreePool(buf); } } while (status == STATUS_BUFFER_OVERFLOW); 

到位NtDeviceIoControlFile我们当然可以使用IoBuildDeviceIoControlRequest + IoCallDriver - 这没什么变化和问题无关