in reply to Re^7: Adding WlanConnect() to Win32::Wlan::API (modded Wlan::API.pm)
in thread Adding WlanConnect() to Win32::Wlan::API

So, I take it that even with properly declared types, Win32::API::Struct is a no go here as the native Wlan API uses enums all over the place, e.g. those DOT11 things?

There are no workarounds? I mean, in the call to the DLL, I cut corners by using ints.

Code doesn't run? OK, I had just typed the .pl in w/o testing it. Now, I just d/led script and module from the website and they don't throw errors here. My Struct.pm contains this header info:

###################################################################### +# # # Win32::API::Struct - Perl Win32 API struct Facility # # Version: 0.45 # Date: 28 Nov 2006 # Author: Aldo Calpini <dada@perl.it> # Maintainer: Cosimo Streppone <cosimo@cpan.org> # # $Id: Struct.pm,v 1.0 2001/10/30 13:57:31 dada Exp $ ###################################################################### +#

Replies are listed 'Best First'.
Re^9: Adding WlanConnect() to Win32::Wlan::API (structs no go?)
by bulk88 (Priest) on Jun 27, 2012 at 21:47 UTC
    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.
      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!