当我们强制转换Descriptor + Descriptor-> SerialNumberOffset时,序列号枚举失败 [英] Serial number enumeration failed when we cast Descriptor+Descriptor->SerialNumberOffset
问题描述
我有一个内核驱动程序,用于查找存储设备的序列号,但是该驱动程序有问题.
Descriptor->SerialNumberOffset
是 103
但 (LPCSTR)(UINT_PTR)Descriptor+(DWORD32)Descriptor->SerialNumberOffset
为NULL
I have a kernel driver which is used to find the serial number of storage devices, but there is an issue with the driver.
Descriptor->SerialNumberOffset
is 103
but (LPCSTR)(UINT_PTR)Descriptor+(DWORD32)Descriptor->SerialNumberOffset
is NULL
这是我的代码
here is my code
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
与OutputBufferLength = STORAGE_DEVICE_DESCRIPTOR.Size
发送.代码可以像这样.
you mistake in OutputBufferLength
- why you decide that sizeof(STORAGE_DEVICE_DESCRIPTOR)*4
is enough ? why not 5* sizeof(STORAGE_DEVICE_DESCRIPTOR)
for example ? really what OutputBufferLength
must be is unknown - you need call this query in loop and compare your current OutputBufferLength
with STORAGE_DEVICE_DESCRIPTOR.Size
- if OutputBufferLength < STORAGE_DEVICE_DESCRIPTOR.Size
- you must again send IOCTL_STORAGE_QUERY_PROPERTY
with OutputBufferLength = STORAGE_DEVICE_DESCRIPTOR.Size
. the code can be look like.
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
-这没什么改变并且与问题无关
in place NtDeviceIoControlFile
we of course can use IoBuildDeviceIoControlRequest
+ IoCallDriver
- this nothing change and unrelated to problem
这篇关于当我们强制转换Descriptor + Descriptor-> SerialNumberOffset时,序列号枚举失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!