From bb8b097c7dafd885a1e08c804cdb8d07791ea891 Mon Sep 17 00:00:00 2001 From: Floris Bos Date: Sun, 21 May 2023 17:22:17 +0200 Subject: [PATCH] Windows: lazy load wlanapi.dll Appearently wlanapi.dll (which we use to borrow the wlan password from the computer running Imager) is not always present on the server editions of Windows, so only load it if it exists. Ref #584 --- src/CMakeLists.txt | 15 +++++++++++---- src/windows/winwlancredentials.cpp | 25 +++++++++++++++++++++++++ src/windows/wlanapi.def | 9 +++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 src/windows/wlanapi.def diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d191b7d..533cbfc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,8 +8,8 @@ OPTION (ENABLE_TELEMETRY "Enable sending telemetry" ON) project(rpi-imager LANGUAGES CXX C) set(IMAGER_VERSION_MAJOR 1) set(IMAGER_VERSION_MINOR 7) -set(IMAGER_VERSION_STR "${IMAGER_VERSION_MAJOR}.${IMAGER_VERSION_MINOR}.4.1") -set(IMAGER_VERSION_CSV "${IMAGER_VERSION_MAJOR},${IMAGER_VERSION_MINOR},4,1") +set(IMAGER_VERSION_STR "${IMAGER_VERSION_MAJOR}.${IMAGER_VERSION_MINOR}.5") +set(IMAGER_VERSION_CSV "${IMAGER_VERSION_MAJOR},${IMAGER_VERSION_MINOR},5,0") add_definitions(-DIMAGER_VERSION_STR="${IMAGER_VERSION_STR}") add_definitions(-DIMAGER_VERSION_CSV=${IMAGER_VERSION_CSV}) set(CMAKE_INCLUDE_CURRENT_DIR ON) @@ -48,8 +48,15 @@ elseif (UNIX) elseif (WIN32) set(DEPENDENCIES acceleratedcryptographichash.cpp dependencies/mountutils/src/windows/functions.cpp dependencies/drivelist/src/windows/list.cpp windows/winfile.cpp windows/winfile.h windows/winwlancredentials.h windows/winwlancredentials.cpp - windows/rpi-imager.rc) - set(EXTRALIBS setupapi wlanapi) + windows/rpi-imager.rc wlanapi_delayed.lib) + set(EXTRALIBS setupapi ${CMAKE_CURRENT_BINARY_DIR}/wlanapi_delayed.lib) + add_custom_command( + OUTPUT wlanapi_delayed.lib + COMMAND ${CMAKE_DLLTOOL} --input-def "${CMAKE_CURRENT_SOURCE_DIR}/windows/wlanapi.def" + --output-delaylib "wlanapi_delayed.lib" --dllname "wlanapi.dll" + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/windows/wlanapi.def + VERBATIM + ) endif() include_directories(BEFORE .) diff --git a/src/windows/winwlancredentials.cpp b/src/windows/winwlancredentials.cpp index 3a80d50..80c6e1c 100644 --- a/src/windows/winwlancredentials.cpp +++ b/src/windows/winwlancredentials.cpp @@ -8,12 +8,29 @@ #include #include #include +#include #include #include #ifndef WLAN_PROFILE_GET_PLAINTEXT_KEY #define WLAN_PROFILE_GET_PLAINTEXT_KEY 4 #endif +static HINSTANCE hWlanApi = NULL; + +/* Called by dlltool generated delaylib code that is used for lazy loading + wlanapi.dll */ +FARPROC WINAPI dllDelayNotifyHook(unsigned dliNotify, PDelayLoadInfo) +{ + if (dliNotify == dliNotePreLoadLibrary) + { + return (FARPROC) hWlanApi; + } + + return NULL; +} + +PfnDliHook __pfnDliNotifyHook2 = dllDelayNotifyHook; + inline QString unescapeXml(QString str) { static const char *table[] = { @@ -35,6 +52,14 @@ inline QString unescapeXml(QString str) WinWlanCredentials::WinWlanCredentials() { + if (!hWlanApi) + hWlanApi = LoadLibraryExA("wlanapi.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32); + if (!hWlanApi) + { + qDebug() << "wlanapi.dll not available"; + return; + } + /* Get both SSID and PSK in one go, and store it in variables */ HANDLE h; DWORD supportedVersion = 0; diff --git a/src/windows/wlanapi.def b/src/windows/wlanapi.def new file mode 100644 index 0000000..3df794e --- /dev/null +++ b/src/windows/wlanapi.def @@ -0,0 +1,9 @@ +LIBRARY wlanapi +EXPORTS +WlanCloseHandle@8 +WlanEnumInterfaces@12 +WlanFreeMemory@4 +WlanGetProfile@28 +WlanGetProfileList@16 +WlanOpenHandle@16 +WlanQueryInterface@28