char szVolName[MAX_PATH], szFSName[MAX_PATH];
DWORD dwSN, dwMaxLen, dwVolFlags;
::GetVolumeInformation("C:\\", szVolName, MAX_PATH, &dwSN,
&dwMaxLen, &dwVolFlags, szFSName, MAX_PATH);
if (dwVolFlags & FILE_NAMED_STREAMS)
{
// File system supports named streams
}
else
{
// Named streams are not supported
}
* This source code was highlighted with Source Code Highlighter .
HANDLE hFile = ::CreateFile( "file.dat:alt" , ...
::DeleteFile( "file.dat:alt" );
HANDLE hInFile = ::CreateFile(szFromStream, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
HANDLE hOutFile = ::CreateFile(szToStream, GENERIC_WRITE, FILE_SHARE_READ, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
BYTE buf[64*1024];
DWORD dwBytesRead, dwBytesWritten;
do
{
::ReadFile(hInFile, buf, sizeof (buf), &dwBytesRead, NULL);
if (dwBytesRead) ::WriteFile(hOutFile, buf, dwBytesRead, &dwBytesWritten, NULL);
}
while (dwBytesRead == sizeof (buf));
::CloseHandle(hInFile);
::CloseHandle(hOutFile);
* This source code was highlighted with Source Code Highlighter .
// Open a file and obtain stream information
BYTE InfoBlock[64 * 1024]; // Buffer must be large enough
PFILE_STREAM_INFORMATION pStreamInfo = (PFILE_STREAM_INFORMATION)InfoBlock;
IO_STATUS_BLOCK ioStatus;
HANDLE hFile = ::CreateFile(szPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
NtQueryInformationFile(hFile, &ioStatus, InfoBlock,
sizeof (InfoBlock), FileStreamInformation);
::CloseHandle(hFile);
* This source code was highlighted with Source Code Highlighter .
// Open a directory and obtain stream information
// Obtain backup privilege in case we don't have it
HANDLE hToken;
TOKEN_PRIVILEGES tp;
::OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
::LookupPrivilegeValue(NULL, SE_BACKUP_NAME, &tp.Privileges[0].Luid);
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
::AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof (TOKEN_PRIVILEGES), NULL, NULL);
::CloseHandle(hToken);
HANDLE hFile = ::CreateFile(szPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
BYTE InfoBlock[64 * 1024]; // Buffer must be large enough
PFILE_STREAM_INFORMATION pStreamInfo = (PFILE_STREAM_INFORMATION)InfoBlock;
IO_STATUS_BLOCK ioStatus;
pStreamInfo->StreamNameLength = 0; // Zero in this field means empty info block
NtQueryInformationFile(hFile, &ioStatus, InfoBlock,
sizeof (InfoBlock), FileStreamInformation);
::CloseHandle(hFile);
* This source code was highlighted with Source Code Highlighter .
WCHAR wszStreamName[MAX_PATH];
for (;;)
{
// Check if stream info block is empty (directory may have no stream)
if (pStreamInfo->StreamNameLength == 0) break ; // No stream found
// Get null-terminated stream name
memcpy(wszStreamName, pStreamInfo->StreamName, pStreamInfo->StreamNameLength);
wszStreamName[pStreamInfo->StreamNameLength / sizeof (WCHAR)] = L '\0' ;
print( "%S" , wszStreamName);
if (pStreamInfo->NextEntryOffset == 0) break ; // No more stream records
pStreamInfo = (PFILE_STREAM_INFORMATION)
((LPBYTE)pStreamInfo + pStreamInfo->NextEntryOffset); // Next stream record
}
* This source code was highlighted with Source Code Highlighter .
Source: https://habr.com/ru/post/46990/
All Articles