Низкоуровневое приложение на C ++ завершает работу в Windows Vista / 7, если оно не запущено в режиме совместимости с XP

StackOverflow https://stackoverflow.com/questions/2169092

Вопрос

У меня есть низкоуровневый (например в самом деле низкоуровневый, это в основном все вызовы IOCTL и несколько вызовов API перечисления), который периодически выходит из строя в Windows Vista / 7 на компьютерах клиентов.К сожалению, мне не удалось получить никаких аварийных дампов, но один полезный пользователь упомянул, что запуск программы в режиме совместимости с XP решил проблему.

Приложение всегда запускается с полными правами администратора (оно запускается из другой программы, для которой требуется авторизация администратора), так что это не проблема UAC.Я не использую никаких устаревших API, не полагаюсь на какие-либо взломы реестра и т.д.Я просто выполняю вызовы для перечисления дисков, затем использую команды IOCTL, чтобы получить более низкоуровневую информацию обо всех подключенных устройствах.

Что происходит в режиме совместимости с XP?Что Windows вводит в мое приложение или иным образом изолирует его, что предотвращает его сбой в Vista / 7?Изначально я подозревал повреждение кучи (хотя я рвал на себе волосы, пытаясь воспроизвести или отследить проблему), прежде чем мне сказали, что он отлично работает в режиме совместимости с XP.

Кто-нибудь может предложить какие-либо возможные проблемы, которых можно было бы избежать в режиме совместимости XP, которые я должен изучить, чтобы попытаться решить эту проблему?Спасибо!

Редактировать:

Еще одна вещь, о которой, вероятно, очень важно упомянуть:Я вызываю функции DDK / ядра из пользовательского пространства, чтобы получить доступ к определенным функциям, не доступным через WIN32 API.

Я использую ZwReadFile, ZwCreateFile, ZwWriteFile, RtlInitUnicodeString, ZwQueryVolumeInformationFile, ZwDeviceIoControlFile, ZwSetInformationFile, ZwClose.

IOCTLs, которые я вызываю, включают IOCTL_DISK_GET_PARTITION_INFO_EX, IOCTL_STORAGE_GET_DEVICE_NUMBER, IOCTL_DISK_GET_LENGTH_INFO и IOCTL_DISK_GET_DRIVE_LAYOUT_EX.

Это было полезно?

Решение

Это очень странно, но я вызывал ZwQueryVolumeInformationFile с FsInformationClass, установленным в FileFsVolumeInformation .

Я передал в буфер FILE_FS_VOLUME_INFORMATION файл, который сначала обычно выделялся, а затем был перераспределен в (sizeof(FILE_FS_VOLUME_INFORMATION) + sizeof(TCHAR)*FILE_FS_VOLUME_INFORMATION->VolumeLabelLength).

Потом я позвонил FILE_FS_VOLUME_INFORMATION->VolumeLabel[FILE_FS_VOLUME_INFORMATION->VolumeLabelLength/2] = _T('\0'); и только на некоторых машинах это привело бы к повреждению памяти.

Независимо от размера избыточного распределения (даже при попытке выделения дополнительных полных 256 символов!), это надежно привело бы к повреждению кучи даже при использовании vector<unsigned char> в качестве буфера FILE_FS_VOLUME_INFORMATION.

Похоже, что ядро каким-то образом устанавливает какую-то защиту от записи в буфер, что приводило к повреждению независимо от размера.Копирование первых байтов VolumeLableLength во второй буфер, тогда отложенный _T('\0') решил проблему.Не уверен, как / почему Windows создавала буфер, который Я выделяется и передается в качестве параметра только для чтения или если бы это было хранение после структура FILE_FS_VOLUME_INFORMATION (которая следует завершается массивом символов!), но простое отсутствие изменений каких-либо данных в буфере, которые я передал, сделало свое дело....что является безумием, потому что это происходит только (последовательно и на 100% воспроизводимо) на определенных машинах.

Во всяком случае:проблема решена *фух*!

Другие советы

Там было много изменений водителя низкого уровня от XP на Vista. Я подозреваю, что вы используете IOCTL, который пострадал от него.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top