我想确定本地Windows系统是否连接到网络域(而不是工作组),如果是,请读取域的名称。
我找到了这些Windows API函数来实现此目的:
GetEnvironmentVariable('USERDNSDOMAIN')
NetGetJoinInformation
NetServerGetInfo
NetWkstaGetInfo
LookupaccountSid
它们之间是否有优点或缺点? (更快,更可靠,更准确...)
您会推荐哪个?为什么?
LookupAccountSid
更加专注于搜索sid,NetServerGetInfo
更加专注于检索服务器信息。
因此,这些都不适合您。
从NetGetJoinInformation
和NetWkstaGetInfo
获得的域名对应于USERDOMAIN
而不是USERDNSDOMAIN
,具体取决于您想要的域名。
GetEnvironmentVariable
是仅获取变量值并且可以随时由SetEnvironmentVariable
进行修改的函数(即使我们通常不这样做),因此不建议使用它。
无需特殊的组成员身份即可成功执行
NetGetJoinInformation
功能。
它比NetWkstaGetInfo
更纯(根据您的要求)
最直接,最有效的方法-用 PolicyDnsDomainInformation 调用LsaQueryInformationPolicy
。在输出中,您获得了POLICY_DNS_DOMAIN_INFO
结构。这将是主域的名称和DNS名称。还有 SID
如果与“策略”对象关联的计算机不是以下计算机的成员 域,除Name以外的所有结构成员均为NULL或零。
#include <Ntsecapi.h>
NTSTATUS PrintDomainName()
{
LSA_HANDLE PolicyHandle;
static LSA_OBJECT_ATTRIBUTES oa = { sizeof(oa) };
NTSTATUS status = LsaOpenPolicy(0,&oa,POLICY_VIEW_LOCAL_INFORMATION,&PolicyHandle);
if (LSA_SUCCESS(status))
{
PPOLICY_DNS_DOMAIN_INFO ppddi;
if (LSA_SUCCESS(status = LsaQueryInformationPolicy(PolicyHandle,PolicyDnsDomainInformation,(void**)&ppddi)))
{
if (ppddi->Sid)
{
DbgPrint("DnsDomainName: %wZ\n",&ppddi->DnsDomainName);
}
else
{
DbgPrint("%wZ: not a member of a domain\n",&ppddi->Name);
}
LsaFreeMemory(ppddi);
}
LsaClose(PolicyHandle);
}
return status;
}
NetGetJoinInformation
内部执行相同的操作-查询 PolicyDnsDomainInformation ,但不是在您的远程过程中执行此操作( svchost.exe -k networkservice -p -s LanmanWorkstation - LanmanWorkstation 服务)和许多其他调用。因此效率较低,但调用此api的源代码较少