The following code fails when trying to logically extend my Windows 8.1 file with SetFileVaildData().
The returned Windows error code and message is:
ERROR_PRIVILEGE_NOT_HELD 1314 (0x522) A required privilege is not held by the client.
I'm running the code as Administrator and I have asserted that the process indeed has the SE_MANAGE_VOLUME_NAME
privilege using OpenProcessToken()
and GetTokenInformation()
.
// SetFileValidData_test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
bool ProcessHasSeManageVolumePrivilege();
int _tmain(int argc, _TCHAR* argv[])
{
// Set access methods
DWORD accessMethods = GENERIC_READ | GENERIC_WRITE;
// Set share modes
DWORD shareModes = 0;
// Set security attributes
LPSECURITY_ATTRIBUTES secAttr = NULL;
// Set creation disposition
DWORD creationDispositions = CREATE_ALWAYS;
// Set file flags
DWORD fileFlags = 0;
// Set template
HANDLE templateFile = NULL;
if (!ProcessHasSeManageVolumePrivilege())
{
// Missing privilege to continue
std::cerr << "Process is missing the required SE_MANAGE_VOLUME_NAME (\"SeManageVolumePrivilege\") privilege." << std::endl;
return -1;
}
// Create the file
HANDLE filehandle = CreateFile(
L"testfile.tmp",
accessMethods,
shareModes,
secAttr,
creationDispositions,
fileFlags,
templateFile);
if (filehandle == INVALID_HANDLE_VALUE)
{
// Error
std::cerr << "CreateFile() failed with error #" << GetLastError() << "." << std::endl;
return -1;
}
// Extend the file to 1 MB
if (!SetFileValidData(filehandle, 1024*1024))
{
// Error
std::cerr << "SetFileValidData() failed with error #" << GetLastError() << "." << std::endl;
return -1;
}
std::cout << "File was logically extended successfully!" << std::endl
<< "Press a key to quit..." << std::endl;
getchar();
return 0;
}
bool ProcessHasSeManageVolumePrivilege()
{
HANDLE token;
void* tpv;
TOKEN_PRIVILEGES* tp;
DWORD rl;
bool hasPrivilege = false;
std::cout << "Asserting process has the \"SeManageVolumePrivilege\" privilege:" << std::endl;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &token))
{
std::cerr << "OpenProcessToken() failed with error #" << GetLastError() << "." << std::endl;
return false;
}
if (!GetTokenInformation(token, TokenPrivileges, NULL, 0, &rl))
{
DWORD dw = GetLastError();
if (dw != ERROR_INSUFFICIENT_BUFFER)
{
std::cerr << "GetTokenInformation() failed with error #" << GetLastError() << "." << std::endl;
return false;
}
}
tpv = malloc(rl + 10);
if (!tpv) throw std::bad_alloc();
ZeroMemory(tpv, rl + 10);
if (!GetTokenInformation(token, TokenPrivileges, tpv, rl, &rl))
{
std::cerr << "GetTokenInformation() failed with error #" << GetLastError() << "." << std::endl;
return false;
}
tp = (TOKEN_PRIVILEGES*)tpv;
for (DWORD i = 0; i < tp->PrivilegeCount; i++)
{
const int nLen = 100;
TCHAR bufname[nLen];
DWORD bufsize = nLen;
try
{
LookupPrivilegeName(NULL, &tp->Privileges[i].Luid, bufname, &bufsize);
bufname[nLen - 1] = '\0';
std::wcout << "\t" << bufname;
if (wcscmp(L"SeManageVolumePrivilege", bufname) == 0)
{
std::cout << " ... YES! Found it!" << std::endl;
hasPrivilege = true;
break;
}
else std::cout << " ... no" << std::endl;
}
catch (...)
{
// Clean up before re-throwing exception
free(tpv);
CloseHandle(token);
throw;
}
}
free(tpv);
CloseHandle(token);
token = NULL;
return hasPrivilege;
}
Result:
C:\dev\SetFileValidData_test\Debug> SetFileValidData_test.exe
Asserting process has the "SeManageVolumePrivilege" privilege:
SeIncreaseQuotaPrivilege ... no
SeSecurityPrivilege ... no
SeTakeOwnershipPrivilege ... no
SeLoadDriverPrivilege ... no
SeSystemProfilePrivilege ... no
SeSystemtimePrivilege ... no
SeProfileSingleProcessPrivilege ... no
SeIncreaseBasePriorityPrivilege ... no
SeCreatePagefilePrivilege ... no
SeBackupPrivilege ... no
SeRestorePrivilege ... no
SeShutdownPrivilege ... no
SeDebugPrivilege ... no
SeSystemEnvironmentPrivilege ... no
SeChangeNotifyPrivilege ... no
SeRemoteShutdownPrivilege ... no
SeUndockPrivilege ... no
SeManageVolumePrivilege ... YES! Found it!
SetFileValidData() failed with error #1314.
C:\dev\SetFileValidData_test\Debug>