"Прямой доступ" к диску

Тема в разделе "WASM.WIN32", создана пользователем xh4ck, 24 июл 2007.

  1. xh4ck

    xh4ck New Member

    Публикаций:
    0
    Делаю программу работающую по принципу описанному в статье ms-rem'a "3 способа работы с занятыми файлам", используется 3ий способ.

    Там (в статье) описано лишь чтение с диска по определенным адресам, а мне хотелось бы сделать запись.
    Делаю так:

    получаю номера кластеров, которые занимает некоторый файл (FSCTL_GET_RETRIEVAL_POINTERS).
    открываю том на чтение/запись:

    Код (Text):
    1. hVolume = CreateFile(Name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH | FILE_FLAG_RANDOM_ACCESS , 0);
    2. ...
    3.  
    4. // Смещение файла, относительно начала тома
    5. Offset.QuadPart = Clusters[r] * ClusterSize;
    6. Offset.QuadPart += SectorStart;
    7.  
    8. // Читаю что было ДО
    9. SetFilePointerEx(hVolume, Offset, NULL, FILE_BEGIN);
    10. Bytes=0;
    11. ReadFile(hVolume, lpBackupData, ClusterSize, &Bytes, NULL);
    12.  
    13. // Записываю свои данные в файл
    14. SetFilePointerEx(hVolume, Offset, NULL, FILE_BEGIN);
    15. Bytes=0;
    16. WriteFile(hVolume, lpData, ClusterSize, &Bytes, NULL);
    Так вот самые интересности начинаются после того как якобы прошла запись в файл. Повторный вызов ReadFile по тем адресам, где уже прошла запись это подтверждает. НО! на самом деле записи как будто никакой и не происходит. Файл, находящийся на диске - НЕ изменяется.

    Доступ к файлу через обычное открытие CreateFile("...\file.ext"...) / ReadFile - выдает что файл каким был, таким и остался.
    В то же время доступ к файлу через полученную карту кластеров выдает что файл изменен.

    Почему такое происходит?

    P.S. Работаю в NTFS, в FAT32 - и чтение и запись проходят нормально (естественно я учитываю смещения с учетом таблиц FAT в этом случае.)
    P.P.S. переменная Name == "\\\\.\\E:" например
     
  2. n0name

    n0name New Member

    Публикаций:
    0
    кеширование
     
  3. xh4ck

    xh4ck New Member

    Публикаций:
    0
    а как быть с тем что я открываю том с флагом FILE_FLAG_WRITE_THROUGH?

    Если это более низкоуровневое кэширование, то как можно заставить систему записывать изменения на диск?
     
  4. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    FlushFileBuffers
     
  5. slow

    slow New Member

    Публикаций:
    0
  6. gilg

    gilg New Member

    Публикаций:
    0
    FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING
     
  7. xh4ck

    xh4ck New Member

    Публикаций:
    0
    не помогает... ни FlushFileBuffers, ни установка указанных флагов.
    вообще я нашел только один способ сбрасывать кэш на диск это :

    DeviceIoControl(hVolume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &Bytes, NULL);
    DeviceIoControl(hVolume, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &Bytes, NULL);

    "The system flushes all cached data to the volume before locking it. For example, any data held in a lazy-write cache is written to the volume."

    Но, естественно, это очень даже не всегда подходит, потому что занятый том просто никто не даст залочить. Также выяснил что кэш сбрасывается на диск, например, при выходе из системы... а вот как его сбросить вручную.. ?
     
  8. slow

    slow New Member

    Публикаций:
    0
    http://www.wasm.ru/forum/viewtopic.php?id=6794

    --- сюда чти.
     
  9. xh4ck

    xh4ck New Member

    Публикаций:
    0
    ну из юзермоде использовать CcPurgeCacheSection не получится пожалуй =) а тема на том и закрылась...
    думаю из под пользовательского режима я уже делаю все что нужно:

    hVolume = CreateFile(Name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, 0);

    Эквивалент:

    ZwCreateFile(&hVolume, FILE_READ_DATA | FILE_WRITE_DATA | SYNCHRONIZE, &obj, &block, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NO_INTERMEDIATE_BUFFERING | FILE_WRITE_THROUGH, NULL, 0);

    ...

    От топикстартера (Zufyxe) :
    похоже на ринг3 такую вещь не сделать...
     
  10. n0name

    n0name New Member

    Публикаций:
    0
    возможно, где-то сорец на Delphi видел чтения/записи в собственный запущенный файл, как раз через такой метод.
     
  11. slow

    slow New Member

    Публикаций:
    0
    n0name
    там скорее всего изменение прав доступа на хэндл
     
  12. n0name

    n0name New Member

    Публикаций:
    0
    slow
    нет, именно работа через FSCTL_GET_RETRIEVAL_POINTERS
     
  13. xh4ck

    xh4ck New Member

    Публикаций:
    0
    хмм, как бы найти этот исходник =)

    а там точно для записи использовался WriteFile? или всё те же средстства для дефрагментации и перемещения кластеров?
     
  14. slow

    slow New Member

    Публикаций:
    0
    n0name
    хме. мне тогда тоже интересно) надо б поискать
     
  15. slow

    slow New Member

    Публикаций:
    0
    то что нашлось только для FAT
    http://forum.sources.ru/index.php?showtopic=118043&view=old
     
  16. n0name

    n0name New Member

    Публикаций:
    0
    не. Там это было в смецилаьном подфоруме - исходники/кладовка/etc. Где выкладывались свои полезные сорцы. Наткнулся совершенно случайно.
     
  17. slow

    slow New Member

    Публикаций:
    0
    нифига не нашел там :dntknw:

    kladovka.net.ru имеешь в виду?
     
  18. n0name

    n0name New Member

    Публикаций:
    0
    нет, подфорум на форуме был со схожей функцией.
     
  19. slow

    slow New Member

    Публикаций:
    0
    на каком форуме то? DM или sources?
    впрочем не нашел ни там ни там
     
  20. n0name

    n0name New Member

    Публикаций:
    0
    а хз, помнил бы, написал.