Файловые потоки NTFS - как много в этом слове :-)


Работа с потоками из консоли

Создание файла с потоком:
type nul > somefile.txt:Stream

Запись в поток:
echo "Something" >> somefile.txt:Stream

Чтение из потока:
more < somefile:Stream Копирование содержимого существующего файла в поток: type file1.txt >> somefile.txt:Stream

Копирование содержимого потока в файл:
more < somefile.txt:Stream >> file2.txt
Удаление потоков

Существует мнение о том, что поток можно удалить только вместе с файлом, к которому он прикреплен. Это не так. Если ты знаешь название потока, то ты всегда сможешь удалить его стандартной функцией DeleteFile.

Листинг 1. Пример создания потока.
#include 

int main()
{
DWORD dwRet;
HANDLE hStream =
CreateFile( "testfile:stream", GENERIC_WRITE, FILE_SHARE_WRITE,
NULL, OPEN_ALWAYS, NULL, NULL );
WriteFile( hFile, "This is a stream", 17, &dwRet, NULL );
CloseHandle(hStream);
return 0;
}
Листинг 2. X-Stream: Программа, показывающая список потоков
#include 
#include 
#include 
#include 

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 %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;
}
взято отсюда http://hex.pp.ua/using-alternate-data-streams.php и отсюда http://electro-2006.narod.ru/text/stati/NTFS.html

Comments

Popular posts from this blog

Открываем порт для сервера Minecraft на роутере mikrotik (команда для терминала в WinBox)

Интересное о Формальдегиде