WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Samples from Users

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

DsGetDcName

 Keywords: DsGetDcName _DOMAIN_CONTROLLER_INFOA Pointer Structure InControl 32 Byte Long CLSIDFromString StringFromGUID2

#DefineFunction fGetDC(sComputerName, sDomain, sGUID, sSiteName, lFlags) ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms675983(v=vs.85).aspx
   ;******************************************************************************************************************
   ;constants used for the API DsGetDCName
   ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms675983(v=vs.85).aspx

   ;******************************************************************************************************************
   ;Flags to passed to DsGetDcName
   DS_FORCE_REDISCOVERY            =xHex(00000001)
   DS_DIRECTORY_SERVICE_REQUIRED   =xHex(00000010)
   DS_DIRECTORY_SERVICE_PREFERRED  =xHex(00000020)
   DS_GC_SERVER_REQUIRED           =xHex(00000040)
   DS_PDC_REQUIRED                 =xHex(00000080)
   DS_BACKGROUND_ONLY              =xHex(00000100)
   DS_IP_REQUIRED                  =xHex(00000200)
   DS_KDC_REQUIRED                 =xHex(00000400)
   DS_TIMESERV_REQUIRED            =xHex(00000800)
   DS_WRITABLE_REQUIRED            =xHex(00001000)
   DS_GOOD_TIMESERV_PREFERRED      =xHex(00002000)
   DS_AVOID_SELF                   =xHex(00004000)
   DS_ONLY_LDAP_NEEDED             =xHex(00008000)
   DS_IS_FLAT_NAME                 =xHex(00010000)
   DS_IS_DNS_NAME                  =xHex(00020000)
   DS_TRY_NEXTCLOSEST_SITE         =xHex(00040000)
   DS_DIRECTORY_SERVICE_6_REQ      =xHex(00080000) ;ORIGINAL NAME "DS_DIRECTORY_SERVICE_6_REQUIRED" renamed since WB does not support vars longer than 30 chars
   DS_WEB_SERVICE_REQUIRED         =xHex(00100000)
   DS_DIRECTORY_SERVICE_8_REQ      =xHex(00200000) ;ORIGINAL NAME "DS_DIRECTORY_SERVICE_8_REQUIRED" renamed since WB does not support vars longer than 30 chars
   DS_RETURN_DNS_NAME              =xHex(40000000)
   DS_RETURN_FLAT_NAME             =xHex(80000000)

   ;******************************************************************************************************************
   ;dllcall return values
   ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx
   ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms681383(v=vs.85).aspx
   ERROR_SUCCESS                   =xHex(0)     ;0
   ERROR_INVALID_DOMAINNAME        =xHex("4BC") ;1212
   ERROR_INVALID_FLAGS             =xHex("3EC") ;1004
   ERROR_NOT_ENOUGH_MEMORY         =xHex(8)     ;8
   ERROR_NO_SUCH_DOMAIN            =xHex("54B") ;1355

   ;******************************************************************************************************************
   ;address type returns
   DS_INET_ADDRESS                 =1
   DS_NETBIOS_ADDRESS              =2

   ;******************************************************************************************************************
   ;return flags
   DS_PDC_FLAG                     =xHex(00000001)   ;    // DC is PDC of Domain
   DS_GC_FLAG                      =xHex(00000004)   ;    // DC is a GC of forest
   DS_LDAP_FLAG                    =xHex(00000008)   ;    // Server supports an LDAP server
   DS_DS_FLAG                      =xHex(00000010)   ;    // DC supports a DS and is a Domain Controller
   DS_KDC_FLAG                     =xHex(00000020)   ;    // DC is running KDC service
   DS_TIMESERV_FLAG                =xHex(00000040)   ;    // DC is running time service
   DS_CLOSEST_FLAG                 =xHex(00000080)   ;    // DC is in closest site to client
   DS_WRITABLE_FLAG                =xHex(00000100)   ;    // DC has a writable DS
   DS_GOOD_TIMESERV_FLAG           =xHex(00000200)   ;    // DC is running time service (and has clock hardware)
   DS_NDNC_FLAG                    =xHex(00000400)   ;    // DomainName is non-domain NC serviced by the LDAP server
   DS_SELECT_SECRET_DOMAIN_6_FLAG  =xHex(00000800)   ;    // DC has some secrets
   DS_FULL_SECRET_DOMAIN_6_FLAG    =xHex(00001000)   ;    // DC has all secrets
   DS_WS_FLAG                      =xHex(00002000)   ;    // DC is running web service
   DS_DS_8_FLAG                    =xHex(00004000)   ;    // DC is running Win8 or later
   DS_PING_FLAGS                   =xHex("000FFFFF") ;    // Flags returned on ping
   DS_DNS_CONTROLLER_FLAG          =xHex(20000000)   ;    // DomainControllerName is a DNS name
   DS_DNS_DOMAIN_FLAG              =xHex(40000000)   ;    // DomainName is a DNS name
   DS_DNS_FOREST_FLAG              =xHex(80000000)   ;    // DnsForestName is a DNS name

   DebugTrace(22)

   ;// Structure returned from DsGetDcName
   ;
   ;typedef struct _DOMAIN_CONTROLLER_INFOA { ; total size = 48bytes
   ;    LPSTR DomainControllerName;  as long, width: 4, offset: 0
   ;    LPSTR DomainControllerAddress;  as long, width: 4, offset: 4
   ;    ULONG DomainControllerAddressType; as byte, width: 4, offset: 8
   ;    GUID DomainGuid;  read as 15 word(s),  width: 16, offsets: 12 though 26, term at 27
   ;    LPSTR DomainName;  as long, width: 4, offset: 28
   ;    LPSTR DnsForestName;  as long, width: 4, offset: 32
   ;    ULONG Flags;  as word, width: 4, offset: 36
   ;    LPSTR DcSiteName;  as long, width: 4, offset: 40
   ;    LPSTR ClientSiteName;  as long, width: 4, offset: 44
   ;} DOMAIN_CONTROLLER_INFOA, *PDOMAIN_CONTROLLER_INFOA;

   If sGUID==""
      pGUID=BinaryAlloc(0)
   Else
      dll_Ole32=DllLoad(DirWindows(1):"Ole32.dll")
      ;bin_GUID=BinaryAlloc(76)
      pGUID=BinaryAlloc(4)
      ;binaryPokeStrW(bin_GUID, 0, sGUID)
      DllCall(dll_Ole32,long:"CLSIDFromString",lpwstr:sGUID,lpbinary:pGUID))
      DllFree(dll_Ole32)
      ;binaryfree(bin_GUID)
   EndIf

   ;the code below modified from suggestion by *-~tonyd-~* from winbatch support.  i was stuck on the secondary extraction.  not sure if i would hav eeventually gotten it
   ;many thanksssss
   hpp_DCStructure=BinaryAlloc(4)  ;create buffer handle to hold the structure info
   dll_NetAPI32=DllLoad(DirWindows(1):"Netapi32.dll")
   ret_dsGetDCName=DllCall(dll_NetAPI32, long:"DsGetDcNameA", lpstr:sComputerName, lpstr:sDomain, lpbinary:pGUID, lpstr:sSiteName, long:lFlags, lpbinary:hpp_DCStructure)

   If ret_dsGetDCName==ERROR_INVALID_DOMAINNAME
      sMsgText="Error: ":ret_dsGetDCName:", ERROR_INVALID_DOMAINNAME":@CRLF:"The format of the specified DomainName is invalid."
   ElseIf ret_dsGetDCName==ERROR_INVALID_FLAGS
      sMsgText="Error: ":ret_dsGetDCName:", ERROR_INVALID_FLAGS":@CRLF:"The Flags parameter contains conflicting or superfluous flags."
   ElseIf ret_dsGetDCName==ERROR_NOT_ENOUGH_MEMORY
      sMsgText="Error: ":ret_dsGetDCName:", ERROR_NOT_ENOUGH_MEMORY":@CRLF:"A memory allocation failure occurred."
   ElseIf ret_dsGetDCName==ERROR_NO_SUCH_DOMAIN
      sMsgText="Error: ":ret_dsGetDCName:", ERROR_NO_SUCH_DOMAIN":@CRLF:"No domain controller is available for the specified domain or the domain does not exist."
   Else
      sMsgText="Error: ":ret_dsGetDCName:", Unknown Error"
   EndIf

   If ret_dsGetDCName!=ERROR_SUCCESS Then xMessageBox("Error", "The system could not contact a domain controller.  Make sure the system is connected to the network.  The error returned was:":@CRLF:@CRLF:sMsgText, xHex(10))
   If ret_dsGetDCName!=ERROR_SUCCESS Then Return(-1)

   p2b_DCStructure=BinaryPeek4(hpp_DCStructure, 0) ;extract the structure info (memory address) captured by dllcall

   ;parse info
   pDCName=IntControl(32, p2b_DCStructure, "LONG", 0, 0) ; read structure's first element string pointer here. for other values, change offset (add to p2b_DCStructure) and type (if necessary)
   sDCName=fGetStringFromPointer(pDCName)

   pDCAddress=IntControl(32, p2b_DCStructure+4, "LONG", 0, 0)  ; read structure's second element string pointer here (mem address + offset).
   sDCAddress=fGetStringFromPointer(pDCAddress)

   iDCAddressType=IntControl(32, p2b_DCStructure+8, "BYTE", 0, 0)  ; read structure's third element byte value here (mem address + offset).

   If IntControl(32, p2b_DCStructure+12, "WORD", 0, 0) ;if the first offset in the structure's fourth element is NOT zero then we have a GUID to parse (?) - don't have a domain with NO GUID to test on...
      hDomainGuid=BinaryAlloc(16)  ;create a buffer to hold the GUID for when we convert it to a string
      For iDomainGuid_loopcount=0 To 14  ;fill the buffer with each read of the GUID values - 15 word 'values' (is 16 is terminator??) so BinaryPoke2 for the 16 bit words...
         BinaryPoke2(hDomainGuid, iDomainGuid_loopcount, IntControl(32, p2b_DCStructure + 12 + iDomainGuid_loopcount, "WORD", 0, 0))
      Next
      GUID_LENGTH=38 ;set guid length constant
      hGUID=BinaryAlloc((GUID_LENGTH+1)*2) ;create the nahdles for the returned GUID string, add null terminator and double size for unicode
      dll_ole32=DllLoad(DirWindows(1):"ole32.dll")
      iGUID_Length=DllCall(dll_ole32,long:"StringFromGUID2",lpbinary:hDomainGuid,lpbinary:hGUID,long:(GUID_LENGTH+1)*2)
      BinaryEodSet(hGUID, (GUID_LENGTH+1)*2)
      BinaryConvert(hGUID, 3, 0, 0, 0)
      sDomainGuid=BinaryPeekStr(hGUID, 0, iGUID_Length)
      BinaryFree(hGUID)
      BinaryFree(hDomainGuid)
      DllFree(dll_ole32)
   Else
      sDomainGuid="NULL"
   EndIf

   pDomainName=IntControl(32, p2b_DCStructure+28, "LONG", 0, 0)  ; read structure's fifth element string pointer here (mem address + offset).
   sDomainName=fGetStringFromPointer(pDomainName)

   pDNSForestName=IntControl(32, p2b_DCStructure+32, "LONG", 0, 0)
   sDNSForestName=fGetStringFromPointer(pDomainName)

   pFlags=IntControl(32, p2b_DCStructure+36, "WORD", 0, 0)
   lstFlags=""
   If pFlags
      If pFlags & DS_PDC_FLAG Then lstFlags=ItemInsert("DS_PDC_FLAG", -1, lstFlags, "|")
      If pFlags & DS_GC_FLAG Then lstFlags=ItemInsert("DS_GC_FLAG", -1, lstFlags, "|")
      If pFlags & DS_LDAP_FLAG Then lstFlags=ItemInsert("DS_LDAP_FLAG", -1, lstFlags, "|")
      If pFlags & DS_DS_FLAG Then lstFlags=ItemInsert("DS_DS_FLAG", -1, lstFlags, "|")
      If pFlags & DS_KDC_FLAG Then lstFlags=ItemInsert("DS_KDC_FLAG", -1, lstFlags, "|")
      If pFlags & DS_TIMESERV_FLAG Then lstFlags=ItemInsert("DS_TIMESERV_FLAG", -1, lstFlags, "|")
      If pFlags & DS_CLOSEST_FLAG Then lstFlags=ItemInsert("DS_CLOSEST_FLAG", -1, lstFlags, "|")
      If pFlags & DS_WRITABLE_FLAG Then lstFlags=ItemInsert("DS_WRITABLE_FLAG", -1, lstFlags, "|")
      If pFlags & DS_GOOD_TIMESERV_FLAG Then lstFlags=ItemInsert("DS_GOOD_TIMESERV_FLAG", -1, lstFlags, "|")
      If pFlags & DS_NDNC_FLAG Then lstFlags=ItemInsert("DS_NDNC_FLAG", -1, lstFlags, "|")
      If pFlags & DS_SELECT_SECRET_DOMAIN_6_FLAG Then lstFlags=ItemInsert("DS_SELECT_SECRET_DOMAIN_6_FLAG", -1, lstFlags, "|")
      If pFlags & DS_FULL_SECRET_DOMAIN_6_FLAG Then lstFlags=ItemInsert("DS_FULL_SECRET_DOMAIN_6_FLAG", -1, lstFlags, "|")
      If pFlags & DS_WS_FLAG Then lstFlags=ItemInsert("DS_WS_FLAG", -1, lstFlags, "|")
      If pFlags & DS_DS_8_FLAG Then lstFlags=ItemInsert("DS_DS_8_FLAG", -1, lstFlags, "|")
      If pFlags & DS_PING_FLAGS Then lstFlags=ItemInsert("DS_PING_FLAGS", -1, lstFlags, "|")
      If pFlags & DS_DNS_CONTROLLER_FLAG Then lstFlags=ItemInsert("DS_DNS_CONTROLLER_FLAG", -1, lstFlags, "|")
      If pFlags & DS_DNS_DOMAIN_FLAG Then lstFlags=ItemInsert("DS_DNS_DOMAIN_FLAG", -1, lstFlags, "|")
      If pFlags & DS_DNS_FOREST_FLAG Then lstFlags=ItemInsert("DS_DNS_FOREST_FLAG", -1, lstFlags, "|")
   EndIf

   pDcSiteName=IntControl(32, p2b_DCStructure+40, "LONG", 0, 0)
   If pDcSiteName Then sDcSiteName=fGetStringFromPointer(pDcSiteName)
      Else sDcSiteName="NULL"

   pClientSiteName=IntControl(32, p2b_DCStructure+44, "LONG", 0, 0)
   If pClientSiteName Then sClientSiteName=fGetStringFromPointer(pClientSiteName)
      Else sClientSiteName="NULL"

   ;combine values for return
   lstDCInfo=sDCName:@TAB:sDCAddress:@TAB:iDCAddressType:@TAB:sDomainGuid:@TAB:sDomainName:@TAB:sDNSForestName:@TAB:lstFlags:@TAB:sDcSiteName:@TAB:sClientSiteName

   DllCall(dll_NetAPI32, long:"NetApiBufferFree", long:hpp_DCStructure)
   BinaryFree(hpp_DCStructure)
   BinaryFree(pGUID)
   DllFree(dll_NetAPI32)
   Return(lstDCInfo)
#EndFunction
;-------------------------------------------
#DefineFunction fGetStringFromPointer(pointer)
   DebugTrace(22)
   strFromPointer=""
   ;errormode(@off)
   cValue=IntControl(32, pointer, "BYTE", 0, 0)
   ;errormode(@on)
   While cValue
      strFromPointer=strFromPointer:Num2Char(cValue)
      pointer=pointer + 1
      cValue=IntControl(32, pointer, "BYTE", 0,0)
   EndWhile
   Return(strFromPointer)
#EndFunction
;-------------------------------------------


AddExtender("wilx44i.dll")

;fGetDC(sComputerName, sDomain, sGUID, sSiteName, lFlags)
sComputerName=""
sDomain=AskLine("Get DC", "enter the name of a fully qualifed domain:", "")
sGUID=""
sSiteName=""
lFlags=xHex(00000001) ;DS_FORCE_REDISCOVERY


lstDCInfo=fGetDC(sComputerName, sDomain, sGUID, sSiteName, lFlags)

AskTextbox("", "", StrReplace(lstDCInfo, @TAB, @CRLF), 0, 0)
Exit


Article ID:   W17544
Filename:   DsGetDcName.txt
File Created: 2013:03:14:10:45:34
Last Updated: 2013:03:14:10:45:34