Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "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, &sectorSize, &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
2-1230782516
VirusO4eK
2009-01-01 07:01
2009.03.15
Свойство формы visible стандартно стоит false. Это нормально?


15-1231656099
vvrz
2009-01-11 09:41
2009.03.15
Delphi и Windows Mobile


11-1193029359
Robt
2007-10-22 09:02
2009.03.15
ToolBar


15-1231925321
Thor234
2009-01-14 12:28
2009.03.15
D7 and RAD STUDIO 2007


2-1232720314
Виолета с
2009-01-23 17:18
2009.03.15
Лист Бокс





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский