Помощь - Поиск - Пользователи - Календарь
Полная версия: "Хвосты" файлов недоступны
Форум «Всё о Паскале» > Разработка ПО, алгоритмы, общие вопросы > Общие вопросы разработки программ
Neznaika
Записываем 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
Так тебе NTFS и даст писать куда угодно.
Попробуй этот трюк на FAT32 (флешки обычно под ним форматируют), но успеха не гарантирую. Разработчики драйверов файловой системы, тоже не дураки.

Для записи на произвольный кластер, нужно открывать ДИСК и искать кластер, но никак не через файл.
Neznaika
В помощи 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
Содержимое не определено потому, что оно зависит от того, что было до этого записано на том кластере.
WriteFile не сразу пишет на диск - это было бы странно - данные сперва оказываются в файловом буфере операционки. Чтобы самостоятельно сбросить их на диск нужно вызвать FlushFileBuffers(hFile).

По правде говоря, я так и не уяснил для чего вам нужны подобные трюки с файлами.
Neznaika
К сожалению вызов 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
Собственноручно написал подобный код. Здесь включается механизм защиты от мусорных данных: система, при увеличении размера файла, забивает (виртуально) его нулями, конечно, на диске в том кластере наверняка магическая строка остается, но обычными АПИ типа ReadFile уже не обойтись.
volvo
Neznaika, вопрос уже поднимался, в частности - в Королевстве Дельфи: Ответ на вопрос № 43706

Особенно посмотри на первый ответ...
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.