FileShortNameInformation - PRIVILEGE NOT HELD

Hi all,

I try to use ZwSetInformationFile with FileShortNameInformation in the minifilter FS driver. I called this routine both in the driver entry routine and in the system work item thread. However, the ZwSetInfo… call always failed with STATUS_PRIVILEGE_NOT_HELD (0xC0000061).

I am running Win 7 32 bit on the NTFS volume. I have also enabled the privilege SE_RESTORE_PRIVILEGE using ZwAdjustPrivilegesToken on the current process token. But it still fails.

Does anybody know what I am doing wrong?

The code was posted below as well:

NTSTATUS status;
TOKEN_PRIVILEGES privSet;
HANDLE tokenHandle;
TOKEN_PRIVILEGES tokenPriv;

// Open current process token
status = ZwOpenProcessToken(NtCurrentProcess(), TOKEN_ALL_ACCESS,
&tokenHandle);

if ( !NT_SUCCESS( status ) )
{
KdPrint((" NtOpenProcessToken failed, status 0x%x\n", status));
return status;
}

// Set up the information about the privilege we are adjusting
privSet.PrivilegeCount = 1;
privSet.Privileges[0].Luid = RtlConvertUlongToLuid(SE_RESTORE_PRIVILEGE);
privSet.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

status = ZwAdjustPrivilegesToken(tokenHandle, FALSE, &privSet, sizeof(privSet), NULL, NULL);

if ( !NT_SUCCESS( status ) )
KdPrint((“ZwAdjustPrivilegesToken failed, status 0x%x\n”, status));

ZwClose(tokenHandle);

OBJECT_ATTRIBUTES oa;
UNICODE_STRING filenameu;
HANDLE handle;
IO_STATUS_BLOCK iosb;

RtlInitUnicodeString( &filenameu, L"\DosDevices\D:\this is a long name folder" );
InitializeObjectAttributes( &oa, &filenameu, OBJ_CASE_INSENSITIVE|
OBJ_KERNEL_HANDLE , NULL, NULL );

NTSTATUS ntStatus = ZwCreateFile( &handle, GENERIC_WRITE|DELETE, &oa,
&iosb, 0, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, 0, NULL, 0 );

if ( NT_SUCCESS( ntStatus ) )
{

PFILE_NAME_INFORMATION fileNameInfo = (PFILE_NAME_INFORMATION) ExAllocatePool(PagedPool, sizeof(FILE_NAME_INFORMATION)+ 128);

fileNameInfo->FileNameLength = wcslen( L"thisis~3" ) * sizeof( WCHAR );
memcpy( fileNameInfo->FileName, L"thisis~3", fileNameInfo->FileNameLength );

ntStatus = ZwSetInformationFile( handle, &iosb, fileNameInfo, sizeof( FILE_NAME_INFORMATION ) + fileNameInfo->FileNameLength, FileShortNameInformation );

ExFreePool(fileNameInfo);

// Always returns STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS)0xC0000061L):
// A required privilege is not held by the client
KdPrint((“ntStatus: 0x%X\n”, ntStatus));
ZwClose( handle );
}

Is the current thread impersonating? Are you sure the thread or process has
the restore privilege available in its token? You can’t enable a privilege
that isn’t present in the token. It should be there for threads in the
System process, but worth checking (!process/!token will tell you).

Two other things:

  1. STATUS_NOT_ALL_ASSIGNED is a success code so even though the call doesn’t
    work you might not get your DbgPrint. You might want to always print the
    result in this case for debugging purposes

  2. For tidiness you should really call ZwOpenProcessTokenEx and specify the
    OBJ_KERNEL_HANDLE flag.

-scott
OSR
@OSRDrivers

wrote in message news:xxxxx@ntfsd…

Hi all,

I try to use ZwSetInformationFile with FileShortNameInformation in the
minifilter FS driver. I called this routine both in the driver entry routine
and in the system work item thread. However, the ZwSetInfo… call always
failed with STATUS_PRIVILEGE_NOT_HELD (0xC0000061).

I am running Win 7 32 bit on the NTFS volume. I have also enabled the
privilege SE_RESTORE_PRIVILEGE using ZwAdjustPrivilegesToken on the current
process token. But it still fails.

Does anybody know what I am doing wrong?

The code was posted below as well:

NTSTATUS status;
TOKEN_PRIVILEGES privSet;
HANDLE tokenHandle;
TOKEN_PRIVILEGES tokenPriv;

// Open current process token
status = ZwOpenProcessToken(NtCurrentProcess(), TOKEN_ALL_ACCESS,
&tokenHandle);

if ( !NT_SUCCESS( status ) )
{
KdPrint((" NtOpenProcessToken failed, status 0x%x\n", status));
return status;
}

// Set up the information about the privilege we are adjusting
privSet.PrivilegeCount = 1;
privSet.Privileges[0].Luid = RtlConvertUlongToLuid(SE_RESTORE_PRIVILEGE);
privSet.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

status = ZwAdjustPrivilegesToken(tokenHandle, FALSE, &privSet,
sizeof(privSet), NULL, NULL);

if ( !NT_SUCCESS( status ) )
KdPrint((“ZwAdjustPrivilegesToken failed, status 0x%x\n”, status));

ZwClose(tokenHandle);

OBJECT_ATTRIBUTES oa;
UNICODE_STRING filenameu;
HANDLE handle;
IO_STATUS_BLOCK iosb;

RtlInitUnicodeString( &filenameu, L"\DosDevices\D:\this is a long name
folder" );
InitializeObjectAttributes( &oa, &filenameu, OBJ_CASE_INSENSITIVE|
OBJ_KERNEL_HANDLE , NULL, NULL );

NTSTATUS ntStatus = ZwCreateFile( &handle, GENERIC_WRITE|DELETE, &oa,
&iosb, 0, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, 0, NULL, 0 );

if ( NT_SUCCESS( ntStatus ) )
{

PFILE_NAME_INFORMATION fileNameInfo = (PFILE_NAME_INFORMATION)
ExAllocatePool(PagedPool, sizeof(FILE_NAME_INFORMATION)+ 128);

fileNameInfo->FileNameLength = wcslen( L"thisis~3" ) * sizeof( WCHAR );
memcpy( fileNameInfo->FileName, L"thisis~3",
fileNameInfo->FileNameLength );

ntStatus = ZwSetInformationFile( handle, &iosb, fileNameInfo, sizeof(
FILE_NAME_INFORMATION ) + fileNameInfo->FileNameLength,
FileShortNameInformation );

ExFreePool(fileNameInfo);

// Always returns STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS)0xC0000061L):
// A required privilege is not held by the client
KdPrint((“ntStatus: 0x%X\n”, ntStatus));
ZwClose( handle );
}

On 02/15/2017 09:37 PM, xxxxx@gmail.com wrote:

NTSTATUS ntStatus = ZwCreateFile( &handle, GENERIC_WRITE|DELETE, &oa,
&iosb, 0, FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN, 0, NULL, 0 );

I think you’ll also need FILE_OPEN_FOR_BACKUP_INTENT for the restore
privilege to be applied to the handle.

  • M


http://www.malsmith.net

Malcolm, you just saved my life, thanks!