in reply to Re^8: Adding WlanConnect() to Win32::Wlan::API (structs no go?)
in thread Adding WlanConnect() to Win32::Wlan::API

Your using a module 6 years older than the current version with .68-.45*100 releases in between. A 6 year old module isn't necessarily bad, but if it has had 2 dozen releases since in 6 years, using such an old version is ill advised. Try using the latest version of Win32::API.

As an experiment, I installed 0.45 of Win32::API, your code still doesn't run.
C:\Documents and Settings\Owner\Desktop\cpan libs\Win32-Wlan-0.06>perl + wlan.pl The system cannot find the file specified at C:/perl512/site/lib/Win32 +/Wlan/API. pm line 381, <DATA> line 164. C:\Documents and Settings\Owner\Desktop\cpan libs\Win32-Wlan-0.06>perl + -MWin32:: API -MWin32::Wlan::API -e "print $Win32::API::VERSION" 0.45 C:\Documents and Settings\Owner\Desktop\cpan libs\Win32-Wlan-0.06>
Internally, Win32::API 0.45 still generates a garbage struct since your using undefined Win32::API types.
#from Win32::API::Struct 0.45 sub Pack { my $self = shift; my($packing, $items, $recipients) = $self->getPack(); DEBUG "(PM)Struct::Pack: $self->{__typedef__}(buffer) = pack($pack +ing, @$items)\n"; $self->{buffer} = pack($packing, @$items); if(DEBUG) { for my $i (0..$self->sizeof-1) { printf " %3d: 0x%02x\n", $i, ord(substr($self->{buffer} +, $i, 1)); } } $self->{buffer_recipients} = $recipients }
$packing contains "SL". I modified Wlan::API's WlanConnect to
sub WlanConnect { croak "Wlan functions are not available" unless $wlan_available; my ($handle, $guuid, $profilename, $ssid) = @_; my $pDot11Ssid = Win32::API::Struct->new('DOT11_SSID'); $pDot11Ssid->{uSSIDLength} = length $ssid; $pDot11Ssid->{ucSSID} = $ssid; my $Wlan_connection_parameters = Win32::API::Struct->new('WLAN_CON +NECTION_PARAMETERS'); $Wlan_connection_parameters->{wlanConnectionMode} = 0; $Wlan_connection_parameters->{strProfile} = $profilename; $Wlan_connection_parameters->{pDot11Ssid} = $pDot11Ssid; $Wlan_connection_parameters->{pDesiredBssidList} = 0; $Wlan_connection_parameters->{dot11BssType} = 3; $Wlan_connection_parameters->{dwFlags} = 0; my $reterr = $API{ WlanConnect }->Call($handle, $guuid, $Wlan_con +nection_parameters, 0); $reterr == 0 or die "WlanConnect return Error $reterr "; };
and reran it under Win32::API, 0.45.
C:\Documents and Settings\Owner\Desktop\cpan libs\Win32-Wlan-0.06>perl + wlan.pl WlanConnect return Error 87 at C:/perl512/site/lib/Win32/Wlan/API.pm +line 382, <DATA> line 164. C:\Documents and Settings\Owner\Desktop\cpan libs\Win32-Wlan-0.06>perl + -MWin32: API -MWin32::Wlan::API -e "print $Win32::API::VERSION" 0.45 C:\Documents and Settings\Owner\Desktop\cpan libs\Win32-Wlan-0.06>
The work around is to use "INT" instead of enums specific types and keep a hash that converts enum slice names (as hash key names) to numeric equivalents (hash key value). Not all the things in WLAN_CONNECTION_PARAMETERS are enums. Some are pointers to other structs. Can I ask what level is your knowledge of C?

update, at first glance, there seems to be a bug in latest Win32::API, a ::Struct with a pointer to a ::Struct is broken, the parent ::Struct always treats the child ::Struct nested inline struct, not a struct pointer. So the Error 87 invalid parameter is the limit of using Win32::API::Struct module. You have to use pack, there probably is no alternative.

Replies are listed 'Best First'.
Re^10: Adding WlanConnect() to Win32::Wlan::API (structs no go?)
by bulk88 (Priest) on Jun 28, 2012 at 02:48 UTC
    i got WlanConnect to work, here is your WlanConnect, it makes my wireless popup bubble come up, so it works
    sub WlanConnect { croak "Wlan functions are not available" unless $wlan_available; my ($handle, $guuid, $profilename, $ssid) = @_; # possibly overkill, a pDot11Ssid = 0 should suffice #my $pDot11Ssid = Win32::API::Struct->new('PDOT11_SSID'); #$pDot11Ssid->{uSSIDLength} = length $ssid; #$pDot11Ssid->{ucSSID} = $ssid; my $SSIDstruct = pack('LZ[32]',length $ssid, $ssid ); #not overflo +w checked my $Wlan_connection_parameters = pack('LPPJLL', 0, $profilename, $ +SSIDstruct, 0, 3, 0); #$Wlan_connection_parameters->{wlanConnectionMode} = 0; #$Wlan_connection_parameters->{strProfile} = $profilename; #$Wlan_connection_parameters->{pDot11Ssid} = $pDot11Ssid; #$Wlan_connection_parameters->{pDesiredBssidList} = 0; #$Wlan_connection_parameters->{dot11BssType} = 3; #$Wlan_connection_parameters->{dwFlags} = 0; my $reterr = $API{ WlanConnect }->Call($handle, $guuid, $Wlan_con +nection_parameters, 0); $reterr == 0 or die "WlanConnect return Error $reterr "; }
    I also changed main for null safety and to work on my machine
    sub main { $ARGV[0] = 'removed'; $ARGV[1] = 'removed'; die "USAGE: $0 PROFILENAME SSID\n" unless($ARGV[1]); my $profilename = $ARGV[0]; my $ssid = $ARGV[1]; my $wlan_handle = WlanOpenHandle(); my @interfaces = WlanEnumInterfaces($wlan_handle); my $wlan_guuid = $interfaces[0]->{guuid}; $profilename = encode('UTF-16LE', $profilename."\x00"); WlanConnect($wlan_handle, $wlan_guuid, $profilename, $ssid); }
    I dont think my pack codes work on x64 BTW. Perhaps another monk can rewrite them to be portable, or you can just make another SOPW post.

      Thanks for the rewrite! It makes sense.

      However. I have to report that perl.exe (ActiveState v5.8.8) dies with an exception when making the call to the native WlanConnect() and Windows pops up its error reporting applet. Well, it might be XP or it might be the adhoc network but I guess that's the end of the line.

      Update: SUCCESS! WlanConnect() connects.

      I had failed to re-adjust the signature. Must be:

      ['WlanConnect' => 'IPPI' => 'I']

      Thanks, bulk88!

        Likely, the exception comes from improperly (un)packing a parameter, or packing it with the wrong width. I would look close at the parameters and their values, and compare them to the C equivalents.

        This gives me a horrible idea - maybe Convert::Binary::C can be abused to generate pack templates for arbitrary structs, as it contains the necessary logic to invoke a C compiler for getting the struct (and alignment) information. A cursory glance doesn't show me the easy way to get a pack/unpack template pair from that, but likely there is a way...