我需要一种方法来确定运行我的程序的计算机是否加入了任何域。它属于哪个特定域并不重要,只要它是否连接到任何东西。我在 vc++ 中针对 Win32 API 进行编码。
7 回答
直接来自微软:
如何确定 Windows NT/Windows 2000 计算机是否是域成员
此方法使用 Windows API。从文章摘要:
本文介绍如何确定运行 Windows NT 4.0 或 Windows 2000 的计算机是域成员、工作组成员还是使用本地安全机构 API 的独立计算机。
本文还提供了一个小程序的示例代码,该程序输出运行该程序的计算机是域的一部分、工作组的一部分还是独立计算机。
我认为NetServerEnum功能将帮助您实现您想要的;我会要求具有servertype参数SV_TYPE_DOMAIN_CTRL
常量的主域控制器。如果您没有得到任何信息,那么您不在域中。
MSDN 示例中的代码有点过时。这是我想出的有效功能。
bool ComputerBelongsToDomain()
{
bool ret = false;
LSA_OBJECT_ATTRIBUTES objectAttributes;
LSA_HANDLE policyHandle;
NTSTATUS status;
PPOLICY_PRIMARY_DOMAIN_INFO info;
// Object attributes are reserved, so initialize to zeros.
ZeroMemory(&objectAttributes, sizeof(objectAttributes));
status = LsaOpenPolicy(NULL, &objectAttributes, GENERIC_READ | POLICY_VIEW_LOCAL_INFORMATION, &policyHandle);
if (!status)
{
status = LsaQueryInformationPolicy(policyHandle, PolicyPrimaryDomainInformation, (LPVOID*)&info);
if (!status)
{
if (info->Sid)
ret = true;
LsaFreeMemory(info);
}
LsaClose(policyHandle);
}
return ret;
}
这是我没有提到的一种非常简单的方法。
TCHAR UserDnsDomain[128] = { 0 };
DWORD Result = 0;
Result = GetEnvironmentVariable("USERDNSDOMAIN", UserDnsDomain, sizeof(UserDnsDomain));
if (Result == 0 || Result >= sizeof(UserDnsDomain) || GetLastError() == ERROR_ENVVAR_NOT_FOUND)
{
return(FALSE); // Not logged in to a domain
}
这是基于这样的想法,即如果运行此代码的用户当前未登录到域,则 USERDNSDOMAIN 环境变量将为空或不可用。但是您应该考虑一些注意事项。
优点:
- 很容易实现。
- 99% 可靠。
缺点:
- 如果计算机已加入域,但执行此代码的用户使用本地帐户登录到该计算机,则可能会失败或返回错误结果。
- 如果计算机已加入域,但在登录/用户使用缓存凭据登录时与域控制器的网络连接不可用,则可能会失败或返回错误结果。
您可以检查注册表项 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon 以获取“CachePrimaryDomain”的值。
从计算机的名称来看呢?
编辑:这是一个糟糕的“答案”。我的意思是检查domain\name
计算机名称中的表格。这当然意味着您确实知道域的名称,它并不能解决仅知道计算机是否在任何域中的问题。
避免 LSA,这是一种错误的方法。您必须使用 DS api(2 行代码)