Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Принцип сортировки NTFS_RECORD - ов в MFT.


Страницы:   1 2 3

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 :)


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо