Форум: "WinAPI";
Текущий архив: 2009.03.15;
Скачать: [xml.tar.bz2];
ВнизКак удалить файл без восстановления Найти похожие ветки
← →
Игорь Шевченко © (2008-03-27 11:51) [80]Riply © (27.03.08 11:47) [79]
> Я напомню из поста [14]
>
> "Я воспроизводила, примерно, такое:
> Создавала файл, например, занимающий восемь кластеров с
> "номерами":
> 0..3, 128...131.
> И после "обычной" записи в него его картинка становилась:
> 0..7.
> Я не утверждаю, что это происходит всегда,
> но в моих тестах это повторилось несколько раз."
Ты забыла указать, у тебя при этом, при "обычной" записи, параллельно кластеры перемещались ? Явно твоим процессом или дефрагментатором.
← →
guav © (2008-03-27 11:55) [81]> [73] clickmaker © (27.03.08 10:37)
> что нельзя так затереть файл, чтобы не было возможности
> восстановить?
Я бы так сказал, что, скорее всего, простая перезапись приведёт к тому, что файл не будет восстановим. Но "скорее всего" может быть недостаточно, тогда затереть гарантировано может быть сложно. Нужно учитывать кучу всего.
Например, если после кода [54] файл сразу удалить, то файл может быть восстановим - запись происходит не сразу, может так получиться, что на момент записи писать будет уже некуда и незачем. Соотвественно того же можно достичь не удаляя файл, а просто чита его через прямой доступ к тому сразу после затирания.
← →
Игорь Шевченко © (2008-03-27 12:00) [82]guav © (27.03.08 11:55) [81]
> Соотвественно того же можно достичь не удаляя файл, а просто
> чита его через прямой доступ к тому сразу после затирания.
>
А можно просто скопировать его перед тем, как затереть :) Возни меньше.
← →
guav © (2008-03-27 12:07) [83]> [82] Игорь Шевченко © (27.03.08 12:00)
Я понимаю что не спортивно. Просто пример, что затереть не так просто :)
Чтобы устранить указаную в [81] проблему, в затиралках используют FILE_FLAG_NO_BUFFERING.
Я самопроизвольное перемещение наблюдал только на сжатых файлах.
← →
Riply © (2008-03-27 12:08) [84]> [80] Игорь Шевченко © (27.03.08 11:51)
> Ты забыла указать, у тебя при этом, при "обычной" записи, параллельно кластеры перемещались ?
> Явно твоим процессом или дефрагментатором.
Тогда я вела запись процедурой, аналогичной WipeFileBySchevchenko,
только не циклом, а буфером размером равным размеру файла.
Дефрагментатор запущен не был.
Насчет пермещающих кластеры процессов ничего сказать не могу.
Моих не было, а вот не мои могли быть
(например, стояли Norton Unerase, DAEMON Tools может еще что. Не помню).
Это те, на кого может пасть подозрение.
Тогда я о других процессах и не думала.
Я полагала, что это может делать только система и никто более,
соответственно не обращала внимания на то, кто еще работает.
← →
clickmaker © (2008-03-27 12:11) [85]
> Чтобы устранить указаную в [81] проблему, в затиралках используют
> FILE_FLAG_NO_BUFFERING
что, он даже после CloseHandle может быть не записан?
← →
guav © (2008-03-27 12:31) [86]> [85] clickmaker © (27.03.08 12:11)
да.
← →
Игорь Шевченко © (2008-03-27 12:59) [87]guav © (27.03.08 12:31) [86]
Чудные дела творятся на свете. Файл после CloseHandle не записывается на диск...
← →
guav © (2008-03-27 13:27) [88]> [87] Игорь Шевченко © (27.03.08 12:59)
Ок, будет пример или опровержение.
← →
Игорь Шевченко © (2008-03-27 14:06) [89]Я к чему - вроде пользуюсь системой тихо, мирно, ожидаю, что будет работать, как написано.
А написано примерно вот так:
"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 14:44) [90]> [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 15:08) [91]А давай после вот этого
WriteFile(file, pBuffer, len, &ret, NULL);
добавим
FlushFileBuffers (file) ?
← →
Игорь Шевченко © (2008-03-27 15:10) [92]
> Как Вы объясните стабильно воспроизводимый вывод
Кстати, об этом Riply писала, когда записывала в файл Hello Dolly, а потом читала по секторам. В начинающих ветка была.
← →
guav © (2008-03-27 15:21) [93]> [91] Игорь Шевченко © (27.03.08 15:08)
Ну так будет выдавать строку "AAAA...".
Но сама по себе CloseFile как в [54] буферы таки не сбрасывает сразу.
← →
Игорь Шевченко © (2008-03-27 15:24) [94]guav © (27.03.08 15:21) [93]
А если DeleteFile не делать ? Конечно надо логику смотреть, я не готов объяснить поведение вот так и сразу.
← →
guav © (2008-03-27 15:26) [95]> [94] Игорь Шевченко © (27.03.08 15:24)
> А если DeleteFile не делать ?
Результат не стабильный тогда, и старые и новые данные могут читаться.
← →
guav © (2008-03-27 15:31) [96]> [95] guav © (27.03.08 15:26)
Если перенести открытие тома в начало и убрать memset(pBuffer, 0, sectorlen), то будут старые чаще чем новые.
← →
Игорь Шевченко © (2008-03-27 16:33) [97]guav © (27.03.08 15:31) [96]
Значит что-то где-то кешируется. Весьма вероятно, что и старые сектора могут браться из кэша при прямом чтении диска, кстате
← →
guav © (2008-03-27 16:55) [98]> [97] Игорь Шевченко © (27.03.08 16:33)
Есть основания утверждать, что кэшируется именно запись.
При DeleteFile данные читаются долго после перезаписи.
FILE_FLAG_NO_BUFFERING или FlushFileBuffers работает.
Без FILE_FLAG_NO_BUFFERING запись кэшируется.
CloseFile этот кэш не сбрасывает.
← →
guav © (2008-03-27 16:58) [99]> [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, а запись/чтение блока с размером некратным размеру сектора число без буфера не получится.
← →
Игорь Шевченко © (2008-03-27 17:09) [100]guav © (27.03.08 16:58) [99]
И все-таки мне интересно, почему нужен DeleteFile.
← →
guav © (2008-03-27 18:47) [101]> [100] Игорь Шевченко © (27.03.08 17:09)
Без DeleteFile тоже работает.
Но буфер с буквами A когда-нибудь будет записан.
А если файл сразу удалить, то буфер с буквами А уже не будет нужен.
"... Скажем, много лет назад существовала программа для Linux, которая заполняла нули в блоки данных перед их освобождением, однако ОС откладывала запись. Позднее ОС замечала, что блок свободен, и вообще не записывала нули на диск. Кроме того, многие программы предполагают, что при записи данных в существующий файл ОС будет использовать те же блоки данных. Однако ОС также может выделить новые блоки данных, и в этом случае содержимое файла останется на диске."
Брайан Кэрриэ, "Криминалистический анализ файловых систем", с 175
← →
Игорь Шевченко © (2008-03-27 20:25) [102]
> Однако ОС также может выделить новые блоки данных, и в этом
> случае содержимое файла останется на диске
Вот этот момент надо бы подкрепить.
← →
Riply © (2008-03-28 11:20) [103]Допустим, система пытается записать на диск и
у нее не получается (например, кластер файла оказался помечен как плохой), а прочитать может.
Как она поступает в таком случае ?
← →
Игорь Шевченко © (2008-03-28 12:51) [104]Riply © (28.03.08 11:20) [103]
> Как она поступает в таком случае ?
в EventLog пишет
Страницы: 1 2 3 вся ветка
Форум: "WinAPI";
Текущий архив: 2009.03.15;
Скачать: [xml.tar.bz2];
Память: 0.66 MB
Время: 0.043 c