Dodal sem podporo za delo s ključi v registru. Ni še dokončna. Vseeno uveljavljam, da bo na varnem.
This commit is contained in:
parent
b68530c0a2
commit
12a8cbd84e
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -9,6 +9,7 @@ AMSICA/res/en_GB.po -text
|
|||||||
AMSICA/src/AMSICA.cpp -text
|
AMSICA/src/AMSICA.cpp -text
|
||||||
AMSICA/src/AMSICAFileOp.cpp -text
|
AMSICA/src/AMSICAFileOp.cpp -text
|
||||||
AMSICA/src/AMSICATSOp.cpp -text
|
AMSICA/src/AMSICATSOp.cpp -text
|
||||||
|
AMSICA/src/MSICARegOp.cpp -text
|
||||||
AMSICA/src/StdAfx.cpp -text
|
AMSICA/src/StdAfx.cpp -text
|
||||||
MSITSCA/L10N/sl_SI.po -text
|
MSITSCA/L10N/sl_SI.po -text
|
||||||
MSITSCA/MSITSCA.cpp -text
|
MSITSCA/MSITSCA.cpp -text
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
<ClCompile Include="..\src\AMSICA.cpp" />
|
<ClCompile Include="..\src\AMSICA.cpp" />
|
||||||
<ClCompile Include="..\src\AMSICAFileOp.cpp" />
|
<ClCompile Include="..\src\AMSICAFileOp.cpp" />
|
||||||
<ClCompile Include="..\src\AMSICATSOp.cpp" />
|
<ClCompile Include="..\src\AMSICATSOp.cpp" />
|
||||||
|
<ClCompile Include="..\src\MSICARegOp.cpp" />
|
||||||
<ClCompile Include="..\src\StdAfx.cpp">
|
<ClCompile Include="..\src\StdAfx.cpp">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||||
|
@ -27,6 +27,9 @@
|
|||||||
<ClCompile Include="..\src\StdAfx.cpp">
|
<ClCompile Include="..\src\StdAfx.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\MSICARegOp.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\include\AMSICA.h">
|
<ClInclude Include="..\include\AMSICA.h">
|
||||||
|
@ -26,11 +26,15 @@
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Error codes (last unused 2561L)
|
// Error codes (next unused 2565L)
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#define ERROR_INSTALL_DELETE_FAILED 2554L
|
#define ERROR_INSTALL_FILE_DELETE_FAILED 2554L
|
||||||
#define ERROR_INSTALL_MOVE_FAILED 2555L
|
#define ERROR_INSTALL_FILE_MOVE_FAILED 2555L
|
||||||
|
#define ERROR_INSTALL_REGKEY_CREATE_FAILED 2561L
|
||||||
|
#define ERROR_INSTALL_REGKEY_COPY_FAILED 2562L
|
||||||
|
#define ERROR_INSTALL_REGKEY_PROBING_FAILED 2563L
|
||||||
|
#define ERROR_INSTALL_REGKEY_DELETE_FAILED 2564L
|
||||||
#define ERROR_INSTALL_TASK_CREATE_FAILED 2556L
|
#define ERROR_INSTALL_TASK_CREATE_FAILED 2556L
|
||||||
#define ERROR_INSTALL_TASK_DELETE_FAILED 2557L
|
#define ERROR_INSTALL_TASK_DELETE_FAILED 2557L
|
||||||
#define ERROR_INSTALL_TASK_ENABLE_FAILED 2558L
|
#define ERROR_INSTALL_TASK_ENABLE_FAILED 2558L
|
||||||
@ -83,8 +87,8 @@ class COpTypeSingleString : public COperation
|
|||||||
public:
|
public:
|
||||||
COpTypeSingleString(LPCWSTR pszValue = L"", int iTicks = 0);
|
COpTypeSingleString(LPCWSTR pszValue = L"", int iTicks = 0);
|
||||||
|
|
||||||
friend inline HRESULT operator <<(ATL::CAtlFile &f, const AMSICA::COpTypeSingleString &op);
|
friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpTypeSingleString &op);
|
||||||
friend inline HRESULT operator >>(ATL::CAtlFile &f, AMSICA::COpTypeSingleString &op);
|
friend inline HRESULT operator >>(ATL::CAtlFile &f, COpTypeSingleString &op);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ATL::CAtlStringW m_sValue;
|
ATL::CAtlStringW m_sValue;
|
||||||
@ -100,8 +104,8 @@ class COpTypeSrcDstString : public COperation
|
|||||||
public:
|
public:
|
||||||
COpTypeSrcDstString(LPCWSTR pszValue1 = L"", LPCWSTR pszValue2 = L"", int iTicks = 0);
|
COpTypeSrcDstString(LPCWSTR pszValue1 = L"", LPCWSTR pszValue2 = L"", int iTicks = 0);
|
||||||
|
|
||||||
friend inline HRESULT operator <<(ATL::CAtlFile &f, const AMSICA::COpTypeSrcDstString &op);
|
friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpTypeSrcDstString &op);
|
||||||
friend inline HRESULT operator >>(ATL::CAtlFile &f, AMSICA::COpTypeSrcDstString &op);
|
friend inline HRESULT operator >>(ATL::CAtlFile &f, COpTypeSrcDstString &op);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ATL::CAtlStringW m_sValue1;
|
ATL::CAtlStringW m_sValue1;
|
||||||
@ -118,8 +122,8 @@ class COpTypeBoolean : public COperation
|
|||||||
public:
|
public:
|
||||||
COpTypeBoolean(BOOL bValue = TRUE, int iTicks = 0);
|
COpTypeBoolean(BOOL bValue = TRUE, int iTicks = 0);
|
||||||
|
|
||||||
friend inline HRESULT operator <<(ATL::CAtlFile &f, const AMSICA::COpTypeBoolean &op);
|
friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpTypeBoolean &op);
|
||||||
friend inline HRESULT operator >>(ATL::CAtlFile &f, AMSICA::COpTypeBoolean &op);
|
friend inline HRESULT operator >>(ATL::CAtlFile &f, COpTypeBoolean &op);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BOOL m_bValue;
|
BOOL m_bValue;
|
||||||
@ -162,6 +166,82 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COpRegKeySingle
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class COpRegKeySingle : public COpTypeSingleString
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
COpRegKeySingle(HKEY hKeyRoot = NULL, LPCWSTR pszKeyName = L"", int iTicks = 0);
|
||||||
|
|
||||||
|
friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegKeySingle &op);
|
||||||
|
friend inline HRESULT operator >>(ATL::CAtlFile &f, COpRegKeySingle &op);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
HKEY m_hKeyRoot;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COpRegKeySrcDst
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class COpRegKeySrcDst : public COpTypeSrcDstString
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
COpRegKeySrcDst(HKEY hKeyRoot = NULL, LPCWSTR pszKeyNameSrc = L"", LPCWSTR pszKeyNameDst = L"", int iTicks = 0);
|
||||||
|
|
||||||
|
friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegKeySrcDst &op);
|
||||||
|
friend inline HRESULT operator >>(ATL::CAtlFile &f, COpRegKeySrcDst &op);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
HKEY m_hKeyRoot;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COpRegKeyCreate
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class COpRegKeyCreate : public COpRegKeySingle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
COpRegKeyCreate(HKEY hKeyRoot = NULL, LPCWSTR pszKeyName = L"", int iTicks = 0);
|
||||||
|
virtual HRESULT Execute(CSession *pSession);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COpRegKeyCopy
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class COpRegKeyCopy : public COpRegKeySrcDst
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
COpRegKeyCopy(HKEY hKey = NULL, LPCWSTR pszKeyNameSrc = L"", LPCWSTR pszKeyNameDst = L"", int iTicks = 0);
|
||||||
|
virtual HRESULT Execute(CSession *pSession);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static LONG CopyKeyRecursively(HKEY hKeyRoot, LPCWSTR pszKeyNameSrc, LPCWSTR pszKeyNameDst, REGSAM samAdditional);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COpRegKeyDelete
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
class COpRegKeyDelete : public COpRegKeySingle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
COpRegKeyDelete(HKEY hKey = NULL, LPCWSTR pszKeyName = L"", int iTicks = 0);
|
||||||
|
virtual HRESULT Execute(CSession *pSession);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static LONG DeleteKeyRecursively(HKEY hKeyRoot, LPCWSTR pszKeyName, REGSAM sam);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// COpTaskCreate
|
// COpTaskCreate
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
@ -176,8 +256,8 @@ public:
|
|||||||
UINT SetFromRecord(MSIHANDLE hInstall, MSIHANDLE hRecord);
|
UINT SetFromRecord(MSIHANDLE hInstall, MSIHANDLE hRecord);
|
||||||
UINT SetTriggersFromView(MSIHANDLE hView);
|
UINT SetTriggersFromView(MSIHANDLE hView);
|
||||||
|
|
||||||
friend inline HRESULT operator <<(ATL::CAtlFile &f, const AMSICA::COpTaskCreate &op);
|
friend inline HRESULT operator <<(ATL::CAtlFile &f, const COpTaskCreate &op);
|
||||||
friend inline HRESULT operator >>(ATL::CAtlFile &f, AMSICA::COpTaskCreate &op);
|
friend inline HRESULT operator >>(ATL::CAtlFile &f, COpTaskCreate &op);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ATL::CAtlStringW m_sApplicationName;
|
ATL::CAtlStringW m_sApplicationName;
|
||||||
@ -665,7 +745,7 @@ inline HRESULT operator >>(ATL::CAtlFile &f, TASK_TRIGGER &ttData)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline HRESULT operator <<(ATL::CAtlFile &f, const AMSICA::COperation &op)
|
inline HRESULT operator <<(ATL::CAtlFile &f, const COperation &op)
|
||||||
{
|
{
|
||||||
return f << op.m_iTicks;
|
return f << op.m_iTicks;
|
||||||
}
|
}
|
||||||
@ -740,8 +820,8 @@ inline HRESULT operator <<(ATL::CAtlFile &f, const COpTypeBoolean &op)
|
|||||||
|
|
||||||
inline HRESULT operator >>(ATL::CAtlFile &f, COpTypeBoolean &op)
|
inline HRESULT operator >>(ATL::CAtlFile &f, COpTypeBoolean &op)
|
||||||
{
|
{
|
||||||
int iValue;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
int iValue;
|
||||||
|
|
||||||
hr = f >> (COperation &)op;
|
hr = f >> (COperation &)op;
|
||||||
if (FAILED(hr)) return hr;
|
if (FAILED(hr)) return hr;
|
||||||
@ -754,6 +834,53 @@ inline HRESULT operator >>(ATL::CAtlFile &f, COpTypeBoolean &op)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegKeySingle &op)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = f << (const COpTypeSingleString &)op; if (FAILED(hr)) return hr;
|
||||||
|
hr = f << (int)(op.m_hKeyRoot); if (FAILED(hr)) return hr;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline HRESULT operator >>(ATL::CAtlFile &f, COpRegKeySingle &op)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
int iValue;
|
||||||
|
|
||||||
|
hr = f >> (COpTypeSingleString &)op; if (FAILED(hr)) return hr;
|
||||||
|
hr = f >> iValue; if (FAILED(hr)) return hr; op.m_hKeyRoot = (HKEY)iValue;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline HRESULT operator <<(ATL::CAtlFile &f, const COpRegKeySrcDst &op)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
hr = f << (const COpTypeSrcDstString &)op; if (FAILED(hr)) return hr;
|
||||||
|
hr = f << (int)(op.m_hKeyRoot); if (FAILED(hr)) return hr;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline HRESULT operator >>(ATL::CAtlFile &f, COpRegKeySrcDst &op)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
int iValue;
|
||||||
|
|
||||||
|
hr = f >> (COpTypeSrcDstString &)op; if (FAILED(hr)) return hr;
|
||||||
|
hr = f >> iValue; if (FAILED(hr)) return hr; op.m_hKeyRoot = (HKEY)iValue;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline HRESULT operator <<(ATL::CAtlFile &f, const COpTaskCreate &op)
|
inline HRESULT operator <<(ATL::CAtlFile &f, const COpTaskCreate &op)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
@ -934,6 +1061,44 @@ inline HRESULT operator >>(ATL::CAtlFile &f, COpList &list)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Inline Functions
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
inline BOOL IsWow64Process()
|
||||||
|
{
|
||||||
|
#ifndef _WIN64
|
||||||
|
// Find IsWow64Process() address in KERNEL32.DLL.
|
||||||
|
BOOL (WINAPI *_IsWow64Process)(__in HANDLE hProcess, __out PBOOL Wow64Process) = (BOOL(WINAPI*)(__in HANDLE, __out PBOOL))::GetProcAddress(::GetModuleHandle(_T("KERNEL32.DLL")), "IsWow64Process");
|
||||||
|
|
||||||
|
// See if our 32-bit process is running in 64-bit environment.
|
||||||
|
if (_IsWow64Process) {
|
||||||
|
BOOL bResult;
|
||||||
|
|
||||||
|
// See, what IsWow64Process() says about current process.
|
||||||
|
if (_IsWow64Process(::GetCurrentProcess(), &bResult)) {
|
||||||
|
// Return result.
|
||||||
|
return bResult;
|
||||||
|
} else {
|
||||||
|
// IsWow64Process() returned an error. Assume, the process is not WOW64.
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// This KERNEL32.DLL doesn't know IsWow64Process().Definitely not a WOW64 process.
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// 64-bit processes are never run as WOW64.
|
||||||
|
return FALSE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
// Inline methods
|
// Inline methods
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -43,7 +43,7 @@ HRESULT COpFileDelete::Execute(CSession *pSession)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
else {
|
else {
|
||||||
PMSIHANDLE hRecordProg = ::MsiCreateRecord(3);
|
PMSIHANDLE hRecordProg = ::MsiCreateRecord(3);
|
||||||
verify(::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_DELETE_FAILED) == ERROR_SUCCESS);
|
verify(::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_FILE_DELETE_FAILED) == ERROR_SUCCESS);
|
||||||
verify(::MsiRecordSetStringW(hRecordProg, 2, m_sValue ) == ERROR_SUCCESS);
|
verify(::MsiRecordSetStringW(hRecordProg, 2, m_sValue ) == ERROR_SUCCESS);
|
||||||
verify(::MsiRecordSetInteger(hRecordProg, 3, dwError ) == ERROR_SUCCESS);
|
verify(::MsiRecordSetInteger(hRecordProg, 3, dwError ) == ERROR_SUCCESS);
|
||||||
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
||||||
@ -78,7 +78,7 @@ HRESULT COpFileMove::Execute(CSession *pSession)
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
} else {
|
} else {
|
||||||
PMSIHANDLE hRecordProg = ::MsiCreateRecord(4);
|
PMSIHANDLE hRecordProg = ::MsiCreateRecord(4);
|
||||||
verify(::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_MOVE_FAILED) == ERROR_SUCCESS);
|
verify(::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_FILE_MOVE_FAILED) == ERROR_SUCCESS);
|
||||||
verify(::MsiRecordSetStringW(hRecordProg, 2, m_sValue1 ) == ERROR_SUCCESS);
|
verify(::MsiRecordSetStringW(hRecordProg, 2, m_sValue1 ) == ERROR_SUCCESS);
|
||||||
verify(::MsiRecordSetStringW(hRecordProg, 3, m_sValue2 ) == ERROR_SUCCESS);
|
verify(::MsiRecordSetStringW(hRecordProg, 3, m_sValue2 ) == ERROR_SUCCESS);
|
||||||
verify(::MsiRecordSetInteger(hRecordProg, 4, dwError ) == ERROR_SUCCESS);
|
verify(::MsiRecordSetInteger(hRecordProg, 4, dwError ) == ERROR_SUCCESS);
|
||||||
|
@ -45,8 +45,8 @@ HRESULT COpTaskCreate::Execute(CSession *pSession)
|
|||||||
// Delete existing task first.
|
// Delete existing task first.
|
||||||
// Since task deleting is a complicated job (when rollback/commit support is required), and we do have an operation just for that, we use it.
|
// Since task deleting 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, COpTaskDelete::Execute() returns S_OK if task doesn't exist.
|
// Don't worry, COpTaskDelete::Execute() returns S_OK if task doesn't exist.
|
||||||
COpTaskDelete opDeleteTask(m_sValue);
|
COpTaskDelete opDelete(m_sValue);
|
||||||
hr = opDeleteTask.Execute(pSession);
|
hr = opDelete.Execute(pSession);
|
||||||
if (FAILED(hr)) goto finish;
|
if (FAILED(hr)) goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
279
AMSICA/src/MSICARegOp.cpp
Normal file
279
AMSICA/src/MSICARegOp.cpp
Normal file
@ -0,0 +1,279 @@
|
|||||||
|
#include "StdAfx.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace AMSICA {
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COpRegKeySingle
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
COpRegKeySingle::COpRegKeySingle(HKEY hKeyRoot, LPCWSTR pszKeyName, int iTicks) :
|
||||||
|
m_hKeyRoot(hKeyRoot),
|
||||||
|
COpTypeSingleString(pszKeyName, iTicks)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COpRegKeySrcDst
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
COpRegKeySrcDst::COpRegKeySrcDst(HKEY hKeyRoot, LPCWSTR pszKeyNameSrc, LPCWSTR pszKeyNameDst, int iTicks) :
|
||||||
|
m_hKeyRoot(hKeyRoot),
|
||||||
|
COpTypeSrcDstString(pszKeyNameSrc, pszKeyNameDst, iTicks)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COpRegKeyCreate
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
COpRegKeyCreate::COpRegKeyCreate(HKEY hKeyRoot, LPCWSTR pszKeyName, int iTicks) : COpRegKeySingle(hKeyRoot, pszKeyName, iTicks)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT COpRegKeyCreate::Execute(CSession *pSession)
|
||||||
|
{
|
||||||
|
assert(pSession);
|
||||||
|
LONG lResult;
|
||||||
|
REGSAM samAdditional = 0;
|
||||||
|
ATL::CAtlStringW sPartialName;
|
||||||
|
int iStart = 0;
|
||||||
|
|
||||||
|
assert(0); // TODO: Preizkusi ta del kode.
|
||||||
|
|
||||||
|
#ifndef _WIN64
|
||||||
|
if (IsWow64Process()) {
|
||||||
|
// 32-bit processes run as WOW64 should use 64-bit registry too.
|
||||||
|
samAdditional |= KEY_WOW64_64KEY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
HKEY hKey;
|
||||||
|
|
||||||
|
int iStartNext = m_sValue.Find(L'\\', iStart);
|
||||||
|
if (iStartNext >= 0)
|
||||||
|
sPartialName.SetString(m_sValue, iStartNext);
|
||||||
|
else
|
||||||
|
sPartialName = m_sValue;
|
||||||
|
|
||||||
|
// Try to open the key, to see if it exists.
|
||||||
|
lResult = ::RegOpenKeyExW(m_hKeyRoot, sPartialName, 0, KEY_ENUMERATE_SUB_KEYS | samAdditional, &hKey);
|
||||||
|
if (lResult == ERROR_FILE_NOT_FOUND) {
|
||||||
|
// The key doesn't exist yet. Create it.
|
||||||
|
|
||||||
|
if (pSession->m_bRollbackEnabled) {
|
||||||
|
// Order rollback action to delete the key. ::RegCreateEx() might create a key but return failure.
|
||||||
|
pSession->m_olRollback.AddHead(new COpRegKeyDelete(m_hKeyRoot, sPartialName));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the key.
|
||||||
|
lResult = ::RegCreateKeyExW(m_hKeyRoot, sPartialName, NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_ENUMERATE_SUB_KEYS | samAdditional, NULL, &hKey, NULL);
|
||||||
|
if (lResult != ERROR_SUCCESS) break;
|
||||||
|
verify(::RegCloseKey(hKey) == ERROR_SUCCESS);
|
||||||
|
} else if (lResult == ERROR_SUCCESS) {
|
||||||
|
// This key already exists. Release its handle and continue.
|
||||||
|
verify(::RegCloseKey(hKey) == ERROR_SUCCESS);
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (iStartNext < 0) break;
|
||||||
|
iStart = iStartNext + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lResult == ERROR_SUCCESS)
|
||||||
|
return S_OK;
|
||||||
|
else {
|
||||||
|
PMSIHANDLE hRecordProg = ::MsiCreateRecord(4);
|
||||||
|
verify(::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_CREATE_FAILED) == ERROR_SUCCESS);
|
||||||
|
verify(::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ) == ERROR_SUCCESS);
|
||||||
|
verify(::MsiRecordSetStringW(hRecordProg, 3, m_sValue ) == ERROR_SUCCESS);
|
||||||
|
verify(::MsiRecordSetInteger(hRecordProg, 4, lResult ) == ERROR_SUCCESS);
|
||||||
|
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
||||||
|
return AtlHresultFromWin32(lResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COpRegKeyCopy
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
COpRegKeyCopy::COpRegKeyCopy(HKEY hKeyRoot, LPCWSTR pszKeyNameSrc, LPCWSTR pszKeyNameDst, int iTicks) : COpRegKeySrcDst(hKeyRoot, pszKeyNameSrc, pszKeyNameDst, iTicks)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT COpRegKeyCopy::Execute(CSession *pSession)
|
||||||
|
{
|
||||||
|
assert(pSession);
|
||||||
|
LONG lResult;
|
||||||
|
REGSAM samAdditional = 0;
|
||||||
|
|
||||||
|
assert(0); // TODO: Preizkusi ta del kode.
|
||||||
|
|
||||||
|
{
|
||||||
|
// Delete existing destination key first.
|
||||||
|
// Since deleting registry key 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, COpRegKeyDelete::Execute() returns S_OK if key doesn't exist.
|
||||||
|
COpRegKeyDelete opDelete(m_hKeyRoot, m_sValue2);
|
||||||
|
HRESULT hr = opDelete.Execute(pSession);
|
||||||
|
if (FAILED(hr)) return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _WIN64
|
||||||
|
if (IsWow64Process()) {
|
||||||
|
// 32-bit processes run as WOW64 should use 64-bit registry too.
|
||||||
|
samAdditional |= KEY_WOW64_64KEY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pSession->m_bRollbackEnabled) {
|
||||||
|
// Order rollback action to delete the destination key.
|
||||||
|
pSession->m_olRollback.AddHead(new COpRegKeyDelete(m_hKeyRoot, m_sValue2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy the registry key.
|
||||||
|
lResult = CopyKeyRecursively(m_hKeyRoot, m_sValue1, m_sValue2, samAdditional);
|
||||||
|
if (lResult == ERROR_SUCCESS)
|
||||||
|
return S_OK;
|
||||||
|
else {
|
||||||
|
PMSIHANDLE hRecordProg = ::MsiCreateRecord(5);
|
||||||
|
verify(::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_COPY_FAILED) == ERROR_SUCCESS);
|
||||||
|
verify(::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ) == ERROR_SUCCESS);
|
||||||
|
verify(::MsiRecordSetStringW(hRecordProg, 3, m_sValue1 ) == ERROR_SUCCESS);
|
||||||
|
verify(::MsiRecordSetStringW(hRecordProg, 4, m_sValue2 ) == ERROR_SUCCESS);
|
||||||
|
verify(::MsiRecordSetInteger(hRecordProg, 5, lResult ) == ERROR_SUCCESS);
|
||||||
|
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
||||||
|
return AtlHresultFromWin32(lResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
// COpRegKeyDelete
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
COpRegKeyDelete::COpRegKeyDelete(HKEY hKeyRoot, LPCWSTR m_hKeyRoot, int iTicks) : COpRegKeySingle(hKeyRoot, m_hKeyRoot, iTicks)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT COpRegKeyDelete::Execute(CSession *pSession)
|
||||||
|
{
|
||||||
|
assert(pSession);
|
||||||
|
LONG lResult;
|
||||||
|
REGSAM samAdditional = 0;
|
||||||
|
|
||||||
|
assert(0); // TODO: Preizkusi ta del kode.
|
||||||
|
|
||||||
|
#ifndef _WIN64
|
||||||
|
if (IsWow64Process()) {
|
||||||
|
// 32-bit processes run as WOW64 should use 64-bit registry too.
|
||||||
|
samAdditional |= KEY_WOW64_64KEY;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (pSession->m_bRollbackEnabled) {
|
||||||
|
// Make a backup of the key first.
|
||||||
|
ATL::CAtlStringW sBackupName;
|
||||||
|
UINT uiCount = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
HKEY hKey;
|
||||||
|
sBackupName.Format(L"%ls (orig %u)", (LPCWSTR)m_sValue, ++uiCount);
|
||||||
|
lResult = ::RegOpenKeyExW(m_hKeyRoot, sBackupName, 0, KEY_ENUMERATE_SUB_KEYS | samAdditional, &hKey);
|
||||||
|
if (lResult != ERROR_SUCCESS) break;
|
||||||
|
verify(::RegCloseKey(hKey));
|
||||||
|
}
|
||||||
|
if (lResult == ERROR_FILE_NOT_FOUND) {
|
||||||
|
// Since copying registry key is a complicated job (when rollback/commit support is required), and we do have an operation just for that, we use it.
|
||||||
|
COpRegKeyCopy opCopy(m_hKeyRoot, m_sValue, sBackupName);
|
||||||
|
HRESULT hr = opCopy.Execute(pSession);
|
||||||
|
if (FAILED(hr)) return hr;
|
||||||
|
|
||||||
|
// Order rollback action to restore the key from backup copy.
|
||||||
|
pSession->m_olRollback.AddHead(new COpRegKeyCopy(m_hKeyRoot, sBackupName, m_sValue));
|
||||||
|
|
||||||
|
// Order commit action to delete backup copy.
|
||||||
|
pSession->m_olCommit.AddTail(new COpRegKeyDelete(m_hKeyRoot, sBackupName, TRUE));
|
||||||
|
} else {
|
||||||
|
PMSIHANDLE hRecordProg = ::MsiCreateRecord(4);
|
||||||
|
verify(::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_PROBING_FAILED) == ERROR_SUCCESS);
|
||||||
|
verify(::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ) == ERROR_SUCCESS);
|
||||||
|
verify(::MsiRecordSetStringW(hRecordProg, 3, sBackupName ) == ERROR_SUCCESS);
|
||||||
|
verify(::MsiRecordSetInteger(hRecordProg, 4, lResult ) == ERROR_SUCCESS);
|
||||||
|
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
||||||
|
return AtlHresultFromWin32(lResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the registry key.
|
||||||
|
lResult = DeleteKeyRecursively(m_hKeyRoot, m_sValue, KEY_ENUMERATE_SUB_KEYS | samAdditional);
|
||||||
|
if (lResult == ERROR_SUCCESS)
|
||||||
|
return S_OK;
|
||||||
|
else {
|
||||||
|
PMSIHANDLE hRecordProg = ::MsiCreateRecord(4);
|
||||||
|
verify(::MsiRecordSetInteger(hRecordProg, 1, ERROR_INSTALL_REGKEY_DELETE_FAILED) == ERROR_SUCCESS);
|
||||||
|
verify(::MsiRecordSetInteger(hRecordProg, 2, (UINT)m_hKeyRoot & 0x7fffffff ) == ERROR_SUCCESS);
|
||||||
|
verify(::MsiRecordSetStringW(hRecordProg, 3, m_sValue ) == ERROR_SUCCESS);
|
||||||
|
verify(::MsiRecordSetInteger(hRecordProg, 4, lResult ) == ERROR_SUCCESS);
|
||||||
|
::MsiProcessMessage(pSession->m_hInstall, INSTALLMESSAGE_ERROR, hRecordProg);
|
||||||
|
return AtlHresultFromWin32(lResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LONG COpRegKeyDelete::DeleteKeyRecursively(HKEY hKeyRoot, LPCWSTR pszKeyName, REGSAM sam)
|
||||||
|
{
|
||||||
|
HKEY hKey;
|
||||||
|
LONG lResult;
|
||||||
|
|
||||||
|
// Open the key.
|
||||||
|
lResult = ::RegOpenKeyEx(hKeyRoot, pszKeyName, 0, sam, &hKey);
|
||||||
|
if (lResult == ERROR_SUCCESS) {
|
||||||
|
DWORD dwMaxSubKeyLen;
|
||||||
|
|
||||||
|
// Determine the largest subkey name.
|
||||||
|
lResult = ::RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, &dwMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
if (lResult == ERROR_SUCCESS) {
|
||||||
|
LPWSTR pszSubKeyName;
|
||||||
|
|
||||||
|
// Prepare buffer to hold the subkey names (including zero terminator).
|
||||||
|
dwMaxSubKeyLen++;
|
||||||
|
pszSubKeyName = new TCHAR[dwMaxSubKeyLen];
|
||||||
|
if (pszSubKeyName) {
|
||||||
|
DWORD dwIndex;
|
||||||
|
|
||||||
|
// Iterate over all subkeys and delete them. Skip failed.
|
||||||
|
for (dwIndex = 0; lResult != ERROR_NO_MORE_ITEMS ;) {
|
||||||
|
lResult = ::RegEnumKeyEx(hKey, dwIndex, pszSubKeyName, &dwMaxSubKeyLen, NULL, NULL, NULL, NULL);
|
||||||
|
if (lResult == ERROR_SUCCESS)
|
||||||
|
lResult = DeleteKeyRecursively(hKey, pszSubKeyName, sam);
|
||||||
|
else
|
||||||
|
dwIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] pszSubKeyName;
|
||||||
|
} else
|
||||||
|
lResult = ERROR_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
verify(::RegCloseKey(hKey) == ERROR_SUCCESS);
|
||||||
|
|
||||||
|
// Finally try to delete the key.
|
||||||
|
lResult = ::RegDeleteKeyW(hKeyRoot, pszKeyName);
|
||||||
|
} else if (lResult == ERROR_FILE_NOT_FOUND) {
|
||||||
|
// The key doesn't exist. Not really an error in this case.
|
||||||
|
lResult = ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace AMSICA
|
Loading…
x
Reference in New Issue
Block a user