IPB
ЛогинПароль:

 
 Ответить  Открыть новую тему 
> "Хвосты" файлов недоступны, Ошибка в коде
Neznaika
сообщение 24.08.2007 19:51
Сообщение #1


Пионер
**

Группа: Пользователи
Сообщений: 51
Пол: Мужской

Репутация: -  0  +


Записываем 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.');



Этот код не работает. Можно ли что-нибудь сделать, чтобы исправить ошибку???
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
hardcase
сообщение 24.08.2007 20:41
Сообщение #2


code warrior
****

Группа: Пользователи
Сообщений: 484
Пол: Мужской
Реальное имя: Славен

Репутация: -  8  +


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

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

Сообщение отредактировано: hardcase - 24.08.2007 20:43


--------------------
ИзВ ин ИтЕ зА нЕ рОв НЫй П оч ЕРк
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Neznaika
сообщение 24.08.2007 22:20
Сообщение #3


Пионер
**

Группа: Пользователи
Сообщений: 51
Пол: Мужской

Репутация: -  0  +


В помощи 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).

Сообщение отредактировано: Neznaika - 24.08.2007 22:27
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
hardcase
сообщение 25.08.2007 0:24
Сообщение #4


code warrior
****

Группа: Пользователи
Сообщений: 484
Пол: Мужской
Реальное имя: Славен

Репутация: -  8  +


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

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

Сообщение отредактировано: hardcase - 25.08.2007 0:25


--------------------
ИзВ ин ИтЕ зА нЕ рОв НЫй П оч ЕРк
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
Neznaika
сообщение 25.08.2007 10:15
Сообщение #5


Пионер
**

Группа: Пользователи
Сообщений: 51
Пол: Мужской

Репутация: -  0  +


К сожалению вызов 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.
Эти трюки можно было бы использовать для защиты файла от копирования.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
hardcase
сообщение 25.08.2007 15:20
Сообщение #6


code warrior
****

Группа: Пользователи
Сообщений: 484
Пол: Мужской
Реальное имя: Славен

Репутация: -  8  +


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


--------------------
ИзВ ин ИтЕ зА нЕ рОв НЫй П оч ЕРк
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
volvo
сообщение 25.08.2007 15:50
Сообщение #7


Гость






Neznaika, вопрос уже поднимался, в частности - в Королевстве Дельфи: Ответ на вопрос № 43706

Особенно посмотри на первый ответ...
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 19.04.2024 18:07
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"