Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Общие вопросы разработки программ _ "Хвосты" файлов недоступны

Автор: Neznaika 24.08.2007 23:51

Записываем MAGIC в "хвост" файла FileName:


type
String5 = String[5];
const
MAGIC : String5 = 'Magic';
MAGIC_SIZE = SizeOf(String5);
CLUSTER_SIZE = 4096;
FileName : array[0..12] of Char = 'TestFile.dat'#0;
var
hFile : THandle;
FileSize : DWord;
DW : DWord;
...
hFile := CreateFile(@FileName,GENERIC_READ or GENERIC_WRITE,0,NIL,OPEN_EXISTING,0,0);
FileSize := GetFileSize(hFile,NIL);
if (CLUSTER_SIZE - FileSize mod CLUSTER_SIZE) < MAGIC_SIZE then
begin
Write('"Хвост" файла слишком мал!');
CloseHandle(hFile);
Exit
end;
SetFilePointer(hFile,FileSize,NIL,FILE_BEGIN);
WriteFile(hFile,MAGIC,MAGIC_SIZE,DW,NIL);
SetFilePointer(hFile,FileSize,NIL,FILE_BEGIN);
SetEndOfFile(hFile);
CloseHandle(hFile)



Читаем 6 байт из "хвоста" файла и сравниваем их с MAGIC

var
TestString : String5;
...
hFile := CreateFile(@FileName,GENERIC_READ or GENERIC_WRITE,0,NIL,OPEN_EXISTING,0,0);
FileSize := GetFileSize(hFile,NIL);
if (CLUSTER_SIZE - FileSize mod CLUSTER_SIZE) < MAGIC_SIZE then
begin
Write('"Хвост" файла слишком мал!!');
CloseHandle(hFile);
Exit
end;
{ Читаем "хвост". }
SetFilePointer(hFile,FileSize+MAGIC_SIZE,NIL,FILE_BEGIN);
SetEndOfFile(hFile);
SetFilePointer(hFile,FileSize,NIL,FILE_BEGIN);
ReadFile(hFile,TestString,MAGIC_SIZE,DW,NIL);
{ Возвращаем файлу нормальную длину - усекаем файл. }
SetFilePointer(hFile,FileSize,NIL,FILE_BEGIN);
SetEndOfFile(hFile);
CloseHandle(hFile);
{ Проверяем TestString. }
if TestString <> MAGIC then
WriteLn('Tail <> MAGIC - ERROR!!!')
else
WriteLn('Tail = MAGIC - OK.');



Этот код не работает. Можно ли что-нибудь сделать, чтобы исправить ошибку???

Автор: hardcase 25.08.2007 0:41

Так тебе NTFS и даст писать куда угодно.
Попробуй этот трюк на FAT32 (флешки обычно под ним форматируют), но успеха не гарантирую. Разработчики драйверов файловой системы, тоже не дураки.

Для записи на произвольный кластер, нужно открывать ДИСК и искать кластер, но никак не через файл.

Автор: Neznaika 25.08.2007 2:20

В помощи Win32 Programmer's Reference для SetEndOfFile написано:

Цитата
This function can be used to truncate or extend a file. If the file is extended, the contents of the file between the old EOF position and the new position are not defined.

При увеличении - содержимое неопределено.

Но, если в первом блоке кода написать

...
SetFilePointer(hFile,FileSize,NIL,FILE_BEGIN);
WriteFile(hFile,MAGIC,MAGIC_SIZE,DW,NIL);
SetFilePointer(hFile,FileSize,NIL,FILE_BEGIN);
SetEndOfFile(hFile);
SetFilePointer(hFile,FileSize+MAGIC_SIZE,NIL,FILE_BEGIN);
SetEndOfFile(hFile);



То есть размер файла FileName увеличится на MAGIC_SIZE, но в конце файла будут НУЛИ.
А нули - это вполне определённое содержимое(они затёрли MAGIC, записанное WriteFile).

Автор: hardcase 25.08.2007 4:24

Содержимое не определено потому, что оно зависит от того, что было до этого записано на том кластере.
WriteFile не сразу пишет на диск - это было бы странно - данные сперва оказываются в файловом буфере операционки. Чтобы самостоятельно сбросить их на диск нужно вызвать FlushFileBuffers(hFile).

По правде говоря, я так и не уяснил для чего вам нужны подобные трюки с файлами.

Автор: Neznaika 25.08.2007 14:15

К сожалению вызов FlushFileBuffers(hFile) здесь не помогает


...
SetFilePointer(hFile,FileSize,NIL,FILE_BEGIN);
WriteFile(hFile,MAGIC,MAGIC_SIZE,DW,NIL);
FlushFileBuffers(hFile); { !!! }
SetFilePointer(hFile,FileSize,NIL,FILE_BEGIN);
SetEndOfFile(hFile);
SetFilePointer(hFile,FileSize+MAGIC_SIZE,NIL,FILE_BEGIN);
SetEndOfFile(hFile);


тоже не работает.

P.S.
Эти трюки можно было бы использовать для защиты файла от копирования.

Автор: hardcase 25.08.2007 19:20

Собственноручно написал подобный код. Здесь включается механизм защиты от мусорных данных: система, при увеличении размера файла, забивает (виртуально) его нулями, конечно, на диске в том кластере наверняка магическая строка остается, но обычными АПИ типа ReadFile уже не обойтись.

Автор: volvo 25.08.2007 19:50

Neznaika, вопрос уже поднимался, в частности - в Королевстве Дельфи: http://www.delphikingdom.ru/asp/answer.asp?IDAnswer=43706

Особенно посмотри на первый ответ...