BackupWrite: empty stream

From
Alexander Starostin (2:5020/1297.153)
To
All ()
Date
2001-12-19T02:19:18Z
Area
SU.WINDOWS.NT.PROG
   Hello, dear All !

Использую BackupWrite() для создания альтернативных потоков на NТFS-томе. Нижеприведенный код удачно создает поток, но только непустой (содержимое его в данном случае меня не волнует - мусор). В случае же указания нулевого StreamDataSize никаких изменений с потоками файла не происходит, а именно поток не создается (новый), либо не усекается до нулевой длины (если поток уже существует). При этом нигде не обнаруживается ошибочных условий.

int Test()
{
 const WCHAR *StreamName = L":StreamName";
 const char *FileName = "s:\\test.dat";
 const DWORD StreamDataSize = 0; //123;

 HANDLE hFile = CreateFile(FileName, GENERIC_WRITE,
  FILE_SHARE_READ | FILE_SHARE_WRITE,
  NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
 if (hFile == INVALID_HANDLE_VALUE)
 {
  printf("Err1: %d\n", GetLastError() );
  return -1;
 }

 WIN32_STREAM_ID* pStream = (WIN32_STREAM_ID*)malloc(1024);
 if (!pStream)
 {
  printf("Err2: malloc\n");
  return -1;
 }
 ZeroMemory(pStream, sizeof(WIN32_STREAM_ID) );

 pStream->dwStreamId = BACKUP_ALTERNATE_DATA;
 pStream->dwStreamAttributes = 0;
 pStream->dwStreamNameSize = 2*wcslen(StreamName);
 wcscpy((WCHAR*)&pStream->cStreamName, StreamName);
 pStream->Size.HighPart = 0;
 pStream->Size.LowPart = StreamDataSize;
 const DWORD StreamHeaderSize = offsetof(WIN32_STREAM_ID, cStreamName);
 const DWORD StreamTotalSize = StreamHeaderSize+pStream->dwStreamNameSize+StreamDataSize;

 DWORD Written; LPVOID Context = NULL;
 int rc=0;
  if (FALSE == BackupWrite(hFile, (LPBYTE)pStream,
  StreamTotalSize,
  &Written, FALSE, FALSE, &Context) )
  printf("Err3: %d\n", GetLastError() ), rc=-1;
 printf("Written=0x%X\n", Written);
 if (Written != StreamTotalSize)
  printf("Err4: Written!=StreamTotalSize\n"), rc=-1;

 if (FALSE == BackupWrite(hFile, NULL, 0,
  NULL, TRUE, FALSE, &Context) )
  printf("Err5: %d\n", GetLastError() ), rc=-1;

 free(pStream);
 CloseHandle(hFile);
 return rc;
}

Любопытен лог filemon:
=== Для случая непустого потока (длины 123)
IRP_MJ_CREATE S:\test.dat SUCCESS Attributes: Any Options: Open
IRP_MJ_CREATE S:\test.dat\:StreamName SUCCESS Attributes: N Options: OverwriteIf
IRP_MJ_WRITE  S:\test.dat\:StreamName SUCCESS Offset: 0 Length: 123
IRP_MJ_CLEANUP S:\test.dat\:StreamName SUCCESS
IRP_MJ_CLEANUP S:\test.dat SUCCESS
IRP_MJ_CLOSE  S:\test.dat SUCCESS
=== Для случая пустого потока
IRP_MJ_CREATE S:\test.dat SUCCESS Attributes: Any Options: Open
IRP_MJ_CLEANUP S:\test.dat SUCCESS
IRP_MJ_CLOSE  S:\test.dat SUCCESS
===

Эффект стабилен на WINNT4SP6 и WIN2000SP1. В MSDN ничего о недопустимости использования BackupWrite() для создания пустых потоков не нашел. Понятно, что можно использовать обычный CreateFile("S:\\test.dat:StreamName"), что собственно и делает BackupWrite(), но...

Have a nice day!

---
 * Origin:  (2:5020/1297.153)