You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows 10下AdjustTokenPrivileges循环调用后出现ERROR_NOT_ALL_ASSIGNED问题求助

解决循环调用AdjustTokenPrivileges返回ERROR_NOT_ALL_ASSIGNED的问题

哥们,我之前也踩过这个坑!你这个情况大概率是没有在每次循环结束后正确清理令牌句柄,或者第一次权限调整后令牌状态残留导致的。咱们一步步来解决:

问题根源分析

第一次调用AdjustTokenPrivileges成功启用/移除权限后,如果没关闭hToken句柄,下次循环再打开令牌时可能拿到的是同一个句柄,而此时令牌的内部权限状态已经混乱,导致后续调用时系统认为你要分配的权限没被正确授权,就返回ERROR_NOT_ALL_ASSIGNED了。

另外,当你尝试移除一个已经被移除的权限时,AdjustTokenPrivileges也会返回这个错误,这其实是正常的,但如果没正确处理句柄,就会变成循环里的持续问题。

具体修复方案

1. 每次循环必须关闭令牌句柄

这是最关键的一步!每次权限操作完成后,一定要用CloseHandle(hToken)关闭句柄,避免句柄泄漏和状态残留。给你调整后的循环内代码示例:

// 循环体内的完整逻辑
TOKEN_PRIVILEGES priv = { 0 };
HANDLE hToken = NULL;
LUID luid = { 0 };

// 1. 重新打开当前进程的令牌(每次循环都要重新获取)
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
    // 处理打开令牌失败的错误,比如输出GetLastError()
    goto Cleanup;
}

// 2. 获取SE_DEBUG_NAME的LUID值
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid)) {
    // 处理查找权限失败的错误
    goto Cleanup;
}

// 3. 启用SE_DEBUG权限
priv.PrivilegeCount = 1;
priv.Privileges[0].Luid = luid;
priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

if (!AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
    DWORD err = GetLastError();
    if (err != ERROR_NOT_ALL_ASSIGNED) {
        // 这里才是真正的启用失败,需要处理
    }
}

// --- 这里执行你需要SE_DEBUG权限的操作 ---

// 4. 移除SE_DEBUG权限
priv.Privileges[0].Attributes = 0;
if (!AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
    DWORD err = GetLastError();
    // 移除时返回ERROR_NOT_ALL_ASSIGNED是正常的,因为权限可能已经被移除,不用处理
    if (err != ERROR_NOT_ALL_ASSIGNED) {
        // 处理其他移除错误
    }
}

Cleanup:
// 关键!每次循环结束都要关闭令牌句柄
if (hToken != NULL) {
    CloseHandle(hToken);
}

2. 正确处理移除权限时的ERROR_NOT_ALL_ASSIGNED

当你第二次及以后移除权限时,权限本来就处于未启用状态,此时AdjustTokenPrivileges返回ERROR_NOT_ALL_ASSIGNED是正常现象,不用把它当成致命错误处理,只要确保后续关闭句柄即可。

3. 每次循环都重新打开令牌

不要复用之前的hToken句柄,每次循环都通过OpenProcessToken获取新的令牌句柄,这样能彻底避免之前的权限操作残留状态影响后续调用。

额外注意点

  • 确保你的程序确实是以管理员身份运行,SE_DEBUG_NAME权限只有管理员才能申请到;
  • 调用AdjustTokenPrivileges后,要用GetLastError()区分错误类型:启用权限时如果返回TRUE但GetLastError()是ERROR_NOT_ALL_ASSIGNED,说明权限没被成功启用,这才是需要处理的问题;移除时的该错误可以直接忽略。

内容的提问来源于stack exchange,提问作者alvinma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:54:55