183 lines
7.3 KiB
C++
183 lines
7.3 KiB
C++
#include "stdafx.h"
|
|
|
|
#pragma comment(lib, "wlanapi.lib")
|
|
|
|
|
|
namespace MSICA {
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// COpWLANProfile
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
COpWLANProfile::COpWLANProfile(const GUID &guidInterface, LPCWSTR pszProfileName, int iTicks) :
|
|
COpTypeSingleString(pszProfileName, iTicks),
|
|
m_guidInterface(guidInterface)
|
|
{
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// COpWLANProfileDelete
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
COpWLANProfileDelete::COpWLANProfileDelete(const GUID &guidInterface, LPCWSTR pszProfileName, int iTicks) : COpWLANProfile(guidInterface, pszProfileName, iTicks)
|
|
{
|
|
}
|
|
|
|
|
|
HRESULT COpWLANProfileDelete::Execute(CSession *pSession)
|
|
{
|
|
DWORD dwError, dwNegotiatedVersion;
|
|
HANDLE hClientHandle;
|
|
|
|
dwError = ::WlanOpenHandle(2, NULL, &dwNegotiatedVersion, &hClientHandle);
|
|
if (dwError == NO_ERROR) {
|
|
if (pSession->m_bRollbackEnabled) {
|
|
ATL::CAtlStringW sBackupName;
|
|
UINT uiCount = 0;
|
|
|
|
do {
|
|
// Rename the profile to make a backup.
|
|
sBackupName.Format(L"%ls (orig %u)", (LPCWSTR)m_sValue, ++uiCount);
|
|
dwError = ::WlanRenameProfile(hClientHandle, &m_guidInterface, m_sValue, sBackupName, NULL);
|
|
} while (dwError == ERROR_ALREADY_EXISTS);
|
|
if (dwError == NO_ERROR) {
|
|
// Order rollback action to restore from backup copy.
|
|
pSession->m_olRollback.AddHead(new COpWLANProfileRename(m_guidInterface, sBackupName, m_sValue));
|
|
|
|
// Order commit action to delete backup copy.
|
|
pSession->m_olCommit.AddTail(new COpWLANProfileDelete(m_guidInterface, sBackupName));
|
|
}
|
|
} else {
|
|
// Delete the profile.
|
|
dwError = ::WlanDeleteProfile(hClientHandle, &m_guidInterface, m_sValue, NULL);
|
|
}
|
|
::WlanCloseHandle(hClientHandle, NULL);
|
|
}
|
|
|
|
if (dwError == NO_ERROR || dwError == ERROR_NOT_FOUND)
|
|
return S_OK;
|
|
else {
|
|
PMSIHANDLE hRecordProg = ::MsiCreateRecord(4);
|
|
ATL::CAtlStringW sGUID;
|
|
GuidToString(m_guidInterface, sGUID);
|
|
::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_WLAN_PROFILE_DELETE);
|
|
::MsiRecordSetStringW(hRecordProg, 2, sGUID );
|
|
::MsiRecordSetStringW(hRecordProg, 3, m_sValue );
|
|
::MsiRecordSetInteger(hRecordProg, 4, dwError );
|
|
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
|
return AtlHresultFromWin32(dwError);
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// COpWLANProfileRename
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
COpWLANProfileRename::COpWLANProfileRename(const GUID &guidInterface, LPCWSTR pszProfileNameSrc, LPCWSTR pszProfileNameDst, int iTicks) :
|
|
COpWLANProfile(guidInterface, pszProfileNameSrc, iTicks),
|
|
m_sProfileNameDst(pszProfileNameDst)
|
|
{
|
|
}
|
|
|
|
|
|
HRESULT COpWLANProfileRename::Execute(CSession *pSession)
|
|
{
|
|
DWORD dwError, dwNegotiatedVersion;
|
|
HANDLE hClientHandle;
|
|
|
|
dwError = ::WlanOpenHandle(2, NULL, &dwNegotiatedVersion, &hClientHandle);
|
|
if (dwError == NO_ERROR) {
|
|
// Rename the profile.
|
|
dwError = ::WlanRenameProfile(hClientHandle, &m_guidInterface, m_sValue, m_sProfileNameDst, NULL);
|
|
if (dwError == NO_ERROR && pSession->m_bRollbackEnabled) {
|
|
// Order rollback action to rename it back.
|
|
pSession->m_olRollback.AddHead(new COpWLANProfileRename(m_guidInterface, m_sProfileNameDst, m_sValue));
|
|
}
|
|
::WlanCloseHandle(hClientHandle, NULL);
|
|
}
|
|
|
|
if (dwError == NO_ERROR)
|
|
return S_OK;
|
|
else {
|
|
PMSIHANDLE hRecordProg = ::MsiCreateRecord(5);
|
|
ATL::CAtlStringW sGUID;
|
|
GuidToString(m_guidInterface, sGUID);
|
|
::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_WLAN_PROFILE_RENAME);
|
|
::MsiRecordSetStringW(hRecordProg, 2, sGUID );
|
|
::MsiRecordSetStringW(hRecordProg, 3, m_sValue );
|
|
::MsiRecordSetStringW(hRecordProg, 4, m_sProfileNameDst );
|
|
::MsiRecordSetInteger(hRecordProg, 5, dwError );
|
|
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
|
return AtlHresultFromWin32(dwError);
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// COpWLANProfileSet
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
COpWLANProfileSet::COpWLANProfileSet(const GUID &guidInterface, LPCWSTR pszProfileName, LPCWSTR pszProfileXML, int iTicks) :
|
|
COpWLANProfile(guidInterface, pszProfileName, iTicks),
|
|
m_sProfileXML(pszProfileXML)
|
|
{
|
|
}
|
|
|
|
|
|
HRESULT COpWLANProfileSet::Execute(CSession *pSession)
|
|
{
|
|
DWORD dwError, dwNegotiatedVersion;
|
|
HANDLE hClientHandle;
|
|
WLAN_REASON_CODE wlrc = 0;
|
|
|
|
{
|
|
// 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.
|
|
// Don't worry, COpWLANProfileDelete::Execute() returns S_OK if profile doesn't exist.
|
|
COpWLANProfileDelete opDelete(m_guidInterface, m_sValue);
|
|
HRESULT hr = opDelete.Execute(pSession);
|
|
if (FAILED(hr)) return hr;
|
|
}
|
|
|
|
dwError = ::WlanOpenHandle(2, NULL, &dwNegotiatedVersion, &hClientHandle);
|
|
if (dwError == NO_ERROR) {
|
|
// Set the profile.
|
|
dwError = ::WlanSetProfile(hClientHandle, &m_guidInterface, 0, 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)
|
|
return S_OK;
|
|
else {
|
|
PMSIHANDLE hRecordProg = ::MsiCreateRecord(5);
|
|
ATL::CAtlStringW sGUID, sReason;
|
|
DWORD dwSize = 1024;
|
|
LPWSTR szBuffer = sReason.GetBuffer(dwSize);
|
|
|
|
GuidToString(m_guidInterface, sGUID);
|
|
if (::WlanReasonCodeToString(wlrc, dwSize, szBuffer, NULL) == NO_ERROR) {
|
|
sReason.ReleaseBuffer(dwSize);
|
|
::MsiRecordSetStringW(hRecordProg, 4, sReason);
|
|
} else {
|
|
sReason.ReleaseBuffer(dwSize);
|
|
sReason.Format(L"0x%x", wlrc);
|
|
}
|
|
|
|
::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);
|
|
}
|
|
}
|
|
|
|
} // namespace MSICA
|