Wlanapi.dll is accessed dynamically now (since not present on Windows Server by default)
This commit is contained in:
parent
4bb46b2ff1
commit
d64d5d31ab
@ -59,6 +59,7 @@ i2 L0
|
|||||||
2571 Error [3] changing service "[2]" start type. Please, contact your support personnel.
|
2571 Error [3] changing service "[2]" start type. Please, contact your support personnel.
|
||||||
2572 Error [3] starting service "[2]". Please, contact your support personnel.
|
2572 Error [3] starting service "[2]". Please, contact your support personnel.
|
||||||
2573 Error [3] stopping service "[2]". Please, contact your support personnel.
|
2573 Error [3] stopping service "[2]". Please, contact your support personnel.
|
||||||
|
2580 Error installing WLAN profiles, because WLAN is not installed. Please, install Wireless LAN Service Windows feature, or contact your support personnel.
|
||||||
2579 Error opening WLAN handle, because WLAN AutoConfig service is not started. Please, enable and start WLAN AutoConfig service, or contact your support personnel.
|
2579 Error opening WLAN handle, because WLAN AutoConfig service is not started. Please, enable and start WLAN AutoConfig service, or contact your support personnel.
|
||||||
2577 Error [2] opening WLAN handle. Please, contact your support personnel.
|
2577 Error [2] opening WLAN handle. Please, contact your support personnel.
|
||||||
2578 WLAN profile "[2]" XML data is not UTF-16 encoded. Please, contact your support personnel.
|
2578 WLAN profile "[2]" XML data is not UTF-16 encoded. Please, contact your support personnel.
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Error codes (next unused 2580L)
|
// Error codes (next unused 2581L)
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define ERROR_INSTALL_DATABASE_OPEN 2550L
|
#define ERROR_INSTALL_DATABASE_OPEN 2550L
|
||||||
@ -57,6 +57,7 @@
|
|||||||
#define ERROR_INSTALL_SVC_SET_START 2571L
|
#define ERROR_INSTALL_SVC_SET_START 2571L
|
||||||
#define ERROR_INSTALL_SVC_START 2572L
|
#define ERROR_INSTALL_SVC_START 2572L
|
||||||
#define ERROR_INSTALL_SVC_STOP 2573L
|
#define ERROR_INSTALL_SVC_STOP 2573L
|
||||||
|
#define ERROR_INSTALL_WLAN_NOT_INSTALLED 2580L
|
||||||
#define ERROR_INSTALL_WLAN_SVC_NOT_STARTED 2579L
|
#define ERROR_INSTALL_WLAN_SVC_NOT_STARTED 2579L
|
||||||
#define ERROR_INSTALL_WLAN_HANDLE_OPEN 2577L
|
#define ERROR_INSTALL_WLAN_HANDLE_OPEN 2577L
|
||||||
#define ERROR_INSTALL_WLAN_PROFILE_NOT_UTF16 2578L
|
#define ERROR_INSTALL_WLAN_PROFILE_NOT_UTF16 2578L
|
||||||
|
154
src/OpWLAN.cpp
154
src/OpWLAN.cpp
@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
#pragma comment(lib, "wlanapi.lib")
|
|
||||||
|
|
||||||
|
|
||||||
namespace MSICA {
|
namespace MSICA {
|
||||||
|
|
||||||
@ -46,45 +44,52 @@ COpWLANProfileDelete::COpWLANProfileDelete(const GUID &guidInterface, LPCWSTR ps
|
|||||||
|
|
||||||
HRESULT COpWLANProfileDelete::Execute(CSession *pSession)
|
HRESULT COpWLANProfileDelete::Execute(CSession *pSession)
|
||||||
{
|
{
|
||||||
DWORD dwError, dwNegotiatedVersion;
|
if (::pfnWlanOpenHandle && ::pfnWlanCloseHandle && ::pfnWlanGetProfile && ::pfnWlanDeleteProfile && ::pfnWlanFreeMemory) {
|
||||||
HANDLE hClientHandle;
|
DWORD dwError, dwNegotiatedVersion;
|
||||||
|
HANDLE hClientHandle;
|
||||||
|
|
||||||
dwError = ::WlanOpenHandle(2, NULL, &dwNegotiatedVersion, &hClientHandle);
|
dwError = ::pfnWlanOpenHandle(2, NULL, &dwNegotiatedVersion, &hClientHandle);
|
||||||
if (dwError == NO_ERROR) {
|
if (dwError == NO_ERROR) {
|
||||||
if (pSession->m_bRollbackEnabled) {
|
if (pSession->m_bRollbackEnabled) {
|
||||||
LPWSTR pszProfileXML = NULL;
|
LPWSTR pszProfileXML = NULL;
|
||||||
DWORD dwFlags = 0, dwGrantedAccess = 0;
|
DWORD dwFlags = 0, dwGrantedAccess = 0;
|
||||||
|
|
||||||
// Get profile settings as XML first.
|
// Get profile settings as XML first.
|
||||||
dwError = ::WlanGetProfile(hClientHandle, &m_guidInterface, m_sValue, NULL, &pszProfileXML, &dwFlags, &dwGrantedAccess);
|
dwError = ::pfnWlanGetProfile(hClientHandle, &m_guidInterface, m_sValue, NULL, &pszProfileXML, &dwFlags, &dwGrantedAccess);
|
||||||
if (dwError == NO_ERROR) {
|
|
||||||
// Delete the profile.
|
|
||||||
dwError = ::WlanDeleteProfile(hClientHandle, &m_guidInterface, m_sValue, NULL);
|
|
||||||
if (dwError == NO_ERROR) {
|
if (dwError == NO_ERROR) {
|
||||||
// Order rollback action to recreate it.
|
// Delete the profile.
|
||||||
pSession->m_olRollback.AddHead(new COpWLANProfileSet(m_guidInterface, dwFlags, m_sValue, pszProfileXML));
|
dwError = ::pfnWlanDeleteProfile(hClientHandle, &m_guidInterface, m_sValue, NULL);
|
||||||
|
if (dwError == NO_ERROR) {
|
||||||
|
// Order rollback action to recreate it.
|
||||||
|
pSession->m_olRollback.AddHead(new COpWLANProfileSet(m_guidInterface, dwFlags, m_sValue, pszProfileXML));
|
||||||
|
}
|
||||||
|
::pfnWlanFreeMemory(pszProfileXML);
|
||||||
}
|
}
|
||||||
::WlanFreeMemory(pszProfileXML);
|
} else {
|
||||||
|
// Delete the profile.
|
||||||
|
dwError = ::pfnWlanDeleteProfile(hClientHandle, &m_guidInterface, m_sValue, NULL);
|
||||||
}
|
}
|
||||||
} else {
|
::pfnWlanCloseHandle(hClientHandle, NULL);
|
||||||
// Delete the profile.
|
|
||||||
dwError = ::WlanDeleteProfile(hClientHandle, &m_guidInterface, m_sValue, NULL);
|
|
||||||
}
|
}
|
||||||
::WlanCloseHandle(hClientHandle, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dwError == NO_ERROR || dwError == ERROR_NOT_FOUND)
|
if (dwError == NO_ERROR || dwError == ERROR_NOT_FOUND)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
else {
|
else {
|
||||||
PMSIHANDLE hRecordProg = ::MsiCreateRecord(4);
|
PMSIHANDLE hRecordProg = ::MsiCreateRecord(4);
|
||||||
ATL::CAtlStringW sGUID;
|
ATL::CAtlStringW sGUID;
|
||||||
GuidToString(&m_guidInterface, sGUID);
|
GuidToString(&m_guidInterface, sGUID);
|
||||||
::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_WLAN_PROFILE_DELETE);
|
::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_WLAN_PROFILE_DELETE);
|
||||||
::MsiRecordSetStringW(hRecordProg, 2, sGUID );
|
::MsiRecordSetStringW(hRecordProg, 2, sGUID );
|
||||||
::MsiRecordSetStringW(hRecordProg, 3, m_sValue );
|
::MsiRecordSetStringW(hRecordProg, 3, m_sValue );
|
||||||
::MsiRecordSetInteger(hRecordProg, 4, dwError );
|
::MsiRecordSetInteger(hRecordProg, 4, dwError );
|
||||||
|
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
||||||
|
return AtlHresultFromWin32(dwError);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PMSIHANDLE hRecordProg = ::MsiCreateRecord(1);
|
||||||
|
::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_WLAN_NOT_INSTALLED);
|
||||||
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
||||||
return AtlHresultFromWin32(dwError);
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,50 +108,57 @@ COpWLANProfileSet::COpWLANProfileSet(const GUID &guidInterface, DWORD dwFlags, L
|
|||||||
|
|
||||||
HRESULT COpWLANProfileSet::Execute(CSession *pSession)
|
HRESULT COpWLANProfileSet::Execute(CSession *pSession)
|
||||||
{
|
{
|
||||||
DWORD dwError, dwNegotiatedVersion;
|
if (::pfnWlanOpenHandle && ::pfnWlanCloseHandle && ::pfnWlanSetProfile && ::pfnWlanReasonCodeToString) {
|
||||||
HANDLE hClientHandle;
|
DWORD dwError, dwNegotiatedVersion;
|
||||||
WLAN_REASON_CODE wlrc = 0;
|
HANDLE hClientHandle;
|
||||||
|
WLAN_REASON_CODE wlrc = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
// Delete existing profile first.
|
// Delete existing profile first.
|
||||||
// Since deleting a profile is a complicated job (when rollback/commit support is required), and we do have an operation just for that, we use it.
|
// Since deleting a profile is a complicated job (when rollback/commit support is required), and we do have an operation just for that, we use it.
|
||||||
// Don't worry, COpWLANProfileDelete::Execute() returns S_OK if profile doesn't exist.
|
// Don't worry, COpWLANProfileDelete::Execute() returns S_OK if profile doesn't exist.
|
||||||
COpWLANProfileDelete opDelete(m_guidInterface, m_sValue);
|
COpWLANProfileDelete opDelete(m_guidInterface, m_sValue);
|
||||||
HRESULT hr = opDelete.Execute(pSession);
|
HRESULT hr = opDelete.Execute(pSession);
|
||||||
if (FAILED(hr)) return hr;
|
if (FAILED(hr)) return hr;
|
||||||
}
|
|
||||||
|
|
||||||
dwError = ::WlanOpenHandle(2, NULL, &dwNegotiatedVersion, &hClientHandle);
|
|
||||||
if (dwError == NO_ERROR) {
|
|
||||||
// Set the profile.
|
|
||||||
dwError = ::WlanSetProfile(hClientHandle, &m_guidInterface, m_dwFlags, m_sProfileXML, NULL, TRUE, NULL, &wlrc);
|
|
||||||
if (dwError == NO_ERROR && pSession->m_bRollbackEnabled) {
|
|
||||||
// Order rollback action to delete it.
|
|
||||||
pSession->m_olRollback.AddHead(new COpWLANProfileDelete(m_guidInterface, m_sValue));
|
|
||||||
}
|
}
|
||||||
::WlanCloseHandle(hClientHandle, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dwError == NO_ERROR)
|
dwError = ::pfnWlanOpenHandle(2, NULL, &dwNegotiatedVersion, &hClientHandle);
|
||||||
return S_OK;
|
if (dwError == NO_ERROR) {
|
||||||
else {
|
// Set the profile.
|
||||||
PMSIHANDLE hRecordProg = ::MsiCreateRecord(5);
|
dwError = ::pfnWlanSetProfile(hClientHandle, &m_guidInterface, m_dwFlags, m_sProfileXML, NULL, TRUE, NULL, &wlrc);
|
||||||
ATL::CAtlStringW sGUID, sReason;
|
if (dwError == NO_ERROR && pSession->m_bRollbackEnabled) {
|
||||||
DWORD dwSize = 1024, dwResult;
|
// Order rollback action to delete it.
|
||||||
LPWSTR szBuffer = sReason.GetBuffer(dwSize);
|
pSession->m_olRollback.AddHead(new COpWLANProfileDelete(m_guidInterface, m_sValue));
|
||||||
|
}
|
||||||
|
::pfnWlanCloseHandle(hClientHandle, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
GuidToString(&m_guidInterface, sGUID);
|
if (dwError == NO_ERROR)
|
||||||
dwResult = ::WlanReasonCodeToString(wlrc, dwSize, szBuffer, NULL);
|
return S_OK;
|
||||||
sReason.ReleaseBuffer(dwSize);
|
else {
|
||||||
if (dwResult != NO_ERROR) sReason.Format(L"0x%x", wlrc);
|
PMSIHANDLE hRecordProg = ::MsiCreateRecord(5);
|
||||||
|
ATL::CAtlStringW sGUID, sReason;
|
||||||
|
DWORD dwSize = 1024, dwResult;
|
||||||
|
LPWSTR szBuffer = sReason.GetBuffer(dwSize);
|
||||||
|
|
||||||
::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_WLAN_PROFILE_SET);
|
GuidToString(&m_guidInterface, sGUID);
|
||||||
::MsiRecordSetStringW(hRecordProg, 2, sGUID );
|
dwResult = ::pfnWlanReasonCodeToString(wlrc, dwSize, szBuffer, NULL);
|
||||||
::MsiRecordSetStringW(hRecordProg, 3, m_sValue );
|
sReason.ReleaseBuffer(dwSize);
|
||||||
::MsiRecordSetStringW(hRecordProg, 4, sReason );
|
if (dwResult != NO_ERROR) sReason.Format(L"0x%x", wlrc);
|
||||||
::MsiRecordSetInteger(hRecordProg, 5, dwError );
|
|
||||||
|
::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_WLAN_PROFILE_SET);
|
||||||
|
::MsiRecordSetStringW(hRecordProg, 2, sGUID );
|
||||||
|
::MsiRecordSetStringW(hRecordProg, 3, m_sValue );
|
||||||
|
::MsiRecordSetStringW(hRecordProg, 4, sReason );
|
||||||
|
::MsiRecordSetInteger(hRecordProg, 5, dwError );
|
||||||
|
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
||||||
|
return AtlHresultFromWin32(dwError);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PMSIHANDLE hRecordProg = ::MsiCreateRecord(1);
|
||||||
|
::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_WLAN_NOT_INSTALLED);
|
||||||
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
||||||
return AtlHresultFromWin32(dwError);
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/stdafx.h
10
src/stdafx.h
@ -33,3 +33,13 @@
|
|||||||
#include <mstask.h>
|
#include <mstask.h>
|
||||||
#include <taskschd.h>
|
#include <taskschd.h>
|
||||||
#include <wlanapi.h>
|
#include <wlanapi.h>
|
||||||
|
|
||||||
|
// Must not statically link to Wlanapi.dll as it is not available on Windows
|
||||||
|
// without a WLAN interface.
|
||||||
|
extern VOID (WINAPI *pfnWlanFreeMemory)(__in PVOID pMemory);
|
||||||
|
extern DWORD (WINAPI *pfnWlanOpenHandle)(__in DWORD dwClientVersion, __reserved PVOID pReserved, __out PDWORD pdwNegotiatedVersion, __out PHANDLE phClientHandle);
|
||||||
|
extern DWORD (WINAPI *pfnWlanCloseHandle)(__in HANDLE hClientHandle, __reserved PVOID pReserved);
|
||||||
|
extern DWORD (WINAPI *pfnWlanGetProfile)(__in HANDLE hClientHandle, __in CONST GUID *pInterfaceGuid, __in LPCWSTR strProfileName, __reserved PVOID pReserved, __deref_out LPWSTR *pstrProfileXml, __inout_opt DWORD *pdwFlags, __out_opt DWORD *pdwGrantedAccess);
|
||||||
|
extern DWORD (WINAPI *pfnWlanSetProfile)(__in HANDLE hClientHandle, __in CONST GUID *pInterfaceGuid, __in DWORD dwFlags, __in LPCWSTR strProfileXml, __in_opt LPCWSTR strAllUserProfileSecurity, __in BOOL bOverwrite, __reserved PVOID pReserved, __out DWORD *pdwReasonCode);
|
||||||
|
extern DWORD (WINAPI *pfnWlanDeleteProfile)(__in HANDLE hClientHandle, __in CONST GUID *pInterfaceGuid, __in LPCWSTR strProfileName, __reserved PVOID pReserved);
|
||||||
|
extern DWORD (WINAPI *pfnWlanReasonCodeToString)(__in DWORD dwReasonCode, __in DWORD dwBufferSize, __in_ecount(dwBufferSize) PWCHAR pStringBuffer, __reserved PVOID pReserved);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user