Pull to refresh

Comments 1

В процессе работы столкнулся с одним багом. Вернее, даже не багом, а побочным эффектом использования IStream* вместо имён файлов. Началось всё с того, что я заметил, что иногда архив не записывается в поток. Дальнейшее расследование показало, что после вызова FCIFlushCabinet управление магическим образом продолжается дальше не по шагам, даже когда жмёшь F10.
Суть проблемы в том, что FCI/FDI трактует имена файлов, которые мы ему передаём, как нуль-терминированные строки. Эти строки он копирует, и копирует, как можно догадаться, до завершающего \0. Когда в значении интерфейсного указателя проскакивал нулевой байт (за исключением старшего, потому что он оказывается в конце строки), программа сбоила, потому что скопированное «имя файла» было уже не то. Выглядело это примерно так: 0x07be0020, что в памяти будет представлено как 20 00 be 07. Следовательно, когда FCI/FDI копирует эту строку, в буфер попадает 20 00 +какой-то мусор, т.е. в результате получалось что-то типа 20 00 de ad → 0xadde0020, а это уже совершенно не то; поэтому выполнение FCIFlushCabinet и прерывалось.
Т.к. прямого влияния на генерацию значений IStream* я оказать не мог, пришлось идти окольными путями — например, создавать временный объект в хранилище (ему как раз присваивался указатель с нулевым байтом), снова получать указатель на нужный поток, и затем уничтожать временный объект. Пока что этот способ работает, но ясное дело, что его работоспособность — 99.9%, поэтому, если есть какие-то другие варианты изменения получаемых IStream*, с радостью о них узнаю :)

Кстати, исходный описанных выше функций можно скачать тут. Не забудьте подключить Cabinet.lib, а также ShLWAPI.lib, и модифицируйте fnNotify под свои нужды.
Sign up to leave a comment.

Articles