Matt,
you wrote on Wednesday, February 27, 2002, 08:27:50:
MW> Does anyone know about FILE_INFORMATION_CLASS: FileStreamInformation
MW> and the FILE_STREAM_INFORMATION structure ?
It is used to enumerate the named streams of a file on a file system
that supports this (e.g. NTFS). Here is an user mode sample:
#define STREAMBUFFERSIZE 32768
NTSTATUS GetStreamInfo(HANDLE hFile)
{
IO_STATUS_BLOCK IoStatus;
DWORD dwBufferSize = STREAMBUFFERSIZE;
FILE_STREAM_INFORMATION *pFsi = NULL, *m_pFsi = NULL;
WCHAR szStreamName[MAX_PATH + 1];
NTSTATUS ntStatus;
// Increase buffer size until all stream names fit into
do
{
if ((pFsi = malloc(dwBufferSize)) == NULL)
break;
memset(pFsi, 0, dwBufferSize);
ntStatus = NtQueryInformationFile(
hFile,
&IoStatus,
pFsi,
dwBufferSize,
FileStreamInformation
);
if (ntStatus != STATUS_BUFFER_OVERFLOW)
break;
free(pFsi);
pFsi = NULL;
dwBufferSize += STREAMBUFFERSIZE;
} while (ntStatus == STATUS_BUFFER_OVERFLOW);
if (ntStatus == STATUS_SUCCESS)
{
// Loop over stream names and print them
m_pFsi = pFsi;
while (TRUE)
{
// Directories without special alternate streams do not return valid stream info
if (m_pFsi->StreamNameLength)
{
// Remember: StreamNameLength specifies the stream names length in BYTES!
wcsncpy(szStreamName, m_pFsi->StreamName, m_pFsi->StreamNameLength / sizeof(WCHAR));
// wcsncpy does not null terminate
szStreamName[m_pFsi->StreamNameLength / sizeof(WCHAR)] = 0;
printf(“\t%ls\n”, szStreamName);
}
if (m_pFsi->NextEntryOffset)
m_pFsi = (FILE_STREAM_INFORMATION *) ((BYTE *)m_pFsi + m_pFsi->NextEntryOffset);
else
break;
}
}
if (pFsi)
free(pFsi);
}
Ralf.