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

调用CreateWellKnownSid指定WinAccountAdministratorSid报错,如何获取本地DomainSid?

问题原因与解决方案

你遇到的“参数不正确”错误,核心原因是WinAccountAdministratorSid这个SID类型的特殊性,和你成功使用的WinBuiltinAdministratorsSid/WinBuiltinUsersSid完全不同:

  • WinBuiltinAdministratorsSid是通用的内置管理员组SID,它不依赖具体的域或本地机器,所以调用CreateWellKnownSid时可以直接传NULL作为DomainSid参数。
  • WinAccountAdministratorSid是绑定到特定域/本地机器的内置管理员用户SID,它是基于域/机器的基础SID生成的,必须指定对应的DomainSid参数(不能传NULL),否则就会触发参数错误。

如何获取本地计算机的DomainSid?

要获取本地机器的SID(也就是本地环境下的DomainSid),可以通过LookupAccountNameW函数实现——把本地机器名作为查询对象,就能拿到机器对应的SID。

修改后的完整代码示例

#include <Windows.h>
#include <wchar.h>
#include <LM.h>
#include <locale.h>
#pragma comment(lib, "Netapi32.lib")
#define MAX_NAME 256

VOID ShowError(DWORD errorCode) {
    DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
    LPWSTR errorMessage;
    DWORD size = 0;
    if (!FormatMessageW(flags, NULL, errorCode, 0, (LPWSTR)&errorMessage, size, NULL)) {
        fwprintf(stderr, L"Could not get the format message, error code: %u\n", GetLastError());
        exit(1);
    }
    wprintf(L"\n%s", errorMessage);
    LocalFree(errorMessage);
}

int wmain(int argc, WCHAR **argv) {
    _wsetlocale(LC_ALL, L"English");

    // 第一步:获取本地计算机的SID(DomainSid)
    WCHAR computerName[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD computerNameLen = MAX_COMPUTERNAME_LENGTH + 1;
    if (!GetComputerNameW(computerName, &computerNameLen)) {
        ShowError(GetLastError());
        return 1;
    }

    PSID domainSid = NULL;
    DWORD domainSidSize = 0;
    WCHAR domainName[MAX_NAME];
    DWORD domainNameSize = MAX_NAME;
    SID_NAME_USE sidType;

    // 第一次调用LookupAccountNameW,获取所需内存的大小
    LookupAccountNameW(NULL, computerName, NULL, &domainSidSize, domainName, &domainNameSize, &sidType);
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        ShowError(GetLastError());
        return 1;
    }

    // 分配内存存储DomainSid
    domainSid = (PSID)LocalAlloc(LMEM_FIXED, domainSidSize);
    if (!domainSid) {
        ShowError(GetLastError());
        return 1;
    }

    // 第二次调用,真正获取本地机器的SID
    if (!LookupAccountNameW(NULL, computerName, domainSid, &domainSidSize, domainName, &domainNameSize, &sidType)) {
        ShowError(GetLastError());
        LocalFree(domainSid);
        return 1;
    }

    // 第二步:获取内置管理员用户的SID
    UINT memFlags = LMEM_FIXED;
    DWORD numOfBytes = SECURITY_MAX_SID_SIZE;
    PSID builtInAdminSid = (PSID)LocalAlloc(memFlags, numOfBytes);
    if (!builtInAdminSid) {
        ShowError(GetLastError());
        LocalFree(domainSid);
        return 1;
    }

    WELL_KNOWN_SID_TYPE accountAdminSid = WinAccountAdministratorSid;
    if (!CreateWellKnownSid(accountAdminSid, domainSid, builtInAdminSid, &numOfBytes)) {
        ShowError(GetLastError());
        LocalFree(builtInAdminSid);
        LocalFree(domainSid);
        return 1;
    }

    // 这里可以添加对builtInAdminSid的使用逻辑,比如转换为字符串输出等

    // 记得释放所有分配的内存
    LocalFree(builtInAdminSid);
    LocalFree(domainSid);
    return 0;
}

关键细节说明

  1. 获取本地机器SID:先用GetComputerNameW拿到本地机器的NetBIOS名称,再通过LookupAccountNameW查询这个名称对应的SID——因为本地机器本身也是一个安全主体,它的SID就是我们需要的DomainSid。
  2. CreateWellKnownSid的正确调用:现在传入获取到的domainSid作为第二个参数,就能成功生成绑定到本地机器的内置管理员用户SID了。
  3. 内存管理:所有通过LocalAlloc分配的内存,一定要在使用完成后用LocalFree释放,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:25:36