1

In my program, I am calling DsGetDcName to get a domain controller.

Microsoft's documentation for DsGetDcName says this:

By default, this function does not ensure that the returned domain controller is currently available. Instead, the caller should attempt to use the returned domain controller.

I can't ping the domain controller to "use the domain controller" as the firewall might be turned on

So, my question is...how do I "attempt to use the returned domain controller"?

#include <Windows.h>
#include <DsGetDC.h>
#include <wchar.h>
#pragma comment(lib, "NetApi32.lib")

int main()
{
    PDOMAIN_CONTROLLER_INFOW pdci{};
    ULONG flags = DS_DIRECTORY_SERVICE_REQUIRED;
    DWORD dwRet = DsGetDcNameW(NULL, NULL, NULL, NULL, flags, &pdci);
    wprintf(L"%s\n", pdci->DomainControllerName);
}
Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84
JeffR
  • 765
  • 2
  • 8
  • 23

1 Answers1

1

I assume you're getting the name of a domain controller because you want to do something with it. So just do whatever you're going to do. You don't need to do anything special.

That remark is just a warning that the first time your code does something that will contact the DC, you should handle the case where the DC is not active. In that case, you can do what the documentation goes on to say:

If the domain controller is not available, the caller should call the DsGetDcName function again, specifying the DS_FORCE_REDISCOVERY flag.

Then you can try again with that new DC.

Realistically, this will be a very rare case. The documentation of the DS_FORCE_REDISCOVERY flag explains why:

When the DS_FORCE_REDISCOVERY flag is not specified, DsGetDcName may return cached domain controller data.

So if the computer has already been using a specific DC, then DsGetDcName will return that DC without checking if it is still available. That means that, really, the only time DsGetDcName will return a DC that cannot be contacted is if the DC suddenly cannot be contacted, which could be a network issue, or even the DC being decommissioned.

Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84
  • So how do I determine if the DC is "not active"? Is there an API call I can use to check if the actual DC is "not active"? – JeffR Feb 07 '22 at 12:26
  • What is your purpose in using `DsGetDcName` in the first place? What are you planning to do with that DC name? – Gabriel Luci Feb 07 '22 at 15:33
  • I have other uses for it, but right now I store the cached DC in a class property. Then, at some point later, I will use the DC name in other functions. So when I get the DC, I want to be able to make sure it's active, and not just the cached one for the system, which may not be active. – JeffR Feb 07 '22 at 15:35
  • 1
    You can use the `DS_FORCE_REDISCOVERY` flag right away to make sure you find an active one. But if you're caching it yourself, you still could run into the same problem of the DC being unavailable when you use it. So wherever you use it, you should account for the possibility of an error and the need for calling `DsGetDcName` again. Or you could just ignore the possibility of the DC being unavailable, depending on what your application is and how important it is that it *never* crashes. It will be a *very* rare case that you may never experience in real use. – Gabriel Luci Feb 07 '22 at 16:02
  • Ok, that makes sense. Thanks for your help. – JeffR Feb 07 '22 at 16:28