使用LookupAccountName时访问冲突写入位置0x00000000

在使用NetUserAdd创建用户帐户后,我发现我需要使用NetLocalGroupAddMembers将用户添加到Users组,因此我调用CreateWellKnownSid来获取用户的SID,LookupAccountSid从该SID获取字符串名称并传递给它到NetLocalGroupAddMembers.

我还需要指定用户名,但函数需要domain \ name格式为level 3LOCALGROUP_MEMBERS_INFO_3 ),但我没有。 我决定调用LookupAccountName来获取用户名SID并将其传递给level 0LOCALGROUP_MEMBERS_INFO_0 )。

这就是我做的方式:

 //LocalAlloc UINT memAttributes = LMEM_FIXED; SIZE_T sidSize = SECURITY_MAX_SID_SIZE; //LookupAccountName PSID accountSID; SID_NAME_USE typeOfAccount; //NetLocalGroupAddMembers NET_API_STATUS localGroupAdd; DWORD levelOfData = 0; //LOCALGROUP_MEMBERS_INFO_0 LOCALGROUP_MEMBERS_INFO_0 localMembers; DWORD totalEntries = 0; //Allocate memory for LookupAccountName if (!(accountSID = LocalAlloc(memAttributes, sidSize))) { wprintf(L"\nMemory allocation for account SID failed: \n"); ShowError(GetLastError()); exit(1); } if (!LookupAccountNameW(NULL, argv[1], accountSID, (LPDWORD)&sidSize, NULL, 0, &typeOfAccount)) { fwprintf(stderr, L"Error getting SID from name: \n"); ShowError(GetLastError()); return 1; } //Here I should be able to use NetLocalGroupAddMembers //to add the user passed as argument to the Users group. localMembers.lgrmi0_sid = accountSID; localGroupAdd = NetLocalGroupAddMembers(NULL, name, levelOfData, (LPBYTE)&localMembers, totalEntries); if (localGroupAdd != NERR_Success) { fwprintf(stderr, L"Error adding member to the local group: \n"); ShowError(GetLastError()); return 1; } else { wprintf(L"\nUser %s has been successfully added.\n", argv[1]); } 

这是我得到的错误:

UserCreator.exe中的0x743F059A(sechost.dll)抛出exception:0xC0000005:访问冲突写入位置0x00000000。

有什么线索吗?

提前致谢!

ReferencedDomainName参数实际上不是可选的。

 LPCTSTR machine = NULL, username = /*TEXT("Anders")*/ argv[1]; TCHAR domain[MAX_PATH]; BYTE accountSIDbuf[SECURITY_MAX_SID_SIZE]; PSID accountSID = (PSID) accountSIDbuf; DWORD cbSid = SECURITY_MAX_SID_SIZE, cchRD = MAX_PATH; SID_NAME_USE snu; if (!LookupAccountName(machine, username, accountSID, &cbSid, domain, &cchRD, &snu)) { printf("Error %u\n", GetLastError()); return ; } LPTSTR sidstr; if (!ConvertSidToStringSid(accountSID, &sidstr)) { return ; } _tprintf(_T("SID of %s\\%s is %s\n"), domain, username, sidstr); LocalFree(sidstr); 

您的代码的另一个问题是ShowError(GetLastError()); 调用其他函数后,不能使用GetLastError() 。 改写为

 DWORD error = GetLastError(); fwprintf(stderr, L"Error getting SID from name: \n"); ShowError(error); 

但在这种情况下即使这是错误的,因为NetLocalGroupAddMembers不调用SetLastError ,它只是直接返回错误代码。

编辑:

只是为了澄清参数的用法; 如果要查询域缓冲区所需的大小,可以执行以下操作:

 DWORD cchRD = 0; LookupAccountName(..., NULL, &cchRD, &snu); // The function is still going to report failure LPTSTR domain = malloc(cchRD * sizeof(*domain)); LookupAccountName(..., domain, &cchRD, &snu); 

在我的例子中,我通过传入一个“足够大”的缓冲区来避免这种情况。