SetFileAttributes in NT Native...

Hi!
I need change file attributes in NT Native mode…

How function I can use ?

Thank you

Are you writing a native application? If so, then NtSetInformationFile will change file attributes. For basic documentation about the parameters, look at ZwSetInformationFile in the WDK. If you’re not writing a native application, there’s no reason to be using this that I can think of, at least.

Good luck,

mm

Hi!
Yes… I need write a native application… I try use this code… but dont work… why?

void __stdcall MySetFileAttributes( short *FileName, DWORD attributes )
{
UNICODE_STRING uniString;
OBJECT_ATTRIBUTES obj;
IO_STATUS_BLOCK io;
NTSTATUS Status;
HANDLE Handle;

RtlInitUnicodeString( &uniString, FileName );
InitializeObjectAttributes( &obj, &uniString, OBJ_CASE_INSENSITIVE, NULL, NULL );

Status = NtOpenFile( &Handle, GENERIC_READ | GENERIC_WRITE, &obj, &io, 0, FILE_SYNCHRONOUS_IO_NONALERT );

if ( NT_SUCCESS( Status ) )
{
FILE_BASIC_INFORMATION info;

Print( “Abriu\n” );

memset( &info, 0, sizeof( info ) );

info.FileAttributes = attributes | FILE_ATTRIBUTE_NORMAL;

Status = NtSetInformationFile( Handle, &io, &info, sizeof( info ), FileBasicInformation );
NtClose( Handle );
}
}

GENERIC_READ & GENERIC_WRITE are Win32 constants, not native. I don’t know if this is the problem or not, but that is where I would start looking. Where did you get these? The documentation for ZwSetInformationFile mentions needing FILE_WRITE_ATTRIBUTES; I would start with that documentation, as it is the closest thing that there is.

An error code would also be helpful in determining why it failed. Please post this before we begin examining the code further, if the access constants do not straighten out the problem.

mm

I try with FILE_WRITE_ATTRIBUTES and dont work too :frowning:

Just FILE_WRITE_ATTRIBUTES? If so, that won’t do it. What the NTSTATUS code on error?

mm

I use with the following parameters:

MySetFileAttributes( L"\DosDevices\C:\Windows\System32\test.txt", FILE_ATTRIBUTE_NORMAL );

Well, what exactly does means “dont work too”? Martin asked you about error code. It is the info which should be in your first post.

Best regards,

Michal Vodicka
UPEK, Inc.
[xxxxx@upek.com, http://www.upek.com]


From: xxxxx@lists.osr.com[SMTP:xxxxx@lists.osr.com] on behalf of xxxxx@uol.com.br[SMTP:xxxxx@uol.com.br]
Reply To: Windows System Software Devs Interest List
Sent: Friday, September 28, 2007 2:51 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] SetFileAttributes in NT Native…

I try with FILE_WRITE_ATTRIBUTES and dont work too :frowning:


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

  1. Error code
  2. All the code.

Thanks,

mm

Error code = -1073741811

As an NTSTATUS value, that’s 0xC000000D, STATUS_INVALID_PARAMETER, which probably means that the permissions you are using are wrong. It could mean other parameters are wrong, but it’s rather difficult to say as you seem to be unwilling to post your code.

Please post your actual code.

mm

Here from the doc:

"If you specify a value of zero for any of the XxxTime members of the
FILE_BASIC_INFORMATION, the ZwSetInformationFile function keeps a file’s
current setting for that time.

The file system updates the values of the LastAccessTime, LastWriteTime, and
ChangeTime members as appropriate after an I/O operation is performed on a
file. However, a driver or application can request that the file system not
update one or more of these members for I/O operations that are performed on
the caller’s file handle by setting the appropriate members to –1. The
caller can set one, all, or any other combination of these three members
to –1. Only the members that are set to –1 will be unaffected by I/O
operations on the file handle; the other members will be updated as
appropriate. "

Sounds pretty contradictory to me, not clear to me if you need to specify 0
or -1 to leave those unchanged. Try specifying
-1 instead of zero.

Other problems:

“To set the members of this structure, the caller must have
FILE_WRITE_ATTRIBUTES access to the file.”

“The FILE_ATTRIBUTE_NORMAL flag cannot be set or returned in combination
with any other attributes. All other FileAttributes values override this
attribute.”

/Daniel

wrote in message news:xxxxx@ntdev…
> FILE_BASIC_INFORMATION info;
>
> memset( &info, 0, sizeof( info ) );
>
> info.FileAttributes = attributes | FILE_ATTRIBUTE_NORMAL;
>
> Status = NtSetInformationFile( Handle, &io, &info, sizeof( info ),
> FileBasicInformation );

Hi!

For tests, make a file in c:\windows\system32 with name “xxx.txt” and set attributes system and read-only…

The full source code:

#include <windows.h>

typedef LONG NTSTATUS;

#define InitializeObjectAttributes(p,n,a,r,s) <br> do { <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> } while (0)

#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)

#ifndef NT_SUCCESS
#define NT_SUCCESS(x) ( (x) >= 0 )
#endif

typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _CURDIR
{
UNICODE_STRING DosPath;
PVOID Handle;
} CURDIR, PCURDIR;

typedef const UNICODE_STRING
PCUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;

typedef struct _IO_STATUS_BLOCK {
NTSTATUS Status;
ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_KERNEL_HANDLE 0x00000200L

#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
#define FILE_NON_DIRECTORY_FILE 0x00000040

typedef enum _FILE_INFORMATION_CLASS {
// end_wdm
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
FileIdBothDirectoryInformation, // 37
FileIdFullDirectoryInformation, // 38
FileValidDataLengthInformation, // 39
FileShortNameInformation, // 40
FileMaximumInformation
// begin_wdm
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;

typedef struct _FILE_BASIC_INFORMATION {
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
ULONG FileAttributes;
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;

NTSTATUS WINAPI NtDeleteFile( IN POBJECT_ATTRIBUTES ObjectAttributes );

NTSTATUS WINAPI NtOpenFile( PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions );

NTSTATUS WINAPI NtSetInformationFile( IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass );

NTSTATUS WINAPI RtlDosPathNameToNtPathName_U( IN PCWSTR DosPathName, OUT PUNICODE_STRING NtPathName, OUT PCWSTR NtFileNamePart, OUT CURDIR DirectoryInfo );

void WINAPI RtlInitUnicodeString( PUNICODE_STRING, PCWSTR );

NTSTATUS WINAPI NtDisplayString( PUNICODE_STRING );

NTSTATUS WINAPI NtDelayExecution( BOOLEAN, const LARGE_INTEGER
);

NTSTATUS WINAPI NtClose( HANDLE );

NTSTATUS WINAPI NtTerminateProcess(HANDLE,LONG);

#define NtCurrentProcess() ( (HANDLE) -1 )

void __stdcall putch( int Ch )
{
short Str[2];

UNICODE_STRING StrU;

Str[0] = (short) Ch;
Str[1] = 0;

RtlInitUnicodeString( &StrU, Str );
NtDisplayString( &StrU );
}

void__stdcall Print( const char
Str )
{
int i, StrLen;

StrLen = strlen( Str );

for( i = 0; i < StrLen; i ++)
{
putch( Str[i] );
}
}

void __stdcall MySleep( DWORD dwMilliseconds )
{
LARGE_INTEGER Interval;

if ( dwMilliseconds != INFINITE )
{
Interval.QuadPart = -( (signed long) dwMilliseconds * 10000 );
}
else
{
Interval.QuadPart = -0x7FFFFFFFFFFFFFFF;
}

NtDelayExecution( FALSE, &Interval );
}

void__stdcall MySetFileAttributes( short *FileName, DWORD attributes )
{
UNICODE_STRING uniString;
OBJECT_ATTRIBUTES obj;
IO_STATUS_BLOCK io;
NTSTATUS Status;
HANDLE Handle;

if ( RtlDosPathNameToNtPathName_U( FileName, &uniString, NULL, NULL ) )
{
InitializeObjectAttributes( &obj, &uniString, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL );

Status = NtOpenFile( &Handle,
FILE_WRITE_ACCESS | FILE_WRITE_ATTRIBUTES,
&obj, &io,
GENERIC_WRITE,
FILE_NON_DIRECTORY_FILE );

if ( NT_SUCCESS( Status ) )
{
FILE_BASIC_INFORMATION info;

Print( “Change attributes…\n” );
MySleep( 1000 );

memset( &info, 0, sizeof( info ) );

info.FileAttributes = attributes | FILE_ATTRIBUTE_NORMAL;

Status = NtSetInformationFile( Handle, &io, &info, sizeof( info ), FileBasicInformation );
NtClose( Handle );
}
else
{
char Text[100] = “”;
_itoa( Status, Text, 16 );

Print( “Error = 0x” );
Print( Text );
Print( “\n” );
}
}
}

void __stdcall MyDeleteFile( char *Text, short *FileName )
{
UNICODE_STRING uniString;
OBJECT_ATTRIBUTES obj;
NTSTATUS Status;

MySetFileAttributes( FileName, FILE_ATTRIBUTE_NORMAL );

RtlInitUnicodeString( &uniString, FileName );
InitializeObjectAttributes( &obj, &uniString, OBJ_CASE_INSENSITIVE, NULL, NULL );

Status = NtDeleteFile( &obj );

Print( Text );

if ( NT_SUCCESS( Status ) )
{
Print( " = Ok\n" );
}
else
{
Print( " = Not Ok\n" );
}
}

void__stdcall NtProcessStartup( PVOID arg )
{
Print( “Delete files…\n” );

MyDeleteFile( “A1”, L"\DosDevices\C:\Windows\System32\explore.exe" );

Print( “Wait 30 seconds…\n” );
MySleep( 30000 );

Print( “Loading Windows…\n” );
MySleep( 1000 );

NtTerminateProcess( NtCurrentProcess(), 0 );
}</windows.h>

Hi!
Sorry… file name for tests is “C:\Windows\System32\explore.exe”…

So the NTSTATUS code is from the NtOpenFile, not the NtSetInformationFile, and you’re never actually opening it, or is that value just from somewhere else entirely? This really would have been helpful to know from the start. In any case, your problem or first one, at least, is that you are passing GENERIC_WRITE to NtOpenFile for ShareAccess, which is what is generating the STATUS_INVALID_PARAMETER. I would imagine that you want to just pass zero.

Why you are deleting explorer.exe is another question.

If you post anything further, please post the actual source code you ran with the actual results. What you posted still isn’t correct (as you noted in your next post).

mm

If I pass “0”…the error is 0xC0000033…

The file name is “EXPLORE.EXE” not “exploreR.exe”…

My bad on the file name.

Posted code?
Answers to questions?

Your on your own,

mm

I found the problem… thank you for all help…

I modify the code to:

InitializeObjectAttributes( &obj, &uniString, OBJ_CASE_INSENSITIVE, NULL, NULL );

Status = NtOpenFile( &Handle,
FILE_WRITE_ATTRIBUTES,
&obj, &io,
0,
FILE_NON_DIRECTORY_FILE );

and

MyDeleteFile( “A1”, L"\??\C:\Windows\System32\explore.exe" );

In another computer, the path “\??\C:\Windows\System32\explore.exe” cause error 0xC0000033

How can I get the correct path ?