From: Vibhav Pant vibhavp@gmail.com
--- dlls/wlanapi/dbus.c | 29 +++++++++++++++-- dlls/wlanapi/main.c | 64 +++++++++++++++++++++++++++++++++++++ dlls/wlanapi/unixlib.c | 22 ++++++++++++- dlls/wlanapi/unixlib.h | 10 ++++++ dlls/wlanapi/unixlib_priv.h | 7 ++-- dlls/wlanapi/wlanapi.spec | 2 +- include/wlanapi.h | 34 ++++++++++++++++++++ 7 files changed, 162 insertions(+), 6 deletions(-)
diff --git a/dlls/wlanapi/dbus.c b/dlls/wlanapi/dbus.c index f0e3ea124e2..a9b13295d54 100644 --- a/dlls/wlanapi/dbus.c +++ b/dlls/wlanapi/dbus.c @@ -634,7 +634,9 @@ static char *__WINE_MALLOC networkmanager_device_get_active_ap( void *connection return dup; }
-NTSTATUS networkmanager_get_access_points( void *connection, const GUID *device, struct list *access_points ) +NTSTATUS networkmanager_get_access_points( void *connection, const GUID *device, + const DOT11_SSID *ssid, BOOL security, + struct list *access_points ) { DBusMessage *request, *reply; DBusError error; @@ -698,8 +700,15 @@ NTSTATUS networkmanager_get_access_points( void *connection, const GUID *device,
if (networkmanager_get_access_point_info( connection, object_path, &info )) { - struct wlan_network *network = calloc( 1, sizeof( *network ) ); + struct wlan_network *network; + + if (ssid && !(info.ssid_len == ssid->uSSIDLength && + !memcmp( info.ssid, ssid->ucSSID, sizeof( info.ssid ) ))) + continue; + if (security && !(info.flags & 1)) /* NM_802_11_AP_FLAGS_PRIVACY */ + continue;
+ network = calloc( 1, sizeof( *network ) ); if (!network) continue; network->info = info; network->info.connected = active_ap && !strcmp( active_ap, object_path ); @@ -847,3 +856,19 @@ void wlan_bss_info_to_WLAN_AVAILABLE_NETWORK( const struct wlan_bss_info *info, if (info->connected) dest->dwFlags |= WLAN_AVAILABLE_NETWORK_CONNECTED; } + +void wlan_bss_info_to_WLAN_BSS_ENTRY( const struct wlan_bss_info *info, WLAN_BSS_ENTRY *dest ) +{ + memset( dest, 0, sizeof( *dest )); + + FIXME( "(%p, %p) semi-stub\n", info, dest ); + memcpy( dest->dot11Ssid.ucSSID, info->ssid, sizeof( info->ssid ) ); + dest->dot11Ssid.uSSIDLength = info->ssid_len; + + memcpy( dest->dot11Bssid, info->hw_address, sizeof( info->hw_address ) ); + dest->dot11BssType = info->mode == NM_802_11_MODE_INFRA ? dot11_BSS_type_infrastructure + : dot11_BSS_type_independent; + dest->uLinkQuality = info->strength; + dest->bInRegDomain = TRUE; + dest->usBeaconPeriod = 1; +} diff --git a/dlls/wlanapi/main.c b/dlls/wlanapi/main.c index f27ce1fba80..e46646eddf9 100644 --- a/dlls/wlanapi/main.c +++ b/dlls/wlanapi/main.c @@ -285,6 +285,70 @@ DWORD WINAPI WlanGetAvailableNetworkList(HANDLE handle, const GUID *guid, DWORD return ERROR_SUCCESS; }
+DWORD WINAPI WlanGetNetworkBssList( HANDLE handle, const GUID *guid, const DOT11_SSID *ssid, + DOT11_BSS_TYPE bss_type, BOOL security, void *reserved, + WLAN_BSS_LIST **bss_list ) +{ + struct wine_wlan *wlan; + struct wlan_network_list_get_params params = {0}; + struct wlan_network_list_move_to_bss_entry_params move_params = {0}; + WLAN_BSS_LIST *ret_list; + NTSTATUS status; + DWORD size; + + TRACE( "(%p, %p, %p, %d, %d, %p, %p)\n", handle, guid, ssid, bss_type, security, reserved, + bss_list ); + + if (!handle || !guid || reserved || !bss_list) + return ERROR_INVALID_PARAMETER; + if (ssid) + { + if (ssid->uSSIDLength > sizeof(ssid->ucSSID)) + return ERROR_INVALID_PARAMETER; + switch (bss_type) + { + case dot11_BSS_type_infrastructure: + case dot11_BSS_type_independent: + case dot11_BSS_type_any: + break; + default: + return ERROR_INVALID_PARAMETER; + } + } + + wlan = handle_index( handle ); + if (!wlan) + return ERROR_INVALID_HANDLE; + + params.handle = wlan->unix_handle; + params.interface = guid; + params.ssid_filter = ssid; + params.security = ssid && security; + status = UNIX_WLAN_CALL( wlan_network_list_get, ¶ms ); + if (status != STATUS_SUCCESS) + return RtlNtStatusToDosError( status ); + + size = offsetof( WLAN_BSS_LIST, wlanBssEntries[params.len] ); + ret_list = WlanAllocateMemory( size ); + if (!ret_list) + { + struct wlan_network_list_free_params free_params = {0}; + free_params.networks = params.networks; + UNIX_WLAN_CALL( wlan_network_list_free, &free_params ); + return ERROR_NOT_ENOUGH_MEMORY; + } + + move_params.networks = params.networks; + move_params.dest = ret_list->wlanBssEntries; + UNIX_WLAN_CALL( wlan_network_list_move_to_bss_entry, &move_params ); + + ret_list->dwTotalSize = size; + ret_list->dwNumberOfItems = params.len; + *bss_list = ret_list; + + return ERROR_SUCCESS; +} + DWORD WINAPI WlanQueryInterface(HANDLE handle, const GUID *guid, WLAN_INTF_OPCODE opcode, void *reserved, DWORD *data_size, void **data, WLAN_OPCODE_VALUE_TYPE *opcode_type) { diff --git a/dlls/wlanapi/unixlib.c b/dlls/wlanapi/unixlib.c index 3b64c55730c..02f5d077100 100644 --- a/dlls/wlanapi/unixlib.c +++ b/dlls/wlanapi/unixlib.c @@ -138,7 +138,8 @@ NTSTATUS wlan_network_list_get( void *params ) if (!networks) return STATUS_NO_MEMORY;
list_init( networks ); - status = networkmanager_get_access_points( (void *)args->handle, args->interface, networks ); + status = networkmanager_get_access_points( (void *)args->handle, args->interface, + args->ssid_filter, args->security, networks ); if (status != STATUS_SUCCESS) { free( networks ); @@ -168,6 +169,24 @@ NTSTATUS wlan_network_list_move_to_avail_network( void *params ) return STATUS_SUCCESS; }
+NTSTATUS wlan_network_list_move_to_bss_entry( void *params ) +{ + struct wlan_network_list_move_to_bss_entry_params *args = params; + struct wlan_network *networks = (struct wlan_network *)args->networks; + struct wlan_network *cur, *next; + SIZE_T i = 0; + + LIST_FOR_EACH_ENTRY_SAFE( cur, next, &networks->entry, struct wlan_network, entry) + { + wlan_bss_info_to_WLAN_BSS_ENTRY( &cur->info, &args->dest[i++] ); + list_remove( &cur->entry ); + free( cur ); + } + + free( networks ); + return STATUS_SUCCESS; +} + NTSTATUS wlan_network_list_free( void *params ) { struct wlan_network_list_free_params *args = params; @@ -195,6 +214,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = {
wlan_network_list_get, wlan_network_list_move_to_avail_network, + wlan_network_list_move_to_bss_entry, wlan_network_list_free, };
diff --git a/dlls/wlanapi/unixlib.h b/dlls/wlanapi/unixlib.h index 06c961c5e36..2776c515e96 100644 --- a/dlls/wlanapi/unixlib.h +++ b/dlls/wlanapi/unixlib.h @@ -64,6 +64,8 @@ struct wlan_network_list_get_params { UINT_PTR handle; const GUID *interface; + const DOT11_SSID *ssid_filter; + BOOL security;
UINT_PTR networks; SIZE_T len; @@ -76,6 +78,13 @@ struct wlan_network_list_move_to_avail_network_params WLAN_AVAILABLE_NETWORK *dest; };
+struct wlan_network_list_move_to_bss_entry_params +{ + UINT_PTR networks; + + WLAN_BSS_ENTRY *dest; +}; + struct wlan_network_list_free_params { UINT_PTR networks; @@ -94,6 +103,7 @@ enum wlanpi_funcs
unix_wlan_network_list_get, unix_wlan_network_list_move_to_avail_network, + unix_wlan_network_list_move_to_bss_entry, unix_wlan_network_list_free,
unix_funcs_count diff --git a/dlls/wlanapi/unixlib_priv.h b/dlls/wlanapi/unixlib_priv.h index 3868218250f..89f0a034d97 100644 --- a/dlls/wlanapi/unixlib_priv.h +++ b/dlls/wlanapi/unixlib_priv.h @@ -58,7 +58,10 @@ extern NTSTATUS init_dbus_connection( UINT_PTR *handle ); extern void close_dbus_connection( void *c ); extern NTSTATUS networkmanager_get_wifi_devices( void *connection, struct list *devices ); extern NTSTATUS networkmanager_get_access_points( void *connection, const GUID *device, - struct list *access_points ); + const DOT11_SSID *ssid, BOOL security, + struct list *access_points ); extern void wlan_bss_info_to_WLAN_AVAILABLE_NETWORK( const struct wlan_bss_info *info, - WLAN_AVAILABLE_NETWORK *dest ); + WLAN_AVAILABLE_NETWORK *dest ); +extern void wlan_bss_info_to_WLAN_BSS_ENTRY( const struct wlan_bss_info *info, + WLAN_BSS_ENTRY *dest ); #endif /* __WINE_WLANAPI_UNIXLIB_PRIV_H */ diff --git a/dlls/wlanapi/wlanapi.spec b/dlls/wlanapi/wlanapi.spec index 45d83c80b0f..6b47812d017 100644 --- a/dlls/wlanapi/wlanapi.spec +++ b/dlls/wlanapi/wlanapi.spec @@ -9,7 +9,7 @@ @ stdcall WlanGetAvailableNetworkList(ptr ptr long ptr ptr) @ stub WlanGetFilterList @ stub WlanGetInterfaceCapability -@ stub WlanGetNetworkBssList +@ stdcall WlanGetNetworkBssList(ptr ptr ptr long long ptr ptr) @ stub WlanGetProfile @ stub WlanGetProfileCustomUserData @ stub WlanGetProfileList diff --git a/include/wlanapi.h b/include/wlanapi.h index 5bd7c969b8c..1f37ba6a183 100644 --- a/include/wlanapi.h +++ b/include/wlanapi.h @@ -136,6 +136,38 @@ typedef struct _WLAN_AVAILABLE_NETWORK DWORD dwReserved; } WLAN_AVAILABLE_NETWORK, *PWLAN_AVAILABLE_NETWORK;
+typedef struct _WLAN_RATE_SET { + ULONG uRateSetLength; + USHORT usRateSet[DOT11_RATE_SET_MAX_LENGTH]; +} WLAN_RATE_SET, *PWLAN_RATE_SET; + +typedef struct _WLAN_BSS_ENTRY +{ + DOT11_SSID dot11Ssid; + ULONG uPhyId; + DOT11_MAC_ADDRESS dot11Bssid; + DOT11_BSS_TYPE dot11BssType; + DOT11_PHY_TYPE dot11BssPhyType; + LONG lRssi; + ULONG uLinkQuality; + BOOLEAN bInRegDomain; + USHORT usBeaconPeriod; + ULONGLONG ullTimestamp; + ULONGLONG ullHostTimestamp; + USHORT usCapabilityInformation; + ULONG ulChCenterFrequency; + WLAN_RATE_SET wlanRateSet; + ULONG ulIeOffset; + ULONG ulIeSize; +} WLAN_BSS_ENTRY, *PWLAN_BSS_ENTRY; + +typedef struct _WLAN_BSS_LIST +{ + DWORD dwTotalSize; + DWORD dwNumberOfItems; + WLAN_BSS_ENTRY wlanBssEntries[1]; +} WLAN_BSS_LIST, *PWLAN_BSS_LIST; + typedef enum _WLAN_INTF_OPCODE { wlan_intf_opcode_autoconf_start = 0x000000000, @@ -261,5 +293,7 @@ DWORD WINAPI WlanScan(HANDLE, const GUID *, const DOT11_SSID *, const WLAN_RAW_D DWORD WINAPI WlanRegisterNotification(HANDLE, DWORD, BOOL, WLAN_NOTIFICATION_CALLBACK, void *, void *, DWORD *); DWORD WINAPI WlanGetAvailableNetworkList(HANDLE, const GUID *, DWORD, void *, WLAN_AVAILABLE_NETWORK_LIST **); DWORD WINAPI WlanQueryInterface(HANDLE, const GUID *, WLAN_INTF_OPCODE, void *, DWORD *, void **, WLAN_OPCODE_VALUE_TYPE *); +DWORD WINAPI WlanGetNetworkBssList( HANDLE, const GUID *, const DOT11_SSID *, DOT11_BSS_TYPE, BOOL, + void *, WLAN_BSS_LIST ** );
#endif /* _WLAN_WLANAPI_H */