Укажите отработанное время

Отработанное время:
Продуктивное время:
Bug 2158 - Не поддерживается USB-ключ Guardant Stealth/Net II (0a89:0003)   Make a simular bug
Summary: Не поддерживается USB-ключ Guardant Stealth/Net II (0a89:0003)
Status: CLOSED FIXED
Alias: None
Product: WINE@Etersoft
Classification: Продукты (Products)
Component: Ключи защиты ; Системы защиты ; Файл лицензии (show other bugs)
Version: 2.0
Hardware: PC Windows
: P5 minor
Target Milestone: ---
Assignee: Александр Морозов
QA Contact:
URL:
Whiteboard:
Keywords:
: 54 (view as bug list)
Depends on: 54
Blocks: 468 2241 2891
  Show dependency treegraph
 
In work:
Reported: 2008-07-25 16:05 MSD by Александр Морозов
Modified: 2014-01-05 02:56 MSK (History)
4 users (show)

See Also:
Заявки RT:
Связано с:
Дата напоминания:


Attachments
Патч, полученный от компании "Актив" (2.46 KB, patch)
2010-11-18 03:58 MSK, Александр Морозов
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Александр Морозов 2008-07-25 16:05:38 MSD
Ключ используется "ЛIГА:ЗАКОН Головний бухгалтер".

При загрузке драйвера ключа grdusb.sys происходит обращение к нереализованной функции:
wine: Call from 0x7b83fda0 to unimplemented function hal.dll.ExAcquireFastMutex, aborting
Comment 1 Александр Морозов 2008-07-25 17:32:33 MSD
Если добавить стабы для ExAcquireFastMutex и ExReleaseFastMutex, то DriverEntry (функция драйвера, вызываемая в начале его загрузки) выполняется без падений.

Для того, чтобы происходил вызов AddDevice, необходимо присвоить HKLM\System\CurrentControlSet\Enum\USB\Vid_0a89&Pid_0003\5&6d75465&0&1\ClassGUID значение "{36FC9E60-C465-11CF-8056-444553540000}".

Кроме того я столкнулся с тем, что при импорте reg-файлов из Windows значения параметров с типом REG_MULTI_SZ отображаются в виде знаков вопроса (вроде бы раньше всё работало). HKLM\System\CurrentControlSet\Enum\USB\Vid_0a89&Pid_0003\5&6d75465&0&1\HardwareID, отображающийся подобным образом, пришлось заменить на строку "USB\Vid_0a89&Pid_0003", без этого AddDevice не вызывался.

В настоящее время AddDevice падает из-за вызова нереализованных функций.
Comment 2 Александр Морозов 2008-08-01 13:27:38 MSD
После добавления некоторого количества стабов и небольшого изменения wineusbhub драйвер загружается без падений. Есть небольшая проблема: обработка IRP_MN_QUERY_CAPABILITIES завершается с ошибкой. Скорее всего, это не критично для работы с ключом. Для того, что бы проверить, работает ли он, надо установить под Wine "ЛIГА:ЗАКОН Головний бухгалтер".
Comment 3 Александр Морозов 2008-08-20 18:24:44 MSD
Поэкспериментировал с FRONTOL. В результате запуска FRONTOL.exe происходит обращение к \\.\GRDKEY, создаваемому grdkey.sys. По-видимому, для работы USB-ключа необходим не только grdusb.sys, но и grdkey.sys.

grdkey.sys содержит функцию AddDevice. Для её вызова в Wine надо, видимо, реализовать вызов AddDevice для драйверов устройств, описываемых в HKLM\SYSTEM\CurrentControlSet\Enum\Root. Пока что AddDevice вызывается wineusb только для USB-устройств.

Сделал хак, вызывающий AddDevice при загрузке grdkey.sys. После добавления необходимых стабов загружающий grdkey.sys winedevice падает, судя по всему, при выходе из AddDevice.
Comment 4 Александр Морозов 2008-08-21 14:16:28 MSD
Падение происходит не при выходе из AddDevice, а после возврата из обработчика IRP_MN_START_DEVICE
Comment 5 Александр Морозов 2008-08-21 14:48:55 MSD
После выполнения обработчика IRP_MN_START_DEVICE меняются регистры EBP и ESP. Если восстанавливать EBP после его выполнения, то падения не происходит.
Comment 6 Александр Морозов 2008-08-21 16:06:55 MSD
Второй вызов DeviceIoControl завершается с ошибкой. Скорее всего она вызвана тем, что не реализован IoAllocateMdl (всегда возвращает NULL).

trace:vxd:DeviceIoControl (0x144,e1b10014,0x323e2c,22848,0x323e2c,22848,0x31d184,(nil))
trace:ntoskrnl:process_ioctl ioctl e1b10014 device 0x116590 in_size 22848 out_size 22848
trace:ntoskrnl:IoAllocateIrp 2, 0
trace:ntoskrnl:ExAllocatePoolWithTag 184 pool 0 -> 0x111570
trace:ntoskrnl:IoInitializeIrp 0x111570, 184, 2
trace:ntoskrnl:ExAllocatePoolWithTag 22848 pool 0 -> 0x121a18
trace:ntoskrnl:ExAllocatePoolWithTag 64 pool 0 -> 0x1111c0
trace:ntoskrnl:ExAllocatePoolWithTag 8192 pool 0 -> 0x111630
trace:ntoskrnl:ExAllocatePoolWithTag 12300 pool 0 -> 0x127360
trace:ntoskrnl:ExAllocatePoolWithTag 4248 pool 0 -> 0x113638
trace:ntoskrnl:ExFreePoolWithTag 0x113638
fixme:ntoskrnl:IoAllocateMdl stub: 0x471bce, 303783, 0, 0, (nil)
trace:ntoskrnl:ExAllocatePoolWithTag 4248 pool 0 -> 0x113638
trace:ntoskrnl:ExFreePoolWithTag 0x113638
trace:ntoskrnl:__regs_IofCompleteRequest 0x111570 0
trace:ntoskrnl:ExFreePoolWithTag 0x1111c0
trace:ntoskrnl:ExFreePoolWithTag 0x111630
trace:ntoskrnl:ExFreePoolWithTag 0x127360
trace:ntoskrnl:IoFreeIrp 0x111570
trace:ntoskrnl:ExFreePoolWithTag 0x111570
trace:ntoskrnl:ExFreePoolWithTag 0x121a18
trace:vxd:DeviceIoControl status 0xc0000017, returning 0x0

0xC0000017 - это STATUS_NO_MEMORY
Comment 7 Александр Морозов 2008-08-21 17:36:02 MSD
> После выполнения обработчика IRP_MN_START_DEVICE
> меняются регистры EBP и ESP. Если
> восстанавливать EBP после его выполнения, то
> падения не происходит.

Не EBP, а EBX
Comment 8 Александр Морозов 2008-08-22 18:09:54 MSD
После реализации IoAllocateMdl и добавления нескольких стабов обрабочик IRP_MJ_DEVICE_CONTROL возвращает STATUS_INVALID_PARAMETER.
Comment 9 Александр Морозов 2008-08-22 18:13:43 MSD
trace:vxd:DeviceIoControl (0x144,e1b10014,0x323e2c,22848,0x323e2c,22848,0x31d184,(nil))
trace:ntoskrnl:process_ioctl ioctl e1b10014 device 0x116590 in_size 22848 out_size 22848
trace:ntoskrnl:IoAllocateIrp 2, 0
trace:ntoskrnl:ExAllocatePoolWithTag 184 pool 0 -> 0x111570
trace:ntoskrnl:IoInitializeIrp 0x111570, 184, 2
trace:ntoskrnl:ExAllocatePoolWithTag 22848 pool 0 -> 0x121a18
trace:ntoskrnl:process_ioctl esp 0x7ecfa7c0 ebx 0x7eeb2d90
trace:ntoskrnl:ExAllocatePoolWithTag 64 pool 0 -> 0x1111c0
trace:ntoskrnl:ExAllocatePoolWithTag 8192 pool 0 -> 0x111630
trace:ntoskrnl:ExAllocatePoolWithTag 12300 pool 0 -> 0x127360
trace:ntoskrnl:ExAllocatePoolWithTag 4248 pool 0 -> 0x113638
trace:ntoskrnl:ExFreePoolWithTag 0x113638
fixme:ntoskrnl:IoAllocateMdl 0x471bce, 303783, 0, 0, (nil)
trace:ntoskrnl:ExAllocatePoolWithTag 28 pool 0 -> 0x1114a8
trace:ntoskrnl:IoAllocateMdl buf 0x700000
trace:ntoskrnl:MmProbeAndLockPages 0x1114a8 0 0
trace:ntoskrnl:MmMapLockedPages 0x1114a8 0
fixme:ntoskrnl:IoAllocateMdl 0x471ab3, 257, 0, 0, (nil)
trace:ntoskrnl:ExAllocatePoolWithTag 28 pool 0 -> 0x111368
trace:ntoskrnl:IoAllocateMdl buf 0x800000
trace:ntoskrnl:MmProbeAndLockPages 0x111368 0 0
trace:ntoskrnl:MmMapLockedPages 0x111368 0
trace:ntoskrnl:MmUnlockPages 0x1114a8
trace:ntoskrnl:IoFreeMdl 0x1114a8
trace:ntoskrnl:ExFreePoolWithTag 0x1114a8
trace:ntoskrnl:MmUnlockPages 0x111368
trace:ntoskrnl:IoFreeMdl 0x111368
trace:ntoskrnl:ExFreePoolWithTag 0x111368
trace:ntoskrnl:ExAllocatePoolWithTag 4248 pool 0 -> 0x113638
trace:ntoskrnl:ExFreePoolWithTag 0x113638
trace:ntoskrnl:__regs_IofCompleteRequest 0x111570 0
trace:ntoskrnl:ExFreePoolWithTag 0x1111c0
trace:ntoskrnl:ExFreePoolWithTag 0x111630
trace:ntoskrnl:ExFreePoolWithTag 0x127360
trace:ntoskrnl:process_ioctl esp 0x7ecfa7c0 ebx 0x7eeb2d90
trace:ntoskrnl:process_ioctl status 3221225485
trace:ntoskrnl:IoFreeIrp 0x111570
trace:ntoskrnl:ExFreePoolWithTag 0x111570
trace:ntoskrnl:ExFreePoolWithTag 0x121a18
trace:vxd:DeviceIoControl status 0xc000000d, returning 0x0
Comment 10 Александр Морозов 2008-08-27 19:42:52 MSD
Установить причину того, что обрабочик IRP_MJ_DEVICE_CONTROL завершается с ошибкой, пока не удалось
Comment 11 Александр Морозов 2008-08-28 18:53:01 MSD
Пока что никаких успехов.
Comment 12 Александр Морозов 2008-09-03 15:24:30 MSD
Изменил реализацию IoAllocateMdl. Теперь просходит падение при обращении по адерсу, получаемому добавлением некоторого смещения к числу из массива, расположенного после структуры MDL. 

В WinDDK для доступа к этому массиву определён такой макрос:

//++
// PPFN_NUMBER
// MmGetMdlPfnArray (
//     IN PMDL Mdl
//     )
//
// Routine Description:
//
//     The MmGetMdlPfnArray routine returns the virtual address of the
//     first element of the array of physical page numbers associated with
//     the MDL.
//
// Arguments:
//
//     Mdl - Pointer to an MDL.
//
// Return Value:
//
//     Returns the virtual address of the first element of the array of
//     physical page numbers associated with the MDL.
//
//--

#define MmGetMdlPfnArray(Mdl) ((PPFN_NUMBER)(Mdl + 1))
Comment 13 Александр Морозов 2008-09-03 17:06:13 MSD
> Изменил реализацию IoAllocateMdl. Теперь
> просходит падение при обращении по адерсу,
> получаемому добавлением некоторого
> смещения к числу из массива,
> расположенного после структуры MDL. 

Как выяснилось, это падение было вызвано ошибкой, допущенной при изменении IoAllocateMdl. Так что проблема та же: обрабочик IRP_MJ_DEVICE_CONTROL возвращает STATUS_INVALID_PARAMETER.
Comment 14 Александр Морозов 2008-09-22 19:55:53 MSD
При запуске FRONTOL.exe после открытия файла \\.\GRDKEY для него 2 раза вызывается DeviceIoContol (с разными кодами IOCTL). Написал тестовую программу, делающую тоже самое. Единственное отличие: во входном буфере, используемом при втором вызове, мусор.

Вывод под Windows XP:
IOCTL_1: error 0, 64 bytes
IOCTL_2: error 87, 64 bytes

Вывод под Wine:
IOCTL_1: error 0, 64 bytes
IOCTL_2: error 87, 1 bytes

Здесь error - код, возвращаемый GetLastError. bytes - число байт, записанных в выходной буфер.

Под Wine после обработки второго вызова IOCTL в irp->IoStatus.Information помещается 0. Непонятно, откуда берётся "1 bytes".
Comment 15 Александр Морозов 2008-09-23 13:32:38 MSD
Если при втором вызове DeviceIoControl передавать те же данные, что передаются FRONTOL (вообще, 22848 байт, что помещаются во входной буфер, не всегда одни и те же, но начало одинаковое), то машина с Windows XP перезагружается. Под Wine вывод тестовой программы такой же, как и при передаче мусора.

Если передавать первые 128 байт, передаваемые FRONTOL, а дальше нули, то под Wine:
IOCTL_1: error 0, 64 bytes
IOCTL_2: error 8, 1 bytes
Под Windows:
IOCTL_1: error 0, 64 bytes
IOCTL_2: error 8, 64 bytes
Comment 16 Александр Морозов 2008-09-23 15:40:22 MSD
С помощью тестового драйвера получил структуру IRP, передаваемую в WinXP обработчику IOCTL драйвера grdkey.sys. Тестовый драйвер содержит те же обработчики, что и grdkey.sys и помещается в систему на его место.

Модифицировал process_ioctl так, чтобы поля IRP заполнялись как в Windows. Ошибка, возвращаемая обработчиком IOCTL, не изменилась.
Comment 17 Александр Морозов 2008-09-23 15:45:05 MSD
В process_ioctl некоторые указатели в структуре IRP устанавливаются в 0x99999999, так как я точно не знаю, на что они должны указывать. В Wine при обращении к 0x99999999 драйвер должен упасть.
Comment 18 Александр Морозов 2008-09-23 19:51:43 MSD
В Windows ExAllocatePoolWithTag возвращает указатель, выровненный на 8 или 16 байт (для 32 и 64-битных Win соответственно), если размер выделяемой памяти меньше размера страницы, и выровненный на размер страницы, если размер выделяемой памяти больше размера страницы. В Wine никакого выравнивания специально не делается.

Как оказалось, выставляемые в MDL флаги меняются в зависимости от размера области памяти. Сделал небольшой хак для IoAllocateMdl.

Подправил ExAllocatePoolWithTag, чтобы возвращались выровненные указатели.

Возвращаемая обработчиком IOCTL ошибка не изменилась.
Comment 19 Александр Морозов 2008-09-26 12:40:26 MSD
Если поставить FRONTOL под Windows, то с помощью тестового драйвера можно узнать, как происходит работа с драйвером под Windows, и сравнить с тем, что у нас под Wine. Возможно, есть отличия не только в работе драйвера но и на более высоком уровне. Поставил FRONTOL на winxp, но при запуске FRONTOL.exe почему-то ничего не происходит.
Comment 20 Александр Морозов 2008-09-26 15:09:16 MSD
> Если передавать первые 128 байт,
> передаваемые FRONTOL, а дальше нули, то под Wine:
> IOCTL_1: error 0, 64 bytes
> IOCTL_2: error 8, 1 bytes

Ошибка 8 - ERROR_NOT_ENOUGH_MEMORY. При этом в логе присутствует:
fixme:ntoskrnl:IoAllocateMdl 0xfdbcb332, 3350401000, 0, 0, (nil)
Второй параметр - это размер в байтах.
Comment 21 Александр Морозов 2008-09-26 19:11:47 MSD
FRONTOL.exe заработал после того, как я во FrontolIni.exe выставил автозапуск при старте в качестве приложения, номер ПК 1 и перезагрузился. Если выйти из запущенного при загрузке Frontol`а, то снова его запустить получается далеко не с первого раза.

FRONTOL.exe можно запустить на WinXP с тестовым драйвером вместо grdkey.sys. Видимо, роль grdkey.sys невелика и основную работу выполняет grdusb.sys.

В логах, получаемых при запуске FRONTOL.exe, есть следующие строчки:
trace:reg:NtOpenKey (0x38,L"System\\CurrentControlSet\\Control\\DeviceClasses",20019,0x31de44)
trace:reg:NtOpenKey <- (nil)

После импорта "System\CurrentControlSet\Control\DeviceClasses" из WinXP получаем:
warn:file:CreateFileW Unable to create file L"\\\\?\\USB#VID_0A89&PID_0003#5&6D75465&0&1#{46B89760-C784-11D4-81A8-0080AD87AF5C}" (status c0000034)

Под WinXP этот файл успешно открывается.
Comment 22 Александр Морозов 2008-09-29 19:22:36 MSD
GrdKey.sys не нужен для запуска Frontol.

Сделал хак, чтобы открывался \\.\GrdUsb при открытии
\\?\USB#VID_0A89&PID_0003#5&6D75465&0&1#{46B89760-C784-11D4-81A8-0080AD87AF5C}

Сделал тестовый драйвер (grdusbtest), который можно подсунуть вместо grdusb.sys. Но обращения к нему при запуске Frontol не происходит. При этом Frontol всё же как-то определяет, что ключа нет.

Фрагмент лога ww FRONTOL.exe после небольших изменений process_ioctl:
trace:vxd:DeviceIoControl (0x144,e1b20008,(nil),0,0x31e27c,26,0x31e29c,(nil))
trace:vxd:DeviceIoControl status 0xc000000d, returning 0x0
trace:vxd:DeviceIoControl (0x144,e1b20010,(nil),0,0x31e23c,64,0x31e29c,(nil))
trace:vxd:DeviceIoControl status 0x0, returning 0x1
trace:vxd:DeviceIoControl (0x144,e1b20004,0x323e2c,22848,0x323e2c,22848,0x31d184,(nil))
trace:vxd:DeviceIoControl status 0xc000000d, returning 0x0
Comment 23 Александр Морозов 2008-09-30 19:33:11 MSD
Исправлен тестовый драйвер, так что теперь видно, как Frontol к нему обращается. Файл \\?\USB#VID_0A89&PID_0003#5&6D75465&0&1#{46B89760-C784-11D4-81A8-0080AD87AF5C} появляется после выполнения IoRegisterDeviceInterface и IoSetDeviceInterfaceState.

Эти функции надо реализовать в Wine.

Пока сделано так, что при открытии файла с именем \\?\USB#VID_0A89&PID_0003#5&6D75465&0&1#{46B89760-C784-11D4-81A8-0080AD87AF5C} открывается \\.\GrdUsb, а потом в process_ioctl ссылка на его DEVICE_OBJECT заменяется на ссылку соответствующую DEVICE_OBJECT нужного нам безымянного устройства.

$ WINEDEBUG=+vxd,-ntoskrnl,-ntdll,-file,-usbd ww FRONTOL.exe
trace:vxd:DeviceIoControl (0x144,e1b20008,(nil),0,0x31e27c,26,0x31e29c,(nil))
trace:vxd:DeviceIoControl status 0x0, returning 0x1
trace:vxd:DeviceIoControl (0x144,e1b20010,(nil),0,0x31e23c,64,0x31e29c,(nil))
trace:vxd:DeviceIoControl status 0x0, returning 0x1
trace:vxd:DeviceIoControl (0x144,e1b20004,0x323e2c,22848,0x323e2c,22848,0x31d184,(nil))
trace:vxd:DeviceIoControl status 0xc000000d, returning 0x0

При выполнении DeviceIoControl с кодом 0xe1b20004 и теми же входными данными, что передаются драйверу под Wine, Windows XP перезагружается.
Comment 24 Александр Морозов 2008-10-01 20:01:43 MSD
В Windows можно передать драйверу виртуальный адрес буфера в адресном пространстве пользовательской программы, и драйвер может туда что-нибудь записать. Вполне возможно, что при обработке третьего IOCTL именно это и происходит.

Написан тест, в котором это делается с помощью функций Io*Mdl и Mm*.

В Wine драйвер выполняется в отдельном процессе, то есть надо реализовать чтение/запись из одного процесса в адресное пространство другого процесса.
Comment 25 Александр Морозов 2008-10-06 19:47:43 MSD
Попробовал реализовать чтение из адресного пространства другого процесса и запись туда же. Пока что тест проваливается.
Comment 26 Александр Морозов 2008-10-07 19:54:50 MSD
Тест работает за исключением бага, в результате которого неправильно возвращается количество записанных в выходной буфер байт:
ntoskrnl.c:292: Test failed: Wrong reply length: 1 (expected 0)

Тест работает только один раз после запуска wineserver, так как id процесса, в адресное пространство которого производится запись, пока что жёстко установлен в 8. Это соответствует первому запущенному процессу.

Обработка IOCTL с кодом 0xe1b20004 завершается с ошибкой 0xc000000d.
Comment 27 Александр Морозов 2008-10-08 19:28:31 MSD
Теперь вызывающий DeviceIoControl процесс, в адресное пространство которого производится запись, может иметь любой id. Тест работает любое число раз без перезапуска wineserver.

Драйвер при выполнении FRONTOL.exe падает:
.......
.......
trace:ntoskrnl:MmMapLockedPages 0x110fc8 0
trace:ntoskrnl:ExAllocatePoolWithTag 266696 pool 0 -> 0x1745c8
trace:ntoskrnl:ExFreePoolWithTag 0x1745c8
trace:ntoskrnl:ExAllocatePoolWithTag 390120 pool 0 -> 0x1745c8
warn:seh:setup_exception_record exception outside of stack limits in thread 0014 eip 00144f5a esp 00129cac stack 0x7ebcd000-0x7ecdb000
trace:seh:raise_exception code=c0000005 flags=0 addr=0x144f5a
trace:seh:raise_exception  info[0]=00000000
trace:seh:raise_exception  info[1]=001e0000
trace:seh:raise_exception  eax=8d3de58b ebx=0012a280 ecx=fffd51b1 edx=00000000 esi=0012a1e8 edi=001e0000
trace:seh:raise_exception  ebp=00129cbc esp=00129cac cs=0073 ds=007b es=007b fs=0033 gs=003b flags=00010286
err:seh:raise_exception Exception frame is not in stack limits => unable to dispatch exception.
trace:seh:raise_exception code=eedfade flags=1 addr=0x7b840040
trace:seh:raise_exception  info[0]=010f70e3
trace:seh:raise_exception  info[1]=0179abf8
trace:seh:raise_exception  info[2]=010f3027
trace:seh:raise_exception  info[3]=fffffc7a
trace:seh:raise_exception  info[4]=005a50dc
trace:seh:raise_exception  info[5]=0032fd9c
trace:seh:raise_exception  info[6]=0032ad50
trace:seh:raise_exception  eax=7b82c86d ebx=7b8a587c ecx=00000000 edx=00000007 esi=fffffc7a edi=005a50dc
trace:seh:raise_exception  ebp=0032ad1c esp=0032acb8 cs=0073 ds=007b es=007b fs=0033 gs=003b flags=00000216
trace:seh:call_stack_handlers calling handler at 0x10f716d code=eedfade flags=1
trace:seh:call_stack_handlers handler at 0x10f716d returned 1
trace:seh:call_stack_handlers calling handler at 0x10e5edb code=eedfade flags=1
trace:seh:call_stack_handlers handler at 0x10e5edb returned 1
trace:seh:call_stack_handlers calling handler at 0x4f0a53 code=eedfade flags=1
trace:seh:__regs_RtlUnwind code=eedfade flags=3
trace:seh:__regs_RtlUnwind calling handler at 0x7bc384e0 code=eedfade flags=3
trace:seh:__regs_RtlUnwind handler at 0x7bc384e0 returned 1
trace:seh:__regs_RtlUnwind calling handler at 0x10f716d code=eedfade flags=3
trace:seh:__regs_RtlUnwind handler at 0x400064e8 returned 1
trace:seh:__regs_RtlUnwind calling handler at 0x10e5edb code=eedfade flags=3
trace:seh:__regs_RtlUnwind handler at 0x400064e8 returned 1
trace:seh:call_stack_handlers handler at 0x40006627 returned 1
trace:seh:call_stack_handlers calling handler at 0x4f0aa0 code=eedfade flags=1
trace:seh:call_stack_handlers handler at 0x4f0aa0 returned 1
trace:seh:call_stack_handlers calling handler at 0x4f0301 code=eedfade flags=1
trace:seh:__regs_RtlUnwind code=eedfade flags=3
trace:seh:__regs_RtlUnwind calling handler at 0x7bc384e0 code=eedfade flags=3
trace:seh:__regs_RtlUnwind handler at 0x7bc384e0 returned 1
trace:seh:__regs_RtlUnwind calling handler at 0x4f0aa0 code=eedfade flags=3
trace:seh:__regs_RtlUnwind handler at 0x400064e8 returned 1
Comment 28 Александр Морозов 2008-10-09 19:38:09 MSD
Поэкспериментировал с функциями IoRegisterDeviceInterface и IoSetDeviceInterfaceState. Узнал, какие ключи реестра создаются в Windows XP при их использовании.
Comment 29 Александр Морозов 2008-10-10 19:22:17 MSD
Исправил проблему, о которой говорилось в комментарии #1. Теперь не надо менять HKLM\System\CurrentControlSet\Enum\USB\Vid_0a89&Pid_0003\5&6d75465&0&1\ClassGUID. Патч "wineusb: Enumerate USB devices with any GUID.".

Реализовал функцию IoSetDeviceInterfaceState.
Comment 30 Александр Морозов 2008-10-16 19:13:51 MSD
Реализовал IoRegisterDeviceInterface. Теперь нет необходимости импортировать HKLM\System\CurrentControlSet\Control\DeviceClasses из Windows.
Comment 31 Александр Морозов 2008-11-17 19:50:27 MSK
14.11.2008 из Guardant прислали патч, при использовании которого защищённое ключом приложение (Frontol) считает, что ключ есть. Этот патч нельзя использовать в качестве решения проблемы из-за возможных побочных эффектов.

Проблема в том, что в Wine драйвер выполняется в пользовательском адресном пространстве. Загрузка только образа драйвера по адресу выше 0x80000000 проблему не решает, происходит падение DriverEntry. Размещение первого аргумента DriverEntry выше 0x80000000 решает проблему с падением, но проверка ключа завершается неудачно.
Comment 32 Александр Морозов 2008-11-17 19:51:54 MSK
Created attachment 892 [details]
Патч, полученный от компании "Актив"
Comment 33 Александр Морозов 2008-11-18 20:15:11 MSK
Задал вопрос по поводу данной проблемы в wine-devel@winehq.org:
http://www.winehq.org/pipermail/wine-devel/2008-November/070592.html
Comment 34 Александр Морозов 2008-11-19 20:26:56 MSK
В качестве эксперимента сделал патч, при использовании которого образ драйвера 
и стек размещаются выше 0x80000000, память с помощью ExAllocatePool 
выделяется там же. С этим патчем драйвер падает при инициализации. Возможно, причина в том, что вызываемые драйвером функции (экспортируемые ntoskrnl.exe, hal.dll и пр.) также должны располагаться выше 0x80000000.
Comment 35 Александр Морозов 2008-11-20 18:54:17 MSK
Модифицировал экспериментальный патч так, чтобы функции grdusb.sys не могли определить, что адрес вызвавшей их функции меньше 0x80000000. Драйвер падает при обработке IRP_MN_START_DEVICE.
Comment 36 Александр Морозов 2008-11-21 19:50:20 MSK
Принудительная загрузка части модулей по адресам выше 0x80000000 проблему не решает:
PE      81000000-8111e380       Export          grdusb.sys
ELF     90000000-9003c000       Deferred        ntoskrnl<elf>
ELF     90040000-90055000       Deferred        usbd.sys.so
ELF     90060000-90075000       Deferred        wineusbhub<elf>
ELF     90100000-90116000       Deferred        winedevice<elf>

Решил менять границы адресного пространства для процесса winedevice.exe. Имеются проблемы с загрузкой модулей. Надо чтобы они гарантированно загружались выше 0x81000000 (адреса 0x80000000 - 0x80ffffff используются для globally shared heap).
Comment 37 Александр Морозов 2008-11-24 18:18:29 MSK
Проблема с загрузкой модулей решена с помощью более ранней установки user_space_limit и working_set_limit.
Comment 38 Александр Морозов 2008-11-24 19:07:23 MSK
Закоммитил драйвер ключа в cvs wine-etersoft.
Отправил в wine-patches@lists.etersoft.ru:
ntoskrnl.exe: Implement IoAllocateMdl and IoFreeMdl.
include: Add LOCK_OPERATION definition.
ntoskrnl.exe: Add stubs for MmProbeAndLockPages and MmUnlockPages.
ntoskrnl.exe: Add stubs for MmMapLockedPages and MmUnmapLockedPages.
ntoskrnl.exe: Implement MmMapLockedPages.
Implement IoRegisterDeviceInterface and IoSetDeviceInterfaceState.
Use addresses 81000000 - 84ff0000 for winedevice.exe.
ntoskrnl.exe: Return FALSE in IoIsWdmVersionAvailable (eterbug #2158).
Add registry file for Guardant Stealth/Net II USB key support.
Add udev rule for Guardant Stealth/Net II.
Comment 39 Александр Морозов 2008-11-24 19:13:05 MSK
*** Bug 54 has been marked as a duplicate of this bug. ***
Comment 40 Ferdik 2013-05-14 18:27:35 MSK
(В ответ на comment #36)
> Принудительная загрузка части модулей по адресам выше 0x80000000 проблему не
> решает:
> PE      81000000-8111e380       Export          grdusb.sys
> ELF     90000000-9003c000       Deferred        ntoskrnl<elf>
> ELF     90040000-90055000       Deferred        usbd.sys.so
> ELF     90060000-90075000       Deferred        wineusbhub<elf>
> ELF     90100000-90116000       Deferred        winedevice<elf>
> 
> Решил менять границы адресного пространства для процесса winedevice.exe.
> Имеются проблемы с загрузкой модулей. Надо чтобы они гарантированно загружались
> выше 0x81000000 (адреса 0x80000000 - 0x80ffffff используются для globally
> shared heap).

(В ответ на comment #6)
> Второй вызов DeviceIoControl завершается с ошибкой. Скорее всего она вызвана
> тем, что не реализован IoAllocateMdl (всегда возвращает NULL).
> 
> trace:vxd:DeviceIoControl
> (0x144,e1b10014,0x323e2c,22848,0x323e2c,22848,0x31d184,(nil))
> trace:ntoskrnl:process_ioctl ioctl e1b10014 device 0x116590 in_size 22848
> out_size 22848
> trace:ntoskrnl:IoAllocateIrp 2, 0
> trace:ntoskrnl:ExAllocatePoolWithTag 184 pool 0 -> 0x111570
> trace:ntoskrnl:IoInitializeIrp 0x111570, 184, 2
> trace:ntoskrnl:ExAllocatePoolWithTag 22848 pool 0 -> 0x121a18
> trace:ntoskrnl:ExAllocatePoolWithTag 64 pool 0 -> 0x1111c0
> trace:ntoskrnl:ExAllocatePoolWithTag 8192 pool 0 -> 0x111630
> trace:ntoskrnl:ExAllocatePoolWithTag 12300 pool 0 -> 0x127360
> trace:ntoskrnl:ExAllocatePoolWithTag 4248 pool 0 -> 0x113638
> trace:ntoskrnl:ExFreePoolWithTag 0x113638
> fixme:ntoskrnl:IoAllocateMdl stub: 0x471bce, 303783, 0, 0, (nil)
> trace:ntoskrnl:ExAllocatePoolWithTag 4248 pool 0 -> 0x113638
> trace:ntoskrnl:ExFreePoolWithTag 0x113638
> trace:ntoskrnl:__regs_IofCompleteRequest 0x111570 0
> trace:ntoskrnl:ExFreePoolWithTag 0x1111c0
> trace:ntoskrnl:ExFreePoolWithTag 0x111630
> trace:ntoskrnl:ExFreePoolWithTag 0x127360
> trace:ntoskrnl:IoFreeIrp 0x111570
> trace:ntoskrnl:ExFreePoolWithTag 0x111570
> trace:ntoskrnl:ExFreePoolWithTag 0x121a18
> trace:vxd:DeviceIoControl status 0xc0000017, returning 0x0
> 
> 0xC0000017 - это STATUS_NO_MEMORY

(В ответ на comment #39)
> *** Задача 54 признана повтором этой задачи. ***

(В ответ на comment #14)
> При запуске FRONTOL.exe после открытия файла \\.\GRDKEY для него 2 раза
> вызывается DeviceIoContol (с разными кодами IOCTL). Написал тестовую программу,
> делающую тоже самое. Единственное отличие: во входном буфере, используемом при
> втором вызове, мусор.
> 
> Вывод под Windows XP:
> IOCTL_1: error 0, 64 bytes
> IOCTL_2: error 87, 64 bytes
> 
> Вывод под Wine:
> IOCTL_1: error 0, 64 bytes
> IOCTL_2: error 87, 1 bytes
> 
> Здесь error - код, возвращаемый GetLastError. bytes - число байт, записанных в
> выходной буфер.
> 
> Под Wine после обработки второго вызова IOCTL в irp->IoStatus.Information
> помещается 0. Непонятно, откуда берётся "1 bytes".

(В ответ на comment #7)
> > После выполнения обработчика IRP_MN_START_DEVICE
> > меняются регистры EBP и ESP. Если
> > восстанавливать EBP после его выполнения, то
> > падения не происходит.
> 
> Не EBP, а EBX

(В ответ на comment #3)
> Поэкспериментировал с FRONTOL. В результате запуска FRONTOL.exe происходит
> обращение к \\.\GRDKEY, создаваемому grdkey.sys. По-видимому, для работы
> USB-ключа необходим не только grdusb.sys, но и grdkey.sys.
> 
> grdkey.sys содержит функцию AddDevice. Для её вызова в Wine надо, видимо,
> реализовать вызов AddDevice для драйверов устройств, описываемых в
> HKLM\SYSTEM\CurrentControlSet\Enum\Root. Пока что AddDevice вызывается wineusb
> только для USB-устройств.
> 
> Сделал хак, вызывающий AddDevice при загрузке grdkey.sys. После добавления
> необходимых стабов загружающий grdkey.sys winedevice падает, судя по всему, при
> выходе из AddDevice.

(В ответ на comment #0)
> Ключ используется "ЛIГА:ЗАКОН Головний бухгалтер".
> 
> При загрузке драйвера ключа grdusb.sys происходит обращение к нереализованной
> функции:
> wine: Call from 0x7b83fda0 to unimplemented function
> hal.dll.ExAcquireFastMutex, aborting

(В ответ на comment #0)
> Ключ используется "ЛIГА:ЗАКОН Головний бухгалтер".
> 
> При загрузке драйвера ключа grdusb.sys происходит обращение к нереализованной
> функции:
> wine: Call from 0x7b83fda0 to unimplemented function
> hal.dll.ExAcquireFastMutex, aborting

(В ответ на comment #0)
> Ключ используется "ЛIГА:ЗАКОН Головний бухгалтер".
> 
> При загрузке драйвера ключа grdusb.sys происходит обращение к нереализованной
> функции:
> wine: Call from 0x7b83fda0 to unimplemented function
> hal.dll.ExAcquireFastMutex, aborting

(В ответ на comment #0)
> Ключ используется "ЛIГА:ЗАКОН Головний бухгалтер".
> 
> При загрузке драйвера ключа grdusb.sys происходит обращение к нереализованной
> функции:
> wine: Call from 0x7b83fda0 to unimplemented function
> hal.dll.ExAcquireFastMutex, aborting

(В ответ на comment #1)
> Если добавить стабы для ExAcquireFastMutex и ExReleaseFastMutex, то DriverEntry
> (функция драйвера, вызываемая в начале его загрузки) выполняется без падений.
> 
> Для того, чтобы происходил вызов AddDevice, необходимо присвоить
> HKLM\System\CurrentControlSet\Enum\USB\Vid_0a89&Pid_0003\5&6d75465&0&1\ClassGUID
> значение "{36FC9E60-C465-11CF-8056-444553540000}".
> 
> Кроме того я столкнулся с тем, что при импорте reg-файлов из Windows значения
> параметров с типом REG_MULTI_SZ отображаются в виде знаков вопроса (вроде бы
> раньше всё работало).
> HKLM\System\CurrentControlSet\Enum\USB\Vid_0a89&Pid_0003\5&6d75465&0&1\HardwareID,
> отображающийся подобным образом, пришлось заменить на строку
> "USB\Vid_0a89&Pid_0003", без этого AddDevice не вызывался.
> 
> В настоящее время AddDevice падает из-за вызова нереализованных функций.

(В ответ на comment #4)
> Падение происходит не при выходе из AddDevice, а после возврата из обработчика
> IRP_MN_START_DEVICE

(В ответ на comment #2)
> После добавления некоторого количества стабов и небольшого изменения wineusbhub
> драйвер загружается без падений. Есть небольшая проблема: обработка
> IRP_MN_QUERY_CAPABILITIES завершается с ошибкой. Скорее всего, это не критично
> для работы с ключом. Для того, что бы проверить, работает ли он, надо
> установить под Wine "ЛIГА:ЗАКОН Головний бухгалтер".

(В ответ на comment #6)
> Второй вызов DeviceIoControl завершается с ошибкой. Скорее всего она вызвана
> тем, что не реализован IoAllocateMdl (всегда возвращает NULL).
> 
> trace:vxd:DeviceIoControl
> (0x144,e1b10014,0x323e2c,22848,0x323e2c,22848,0x31d184,(nil))
> trace:ntoskrnl:process_ioctl ioctl e1b10014 device 0x116590 in_size 22848
> out_size 22848
> trace:ntoskrnl:IoAllocateIrp 2, 0
> trace:ntoskrnl:ExAllocatePoolWithTag 184 pool 0 -> 0x111570
> trace:ntoskrnl:IoInitializeIrp 0x111570, 184, 2
> trace:ntoskrnl:ExAllocatePoolWithTag 22848 pool 0 -> 0x121a18
> trace:ntoskrnl:ExAllocatePoolWithTag 64 pool 0 -> 0x1111c0
> trace:ntoskrnl:ExAllocatePoolWithTag 8192 pool 0 -> 0x111630
> trace:ntoskrnl:ExAllocatePoolWithTag 12300 pool 0 -> 0x127360
> trace:ntoskrnl:ExAllocatePoolWithTag 4248 pool 0 -> 0x113638
> trace:ntoskrnl:ExFreePoolWithTag 0x113638
> fixme:ntoskrnl:IoAllocateMdl stub: 0x471bce, 303783, 0, 0, (nil)
> trace:ntoskrnl:ExAllocatePoolWithTag 4248 pool 0 -> 0x113638
> trace:ntoskrnl:ExFreePoolWithTag 0x113638
> trace:ntoskrnl:__regs_IofCompleteRequest 0x111570 0
> trace:ntoskrnl:ExFreePoolWithTag 0x1111c0
> trace:ntoskrnl:ExFreePoolWithTag 0x111630
> trace:ntoskrnl:ExFreePoolWithTag 0x127360
> trace:ntoskrnl:IoFreeIrp 0x111570
> trace:ntoskrnl:ExFreePoolWithTag 0x111570
> trace:ntoskrnl:ExFreePoolWithTag 0x121a18
> trace:vxd:DeviceIoControl status 0xc0000017, returning 0x0
> 
> 0xC0000017 - это STATUS_NO_MEMORY

(В ответ на comment #21)
> FRONTOL.exe заработал после того, как я во FrontolIni.exe выставил автозапуск
> при старте в качестве приложения, номер ПК 1 и перезагрузился. Если выйти из
> запущенного при загрузке Frontol`а, то снова его запустить получается далеко не
> с первого раза.
> 
> FRONTOL.exe можно запустить на WinXP с тестовым драйвером вместо grdkey.sys.
> Видимо, роль grdkey.sys невелика и основную работу выполняет grdusb.sys.
> 
> В логах, получаемых при запуске FRONTOL.exe, есть следующие строчки:
> trace:reg:NtOpenKey
> (0x38,L"System\\CurrentControlSet\\Control\\DeviceClasses",20019,0x31de44)
> trace:reg:NtOpenKey <- (nil)
> 
> После импорта "System\CurrentControlSet\Control\DeviceClasses" из WinXP
> получаем:
> warn:file:CreateFileW Unable to create file
> L"\\\\?\\USB#VID_0A89&PID_0003#5&6D75465&0&1#{46B89760-C784-11D4-81A8-0080AD87AF5C}"
> (status c0000034)
> 
> Под WinXP этот файл успешно открывается.