我有一个内核驱动程序,用于查找存储设备的序列号,但驱动程序存在问题。
Descriptor->SerialNumberOffset
103
但 (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;
}
}
}
}
请分享如何解决此问题
答案 0 :(得分:1)
你误以为OutputBufferLength
- 为什么你认为sizeof(STORAGE_DEVICE_DESCRIPTOR)*4
就够了?为什么不5* sizeof(STORAGE_DEVICE_DESCRIPTOR)
呢?确实OutputBufferLength
必须是未知的 - 您需要循环调用此查询并将当前OutputBufferLength
与STORAGE_DEVICE_DESCRIPTOR.Size
进行比较 - 如果OutputBufferLength < STORAGE_DEVICE_DESCRIPTOR.Size
- 您必须再次发送IOCTL_STORAGE_QUERY_PROPERTY
与OutputBufferLength = STORAGE_DEVICE_DESCRIPTOR.Size
。代码看起来像。
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
- 这没有任何变化,与问题无关