use Win32::API; use strict; use Error qw(:try); use Data::Dumper; # Define result constants use constant ERROR_INVALID_DOMAINNAME => 1212; # The format of the specified DomainName is invalid. use constant ERROR_INVALID_FLAGS => 1004; # The Flags parameter contains conflicting or superfluous flags. use constant ERROR_NOT_ENOUGH_MEMORY => 8; # A memory allocation failure occurred. use constant ERROR_NO_SUCH_DOMAIN => 1355; # No domain controller is available for the specified domain or the domain does not exist. use constant ERROR_SUCCESS => 0; # No worries! # Define structs used as parameters typedef Win32::API::Struct GUID => qw { DWORD Data1; WORD Data2; WORD Data3; BYTE Data4[8]; }; typedef Win32::API::Struct DOMAIN_CONTROLLER_INFO => qw { LPTSTR DomainControllerName; LPTSTR DomainControllerAddress; ULONG DomainControllerAddressType; GUID DomainGuid; LPTSTR DomainName; LPTSTR DnsForestName; ULONG Flags; LPTSTR DcSiteName; LPTSTR ClientSiteName; }; # Create instances of these structs my $domainguid = Win32::API::Struct->new('GUID'); my $dci = Win32::API::Struct->new('DOMAIN_CONTROLLER_INFO'); #Import our function my $DsGetDcName = Win32::API->new('Netapi32', 'DsGetDcName', 'PPSPNS', 'N') or die Win32::FormatMessage(Win32::GetLastError); if (not defined $DsGetDcName) {die "Couldn't get DsGetDcName! $!\n";} try { # Call the imported function... my $dc = $DsGetDcName->Call('mymachine', 'mydomain', $domainguid, 'myADsite', 0x00020000, $dci); print "Return value: [$dc]\n"; if ($dc == ERROR_INVALID_DOMAINNAME) {print "ERROR_INVALID_DOMAINNAME\n"} if ($dc == ERROR_INVALID_FLAGS) {print "ERROR_INVALID_FLAGS\n"} if ($dc == ERROR_NOT_ENOUGH_MEMORY) {print "ERROR_NOT_ENOUGH_MEMORY\n"} if ($dc == ERROR_NO_SUCH_DOMAIN) {print "ERROR_NO_SUCH_DOMAIN\n"} if ($dc == ERROR_SUCCESS) {print "ERROR_SUCCESS\n"} } catch Error with { my $err = shift; print "Error: $err\n"; }; print Dumper($dci);