Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ AdjustTokenPrivileges:错误\u未\u成功后分配的所有\u_C++_Windows_Winapi_Visual C++_Privileges - Fatal编程技术网

C++ AdjustTokenPrivileges:错误\u未\u成功后分配的所有\u

C++ AdjustTokenPrivileges:错误\u未\u成功后分配的所有\u,c++,windows,winapi,visual-c++,privileges,C++,Windows,Winapi,Visual C++,Privileges,我的代码有一个循环,它使用AdjustTokenPrivileges启用SE_DEBUG_NAME权限并将其删除。 每次我运行它时,第一组enable/disable都是成功的,但是在第一个循环之后,其余的enable/remove的give ERROR\u NOT\u ALL\u分配给AdjustTokenPrivileges。 机器是Windows 10 pro 64位。已编译的exe在“以管理员身份运行”模式下运行。 请帮忙 下面的代码在一个循环中 TOKEN_PRIVILEGES pri

我的代码有一个循环,它使用AdjustTokenPrivileges启用SE_DEBUG_NAME权限并将其删除。 每次我运行它时,第一组enable/disable都是成功的,但是在第一个循环之后,其余的enable/remove的give ERROR\u NOT\u ALL\u分配给AdjustTokenPrivileges。 机器是Windows 10 pro 64位。已编译的exe在“以管理员身份运行”模式下运行。 请帮忙

下面的代码在一个循环中

TOKEN_PRIVILEGES priv = { 0,0,0,0 };
HANDLE hToken = NULL;
LUID luid = { 0,0 };
BOOL Status = true;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
    Status = false;
    goto EXIT;
}
if (!LookupPrivilegeValueW(0, lpszPrivilege, &luid)) {
    Status = false;
    goto EXIT;
}
priv.PrivilegeCount = 1;
priv.Privileges[0].Luid = luid;
priv.Privileges[0].Attributes = bEnablePrivilege ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED;
if (!AdjustTokenPrivileges(hToken, false, &priv, 0, 0, 0)) {
    Status = false;
    goto EXIT;
}
std::cout << "priv:" << GetLastError() << std::endl; //gives 0(no error) on first pair of enable/disable, then 0x514, which is ERROR_NOT_ALL_ASSIGNED, on the following loops.
EXIT:
if (hToken)
    CloseHandle(hToken);
return Status;
TOKEN_PRIVILEGES={0,0,0};
句柄hToken=NULL;
LUID LUID={0,0};
布尔状态=真;
如果(!OpenProcessToken(GetCurrentProcess()、标记\u调整\u权限,&hToken)){
状态=假;
转到出口;
}
if(!LookupPrivilegeValueW(0,lpszPrivilege,&luid)){
状态=假;
转到出口;
}
priv.privilegecont=1;
priv.Privileges[0]。Luid=Luid;
priv.Privileges[0]。属性=bEnablePrivilege?启用SE_特权:删除SE_特权;
if(!AdjustTokenPrivileges(hToken、false和priv、0、0、0)){
状态=假;
转到出口;
}
std::cout告诉您原因:

已删除SE_特权

由于该特权已从令牌中删除,因此尝试重新启用该特权会导致警告错误\u NOT \u ALL \u ASSIGNED,就好像该特权从未存在过一样

将属性设置为0以禁用。MSDN有一个例子…

告诉您原因:

已删除SE_特权

由于该特权已从令牌中删除,因此尝试重新启用该特权会导致警告错误\u NOT \u ALL \u ASSIGNED,就好像该特权从未存在过一样

将属性设置为0以禁用。MSDN有一个例子…

感谢Anders

换线

priv.Privileges[0].Attributes = bEnablePrivilege ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED;

修正了密码。但是代码现在只启用/禁用特权。 正如MSDN所说

特权的取消是不可逆转的

因此,我无法将其删除并重新添加。

感谢Anders

换线

priv.Privileges[0].Attributes = bEnablePrivilege ? SE_PRIVILEGE_ENABLED : SE_PRIVILEGE_REMOVED;

修正了密码。但是代码现在只启用/禁用特权。 正如MSDN所说

特权的取消是不可逆转的


因此,我无法将其删除并重新添加。

谢谢。我现在知道如何禁用它了。但如果可能的话,我仍然想删除并重新添加该特权。您不允许向令牌添加内容,一旦它消失,它将永远消失。只需在需要打开和关闭时禁用即可。通常,在多线程进程中,最好通过复制模拟令牌仅为当前线程启用权限。在这种情况下,可以删除特权,因为您可以简单地恢复到流程令牌。可能有这样做的原因,可能与Windows API在某些情况下如何自动为当前线程启用权限有关。删除特权可确保不会发生这种情况。@eryksun但在旧版本中不能删除它们。我通常编写一个返回初始状态的包装器,这样当每个线程都使用它时,只有最后一个线程才真正禁用特权。我相信Windows也是这样做的。删除特权是很久以前引入的,大约在2003年。至于Windows,它在Server2003SP1之前使用的是
BasepAcquirePrivilege
。运行库在Server2003SP2中获得了
RtlAcquirePrivilege
。默认情况下,这将使用当前模拟,或模拟流程令牌(即自Vista以来的
RtlImpersonateSelfEx
)。可选标志支持先恢复到self并直接使用流程令牌(意味着恢复到self)。在使用重复模拟令牌的常见情况下,
RtlReleasePrivilege
只需恢复为self。谢谢。我现在知道如何禁用它了。但如果可能的话,我仍然想删除并重新添加该特权。您不允许向令牌添加内容,一旦它消失,它将永远消失。只需在需要打开和关闭时禁用即可。通常,在多线程进程中,最好通过复制模拟令牌仅为当前线程启用权限。在这种情况下,可以删除特权,因为您可以简单地恢复到流程令牌。可能有这样做的原因,可能与Windows API在某些情况下如何自动为当前线程启用权限有关。删除特权可确保不会发生这种情况。@eryksun但在旧版本中不能删除它们。我通常编写一个返回初始状态的包装器,这样当每个线程都使用它时,只有最后一个线程才真正禁用特权。我相信Windows也是这样做的。删除特权是很久以前引入的,大约在2003年。至于Windows,它在Server2003SP1之前使用的是
BasepAcquirePrivilege
。运行库在Server2003SP2中获得了
RtlAcquirePrivilege
。默认情况下,这将使用当前模拟,或模拟流程令牌(即自Vista以来的
RtlImpersonateSelfEx
)。可选标志支持先恢复到self并直接使用流程令牌(意味着恢复到self)。在使用重复模拟令牌的常见情况下,
RtlReleasePrivilege
只需还原为self;禁用或删除。将
DWORD
属性
字段的值指定为0以禁用权限
NULL
在语义上是为指针保留的(例如
(void*)0
(char*)0
),在某些编译器上,将其指定给整数可能是一个错误。您不能,必须选择一个;禁用或删除。将
DWORD
属性
字段的值指定为0以禁用权限
NULL
在语义上是为指针保留的(例如
(void*)0
(char*)0
),在某些编译器上,将其指定给整数可能是错误的。