void EnumStreams(char *strFilePath) { PVOID streamContext = 0; DWORD dwReadBytes, seek_high; WIN32_STREAM_ID streamHeader; WCHAR strStreamName[MAX_PATH]; char strBuffer[1024];
//Open the file for stream enumeration HANDLE hFile = CreateFileA( strFilePath, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
if( hFile == INVALID_HANDLE_VALUE ) { printf("Failed to open the file %s, Error=0x%.8x", strFilePath, GetLastError()); return; }
while(1) {
//check if we have reached the end of file if( FALSE == BackupRead(hFile, (LPBYTE)&streamHeader, (LPBYTE)&streamHeader.cStreamName-(LPBYTE)&streamHeader, &dwReadBytes,
FALSE, FALSE, &streamContext) ) { break; }
//check if we have read the stream header properly if( (long)dwReadBytes != (LPBYTE)&streamHeader.cStreamName-(LPBYTE)&streamHeader ) break;
//we are interested only in alternate data streams if(streamHeader.dwStreamId == BACKUP_ALTERNATE_DATA) { if (streamHeader.wStreamNameSize != 0 ) {
if( BackupRead(hFile, (LPBYTE)strStreamName,
streamHeader.dwStreamNameSize, &dwReadBytes, FALSE, FALSE, &streamContext) ) { strStreamName[streamHeader.dwStreamNameSize/2]=L'\0';
//
//Reformat the stream file name ... :stream.txt:$DATA //
sprintf_s(strBuffer, 1024, "%S", &strStreamName[1]); char *ptr = strchr(strBuffer, ':'); if( ptr != NULL ) *ptr = '\0';
printf("\n Found Stream - %s", strBuffer);
} } }
// jump to the next stream header if (BackupSeek(hFile, ~0, ~0, &dwReadBytes, &seek_high,
&streamContext) == FALSE) { //for any errors other than seek break out of loop if (GetLastError() != ERROR_SEEK) { // terminate BackupRead() loop BackupRead(hFile, 0, 0, &dwReadBytes, TRUE, FALSE, &streamContext);
break; }
streamHeader.Size.QuadPart -= dwReadBytes; streamHeader.Size.HighPart -= seek_high;
BYTE buffer[4096];
while(streamHeader.Size.QuadPart > 0) { if (dwReadBytes!=sizeof(buffer) ||
!BackupRead(hFile, buffer, sizeof(buffer), &dwReadBytes, FALSE,
FALSE, &streamContext) ) { break; }
streamHeader.Size.QuadPart -= dwReadBytes; } //end of inner while loop } //end of 'jump to next stream' if loop
} //main while loop
//Finally clean up the buffers used for seeking if (streamContext) BackupRead(hFile, 0, 0, &dwReadBytes, TRUE, FALSE, &streamContext);
CloseHandle(hFile);
return;
}
|