我有一个内核驱动程序,用来查找存储设备的序列号,但是驱动程序有问题。Descriptor->SerialNumberOffset
是103
但(LPCSTR)(UINT_PTR)Descriptor+(DWORD32)Descriptor->SerialNumberOffset
为空
这是我的密码
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
与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);
当然,我们可以使用