Logically extending file fails

让人想犯罪 __ 提交于 2020-01-15 10:30:34

问题


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>

回答1:


Privileges need to be enabled before you can use them. Here's some code from one of my projects that enables SE_INCREASE_QUOTE_NAME and SE_ASSIGNPRIMARYTOKEN_NAME, it can be easily modified to enable other privileges.

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;
}


来源:https://stackoverflow.com/questions/22295572/logically-extending-file-fails

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!