From 3f583916719eeef598d10a5d4e14ef14f008243b Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Tue, 11 May 2021 07:36:37 -0700 Subject: Merge Dtf --- src/samples/Dtf/Tools/SfxCA/RemoteMsi.cpp | 629 ++++++++++++++++++++++++++++++ 1 file changed, 629 insertions(+) create mode 100644 src/samples/Dtf/Tools/SfxCA/RemoteMsi.cpp (limited to 'src/samples/Dtf/Tools/SfxCA/RemoteMsi.cpp') diff --git a/src/samples/Dtf/Tools/SfxCA/RemoteMsi.cpp b/src/samples/Dtf/Tools/SfxCA/RemoteMsi.cpp new file mode 100644 index 00000000..ba59fdf7 --- /dev/null +++ b/src/samples/Dtf/Tools/SfxCA/RemoteMsi.cpp @@ -0,0 +1,629 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. + +#include "precomp.h" +#include "RemoteMsiSession.h" + + +// +// Ensures that the request buffer is large enough to hold a request, +// reallocating the buffer if necessary. +// It will also reduce the buffer size if the previous allocation was very large. +// +static __success(return == 0) UINT EnsureBufSize(__deref_out_ecount(*pcchBuf) wchar_t** pszBuf, __deref_inout DWORD* pcchBuf, DWORD cchRequired) +{ + // It will also reduce the buffer size if the previous allocation was very large. + if (*pcchBuf < cchRequired || (LARGE_BUFFER_THRESHOLD/2 < *pcchBuf && cchRequired < *pcchBuf)) + { + if (*pszBuf != NULL) + { + SecureZeroMemory(*pszBuf, *pcchBuf); + delete[] *pszBuf; + } + + *pcchBuf = max(MIN_BUFFER_STRING_SIZE, cchRequired); + *pszBuf = new wchar_t[*pcchBuf]; + + if (*pszBuf == NULL) + { + return ERROR_OUTOFMEMORY; + } + } + + return ERROR_SUCCESS; +} + +typedef int (WINAPI *PMsiFunc_I_I)(int in1, __out int* out1); +typedef int (WINAPI *PMsiFunc_II_I)(int in1, int in2, __out int* out1); +typedef int (WINAPI *PMsiFunc_IS_I)(int in1, __in_z wchar_t* in2, __out int* out1); +typedef int (WINAPI *PMsiFunc_ISI_I)(int in1, __in_z wchar_t* in2, int in3, __out int* out1); +typedef int (WINAPI *PMsiFunc_ISII_I)(int in1, __in_z wchar_t* in2, int in3, int in4, __out int* out1); +typedef int (WINAPI *PMsiFunc_IS_II)(int in1, __in_z wchar_t* in2, __out int* out1, __out int* out2); +typedef MSIDBERROR (WINAPI *PMsiEFunc_I_S)(int in1, __out_ecount_full(*cchOut1) wchar_t* out1, __inout DWORD* cchOut1); +typedef int (WINAPI *PMsiFunc_I_S)(int in1, __out_ecount_full(*cchOut1) wchar_t* out1, __inout DWORD* cchOut1); +typedef int (WINAPI *PMsiFunc_II_S)(int in1, int in2, __out_ecount_full(*cchOut1) wchar_t* out1, __inout DWORD* cchOut1); +typedef int (WINAPI *PMsiFunc_IS_S)(int in1, __in_z wchar_t* in2, __out_ecount_full(*cchOut1) wchar_t* out1, __inout DWORD* cchOut1); +typedef int (WINAPI *PMsiFunc_ISII_SII)(int in1, __in_z wchar_t* in2, int in3, int in4, __out_ecount_full(*cchOut1) wchar_t* out1, __inout DWORD* cchOut1, __out int* out2, __out int* out3); + +UINT MsiFunc_I_I(PMsiFunc_I_I func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp) +{ + int in1 = pReq->fields[0].iValue; + int out1; + UINT ret = (UINT) func(in1, &out1); + if (ret == 0) + { + pResp->fields[1].vt = VT_I4; + pResp->fields[1].iValue = out1; + } + return ret; +} + +UINT MsiFunc_II_I(PMsiFunc_II_I func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp) +{ + int in1 = pReq->fields[0].iValue; + int in2 = pReq->fields[1].iValue; + int out1; + UINT ret = (UINT) func(in1, in2, &out1); + if (ret == 0) + { + pResp->fields[1].vt = VT_I4; + pResp->fields[1].iValue = out1; + } + return ret; +} + +UINT MsiFunc_IS_I(PMsiFunc_IS_I func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp) +{ + int in1 = pReq->fields[0].iValue; + wchar_t* in2 = pReq->fields[1].szValue; + int out1; + UINT ret = (UINT) func(in1, in2, &out1); + if (ret == 0) + { + pResp->fields[1].vt = VT_I4; + pResp->fields[1].iValue = out1; + } + return ret; +} + +UINT MsiFunc_ISI_I(PMsiFunc_ISI_I func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp) +{ + int in1 = pReq->fields[0].iValue; + wchar_t* in2 = pReq->fields[1].szValue; + int in3 = pReq->fields[2].iValue; + int out1; + UINT ret = (UINT) func(in1, in2, in3, &out1); + if (ret == 0) + { + pResp->fields[1].vt = VT_I4; + pResp->fields[1].iValue = out1; + } + return ret; +} + +UINT MsiFunc_ISII_I(PMsiFunc_ISII_I func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp) +{ + int in1 = pReq->fields[0].iValue; + wchar_t* in2 = pReq->fields[1].szValue; + int in3 = pReq->fields[2].iValue; + int in4 = pReq->fields[3].iValue; + int out1; + UINT ret = (UINT) func(in1, in2, in3, in4, &out1); + if (ret == 0) + { + pResp->fields[1].vt = VT_I4; + pResp->fields[1].iValue = out1; + } + return ret; +} + +UINT MsiFunc_IS_II(PMsiFunc_IS_II func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp) +{ + int in1 = pReq->fields[0].iValue; + wchar_t* in2 = pReq->fields[1].szValue; + int out1, out2; + UINT ret = (UINT) func(in1, in2, &out1, &out2); + if (ret == 0) + { + pResp->fields[1].vt = VT_I4; + pResp->fields[1].iValue = out1; + pResp->fields[2].vt = VT_I4; + pResp->fields[2].iValue = out2; + } + return ret; +} + +UINT MsiFunc_I_S(PMsiFunc_I_S func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp, __deref_inout_ecount(cchBuf) wchar_t*& szBuf, __inout DWORD& cchBuf) +{ + int in1 = pReq->fields[0].iValue; + szBuf[0] = L'\0'; + DWORD cchValue = cchBuf; + UINT ret = (UINT) func(in1, szBuf, &cchValue); + if (ret == ERROR_MORE_DATA) + { + ret = EnsureBufSize(&szBuf, &cchBuf, ++cchValue); + if (ret == 0) + { + ret = (UINT) func(in1, szBuf, &cchValue); + } + } + if (ret == 0) + { + pResp->fields[1].vt = VT_LPWSTR; + pResp->fields[1].szValue = szBuf; + } + return ret; +} + +MSIDBERROR MsiEFunc_I_S(PMsiEFunc_I_S func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp, __deref_inout_ecount(cchBuf) wchar_t*& szBuf, __inout DWORD& cchBuf) +{ + int in1 = pReq->fields[0].iValue; + szBuf[0] = L'\0'; + DWORD cchValue = cchBuf; + MSIDBERROR ret = func(in1, szBuf, &cchValue); + if (ret == MSIDBERROR_MOREDATA) + { + if (0 == EnsureBufSize(&szBuf, &cchBuf, ++cchValue)) + { + ret = func(in1, szBuf, &cchValue); + } + } + if (ret != MSIDBERROR_MOREDATA) + { + pResp->fields[1].vt = VT_LPWSTR; + pResp->fields[1].szValue = szBuf; + } + return ret; +} + +UINT MsiFunc_II_S(PMsiFunc_II_S func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp, __deref_inout_ecount(cchBuf) wchar_t*& szBuf, __inout DWORD& cchBuf) +{ + int in1 = pReq->fields[0].iValue; + int in2 = pReq->fields[1].iValue; + szBuf[0] = L'\0'; + DWORD cchValue = cchBuf; + UINT ret = (UINT) func(in1, in2, szBuf, &cchValue); + if (ret == ERROR_MORE_DATA) + { + ret = EnsureBufSize(&szBuf, &cchBuf, ++cchValue); + if (ret == 0) + { + ret = (UINT) func(in1, in2, szBuf, &cchValue); + } + } + if (ret == 0) + { + pResp->fields[1].vt = VT_LPWSTR; + pResp->fields[1].szValue = szBuf; + } + return ret; +} + +UINT MsiFunc_IS_S(PMsiFunc_IS_S func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp, __deref_inout_ecount(cchBuf) wchar_t*& szBuf, __inout DWORD& cchBuf) +{ + int in1 = pReq->fields[0].iValue; + wchar_t* in2 = pReq->fields[1].szValue; + szBuf[0] = L'\0'; + DWORD cchValue = cchBuf; + UINT ret = (UINT) func(in1, in2, szBuf, &cchValue); + if (ret == ERROR_MORE_DATA) + { + ret = EnsureBufSize(&szBuf, &cchBuf, ++cchValue); + if (ret == 0) + { + ret = (UINT) func(in1, in2, szBuf, &cchValue); + } + } + if (ret == 0) + { + pResp->fields[1].vt = VT_LPWSTR; + pResp->fields[1].szValue = szBuf; + } + return ret; +} + +UINT MsiFunc_ISII_SII(PMsiFunc_ISII_SII func, const RemoteMsiSession::RequestData* pReq, RemoteMsiSession::RequestData* pResp, __deref_inout_ecount(cchBuf) wchar_t*& szBuf, __inout DWORD& cchBuf) +{ + int in1 = pReq->fields[0].iValue; + wchar_t* in2 = pReq->fields[1].szValue; + int in3 = pReq->fields[2].iValue; + int in4 = pReq->fields[3].iValue; + szBuf[0] = L'\0'; + DWORD cchValue = cchBuf; + int out2, out3; + UINT ret = (UINT) func(in1, in2, in3, in4, szBuf, &cchValue, &out2, &out3); + if (ret == ERROR_MORE_DATA) + { + ret = EnsureBufSize(&szBuf, &cchBuf, ++cchValue); + if (ret == 0) + { + ret = (UINT) func(in1, in2, in3, in4, szBuf, &cchValue, &out2, &out3); + } + } + if (ret == 0) + { + pResp->fields[1].vt = VT_LPWSTR; + pResp->fields[1].szValue = szBuf; + pResp->fields[2].vt = VT_I4; + pResp->fields[2].iValue = out2; + pResp->fields[3].vt = VT_I4; + pResp->fields[3].iValue = out3; + } + return ret; +} + +void RemoteMsiSession::ProcessRequest(RequestId id, const RequestData* pReq, RequestData* pResp) +{ + SecureZeroMemory(pResp, sizeof(RequestData)); + + UINT ret = EnsureBufSize(&m_pBufSend, &m_cbBufSend, 1024); + + if (0 == ret) + { + switch (id) + { + case RemoteMsiSession::EndSession: + { + this->ExitCode = pReq->fields[0].iValue; + } + break; + case RemoteMsiSession::MsiCloseHandle: + { + MSIHANDLE h = (MSIHANDLE) pReq->fields[0].iValue; + ret = ::MsiCloseHandle(h); + } + break; + case RemoteMsiSession::MsiProcessMessage: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + INSTALLMESSAGE eMessageType = (INSTALLMESSAGE) pReq->fields[1].iValue; + MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[2].iValue; + ret = ::MsiProcessMessage(hInstall, eMessageType, hRecord); + } + break; + case RemoteMsiSession::MsiGetProperty: + { + ret = MsiFunc_IS_S((PMsiFunc_IS_S) ::MsiGetProperty, pReq, pResp, m_pBufSend, m_cbBufSend); + } + break; + case RemoteMsiSession::MsiSetProperty: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + const wchar_t* szName = pReq->fields[1].szValue; + const wchar_t* szValue = pReq->fields[2].szValue; + ret = ::MsiSetProperty(hInstall, szName, szValue); + } + break; + case RemoteMsiSession::MsiCreateRecord: + { + UINT cParams = pReq->fields[0].uiValue; + ret = ::MsiCreateRecord(cParams); + } + break; + case RemoteMsiSession::MsiRecordGetFieldCount: + { + MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; + ret = ::MsiRecordGetFieldCount(hRecord); + } + break; + case RemoteMsiSession::MsiRecordGetInteger: + { + MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; + UINT iField = pReq->fields[1].uiValue; + ret = ::MsiRecordGetInteger(hRecord, iField); + } + break; + case RemoteMsiSession::MsiRecordSetInteger: + { + MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; + UINT iField = pReq->fields[1].uiValue; + int iValue = pReq->fields[2].iValue; + ret = ::MsiRecordSetInteger(hRecord, iField, iValue); + } + break; + case RemoteMsiSession::MsiRecordGetString: + { + ret = MsiFunc_II_S((PMsiFunc_II_S) ::MsiRecordGetString, pReq, pResp, m_pBufSend, m_cbBufSend); + } + break; + case RemoteMsiSession::MsiRecordSetString: + { + MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; + UINT iField = pReq->fields[1].uiValue; + const wchar_t* szValue = pReq->fields[2].szValue; + ret = ::MsiRecordSetString(hRecord, iField, szValue); + } + break; + case RemoteMsiSession::MsiRecordClearData: + { + MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; + ret = ::MsiRecordClearData(hRecord); + } + break; + case RemoteMsiSession::MsiRecordIsNull: + { + MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; + UINT iField = pReq->fields[1].uiValue; + ret = ::MsiRecordIsNull(hRecord, iField); + } + break; + case RemoteMsiSession::MsiFormatRecord: + { + ret = MsiFunc_II_S((PMsiFunc_II_S) ::MsiFormatRecord, pReq, pResp, m_pBufSend, m_cbBufSend); + } + break; + case RemoteMsiSession::MsiGetActiveDatabase: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + ret = (UINT) ::MsiGetActiveDatabase(hInstall); + } + break; + case RemoteMsiSession::MsiDatabaseOpenView: + { + ret = MsiFunc_IS_I((PMsiFunc_IS_I) ::MsiDatabaseOpenView, pReq, pResp); + } + break; + case RemoteMsiSession::MsiViewExecute: + { + MSIHANDLE hView = (MSIHANDLE) pReq->fields[0].iValue; + MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[1].iValue; + ret = ::MsiViewExecute(hView, hRecord); + } + break; + case RemoteMsiSession::MsiViewFetch: + { + ret = MsiFunc_I_I((PMsiFunc_I_I) ::MsiViewFetch, pReq, pResp); + } + break; + case RemoteMsiSession::MsiViewModify: + { + MSIHANDLE hView = (MSIHANDLE) pReq->fields[0].iValue; + MSIMODIFY eModifyMode = (MSIMODIFY) pReq->fields[1].iValue; + MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[2].iValue; + ret = ::MsiViewModify(hView, eModifyMode, hRecord); + } + break; + case RemoteMsiSession::MsiViewGetError: + { + ret = MsiEFunc_I_S((PMsiEFunc_I_S) ::MsiViewGetError, pReq, pResp, m_pBufSend, m_cbBufSend); + } + break; + case RemoteMsiSession::MsiViewGetColumnInfo: + { + ret = MsiFunc_II_I((PMsiFunc_II_I) ::MsiViewGetColumnInfo, pReq, pResp); + } + break; + case RemoteMsiSession::MsiDatabaseGetPrimaryKeys: + { + ret = MsiFunc_IS_I((PMsiFunc_IS_I) ::MsiDatabaseGetPrimaryKeys, pReq, pResp); + } + break; + case RemoteMsiSession::MsiDatabaseIsTablePersistent: + { + MSIHANDLE hDb = (MSIHANDLE) pReq->fields[0].iValue; + const wchar_t* szTable = pReq->fields[1].szValue; + ret = ::MsiDatabaseIsTablePersistent(hDb, szTable); + } + break; + case RemoteMsiSession::MsiDoAction: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + const wchar_t* szAction = pReq->fields[1].szValue; + ret = ::MsiDoAction(hInstall, szAction); + } + break; + case RemoteMsiSession::MsiEnumComponentCosts: + { + ret = MsiFunc_ISII_SII((PMsiFunc_ISII_SII) ::MsiEnumComponentCosts, pReq, pResp, m_pBufSend, m_cbBufSend); + } + break; + case RemoteMsiSession::MsiEvaluateCondition: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + const wchar_t* szCondition = pReq->fields[1].szValue; + ret = ::MsiEvaluateCondition(hInstall, szCondition); + } + break; + case RemoteMsiSession::MsiGetComponentState: + { + ret = MsiFunc_IS_II((PMsiFunc_IS_II) ::MsiGetComponentState, pReq, pResp); + } + break; + case RemoteMsiSession::MsiGetFeatureCost: + { + ret = MsiFunc_ISII_I((PMsiFunc_ISII_I) ::MsiGetFeatureCost, pReq, pResp); + } + break; + case RemoteMsiSession::MsiGetFeatureState: + { + ret = MsiFunc_IS_II((PMsiFunc_IS_II) ::MsiGetFeatureState, pReq, pResp); + } + break; + case RemoteMsiSession::MsiGetFeatureValidStates: + { + ret = MsiFunc_IS_I((PMsiFunc_IS_I) ::MsiGetFeatureValidStates, pReq, pResp); + } + break; + case RemoteMsiSession::MsiGetLanguage: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + ret = ::MsiGetLanguage(hInstall); + } + break; + case RemoteMsiSession::MsiGetLastErrorRecord: + { + ret = ::MsiGetLastErrorRecord(); + } + break; + case RemoteMsiSession::MsiGetMode: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + MSIRUNMODE iRunMode = (MSIRUNMODE) pReq->fields[1].iValue; + ret = ::MsiGetMode(hInstall, iRunMode); + } + break; + case RemoteMsiSession::MsiGetSourcePath: + { + ret = MsiFunc_IS_S((PMsiFunc_IS_S) ::MsiGetSourcePath, pReq, pResp, m_pBufSend, m_cbBufSend); + } + break; + case RemoteMsiSession::MsiGetSummaryInformation: + { + ret = MsiFunc_ISI_I((PMsiFunc_ISI_I) ::MsiGetSummaryInformation, pReq, pResp); + } + break; + case RemoteMsiSession::MsiGetTargetPath: + { + ret = MsiFunc_IS_S((PMsiFunc_IS_S) ::MsiGetTargetPath, pReq, pResp, m_pBufSend, m_cbBufSend); + } + break; + case RemoteMsiSession::MsiRecordDataSize: + { + MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; + UINT iField = pReq->fields[1].uiValue; + ret = ::MsiRecordDataSize(hRecord, iField); + } + break; + case RemoteMsiSession::MsiRecordReadStream: + { + MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; + UINT iField = pReq->fields[1].uiValue; + DWORD cbRead = (DWORD) pReq->fields[2].uiValue; + ret = EnsureBufSize(&m_pBufSend, &m_cbBufSend, (cbRead + 1) / 2); + if (ret == 0) + { + ret = ::MsiRecordReadStream(hRecord, iField, (char*) m_pBufSend, &cbRead); + if (ret == 0) + { + pResp->fields[1].vt = VT_STREAM; + pResp->fields[1].szValue = m_pBufSend; + pResp->fields[2].vt = VT_I4; + pResp->fields[2].uiValue = (UINT) cbRead; + } + } + } + break; + case RemoteMsiSession::MsiRecordSetStream: + { + MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; + UINT iField = pReq->fields[1].uiValue; + const wchar_t* szFilePath = pReq->fields[2].szValue; + ret = ::MsiRecordSetStream(hRecord, iField, szFilePath); + } + break; + case RemoteMsiSession::MsiSequence: + { + MSIHANDLE hRecord = (MSIHANDLE) pReq->fields[0].iValue; + const wchar_t* szTable = pReq->fields[1].szValue; + UINT iSequenceMode = pReq->fields[2].uiValue; + ret = ::MsiSequence(hRecord, szTable, iSequenceMode); + } + break; + case RemoteMsiSession::MsiSetComponentState: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + const wchar_t* szComponent = pReq->fields[1].szValue; + INSTALLSTATE iState = (INSTALLSTATE) pReq->fields[2].iValue; + ret = ::MsiSetComponentState(hInstall, szComponent, iState); + } + break; + case RemoteMsiSession::MsiSetFeatureAttributes: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + const wchar_t* szFeature = pReq->fields[1].szValue; + DWORD dwAttrs = (DWORD) pReq->fields[2].uiValue; + ret = ::MsiSetFeatureAttributes(hInstall, szFeature, dwAttrs); + } + break; + case RemoteMsiSession::MsiSetFeatureState: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + const wchar_t* szFeature = pReq->fields[1].szValue; + INSTALLSTATE iState = (INSTALLSTATE) pReq->fields[2].iValue; + ret = ::MsiSetFeatureState(hInstall, szFeature, iState); + } + break; + case RemoteMsiSession::MsiSetInstallLevel: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + int iInstallLevel = pReq->fields[1].iValue; + ret = ::MsiSetInstallLevel(hInstall, iInstallLevel); + } + break; + case RemoteMsiSession::MsiSetMode: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + MSIRUNMODE iRunMode = (MSIRUNMODE) pReq->fields[1].uiValue; + BOOL fState = (BOOL) pReq->fields[2].iValue; + ret = ::MsiSetMode(hInstall, iRunMode, fState); + } + break; + case RemoteMsiSession::MsiSetTargetPath: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + const wchar_t* szFolder = pReq->fields[1].szValue; + const wchar_t* szFolderPath = pReq->fields[2].szValue; + ret = ::MsiSetTargetPath(hInstall, szFolder, szFolderPath); + } + break; + case RemoteMsiSession::MsiSummaryInfoGetProperty: + { + MSIHANDLE hSummaryInfo = (MSIHANDLE) pReq->fields[0].iValue; + UINT uiProperty = pReq->fields[1].uiValue; + UINT uiDataType; + int iValue; + FILETIME ftValue; + m_pBufSend[0] = L'\0'; + DWORD cchValue = m_cbBufSend; + ret = ::MsiSummaryInfoGetProperty(hSummaryInfo, uiProperty, &uiDataType, &iValue, &ftValue, m_pBufSend, &cchValue); + if (ret == ERROR_MORE_DATA) + { + ret = EnsureBufSize(&m_pBufSend, &m_cbBufSend, ++cchValue); + if (ret == 0) + { + ret = ::MsiSummaryInfoGetProperty(hSummaryInfo, uiProperty, &uiDataType, &iValue, &ftValue, m_pBufSend, &cchValue); + } + } + if (ret == 0) + { + pResp->fields[1].vt = VT_UI4; + pResp->fields[1].uiValue = uiDataType; + + switch (uiDataType) + { + case VT_I2: + case VT_I4: + pResp->fields[2].vt = VT_I4; + pResp->fields[2].iValue = iValue; + break; + case VT_FILETIME: + pResp->fields[2].vt = VT_UI4; + pResp->fields[2].iValue = ftValue.dwHighDateTime; + pResp->fields[3].vt = VT_UI4; + pResp->fields[3].iValue = ftValue.dwLowDateTime; + break; + case VT_LPSTR: + pResp->fields[2].vt = VT_LPWSTR; + pResp->fields[2].szValue = m_pBufSend; + break; + } + } + } + break; + case RemoteMsiSession::MsiVerifyDiskSpace: + { + MSIHANDLE hInstall = (MSIHANDLE) pReq->fields[0].iValue; + ret = ::MsiVerifyDiskSpace(hInstall); + } + break; + + default: + { + ret = ERROR_INVALID_FUNCTION; + } + break; + } + } + + pResp->fields[0].vt = VT_UI4; + pResp->fields[0].uiValue = ret; +} -- cgit v1.2.3-55-g6feb