Ken,
you wrote on Wednesday, March 27, 2002, 17:21:26:
KG> I’ve noticed on WIN2K that when an NTFS stream is renamed (by
KG> explorer) the file name is not included as part of the “to” file,
KG> only the stream name. Is this normal behavior?
Yes.
KG> I’ve tried do a rename via the win32 API “MoveFile”, but it says the
KG> syntax is incorrect when I try to. The SDK documents say that there
KG> is no “official or supported way to rename a stream”. So what is the
KG> unofficial behavior that a file system/filter is to expect?
Below is an example, which is the only way I know to rename a stream. It
does use the native API but not any undocumented functions in there. The
functions and structures are documented in the DDK/IFS Kit. I have
copied the neccessary stuff from the DDK headers
(FILE_RENAME_INFORMATION is documented in the IFS Kit), you need to link
with ntdll.lib. The trick is to open the stream as a separate “file”,
relative to the “parent file”.
The sample assumes that there is a file C:\Test.txt with a named stream
named ‘:TestStream’ which is supposed to be renamed to ‘:RenamedStream’.
Type
echo hello>c:\test.txt:TestStream
in a DOS box to create this file/stream.
========================================================================
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <windows.h>
typedef LONG NTSTATUS;
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
typedef enum _FILE_INFORMATION_CLASS {
FileDirectoryInformation = 1,
FileFullDirectoryInformation, // 2
FileBothDirectoryInformation, // 3
FileBasicInformation, // 4 wdm
FileStandardInformation, // 5 wdm
FileInternalInformation, // 6
FileEaInformation, // 7
FileAccessInformation, // 8
FileNameInformation, // 9
FileRenameInformation, // 10
FileLinkInformation, // 11
FileNamesInformation, // 12
FileDispositionInformation, // 13
FilePositionInformation, // 14 wdm
FileFullEaInformation, // 15
FileModeInformation, // 16
FileAlignmentInformation, // 17
FileAllInformation, // 18
FileAllocationInformation, // 19
FileEndOfFileInformation, // 20 wdm
FileAlternateNameInformation, // 21
FileStreamInformation, // 22
FilePipeInformation, // 23
FilePipeLocalInformation, // 24
FilePipeRemoteInformation, // 25
FileMailslotQueryInformation, // 26
FileMailslotSetInformation, // 27
FileCompressionInformation, // 28
FileObjectIdInformation, // 29
FileCompletionInformation, // 30
FileMoveClusterInformation, // 31
FileQuotaInformation, // 32
FileReparsePointInformation, // 33
FileNetworkOpenInformation, // 34
FileAttributeTagInformation, // 35
FileTrackingInformation, // 36
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef struct _FILE_RENAME_INFORMATION {
BOOLEAN ReplaceIfExists;
HANDLE RootDirectory;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
#define FILE_OPEN 0x00000001
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define OBJ_CASE_INSENSITIVE 0x00000040L
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
void * SecurityDescriptor;
void * SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
void * Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
#define InitializeObjectAttributes( p, n, a, r, s ) { <br> (p)->Length = sizeof(OBJECT_ATTRIBUTES); <br> (p)->RootDirectory = r; <br> (p)->Attributes = a; <br> (p)->ObjectName = n; <br> (p)->SecurityDescriptor = s; <br> (p)->SecurityQualityOfService = NULL; <br> }
void NTAPI RtlInitUnicodeString(
PUNICODE_STRING DestinationString,
PCWSTR SourceString
);
NTSTATUS NTAPI NtCreateFile(
PHANDLE FileHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PIO_STATUS_BLOCK IoStatusBlock,
PLARGE_INTEGER AllocationSize,
ULONG FileAttributes,
ULONG ShareAccess,
ULONG CreateDisposition,
ULONG CreateOptions,
void * EaBuffer,
ULONG EaLength
);
NTSTATUS NTAPI NtSetInformationFile(
HANDLE FileHandle,
PIO_STATUS_BLOCK IoStatusBlock,
void * FileInformation,
ULONG Length,
FILE_INFORMATION_CLASS FileInformationClass
);
NTSTATUS NTAPI NtClose(
HANDLE Handle
);
int main(int argc,char argv[])
{
WCHAR szFileName[] = L"\??\C:\Test.txt";
WCHAR szStreamName[] = L":TestStream";
WCHAR szNewStreamName[] = L":RenamedStream";
FILE_RENAME_INFORMATION pFri = NULL;
ULONG BufferSize;
UNICODE_STRING Name;
IO_STATUS_BLOCK Iosb;
OBJECT_ATTRIBUTES FileObject;
HANDLE hFile;
HANDLE hStream;
NTSTATUS ntStatus;
// Open the file
RtlInitUnicodeString(&Name, szFileName);
InitializeObjectAttributes(
&FileObject,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
ntStatus = NtCreateFile(
&hFile,
DELETE | SYNCHRONIZE,
&FileObject,
&Iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_DELETE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
if (STATUS_SUCCESS != ntStatus)
{
printf(“Could not open file %ls, error %lX\n”, szFileName, ntStatus);
return -1;
}
// Open the stream
RtlInitUnicodeString(&Name, szStreamName);
InitializeObjectAttributes(
&FileObject,
&Name,
OBJ_CASE_INSENSITIVE,
hFile, // file is specified as “root directory” for named stream
NULL
);
ntStatus = NtCreateFile(
&hStream,
DELETE | SYNCHRONIZE,
&FileObject,
&Iosb,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_DELETE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
if (STATUS_SUCCESS != ntStatus)
{
printf(“Could not open stream %ls, error %lX\n”, szStreamName, ntStatus);
NtClose(hFile);
return -1;
}
BufferSize = sizeof(FILE_RENAME_INFORMATION) + (wcslen(szNewStreamName) * sizeof(WCHAR)) + sizeof(WCHAR);
pFri = malloc( BufferSize );
if (NULL == pFri)
printf(“Out of memory\n”);
else
{
pFri->ReplaceIfExists = TRUE;
pFri->RootDirectory = NULL;
pFri->FileNameLength = wcslen(szNewStreamName) * sizeof(WCHAR);
wcscpy(pFri->FileName, szNewStreamName);
ntStatus = NtSetInformationFile(
hStream,
&Iosb,
pFri,
BufferSize,
FileRenameInformation
);
if (STATUS_SUCCESS != ntStatus)
printf(“Unable to rename stream, error %lX\n”, ntStatus);
}
if (NULL != pFri)
free(pFri);
NtClose(hStream);
NtClose(hFile);
return 0;
}
Ralf.
–
/======================== Foot shot for today =========================
Kann Datei footshot.txt nicht ?ffnen
======================================================================/</windows.h></wchar.h></string.h></stdlib.h></stdio.h>