当我们强制转换Descriptor + Descriptor-> SerialNumberOffset时,序列号枚举失败 [英] Serial number enumeration failed when we cast Descriptor+Descriptor->SerialNumberOffset

查看:304
本文介绍了当我们强制转换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必须是未知的-您需要循环调用此查询,并将当前的OutputBufferLengthSTORAGE_DEVICE_DESCRIPTOR.Size进行比较-如果OutputBufferLength < STORAGE_DEVICE_DESCRIPTOR.Size-您必须再次将IOCTL_STORAGE_QUERY_PROPERTYOutputBufferLength = 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆