![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работа со Streams
GMan © (2005-02-01 09:25:00)Как получить список потоков в файле?
}{enon (2005-02-01 15:54:00) [1]2 GMan,kaZaNoVa: Thanks!
GMan (2005-02-01 15:30:00) [2]2 kaZaNoVa:
Огромное спасибо!!!
GMan (2005-02-01 14:58:00) [3]2 }{enon:
#include
#include
#include
#include
/*
* X-Stream 2.0 - NTFS Alternate Data Streams Enumeration
* Copyright (c) 2003 - 2004 A.M.D.F.
* mailto:amdf@mera.net.ru
*/
int _tmain( int argc, _TCHAR *argv[] )
{
WIN32_STREAM_ID sid;
ZeroMemory(&sid, sizeof(WIN32_STREAM_ID));
DWORD dw1,dw2,dwRead;
INT numofstreams = 0;
//Буфер для имени потока в формате Unicode
WCHAR wszStreamName[MAX_PATH];
LPVOID lpContext = NULL;
/*
* Открываем файл для чтения с параметром
* FILE_FLAG_BACKUP_SEMANTICS, что позволяет нам
* открывать не только файлы, но и каталоги с дисками.
*/
HANDLE hFile = CreateFile(argv[1],GENERIC_READ,FILE_SHARE_READ,
NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
if (hFile == INVALID_HANDLE_VALUE)
{ printf("\nError: Could't open file, directory or disk device %s\n",argv[1]);
exit(0);
}
DWORD dwStreamHeaderSize = (LPBYTE)&sid.cStreamName -
(LPBYTE)&sid + sid.dwStreamNameSize;
printf("\nStreams information for %s:\n",argv[1]);
while ( BackupRead(hFile, (LPBYTE) &sid,
dwStreamHeaderSize, &dwRead, FALSE, TRUE,
&lpContext) )
{ //Если тип потока неверный, значит прерываем цикл
if (sid.dwStreamId == BACKUP_INVALID) break;
ZeroMemory(&wszStreamName,sizeof(wszStreamName));
//Получаем имя потока
if (!BackupRead(hFile, (LPBYTE) wszStreamName, sid.dwStreamNameSize,
&dwRead, FALSE, TRUE, &lpContext)) break;
if (sid.dwStreamId == BACKUP_DATA ||
sid.dwStreamId == BACKUP_ALTERNATE_DATA)
{ numofstreams++;
printf("\n\nStream\t\t#%u",numofstreams);
switch (sid.dwStreamId)
{ case BACKUP_DATA:
printf("\nName:\t\t::$DATA"); break;
case BACKUP_ALTERNATE_DATA:
printf("\nName:\t\t%S",wszStreamName); break;
}
printf("\nSize:\t\t%u\n",sid.Size);
}
//Перемещаемся к следующему потоку
BackupSeek(hFile, sid.Size.LowPart, sid.Size.HighPart,
&dw1, &dw2, &lpContext);
//Очищаем структуру перед следующим проходом цикла
ZeroMemory(&sid,sizeof(sid));
}
//Очищаем lpContext, содержащий служебную информацию
//для работы функции BackupRead
BackupRead(hFile, NULL, NULL,
&dwRead, TRUE, FALSE, &lpContext);
//Закрываем файл
CloseHandle(hFile);
return 0;
}
kaZaNoVa (2005-02-01 13:43:00) [4]САБЖ
function BackupSeekA(hFile: THandle; dwLowBytesToSeek, dwHighBytesToSeek: DWORD;
lpdwLowByteSeeked, lpdwHighByteSeeked: PDWORD;var lpContext: Pointer): BOOL; stdcall; external kernel32 name 'BackupSeek';
procedure TForm1.Button1Click(Sender: TObject);
Procedure EnumStreamsInfo(path:PChar);
var s:string;
wszStreamName:array[0..MAX_PATH-1] of WCHAR;
sid:WIN32_STREAM_ID absolute wszStreamName;
h:thandle;
p:pointer;
temp,dw1, dw2:cardinal;
begin
p:=nil;
h:=CreateFile(path,GENERIC_READ, 0, nil, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS or FILE_FLAG_POSIX_SEMANTICS, 0);
while true do begin
memo1.Lines.Add('_-_-_-_-_-_-'); // разграничиваем записи ;)
BackupRead(h, @wszStreamName, sizeof(sid), temp, FALSE, TRUE, p);
if temp = 0 then break;
if sid.dwStreamNameSize > 0 then begin // если у потока есть имя, то узнаем его
BackupRead(h, pointer(integer(@wszStreamName) + sizeof(sid)), sid.dwStreamNameSize, temp, FALSE, TRUE, p);
if temp <> sid.dwStreamNameSize then break;
{ для простоты всё выводиться в TMemo }
memo1.Lines.Add(PwideChar(@sid.cStreamName));
end;
memo1.Lines.Add('Stream size: '+IntToStr(sid.Size));
s:='Type of data: ';
case sid.dwStreamId of // определяем тип потока
BACKUP_DATA: s := s+'data';
BACKUP_EA_DATA: s := s+'extended attributes';
BACKUP_SECURITY_DATA: s := s+'security';
BACKUP_ALTERNATE_DATA: s := s+'other streams';
BACKUP_LINK: s := s+'link';
else s := s+'unknown';
end;
memo1.Lines.Add(s);
if sid.Size>0 then
{ я не думаю, что у кого-то есть потоки больше 4ГБ, поэтому второй параметр поиска = 0 }
BackupSeekA(h, sid.Size, 0, @dw1, @dw2, p);
end;
BackupRead(h, @sid, 0, temp, TRUE, FALSE, p);
CloseHandle(h);
end;
begin
EnumStreamsInfo(PChar(edit1.Text));
end;
}{enon (2005-02-01 12:18:00) [5]А можно выложить исходник на C? Интересно, как оно работает...
Erik1 (2005-02-01 12:00:00) [6]И классу TFileStream и его потомкам это неимеет отношения.
Набережных С (2005-02-01 11:19:00) [7]Backup API. Сходи на MSDN - BackupRead и рядом с ним, ничего сложного.
GMan (2005-02-01 10:24:00) [8]Что, о таком никто не слышал??? Как минимум странно...
Неужели никто не работал со стримами?
GMan (2005-02-01 09:37:00) [9]В файловой системе NTFS реализована возможность хранения в файле дополнительных потоков с данными любого рода. Содержимое самого файла хранится в FileName::StreamName.
Так вот, мне интересно как можно получить список потоков для выбранного файла на Delphi (исходник на C у меня есть, но я не знаю C :()
GMan (2005-02-01 09:37:00) [10]В файловой системе NTFS реализована возможность хранения в файле дополнительных потоков с данными любого рода. Содержимое самого файла хранится в FileName::StreamName.
Так вот, мне интересно как можно получить список потоков для выбранного файла на Delphi (исходник на C у меня есть, но я не знаю C :()
MBo (2005-02-01 09:28:00) [11]Расшифруй вопрос....