DWORD DsGetDcName( __in LPCTSTR ComputerName, __in LPCTSTR DomainName, __in GUID *DomainGuid, __in LPCTSTR SiteName, __in ULONG Flags, __out PDOMAIN_CONTROLLER_INFO *DomainControllerInfo ); #### typedef struct _DOMAIN_CONTROLLER_INFO { LPTSTR DomainControllerName; LPTSTR DomainControllerAddress; ULONG DomainControllerAddressType; GUID DomainGuid; LPTSTR DomainName; LPTSTR DnsForestName; ULONG Flags; LPTSTR DcSiteName; LPTSTR ClientSiteName; } DOMAIN_CONTROLLER_INFO, *PDOMAIN_CONTROLLER_INFO; #### typedef struct _GUID { DWORD Data1; WORD Data2; WORD Data3; BYTE Data4[8]; }GUID; #### 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); #### 'DcSiteName' => '', 'DnsForestName' => '', 'Flags' => 0, 'DomainControllerName' => 'áµ ', 'DomainControllerAddress' => '', 'buffer' => 'pµ ╘g ( ╘g (╘g ( ╘g (╘g (', '__typedef__' => 'DOMAIN_CONTROLLER_INFO', 'ClientSiteName' => '', 'DomainGuid' => bless( { '__typedef__' => 'GUID', 'Data1' => 0, 'Data3' => 0, 'typedef' => [ [ 'Data1', 'L', 'DWORD' ], [ 'Data2', 'S', 'WORD' ], [ 'Data3', 'S', 'WORD' ], [ 'Data4', 'C*8', 'BYTE' ] ], 'Data4' => '', 'Data2' => 0 }, 'Win32::API::Struct' ), 'buffer_recipients' => [ $VAR1, $VAR1, $VAR1, $VAR1->{'DomainGuid'}, $VAR1->{'DomainGuid'}, $VAR1->{'DomainGuid'}, $VAR1->{'DomainGuid'}, $VAR1, $VAR1, $VAR1, $VAR1, $VAR1 ], 'typedef' => [ [ 'DomainControllerName', 'p', 'LPTSTR' ], [ 'DomainControllerAddress', 'p', 'LPTSTR' ], [ 'DomainControllerAddressType', 'L', 'ULONG' ], [ 'DomainGuid', '>', 'GUID' ], [ 'DomainName', 'p', 'LPTSTR' ], [ 'DnsForestName', 'p', 'LPTSTR' ], [ 'Flags', 'L', 'ULONG' ], [ 'DcSiteName', 'p', 'LPTSTR' ], [ 'ClientSiteName', 'p', 'LPTSTR' ] ], 'DomainName' => '', 'DomainControllerAddressType' => 0 }, 'Win32::API::Struct' ); #### ABSTRACT ^ With this module you can import and call arbitrary functions from Win32's Dynamic Link Libraries (DLL), without having to write an XS extension. Note, however, that this module can't do everything. In fact, parameters input and output is limited to simpler cases.