views:

715

answers:

6

I need a way to determine whether the computer running my program is joined to any domain. It doesn't matter what specific domain it is part of, just whether it is connected to anything. I'm coding in vc++ against the Win32 API.

A: 

what about from the name of the computer?

sebastian
As far as I know, all Windows computers have to have a name, regardless of whether they're on a network or not.
Head Geek
+1  A: 

You can check the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon for the value of 'CachePrimaryDomain'.

MSDN says this key is no longer in use as of Windows 2000, but was kept for backwards compat. This makes me wonder if it is safe to use?
Kurt
+2  A: 

I think the NetServerEnum function will help you in what you want; I would ask for the primary domain controllers with the SV_TYPE_DOMAIN_CTRL constant for servertype parameter. If you don't get any, then you're not in a domain.

ΤΖΩΤΖΙΟΥ
+4  A: 

Straight from Microsoft:

How To Determine If a Windows NT/Windows 2000 Computer Is a Domain Member

This approach uses the Windows API. From the article summary:

This article describes how to determine if a computer that is running Windows NT 4.0 or Windows 2000 is a member of a domain, is a member of a workgroup, or is a stand-alone computer using the Local Security Authority APIs.

The article also provides sample code for a small program that outputs whether the computer the program is running on is part of a domain, part of a workgroup, or a standalone computer.

Mike Spross
+1  A: 

The code in the MSDN sample is a little outdated. This is the function I came up with that works.

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;
}
Kurt
A: 

Avoid LSA which is a wrong method. You must use DS api (2 lines of code)