![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Принцип сортировки NTFS_RECORD - ов в MFT.
Riply © (2007-06-23 07:06:00)Здравствуйте !
Уже почти целый день бьюсь и никак не могу понять:
по какому принципу отсортированы записи в MFT :(
В общем случае, задача звучит так: по имени файла определить "номер записи в MFT".
Если постараться, то, вроде, ее можно свести к
"написанию" функции сравнения двух записей в MFT:
function Ntfs_RecordCompare(const pRec1, pRec2: PFILE_RECORD_HEADER): integer;
При помощи "метода научного тыка", можно сделать (ну очень шаткое) предположение,
что результат этой функции зависит от следующих параметров FILE_RECORD_HEADER:
Ntfs.Usn: Int64;
// The Update Sequence Number of the NTFS record.
Flags: USHORT;
// A bit array of flags specifying properties of the MFT entry.
// The values defined include: 0x0001 = InUse, 0x0002 = Directory
BytesInUse: ULONG;
// The number of bytes used by the MFT entry.
Сюда же надо добавить параметры из FILENAME_ATTRIBUTE
DirectoryFileReferenceNumber: ULONGLONG;
// The file reference number of the directory in which the filename is entered.
NameType: UCHAR;
//The type of the name.A type of zero indicates an ordinary name, a type of one indicates
//a long name corresponding to a short name, and a type of two indicates a short
//name corresponding to a long name.
А также, от того является ли данная запись, записью "системного файла" или нет.
То что зависит от NameType, у меня вообще в голове не укладывается.
Остальные, хоть как-то да можно объяснить( с натяжкой) :)
P.S. Что-то я совсем запуталась :(
Игорь Шевченко (2007-07-04 10:42:00) [1]Riply © (04.07.07 06:47) [39]
Саша, ты читать умеешь ? :)
Нету у меня (например) таких файлов, которые отсутствуют в \Delphi\Source\
Ни одного. Ты их аккуратно выкладываешь в тот же архив (zip, разумеется), где твой проект живет.
SLoW.AlfaMoon.Com (2007-07-04 10:13:00) [2]Riply © (04.07.07 06:47) [39]
Это не стандартные модули, но у меня например частично есть. Хотя вот эти - HsNtDef, NtPEB - вызывают некоторые подозрения по поводу включенности их в ntdll
Riply (2007-07-04 06:50:00) [3]> [39] Riply © (04.07.07 06:47)
"соберке" - читать: сборке :)
Riply (2007-07-04 06:47:00) [4]>[33] Игорь Шевченко © (03.07.07 09:47)
>С ошибкой выравнивания ?
Была предпринята последняя отчаянная попытка разобраться где и какую стуктуру
я "не так" выравниваю, которая закончилась тем, что прокляла
"тот день, когда я, впервые, села за баранку этого пылесоса" :)
(с)(Кавказкая пленница)
Пришлось приступить к соберке проекта, "чтобы его можно было откомпилировать и запустить"
>[37] Игорь Шевченко © (03.07.07 15:28)
>Считай, что у того, кто будет компилировать проект,
>есть только стандартные из Delphi юниты - не скупись на файлы
А "у того, кто будет компилировать проект", есть такие файлы как:
HsNtDef, NtPEB, NtStatus и NtDLL ? :)
xShadow (2007-07-03 15:45:00) [5]
> Riply ©
Когда человек реально хочет помощи, то выкладывает исходники, тут каждый по разу посмотрит что-то подправит. Десять голов лучше одной :)
З.Ы. Все когда начинали ;)
Игорь Шевченко (2007-07-03 15:28:00) [6]
> Уж очень много "Common_Unit - ов" у меня задействовано.
> "И не сосчитаешь" :)
Считай, что у того, кто будет компилировать проект, есть только стандартные из Delphi юниты - не скупись на файлы
Игорь Шевченко (2007-07-03 15:26:00) [7]
> На это потребуется время.
Я не тороплюсь :)
> Обязательно воспользуюсь, хотя и это и не очень удобно:
Нормально.
Riply (2007-07-03 15:12:00) [8]> [33] Игорь Шевченко © (03.07.07 09:47)
>Ты, если хочешь нормальной помощи
"Тык, кто ж ее не хочет ?" :) (с) "Формула любви"
>собери проект, чтобы его можно было откомпилировать и запустить.
На это потребуется время.
Уж очень много "Common_Unit - ов" у меня задействовано. "И не сосчитаешь" :)
>да и выложи куда, а то и на мыло брось. Мыло вроде знаешь
Выкладывать стыдно: не доросла еще, а вот e-mail сохранился.
P.S.
Большое спасибо, за предложение.
Обязательно воспользуюсь, хотя и это и не очень удобно:
затаскивать Вас в те дебри, в которые Вы мне и соваться не советовали :)
SLoW.AlfaMoon.Com (2007-07-03 11:58:00) [9]собери проект, чтобы его можно было откомпилировать и запустить, да и выложи куда
+1
Игорь Шевченко (2007-07-03 09:47:00) [10]Riply © (02.07.07 23:02) [32]
> С чем это может быть связано ?
С ошибкой выравнивания ?
Ты, если хочешь нормальной помощи, собери проект, чтобы его можно было откомпилировать и запустить, да и выложи куда, а то и на мыло брось. Мыло вроде знаешь
Riply (2007-07-02 23:02:00) [11]Вроде, нашла область, где, возможно, происходит искажение данных.
Имя из FILENAME_ATTRIBUTE, я вытаскиваю следующим образом:
FILENAME_ATTRIBUTE = packed record
.....
NameLength: UCHAR;
NameType: UCHAR; // 0x01 = Long, 0x02 = Short
Name: array[0..0] of WideChar;
function _ExstactName: string;
end;
function FILENAME_ATTRIBUTE._ExstactName: string;
begin
if NameLength > 0
then Result := WideCharLenToString(PWideChar(@Name), NameLength)
else Result := '';
end;
Некоторые из них получаются вот в таком виде (с нечитаемыми символами):
D:\ATI\atidesk\FACCES\x13.DLL
D:\Dissertation Kraft\Off_Docs\Вы\x12иска НТС.doc
D:\FdlNew\Dual files\Du\x11l69a.int
D:\FdlNew\INP Files\defaul\x10.inp
D:\Mathematics\Color\CiteSeDr\liu93multiresolution.p\x10f
D:\Mathematics\Numerical Methods\LS\x10DEMO.PAS
D:\Mathematics\Numerical Methods\SAMPLE6D.D\x10T
D:\Mathematics\Numerical Methods\SA\x10PLE3F.DAT
D:\Text\Electronical report 2005\Primary_Image.\x11mp
С чем это может быть связано ?
Riply (2007-07-02 15:06:00) [12]> [30] Игорь Шевченко © (02.07.07 14:28)
>Мы так и будем в допрос партизана играть ?
Нет. не будем :) Просто очень сложно "варварски выдирать код" :)
>А что пишет Неббет про значения полей в записях ? :)
В той статье, что у меня - ничего,
но алгоритм поиска нужного атрибута в FILE_RECORD_HEADER такой же.
Кажется, разбирая DIRECTORY_INDEX, я учитываю не все обстоятельства.
Скорее всего, ошибка закрадывается раньше, при "прыжках" с одного "узла" на другой,
а проявляется при разборе полученных структур.
Попробую еще раз проверить алгоритм,
может смогу более конкретно описать условия ее(ошибки) возникновения.(а может и исправить ее :)
Игорь Шевченко (2007-07-02 14:28:00) [13]А что пишет Неббет про значения полей в записях ? :)
Мы так и будем в допрос партизана играть ?
Riply (2007-07-02 13:38:00) [14]> [28] Игорь Шевченко © (02.07.07 10:06)
>Хотел бы я знать, в какой ситуации pBaseAttr может принять значение nil...
Sorry.
Я чуть-чуть слукавила (все-таки код варварски выдирается из проекта :)
Вот то, что более походит на правду :)
type
PFILE_RECORD_HEADER = ^FILE_RECORD_HEADER;
FILE_RECORD_HEADER = packed record
Ntfs: NTFS_RECORD_HEADER;
//.......
NextAttributeNumber: USHORT;
function pAttr_Base: PATTRIBUTE;
end;
function FILE_RECORD_HEADER.pAttr_Base: PATTRIBUTE;
begin
Result := Pointer(DWord(@Self) + AttributesOffset);
end;
type
PATTRIBUTE = ^ATTRIBUTE;
ATTRIBUTE = record
AttributeType: ATTRIBUTE_TYPE;
//.....
AttributeNumber: USHORT;
function IsValidType: Boolean;
function pNextAttr: PATTRIBUTE;
end;
function ATTRIBUTE.IsValidType: Boolean;
begin
Result := DWord(AttributeType) <> MAXDWORD;
end;
function ATTRIBUTE.pNextAttr: PATTRIBUTE;
begin
if ResidentLength > 0
then Result := PATTRIBUTE(Dword(@Self) + ResidentLength)
else Result := nil;
end;
И наша тестировочная функция приобретает другой вид:
function EnumAttribute(const pFileRec: PFILE_RECORD_HEADER): integer;
var
pBaseAttr: PATTRIBUTE;
begin
Result := 0;
if pFileRec.Flags = 0 then Exit;
pBaseAttr := pAttr_Base;
while (pBaseAttr <> nil) and pBaseAttr.IsValidType do
begin
inc(Result);
pBaseAttr := pBaseAttr.pNextAttr;
end;
end;
Игорь Шевченко (2007-07-02 10:06:00) [15]
> Подскажите, пожалуйста, в чем может быть дело ?
Хотел бы я знать, в какой ситуации pBaseAttr может принять значение nil...
Riply (2007-07-02 00:44:00) [16]Пытаюсь построить MFT дерево, но на некоторых файлах получаю AV.
Вот экстракт проблеммы:
Структура "базовых" атрибутов
type
PATTRIBUTE = ^ATTRIBUTE;
ATTRIBUTE = record
AttributeType: ATTRIBUTE_TYPE;
Length: ULONG;
Nonresident: BOOLEAN;
NameLength: UCHAR;
NameOffset: USHORT;
Flags: USHORT;
AttributeNumber: USHORT;
end;
И тестировочная функция, которая подсчитывает, сколько разных атрибутов в нашей записи:
function EnumAttribute(const pFileRec: PFILE_RECORD_HEADER): integer;
var
pBaseAttr: PATTRIBUTE;
begin
Result := 0;
if pFileRec.Flags = 0 then Exit;
pBaseAttr := PATTRIBUTE(DWord(pFileRec) + pFileRec.AttributesOffset);
while (pBaseAttr <> nil) and (DWord(pBaseAttr.AttributeType) <> MAXDWORD) do
begin
inc(Result);
if pBaseAttr.Length > 0
then pBaseAttr := PATTRIBUTE(Dword(@pBaseAttr) + pBaseAttr.Length)
else Break;
end;
end;
Вылетаем очеь редко ( примерно один файл на 20000 ).
Механизм вылета простой: Неожиданно параметр Length принимает астрономически большое значение.
Ну и, разумеется, по такому смещению нас выбрасывает черти-куда :)
При сканировании всего дерева MFT, раз двадцать это может быть на одном и том же файле.
Потом, вдруг, мы его проходим нормально, но появляется другой :)
Сразу оговорюсь:
Всестальные параметры в норме (в "связанных" структурах тоже), никаких отклонений.
AV - шный файл не испорчен, никем не используется, к всяким "незявным" не относится :)
- обычный txt, pas или jpeg.
ChkDisk - ом проверяла.
Такое впечатление, что он (Length) "законно" может принимать такие значения
и, в этих случаях, их надо трактовать как-то по-другому.
Подскажите, пожалуйста, в чем может быть дело ?
Игорь Шевченко (2007-06-27 12:20:00) [17]Riply © (27.06.07 11:59) [25]
Ты не поняла. Я имею в виду, что если ты создашь каталог с большим количеством файлов, у тебя элемент в MFT может разползтись и жизнь пресной не покажется, если ты собираешься считать количество файлов. В реализации FindFirst/FindNext все эти нюансы учтены (в NtQueryDirectoryFile)
Riply (2007-06-27 11:59:00) [18]> [24] Игорь Шевченко © (27.06.07 09:54)
>Заведи каталог с несколькими десятками тысяч файлов и
>посчитай через MFT, чтобы жизнь не казалась пресной
Попробовала посчитать весь "системный диск":
TimeOut: 1297
Objects Count: 84 974
FilesCount: 78 031
DirCount: 6 927
UnUseFiles: 15
UnUseDir: 1
(TimeOut - в милисекундах)
Причем, перебирается процедурой, написанной не для подсчета.
Т.е. если ее(процедуру) "заточить" именно для этого,
то результаты будут гораздо лучше :)
Так что я, пока еще, в розовых очках, жизнь кажется прекрасной и совсем "не пресной" :)
Игорь Шевченко (2007-06-27 09:54:00) [19]Riply © (26.06.07 22:09) [23]
Заведи каталог с несколькими десятками тысяч файлов и посчитай через MFT, чтобы жизнь не казалась пресной
Riply (2007-06-26 22:09:00) [20]:))
Попутно решаются всякие смешные задачки.
Давным-давно, я интересовалась:
можно ли не пробегая FindFist/FindNext'ом узнать кол-во файлов в диретории,
для отображения в ProgessBar процесса их обработки(не помню какой).
Нужно было установить максимальную позицию.
Тогда мне сказали, что "низяяяя" :)
Через MFT на получение кол-ва директорий и файлов на всем диске уходит 380 ms :)