На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Обратите внимание:
1. Прежде чем начать новую тему или отправить сообщение, убедитесь, что вы не нарушаете правил форума!
2. Обязательно воспользуйтесь поиском. Возможно, Ваш вопрос уже обсуждали. Полезные ссылки приведены ниже.
3. Темы с просьбой выполнить какую-либо работу за автора в этом разделе не обсуждаются.
4. Используйте теги [ code=cpp ] ...текст программы... [ /code ] для выделения текста программы подсветкой.
5. Помните, здесь телепатов нет. Старайтесь формулировать свой вопрос максимально грамотно и чётко: Как правильно задавать вопросы
6. Запрещено отвечать в темы месячной и более давности без веских на то причин.

Полезные ссылки:
user posted image FAQ Сайта (C++) user posted image FAQ Форума user posted image Наши Исходники user posted image Поиск по Разделу user posted image MSDN Library Online (Windows Driver Kit) user posted image Google

Ваше мнение о модераторах: user posted image B.V.
Модераторы: B.V.
  
> WinAPI. Запись блоков данных в кластеры
    Доброго времени суток. Столкнулся с проблемой, по которой уже неделю ищу информацию. Найти ничего толкового так и не удалось, поэтому пробую написать сюда, может быть здесь кто-то с подобным сталкивался.

    Суть проблемы состоит в том, что существует необходимость записи некоторого буфера данных на жесткий диск напрямую, использую функции WINAPI.

    Открываю том следующим образом.
    ExpandedWrap disabled
      HANDLE hDev = INVALID_HANDLE_VALUE;
      hDev = CreateFile(L"\\\\.\\\D:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
      if (hDev == INVALID_HANDLE_VALUE)
      {
          CloseHandle(hDev);
          free(Path);
          free(R);
          return ERROR_INVALID_HANDLE;
      }

    Далее считываю с тома информацию о количестве байт на сектор и количестве секторов в кластере. Перемножив значение получаю размер кластера = 4096
    Далее с помощью функции получаю список кластеров конкретного файла на диске D:
    И пытаюсь в эти кластеры записать необходимую информацию из переменной Buffer:
    ExpandedWrap disabled
      for (ULONG i = 0; i < ClustersCount; i++)
          if (Clusters[i])
          {
              Offset.QuadPart = ClusterSize * Clusters[i];
              SetFilePointer(hDev, Offset.LowPart, &Offset.HighPart, FILE_BEGIN);
              WriteFile(hDev, Buffer, ClusterSize, &Bytes, (LPOVERLAPPED)NULL);
                      if(Bytes != ClusterSize)
                      {
                          CloseHandle(hDev);
                          return ERROR_ACCESS_DENIED;
                      }
          }

    В результате попытки записи возникает ошибка с кодом 5. Отказано в доступе. Чтение производилось при помощи ReadFile(...); и считалось все удачно.
    Поискав информацию наткнулся на то, что перед записью в кластер нужно демонтировать том при помощи DeviceIoControl(); с управляющим кодом FSCTL_DISMOUNT_VOLUME.
    Но из этого выходить лишь только зависание самой студии и её принудительный перезапуск.
      Могу конечно ошибаться, в пользовательском режиме тебе система не даст напрямую перезаписать системную область, надо это делать в режиме ядра, т.е. в режиме драйвера (своего), к которому ты обращаешься из пользовательского режима.
        Цитата ter_nk_ @
        Могу конечно ошибаться, в пользовательском режиме тебе система не даст напрямую перезаписать системную область, надо это делать в режиме ядра, т.е. в режиме драйвера (своего), к которому ты обращаешься из пользовательского режима.

        Да, возможно это и так, однако, я находил в интернете примеры, где WriteFile в сектор на диске корректно работал. Тем более, что у меня получается перезаписать 1 кластер, а во время записи во второй происходит сбой в студии и она перезапускается.
          Я думаю если диск будет другой, подключенный, проблем не будет. DebugView не пробовал запустить от админа со всеми логами, может что путное скажет?
            Цитата ter_nk_ @
            Я думаю если диск будет другой, подключенный, проблем не будет. DebugView не пробовал запустить от админа со всеми логами, может что путное скажет?

            Нет не пробовал. Даже не знаю, что это такое, сейчас почитаю и, может, правда найду там что-то интересное. Спасибо
              ос какая?

              Добавлено
              запускаешь с админскими правами?
                Цитата shm @
                запускаешь с админскими правами?


                Админские права тут не помогут.
                  Вряд ли это правильно:
                  ExpandedWrap disabled
                    if (hDev == INVALID_HANDLE_VALUE)
                    {
                        CloseHandle(hDev);
                    ...

                  Если так сделать в Линуксе, приложение, скорее всего, рухнет.
                  Виндус такое вытерпит, но всё равно не надо так.
                  Сообщение отредактировано: ЫукпШ -
                    Цитата ter_nk_ @
                    Админские права тут не помогут.

                    Может и не помогут, но без прав не заработает 100%, по крайней мере начиная с Висты.
                      Читаем условия
                      https://msdn.microsoft.com/en-us/library/wi...8(v=vs.85).aspx
                      А здесь продолжения условий.
                      https://support.microsoft.com/en-us/help/94...restrict-direct
                      помимо прочего есть ещё API для дефрагментации диска.

                      Цитата linuxoid @
                      Поискав информацию наткнулся на то, что перед записью в кластер нужно демонтировать том при помощи DeviceIoControl(); с управляющим кодом FSCTL_DISMOUNT_VOLUME.
                      Но из этого выходить лишь только зависание самой студии и её принудительный перезапуск.

                      Венчал надо закрыть все программы которые работают с диском D. А во вторых после размонтирования хэндел уже будет не действительным, поэтому писать через него вы не сможете. После этого Вы должны будете для записи открывать не том, а целиком жёсткий диск.
                      Так как студиа скорее всего параллельно мониторит, то куда вы пишете, то после размонтирования она тоже зависнет так что такой трюк надо проделывать без отладчика.
                      А так как перемонтировать тома может любая программа. То лучше сменить тип файловой системы на RAW. И только после внесения изменений вернуть обратно нужную файловую систему.
                      А так как во время записи вашу программу могут грохнуть то это не хорошо. Так что лучше вначале попробовать залочить том и если это не удасться то пробовать с RAW.
                        Цитата shm @
                        ос какая?

                        Win8. Запускаю с правами администратора

                        Добавлено
                        Цитата ЫукпШ @
                        Вряд ли это правильно:
                        ExpandedWrap disabled
                          if (hDev == INVALID_HANDLE_VALUE)
                          {
                              CloseHandle(hDev);
                          ...

                        Если так сделать в Линуксе, приложение, скорее всего, рухнет.
                        Виндус такое вытерпит, но всё равно не надо так.

                        Да, спасибо что заметили. Понял свою ошибку.

                        Добавлено
                        Цитата Pavia @
                        Читаем условия
                        https://msdn.microsoft.com/en-us/library/wi...8(v=vs.85).aspx
                        А здесь продолжения условий.
                        https://support.microsoft.com/en-us/help/94...restrict-direct
                        помимо прочего есть ещё API для дефрагментации диска.

                        Цитата linuxoid @
                        Поискав информацию наткнулся на то, что перед записью в кластер нужно демонтировать том при помощи DeviceIoControl(); с управляющим кодом FSCTL_DISMOUNT_VOLUME.
                        Но из этого выходить лишь только зависание самой студии и её принудительный перезапуск.

                        Венчал надо закрыть все программы которые работают с диском D. А во вторых после размонтирования хэндел уже будет не действительным, поэтому писать через него вы не сможете. После этого Вы должны будете для записи открывать не том, а целиком жёсткий диск.
                        Так как студиа скорее всего параллельно мониторит, то куда вы пишете, то после размонтирования она тоже зависнет так что такой трюк надо проделывать без отладчика.
                        А так как перемонтировать тома может любая программа. То лучше сменить тип файловой системы на RAW. И только после внесения изменений вернуть обратно нужную файловую систему.
                        А так как во время записи вашу программу могут грохнуть то это не хорошо. Так что лучше вначале попробовать залочить том и если это не удасться то пробовать с RAW.

                        Спасибо за подсказки. Я не думал, что чтение будет простым, а запись такой сложной.
                        Сообщение отредактировано: linuxoid -
                          Может быть кто-нибудь подскажет как можно записать информацию в кластеры другим способом или функцией?
                            Создать загрузочный диск, только вряд ли подойдет.
                              Всем спасибо за помощь. Тема закрыта.
                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0402 ]   [ 17 queries used ]   [ Generated: 29.03.24, 09:06 GMT ]