尝试使用SetFileVaildData()在逻辑上扩展 Windows 8.1 文件时,以下代码失败。
返回的Windows错误代码和消息是:
ERROR_PRIVILEGE_NOT_HELD 1314(0x522)客户端不持有所需的权限。
我将代码作为管理员运行,并且我已声明该进程确实具有使用SE_MANAGE_VOLUME_NAME
和OpenProcessToken()
的{{1}}权限。< / p>
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;
}
答案 0 :(得分:1)
需要启用权限才能使用它们。以下是我的一个启用SE_INCREASE_QUOTE_NAME
和SE_ASSIGNPRIMARYTOKEN_NAME
项目的代码,可以轻松修改它以启用其他权限。
BOOL enable_privs(void)
{
HANDLE token;
struct {
DWORD count;
LUID_AND_ATTRIBUTES privilege[2];
} token_privileges;
token_privileges.count = 2;
token_privileges.privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
token_privileges.privilege[1].Attributes = SE_PRIVILEGE_ENABLED;
if (!LookupPrivilegeValue(0, SE_INCREASE_QUOTA_NAME, &token_privileges.privilege[0].Luid)) return FALSE;
if (!LookupPrivilegeValue(0, SE_ASSIGNPRIMARYTOKEN_NAME, &token_privileges.privilege[1].Luid)) return FALSE;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) return FALSE;
if (!AdjustTokenPrivileges(token, 0, (PTOKEN_PRIVILEGES)&token_privileges, 0, 0, 0)) return FALSE;
if (GetLastError() != ERROR_SUCCESS) return FALSE;
return TRUE;
}