Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Аноним, Вы писали:
А>>Здравствуйте, _f_b_i_, Вы писали:
А>почти разобрался, теперь дескриптор получаю, но не могу предварительно получить его длину
А>1. index=0, langid=0, в качестве буфера &sd
А>получаю length = 4, lengid = 0x409
А>2. index=0, langid=0x409, в качестве буфера &sd
А>получаю length = 4, lengid = 0x409
А>3. index=0, langid=0x409, в качестве буфера 108 байт
А>получаю серийник
Гы... в качестве буфера &sd можно использовать ТОЛЬКО для вычитывания заголовка и все.
Тоесть:
1. index=0, langid=0, size = sizeof (sd) минус вот тот WCHAR[1], buf = &sd; В результате 04 03
2. index=0, langid=0, size = bLength, buf = ExAllocatePool(); В результате 04
03 04 09
3. index=0х0409, langid=из дискриптора, size = sizeof (sd) — WCHAR[1], buf = &sd; 6с 03 (тут должны быть твои 108 байт)
4. index=0х0409, langid=из дискриптора, size = bLength, buf = ExAllocatePool(); В результате 6с 03 .. .. ..
Длину получаешь на шаге 1, 3, и.т.д.
Здравствуйте, dimb82, Вы писали:
Я все сделал как Вы описали но почемуто у меня серийник = 0
Серийник у флешки точно есть.
Проблема получить из драйвера файловой системи. Из под драйвера USB я получаю серийник безпроблем.
Уже бьюсь 2 недели ничего не получается.
Может подскажете вчем может быть проблема?
D>Здравствуйте, Аноним, Вы писали:
А>>Подскажите, как в файловом фильтре, например при обработке IRP_MJ_CREATE определить серийник флешки подключенной через usb, к которой происходит обращение ?
А>>Спасибо.
D>Как определить в IRP_MJ_CREATE не скажу. Да и надо ли каждый раз делать это при обработке каждого IRP_MJ_CREATE? Не проще ли сделать это в момент IRP_MN_MOUNT_VOLUME, а потом просто сохранить полученный серийный номер в своём deviceExtension?
D>Если я не ошибаюсь, то обычно InstanceId у device object, созданного драйвером USBSTOR, совпадает с серийным номером флэшки. То есть нужно получить этот самый device object, а потом узнать его InstanceId.
D>Когда приходит пакет IRP_MN_MOUNT_VOLUME, то можно получить device object тома:
D>D>storageStackDeviceObject = irpSp->Parameters.MountVolume.Vpb->RealDevice;
D>
D>Теперь нужно выцепить из этого объекта другой device object, созданный драйвером USBSTOR. Вот примерный код для этого:
D>D>PDEVICE_OBJECT FilterGetDiskObject(PDEVICE_OBJECT pVolumeObject)
D>{
D> KEVENT waitEvent;
D> PIRP pNewIrp;
D> NTSTATUS status;
D> PVOLUME_DISK_EXTENTS pVolumeExtents;
D> UNICODE_STRING strDeviceName;
D> IO_STATUS_BLOCK IoStatus;
D> PIO_STACK_LOCATION pStackLocation;
D> PFILE_OBJECT pFileObject;
D> PDEVICE_OBJECT pDeviceObject;
D> PDEVICE_OBJECT pLowerDevice;
D> wchar_t data[25];
D> KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);
D> pVolumeExtents = (PVOLUME_DISK_EXTENTS) ExAllocatePoolWithTag(NonPagedPool, sizeof(VOLUME_DISK_EXTENTS), 'USBL');
D> pNewIrp = IoBuildDeviceIoControlRequest(IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
D> pVolumeObject, NULL, 0, (PVOID) pVolumeExtents, sizeof(VOLUME_DISK_EXTENTS),
D> FALSE, &waitEvent, &IoStatus);
D> if (!pNewIrp)
D> {
D> ExFreePool(pVolumeExtents);
D> return NULL;
D> }
D> // send this irp to the storage device
D> pStackLocation = IoGetNextIrpStackLocation(pNewIrp);
D> status = IoCallDriver(pVolumeObject, pNewIrp);
D> if (status == STATUS_PENDING)
D> {
D> status = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL);
D> status = IoStatus.Status;
D> }
D> if (!NT_SUCCESS(status))
D> {
D> ExFreePool(pVolumeExtents);
D> return NULL;
D> }
D> swprintf(data, L"\\GLOBAL??\\PhysicalDrive%d", pVolumeExtents->Extents[0].DiskNumber);
D> RtlInitUnicodeString(&strDeviceName, data);
D> ExFreePool(pVolumeExtents);
D> pDeviceObject = NULL;
D> IoGetDeviceObjectPointer(&strDeviceName, 0, &pFileObject, &pDeviceObject);
D> if (pDeviceObject == NULL)
D> return NULL;
D> pLowerDevice = IoGetDeviceAttachmentBaseRef(pDeviceObject);
D> ObDereferenceObject(pFileObject);
D> return pLowerDevice;
D>}
D>
D>Не забудьте потом вызвать ObDereferenceObject, когда полученный объект больше не будет нужен.
D>Потом надо убедиться, что это USB-устройство. Сделать это можно примерно так:
D>D>BOOLEAN IsUSBDevice(PDEVICE_OBJECT PDO)
D>{
D> NTSTATUS status;
D> GUID busGuid;
D> WCHAR wszEnumerator[30];
D> DEVICE_REMOVAL_POLICY removePolicy = (DEVICE_REMOVAL_POLICY) 0;
D> ULONG retLength;
D> if (PDO == NULL)
D> return FALSE;
D> status = IoGetDeviceProperty(PDO, DevicePropertyBusTypeGuid, 16, &busGuid, &retLength);
D> if (status == STATUS_SUCCESS)
D> {
D> GUID usbGuid = GUID_BUS_TYPE_USB;
D> if (memcmp(&busGuid, &usbGuid, sizeof(GUID)) == 0)
D> return TRUE;
D> }
D> status = IoGetDeviceProperty(PDO, DevicePropertyEnumeratorName, 30, wszEnumerator, &retLength);
D> if (status == STATUS_SUCCESS)
D> {
D> if (wszEnumerator[0] == L'U' &&
D> wszEnumerator[1] == L'S' &&
D> wszEnumerator[2] == L'B')
D> return TRUE;
D> }
D> status = IoGetDeviceProperty(PDO, DevicePropertyRemovalPolicy, sizeof(DEVICE_REMOVAL_POLICY),
D> &removePolicy, &retLength);
D> if (status == STATUS_SUCCESS)
D> {
D> if (removePolicy == 0 || removePolicy == 1)
D> return FALSE;
D> return TRUE;
D> }
D> return FALSE;
D>}
D>
D>Тут три проверки. Первую проверку можно убрать, так как сейчас USBSTOR не поддерживает запрос на DevicePropertyBusTypeGuid. У меня, по крайней мере, ни разу не получалось его выполнить с успехом для USB-дисков. Обычно срабатывает вторая проверка. Но нужно иметь в виду, что проверка довольно грубая. Третья проверка на то, является ли устройство Removable. Я не уверен, что проверка на 100% точная.
D>Теперь надо получить InstanceId. Кода для этого я тут не приведу. Но можно попробовать послать устройству пакет IRP_MN_QUERY_ID/BusQueryInstanceID.
D>Надеюсь, местные гуру поправят или уточнят меня, если я где-то ошибаюсь.
Что именно не получается? На каком этапе получаете ошибку?
А>Я все сделал как Вы описали но почемуто у меня серийник = 0
А>Серийник у флешки точно есть.
А>Проблема получить из драйвера файловой системи. Из под драйвера USB я получаю серийник безпроблем.
А>Уже бьюсь 2 недели ничего не получается.
А>Может подскажете вчем может быть проблема?
Здравствуйте, dimb82, Вы писали:
D>Что именно не получается? На каком этапе получаете ошибку?
Вот привожу код
Не получается сделать запрос USB — устройству
...
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FSControl;
...
NTSTATUS FSControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
...
CurrentStackLocation = IoGetCurrentIrpStackLocation(Irp);
ASSERT(CurrentStackLocation);
DeviceExtension = (PFSOBSRVDEVICEEXTENSION)(DeviceObject->DeviceExtension);
if (CurrentStackLocation->MinorFunction == IRP_MN_MOUNT_VOLUME)
{
if(IsUSBDevice(CurrentStackLocation->Parameters.MountVolume.Vpb->RealDevice))
{
GetDeviceSeriallNumber(DeviceExtension, FilterGetDiskObject(CurrentStackLocation->Parameters.MountVolume.Vpb->RealDevice));
}
}
...
}
PDEVICE_OBJECT FilterGetDiskObject(PDEVICE_OBJECT pVolumeObject)
{
KEVENT waitEvent;
PIRP pNewIrp;
NTSTATUS status;
PVOLUME_DISK_EXTENTS pVolumeExtents;
UNICODE_STRING strDeviceName;
IO_STATUS_BLOCK IoStatus;
PIO_STACK_LOCATION pStackLocation;
PFILE_OBJECT pFileObject;
PDEVICE_OBJECT pDeviceObject;
PDEVICE_OBJECT pLowerDevice;
wchar_t data[25];
KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);
pVolumeExtents = (PVOLUME_DISK_EXTENTS) ExAllocatePoolWithTag(NonPagedPool, sizeof(VOLUME_DISK_EXTENTS), 'USBL');
pNewIrp = IoBuildDeviceIoControlRequest(IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
pVolumeObject, NULL, 0, (PVOID) pVolumeExtents, sizeof(VOLUME_DISK_EXTENTS),
FALSE, &waitEvent, &IoStatus);
if (!pNewIrp)
{
ExFreePool(pVolumeExtents);
return NULL;
}
// send this irp to the storage device
pStackLocation = IoGetNextIrpStackLocation(pNewIrp);
status = IoCallDriver(pVolumeObject, pNewIrp);
if (status == STATUS_PENDING)
{
status = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL);
status = IoStatus.Status;
}
if (!NT_SUCCESS(status))
{
ExFreePool(pVolumeExtents);
return NULL;
}
swprintf(data, L"\\GLOBAL??\\PhysicalDrive%d", pVolumeExtents->Extents[0].DiskNumber);
RtlInitUnicodeString(&strDeviceName, data);
ExFreePool(pVolumeExtents);
pDeviceObject = NULL;
IoGetDeviceObjectPointer(&strDeviceName, 0, &pFileObject, &pDeviceObject);
if (pDeviceObject == NULL)
return NULL;
pLowerDevice = IoGetDeviceAttachmentBaseRef(pDeviceObject);
ObDereferenceObject(pFileObject);
return pLowerDevice;
}
NTSTATUS GetDeviceSeriallNumber(PVOID pDeviceExtension, PDEVICE_OBJECT DiskDeviceObject)
{
PIRP Irp;
KEVENT Event;
IO_STATUS_BLOCK Iosb;
PFSOBSRVDEVICEEXTENSION DeviceExtension = (PFSOBSRVDEVICEEXTENSION)pDeviceExtension;
USB_DEVICE_DESCRIPTOR deviceDescriptor = {0};
USB_STRING_DESCRIPTOR stringDescriptor = {0};
PDEVICE_EXTENSION pdx = NULL;
STORAGE_PROPERTY_QUERY PropQuery;
PSTORAGE_DEVICE_DESCRIPTOR pDesc = NULL;
PFILE_OBJECT pFileObject;
PDEVICE_OBJECT pDeviceObject;
PDEVICE_OBJECT pLowerDevice;
NTSTATUS Status = STATUS_SUCCESS;
ULONG QuerySize = 0x4000;
ULONG retLength = 0;
ULONG ulResultLength = 0;
PVOID infoBuffer = NULL;
PVOID QueryBuffer = NULL;
PURB Urb,Urb1;
ULONG size;
UNICODE_STRING puString = {0,0,0};
UNICODE_STRING strDeviceName;
WCHAR wcharbuff[260];
__try
{
if(!DiskDeviceObject)
{
Status = STATUS_UNSUCCESSFUL;
__leave;
}
QueryBuffer = ExAllocatePoolWithTag( PagedPool, QuerySize, _ALLOC_TAG );
if ( !QueryBuffer )
{
__leave;
}
pdx = (PDEVICE_EXTENSION)DiskDeviceObject->DeviceExtension;
memset( &PropQuery, 0, sizeof(PropQuery) );
memset( QueryBuffer, 0, QuerySize );
PropQuery.PropertyId = StorageDeviceProperty;
PropQuery.QueryType = PropertyStandardQuery;
KeInitializeEvent( &Event, NotificationEvent, FALSE );
Irp = IoBuildDeviceIoControlRequest(IOCTL_STORAGE_QUERY_PROPERTY,
DiskDeviceObject,
&PropQuery,
sizeof(PropQuery),
QueryBuffer,
QuerySize,
FALSE,
&Event,
&Iosb);
if (!Irp)
{
Status = STATUS_UNSUCCESSFUL;
__leave;
}
Status = IoCallDriver( DiskDeviceObject, Irp);
if ( STATUS_PENDING == Status )
{
KeWaitForSingleObject( &Event, Executive, KernelMode, FALSE, (PLARGE_INTEGER) NULL );
Status = Iosb.Status;
}
if ( !NT_SUCCESS( Status ) )
{
__leave;
}
if ( !Iosb.Information )
{
Status = STATUS_UNSUCCESSFUL;
__leave;
}
pDesc = (PSTORAGE_DEVICE_DESCRIPTOR)QueryBuffer;
if (pDesc)
{
DPRINT("%S. %s. Vendor %s\n", DRIVER_NAME, __FUNCTION__,
(LPCSTR)((ULONG_PTR)pDesc + pDesc->VendorIdOffset)); //Сдесь данные правильные
DPRINT("%S. %s. Product %s\n", DRIVER_NAME, __FUNCTION__,
(LPCSTR)((ULONG_PTR)pDesc + pDesc->ProductIdOffset)); //И сдесь тоже данные правильные
DPRINT("%S. %s. Serial %s\n", DRIVER_NAME, __FUNCTION__,
(LPCSTR)((ULONG_PTR)pDesc + pDesc->SerialNumberOffset)); //Сдесь просто скобка '(' смещение = 0
}
Status = IoGetDeviceProperty(DiskDeviceObject, DevicePropertyPhysicalDeviceObjectName, sizeof(wcharbuff), wcharbuff, &ulResultLength);
if(wcharbuff)
{
RtlInitUnicodeString(&strDeviceName, wcharbuff);
IoGetDeviceObjectPointer(&strDeviceName, 0, &pFileObject, &pDeviceObject);
if (pDeviceObject == NULL)
__leave;
pLowerDevice = IoGetDeviceAttachmentBaseRef(pDeviceObject);
ObDereferenceObject(pFileObject);
}
}
__finally
{
if ( QueryBuffer )
{
ExFreePool( QueryBuffer );
QueryBuffer = NULL;
}
}
if (!pLowerDevice)
{
return STATUS_UNSUCCESSFUL;
}
Urb = ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
Urb1 = ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
//size = sizeof(USB_DEVICE_DESCRIPTOR);
//deviceDescriptor = ExAllocatePool(NonPagedPool, size);
DeviceExtension->langid = 0;
UsbBuildGetDescriptorRequest(Urb,
(USHORT) sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_DEVICE_DESCRIPTOR_TYPE,
0,
0, //DeviceExtension->langid,
&deviceDescriptor,
NULL,
sizeof(USB_DEVICE_DESCRIPTOR),
NULL);
if(DiskDeviceObject->Vpb->RealDevice)
Status = SendAwaitUrb(DiskDeviceObject->Vpb->RealDevice, Urb); //Ошибка здесь статус != STATUS_SUCCESS
//pLowerDevice->DeviceExtension->idVendor = deviceDescriptor.idVendor;
//pLowerDevice->DeviceExtension->idProduct = deviceDescriptor.idProduct;
Urb1 = ExAllocatePool(NonPagedPool, sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST));
size = sizeof(USB_STRING_DESCRIPTOR);
UsbBuildGetDescriptorRequest(Urb1,
sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_STRING_DESCRIPTOR_TYPE,
0,
0,
&stringDescriptor,
NULL,
size,
NULL);
if(DiskDeviceObject->Vpb->RealDevice)
Status = SendAwaitUrb(DiskDeviceObject->Vpb->RealDevice, Urb1); //Ошибка здесь тоже статус != STATUS_SUCCESS
//if (STATUS_SUCCESS != Status)
// return STATUS_UNSUCCESSFUL;
//Status = DoCallUSBD(pLowerDevice, Urb1);
if (NT_SUCCESS(Status))
{
if(deviceDescriptor.iManufacturer)
{
Status = GetStringDescriptor(DeviceExtension, deviceDescriptor.iManufacturer, &puString);
if (NT_SUCCESS(Status))
{
DeviceExtension->DeviceManufacturer = ExAllocatePool(NonPagedPool, puString.Length*sizeof(WCHAR));
DeviceExtension->DeviceManufacturer = puString.Buffer;
DPRINT("Manufacturer %S\n", puString.Buffer);
}
}
if(deviceDescriptor.iProduct)
{
Status = GetStringDescriptor(DeviceExtension, deviceDescriptor.iProduct, &puString);
if (NT_SUCCESS(Status))
{
DeviceExtension->DeviceProduct = ExAllocatePool(NonPagedPool, puString.Length*sizeof(WCHAR));
DeviceExtension->DeviceProduct = puString.Buffer;
DPRINT("Product %S\n", puString.Buffer);
}
}
if(deviceDescriptor.iSerialNumber)
{
Status = GetStringDescriptor(DeviceExtension, deviceDescriptor.iSerialNumber, &puString);
if (NT_SUCCESS(Status))
{
DeviceExtension->DeviceSerialNumber = ExAllocatePool(NonPagedPool, puString.Length*sizeof(WCHAR));
DeviceExtension->DeviceSerialNumber = puString.Buffer;
DeviceExtension->DeviceSerialNumberLength = puString.Length + sizeof(WCHAR);
DPRINT("SerialNumber %S\n", puString.Buffer);
}
}
}
// Освободить занятую память
if (&deviceDescriptor)
{
ExFreePool(&deviceDescriptor);
//deviceDescriptor = {0};
}
if (&Urb)
{
ExFreePool(&Urb);
//&Urb = NULL;
}
if (&Urb1)
{
ExFreePool(&Urb1);
//&Urb1 = NULL;
}
return Status;
}
NTSTATUS SendAwaitUrb(PDEVICE_OBJECT fido, PURB pUrb)
{
KEVENT event;
PIRP pIrp = NULL;
IO_STATUS_BLOCK ioStatus;
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION nextStack = NULL;
//PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
KeInitializeEvent(&event, NotificationEvent, FALSE);
pIrp = IoBuildDeviceIoControlRequest(IOCTL_INTERNAL_USB_SUBMIT_URB,
fido, //pdx->NextLowerDriver,
NULL,
0,
NULL,
0,
TRUE,
&event,
&ioStatus);
if (NULL == pIrp)
{
status = ioStatus.Status;
goto exit;
}
nextStack = IoGetNextIrpStackLocation(pIrp);
nextStack->Parameters.Others.Argument1 = pUrb;
status = IoCallDriver(fido, pIrp);
if (STATUS_PENDING == status)
{
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = ioStatus.Status;
}
exit:
return status;
}
Напишу проще
PDEVICE_OBJECT DiskDeviceObject = FilterGetDiskObject(CurrentStackLocation->Parameters.MountVolume.Vpb->RealDevice);
не выполняется запрос к USB устройству
UsbBuildGetDescriptorRequest(Urb,
sizeof (struct _URB_CONTROL_DESCRIPTOR_REQUEST),
USB_DEVICE_DESCRIPTOR_TYPE,
0,
DeviceExtension->langid,
deviceDescriptor,
NULL,
size,
NULL);
if(DiskDeviceObject)
Status = DoCallUSBD(DiskDeviceObject, Urb);