diff --git a/.gitattributes b/.gitattributes index ca03562..3086116 100644 --- a/.gitattributes +++ b/.gitattributes @@ -25,6 +25,7 @@ MSICALib/OpFile.cpp -text MSICALib/OpReg.cpp -text MSICALib/OpSvc.cpp -text MSICALib/OpTS.cpp -text +MSICALib/OpWLAN.cpp -text MSICALib/stdafx.cpp -text MSICALib/stdafx.h -text include/Debug.props -text svneol=unset#text/xml diff --git a/MSICA/L10N/sl_SI.po b/MSICA/L10N/sl_SI.po index 13c37d9..b06d382 100644 --- a/MSICA/L10N/sl_SI.po +++ b/MSICA/L10N/sl_SI.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: MSICA\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-03-21 18:37+0100\n" +"POT-Creation-Date: 2014-03-22 13:34+0100\n" "PO-Revision-Date: \n" "Last-Translator: Simon Rozman \n" "Language-Team: Amebis, d. o. o., Kamnik \n" @@ -84,6 +84,13 @@ msgstr "Digitalno potrdilo: [1]" msgid "Configuring services" msgstr "Nastavljanje servisov" +#: MSIBuild/En.Win32.Debug.ActionText-2.idtx:7 +#: MSIBuild/En.Win32.Release.ActionText-2.idtx:7 +#: MSIBuild/En.x64.Debug.ActionText-2.idtx:7 +#: MSIBuild/En.x64.Release.ActionText-2.idtx:7 +msgid "Evaluating WLAN profiles" +msgstr "Pregled profilov WLAN" + #: MSIBuild/En.Win32.Debug.ActionText-2.idtx:4 #: MSIBuild/En.Win32.Release.ActionText-2.idtx:4 #: MSIBuild/En.x64.Debug.ActionText-2.idtx:4 @@ -98,6 +105,13 @@ msgstr "Nameščanje digitalnih potrdil" msgid "Registering scheduled tasks" msgstr "Registracija razporejenih opravil" +#: MSIBuild/En.Win32.Debug.ActionText-2.idtx:8 +#: MSIBuild/En.Win32.Release.ActionText-2.idtx:8 +#: MSIBuild/En.x64.Debug.ActionText-2.idtx:8 +#: MSIBuild/En.x64.Release.ActionText-2.idtx:8 +msgid "Removing WLAN profiles" +msgstr "Odstranjevanje profilov WLAN" + #: MSIBuild/En.Win32.Debug.ActionText-2.idtx:6 #: MSIBuild/En.Win32.Release.ActionText-2.idtx:6 #: MSIBuild/En.x64.Debug.ActionText-2.idtx:6 @@ -111,3 +125,25 @@ msgstr "Razporejeno opravilo: [1]" #: MSIBuild/En.x64.Release.ActionText-2.idtx:5 msgid "Service: [1]" msgstr "Servis: [1]" + +#: MSIBuild/En.Win32.Debug.ActionText-2.idtx:9 +#: MSIBuild/En.Win32.Release.ActionText-2.idtx:9 +#: MSIBuild/En.x64.Debug.ActionText-2.idtx:9 +#: MSIBuild/En.x64.Release.ActionText-2.idtx:9 +msgid "Setting WLAN profiles" +msgstr "Nastavljanje profilov WLAN" + +#: MSIBuild/En.Win32.Debug.ActionText-2.idtx:7 +#: MSIBuild/En.Win32.Debug.ActionText-2.idtx:8 +#: MSIBuild/En.Win32.Debug.ActionText-2.idtx:9 +#: MSIBuild/En.Win32.Release.ActionText-2.idtx:7 +#: MSIBuild/En.Win32.Release.ActionText-2.idtx:8 +#: MSIBuild/En.Win32.Release.ActionText-2.idtx:9 +#: MSIBuild/En.x64.Debug.ActionText-2.idtx:7 +#: MSIBuild/En.x64.Debug.ActionText-2.idtx:8 +#: MSIBuild/En.x64.Debug.ActionText-2.idtx:9 +#: MSIBuild/En.x64.Release.ActionText-2.idtx:7 +#: MSIBuild/En.x64.Release.ActionText-2.idtx:8 +#: MSIBuild/En.x64.Release.ActionText-2.idtx:9 +msgid "WLAN profile: [1]" +msgstr "Profil WLAN: [1]" diff --git a/MSICA/MSIBuild/Makefile b/MSICA/MSIBuild/Makefile index 865a4f7..1c39cde 100644 --- a/MSICA/MSIBuild/Makefile +++ b/MSICA/MSIBuild/Makefile @@ -59,6 +59,11 @@ TaskTrigger DaysOfMonth Y DoubleInteger Specifies the day of the month a ta TaskTrigger WeekOfMonth Y Integer 1;2;3;4;5 Specifies the week of the month when the task runs. This value is exclusive and is one of the following: 1=The task will run between the first and seventh day of the month, 2=The task will run between the eighth and 14th day of the month, 3=The task will run between the 15th and 21st day of the month, 4=The task will run between the 22nd and 28th of the month, 5=The task will run between the last seven days of the month. TaskTrigger MonthsOfYear Y 0 4095 Integer Specifies the month(s) when the task runs. This value is a combination of the following values: 1=Jan, 2=Feb, 4=Mar, 8=Apr, 16=May, 32=Jun, 64=Jul, 128=Aug, 256=Sep, 512=Oct, 1024=Nov, 2048=Dec. TaskTrigger Task_ N ScheduledTask 1 Identifier Key of the Trigger's task. +WLANProfile WLANProfile N Identifier Primary key, non-localized token. +WLANProfile Name N Formatted Profile name +WLANProfile Binary_ N Binary 1 Identifier The profile XML file. The binary information is looked up from the Binary Table. +WLANProfile Condition Y Condition Optional expression which skips the profile if evaluates to expFalse. If the expression syntax is invalid, the engine will terminate, returning iesBadActionData. +WLANProfile Component_ N Component 1 Identifier Component the profile is part of. < NUL +WLANProfile Name Binary_ Condition Component_ +s$(MSIBUILD_LENGTH_ID) l255 s$(MSIBUILD_LENGTH_ID) S255 s$(MSIBUILD_LENGTH_ID) +WLANProfile WLANProfile +< binCert; @@ -449,6 +451,196 @@ UINT MSICA_API ScheduledTasksEval(MSIHANDLE hInstall) } +UINT MSICA_API EvaluateWLANProfiles(MSIHANDLE hInstall) +{ + //::MessageBox(NULL, _T(__FUNCTION__), _T("MSICA"), MB_OK); + + UINT uiResult; + BOOL bIsCoInitialized = SUCCEEDED(::CoInitialize(NULL)); + MSICA::COpList olExecuteInstall, olExecuteRemove; + BOOL bRollbackEnabled; + PMSIHANDLE + hDatabase, + hRecordProg = ::MsiCreateRecord(3); + ATL::CAtlString sValue; + + // Check and add the rollback enabled state. + uiResult = ::MsiGetProperty(hInstall, _T("RollbackDisabled"), sValue); + bRollbackEnabled = uiResult == NO_ERROR ? + _ttoi(sValue) || !sValue.IsEmpty() && _totlower(sValue.GetAt(0)) == _T('y') ? FALSE : TRUE : + TRUE; + olExecuteInstall.AddTail(new MSICA::COpRollbackEnable(bRollbackEnabled)); + olExecuteRemove.AddTail(new MSICA::COpRollbackEnable(bRollbackEnabled)); + + // Open MSI database. + hDatabase = ::MsiGetActiveDatabase(hInstall); + if (hDatabase) { + // Check if WLANProfile table exists. If it doesn't exist, there's nothing to do. + MSICONDITION condition = ::MsiDatabaseIsTablePersistent(hDatabase, _T("WLANProfile")); + if (condition == MSICONDITION_FALSE || condition == MSICONDITION_TRUE) { + PMSIHANDLE hViewProfile; + + // Prepare a query to get a list/view of profiles. + uiResult = ::MsiDatabaseOpenView(hDatabase, _T("SELECT Binary_,Name,Condition,Component_ FROM WLANProfile"), &hViewProfile); + if (uiResult == NO_ERROR) { + // Execute query! + uiResult = ::MsiViewExecute(hViewProfile, NULL); + if (uiResult == NO_ERROR) { + DWORD dwError, dwNegotiatedVersion; + HANDLE hClientHandle; + + // Open WLAN handle. + dwError = ::WlanOpenHandle(2, NULL, &dwNegotiatedVersion, &hClientHandle); + if (dwError == NO_ERROR) { + WLAN_INTERFACE_INFO_LIST *pInterfaceList; + + // Get a list of WLAN interfaces. + dwError = ::WlanEnumInterfaces(hClientHandle, NULL, &pInterfaceList); + if (dwError == NO_ERROR) { + ATL::CAtlStringW sName, sProfileXML; + ATL::CAtlArray binProfile; + + for (;;) { + PMSIHANDLE hRecord; + INSTALLSTATE iInstalled, iAction; + int iTick = 0; + DWORD i; + + // Fetch one record from the view. + uiResult = ::MsiViewFetch(hViewProfile, &hRecord); + if (uiResult == ERROR_NO_MORE_ITEMS) { + uiResult = NO_ERROR; + break; + } else if (uiResult != NO_ERROR) + break; + + // Read and evaluate profile's condition. + uiResult = ::MsiRecordGetString(hRecord, 3, sValue); + if (uiResult != NO_ERROR) break; + condition = ::MsiEvaluateCondition(hInstall, sValue); + if (condition == MSICONDITION_FALSE) + continue; + else if (condition == MSICONDITION_ERROR) { + uiResult = ERROR_INVALID_FIELD; + break; + } + + // Read profile's name. + uiResult = ::MsiRecordGetString(hRecord, 2, sName); + if (uiResult != NO_ERROR) break; + + // Read profile's component ID. + uiResult = ::MsiRecordGetString(hRecord, 4, sValue); + if (uiResult != NO_ERROR) break; + + // Get the component state. + uiResult = ::MsiGetComponentState(hInstall, sValue, &iInstalled, &iAction); + if (uiResult != NO_ERROR) break; + + if (iAction >= INSTALLSTATE_LOCAL) { + PMSIHANDLE hViewBinary, hRecordBin; + LPCWSTR pProfileStr; + SIZE_T nCount; + + // Perform another query to get profile's binary data. + uiResult = ::MsiDatabaseOpenView(hDatabase, _T("SELECT Data FROM Binary WHERE Name=?"), &hViewBinary); + if (uiResult != NO_ERROR) break; + + // Execute query! + uiResult = ::MsiViewExecute(hViewBinary, hRecord); + if (uiResult != NO_ERROR) break; + + // Fetch one record from the view. + uiResult = ::MsiViewFetch(hViewBinary, &hRecordBin); + if (uiResult == NO_ERROR) + uiResult = ::MsiRecordGetStream(hRecordBin, 1, binProfile); + ::MsiViewClose(hViewBinary); + if (uiResult != NO_ERROR) break; + + // Convert CAtlArray to CAtlStringW. + pProfileStr = (LPCWSTR)binProfile.GetData(); + nCount = binProfile.GetCount()/sizeof(WCHAR); + + if (nCount < 1 || pProfileStr[0] != 0xfeff) { + // The profile XML is not UTF-16 encoded. + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_WLAN_PROFILE_NOT_UTF16); + ::MsiRecordSetStringW(hRecordProg, 2, sName ); + ::MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecordProg); + uiResult = ERROR_INSTALL_USEREXIT; + } + sProfileXML.SetString(pProfileStr + 1, (int)nCount - 1); + + for (i = 0; i < pInterfaceList->dwNumberOfItems; i++) { + // Check for not ready state in interface. + if (pInterfaceList->InterfaceInfo[i].isState != wlan_interface_state_not_ready) { + olExecuteInstall.AddTail(new MSICA::COpWLANProfileSet(pInterfaceList->InterfaceInfo[i].InterfaceGuid, sName, sProfileXML, MSICA_WLAN_PROFILE_TICK_SIZE)); + iTick += MSICA_WLAN_PROFILE_TICK_SIZE; + } + } + + // The amount of tick space to add for each profile to progress indicator. + ::MsiRecordSetInteger(hRecordProg, 1, 3 ); + ::MsiRecordSetInteger(hRecordProg, 2, iTick); + if (::MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL) { uiResult = ERROR_INSTALL_USEREXIT; break; } + } else if (iAction >= INSTALLSTATE_REMOVED) { + // Component is installed, but should be degraded to advertised/removed. Delete the profile from all interfaces. + for (i = 0; i < pInterfaceList->dwNumberOfItems; i++) { + // Check for not ready state in interface. + if (pInterfaceList->InterfaceInfo[i].isState != wlan_interface_state_not_ready) { + olExecuteRemove.AddTail(new MSICA::COpWLANProfileDelete(pInterfaceList->InterfaceInfo[i].InterfaceGuid, sName, MSICA_WLAN_PROFILE_TICK_SIZE)); + iTick += MSICA_WLAN_PROFILE_TICK_SIZE; + } + } + + // The amount of tick space to add for each profile to progress indicator. + ::MsiRecordSetInteger(hRecordProg, 1, 3 ); + ::MsiRecordSetInteger(hRecordProg, 2, iTick); + if (::MsiProcessMessage(hInstall, INSTALLMESSAGE_PROGRESS, hRecordProg) == IDCANCEL) { uiResult = ERROR_INSTALL_USEREXIT; break; } + } + } + ::WlanFreeMemory(pInterfaceList); + } + ::WlanCloseHandle(hClientHandle, NULL); + } else { + uiResult = ERROR_INSTALL_WLAN_HANDLE_OPEN; + ::MsiRecordSetInteger(hRecordProg, 1, uiResult); + ::MsiRecordSetInteger(hRecordProg, 2, dwError); + ::MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecordProg); + } + ::MsiViewClose(hViewProfile); + + if (uiResult == NO_ERROR) { + // Save the sequences. + uiResult = MSICA::SaveSequence(hInstall, _T("SetWLANProfilesExec"), _T("SetWLANProfilesCommit"), _T("SetWLANProfilesRollback"), olExecuteInstall); + uiResult = MSICA::SaveSequence(hInstall, _T("RemoveWLANProfilesExec"), _T("RemoveWLANProfilesCommit"), _T("RemoveWLANProfilesRollback"), olExecuteRemove); + } else if (uiResult != ERROR_INSTALL_USEREXIT) { + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_OPLIST_CREATE); + ::MsiRecordSetInteger(hRecordProg, 2, uiResult ); + ::MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecordProg); + } + } else { + ::MsiRecordSetInteger(hRecordProg, 1, uiResult); + ::MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecordProg); + } + } else { + ::MsiRecordSetInteger(hRecordProg, 1, uiResult); + ::MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecordProg); + } + } + } else { + uiResult = ERROR_INSTALL_DATABASE_OPEN; + ::MsiRecordSetInteger(hRecordProg, 1, uiResult); + ::MsiProcessMessage(hInstall, INSTALLMESSAGE_ERROR, hRecordProg); + } + + olExecuteInstall.Free(); + olExecuteRemove.Free(); + + if (bIsCoInitialized) ::CoUninitialize(); + return uiResult; +} + + UINT MSICA_API ExecuteSequence(MSIHANDLE hInstall) { //::MessageBox(NULL, _T(__FUNCTION__), _T("MSICA"), MB_OK); diff --git a/MSICA/MSICA.h b/MSICA/MSICA.h index 761cdc3..c0a72a3 100644 --- a/MSICA/MSICA.h +++ b/MSICA/MSICA.h @@ -27,6 +27,9 @@ extern "C" { UINT MSICA_API CertificatesEval(MSIHANDLE hInstall); UINT MSICA_API ServiceConfigEval(MSIHANDLE hInstall); UINT MSICA_API ScheduledTasksEval(MSIHANDLE hInstall); + UINT MSICA_API EvaluateWLANProfiles(MSIHANDLE hInstall); + UINT MSICA_API RemoveWLANProfiles(MSIHANDLE hInstall); + UINT MSICA_API SetWLANProfiles(MSIHANDLE hInstall); UINT MSICA_API ExecuteSequence(MSIHANDLE hInstall); #ifdef __cplusplus diff --git a/MSICA/stdafx.h b/MSICA/stdafx.h index 6acdd2a..9a0137c 100644 --- a/MSICA/stdafx.h +++ b/MSICA/stdafx.h @@ -31,6 +31,7 @@ #include #include #include +#include #include "..\MSICALib\MSICALib.h" diff --git a/MSICALib/L10N/sl_SI.po b/MSICALib/L10N/sl_SI.po index 2f34c87..186e322 100644 --- a/MSICALib/L10N/sl_SI.po +++ b/MSICALib/L10N/sl_SI.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: MSICALib\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2014-03-21 18:37+0100\n" +"POT-Creation-Date: 2014-03-22 13:35+0100\n" "PO-Revision-Date: \n" "Last-Translator: Simon Rozman \n" "Language-Team: Amebis, d. o. o., Kamnik \n" @@ -26,12 +26,19 @@ msgstr "1250" #: MSIBuild/En.Win32.Debug.Error-2.idtx:5 #: MSIBuild/En.Win32.Release.Error-2.idtx:5 #: MSIBuild/En.x64.Debug.Error-2.idtx:5 MSIBuild/En.x64.Release.Error-2.idtx:5 -msgid "" -"Error [2] creating scheduled task list. Please, contact your support " -"personnel." +msgid "Error [2] creating task list. Please, contact your support personnel." msgstr "" -"Pri pripravi seznama razvrščenih opravil je prišlo do napake [2]. Obrnite se " -"na svojo tehnično službo." +"Pri pripravi seznama opravil je prišlo do napake [2]. Obrnite se na svojo " +"tehnično službo." + +#: MSIBuild/En.Win32.Debug.Error-2.idtx:20 +#: MSIBuild/En.Win32.Release.Error-2.idtx:20 +#: MSIBuild/En.x64.Debug.Error-2.idtx:20 +#: MSIBuild/En.x64.Release.Error-2.idtx:20 +msgid "Error [2] opening WLAN handle. Please, contact your support personnel." +msgstr "" +"Pri odpiranju ročica WLAN je prišlo do napake [2]. Obrnite se na svojo " +"tehnično službo." #: MSIBuild/En.Win32.Debug.Error-2.idtx:17 #: MSIBuild/En.Win32.Release.Error-2.idtx:17 @@ -168,6 +175,17 @@ msgstr "" "Pri kopiranju razporejenega opravila »[2]« v »[3]« je prišlo do napake [4]. " "Obrnite se na svojo tehnično službo." +#: MSIBuild/En.Win32.Debug.Error-2.idtx:22 +#: MSIBuild/En.Win32.Release.Error-2.idtx:22 +#: MSIBuild/En.x64.Debug.Error-2.idtx:22 +#: MSIBuild/En.x64.Release.Error-2.idtx:22 +msgid "" +"Error [4] deleting profile \"[3]\" on WLAN interface [2]. Please, contact " +"your support personnel." +msgstr "" +"Pri brisanju profila »[3]« na vmesniku WLAN [2] je prišlo do napake [4]. " +"Obrnite se na svojo tehnično službo." + #: MSIBuild/En.Win32.Debug.Error-2.idtx:10 #: MSIBuild/En.Win32.Release.Error-2.idtx:10 #: MSIBuild/En.x64.Debug.Error-2.idtx:10 @@ -179,6 +197,28 @@ msgstr "" "Pri premikanju datoteke »[2]« v »[3]« je prišlo do napake [4]. Obrnite se na " "svojo tehnično službo." +#: MSIBuild/En.Win32.Debug.Error-2.idtx:23 +#: MSIBuild/En.Win32.Release.Error-2.idtx:23 +#: MSIBuild/En.x64.Debug.Error-2.idtx:23 +#: MSIBuild/En.x64.Release.Error-2.idtx:23 +msgid "" +"Error [5] renaming profile \"[3]\" to \"[4]\" on WLAN interface [2]. Please, " +"contact your support personnel." +msgstr "" +"Pri preimenovanju profila »[3]« v »[4]« na vmesniku WLAN [2] je prišlo do " +"napake [5]. Obrnite se na svojo tehnično službo." + +#: MSIBuild/En.Win32.Debug.Error-2.idtx:24 +#: MSIBuild/En.Win32.Release.Error-2.idtx:24 +#: MSIBuild/En.x64.Debug.Error-2.idtx:24 +#: MSIBuild/En.x64.Release.Error-2.idtx:24 +msgid "" +"Error [5] setting profile \"[3]\" on WLAN interface [2] (WLAN reason is " +"[4]). Please, contact your support personnel." +msgstr "" +"Pri nastavljanju profila »[3]« na vmesniku WLAN [2] je prišlo do napake [5] " +"(vzrok WLAN je [4]). Obrnite se na svojo tehnično službo." + #: MSIBuild/En.Win32.Debug.Error-2.idtx:4 #: MSIBuild/En.Win32.Release.Error-2.idtx:4 #: MSIBuild/En.x64.Debug.Error-2.idtx:4 MSIBuild/En.x64.Release.Error-2.idtx:4 @@ -187,3 +227,14 @@ msgid "" msgstr "" "Pri odpiranju namestitvenega paketa je prišlo do napake. Obrnite se na svojo " "tehnično službo." + +#: MSIBuild/En.Win32.Debug.Error-2.idtx:21 +#: MSIBuild/En.Win32.Release.Error-2.idtx:21 +#: MSIBuild/En.x64.Debug.Error-2.idtx:21 +#: MSIBuild/En.x64.Release.Error-2.idtx:21 +msgid "" +"WLAN profile \"[2]\" XML data is not UTF-16 encoded. Please, contact your " +"support personnel." +msgstr "" +"Zapis XML profila WLAN »[2]« ni zapisan v UTF-16. Obrnite se na svojo " +"tehnično službo." diff --git a/MSICALib/MSIBuild/Makefile b/MSICALib/MSIBuild/Makefile index cbc6a47..21d260d 100644 --- a/MSICALib/MSIBuild/Makefile +++ b/MSICALib/MSIBuild/Makefile @@ -25,7 +25,7 @@ Error Message i2 L0 1252 Error Error 2550 Error opening installation package. Please, contact your support personnel. -2551 Error [2] creating scheduled task list. Please, contact your support personnel. +2551 Error [2] creating task list. Please, contact your support personnel. 2552 Error [3] writing to "[2]" task list file. Please, contact your support personnel. 2560 Error [3] reading from "[2]" task list file. Please, contact your support personnel. 2553 Error [3] setting "[2]" parameter. Please, contact your support personnel. @@ -40,6 +40,11 @@ i2 L0 2571 Error [3] changing service "[2]" start type. 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. +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. +2574 Error [4] deleting profile "[3]" on WLAN interface [2]. Please, contact your support personnel. +2575 Error [5] renaming profile "[3]" to "[4]" on WLAN interface [2]. Please, contact your support personnel. +2576 Error [5] setting profile "[3]" on WLAN interface [2] (WLAN reason is [4]). Please, contact your support personnel. <>(ATL::CAtlFile &f, COpWLANProfile &op); + +protected: + GUID m_guidInterface; +}; + + +//////////////////////////////////////////////////////////////////////////// +// COpWLANProfileDelete +//////////////////////////////////////////////////////////////////////////// + +class COpWLANProfileDelete : public COpWLANProfile +{ +public: + COpWLANProfileDelete(const GUID &guidInterface = GUID_NULL, LPCWSTR pszProfileName = L"", int iTicks = 0); + virtual HRESULT Execute(CSession *pSession); +}; + + +//////////////////////////////////////////////////////////////////////////// +// COpWLANProfileRename +//////////////////////////////////////////////////////////////////////////// + +class COpWLANProfileRename : public COpWLANProfile +{ +public: + COpWLANProfileRename(const GUID &guidInterface = GUID_NULL, LPCWSTR pszProfileNameSrc = L"", LPCWSTR pszProfileNameDst = L"", int iTicks = 0); + virtual HRESULT Execute(CSession *pSession); + + friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpWLANProfileRename &op); + friend inline HRESULT operator >>(ATL::CAtlFile &f, COpWLANProfileRename &op); + +protected: + ATL::CAtlStringW m_sProfileNameDst; +}; + + +//////////////////////////////////////////////////////////////////////////// +// COpWLANProfileSet +//////////////////////////////////////////////////////////////////////////// + +class COpWLANProfileSet : public COpWLANProfile +{ +public: + COpWLANProfileSet(const GUID &guidInterface = GUID_NULL, LPCWSTR pszProfileName = L"", LPCWSTR pszProfileXML = L"", int iTicks = 0); + virtual HRESULT Execute(CSession *pSession); + + friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpWLANProfileSet &op); + friend inline HRESULT operator >>(ATL::CAtlFile &f, COpWLANProfileSet &op); + +protected: + ATL::CAtlStringW m_sProfileXML; +}; + + //////////////////////////////////////////////////////////////////////////// // COpList //////////////////////////////////////////////////////////////////////////// @@ -557,6 +627,9 @@ protected: OP_SVC_SET_START, OP_SVC_START, OP_SVC_STOP, + OP_WLAN_PROFILE_DELETE, + OP_WLAN_PROFILE_RENAME, + OP_WLAN_PROFILE_SET, OP_SUBLIST }; @@ -608,6 +681,32 @@ UINT ExecuteSequence(MSIHANDLE hInstall); // Inline helper functions //////////////////////////////////////////////////////////////////// +namespace MSICA { + +inline VOID GuidToString(const GUID &guid, ATL::CAtlStringA &str) +{ + str.Format("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + guid.Data1, + guid.Data2, + guid.Data3, + guid.Data4[0], guid.Data4[1], + guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); +} + + +inline VOID GuidToString(const GUID &guid, ATL::CAtlStringW &str) +{ + str.Format(L"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", + guid.Data1, + guid.Data2, + guid.Data3, + guid.Data4[0], guid.Data4[1], + guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); +} + +} // namespace MSICA + + inline UINT MsiGetPropertyA(MSIHANDLE hInstall, LPCSTR szName, ATL::CAtlStringA &sValue) { DWORD dwSize = 0; @@ -955,6 +1054,26 @@ inline HRESULT operator >>(ATL::CAtlFile &f, DWORDLONG &i) } +inline HRESULT operator <<(ATL::CAtlFile &f, const GUID &guid) +{ + HRESULT hr; + DWORD dwWritten; + + hr = f.Write(&guid, sizeof(GUID), &dwWritten); + return SUCCEEDED(hr) ? dwWritten == sizeof(GUID) ? hr : E_FAIL : hr; +} + + +inline HRESULT operator >>(ATL::CAtlFile &f, GUID &guid) +{ + HRESULT hr; + DWORD dwRead; + + hr = f.Read(&guid, sizeof(GUID), dwRead); + return SUCCEEDED(hr) ? dwRead == sizeof(GUID) ? hr : E_FAIL : hr; +} + + template inline HRESULT operator <<(ATL::CAtlFile &f, const ATL::CAtlArray &a) { @@ -1480,6 +1599,72 @@ inline HRESULT operator >>(ATL::CAtlFile &f, COpSvcControl &op) } +inline HRESULT operator <<(ATL::CAtlFile &f, const COpWLANProfile &op) +{ + HRESULT hr; + + hr = f << (const COpTypeSingleString&)op; if (FAILED(hr)) return hr; + hr = f << op.m_guidInterface; if (FAILED(hr)) return hr; + + return S_OK; +} + + +inline HRESULT operator >>(ATL::CAtlFile &f, COpWLANProfile &op) +{ + HRESULT hr; + + hr = f >> (COpTypeSingleString&)op; if (FAILED(hr)) return hr; + hr = f >> op.m_guidInterface; if (FAILED(hr)) return hr; + + return S_OK; +} + + +inline HRESULT operator <<(ATL::CAtlFile &f, const COpWLANProfileRename &op) +{ + HRESULT hr; + + hr = f << (const COpWLANProfile&)op; if (FAILED(hr)) return hr; + hr = f << op.m_sProfileNameDst; if (FAILED(hr)) return hr; + + return S_OK; +} + + +inline HRESULT operator >>(ATL::CAtlFile &f, COpWLANProfileRename &op) +{ + HRESULT hr; + + hr = f >> (COpWLANProfile&)op; if (FAILED(hr)) return hr; + hr = f >> op.m_sProfileNameDst; if (FAILED(hr)) return hr; + + return S_OK; +} + + +inline HRESULT operator <<(ATL::CAtlFile &f, const COpWLANProfileSet &op) +{ + HRESULT hr; + + hr = f << (const COpWLANProfile&)op; if (FAILED(hr)) return hr; + hr = f << op.m_sProfileXML; if (FAILED(hr)) return hr; + + return S_OK; +} + + +inline HRESULT operator >>(ATL::CAtlFile &f, COpWLANProfileSet &op) +{ + HRESULT hr; + + hr = f >> (COpWLANProfile&)op; if (FAILED(hr)) return hr; + hr = f >> op.m_sProfileXML; if (FAILED(hr)) return hr; + + return S_OK; +} + + inline HRESULT operator <<(ATL::CAtlFile &f, const COpList &list) { POSITION pos; @@ -1493,44 +1678,28 @@ inline HRESULT operator <<(ATL::CAtlFile &f, const COpList &list) for (pos = list.GetHeadPosition(); pos;) { const COperation *pOp = list.GetNext(pos); - if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); - else if (dynamic_cast(pOp)) - hr = list.Save(f, pOp); + if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); + else if (dynamic_cast(pOp)) hr = list.Save(f, pOp); else { // Unsupported type of operation. hr = E_UNEXPECTED; @@ -1561,25 +1730,28 @@ inline HRESULT operator >>(ATL::CAtlFile &f, COpList &list) if (FAILED(hr)) return hr; switch ((COpList::OPERATION)iTemp) { - case COpList::OP_ROLLBACK_ENABLE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_FILE_DELETE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_FILE_MOVE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_REG_KEY_CREATE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_REG_KEY_COPY: hr = list.LoadAndAddTail(f); break; - case COpList::OP_REG_KEY_DELETE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_REG_VALUE_CREATE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_REG_VALUE_COPY: hr = list.LoadAndAddTail(f); break; - case COpList::OP_REG_VALUE_DELETE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_TASK_CREATE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_TASK_DELETE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_TASK_ENABLE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_TASK_COPY: hr = list.LoadAndAddTail(f); break; - case COpList::OP_CERT_INSTALL: hr = list.LoadAndAddTail(f); break; - case COpList::OP_CERT_REMOVE: hr = list.LoadAndAddTail(f); break; - case COpList::OP_SVC_SET_START: hr = list.LoadAndAddTail(f); break; - case COpList::OP_SVC_START: hr = list.LoadAndAddTail(f); break; - case COpList::OP_SVC_STOP: hr = list.LoadAndAddTail(f); break; - case COpList::OP_SUBLIST: hr = list.LoadAndAddTail(f); break; + case COpList::OP_ROLLBACK_ENABLE: hr = list.LoadAndAddTail(f); break; + case COpList::OP_FILE_DELETE: hr = list.LoadAndAddTail(f); break; + case COpList::OP_FILE_MOVE: hr = list.LoadAndAddTail(f); break; + case COpList::OP_REG_KEY_CREATE: hr = list.LoadAndAddTail(f); break; + case COpList::OP_REG_KEY_COPY: hr = list.LoadAndAddTail(f); break; + case COpList::OP_REG_KEY_DELETE: hr = list.LoadAndAddTail(f); break; + case COpList::OP_REG_VALUE_CREATE: hr = list.LoadAndAddTail(f); break; + case COpList::OP_REG_VALUE_COPY: hr = list.LoadAndAddTail(f); break; + case COpList::OP_REG_VALUE_DELETE: hr = list.LoadAndAddTail(f); break; + case COpList::OP_TASK_CREATE: hr = list.LoadAndAddTail(f); break; + case COpList::OP_TASK_DELETE: hr = list.LoadAndAddTail(f); break; + case COpList::OP_TASK_ENABLE: hr = list.LoadAndAddTail(f); break; + case COpList::OP_TASK_COPY: hr = list.LoadAndAddTail(f); break; + case COpList::OP_CERT_INSTALL: hr = list.LoadAndAddTail(f); break; + case COpList::OP_CERT_REMOVE: hr = list.LoadAndAddTail(f); break; + case COpList::OP_SVC_SET_START: hr = list.LoadAndAddTail(f); break; + case COpList::OP_SVC_START: hr = list.LoadAndAddTail(f); break; + case COpList::OP_SVC_STOP: hr = list.LoadAndAddTail(f); break; + case COpList::OP_WLAN_PROFILE_DELETE: hr = list.LoadAndAddTail(f); break; + case COpList::OP_WLAN_PROFILE_RENAME: hr = list.LoadAndAddTail(f); break; + case COpList::OP_WLAN_PROFILE_SET: hr = list.LoadAndAddTail(f); break; + case COpList::OP_SUBLIST: hr = list.LoadAndAddTail(f); break; default: // Unsupported type of operation. hr = E_UNEXPECTED; diff --git a/MSICALib/MSICALib.vcxproj b/MSICALib/MSICALib.vcxproj index e01d031..ecc37e1 100644 --- a/MSICALib/MSICALib.vcxproj +++ b/MSICALib/MSICALib.vcxproj @@ -25,6 +25,7 @@ + Create Create diff --git a/MSICALib/MSICALib.vcxproj.filters b/MSICALib/MSICALib.vcxproj.filters index 7f72ba2..6b2fabb 100644 --- a/MSICALib/MSICALib.vcxproj.filters +++ b/MSICALib/MSICALib.vcxproj.filters @@ -36,6 +36,9 @@ Source Files + + Source Files + diff --git a/MSICALib/OpCert.cpp b/MSICALib/OpCert.cpp index 0b9d1de..beadb5e 100644 --- a/MSICALib/OpCert.cpp +++ b/MSICALib/OpCert.cpp @@ -83,9 +83,9 @@ HRESULT COpCertInstall::Execute(CSession *pSession) return S_OK; else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_CERT_INSTALL_FAILED); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, dwError ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_CERT_INSTALL); + ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); + ::MsiRecordSetInteger(hRecordProg, 3, dwError ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(dwError); } @@ -150,9 +150,9 @@ HRESULT COpCertRemove::Execute(CSession *pSession) return S_OK; else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_CERT_REMOVE_FAILED); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, dwError ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_CERT_REMOVE); + ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); + ::MsiRecordSetInteger(hRecordProg, 3, dwError ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(dwError); } diff --git a/MSICALib/OpFile.cpp b/MSICALib/OpFile.cpp index eaa74b5..98a0dcc 100644 --- a/MSICALib/OpFile.cpp +++ b/MSICALib/OpFile.cpp @@ -42,9 +42,9 @@ HRESULT COpFileDelete::Execute(CSession *pSession) return S_OK; else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_FILE_DELETE_FAILED); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, dwError ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_FILE_DELETE); + ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); + ::MsiRecordSetInteger(hRecordProg, 3, dwError ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(dwError); } @@ -76,10 +76,10 @@ HRESULT COpFileMove::Execute(CSession *pSession) return S_OK; } else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(4); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_FILE_MOVE_FAILED); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue1 ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue2 ); - ::MsiRecordSetInteger(hRecordProg, 4, dwError ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_FILE_MOVE); + ::MsiRecordSetStringW(hRecordProg, 2, m_sValue1 ); + ::MsiRecordSetStringW(hRecordProg, 3, m_sValue2 ); + ::MsiRecordSetInteger(hRecordProg, 4, dwError ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(dwError); } diff --git a/MSICALib/OpReg.cpp b/MSICALib/OpReg.cpp index a651450..4c8d554 100644 --- a/MSICALib/OpReg.cpp +++ b/MSICALib/OpReg.cpp @@ -86,10 +86,10 @@ HRESULT COpRegKeyCreate::Execute(CSession *pSession) return S_OK; else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(4); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_CREATE_FAILED); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 4, lResult ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_CREATE ); + ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff); + ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); + ::MsiRecordSetInteger(hRecordProg, 4, lResult ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(lResult); } @@ -137,11 +137,11 @@ HRESULT COpRegKeyCopy::Execute(CSession *pSession) return S_OK; else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(5); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_COPY_FAILED); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue1 ); - ::MsiRecordSetStringW(hRecordProg, 4, m_sValue2 ); - ::MsiRecordSetInteger(hRecordProg, 5, lResult ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_COPY ); + ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff); + ::MsiRecordSetStringW(hRecordProg, 3, m_sValue1 ); + ::MsiRecordSetStringW(hRecordProg, 4, m_sValue2 ); + ::MsiRecordSetInteger(hRecordProg, 5, lResult ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(lResult); } @@ -336,10 +336,10 @@ HRESULT COpRegKeyDelete::Execute(CSession *pSession) pSession->m_olCommit.AddTail(new COpRegKeyDelete(m_hKeyRoot, sBackupName)); } else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(4); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_PROBING_FAILED); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); - ::MsiRecordSetStringW(hRecordProg, 3, sBackupName ); - ::MsiRecordSetInteger(hRecordProg, 4, lResult ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_PROBING ); + ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff); + ::MsiRecordSetStringW(hRecordProg, 3, sBackupName ); + ::MsiRecordSetInteger(hRecordProg, 4, lResult ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(lResult); } @@ -353,10 +353,10 @@ HRESULT COpRegKeyDelete::Execute(CSession *pSession) return S_OK; else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(4); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_DELETE_FAILED); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 4, lResult ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_DELETE ); + ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff); + ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); + ::MsiRecordSetInteger(hRecordProg, 4, lResult ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(lResult); } @@ -549,11 +549,11 @@ HRESULT COpRegValueCreate::Execute(CSession *pSession) return S_OK; else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(5); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_SETVALUE_FAILED); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetStringW(hRecordProg, 4, m_sValueName ); - ::MsiRecordSetInteger(hRecordProg, 5, lResult ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_SETVALUE); + ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff); + ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); + ::MsiRecordSetStringW(hRecordProg, 4, m_sValueName ); + ::MsiRecordSetInteger(hRecordProg, 5, lResult ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(lResult); } @@ -621,12 +621,12 @@ HRESULT COpRegValueCopy::Execute(CSession *pSession) return S_OK; else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(6); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_COPYVALUE_FAILED); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetStringW(hRecordProg, 4, m_sValueName1 ); - ::MsiRecordSetStringW(hRecordProg, 5, m_sValueName2 ); - ::MsiRecordSetInteger(hRecordProg, 6, lResult ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_COPYVALUE); + ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); + ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); + ::MsiRecordSetStringW(hRecordProg, 4, m_sValueName1 ); + ::MsiRecordSetStringW(hRecordProg, 5, m_sValueName2 ); + ::MsiRecordSetInteger(hRecordProg, 6, lResult ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(lResult); } @@ -689,11 +689,11 @@ HRESULT COpRegValueDelete::Execute(CSession *pSession) pSession->m_olCommit.AddTail(new COpRegValueDelete(m_hKeyRoot, m_sValue, sBackupName)); } else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(5); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_PROBINGVAL_FAILED); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetStringW(hRecordProg, 3, sBackupName ); - ::MsiRecordSetInteger(hRecordProg, 4, lResult ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_PROBINGVAL); + ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); + ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); + ::MsiRecordSetStringW(hRecordProg, 3, sBackupName ); + ::MsiRecordSetInteger(hRecordProg, 4, lResult ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); ::RegCloseKey(hKey); return AtlHresultFromWin32(lResult); @@ -711,11 +711,11 @@ HRESULT COpRegValueDelete::Execute(CSession *pSession) return S_OK; else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(5); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_DELETEVALUE_FAILED); - ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); - ::MsiRecordSetStringW(hRecordProg, 4, m_sValueName ); - ::MsiRecordSetInteger(hRecordProg, 5, lResult ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_DELETEVALUE); + ::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ); + ::MsiRecordSetStringW(hRecordProg, 3, m_sValue ); + ::MsiRecordSetStringW(hRecordProg, 4, m_sValueName ); + ::MsiRecordSetInteger(hRecordProg, 5, lResult ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(lResult); } diff --git a/MSICALib/OpSvc.cpp b/MSICALib/OpSvc.cpp index c5115b5..deeff42 100644 --- a/MSICALib/OpSvc.cpp +++ b/MSICALib/OpSvc.cpp @@ -67,9 +67,9 @@ HRESULT COpSvcSetStart::Execute(CSession *pSession) return S_OK; else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_SVC_SET_START_FAILED); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, dwError ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_SVC_SET_START); + ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); + ::MsiRecordSetInteger(hRecordProg, 3, dwError ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(dwError); } @@ -170,9 +170,9 @@ HRESULT COpSvcStart::Execute(CSession *pSession) return S_OK; else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_SVC_START_FAILED); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, dwError ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_SVC_START); + ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); + ::MsiRecordSetInteger(hRecordProg, 3, dwError ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(dwError); } @@ -225,9 +225,9 @@ HRESULT COpSvcStop::Execute(CSession *pSession) return S_OK; else { PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_SVC_STOP_FAILED); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, dwError ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_SVC_STOP); + ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); + ::MsiRecordSetInteger(hRecordProg, 3, dwError ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); return AtlHresultFromWin32(dwError); } diff --git a/MSICALib/OpTS.cpp b/MSICALib/OpTS.cpp index 14900d2..7524131 100644 --- a/MSICALib/OpTS.cpp +++ b/MSICALib/OpTS.cpp @@ -431,9 +431,9 @@ HRESULT COpTaskCreate::Execute(CSession *pSession) finish: if (FAILED(hr)) { PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_TASK_CREATE_FAILED); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, hr ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_TASK_CREATE); + ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); + ::MsiRecordSetInteger(hRecordProg, 3, hr ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); } return hr; @@ -801,9 +801,9 @@ HRESULT COpTaskDelete::Execute(CSession *pSession) finish: if (FAILED(hr)) { PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_TASK_DELETE_FAILED); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, hr ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_TASK_DELETE); + ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); + ::MsiRecordSetInteger(hRecordProg, 3, hr ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); } return hr; @@ -921,9 +921,9 @@ HRESULT COpTaskEnable::Execute(CSession *pSession) finish: if (FAILED(hr)) { PMSIHANDLE hRecordProg = ::MsiCreateRecord(3); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_TASK_ENABLE_FAILED); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); - ::MsiRecordSetInteger(hRecordProg, 3, hr ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_TASK_ENABLE); + ::MsiRecordSetStringW(hRecordProg, 2, m_sValue ); + ::MsiRecordSetInteger(hRecordProg, 3, hr ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); } return hr; @@ -1026,10 +1026,10 @@ HRESULT COpTaskCopy::Execute(CSession *pSession) finish: if (FAILED(hr)) { PMSIHANDLE hRecordProg = ::MsiCreateRecord(4); - ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_TASK_COPY_FAILED); - ::MsiRecordSetStringW(hRecordProg, 2, m_sValue1 ); - ::MsiRecordSetStringW(hRecordProg, 3, m_sValue2 ); - ::MsiRecordSetInteger(hRecordProg, 4, hr ); + ::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_TASK_COPY); + ::MsiRecordSetStringW(hRecordProg, 2, m_sValue1 ); + ::MsiRecordSetStringW(hRecordProg, 3, m_sValue2 ); + ::MsiRecordSetInteger(hRecordProg, 4, hr ); ::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg); } return hr; diff --git a/MSICALib/OpWLAN.cpp b/MSICALib/OpWLAN.cpp new file mode 100644 index 0000000..b443307 --- /dev/null +++ b/MSICALib/OpWLAN.cpp @@ -0,0 +1,182 @@ +#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 diff --git a/MSICALib/stdafx.h b/MSICALib/stdafx.h index 9e433b4..1635444 100644 --- a/MSICALib/stdafx.h +++ b/MSICALib/stdafx.h @@ -31,5 +31,6 @@ #include #include #include +#include #include "MSICALib.h" diff --git a/include/version.h b/include/version.h index 730ad24..3e5be20 100644 --- a/include/version.h +++ b/include/version.h @@ -1,9 +1,9 @@ -#define MSICA_VERSION 0x00ff0100 +#define MSICA_VERSION 0x00ff0200 #define MSICA_VERSION_MAJ 0 #define MSICA_VERSION_MIN 255 -#define MSICA_VERSION_REV 1 +#define MSICA_VERSION_REV 2 #define MSICA_VERSION_BUILD 0 -#define MSICA_VERSION_STR "1.0-pre1" +#define MSICA_VERSION_STR "1.0-pre2" #define MSICA_BUILD_YEAR_STR "2014"