![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как удалить файл без восстановления [D7]
nikfel © (2008-03-22 11:03:00)Подскажите, пожалуйста. Как удалить файл со всем, чтобы восстановить было нельзя. Заранее спасибо.
Игорь Шевченко (2008-03-28 12:51:00) [1]Riply © (28.03.08 11:20) [103]
> Как она поступает в таком случае ?
в EventLog пишет
Riply (2008-03-28 11:20:00) [2]Допустим, система пытается записать на диск и
у нее не получается (например, кластер файла оказался помечен как плохой), а прочитать может.
Как она поступает в таком случае ?
Игорь Шевченко (2008-03-27 20:25:00) [3]
> Однако ОС также может выделить новые блоки данных, и в этом
> случае содержимое файла останется на диске
Вот этот момент надо бы подкрепить.
guav (2008-03-27 18:47:00) [4]> [100] Игорь Шевченко © (27.03.08 17:09)
Без DeleteFile тоже работает.
Но буфер с буквами A когда-нибудь будет записан.
А если файл сразу удалить, то буфер с буквами А уже не будет нужен.
"... Скажем, много лет назад существовала программа для Linux, которая заполняла нули в блоки данных перед их освобождением, однако ОС откладывала запись. Позднее ОС замечала, что блок свободен, и вообще не записывала нули на диск. Кроме того, многие программы предполагают, что при записи данных в существующий файл ОС будет использовать те же блоки данных. Однако ОС также может выделить новые блоки данных, и в этом случае содержимое файла останется на диске."
Брайан Кэрриэ, "Криминалистический анализ файловых систем", с 175
Игорь Шевченко (2008-03-27 17:09:00) [5]guav © (27.03.08 16:58) [99]
И все-таки мне интересно, почему нужен DeleteFile.
guav (2008-03-27 16:58:00) [6]> [97] Игорь Шевченко © (27.03.08 16:33)
> Весьма вероятно, что и старые сектора могут браться из кэша
> при прямом чтении диска, кстате
При чтении с диска можно указать FILE_FLAG_NO_BUFFERING, на результат не повлияет.
Более того, я не просто так делаю
// Округляем sectorlen вверх до размера сектора
if (sectorlen % sectorSize)
{
sectorlen += sectorSize - sectorlen % sectorSize;
}
Даже без FILE_FLAG_NO_BUFFERING том ведёт себя как с FILE_FLAG_NO_BUFFERING, а запись/чтение блока с размером некратным размеру сектора число без буфера не получится.
guav (2008-03-27 16:55:00) [7]> [97] Игорь Шевченко © (27.03.08 16:33)
Есть основания утверждать, что кэшируется именно запись.
При DeleteFile данные читаются долго после перезаписи.
FILE_FLAG_NO_BUFFERING или FlushFileBuffers работает.
Без FILE_FLAG_NO_BUFFERING запись кэшируется.
CloseFile этот кэш не сбрасывает.
Игорь Шевченко (2008-03-27 16:33:00) [8]guav © (27.03.08 15:31) [96]
Значит что-то где-то кешируется. Весьма вероятно, что и старые сектора могут браться из кэша при прямом чтении диска, кстате
guav (2008-03-27 15:31:00) [9]> [95] guav © (27.03.08 15:26)
Если перенести открытие тома в начало и убрать memset(pBuffer, 0, sectorlen), то будут старые чаще чем новые.
guav (2008-03-27 15:26:00) [10]> [94] Игорь Шевченко © (27.03.08 15:24)
> А если DeleteFile не делать ?
Результат не стабильный тогда, и старые и новые данные могут читаться.
Игорь Шевченко (2008-03-27 15:24:00) [11]guav © (27.03.08 15:21) [93]
А если DeleteFile не делать ? Конечно надо логику смотреть, я не готов объяснить поведение вот так и сразу.
guav (2008-03-27 15:21:00) [12]> [91] Игорь Шевченко © (27.03.08 15:08)
Ну так будет выдавать строку 'AAAA...'.
Но сама по себе CloseFile как в [54] буферы таки не сбрасывает сразу.
Игорь Шевченко (2008-03-27 15:10:00) [13]
> Как Вы объясните стабильно воспроизводимый вывод
Кстати, об этом Riply писала, когда записывала в файл Hello Dolly, а потом читала по секторам. В начинающих ветка была.
Игорь Шевченко (2008-03-27 15:08:00) [14]А давай после вот этого
WriteFile(file, pBuffer, len, &ret, NULL);
добавим
FlushFileBuffers (file) ?
guav (2008-03-27 14:44:00) [15]> [89] Игорь Шевченко © (27.03.08 14:06)
Ок. Как Вы объясните стабильно воспроизводимый вывод старого содержимого файла в этом примере (извините что С, Delphi нету. на FAT не работает, т.к. там из номера кластера смещение не получается простым умножением):
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE file;
DWORD len, sectorlen;
DWORD ret;
BYTE *pBuffer;
STARTING_VCN_INPUT_BUFFER startVcn;
RETRIEVAL_POINTERS_BUFFER rp;
HANDLE volume;
DWORD clusterSize, sectorSize;
DWORD freeClusters, totalClusters;
// Узнаём размеры секотра и кластера.
GetDiskFreeSpace(
_T("D:\\"), &clusterSize, §orSize, &freeClusters, &totalClusters);
// Открываем файл
file = CreateFile(
_T("D:\\placeholders.hpp"),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
0);
// Узнаём первый кластер
startVcn.StartingVcn.QuadPart = 0;
DeviceIoControl(
file,
FSCTL_GET_RETRIEVAL_POINTERS,
&startVcn,
sizeof(startVcn),
&rp,
sizeof(rp),
&ret,
NULL);
// Узнаём размер
sectorlen = len = GetFileSize(file, NULL);
// Округляем sectorlen вверх до размера сектора
if (sectorlen % sectorSize)
{
sectorlen += sectorSize - sectorlen % sectorSize;
}
pBuffer = malloc(sectorlen);
// пишем
memset(pBuffer, 'A', len);
WriteFile(file, pBuffer, len, &ret, NULL);
// закрываем и сразу удаляем (если убрать DeleteFile, может начать выводиться новое содержимое).
CloseHandle(file);
DeleteFile(_T("D:\\placeholders.hpp"));
// Теперь читаем напрямую.
volume = CreateFile(
_T("\\\\.\\D:"),
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
rp.Extents[0].Lcn.QuadPart *= sectorSize * clusterSize;
SetFilePointerEx(volume, rp.Extents[0].Lcn, NULL, FILE_BEGIN);
memset(pBuffer, 0, sectorlen);
ReadFile(volume, pBuffer, sectorlen, &ret, NULL);
CloseHandle(volume);
// тут выводятся старые данные.
puts(pBuffer);
free(pBuffer);
return 0;
}
Игорь Шевченко (2008-03-27 14:06:00) [16]Я к чему - вроде пользуюсь системой тихо, мирно, ожидаю, что будет работать, как написано.
А написано примерно вот так:
"Buffers are normally maintained by the operating system, which determines the optimal time to write the data automatically to disk: when a buffer is full, when a stream is closed, or when a program terminates normally without closing the stream" ( http://msdn2.microsoft.com/en-us/library/9yky46tz.aspx)
Обсуждение вопроса, будут ли буферы сброшены на диск после CloseHandle, прводится здесь:
http://www.tech-archive.net/Archive/VC/microsoft.public.vc.mfc/2007-08/msg00925.html
guav (2008-03-27 13:27:00) [17]> [87] Игорь Шевченко © (27.03.08 12:59)
Ок, будет пример или опровержение.
Игорь Шевченко (2008-03-27 12:59:00) [18]guav © (27.03.08 12:31) [86]
Чудные дела творятся на свете. Файл после CloseHandle не записывается на диск...
guav (2008-03-27 12:31:00) [19]> [85] clickmaker © (27.03.08 12:11)
да.
clickmaker (2008-03-27 12:11:00) [20]
> Чтобы устранить указаную в [81] проблему, в затиралках используют
> FILE_FLAG_NO_BUFFERING
что, он даже после CloseHandle может быть не записан?