为什么这个 for 循环在 C 中的第二次迭代中卡住了?

问题描述 投票:0回答:1

在 C 中,我正在创建一个使用 WinAPI 的程序。对于这个程序,我正在编写一个函数来启用指定的权限。这是我所拥有的:

void EnablePrivileges(LPCWSTR awszPrivileges[], DWORD dwCount){
     HANDLE hToken;
     if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {
          printf("Failed to open process token. Error: %lu\n", GetLastError());
          return;
     }
     TOKEN_PRIVILEGES tp;
     tp.PrivilegeCount = dwCount;
     for (DWORD i = 0; i < dwCount; ++i) {
          wprintf(TEXT("Privilege constant: %ls | Iterator value: %i\n"), awszPrivileges[i], i);
          if(!LookupPrivilegeValueW(NULL, awszPrivileges[i], &tp.Privileges[i].Luid)) {
               printf("Failed to lookup privilege value. Error: %lu\n", GetLastError());
               CloseHandle(hToken);
               return;
          }
          tp.Privileges[i].Attributes = SE_PRIVILEGE_ENABLED;
     }
     if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) {
          printf("Failed to adjust token privileges. Error: %lu\n", GetLastError());
     } else {
          printf("Token privileges adjusted successfully.\n");
     }
     CloseHandle(hToken);
}

int main() {
     LPCWSTR awszPrivileges[] = {SE_TAKE_OWNERSHIP_NAME, SE_AUDIT_NAME, SE_RESTORE_NAME};
     EnablePrivileges(awszPrivileges, 3);
     system("pause");
     return 0;
}

它的编译为零错误。

但是,当我使用管理权限运行它时,它会给出以下内容:

Privilege constant: SeTakeOwnershipPrivilege | Iterator value: 0
Privilege constant: SeAuditPrivilege | Iterator value: 1
Privilege constant: SeAuditPrivilege | Iterator value: 1
Privilege constant: SeAuditPrivilege | Iterator value: 1
Privilege constant: SeAuditPrivilege | Iterator value: 1
Privilege constant: SeAuditPrivilege | Iterator value: 1

...等等。

当只有两个权限尝试启用时,它也会这样做。然而,它只用一个就可以成功工作。

是什么导致 for 循环出现这样的行为?此错误的修复方法是什么?

c winapi
1个回答
0
投票

您正在谈论

tp.Privileges
的结尾。该数组的大小为 1。如文档中所述:

重要 常量

ANYSIZE_ARRAY
在公共头文件 Winnt.h 中定义为 1。要创建包含多个元素的数组,您必须为该结构分配足够的内存以考虑其他元素。

您必须分配一个至少

sizeof(TOKEN_PRIVILEGES) + (dwCount - 1) * sizeof(LUID_AND_ATTRIBUTES)
(正确对齐)的内存块,并在那里初始化您的
TOKEN_PRIVILEGES
对象。

© www.soinside.com 2019 - 2024. All rights reserved.