Прямая запись на диск
От: duke89 Россия  
Дата: 01.02.04 11:25
Оценка: 3 (1)
Привет всем! Должна моя программа записывать на диск NTFS пару чисел, причем так, чтобы ничего на нем не поломать и чтоб эта информация сохранилась на диске не один день, а вечно(ну или пока диск не отформатируют). Мне посоветовали прочитать вначале MFT, узнать какой сетор еще пустой, записать в этот сектор мои числа и записть в MFT, что сектор типа уже занят, чтоб Виндоуз не записал на следующий день в мой сектор что-нибудь другое. Просто запсывать в сектор и читать из него с помощью АПИ я умею(кстати пишу я прогу на Дельфе), а вот как читать и записывать в MFT — не знаю. Может поможете?
Re: Прямая запись на диск
От: MShura  
Дата: 03.02.04 09:45
Оценка: 4 (1)
Здравствуйте, duke89, Вы писали:

D>Привет всем! Должна моя программа записывать на диск NTFS пару чисел, причем так, чтобы ничего на нем не поломать и чтоб эта информация сохранилась на диске не один день, а вечно(ну или пока диск не отформатируют). Мне посоветовали прочитать вначале MFT, узнать какой сетор еще пустой, записать в этот сектор мои числа и записть в MFT, что сектор типа уже занят, чтоб Виндоуз не записал на следующий день в мой сектор что-нибудь другое. Просто запсывать в сектор и читать из него с помощью АПИ я умею(кстати пишу я прогу на Дельфе), а вот как читать и записывать в MFT — не знаю. Может поможете?


Вообще-то это очень непростая тема.
То что тебе советовали верно только в самых общих чертах.
Поскольку если твой кластер не оформить как файл, то первый же вызов chkdsk пометит твой кластер как free.
Самый простой выход — писать в именованный поток какого-нибудь общего файла.
Большинство программ содержимое дополнительных потоков не показывают.
А на NTFS у многих файлов несколько именованных потоков. Тот же Word пользуется этим постоянно.

Даже WIN32 API предоставляет доступ к этим потокам.
Точно не помню, но по моему что-то типа так CreateFile( "C:\\boot.ini:Stream", ... )
Re[2]: Прямая запись на диск
От: Pavel Dvorkin Россия  
Дата: 03.02.04 10:54
Оценка: +1
Привет!

MShura wrote:
>
> Даже WIN32 API предоставляет доступ к этим потокам.
> Точно не помню, но по моему что-то типа так CreateFile( "C:\\boot.ini:Stream", ... )

Все верно, только если файл сотрут, то и информация эта исчезнет. И даже
если его скопируют (обычными средствами), то она скопирована не будет.

--
With best regards,
Pavel Dvorkin
Posted via RSDN NNTP Server 1.7 "Bedlam"
With best regards
Pavel Dvorkin
Re[2]: Прямая запись на диск
От: Вадим Никулин Россия Здесь
Дата: 03.02.04 12:44
Оценка:
Здравствуйте, MShura, Вы писали:

MS>А на NTFS у многих файлов несколько именованных потоков. Тот же Word пользуется этим постоянно.

MS>Даже WIN32 API предоставляет доступ к этим потокам.
MS>Точно не помню, но по моему что-то типа так CreateFile( "C:\\boot.ini:Stream", ... )
Очень интересно, дайте ссылочку (в МСДН или в Веб), где можно прочитать про это.
Re[3]: Прямая запись на диск
От: pjBrain  
Дата: 03.02.04 13:24
Оценка: 4 (1)
ВН>Очень интересно, дайте ссылочку (в МСДН или в Веб), где можно прочитать про это.

Здесь почитать
http://patriot.net/~carvdawg/docs/dark_side.html
А здесь, как реализовать
http://www.sysinternals.com/ntw2k/source/misc.shtml#streams
Re[3]: Прямая запись на диск
От: MShura  
Дата: 03.02.04 13:44
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Привет!


PD>MShura wrote:

>>
>> Даже WIN32 API предоставляет доступ к этим потокам.
>> Точно не помню, но по моему что-то типа так CreateFile( "C:\\boot.ini:Stream", ... )

PD>Все верно, только если файл сотрут, то и информация эта исчезнет. И даже

PD>если его скопируют (обычными средствами), то она скопирована не будет.

Для этого надо воспользоваться каким-нибудь общим файлом (я про это упомянул).
А вообще-то есть еще одно место, где можно хранить своё.
Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0.
Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).
Читаешь данные. Эти данные — исполняемый код загрузчика. Теперь основная задача определить размер кода.
Оставляю эту задачу на твоё усмотрение. Обычно размер этого кода меньше полного размера на несколько секторов.

Соответственно в конец можно писать.

Одна из моих программ так и делает....


В некоторых ситуациях, когда размер кластера больше сектора, может получиться "дырка" размером меньше кластера.
Эта "дырка" находится за пределами адресуемого NTFS пространством, но в пределах FDISK размера.
Т.е. если FDISK размер — N секторов, размер кластера M секторов, на разделе K кластеров, то

дырка здесь:
от K*M + 1 до (N — 2) включительно
N-1 — копия boot.
Re[4]: Прямая запись на диск
От: Аноним  
Дата: 04.02.04 18:05
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Здравствуйте, Pavel Dvorkin, Вы писали:




MS>Для этого надо воспользоваться каким-нибудь общим файлом (я про это упомянул).

MS>А вообще-то есть еще одно место, где можно хранить своё.
MS>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0.
MS>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).
MS>Читаешь данные. Эти данные — исполняемый код загрузчика. Теперь основная задача определить размер кода.
MS>Оставляю эту задачу на твоё усмотрение. Обычно размер этого кода меньше полного размера на несколько секторов.

MS>Соответственно в конец можно писать.


MS>Одна из моих программ так и делает....



Спасибо, буду пробовать. Насколько я понял, надо использовать data.nFileSizeLow. Затем надо поделить nFileSizeLow на 512(кол-во байтов в кластере) и запиать инфу в последний кластер(мне всего надо записать комбинацию из 20 символов, насколько я понял, одного кластера хватит, а последний кластер $boot всегда пустой. Так?

MS>В некоторых ситуациях, когда размер кластера больше сектора, может получиться "дырка" размером меньше кластера.

MS>Эта "дырка" находится за пределами адресуемого NTFS пространством, но в пределах FDISK размера.
MS>Т.е. если FDISK размер — N секторов, размер кластера M секторов, на разделе K кластеров, то

MS>дырка здесь:

MS>от K*M + 1 до (N — 2) включительно
MS>N-1 — копия boot.

Я кажется чего-то не понял. Разве кластер и сектор не одно и то же? (простите за возможно глупые вопросы, я пока новичок в этой области)
Re[5]: Прямая запись на диск
От: duke89 Россия  
Дата: 04.02.04 18:16
Оценка:
Простите меня, предыдущее сообщение — моё.
Re[5]: Прямая запись на диск
От: MShura  
Дата: 04.02.04 18:59
Оценка:
MS>>А вообще-то есть еще одно место, где можно хранить своё.
MS>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0.
MS>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).
MS>>Читаешь данные. Эти данные — исполняемый код загрузчика. Теперь основная задача определить размер кода.
MS>>Оставляю эту задачу на твоё усмотрение. Обычно размер этого кода меньше полного размера на несколько секторов.

MS>>Соответственно в конец можно писать.


MS>>Одна из моих программ так и делает....



А>Спасибо, буду пробовать. Насколько я понял, надо использовать data.nFileSizeLow. Затем надо поделить nFileSizeLow на 512(кол-во байтов в кластере) и запиать инфу в последний кластер(мне всего надо записать комбинацию из 20 символов, насколько я понял, одного кластера хватит, а последний кластер $boot всегда пустой. Так?


Чтобы не было путаницы:
сектор — единица емкости физического диска. Минимальный размер при самом низкоуровневом чтении/записи.
Почти всегда 512 байт.
кластер — логическая единица файловой системы. Измеряется в секторах и на всех известных мне файловых системах
кластер = сектор * 2^N.

Ну конечно надо убедиться сначало, что nFileSizeHigh == 0, затем берем
читаем nFileSizeLow/512 секторов от начала раздела
($Boot единственный файл на NTFS, местоположение данных которого строго фиксировано).
Убеждаемся, что последние 512 байт одни нули.
Пишем туда, что нам надо.
Пишем на диск.

Рекоммендую посмотреть первые ~16 секторов на NTFS с помощью любого DiskEditor.
Например DiskProbe.


MS>>В некоторых ситуациях, когда размер кластера больше сектора, может получиться "дырка" размером меньше кластера.

MS>>Эта "дырка" находится за пределами адресуемого NTFS пространством, но в пределах FDISK размера.
MS>>Т.е. если FDISK размер — N секторов, размер кластера M секторов, на разделе K кластеров, то

MS>>дырка здесь:

MS>>от K*M + 1 до (N — 2) включительно
MS>>N-1 — копия boot.

А>Я кажется чего-то не понял. Разве кластер и сектор не одно и то же? (простите за возможно глупые вопросы, я пока новичок в этой области)


Все файловые системы оперируют внутри себя в терминах кластеров. Это так сказать единица измерения пространства.
Сектор — характеристика жесткого диска.
Re[6]: Прямая запись на диск
От: Вадим Никулин Россия Здесь
Дата: 04.02.04 20:32
Оценка: +1
Здравствуйте, MShura, Вы писали:

MS>Ну конечно надо убедиться сначало, что nFileSizeHigh == 0, затем берем

MS>читаем nFileSizeLow/512 секторов от начала раздела
MS>($Boot единственный файл на NTFS, местоположение данных которого строго фиксировано).
MS>Убеждаемся, что последние 512 байт одни нули.
MS>Пишем туда, что нам надо.
MS>Пишем на диск.

Это, конечно, все очень хорошо, но это — грязный хак. Две таких программы уже не будут корректно работать. ИМХО надо искать какие-то другие способы для решения задачи.
Re[7]: Прямая запись на диск
От: MShura  
Дата: 05.02.04 12:24
Оценка:
Здравствуйте, Вадим Никулин, Вы писали:

ВН>Здравствуйте, MShura, Вы писали:


MS>>Ну конечно надо убедиться сначало, что nFileSizeHigh == 0, затем берем

MS>>читаем nFileSizeLow/512 секторов от начала раздела
MS>>($Boot единственный файл на NTFS, местоположение данных которого строго фиксировано).
MS>>Убеждаемся, что последние 512 байт одни нули.
MS>>Пишем туда, что нам надо.
MS>>Пишем на диск.

ВН>Это, конечно, все очень хорошо, но это — грязный хак. Две таких программы уже не будут корректно работать. ИМХО надо искать какие-то другие способы для решения задачи.


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

Можно вообще написать свою файловую систему, но правда на диске может не быть места, для её размещения.
Более того на (basic) диске очень много небольших (до размера трэка) неиспользуемых мест.
Но вопрос касался NTFS раздела.
Re[6]: Прямая запись на диск
От: duke89 Россия  
Дата: 05.02.04 15:19
Оценка:
Здравствуйте, MShura, Вы писали:

MS>>>А вообще-то есть еще одно место, где можно хранить своё.

MS>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0.
MS>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).



Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.
Re[7]: Прямая запись на диск
От: duke89 Россия  
Дата: 05.02.04 15:57
Оценка:
Здравствуйте, duke89, Вы писали:

D>Здравствуйте, MShura, Вы писали:


MS>>>>А вообще-то есть еще одно место, где можно хранить своё.

MS>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0.
MS>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).



D>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.

Скорее даже другие файлы она находит, но с Boot почему то никак.
Re[8]: Прямая запись на диск
От: duke89 Россия  
Дата: 05.02.04 16:09
Оценка:
Здравствуйте, duke89, Вы писали:

D>Здравствуйте, duke89, Вы писали:


D>>Здравствуйте, MShura, Вы писали:


MS>>>>>А вообще-то есть еще одно место, где можно хранить своё.

MS>>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0.
MS>>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).



D>>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.

D>Скорее даже другие файлы она находит, но с Boot почему то никак.

А $Boot и Boot.ini — это то же самое?
Re[7]: Прямая запись на диск
От: MShura  
Дата: 05.02.04 16:26
Оценка:
Здравствуйте, duke89, Вы писали:

D>Здравствуйте, MShura, Вы писали:


MS>>>>А вообще-то есть еще одно место, где можно хранить своё.

MS>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0.
MS>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).



D>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.


Скачай сорсы
http://www.sysinternals.com/ntw2k/source/ntfsinfo.shtml

Там есть DumpMetaFiles
Re[8]: Прямая запись на диск
От: duke89 Россия  
Дата: 05.02.04 16:42
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Здравствуйте, duke89, Вы писали:


D>>Здравствуйте, MShura, Вы писали:


MS>>>>>А вообще-то есть еще одно место, где можно хранить своё.

MS>>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0.
MS>>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).



D>>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.


MS>Скачай сорсы

MS>http://www.sysinternals.com/ntw2k/source/ntfsinfo.shtml

MS>Там есть DumpMetaFiles


А может быть такое, что нет метафайла $boot? Что тогда делать?
Re[9]: Прямая запись на диск
От: MShura  
Дата: 05.02.04 17:02
Оценка:
Здравствуйте, duke89, Вы писали:

D>Здравствуйте, duke89, Вы писали:


D>>Здравствуйте, duke89, Вы писали:


D>>>Здравствуйте, MShura, Вы писали:


MS>>>>>>А вообще-то есть еще одно место, где можно хранить своё.

MS>>>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0.
MS>>>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).



D>>>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.

D>>Скорее даже другие файлы она находит, но с Boot почему то никак.

D>А $Boot и Boot.ini — это то же самое?


$Boot — мета файл (часть файловой системы), описывающий положение и размер boot кода.
Положение всегда с 0, а размер зависит от версии NTFS и размера кластера.

Boot.ini — это обычный файл, без которого система может спокойно жить.

Руссинович пишет, что FindFirstFile( "C:\\$Boot", &data ) сработает только под NT...
Re[9]: Прямая запись на диск
От: MShura  
Дата: 05.02.04 17:04
Оценка:
Здравствуйте, duke89, Вы писали:

D>Здравствуйте, MShura, Вы писали:


MS>>Здравствуйте, duke89, Вы писали:


D>>>Здравствуйте, MShura, Вы писали:


MS>>>>>>А вообще-то есть еще одно место, где можно хранить своё.

MS>>>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0.
MS>>>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).



D>>>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.


MS>>Скачай сорсы

MS>>http://www.sysinternals.com/ntw2k/source/ntfsinfo.shtml

MS>>Там есть DumpMetaFiles


D>А может быть такое, что нет метафайла $boot? Что тогда делать?

Мета файлы есть всегда, поскольку это часть файловой системы NTFS.


У тебя его утилита показывает DumpMetaFiles?
У меня только под NT показывает, под 2K нет.
файлы $* в NTFS
От: SilverCloud Россия http://rodonist.wordpress.com
Дата: 05.02.04 18:28
Оценка:
По-моему, дело не в функции. Просто доступ к метаданным NTFS из-под администратора был возможен только в версиях NT до Win2K. (На sysinternals была утилитка ntfsinfo, посмотри, если её ещё не убрали.)

Можно попробовать, конечно, под Local System, но это .
В любом случае под простым пользователем работать не будет, и, IMHO, и не должно.

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

В WinAPI имена файлов — это 0-terminated строки, в Native NT API — строки с явно заданной длиной.
Соответственно, файл с именем типа "\0MyCoolFile" должен быть доступен в NT, но недоступен в Win32.
Ещё можно с POSIX-семантикой позаморачиваться.

PS: Если я ошибаюсь, уважаемые гуру меня поправят.
PPS: А вообще, нужно ли такое причинение геммороев? Может, сама задача неправильно поставлена? Сдаётся мне, что права доступа штатными средствами надо разруливать, если ты, конечно, не вирус пишешь
О чём поёт ночная птица?
Re[10]: Прямая запись на диск
От: duke89 Россия  
Дата: 05.02.04 20:23
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Здравствуйте, duke89, Вы писали:


D>>Здравствуйте, MShura, Вы писали:


MS>>>Здравствуйте, duke89, Вы писали:


D>>>>Здравствуйте, MShura, Вы писали:


MS>>>>>>>А вообще-то есть еще одно место, где можно хранить своё.

MS>>>>>>>Речь идет о файле $Boot. Его данные всегда непрерывны и начинаются с кластера 0.
MS>>>>>>>Узнаешь его размер, с помощью FindFirstFile( "C:\\$Boot", &data ).



D>>>>Подскажите пожалуйста, где можно найти пример функции на Дельфи, а то у меня она почему-то не возвращает значения в data и handle =Invalid_handle_value.


MS>>>Скачай сорсы

MS>>>http://www.sysinternals.com/ntw2k/source/ntfsinfo.shtml

MS>>>Там есть DumpMetaFiles


D>>А может быть такое, что нет метафайла $boot? Что тогда делать?

MS>Мета файлы есть всегда, поскольку это часть файловой системы NTFS.


MS>У тебя его утилита показывает DumpMetaFiles?

MS>У меня только под NT показывает, под 2K нет.

В том то и дело, что не показывает. Запускаю я её с правами админа под Win ХР
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.