Если в реестре прописать в ветке HKCU\wine\printing\spooler создаем строковое параметр "LPT1:" со значением "/tmp/printer_data.ps", то при печати в LPT1 должно напечататься в /tmp/printer_data.ps, но печатается в lp0. для теста можно использовать wine cmd /c copy windows\\win.ini lpt1
Трейс по +file: trace:file:GetFileAttributesW L"\\\\.\\lpt1" trace:file:RtlDosPathNameToNtPathName_U (L"\\\\.\\lpt1",0x329da0,(nil),(nil)) trace:file:RtlGetFullPathName_U (L"\\\\.\\lpt1" 520 0x329b14 (nil)) trace:file:get_dos_device L"lpt1" -> "/dev/lp0" trace:file:CopyFileW L"C:\\windows\\win.ini" -> L"\\\\.\\lpt1" trace:file:CreateFileW L"C:\\windows\\win.ini" GENERIC_READ FILE_SHARE_READ FILE_SHARE_WRITE creation 3 attributes 0x0 trace:file:RtlDosPathNameToNtPathName_U (L"C:\\windows\\win.ini",0x329d20,(nil),(nil)) trace:file:RtlGetFullPathName_U (L"C:\\windows\\win.ini" 520 0x329a94 (nil)) trace:file:wine_nt_to_unix_file_name L"\\??\\C:\\windows\\win.ini" -> "/net/wine/bottles/peoples/baraka/.wine-test/dosdevices/c:/windows/win.ini" trace:file:CreateFileW returning 0x44 trace:file:CreateFileW L"\\\\.\\lpt1" GENERIC_WRITE FILE_SHARE_READ FILE_SHARE_WRITE creation 2 attributes 0x20 trace:file:RtlDosPathNameToNtPathName_U (L"\\\\.\\lpt1",0x329d20,(nil),(nil)) trace:file:RtlGetFullPathName_U (L"\\\\.\\lpt1" 520 0x329a94 (nil)) trace:file:get_dos_device L"lpt1" -> "/dev/lp0" warn:file:CreateFileW Unable to create file L"\\\\.\\lpt1" (status c0000008) trace:file:CreateFileW returning 0xffffffff warn:file:CopyFileW Unable to open dest L"\\\\.\\lpt1" trace:file:WriteFile 0xc 0x1637d0 16 0x329d68 (nil) Invalid handle
функция get_dos_device для определения устройства принтера вызывает get_default_lpt_device(int num). num -номер lpt порта (берётся исходной строки). Функция отнимает от номера порта единицу x=num-1. И формирует строку "/dev/lp{x}". Данные из реестра не читаются
Там ещё есть чтение ссылки из dosdevices - если она есть, и указывает на файл в системе, используется он. Странно, это же работало раньше, возможно они выкинули / переделали старый механизм.
Возможно этот код находится где-то в другом месте? Если я правильно понимаю, это реализовано в WINAPI DefineDosDeviceW и QueryDosDevice. но из функции get_dos_device они не вызывается. Думаю алгоритм get_default_lpt_device должен быть следующим: 1) Поиск в реестре 2) Поиск в dosdevices 3) ссылка на "/dev/lp{x}"
Ветка HKCU\wine\printing\spooler, упоминаемая в документации действительно используется, но в другом месте. В функции ScheduleJob.
Да, действительно в этом месте поиск идёт впервую очередь в /dosdevices/ И у меня он завершается успешно. Только впоследствие возникаю проблемы с открытием устройства/файла. Если сделать ссылку /dosdevices/lpt2 -> /dev/lp0, то получаем: warn:file:CreateFileW Unable to create file L"\\\\.\\lpt1" (status c0000008) Если сделать ссылку /dosdevices/lpt2 -> file.txt, то CreateFileW без проблем находит файл, но происходит зависание при попытке записи в файл: trace:file:get_dos_device L"lpt2" -> "/home/vitperov/.wine/dosdevices/lpt2" trace:file:WriteFile 0x8 0x165588 21 0x3192f8 (nil) ▐╔Ю╔╖═╞╗А═╜╝ \\.\lpt2trace:file:WriteFile 0x8 0x165588 2 0x3192f8 (nil) (trace:file:WriteFile 0x8 0x165588 1 0x3192f8 (nil) └trace:file:WriteFile 0x8 0x165588 1 0x3192f8 (nil) /trace:file:WriteFile 0x8 0x165588 1 0x3192f8 (nil) █trace:file:WriteFile 0x8 0x165588 2 0x3192f8 (nil) )?trace:file:ReadFile 0x4 0x165588 260 0x319b38 (nil) На функции ReadFile нормального падения устроить не удалось. Похоже, что система пытается работать с файлом, как с устройством
Если отключить трейс, то текст выглядит как вопрос ▐╔Ю╔╖═╞╗А═╜╝ \\.\lpt2 (└/█)? При просмотре в другой кодировке: LANG=ru_RU.ibm866 ww cmd /c copy sample.txt lpt2 err:winedevice:ServiceMain driver L"Hardlock" failed to load Overwrite \\.\lpt2 (Y/N)? При ответе Y файл успешно перезаписывается.
Стек вызовов: =>0 0x7bc372fb wine_nt_to_unix_file_name+0x623(nameW=0x329da0, unix_name_ret=0x329cb0, disposition=1, check_case=0) [/srv/vitperov/Projects/wine-dev/dlls/ntdll/directory.c:1867] in ntdll (0x00329c08) 1 0x7bc3c6e7 NtQueryFullAttributesFile+0x4a(attr=0x329d88, info=0x329ce8) [/srv/vitperov/Projects/wine-dev/dlls/ntdll/file.c:1968] in ntdll (0x00329cc8) 2 0x7bc3c8d0 NtQueryAttributesFile+0x28(attr=0x329d88, info=0x329d60) [/srv/vitperov/Projects/wine-dev/dlls/ntdll/file.c:2016] in ntdll (0x00329d28) 3 0x7b843b1b GetFileAttributesW+0xdd(name=<register EDI not in topmost frame>) [/srv/vitperov/Projects/wine-dev/dlls/kernel32/file.c:2243] in kernel32 (0x00329db8) 4 0x7eee07b1 WCMD_copy+0x2f8() [/srv/vitperov/Projects/wine-dev/programs/cmd/builtins.c:227] in cmd (0x0032f0d8) Запрос на перезапись находится в WCMD_copy, а ей по сути не известно является ли файл обычным или это принтер. Можно попробовать смотреть атрибут FILE_ATTRIBUTE_DEVICE
Проблема в том, что файл имеет только атрибут FILE_ATTRIBUTE_ARCHIVE
попробовал сделать ссылку lpt3 -> /dev/null Файл копируется без запроса перезаписи, но при этом атрибут lpt3 равен INVALID_FILE_ATTRIBUTES, что равносильно тому, что файл не существует. попробовал сделать ссылку lpt4 -> /dev/pts/19 Текст файла действительно копируется на терминал. Но при этом аттрибут файла всё-равно INVALID_FILE_ATTRIBUTES.
Написал тест. Проверил на винде. Там тоже возвращается FILE_ATTRIBUTE_ARCHIVE.
Итог: 1) функция ScheduleJob (параметры которой задаются в реестре) служит для создания задания печати. Для посылки символов в порт принтера она не подойдёт 2) Сейчас всё работает. Если создать ссылку на файл в dosdevices, то печать перенаправляется туда 3) Думаю можно создать ссылку в dosdevices на удалённый принтер. Не проверял. 3) Если отправлять файл коммандой cmd то появляется вполне логичный запрос на перезапись. Багу пока закрываю, потому что не вижу в чём собственно бага.
Принято. 1.0.10 eter11/eter7