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)