Текущий архив: 2008.09.21;
Скачать: CL | DM;
Вниз
Перечисление потоков "файлового объекта". Найти похожие ветки
← →
Riply © (2007-12-07 08:56) [0]Здравствуйте !
NtQueryInformationFile(..., FileStreamInformation)
возвращает не совсем полную информацию:
в структуре FILE_STREAM_INFORMATION нет описания "типа"(или атрибутов) потока.
Дело в том, что объект может иметь несколько потоков без имени, отличающихся "типом".
NtQueryInformationFile их перебирает, но не дает возможности разобраться "ху из ху" :)
"Типы" можно получить, например, читая "вручную" с помощью BackupRead,
но это очень медленно и некузяво. (Ну и разумеется, работая с MFT).
Нет ли аналога NtQueryInformationFile, дающего более полную информацию ?
← →
Kolan © (2007-12-07 08:59) [1]> Здравствуйте !
Только млин хотел ответить: «ждите Riply»… А это она и есть :)
← →
Rouse_ © (2007-12-07 10:06) [2]Неначем проверить, но глянь вот этот код, в доппотоках 2 байта лишних остаются (смотри на Reserved):
procedure TdlgNTFSThread.QueryStreams;
const
STATUS_BUFFER_OVERFLOW = $80000005;
STATUS_INFO_LENGTH_MISMATCH = $C0000004;
var
IoStatusBlock: IO_STATUS_BLOCK;
FileStreamInformation, FileStreamInformationReader: PFileStreamInformation;
FileStreamInformationSize: DWORD;
AResult: NT_STATUS;
Reserved: array of Byte;
ReservedLength: Integer;
ReservedOffset: PByte;
begin
if FileHandle = INVALID_HANDLE_VALUE then Exit;
AResult := STATUS_BUFFER_OVERFLOW;
FileStreamInformationSize := MAXSHORT;
GetMem(FileStreamInformation, FileStreamInformationSize);
repeat
if AResult = STATUS_INFO_LENGTH_MISMATCH then
begin
FileStreamInformationSize := FileStreamInformationSize * 2;
ReallocMem(FileStreamInformation, FileStreamInformationSize);
end;
AResult := NtQueryInformationFile(FileHandle, IoStatusBlock, FileStreamInformation,
FileStreamInformationSize, FILE_STREAM_INFORMATION);
until AResult <> STATUS_INFO_LENGTH_MISMATCH;
try
if (AResult = NO_ERROR) or (AResult = STATUS_BUFFER_OVERFLOW) then
begin
FileStreamInformationReader := FileStreamInformation;
repeat
SetLength(StreamsSize, Length(StreamsSize) + 1);
StreamsSize[Length(StreamsSize) - 1] :=
FileStreamInformationReader^.StreamSize;
lbStreams.Items.Add(
Copy(PWideChar(@FileStreamInformationReader^.StreamName),
1, FileStreamInformationReader^.StreamNameLength div SizeOf(WideChar)));
ReservedLength :=
FileStreamInformationReader^.NextEntryOffset -
((SizeOf(TFileStreamInformation)) +
FileStreamInformationReader^.StreamNameLength);
if ReservedLength > 0 then
begin
ReservedOffset := Pointer(DWORD(FileStreamInformationReader) +
FileStreamInformationReader^.NextEntryOffset - ReservedLength);
SetLength(Reserved, ReservedLength);
Move(ReservedOffset^, Reserved[0], ReservedLength);
end;
FileStreamInformationReader :=
Pointer(DWORD(FileStreamInformationReader) +
FileStreamInformationReader^.NextEntryOffset);
until FileStreamInformationReader^.NextEntryOffset = 0;
end;
finally
FreeMem(FileStreamInformation);
end;
end;
← →
Rouse_ © (2007-12-07 10:10) [3]во тут целиком можешь взять: http://rouse.drkb.ru/tmp/ntfs.zip
← →
Riply © (2007-12-07 10:37) [4]> [3] Rouse_ © (07.12.07 10:10)
> во тут целиком можешь взять: http://rouse.drkb.ru/tmp/ntfs.zip
Спасибо. Правда я уже успела перевести код из [2] Rouse_ © (07.12.07 10:06)
на русский язык. :)
Ну кто же такие имена для переменных берет как FileStreamInformation ?
Это вводит в заблуждение :)
P.S. Очень надеюсь, что эти два байта (про которые ты говоришь) и есть искомое,
но боюсь что это просто выравнивание :(
Сейчас буду тестировать.
О результатах доложу :)
← →
Rouse_ © (2007-12-07 10:43) [5]
> Ну кто же такие имена для переменных берет как FileStreamInformation ?
> Это вводит в заблуждение :)
Нормальные имена :) Я не люблю пользоваться приведениями типа
FILE_STREAM_INFORMATION = FileStreamInformation :)
Незачем сущности плодить :)
← →
Юрий Зотов © (2007-12-07 11:03) [6]Александра, скромность, конечно, человека украшает, но постить подобные темы в "начинающие" - это уже перебор. Не прибавляй работы, плз.
← →
guav © (2007-12-07 11:26) [7]В MSDN написано что типы учтены в имени, т.е. имя потока имеет формат :имя:тип, вроде ::$DATA или :AldData:$DATA или ::$FILE_NAME
Я сам не пробовал вызывать NtQueryInformationFile, но с таким синтаксисом я сталкивался в других функциях, например полный формат имени потока для CreateFile - имяфайла:имяпотока:типпотока.
Кстати, если нужны только сами имена, почему бы не применить FindNextStreamW/FindFirstStream[Transacted]W ?
← →
guav © (2007-12-07 11:33) [8]Стоп. Разве вообще другие типы потоков, кроме $DATA должны возвращатся ?
Про выравнивание - там же в MSDN:
The FILE_STREAM_INFORMATION structure must be aligned on a LONGLONG (8-byte) boundary. If a buffer contains two or more of these structures, the NextEntryOffset value in each entry, except the last, falls on an 8-byte boundary.
← →
Riply © (2007-12-07 12:24) [9]> [5] Rouse_ © (07.12.07 10:43)
> Нормальные имена :) Я не люблю пользоваться приведениями типа
> FILE_STREAM_INFORMATION = FileStreamInformation :)
> Незачем сущности плодить :)
Когда я собственнолапно перевожу структуры, я тоже не "плодю сущности" :)
но если я использую юниты, например, от JWA,
то они там сами уже наплодили выше крыши - ну не затирать же :)
По САБЖУ: Это все-таки выравнивание :(
А жаль. Так бы было здорово. (Может я, конечно, и ошибаюсь. Проверялось не досконально)
> [6] Юрий Зотов © (07.12.07 11:03)
> Александра, скромность, конечно, человека украшает, но постить подобные
> темы в "начинающие" - это уже перебор. Не прибавляй работы, плз.
Sorry. Всю жизнь там (в Начинающих) сидела - привычка. Обещаю исправиться :)
> [7] guav © (07.12.07 11:26)
> В MSDN написано что типы учтены в имени, т.е. имя потока имеет
> формат :имя:тип, вроде ::$DATA или :AldData:$DATA или ::$FILE_NAME
Если я правильно понимаю, то так должно быть (что-то типа правла хорошего тона),
но не является законом. Да и вытаскивать тип из строки: брр...
Гораздо приятнее когда тебе DWord возвращают :)
> Я сам не пробовал вызывать NtQueryInformationFile, но с таким синтаксисом я сталкивался в других функциях,
> например полный формат имени потока для CreateFile - имяфайла:имяпотока:типпотока.
Он с таким же успехом может съесть имя и не в таком формате :)
> Кстати, если нужны только сами имена, почему бы не
> применить FindNextStreamW/FindFirstStream[Transacted]W ?
NtQueryInformationFile - удобнее, быстрее и гибче. (Это мое imho)
Придется слазить в ReactOS, посмотреть что там к чему.
Очень надеюсь, что они работают не через BackupRead.
> [8] guav © (07.12.07 11:33)
> Стоп. Разве вообще другие типы потоков, кроме $DATA должны возвращатся ?
Вроде да. С какой стати - нет ? С ними же тоже надо работать :)
← →
Rouse_ © (2007-12-07 12:43) [10]Выложи куда нибуть такой файлик. Только заархивируй RAR-ом, он умеет файловые потоки тоже сохранять - гляну на досуге.
← →
guav © (2007-12-07 12:49) [11]> Он с таким же успехом может съесть имя и не в таком формате :)
Это понятно. но главное что с полной квалификацией атрибутов тоже "ест".
Причём это можно видеть даже на консольных командах :)
> По САБЖУ: Это все-таки выравнивание :(
> (Может я, конечно, и ошибаюсь. Проверялось не досконально)
В MSDN утверждают что выравнивание, и здесь я думаю стоит им верить.
> Вроде да. С какой стати - нет ? С ними же тоже надо работать :)
А вот в MSDN пишут (смотрю оффлайновый, там где описана структура FILE_STREAM_INFORMATION):The FILE_STREAM_INFORMATION structure is used to enumerate the streams for a file.
Разве другие атрибуты считаются потоками. Впрочем, раз ты уже вызывала эту функцию, вот и скажи, нет ли там имён файлов.
Причём, там же в MSDN упоминается из аттрибутов только $DATA
← →
guav © (2007-12-07 12:53) [12]> Причём это можно видеть даже на консольных командах :)
C:\>more< $Mft::$Zzzz
The parameter is incorrect.
C:\>more< $Mft::$Bitmap
Access is denied.
> > В MSDN написано что типы учтены в имени, т.е. имя потока имеет
> > формат :имя:тип, вроде ::$DATA или :AldData:$DATA или
> ::$FILE_NAME
> Если я правильно понимаю, то так должно быть (что-то типа
> правла хорошего тона),
> но не является законом.
Если я правильно понимаю, то там где оно нужно (ну т.е. на NTFS) оно будет.
← →
Riply © (2007-12-07 12:59) [13]> [10] Rouse_ © (07.12.07 12:43)
> Выложи куда нибуть такой файлик. Только заархивируй RAR-ом,
>он умеет файловые потоки тоже сохранять - гляну на досуге.
Вот здесь: http://slil.ru/25202642
Там такой поток: ObjectIdentifier 64 Byte
Но бывают и другого размера и типа.
← →
Rouse_ © (2007-12-07 13:02) [14]
> Придется слазить в ReactOS, посмотреть что там к чему.
> Очень надеюсь, что они работают не через BackupRead.
В случае FileBasicInformation производится вызов FastIoQueryBasicInfo, во всех остальных случаях через драйвер посредством вызова обработчика завязанного на IRP_MJ_QUERY_INFORMATION
← →
Rouse_ © (2007-12-07 13:06) [15]
> Вот здесь: http://slil.ru/25202642
> Там такой поток: ObjectIdentifier 64 Byte
При архивировании выбери из меню "добавить в архив" появится диалог, там зайди на вторую закладки, включи гайку "Сохранять файловые потоки" :)
А то этот чистый файл, без потоков :)
← →
Riply © (2007-12-07 13:20) [16]> [11] guav © (07.12.07 12:49)
> The FILE_STREAM_INFORMATION structure is used to enumerate the streams for a file.
> Разве другие атрибуты считаются потоками.
А разве нет ? Это будет для меня открытием. Чем они хуже ?
> Впрочем, раз ты уже вызывала эту функцию, вот и скажи, нет ли там имён файлов.
Имен нет, но довольно часто возвращает поток с длинной имени равной нулю.
(Т.е. там не то что имени или типа нет. Там нет даже ":" )
Это как понимать ? Что это за образование ?
BackupRead его находит.
> Если я правильно понимаю, то там где оно нужно (ну т.е. на NTFS) оно будет.
В том файле, который я выложила, NtQueryInformationFile находит поток,
но говорит, что имени нет.
Конечно, может я неправильно использую эту функцию.
← →
Riply © (2007-12-07 13:21) [17]> [15] Rouse_ © (07.12.07 13:06)
> А то этот чистый файл, без потоков :)
Sorry. Сейчас исправлюсь.
← →
Riply © (2007-12-07 13:45) [18]> [15] Rouse_ © (07.12.07 13:06)
> При архивировании выбери из меню "добавить в архив" появится диалог,
> там зайди на вторую закладки, включи гайку "Сохранять файловые потоки" :)
А разархивировать тоже надо хитро ?
Ничего не понимаю: архивирую как ты сказал.
Разархивирую: потока в новом файле нет. Сравниваю с исодным файлом - в нем поток есть.
Может RAR его не видит потому что имя пустое ?
← →
guav © (2007-12-07 13:48) [19]> [18] Riply © (07.12.07 13:45)
А ты попробуй заархивировать с обычным альтернативным $DATA
Я думаю что винрар согласен со мной что $OBJECT_ID - не поток :)
← →
Rouse_ © (2007-12-07 13:56) [20]
> А разархивировать тоже надо хитро ?
Нет, просто разархивировать :)
← →
Riply © (2007-12-07 13:58) [21]> [19] guav © (07.12.07 13:48)
> А ты попробуй заархивировать с обычным альтернативным $DATA
Попробую. Думаю получиться т.к. имя не будет пустым(в нем будет :DATA) и RAR его увидит :)
> Я думаю что винрар согласен со мной что $OBJECT_ID - не поток :)
Еще и какой поток: у него и размер может быть в сотни байт. :)
Попробую скачать 7z. Может он сумеет сохранить ?
В крайнем случае, у меня таких файлов несколько.
В основном это html файлы, скаченные с интернета.
В фаворитах тоже встречаются (у меня там аж целых четыре таких).
Можете попробовать поискать подобные у себя. Я думаю найдутся :)
← →
guav © (2007-12-07 14:02) [22]> Еще и какой поток: у него и размер может быть в сотни байт. :)
Тут вопрос не в размере а о терминологии Windows.
у $Mft $BITMAP большой, но всё же это ИМХО не поток :)
← →
Riply © (2007-12-07 14:17) [23]> [22] guav © (07.12.07 14:02)
> Тут вопрос не в размере а о терминологии Windows.
> у $Mft $BITMAP большой, но всё же это ИМХО не поток :)
Хорошо. Как тогда объяснить, что NtQueryInformationFile
возвращает что-то с именем нулевой длинны ?
Если рассуждать как ты, то потоков без имени не бывает,
а она перебирает только потоки. Что же она находит ?
P.S. с такими "несуществующими потоками" встречаются и директории.
← →
guav © (2007-12-07 15:01) [24]> [23] Riply © (07.12.07 14:17)
Сколько этого "чего-то" на файл ?
Если один, то ввидимо имеется ввиду ::$DATA
If a file system supports stream enumeration, but the file has no streams other than the default data stream, which is unnamed, the file system should return a single FILE_STREAM_INFORMATION structure containing either "::$DATA" or a zero-length Unicode string as the StreamName.
Какой там StreamSize ? Совпадает ли с размером какого либо аттрибута ? какого именно ?
> P.S. с такими "несуществующими потоками" встречаются и директории.
Вроде у директории тоже может быть $DATA
Интерсно, а FindNextStreamW тоже будет возвращать "что-то" ?
← →
Riply © (2007-12-08 04:05) [25]> [24] guav © (07.12.07 15:01)
Похоже, что ты прав.
> Сколько этого "чего-то" на файл ?
> Если один, то ввидимо имеется ввиду ::$DATA
Более одного "чего-то" у объектов обнаружить не удалось.
> Какой там StreamSize ? Совпадает ли с размером какого либо аттрибута ? какого именно ?
Совпадает... С размером ::$DATA.
> Вроде у директории тоже может быть $DATA
И даже не одна :)
Значит, мой страшный безымянный барабашка - всего навсего основной поток,
не пожелавший показывать свой тип :)
Страницы: 1 вся ветка
Текущий архив: 2008.09.21;
Скачать: CL | DM;
Память: 0.55 MB
Время: 0.015 c