/******************************************************************** WcaGetRecordFormattedString() - gets formatted string filed from record ********************************************************************/ extern "C" HRESULT WIXAPI WcaGetRecordFormattedString( __in MSIHANDLE hRec, __in UINT uiField, __inout LPWSTR* ppwzData ) { if (!hRec || !ppwzData) { return E_INVALIDARG; } HRESULT hr = S_OK; UINT er; DWORD_PTR cch = 0; PMSIHANDLE hRecFormat; // get the format string hr = WcaGetRecordString(hRec, uiField, ppwzData); ExitOnFailure(hr, "failed to get string from record"); if (!**ppwzData) { ExitFunction(); } // hide the nulls '[~]' so we can get them back after formatting HideNulls(*ppwzData); // set up the format record hRecFormat = ::MsiCreateRecord(1); ExitOnNull(hRecFormat, hr, E_UNEXPECTED, "Failed to create record to format string"); hr = WcaSetRecordString(hRecFormat, 0, *ppwzData); ExitOnFailure(hr, "failed to set string to format record"); // format the string hr = StrMaxLength(*ppwzData, &cch); ExitOnFailure(hr, "failed to get max length of string"); er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecFormat, *ppwzData, (DWORD*)&cch); if (ERROR_MORE_DATA == er) { hr = StrAlloc(ppwzData, ++cch); ExitOnFailure(hr, "Failed to allocate memory for record string"); er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecFormat, *ppwzData, (DWORD*)&cch); } ExitOnWin32Error(er, hr, "Failed to format string"); // put the nulls back RevealNulls(*ppwzData); LExit: return hr; }
/******************************************************************** WcaGetFormattedString - gets a formatted string value from the active install ********************************************************************/ extern "C" HRESULT WIXAPI WcaGetFormattedString( __in_z LPCWSTR wzString, __out LPWSTR* ppwzData ) { if (!wzString || !*wzString || !ppwzData) { return E_INVALIDARG; } HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hRecord = ::MsiCreateRecord(1); DWORD_PTR cch = 0; er = ::MsiRecordSetStringW(hRecord, 0, wzString); ExitOnWin32Error1(er, hr, "Failed to set record field 0 with '%ls'", wzString); if (!*ppwzData) { WCHAR szEmpty[1] = L""; er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecord, szEmpty, (DWORD *)&cch); if (ERROR_MORE_DATA == er || ERROR_SUCCESS == er) { hr = StrAlloc(ppwzData, ++cch); } else { hr = HRESULT_FROM_WIN32(er); } ExitOnFailure1(hr, "Failed to allocate string for formatted string: '%ls'", wzString); } else { hr = StrMaxLength(*ppwzData, &cch); ExitOnFailure(hr, "Failed to get previous size of property data string"); } er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecord, *ppwzData, (DWORD *)&cch); if (ERROR_MORE_DATA == er) { hr = StrAlloc(ppwzData, ++cch); ExitOnFailure1(hr, "Failed to allocate string for formatted string: '%ls'", wzString); er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecord, *ppwzData, (DWORD *)&cch); } ExitOnWin32Error1(er, hr, "Failed to get formatted string: '%ls'", wzString); LExit: return hr; }
/******************************************************************** WcaGetProperty - gets a string property value from the active install ********************************************************************/ extern "C" HRESULT WIXAPI WcaGetProperty( __in_z LPCWSTR wzProperty, __inout LPWSTR* ppwzData ) { if (!wzProperty || !*wzProperty || !ppwzData) { return E_INVALIDARG; } HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; DWORD_PTR cch = 0; if (!*ppwzData) { WCHAR szEmpty[1] = L""; er = ::MsiGetPropertyW(WcaGetInstallHandle(), wzProperty, szEmpty, (DWORD *)&cch); if (ERROR_MORE_DATA == er || ERROR_SUCCESS == er) { hr = StrAlloc(ppwzData, ++cch); } else { hr = HRESULT_FROM_WIN32(er); } ExitOnFailure1(hr, "Failed to allocate string for Property '%ls'", wzProperty); } else { hr = StrMaxLength(*ppwzData, &cch); ExitOnFailure(hr, "Failed to get previous size of property data string."); } er = ::MsiGetPropertyW(WcaGetInstallHandle(), wzProperty, *ppwzData, (DWORD *)&cch); if (ERROR_MORE_DATA == er) { Assert(*ppwzData); hr = StrAlloc(ppwzData, ++cch); ExitOnFailure1(hr, "Failed to allocate string for Property '%ls'", wzProperty); er = ::MsiGetPropertyW(WcaGetInstallHandle(), wzProperty, *ppwzData, (DWORD *)&cch); } ExitOnWin32Error1(er, hr, "Failed to get data for property '%ls'", wzProperty); LExit: return hr; }
/******************************************************************** WcaGetTargetPath - gets the target path for a specified folder ********************************************************************/ extern "C" HRESULT WIXAPI WcaGetTargetPath( __in_z LPCWSTR wzFolder, __out LPWSTR* ppwzData ) { if (!wzFolder || !*wzFolder || !ppwzData) return E_INVALIDARG; HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; DWORD_PTR cch = 0; if (!*ppwzData) { WCHAR szEmpty[1] = L""; er = ::MsiGetTargetPathW(WcaGetInstallHandle(), wzFolder, szEmpty, (DWORD*)&cch); if (ERROR_MORE_DATA == er || ERROR_SUCCESS == er) { ++cch; //Add one for the null terminator hr = StrAlloc(ppwzData, cch); } else { hr = HRESULT_FROM_WIN32(er); } ExitOnFailure1(hr, "Failed to allocate string for target path of folder: '%ls'", wzFolder); } else { hr = StrMaxLength(*ppwzData, &cch); ExitOnFailure(hr, "Failed to get previous size of string"); } er = ::MsiGetTargetPathW(WcaGetInstallHandle(), wzFolder, *ppwzData, (DWORD*)&cch); if (ERROR_MORE_DATA == er) { ++cch; hr = StrAlloc(ppwzData, cch); ExitOnFailure1(hr, "Failed to allocate string for target path of folder: '%ls'", wzFolder); er = ::MsiGetTargetPathW(WcaGetInstallHandle(), wzFolder, *ppwzData, (DWORD*)&cch); } ExitOnWin32Error1(er, hr, "Failed to get target path for folder '%ls'", wzFolder); LExit: return hr; }
/******************************************************************** WcaGetComponentToDo() - gets a component's install states and determines if they mean install, uninstall, or reinstall. ********************************************************************/ extern "C" WCA_TODO WIXAPI WcaGetComponentToDo( __in_z LPCWSTR wzComponentId ) { INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; if (ERROR_SUCCESS != ::MsiGetComponentStateW(WcaGetInstallHandle(), wzComponentId, &isInstalled, &isAction)) { return WCA_TODO_UNKNOWN; } if (WcaIsReInstalling(isInstalled, isAction)) { return WCA_TODO_REINSTALL; } else if (WcaIsUninstalling(isInstalled, isAction)) { return WCA_TODO_UNINSTALL; } else if (WcaIsInstalling(isInstalled, isAction)) { return WCA_TODO_INSTALL; } else { return WCA_TODO_UNKNOWN; } }
HRESULT BuildCommandLine( __in LPCWSTR wzProperty, __out LPWSTR *ppwzCommand ) { Assert(ppwzCommand); HRESULT hr = S_OK; BOOL fScheduled = ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_SCHEDULED); BOOL fRollback = ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK); BOOL fCommit = ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_COMMIT); if (fScheduled || fRollback || fCommit) { if (WcaIsPropertySet("CustomActionData")) { hr = WcaGetProperty( L"CustomActionData", ppwzCommand); ExitOnFailure(hr, "Failed to get CustomActionData"); } } else if (WcaIsUnicodePropertySet(wzProperty)) { hr = WcaGetFormattedProperty(wzProperty, ppwzCommand); ExitOnFailure(hr, "Failed to get %ls", wzProperty); hr = WcaSetProperty(wzProperty, L""); // clear out the property now that we've read it ExitOnFailure(hr, "Failed to set %ls", wzProperty); } if (!*ppwzCommand) { ExitOnFailure(hr = E_INVALIDARG, "Failed to get command line data"); } if (L'"' != **ppwzCommand) { WcaLog(LOGMSG_STANDARD, "Command string must begin with quoted application name."); ExitOnFailure(hr = E_INVALIDARG, "invalid command line property value"); } LExit: return hr; }
/******************************************************************** WcaProcessMessage() - sends a message from the CustomAction ********************************************************************/ extern "C" UINT WIXAPI WcaProcessMessage( __in INSTALLMESSAGE eMessageType, __in MSIHANDLE hRecord ) { UINT er = ::MsiProcessMessage(WcaGetInstallHandle(), eMessageType, hRecord); if (ERROR_INSTALL_USEREXIT == er || IDCANCEL == er) { WcaSetReturnValue(ERROR_INSTALL_USEREXIT); } return er; }
/******************************************************************** WcaSetComponentState() - sets the install state of a Component ********************************************************************/ extern "C" HRESULT WIXAPI WcaSetComponentState( __in_z LPCWSTR wzComponent, __in INSTALLSTATE isState ) { UINT er = ::MsiSetComponentStateW(WcaGetInstallHandle(), wzComponent, isState); if (ERROR_INSTALL_USEREXIT == er) { WcaSetReturnValue(er); } return HRESULT_FROM_WIN32(er); }
/******************************************************************** WcaIsUnicodePropertySet() - returns TRUE if property is set ********************************************************************/ extern "C" BOOL WIXAPI WcaIsUnicodePropertySet( __in LPCWSTR wzProperty ) { DWORD cchProperty = 0; wchar_t wzEmpty[1] = L""; #ifdef DEBUG UINT er = #endif ::MsiGetPropertyW(WcaGetInstallHandle(), wzProperty, wzEmpty, &cchProperty); AssertSz(ERROR_INVALID_PARAMETER != er && ERROR_INVALID_HANDLE != er, "Unexpected return value from ::MsiGetProperty()"); return 0 < cchProperty; // property is set if the length is greater than zero }
/******************************************************************** WcaSetProperty - sets a string property value in the active install ********************************************************************/ extern "C" HRESULT WIXAPI WcaSetProperty( __in_z LPCWSTR wzPropertyName, __in_z LPCWSTR wzPropertyValue ) { HRESULT hr = S_OK; if (!wzPropertyName || !*wzPropertyName || !wzPropertyValue) return E_INVALIDARG; UINT er = ::MsiSetPropertyW(WcaGetInstallHandle(), wzPropertyName, wzPropertyValue); ExitOnWin32Error1(er, hr, "failed to set property: %ls", wzPropertyName); LExit: return hr; }
/******************************************************************** WcaSetIntProperty - sets a integer property value in the active install ********************************************************************/ extern "C" HRESULT WIXAPI WcaSetIntProperty( __in_z LPCWSTR wzPropertyName, __in int nPropertyValue ) { if (!wzPropertyName || !*wzPropertyName) return E_INVALIDARG; // 12 characters should be enough for a 32-bit int: 10 digits, 1 sign, 1 null WCHAR wzPropertyValue[13]; HRESULT hr = StringCchPrintfW(wzPropertyValue, countof(wzPropertyValue), L"%d", nPropertyValue); ExitOnFailure1(hr, "failed to convert into string property value: %d", nPropertyValue); UINT er = ::MsiSetPropertyW(WcaGetInstallHandle(), wzPropertyName, wzPropertyValue); ExitOnWin32Error1(er, hr, "failed to set property: %ls", wzPropertyName); LExit: return hr; }
/******************************************************************** WcaGetIntProperty - gets an integer property value from the active install ********************************************************************/ extern "C" HRESULT WIXAPI WcaGetIntProperty( __in_z LPCWSTR wzProperty, __inout int* piData ) { if (!piData) return E_INVALIDARG; HRESULT hr = S_OK; UINT er; WCHAR wzValue[32]; DWORD cch = countof(wzValue) - 1; er = ::MsiGetPropertyW(WcaGetInstallHandle(), wzProperty, wzValue, &cch); ExitOnWin32Error1(er, hr, "Failed to get data for property '%ls'", wzProperty); *piData = wcstol(wzValue, NULL, 10); LExit: return hr; }
UINT __stdcall ScaFiltersRead(IMSAdminBase* piMetabase, SCA_WEB* pswList, SCA_FILTER** ppsfList) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hView, hRec; PMSIHANDLE hViewWeb, hRecWeb; BOOL fIIsWebFilterTable = FALSE; LPWSTR pwzData = NULL; SCA_FILTER* psf = NULL; DWORD dwLen = 0; // check for required table if (S_OK != WcaTableExists(L"IIsFilter")) { WcaLog(LOGMSG_VERBOSE, "Skipping ScaInstallFilters() - no IIsFilter table"); ExitFunction1(hr = S_FALSE); } // loop through all the filters hr = WcaOpenExecuteView(vcsFilterQuery, &hView); ExitOnFailure(hr, "Failed to open view on IIsFilter table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { hr = AddFilterToList(ppsfList); ExitOnFailure(hr, "failed to add filter to list"); psf = *ppsfList; // get component install state hr = WcaGetRecordString(hRec, fqComponent, &pwzData); ExitOnFailure(hr, "Failed to get Filter.Component_"); er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &psf->isInstalled, &psf->isAction); hr = HRESULT_FROM_WIN32(er); ExitOnFailure(hr, "Failed to get Component state for filter"); ::ZeroMemory(psf->wzFilterRoot, sizeof(psf->wzFilterRoot)); hr = WcaGetRecordString(hRec, fqWeb, &pwzData); ExitOnFailure(hr, "Failed to get Web for VirtualDir"); if (*pwzData) { dwLen = countof(psf->wzWebBase); hr = ScaWebsGetBase(piMetabase, pswList, pwzData, psf->wzWebBase, &dwLen); ExitOnFailure(hr, "Failed to get base of web for Filter"); StringCchPrintfW(psf->wzFilterRoot, countof(psf->wzFilterRoot), L"%s/Filters", psf->wzWebBase); } else { StringCchCopyW(psf->wzFilterRoot, countof(psf->wzFilterRoot), L"/LM/W3SVC/Filters"); } // filter key hr = WcaGetRecordString(hRec, fqFilter, &pwzData); ExitOnFailure(hr, "Failed to get Filter.Filter"); StringCchCopyW(psf->wzKey, countof(psf->wzKey), pwzData); // filter path hr = WcaGetRecordFormattedString(hRec, fqPath, &pwzData); ExitOnFailure(hr, "Failed to get Filter.Path"); StringCchCopyW(psf->wzPath, countof(psf->wzPath), pwzData); // filter description hr = WcaGetRecordFormattedString(hRec, fqDescription, &pwzData); ExitOnFailure(hr, "Failed to get Filter.Description"); StringCchCopyW(psf->wzDescription, countof(psf->wzDescription), pwzData); // filter flags hr = WcaGetRecordInteger(hRec, fqFlags, &psf->iFlags); ExitOnFailure(hr, "Failed to get Filter.Flags"); // filter load order hr = WcaGetRecordInteger(hRec, fqLoadOrder, &psf->iLoadOrder); ExitOnFailure(hr, "Failed to get Filter.LoadOrder"); } if (E_NOMOREITEMS == hr) hr = S_OK; ExitOnFailure(hr, "Failure while processing filters"); LExit: ReleaseStr(pwzData); return hr; }
HRESULT CpiApplicationRolesRead( CPI_APPLICATION_LIST* pAppList, CPI_APPLICATION_ROLE_LIST* pAppRoleList ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hView, hRec; CPI_APPLICATION_ROLE* pItm = NULL; LPWSTR pwzData = NULL; BOOL fMatchingArchitecture = FALSE; // loop through all application roles hr = WcaOpenExecuteView(vcsApplicationRoleQuery, &hView); ExitOnFailure(hr, "Failed to execute view on ComPlusApplicationRole table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { // get component hr = WcaGetRecordString(hRec, arqComponent, &pwzData); ExitOnFailure(hr, "Failed to get component"); // check if the component is our processor architecture if (pwzData && *pwzData) { hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture); ExitOnFailure(hr, "Failed to get component architecture."); if (!fMatchingArchitecture) { continue; // not the same architecture, ignore } } // create entry pItm = (CPI_APPLICATION_ROLE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_APPLICATION_ROLE)); if (!pItm) ExitFunction1(hr = E_OUTOFMEMORY); // get component install state if (pwzData && *pwzData) { pItm->fHasComponent = TRUE; er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state"); } // get key hr = WcaGetRecordString(hRec, arqApplicationRole, &pwzData); ExitOnFailure(hr, "Failed to get key"); StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData); // get application hr = WcaGetRecordString(hRec, arqApplication, &pwzData); ExitOnFailure(hr, "Failed to get application"); hr = CpiApplicationFindByKey(pAppList, pwzData, &pItm->pApplication); if (S_FALSE == hr) hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); ExitOnFailure1(hr, "Failed to find application, key: %S", pwzData); // get name hr = WcaGetRecordFormattedString(hRec, arqName, &pwzData); ExitOnFailure(hr, "Failed to get name"); StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData); // get properties if (CpiTableExists(cptComPlusApplicationRoleProperty)) { hr = CpiPropertiesRead(vcsApplicationRolePropertyQuery, pItm->wzKey, pdlApplicationRoleProperties, &pItm->pProperties, &pItm->iPropertyCount); ExitOnFailure(hr, "Failed to get properties"); } // set references & increment counters if (pItm->fHasComponent) { if (WcaIsInstalling(pItm->isInstalled, pItm->isAction)) { CpiApplicationAddReferenceInstall(pItm->pApplication); pAppRoleList->iInstallCount++; } if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) { CpiApplicationAddReferenceUninstall(pItm->pApplication); pAppRoleList->iUninstallCount++; } } // add entry if (pAppRoleList->pFirst) pItm->pNext = pAppRoleList->pFirst; pAppRoleList->pFirst = pItm; pItm = NULL; } if (E_NOMOREITEMS == hr) hr = S_OK; LExit: // clean up if (pItm) FreeApplicationRole(pItm); ReleaseStr(pwzData); return hr; }
static HRESULT TrusteesInApplicationRolesRead( LPCWSTR pwzQuery, CPI_APPLICATION_ROLE_LIST* pAppRoleList, CPI_USER_IN_APPLICATION_ROLE_LIST* pUsrInAppRoleList ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hView, hRec; CPI_USER_IN_APPLICATION_ROLE* pItm = NULL; LPWSTR pwzData = NULL; LPWSTR pwzDomain = NULL; LPWSTR pwzName = NULL; BOOL fMatchingArchitecture = FALSE; // loop through all application roles hr = WcaOpenExecuteView(pwzQuery, &hView); ExitOnFailure(hr, "Failed to execute view on table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { // get component hr = WcaGetRecordString(hRec, tiarqComponent, &pwzData); ExitOnFailure(hr, "Failed to get component"); // check if the component is our processor architecture hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture); ExitOnFailure(hr, "Failed to get component architecture."); if (!fMatchingArchitecture) { continue; // not the same architecture, ignore } // create entry pItm = (CPI_USER_IN_APPLICATION_ROLE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_USER_IN_APPLICATION_ROLE)); if (!pItm) ExitFunction1(hr = E_OUTOFMEMORY); // get component install state er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state"); // get key hr = WcaGetRecordString(hRec, tiarqUserInApplicationRole, &pwzData); ExitOnFailure(hr, "Failed to get key"); StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData); // get application role hr = WcaGetRecordString(hRec, tiarqApplicationRole, &pwzData); ExitOnFailure(hr, "Failed to get application role"); hr = CpiApplicationRoleFindByKey(pAppRoleList, pwzData, &pItm->pApplicationRole); if (S_FALSE == hr) hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); ExitOnFailure1(hr, "Failed to find application role, key: %S", pwzData); // get user domain hr = WcaGetRecordFormattedString(hRec, tiarqDomain, &pwzDomain); ExitOnFailure(hr, "Failed to get domain"); // get user name hr = WcaGetRecordFormattedString(hRec, tiarqName, &pwzName); ExitOnFailure(hr, "Failed to get name"); // build account name hr = CpiBuildAccountName(pwzDomain, pwzName, &pItm->pwzAccount); ExitOnFailure(hr, "Failed to build account name"); // set references & increment counters if (WcaIsInstalling(pItm->isInstalled, pItm->isAction)) { CpiApplicationRoleAddReferenceInstall(pItm->pApplicationRole); pUsrInAppRoleList->iInstallCount++; } if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) { CpiApplicationRoleAddReferenceUninstall(pItm->pApplicationRole); pUsrInAppRoleList->iUninstallCount++; } // add entry if (pUsrInAppRoleList->pFirst) pItm->pNext = pUsrInAppRoleList->pFirst; pUsrInAppRoleList->pFirst = pItm; pItm = NULL; } if (E_NOMOREITEMS == hr) hr = S_OK; LExit: // clean up if (pItm) FreeUserInApplicationRole(pItm); ReleaseStr(pwzData); ReleaseStr(pwzDomain); ReleaseStr(pwzName); return hr; }
HRESULT MqiMessageQueueRead( MQI_MESSAGE_QUEUE_LIST* pList ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hView, hRec; MQI_MESSAGE_QUEUE* pItm = NULL; LPWSTR pwzData = NULL; // loop through all partitions hr = WcaOpenExecuteView(vcsMessageQueueQuery, &hView); ExitOnFailure(hr, "Failed to execute view on MessageQueue table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { // create entry pItm = (MQI_MESSAGE_QUEUE*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MQI_MESSAGE_QUEUE)); if (!pItm) ExitFunction1(hr = E_OUTOFMEMORY); // get key hr = WcaGetRecordString(hRec, mqqMessageQueue, &pwzData); ExitOnFailure(hr, "Failed to get key"); StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData); // get component install state hr = WcaGetRecordString(hRec, mqqComponent, &pwzData); ExitOnFailure(hr, "Failed to get component"); // get component install state er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state"); // get base priority hr = WcaGetRecordInteger(hRec, mqqBasePriority, &pItm->iBasePriority); ExitOnFailure(hr, "Failed to get base priority"); // get journal quota hr = WcaGetRecordInteger(hRec, mqqJournalQuota, &pItm->iJournalQuota); ExitOnFailure(hr, "Failed to get journal quota"); // get label hr = WcaGetRecordFormattedString(hRec, mqqLabel, &pwzData); ExitOnFailure(hr, "Failed to get label"); StringCchCopyW(pItm->wzLabel, countof(pItm->wzLabel), pwzData); // get multicast address hr = WcaGetRecordFormattedString(hRec, mqqMulticastAddress, &pwzData); ExitOnFailure(hr, "Failed to get multicast address"); StringCchCopyW(pItm->wzMulticastAddress, countof(pItm->wzMulticastAddress), pwzData); // get path name hr = WcaGetRecordFormattedString(hRec, mqqPathName, &pwzData); ExitOnFailure(hr, "Failed to get path name"); StringCchCopyW(pItm->wzPathName, countof(pItm->wzPathName), pwzData); // get privacy level hr = WcaGetRecordInteger(hRec, mqqPrivLevel, &pItm->iPrivLevel); ExitOnFailure(hr, "Failed to get privacy level"); // get quota hr = WcaGetRecordInteger(hRec, mqqQuota, &pItm->iQuota); ExitOnFailure(hr, "Failed to get quota"); // get service type guid hr = WcaGetRecordFormattedString(hRec, mqqServiceTypeGuid, &pwzData); ExitOnFailure(hr, "Failed to get service type guid"); StringCchCopyW(pItm->wzServiceTypeGuid, countof(pItm->wzServiceTypeGuid), pwzData); // get attributes hr = WcaGetRecordInteger(hRec, mqqAttributes, &pItm->iAttributes); ExitOnFailure(hr, "Failed to get attributes"); // increment counters if (WcaIsInstalling(pItm->isInstalled, pItm->isAction)) pList->iInstallCount++; if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) pList->iUninstallCount++; // add entry pItm->pNext = pList->pFirst; pList->pFirst = pItm; pItm = NULL; } if (E_NOMOREITEMS == hr) hr = S_OK; LExit: // clean up if (pItm) ::HeapFree(::GetProcessHeap(), 0, pItm); ReleaseStr(pwzData); return hr; }
HRESULT CpiPartitionsRead( CPI_PARTITION_LIST* pPartList ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hView, hRec; CPI_PARTITION* pItm = NULL; LPWSTR pwzData = NULL; BOOL fMatchingArchitecture = FALSE; // loop through all partitions hr = WcaOpenExecuteView(vcsPartitionQuery, &hView); ExitOnFailure(hr, "Failed to execute view on ComPlusPartition table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { // get component hr = WcaGetRecordString(hRec, pqComponent, &pwzData); ExitOnFailure(hr, "Failed to get component"); // check if the component is our processor architecture if (pwzData && *pwzData) { hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture); ExitOnFailure(hr, "Failed to get component architecture."); if (!fMatchingArchitecture) { continue; // not the same architecture, ignore } } // create entry pItm = (CPI_PARTITION*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_PARTITION)); if (!pItm) ExitFunction1(hr = E_OUTOFMEMORY); // get component install state if (pwzData && *pwzData) { pItm->fHasComponent = TRUE; er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state"); } // get key hr = WcaGetRecordString(hRec, pqPartition, &pwzData); ExitOnFailure(hr, "Failed to get key"); StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData); // get id hr = WcaGetRecordFormattedString(hRec, pqID, &pwzData); ExitOnFailure(hr, "Failed to get id"); if (pwzData && *pwzData) { hr = PcaGuidToRegFormat(pwzData, pItm->wzID, countof(pItm->wzID)); ExitOnFailure(hr, "Failed to parse id guid value, key: %S, value: '%S'", pItm->wzKey, pwzData); } // get name hr = WcaGetRecordFormattedString(hRec, pqName, &pwzData); ExitOnFailure(hr, "Failed to get name"); StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData); // if partition is a locater, either an id or a name must be provided if (!pItm->fHasComponent && !*pItm->wzID && !*pItm->wzName) ExitOnFailure(hr = E_FAIL, "A partition locater must have either an id or a name associated, key: %S", pItm->wzKey); // if partition is not a locater, an name must be provided if (pItm->fHasComponent && !*pItm->wzName) ExitOnFailure(hr = E_FAIL, "A partition must have a name associated, key: %S", pItm->wzKey); // get properties if (CpiTableExists(cptComPlusPartitionProperty) && pItm->fHasComponent) { hr = CpiPropertiesRead(vcsPartitionPropertyQuery, pItm->wzKey, pdlPartitionProperties, &pItm->pProperties, &pItm->iPropertyCount); ExitOnFailure(hr, "Failed to get properties"); } // increment counters if (pItm->fHasComponent && WcaIsInstalling(pItm->isInstalled, pItm->isAction)) pPartList->iInstallCount++; if (pItm->fHasComponent && WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) pPartList->iUninstallCount++; // add entry if (pPartList->pFirst) pItm->pNext = pPartList->pFirst; pPartList->pFirst = pItm; pItm = NULL; } if (E_NOMOREITEMS == hr) hr = S_OK; LExit: // clean up if (pItm) FreePartition(pItm); ReleaseStr(pwzData); return hr; }
static HRESULT RemoveUsersInApplicationRole( CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; ICatalogCollection* piUsrInRoleColl = NULL; PSID pSid = NULL; long lChanges = 0; // log WcaLog(LOGMSG_VERBOSE, "Removing user from application role, key: %S", pAttrs->pwzKey); // get users in role collection hr = CpiGetUsersInRoleCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pwzRoleName, &piUsrInRoleColl); ExitOnFailure(hr, "Failed to get users in role collection"); if (S_FALSE == hr) { // users in role collection not found WcaLog(LOGMSG_VERBOSE, "Unable to retrieve users in role collection, nothing to delete, key: %S", pAttrs->pwzKey); ExitFunction1(hr = S_OK); } // get SID for account do { er = ERROR_SUCCESS; hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid); if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK)) { WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount); er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); switch (er) { case IDABORT: ExitFunction(); // exit with error code from CpiAccountNameToSid() case IDRETRY: break; case IDIGNORE: default: ExitFunction1(hr = S_OK); } } else ExitOnFailure(hr, "Failed to get SID for account"); } while (IDRETRY == er); // remove hr = CpiRemoveUserCollectionObject(piUsrInRoleColl, pSid); if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr) { WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr); hr = S_FALSE; } else ExitOnFailure(hr, "Failed to remove user"); if (S_FALSE == hr) { // role not found WcaLog(LOGMSG_VERBOSE, "User not found for application role, nothing to delete, key: %S", pAttrs->pwzKey); ExitFunction1(hr = S_OK); } // save changes hr = piUsrInRoleColl->SaveChanges(&lChanges); if (COMADMIN_E_OBJECTERRORS == hr) CpiLogCatalogErrorInfo(); ExitOnFailure(hr, "Failed to save changes"); // log WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey); hr = S_OK; LExit: // clean up ReleaseObject(piUsrInRoleColl); if (pSid) ::HeapFree(::GetProcessHeap(), 0, pSid); return hr; }
HRESULT ScaDbsRead( __inout SCA_DB** ppsdList, __in SCA_ACTION saAction ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hView; PMSIHANDLE hRec; PMSIHANDLE hViewFileSpec = NULL; LPWSTR pwzData = NULL; LPWSTR pwzId = NULL; LPWSTR pwzComponent = NULL; SCA_DB* psd = NULL; if (S_OK != WcaTableExists(L"SqlDatabase")) { WcaLog(LOGMSG_VERBOSE, "Skipping ScaCreateDatabase() - SqlDatabase table not present"); ExitFunction1(hr = S_FALSE); } if (S_OK == WcaTableExists(L"SqlFileSpec")) { hr = WcaOpenView(vcsSqlFileSpecQuery, &hViewFileSpec); ExitOnFailure(hr, "failed to open view on SqlFileSpec table"); } // loop through all the sql databases hr = WcaOpenExecuteView(vcsSqlDatabaseQuery, &hView); ExitOnFailure(hr, "Failed to open view on SqlDatabase table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { BOOL fHasComponent = FALSE; INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; hr = WcaGetRecordString(hRec, sdqSqlDb, &pwzId); ExitOnFailure(hr, "Failed to get SqlDatabase.SqlDb"); hr = WcaGetRecordString(hRec, sdqComponent, &pwzComponent); ExitOnFailure1(hr, "Failed to get Component for database: '%ls'", psd->wzKey); if (pwzComponent && *pwzComponent) { fHasComponent = TRUE; er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &isInstalled, &isAction); hr = HRESULT_FROM_WIN32(er); ExitOnFailure1(hr, "Failed to get state for component: %ls", pwzComponent); // If we're doing install but the Component is not being installed or we're doing // uninstall but the Component is not being uninstalled, skip it. if ((WcaIsInstalling(isInstalled, isAction) && SCA_ACTION_INSTALL != saAction) || (WcaIsUninstalling(isInstalled, isAction) && SCA_ACTION_UNINSTALL != saAction)) { continue; } } hr = NewDb(&psd); ExitOnFailure1(hr, "Failed to allocate memory for new database: %D", pwzId); hr = ::StringCchCopyW(psd->wzKey, countof(psd->wzKey), pwzId); ExitOnFailure1(hr, "Failed to copy SqlDatabase.SqlDbL: %ls", pwzId); hr = ::StringCchCopyW(psd->wzComponent, countof(psd->wzComponent), pwzComponent); ExitOnFailure1(hr, "Failed to copy SqlDatabase.Component_: %ls", pwzComponent); psd->fHasComponent = fHasComponent; psd->isInstalled = isInstalled; psd->isAction = isAction; hr = WcaGetRecordFormattedString(hRec, sdqServer, &pwzData); ExitOnFailure1(hr, "Failed to get Server for database: '%ls'", psd->wzKey); hr = ::StringCchCopyW(psd->wzServer, countof(psd->wzServer), pwzData); ExitOnFailure1(hr, "Failed to copy server string to database object:%ls", pwzData); hr = WcaGetRecordFormattedString(hRec, sdqInstance, &pwzData); ExitOnFailure1(hr, "Failed to get Instance for database: '%ls'", psd->wzKey); hr = ::StringCchCopyW(psd->wzInstance, countof(psd->wzInstance), pwzData); ExitOnFailure1(hr, "Failed to copy instance string to database object:%ls", pwzData); hr = WcaGetRecordFormattedString(hRec, sdqDatabase, &pwzData); ExitOnFailure1(hr, "Failed to get Database for database: '%ls'", psd->wzKey); hr = ::StringCchCopyW(psd->wzDatabase, countof(psd->wzDatabase), pwzData); ExitOnFailure1(hr, "Failed to copy database string to database object:%ls", pwzData); hr = WcaGetRecordInteger(hRec, sdqAttributes, &psd->iAttributes); ExitOnFailure(hr, "Failed to get SqlDatabase.Attributes"); hr = WcaGetRecordFormattedString(hRec, sdqUser, &pwzData); ExitOnFailure1(hr, "Failed to get User record for database: '%ls'", psd->wzKey); // if a user was specified if (*pwzData) { psd->fUseIntegratedAuth = FALSE; hr = ScaGetUser(pwzData, &psd->scau); ExitOnFailure1(hr, "Failed to get user information for database: '%ls'", psd->wzKey); } else { psd->fUseIntegratedAuth = TRUE; // integrated authorization doesn't have a User record } hr = WcaGetRecordString(hRec, sdqDbFileSpec, &pwzData); ExitOnFailure1(hr, "Failed to get Database FileSpec for database: '%ls'", psd->wzKey); // if a database filespec was specified if (*pwzData) { hr = GetFileSpec(hViewFileSpec, pwzData, &psd->sfDb); ExitOnFailure1(hr, "failed to get FileSpec for: %ls", pwzData); if (S_OK == hr) { psd->fHasDbSpec = TRUE; } } hr = WcaGetRecordString(hRec, sdqLogFileSpec, &pwzData); ExitOnFailure1(hr, "Failed to get Log FileSpec for database: '%ls'", psd->wzKey); // if a log filespec was specified if (*pwzData) { hr = GetFileSpec(hViewFileSpec, pwzData, &psd->sfLog); ExitOnFailure1(hr, "failed to get FileSpec for: %ls", pwzData); if (S_OK == hr) { psd->fHasLogSpec = TRUE; } } *ppsdList = AddDbToList(*ppsdList, psd); psd = NULL; // set the db NULL so it doesn't accidentally get freed below } if (E_NOMOREITEMS == hr) { hr = S_OK; } ExitOnFailure(hr, "Failure occured while processing SqlDatabase table"); LExit: if (psd) { ScaDbsFreeList(psd); } ReleaseStr(pwzComponent); ReleaseStr(pwzId); ReleaseStr(pwzData); return hr; }
HRESULT CpiSubscriptionsRead( CPI_ASSEMBLY_LIST* pAsmList, CPI_SUBSCRIPTION_LIST* pSubList ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hView, hRec; CPI_SUBSCRIPTION* pItm = NULL; LPWSTR pwzData = NULL; BOOL fMatchingArchitecture = FALSE; // loop through all applications hr = WcaOpenExecuteView(vcsSubscriptionQuery, &hView); ExitOnFailure(hr, "Failed to execute view on ComPlusSubscription table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { // get component hr = WcaGetRecordString(hRec, sqComponent, &pwzData); ExitOnFailure(hr, "Failed to get component"); // check if the component is our processor architecture hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture); ExitOnFailure(hr, "Failed to get component architecture."); if (!fMatchingArchitecture) { continue; // not the same architecture, ignore } // create entry pItm = (CPI_SUBSCRIPTION*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_SUBSCRIPTION)); if (!pItm) ExitFunction1(hr = E_OUTOFMEMORY); // get component install state er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state"); // get key hr = WcaGetRecordString(hRec, sqSubscription, &pwzData); ExitOnFailure(hr, "Failed to get key"); StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData); // get com+ component hr = WcaGetRecordString(hRec, sqComPlusComponent, &pwzData); ExitOnFailure(hr, "Failed to get COM+ component"); hr = ComponentFindByKey(pAsmList, pwzData, &pItm->pAssembly, &pItm->pComponent); if (S_FALSE == hr) { // component not found ExitOnFailure1(hr = E_FAIL, "Failed to find component, key: %S", pwzData); } // get id hr = WcaGetRecordFormattedString(hRec, sqID, &pwzData); ExitOnFailure(hr, "Failed to get id"); if (pwzData && *pwzData) { hr = PcaGuidToRegFormat(pwzData, pItm->wzID, countof(pItm->wzID)); ExitOnFailure2(hr, "Failed to parse id guid value, key: %S, value: '%S'", pItm->wzKey, pwzData); } // get name hr = WcaGetRecordFormattedString(hRec, sqName, &pwzData); ExitOnFailure(hr, "Failed to get name"); StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData); // get event clsid hr = WcaGetRecordFormattedString(hRec, sqEventCLSID, &pwzData); ExitOnFailure(hr, "Failed to get event clsid"); StringCchCopyW(pItm->wzEventCLSID, countof(pItm->wzEventCLSID), pwzData); // get publisher id hr = WcaGetRecordFormattedString(hRec, sqPublisherID, &pwzData); ExitOnFailure(hr, "Failed to get publisher id"); StringCchCopyW(pItm->wzPublisherID, countof(pItm->wzPublisherID), pwzData); // get properties if (CpiTableExists(cptComPlusSubscriptionProperty)) { hr = CpiPropertiesRead(vcsSubscriptionPropertyQuery, pItm->wzKey, pdlSubscriptionProperties, &pItm->pProperties, &pItm->iPropertyCount); ExitOnFailure(hr, "Failed to get subscription properties"); } // set references & increment counters if (WcaIsInstalling(pItm->isInstalled, pItm->isAction)) { CpiApplicationAddReferenceInstall(pItm->pAssembly->pApplication); pItm->pAssembly->fReferencedForInstall = TRUE; pSubList->iInstallCount++; if (pItm->pAssembly->iAttributes & aaRunInCommit) pSubList->iCommitCount++; } if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) { CpiApplicationAddReferenceUninstall(pItm->pAssembly->pApplication); pItm->pAssembly->fReferencedForUninstall = TRUE; pSubList->iUninstallCount++; } // add entry if (pSubList->pFirst) pItm->pNext = pSubList->pFirst; pSubList->pFirst = pItm; pItm = NULL; } if (E_NOMOREITEMS == hr) hr = S_OK; LExit: // clean up if (pItm) FreeSubscription(pItm); ReleaseStr(pwzData); return hr; }
static HRESULT ReadXmlConfigTable( __inout XML_CONFIG_CHANGE** ppxfcHead, __inout XML_CONFIG_CHANGE** ppxfcTail ) { Assert(ppxfcHead && ppxfcTail); HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hView = NULL; PMSIHANDLE hRec = NULL; LPWSTR pwzData = NULL; // loop through all the xml configurations hr = WcaOpenExecuteView(vcsXmlConfigQuery, &hView); ExitOnFailure(hr, "failed to open view on XmlConfig table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { hr = AddXmlConfigChangeToList(ppxfcHead, ppxfcTail); ExitOnFailure(hr, "failed to add xml file change to list"); // Get record Id hr = WcaGetRecordString(hRec, xfqXmlConfig, &pwzData); ExitOnFailure(hr, "failed to get XmlConfig record Id"); hr = StringCchCopyW((*ppxfcTail)->wzId, countof((*ppxfcTail)->wzId), pwzData); ExitOnFailure(hr, "failed to copy XmlConfig record Id"); // Get component name hr = WcaGetRecordString(hRec, xfqComponent, &pwzData); ExitOnFailure1(hr, "failed to get component name for XmlConfig: %ls", (*ppxfcTail)->wzId); // Get the component's state if (0 < lstrlenW(pwzData)) { hr = StringCchCopyW((*ppxfcTail)->wzComponent, countof((*ppxfcTail)->wzComponent), pwzData); ExitOnFailure(hr, "failed to copy component id"); er = ::MsiGetComponentStateW(WcaGetInstallHandle(), (*ppxfcTail)->wzComponent, &(*ppxfcTail)->isInstalled, &(*ppxfcTail)->isAction); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "failed to get install state for component id"); } // Get the xml file hr = WcaGetRecordFormattedString(hRec, xfqFile, &pwzData); ExitOnFailure1(hr, "failed to get xml file for XmlConfig: %ls", (*ppxfcTail)->wzId); hr = StringCchCopyW((*ppxfcTail)->wzFile, countof((*ppxfcTail)->wzFile), pwzData); ExitOnFailure(hr, "failed to copy xml file path"); // Figure out if the file is already on the machine or if it's being installed hr = WcaGetRecordString(hRec, xfqFile, &pwzData); ExitOnFailure1(hr, "failed to get xml file for XmlConfig: %ls", (*ppxfcTail)->wzId); if (NULL != wcsstr(pwzData, L"[!") || NULL != wcsstr(pwzData, L"[#")) { (*ppxfcTail)->fInstalledFile = TRUE; } // Get the XmlConfig table flags hr = WcaGetRecordInteger(hRec, xfqXmlFlags, &(*ppxfcTail)->iXmlFlags); ExitOnFailure1(hr, "failed to get XmlConfig flags for XmlConfig: %ls", (*ppxfcTail)->wzId); // Get the Element Path hr = WcaGetRecordFormattedString(hRec, xfqElementPath, &(*ppxfcTail)->pwzElementPath); ExitOnFailure1(hr, "failed to get Element Path for XmlConfig: %ls", (*ppxfcTail)->wzId); // Get the Verify Path hr = WcaGetRecordFormattedString(hRec, xfqVerifyPath, &(*ppxfcTail)->pwzVerifyPath); ExitOnFailure1(hr, "failed to get Verify Path for XmlConfig: %ls", (*ppxfcTail)->wzId); // Get the name hr = WcaGetRecordFormattedString(hRec, xfqName, &pwzData); ExitOnFailure1(hr, "failed to get Name for XmlConfig: %ls", (*ppxfcTail)->wzId); hr = StringCchCopyW((*ppxfcTail)->wzName, countof((*ppxfcTail)->wzName), pwzData); ExitOnFailure(hr, "failed to copy name of element"); // Get the value hr = WcaGetRecordFormattedString(hRec, xfqValue, &pwzData); ExitOnFailure1(hr, "failed to get Value for XmlConfig: %ls", (*ppxfcTail)->wzId); hr = StrAllocString(&(*ppxfcTail)->pwzValue, pwzData, 0); ExitOnFailure(hr, "failed to allocate buffer for value"); // Get the component attributes hr = WcaGetRecordInteger(hRec, xfqCompAttributes, &(*ppxfcTail)->iCompAttributes); ExitOnFailure1(hr, "failed to get component attributes for XmlConfig: %ls", (*ppxfcTail)->wzId); } // if we looped through all records all is well if (E_NOMOREITEMS == hr) { hr = S_OK; } ExitOnFailure(hr, "failed while looping through all objects to secure"); LExit: ReleaseStr(pwzData); return hr; }
static HRESULT CreatePartitionUser( CPI_PARTITION_USER_ATTRIBUTES* pAttrs ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; ICatalogCollection* piUserColl = NULL; ICatalogObject* piUserObj = NULL; PSID pSid = NULL; long lChanges = 0; // log WcaLog(LOGMSG_VERBOSE, "Setting default partition for user, key: %S", pAttrs->pwzKey); // get partition users collection hr = CpiGetPartitionUsersCollection(&piUserColl); ExitOnFailure(hr, "Failed to get partition users collection"); // get SID for account do { er = ERROR_SUCCESS; hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid); if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK)) { WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount); er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); switch (er) { case IDABORT: ExitFunction(); // exit with error code from CpiAccountNameToSid() case IDRETRY: break; case IDIGNORE: default: ExitFunction1(hr = S_OK); } } else ExitOnFailure(hr, "Failed to get SID for account"); } while (IDRETRY == er); // remove any existing entry hr = CpiRemoveUserCollectionObject(piUserColl, pSid); if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr) { WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr); hr = S_FALSE; } else ExitOnFailure(hr, "Failed to remove user"); if (S_OK == hr) WcaLog(LOGMSG_VERBOSE, "Existing default partition for user was removed, key: %S", pAttrs->pwzKey); // add partition user hr = CpiAddCollectionObject(piUserColl, &piUserObj); ExitOnFailure(hr, "Failed to add partition to collection"); hr = CpiPutCollectionObjectValue(piUserObj, L"AccountName", pAttrs->pwzAccount); ExitOnFailure(hr, "Failed to set account name property"); hr = CpiPutCollectionObjectValue(piUserObj, L"DefaultPartitionID", pAttrs->pwzPartID); ExitOnFailure(hr, "Failed to set default partition id property"); // save changes hr = piUserColl->SaveChanges(&lChanges); if (COMADMIN_E_OBJECTERRORS == hr) CpiLogCatalogErrorInfo(); ExitOnFailure(hr, "Failed to save changes"); // log WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey); hr = S_OK; LExit: // clean up ReleaseObject(piUserColl); ReleaseObject(piUserObj); if (pSid) ::HeapFree(::GetProcessHeap(), 0, pSid); return hr; }
static HRESULT CreateUsersInApplicationRole( CPI_USER_IN_APPLICATION_ROLE_ATTRIBUTES* pAttrs ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; ICatalogCollection* piUsrInRoleColl = NULL; ICatalogObject* piUsrInRoleObj = NULL; PSID pSid = NULL; long lChanges = 0; // log WcaLog(LOGMSG_VERBOSE, "Adding user to application role, key: %S", pAttrs->pwzKey); // get users in role collection hr = CpiGetUsersInRoleCollection(pAttrs->pwzPartID, pAttrs->pwzAppID, pAttrs->pwzRoleName, &piUsrInRoleColl); if (S_FALSE == hr) hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); ExitOnFailure(hr, "Failed to get users in role collection"); // get SID for account do { er = ERROR_SUCCESS; hr = CpiAccountNameToSid(pAttrs->pwzAccount, &pSid); if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr && !::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK)) { WcaLog(LOGMSG_STANDARD, "Failed to lookup account name, hr: 0x%x, account: '%S'", hr, pAttrs->pwzAccount); er = WcaErrorMessage(msierrComPlusFailedLookupNames, hr, INSTALLMESSAGE_ERROR | MB_ABORTRETRYIGNORE, 0); switch (er) { case IDABORT: ExitFunction(); // exit with error code from CpiAccountNameToSid() case IDRETRY: break; case IDIGNORE: default: ExitFunction1(hr = S_OK); } } else ExitOnFailure(hr, "Failed to get SID for account"); } while (IDRETRY == er); // find any existing entry hr = CpiFindUserCollectionObject(piUsrInRoleColl, pSid, NULL); if (HRESULT_FROM_WIN32(ERROR_NONE_MAPPED) == hr || HRESULT_FROM_WIN32(ERROR_SOME_NOT_MAPPED) == hr) WcaLog(LOGMSG_STANDARD, "Failed to lookup account names, hr: 0x%x", hr); else ExitOnFailure(hr, "Failed to find user in application role"); if (S_OK == hr) { WcaLog(LOGMSG_VERBOSE, "User already assigned to application role, key: %S", pAttrs->pwzKey); ExitFunction(); // exit with hr = S_OK } // convert SID back to account name hr = CpiSidToAccountName(pSid, &pAttrs->pwzAccount); ExitOnFailure(hr, "Failed to convert SID to account name"); // add user hr = CpiAddCollectionObject(piUsrInRoleColl, &piUsrInRoleObj); ExitOnFailure(hr, "Failed to add user in role to collection"); hr = CpiPutCollectionObjectValue(piUsrInRoleObj, L"User", pAttrs->pwzAccount); ExitOnFailure(hr, "Failed to set role name property"); // save changes hr = piUsrInRoleColl->SaveChanges(&lChanges); if (COMADMIN_E_OBJECTERRORS == hr) CpiLogCatalogErrorInfo(); ExitOnFailure(hr, "Failed to save changes"); // log WcaLog(LOGMSG_VERBOSE, "%d changes saved to catalog, key: %S", lChanges, pAttrs->pwzKey); hr = S_OK; LExit: // clean up ReleaseObject(piUsrInRoleColl); ReleaseObject(piUsrInRoleObj); if (pSid) ::HeapFree(::GetProcessHeap(), 0, pSid); return hr; }
HRESULT ScaWebsRead( __in IMSAdminBase* piMetabase, __in SCA_WEB** ppswList, __in SCA_HTTP_HEADER** ppshhList, __in SCA_WEB_ERROR** ppsweList ) { Assert(piMetabase && ppswList); HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; BOOL fIIsWebSiteTable = FALSE; BOOL fIIsWebAddressTable = FALSE; BOOL fIIsWebApplicationTable = FALSE; PMSIHANDLE hView, hRec; PMSIHANDLE hViewAddresses, hRecAddresses; PMSIHANDLE hViewApplications, hRecApplications; SCA_WEB* psw = NULL; LPWSTR pwzData = NULL; DWORD dwLen = 0; // check to see what tables are available fIIsWebSiteTable = (S_OK == WcaTableExists(L"IIsWebSite")); fIIsWebAddressTable = (S_OK == WcaTableExists(L"IIsWebAddress")); fIIsWebApplicationTable = (S_OK == WcaTableExists(L"IIsWebApplication")); if (!fIIsWebSiteTable || !fIIsWebAddressTable) { WcaLog(LOGMSG_VERBOSE, "Required tables not present"); hr = S_FALSE; goto LExit; } // open the view on webs' addresses hr = WcaOpenView(vcsWebAddressQuery, &hViewAddresses); ExitOnFailure(hr, "Failed to open view on IIsWebAddress table"); // open the view on webs' applications if (fIIsWebApplicationTable) { hr = WcaOpenView(vcsWebApplicationQuery, &hViewApplications); ExitOnFailure(hr, "Failed to open view on IIsWebApplication table"); } // loop through all the webs hr = WcaOpenExecuteView(vcsWebQuery, &hView); ExitOnFailure(hr, "Failed to execute view on IIsWebSite table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { psw = NewWeb(); if (!psw) { hr = E_OUTOFMEMORY; break; } // get the darwin information hr = WcaGetRecordString(hRec, wqWeb, &pwzData); ExitOnFailure(hr, "Failed to get Web"); StringCchCopyW(psw->wzKey, countof(psw->wzKey), pwzData); // get component install state hr = WcaGetRecordString(hRec, wqComponent, &pwzData); ExitOnFailure(hr, "Failed to get Component for Web"); StringCchCopyW(psw->wzComponent, countof(psw->wzComponent), pwzData); if (*(psw->wzComponent)) { psw->fHasComponent = TRUE; er = ::MsiGetComponentStateW(WcaGetInstallHandle(), psw->wzComponent, &psw->isInstalled, &psw->isAction); hr = HRESULT_FROM_WIN32(er); ExitOnFailure(hr, "Failed to get web Component state"); } // get the web's key address hr = WcaGetRecordString(hRec, wqAddress, &pwzData); ExitOnFailure(hr, "Failed to get Address for Web"); StringCchCopyW(psw->swaKey.wzKey, countof(psw->swaKey.wzKey), pwzData); hr = WcaGetRecordFormattedString(hRec, wqIP, &pwzData); ExitOnFailure(hr, "Failed to get IP for Web"); StringCchCopyW(psw->swaKey.wzIP, countof(psw->swaKey.wzIP), pwzData); hr = WcaGetRecordFormattedString(hRec, wqPort, &pwzData); ExitOnFailure(hr, "Failed to get Web Address port"); psw->swaKey.iPort = wcstol(pwzData, NULL, 10); if (0 == psw->swaKey.iPort) ExitOnFailure1(hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA), "invalid port provided for web site: %S", psw->wzDescription); hr = WcaGetRecordFormattedString(hRec, wqHeader, &pwzData); ExitOnFailure(hr, "Failed to get Header for Web"); StringCchCopyW(psw->swaKey.wzHeader, countof(psw->swaKey.wzHeader), pwzData); hr = WcaGetRecordInteger(hRec, wqSecure, &psw->swaKey.fSecure); ExitOnFailure(hr, "Failed to get if Web is secure"); if (S_FALSE == hr) psw->swaKey.fSecure = FALSE; // TODO: fix this to look for the description as well (or is address enough)? // find the web root dwLen = METADATA_MAX_NAME_LEN; hr = ScaWebFindBase(piMetabase, *ppswList, psw->wzKey, psw->swaKey.wzIP, psw->swaKey.iPort, psw->swaKey.wzHeader, psw->swaKey.fSecure, psw->wzWebBase, &dwLen); if (S_OK == hr) { psw->fBaseExists = TRUE; } else if (S_FALSE == hr && FALSE == psw->fHasComponent) // if we're not installing it, fail if it wasn't found { ExitOnFailure1(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "failed to find web site: '%S'", psw->wzKey); } else if (S_FALSE == hr) { dwLen = METADATA_MAX_NAME_LEN; hr = ScaWebFindFreeBase(piMetabase, *ppswList, psw->wzWebBase, dwLen); psw->fBaseExists = FALSE; } ExitOnFailure(hr, "Failed to find web root"); // get any extra web addresses hr = WcaExecuteView(hViewAddresses, hRec); ExitOnFailure(hr, "Failed to execute view on extra IIsWebAddress table"); while (S_OK == (hr = WcaFetchRecord(hViewAddresses, &hRecAddresses))) { if (MAX_ADDRESSES_PER_WEB <= psw->cExtraAddresses) { hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); ExitOnFailure(hr, "Failure to get more extra web addresses, max exceeded."); } hr = WcaGetRecordString(hRecAddresses, waqAddress, &pwzData); ExitOnFailure(hr, "Failed to get extra web Address"); // if this isn't the key address add it if (0 != lstrcmpW(pwzData, psw->swaKey.wzKey)) { StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey), pwzData); hr = WcaGetRecordFormattedString(hRecAddresses, waqIP, &pwzData); ExitOnFailure(hr, "Failed to get extra web IP"); StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP), pwzData); hr = WcaGetRecordFormattedString(hRecAddresses, waqPort, &pwzData); ExitOnFailure(hr, "Failed to get port for extra web IP"); psw->swaExtraAddresses[psw->cExtraAddresses].iPort= wcstol(pwzData, NULL, 10); hr = WcaGetRecordFormattedString(hRecAddresses, waqHeader, &pwzData); ExitOnFailure(hr, "Failed to get header for extra web IP"); StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader), pwzData); hr = WcaGetRecordInteger(hRecAddresses, waqSecure, &psw->swaExtraAddresses[psw->cExtraAddresses].fSecure); ExitOnFailure(hr, "Failed to get if secure extra web IP"); if (S_FALSE == hr) psw->swaExtraAddresses[psw->cExtraAddresses].fSecure = FALSE; psw->cExtraAddresses++; } } if (E_NOMOREITEMS == hr) hr = S_OK; ExitOnFailure(hr, "Failure occured while getting extra web addresses"); // get the web's description hr = WcaGetRecordFormattedString(hRec, wqDescription, &pwzData); ExitOnFailure(hr, "Failed to get Description for Web"); StringCchCopyW(psw->wzDescription, countof(psw->wzDescription), pwzData); hr = WcaGetRecordInteger(hRec, wqConnectionTimeout, &psw->iConnectionTimeout); ExitOnFailure(hr, "Failed to get connection timeout for Web"); if (psw->fHasComponent) // If we're installing it, it needs a dir { // get the web's directory hr = WcaGetRecordString(hRec, wqDirectory, &pwzData); ExitOnFailure(hr, "Failed to get Directory for Web"); WCHAR wzPath[MAX_PATH]; dwLen = countof(wzPath); if (INSTALLSTATE_SOURCE == psw->isAction) er = ::MsiGetSourcePathW(WcaGetInstallHandle(), pwzData, wzPath, &dwLen); else er = ::MsiGetTargetPathW(WcaGetInstallHandle(), pwzData, wzPath, &dwLen); hr = HRESULT_FROM_WIN32(er); ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory"); if (dwLen > countof(wzPath)) { hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER); ExitOnFailure(hr, "Failed because Source/TargetPath for Directory was greater than MAX_PATH."); } // remove traling backslash if (dwLen > 0 && wzPath[dwLen-1] == L'\\') wzPath[dwLen-1] = 0; StringCchCopyW(psw->wzDirectory, countof(psw->wzDirectory), wzPath); } hr = WcaGetRecordInteger(hRec, wqState, &psw->iState); ExitOnFailure(hr, "Failed to get state for Web"); hr = WcaGetRecordInteger(hRec, wqAttributes, &psw->iAttributes); ExitOnFailure(hr, "Failed to get attributes for Web"); // get the dir properties for this web hr = WcaGetRecordString(hRec, wqProperties, &pwzData); ExitOnFailure(hr, "Failed to get directory properties for Web"); if (*pwzData) { hr = ScaGetWebDirProperties(pwzData, &psw->swp); ExitOnFailure(hr, "Failed to get directory properties for Web"); psw->fHasProperties = TRUE; } // get the application information for this web hr = WcaGetRecordString(hRec, wqApplication, &pwzData); ExitOnFailure(hr, "Failed to get application identifier for Web"); if (*pwzData) { hr = ScaGetWebApplication(NULL, pwzData, &psw->swapp); ExitOnFailure(hr, "Failed to get application for Web"); psw->fHasApplication = TRUE; } // get the SSL certificates hr = ScaSslCertificateRead(psw->wzKey, &(psw->pswscList)); ExitOnFailure(hr, "Failed to get SSL Certificates."); // get the custom headers if (*ppshhList) { hr = ScaGetHttpHeader(hhptWeb, psw->wzKey, ppshhList, &(psw->pshhList)); ExitOnFailure(hr, "Failed to get Custom HTTP Headers"); } // get the errors if (*ppsweList) { hr = ScaGetWebError(weptWeb, psw->wzKey, ppsweList, &(psw->psweList)); ExitOnFailure(hr, "Failed to get Custom Errors"); } // get the log information for this web hr = WcaGetRecordString(hRec, wqLog, &pwzData); ExitOnFailure(hr, "Failed to get log identifier for Web"); if (*pwzData) { hr = ScaGetWebLog(piMetabase, pwzData, &psw->swl); ExitOnFailure(hr, "Failed to get Log for Web."); psw->fHasLog = TRUE; } *ppswList = AddWebToList(*ppswList, psw); psw = NULL; // set the web NULL so it doesn't accidentally get freed below } if (E_NOMOREITEMS == hr) hr = S_OK; LExit: // if anything was left over after an error clean it all up if (psw) ScaWebsFreeList(psw); ReleaseStr(pwzData); return hr; }
HRESULT CpiPartitionUsersRead( CPI_PARTITION_LIST* pPartList, CPI_PARTITION_USER_LIST* pPartUsrList ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hView, hRec; CPI_PARTITION_USER* pItm = NULL; LPWSTR pwzData = NULL; LPWSTR pwzDomain = NULL; LPWSTR pwzName = NULL; BOOL fMatchingArchitecture = FALSE; // loop through all partition users hr = WcaOpenExecuteView(vcsPartitionUserQuery, &hView); ExitOnFailure(hr, "Failed to execute view on ComPlusPartitionUser table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { // get component hr = WcaGetRecordString(hRec, puqComponent, &pwzData); ExitOnFailure(hr, "Failed to get component"); // check if the component is our processor architecture hr = CpiVerifyComponentArchitecure(pwzData, &fMatchingArchitecture); ExitOnFailure(hr, "Failed to get component architecture."); if (!fMatchingArchitecture) { continue; // not the same architecture, ignore } // create entry pItm = (CPI_PARTITION_USER*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_PARTITION_USER)); if (!pItm) ExitFunction1(hr = E_OUTOFMEMORY); // get component install state er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state"); // get key hr = WcaGetRecordString(hRec, puqPartitionUser, &pwzData); ExitOnFailure(hr, "Failed to get key"); StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData); // get partition hr = WcaGetRecordString(hRec, puqPartition, &pwzData); ExitOnFailure(hr, "Failed to get partition"); hr = CpiPartitionFindByKey(pPartList, pwzData, &pItm->pPartition); if (S_FALSE == hr) hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); ExitOnFailure(hr, "Failed to find partition, key: %S", pwzData); // get user domain hr = WcaGetRecordFormattedString(hRec, puqDomain, &pwzDomain); ExitOnFailure(hr, "Failed to get user domain"); // get user name hr = WcaGetRecordFormattedString(hRec, puqName, &pwzName); ExitOnFailure(hr, "Failed to get user name"); // build account name hr = CpiBuildAccountName(pwzDomain, pwzName, &pItm->pwzAccount); ExitOnFailure(hr, "Failed to build account name"); // set references & increment counters if (WcaIsInstalling(pItm->isInstalled, pItm->isAction)) { pItm->pPartition->fReferencedForInstall = TRUE; pPartUsrList->iInstallCount++; } if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) { pItm->pPartition->fReferencedForUninstall = TRUE; pPartUsrList->iUninstallCount++; } // add entry if (pPartUsrList->pFirst) pItm->pNext = pPartUsrList->pFirst; pPartUsrList->pFirst = pItm; pItm = NULL; } if (E_NOMOREITEMS == hr) hr = S_OK; LExit: // clean up if (pItm) FreePartitionUser(pItm); ReleaseStr(pwzData); ReleaseStr(pwzDomain); ReleaseStr(pwzName); return hr; }
/******************************************************************** WcaProgressMessage() - extends the progress bar or sends a progress update from the CustomAction ********************************************************************/ extern "C" HRESULT WIXAPI WcaProgressMessage( __in UINT uiCost, __in BOOL fExtendProgressBar ) { static BOOL fExplicitProgressMessages = FALSE; HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; MSIHANDLE hRec = ::MsiCreateRecord(3); // if aren't extending the progress bar and we haven't switched into explicit message mode if (!fExtendProgressBar && !fExplicitProgressMessages) { AssertSz(::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_SCHEDULED) || ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_COMMIT) || ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK), "can only send progress bar messages in a deferred CustomAction"); // tell Darwin to use explicit progress messages ::MsiRecordSetInteger(hRec, 1, 1); ::MsiRecordSetInteger(hRec, 2, 1); ::MsiRecordSetInteger(hRec, 3, 0); er = WcaProcessMessage(INSTALLMESSAGE_PROGRESS, hRec); if (0 == er || IDOK == er || IDYES == er) { hr = S_OK; } else if (IDABORT == er || IDCANCEL == er) { WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit ExitFunction1(hr = S_FALSE); } else { hr = E_UNEXPECTED; } ExitOnFailure(hr, "failed to tell Darwin to use explicit progress messages"); fExplicitProgressMessages = TRUE; } #if DEBUG else if (fExtendProgressBar) // if we are extending the progress bar, make sure we're not deferred { AssertSz(!::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_SCHEDULED), "cannot add ticks to progress bar length from deferred CustomAction"); } #endif // send the progress message ::MsiRecordSetInteger(hRec, 1, (fExtendProgressBar) ? 3 : 2); ::MsiRecordSetInteger(hRec, 2, uiCost); ::MsiRecordSetInteger(hRec, 3, 0); er = WcaProcessMessage(INSTALLMESSAGE_PROGRESS, hRec); if (0 == er || IDOK == er || IDYES == er) { hr = S_OK; } else if (IDABORT == er || IDCANCEL == er) { WcaSetReturnValue(ERROR_INSTALL_USEREXIT); // note that the user said exit hr = S_FALSE; } else { hr = E_UNEXPECTED; } LExit: if (hRec) { ::MsiCloseHandle(hRec); } return hr; }
static HRESULT MessageQueueTrusteePermissionsRead( LPCWSTR pwzQuery, MQI_MESSAGE_QUEUE_LIST* pMessageQueueList, MQI_MESSAGE_QUEUE_PERMISSION_LIST* pList ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hView, hRec; LPWSTR pwzData = NULL; MQI_MESSAGE_QUEUE_PERMISSION* pItm = NULL; // loop through all application roles hr = WcaOpenExecuteView(pwzQuery, &hView); ExitOnFailure(hr, "Failed to execute view on table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { // create entry pItm = (MQI_MESSAGE_QUEUE_PERMISSION*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MQI_MESSAGE_QUEUE_PERMISSION)); if (!pItm) ExitFunction1(hr = E_OUTOFMEMORY); // get key hr = WcaGetRecordString(hRec, mqpqMessageQueuePermission, &pwzData); ExitOnFailure(hr, "Failed to get key"); StringCchCopyW(pItm->wzKey, countof(pItm->wzKey), pwzData); // get component hr = WcaGetRecordString(hRec, mqpqComponent, &pwzData); ExitOnFailure(hr, "Failed to get component"); // get component install state er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &pItm->isInstalled, &pItm->isAction); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to get component state"); // get message queue hr = WcaGetRecordString(hRec, mqpqMessageQueue, &pwzData); ExitOnFailure(hr, "Failed to get application role"); hr = MqiMessageQueueFindByKey(pMessageQueueList, pwzData, &pItm->pMessageQueue); if (S_FALSE == hr) hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); ExitOnFailure(hr, "Failed to find message queue, key: %S", pwzData); // get user domain hr = WcaGetRecordFormattedString(hRec, mqpqDomain, &pwzData); ExitOnFailure(hr, "Failed to get domain"); StringCchCopyW(pItm->wzDomain, countof(pItm->wzDomain), pwzData); // get user name hr = WcaGetRecordFormattedString(hRec, mqpqName, &pwzData); ExitOnFailure(hr, "Failed to get name"); StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData); // get permissions hr = WcaGetRecordInteger(hRec, mqpqPermissions, &pItm->iPermissions); ExitOnFailure(hr, "Failed to get permissions"); // set references & increment counters if (WcaIsInstalling(pItm->isInstalled, pItm->isAction)) pList->iInstallCount++; if (WcaIsUninstalling(pItm->isInstalled, pItm->isAction)) pList->iUninstallCount++; // add entry if (pList->pFirst) pItm->pNext = pList->pFirst; pList->pFirst = pItm; pItm = NULL; } if (E_NOMOREITEMS == hr) hr = S_OK; LExit: // clean up ReleaseStr(pwzData); if (pItm) ::HeapFree(::GetProcessHeap(), 0, pItm); return hr; }
HRESULT ScaSqlStrsReadScripts( __inout SCA_SQLSTR** ppsssList, __in SCA_ACTION saAction ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hView, hRec; PMSIHANDLE hViewBinary, hRecBinary; PMSIHANDLE hViewUser, hRecUser; LPWSTR pwzComponent = NULL; LPWSTR pwzData = NULL; BYTE* pbScript = NULL; DWORD cbRead = 0; DWORD cbScript = 0; DWORD cchScript = 0; LPWSTR pwzScriptBuffer = NULL; WCHAR* pwzScript = NULL; WCHAR* pwz; DWORD cch = 0; SCA_SQLSTR sss; SCA_SQLSTR* psss = NULL; if (S_OK != WcaTableExists(L"SqlScript") || S_OK != WcaTableExists(L"SqlDatabase") || S_OK != WcaTableExists(L"Binary")) { WcaLog(LOGMSG_VERBOSE, "Skipping ScaSqlStrsReadScripts() - SqlScripts and/or SqlDatabase table not present"); ExitFunction1(hr = S_FALSE); } // open a view on the binary table hr = WcaOpenView(vcsSqlBinaryScriptQuery, &hViewBinary); ExitOnFailure(hr, "Failed to open view on Binary table for SqlScripts"); // loop through all the sql scripts hr = WcaOpenExecuteView(vcsSqlScriptQuery, &hView); ExitOnFailure(hr, "Failed to open view on SqlScript table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; hr = WcaGetRecordString(hRec, sscrqComponent, &pwzComponent); ExitOnFailure(hr, "Failed to get Component for SQL Script."); er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &isInstalled, &isAction); hr = HRESULT_FROM_WIN32(er); ExitOnFailure1(hr, "Failed to get state for component: %ls", pwzComponent); // If we're doing install but the Component is not being installed or we're doing // uninstall but the Component is not being uninstalled, skip it. if ((WcaIsInstalling(isInstalled, isAction) && SCA_ACTION_INSTALL != saAction) || (WcaIsUninstalling(isInstalled, isAction) && SCA_ACTION_UNINSTALL != saAction)) { continue; } ::ZeroMemory(&sss, sizeof(sss)); sss.isInstalled = isInstalled; sss.isAction = isAction; hr = WcaGetRecordString(hRec, sscrqSqlScript, &pwzData); ExitOnFailure(hr, "Failed to get SqlScript.Script"); hr = ::StringCchCopyW(sss.wzKey, countof(sss.wzKey), pwzData); ExitOnFailure1(hr, "Failed to copy SqlScript.Script: %ls", pwzData); // find the database information for this string hr = WcaGetRecordString(hRec, sscrqSqlDb, &pwzData); ExitOnFailure1(hr, "Failed to get SqlScript.SqlDb_ for SqlScript '%ls'", sss.wzKey); hr = ::StringCchCopyW(sss.wzSqlDb, countof(sss.wzSqlDb), pwzData); ExitOnFailure1(hr, "Failed to copy SqlScritp.SqlDbb: %ls", pwzData); hr = WcaGetRecordInteger(hRec, sscrqAttributes, &sss.iAttributes); ExitOnFailure1(hr, "Failed to get SqlScript.Attributes for SqlScript '%ls'", sss.wzKey); hr = WcaGetRecordInteger(hRec, sscrqSequence, &sss.iSequence); ExitOnFailure1(hr, "Failed to get SqlScript.Sequence for SqlScript '%ls'", sss.wzKey); // get the sql script out of the binary stream hr = WcaExecuteView(hViewBinary, hRec); ExitOnFailure1(hr, "Failed to open SqlScript.BinaryScript_ for SqlScript '%ls'", sss.wzKey); hr = WcaFetchSingleRecord(hViewBinary, &hRecBinary); ExitOnFailure1(hr, "Failed to fetch SqlScript.BinaryScript_ for SqlScript '%ls'", sss.wzKey); // Note: We need to allocate an extra character on the stream to NULL terminate the SQL script. // The WcaGetRecordStream() function won't let us add extra space on the end of the stream // so we'll read the stream "the old fashioned way". //hr = WcaGetRecordStream(hRecBinary, ssbsqData, (BYTE**)&pbScript, &cbScript); //ExitOnFailure1(hr, "Failed to read SqlScript.BinaryScript_ for SqlScript '%ls'", sss.wzKey); er = ::MsiRecordReadStream(hRecBinary, ssbsqData, NULL, &cbRead); hr = HRESULT_FROM_WIN32(er); ExitOnFailure(hr, "failed to get size of stream"); cbScript = cbRead + sizeof(WCHAR); // we may have an ANSI SQL script but leave enough to even NULL terminate a WCHAR string hr = WcaAllocStream(&pbScript, cbScript); // this will allocate a fully zeroed out buffer so our string will be NULL terminated ExitOnFailure(hr, "failed to allocate data for stream"); er = ::MsiRecordReadStream(hRecBinary, ssbsqData, reinterpret_cast<char*>(pbScript), &cbRead); //read the buffer but leave the space for the NULL terminator hr = HRESULT_FROM_WIN32(er); ExitOnFailure(hr, "failed to read from stream"); Assert(cbRead + sizeof(WCHAR) == cbScript); // Check for the UNICODE BOM file marker. if ((0xFF == *pbScript) && (0xFE == *(pbScript + 1))) { // Copy the UNICODE string after the BOM marker (subtract one because we'll skip the BOM marker). cchScript = (cbScript / sizeof(WCHAR)) - 1; hr = StrAllocString(&pwzScriptBuffer, reinterpret_cast<LPWSTR>(pbScript) + 1, 0); ExitOnFailure1(hr, "Failed to allocate WCHAR string of size '%d'", cchScript); } else { // We have an ANSI string so convert it to UNICODE. cchScript = cbScript; hr = StrAllocStringAnsi(&pwzScriptBuffer, reinterpret_cast<LPCSTR>(pbScript), 0, CP_ACP); ExitOnFailure1(hr, "Failed to allocate WCHAR string of size '%d'", cchScript); } // Free the byte buffer since it has been converted to a new UNICODE string, one way or another. if (pbScript) { WcaFreeStream(pbScript); pbScript = NULL; } // Process the SQL script stripping out unnecessary stuff (like comments) and looking for "GO" statements. pwzScript = pwzScriptBuffer; while (cchScript && pwzScript && *pwzScript) { // strip off leading whitespace while (cchScript && *pwzScript && iswspace(*pwzScript)) { ++pwzScript; --cchScript; } Assert(0 <= cchScript); // if there is a SQL comment remove it while (cchScript && L'/' == *pwzScript && L'*' == *(pwzScript + 1)) { // go until end of comment while (cchScript && *pwzScript && *(pwzScript + 1) && !(L'*' == *pwzScript && L'/' == *(pwzScript + 1))) { ++pwzScript; --cchScript; } Assert(2 <= cchScript); if (2 <= cchScript) { // to account for */ at end pwzScript+=2; cchScript-=2; } Assert(0 <= cchScript); // strip off any new leading whitespace while (cchScript && *pwzScript && iswspace(*pwzScript)) { ++pwzScript; --cchScript; } } while (cchScript && L'-' == *pwzScript && L'-' == *(pwzScript + 1)) { // go past the new line character while (cchScript && *pwzScript && L'\n' != *pwzScript) { ++pwzScript; --cchScript; } Assert(0 <= cchScript); if (cchScript && L'\n' == *pwzScript) { ++pwzScript; --cchScript; } Assert(0 <= cchScript); // strip off any new leading whitespace while (cchScript && *pwzScript && iswspace(*pwzScript)) { ++pwzScript; --cchScript; } } Assert(0 <= cchScript); // try to isolate a "GO" keyword and count the characters in the SQL string pwz = pwzScript; cch = 0; while (cchScript && *pwz) { //skip past comment lines that might have "go" in them //note that these comments are "in the middle" of our function, //or possibly at the end of a line if (cchScript && L'-' == *pwz && L'-' == *(pwz + 1)) { // skip past chars until the new line character while (cchScript && *pwz && (L'\n' != *pwz)) { ++pwz; ++cch; --cchScript; } } //skip past comment lines of form /* to */ that might have "go" in them //note that these comments are "in the middle" of our function, //or possibly at the end of a line if (cchScript && L'/' == *pwz && L'*' == *(pwz + 1)) { // skip past chars until the new line character while (cchScript && *pwz && *(pwz + 1) && !((L'*' == *pwz) && (L'/' == *(pwz + 1)))) { ++pwz; ++cch; --cchScript; } if (2 <= cchScript) { // to account for */ at end pwz+=2; cch+=2; cchScript-=2; } } // Skip past strings that may be part of the SQL statement that might have a "go" in them if ( cchScript && L'\'' == *pwz ) { ++pwz; ++cch; --cchScript; // Skip past chars until the end of the string while ( cchScript && *pwz && !(L'\'' == *pwz) ) { ++pwz; ++cch; --cchScript; } } // Skip past strings that may be part of the SQL statement that might have a "go" in them if ( cchScript && L'\"' == *pwz ) { ++pwz; ++cch; --cchScript; // Skip past chars until the end of the string while ( cchScript && *pwz && !(L'\"' == *pwz) ) { ++pwz; ++cch; --cchScript; } } // if "GO" is isolated if ((pwzScript == pwz || iswspace(*(pwz - 1))) && (L'G' == *pwz || L'g' == *pwz) && (L'O' == *(pwz + 1) || L'o' == *(pwz + 1)) && (0 == *(pwz + 2) || iswspace(*(pwz + 2)))) { *pwz = 0; // null terminate the SQL string on the "G" pwz += 2; cchScript -= 2; break; // found "GO" now add SQL string to list } ++pwz; ++cch; --cchScript; } Assert(0 <= cchScript); if (0 < cch) //don't process if there's nothing to process { // replace tabs with spaces for (LPWSTR pwzTab = wcsstr(pwzScript, L"\t"); pwzTab; pwzTab = wcsstr(pwzTab, L"\t")) *pwzTab = ' '; // strip off whitespace at the end of the script string for (LPWSTR pwzErase = pwzScript + cch - 1; pwzScript < pwzErase && iswspace(*pwzErase); pwzErase--) { *(pwzErase) = 0; cch--; } } if (0 < cch) { hr = NewSqlStr(&psss); ExitOnFailure(hr, "failed to allocate new sql string element"); // copy everything over hr = ::StringCchCopyW(psss->wzKey, countof(psss->wzKey), sss.wzKey); ExitOnFailure(hr, "Failed to copy key string to sqlstr object"); hr = ::StringCchCopyW(psss->wzSqlDb, countof(psss->wzSqlDb), sss.wzSqlDb); ExitOnFailure(hr, "Failed to copy DB string to sqlstr object"); hr = ::StringCchCopyW(psss->wzComponent, countof(psss->wzComponent), sss.wzComponent); ExitOnFailure(hr, "Failed to copy component string to sqlstr object"); psss->isInstalled = sss.isInstalled; psss->isAction = sss.isAction; psss->iAttributes = sss.iAttributes; psss->iSequence = sss.iSequence; // cchRequired includes the NULL terminating char hr = StrAllocString(&psss->pwzSql, pwzScript, 0); ExitOnFailure1(hr, "Failed to allocate string for SQL script: '%ls'", psss->wzKey); *ppsssList = AddSqlStrToList(*ppsssList, psss); psss = NULL; // set the db NULL so it doesn't accidentally get freed below } pwzScript = pwz; } } if (E_NOMOREITEMS == hr) { hr = S_OK; } ExitOnFailure(hr, "Failure occured while reading SqlString table"); LExit: // if anything was left over after an error clean it all up if (psss) { ScaSqlStrsFreeList(psss); } if (pbScript) { WcaFreeStream(pbScript); } ReleaseStr(pwzScriptBuffer); ReleaseStr(pwzData); ReleaseStr(pwzComponent); return hr; }
HRESULT ScaUserRead( __out SCA_USER** ppsuList ) { //Assert(FALSE); Assert(ppsuList); HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hView, hRec, hUserRec, hUserGroupView; LPWSTR pwzData = NULL; BOOL fUserGroupExists = FALSE; SCA_USER *psu = NULL; INSTALLSTATE isInstalled, isAction; if (S_OK != WcaTableExists(L"User")) { WcaLog(LOGMSG_VERBOSE, "User Table does not exist, exiting"); ExitFunction1(hr = S_FALSE); } if (S_OK == WcaTableExists(L"UserGroup")) { fUserGroupExists = TRUE; } // // loop through all the users // hr = WcaOpenExecuteView(vActionableQuery, &hView); ExitOnFailure(hr, "failed to open view on User table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { hr = WcaGetRecordString(hRec, vaqComponent, &pwzData); ExitOnFailure(hr, "failed to get User.Component"); er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &isInstalled, &isAction); hr = HRESULT_FROM_WIN32(er); ExitOnFailure(hr, "failed to get Component state for User"); // don't bother if we aren't installing or uninstalling this component if (WcaIsInstalling(isInstalled, isAction) || WcaIsUninstalling(isInstalled, isAction)) { // // Add the user to the list and populate it's values // hr = AddUserToList(ppsuList); ExitOnFailure(hr, "failed to add user to list"); psu = *ppsuList; psu->isInstalled = isInstalled; psu->isAction = isAction; hr = ::StringCchCopyW(psu->wzComponent, countof(psu->wzComponent), pwzData); ExitOnFailure1(hr, "failed to copy component name: %ls", pwzData); hr = WcaGetRecordString(hRec, vaqUser, &pwzData); ExitOnFailure(hr, "failed to get User.User"); hr = ::StringCchCopyW(psu->wzKey, countof(psu->wzKey), pwzData); ExitOnFailure1(hr, "failed to copy user key: %ls", pwzData); hr = WcaGetRecordFormattedString(hRec, vaqName, &pwzData); ExitOnFailure(hr, "failed to get User.Name"); hr = ::StringCchCopyW(psu->wzName, countof(psu->wzName), pwzData); ExitOnFailure1(hr, "failed to copy user name: %ls", pwzData); hr = WcaGetRecordFormattedString(hRec, vaqDomain, &pwzData); ExitOnFailure(hr, "failed to get User.Domain"); hr = ::StringCchCopyW(psu->wzDomain, countof(psu->wzDomain), pwzData); ExitOnFailure1(hr, "failed to copy user domain: %ls", pwzData); hr = WcaGetRecordFormattedString(hRec, vaqPassword, &pwzData); ExitOnFailure(hr, "failed to get User.Password"); hr = ::StringCchCopyW(psu->wzPassword, countof(psu->wzPassword), pwzData); ExitOnFailure(hr, "failed to copy user password"); hr = WcaGetRecordInteger(hRec, vaqAttributes, &psu->iAttributes); ExitOnFailure(hr, "failed to get User.Attributes"); // Check if this user is to be added to any groups if (fUserGroupExists) { hUserRec = ::MsiCreateRecord(1); hr = WcaSetRecordString(hUserRec, 1, psu->wzKey); ExitOnFailure(hr, "Failed to create user record for querying UserGroup table"); hr = WcaOpenView(vcsUserGroupQuery, &hUserGroupView); ExitOnFailure1(hr, "Failed to open view on UserGroup table for user %ls", psu->wzKey); hr = WcaExecuteView(hUserGroupView, hUserRec); ExitOnFailure1(hr, "Failed to execute view on UserGroup table for user: %ls", psu->wzKey); while (S_OK == (hr = WcaFetchRecord(hUserGroupView, &hRec))) { hr = WcaGetRecordString(hRec, vugqGroup, &pwzData); ExitOnFailure(hr, "failed to get UserGroup.Group"); hr = AddGroupToList(&(psu->psgGroups)); ExitOnFailure(hr, "failed to add group to list"); hr = ScaGetGroup(pwzData, psu->psgGroups); ExitOnFailure1(hr, "failed to get information for group: %ls", pwzData); } if (E_NOMOREITEMS == hr) { hr = S_OK; } ExitOnFailure(hr, "failed to enumerate selected rows from UserGroup table"); } } } if (E_NOMOREITEMS == hr) { hr = S_OK; } ExitOnFailure(hr, "failed to enumerate selected rows from User table"); LExit: ReleaseStr(pwzData); return hr; }
HRESULT ScaSqlStrsRead( __inout SCA_SQLSTR** ppsssList, __in SCA_ACTION saAction ) { HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hView, hRec; PMSIHANDLE hViewUser, hRecUser; LPWSTR pwzComponent = NULL; LPWSTR pwzData = NULL; SCA_SQLSTR* psss = NULL; if (S_OK != WcaTableExists(L"SqlString") || S_OK != WcaTableExists(L"SqlDatabase")) { WcaLog(LOGMSG_VERBOSE, "Skipping ScaSqlStrsRead() - SqlString and/or SqlDatabase table not present"); ExitFunction1(hr = S_FALSE); } // loop through all the sql strings hr = WcaOpenExecuteView(vcsSqlStringQuery, &hView); ExitOnFailure(hr, "Failed to open view on SqlString table"); while (S_OK == (hr = WcaFetchRecord(hView, &hRec))) { INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN; INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN; hr = WcaGetRecordString(hRec, ssqComponent, &pwzComponent); ExitOnFailure(hr, "Failed to get Component for SQL String."); er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &isInstalled, &isAction); hr = HRESULT_FROM_WIN32(er); ExitOnFailure1(hr, "Failed to get state for component: %ls", pwzComponent); // If we're doing install but the Component is not being installed or we're doing // uninstall but the Component is not being uninstalled, skip it. if ((WcaIsInstalling(isInstalled, isAction) && SCA_ACTION_INSTALL != saAction) || (WcaIsUninstalling(isInstalled, isAction) && SCA_ACTION_UNINSTALL != saAction)) { continue; } hr = NewSqlStr(&psss); ExitOnFailure(hr, "failed to allocation new sql string element"); psss->isInstalled = isInstalled; psss->isAction = isAction; hr = WcaGetRecordString(hRec, ssqSqlString, &pwzData); ExitOnFailure(hr, "Failed to get SqlString.String"); hr = ::StringCchCopyW(psss->wzKey, countof(psss->wzKey), pwzData); ExitOnFailure1(hr, "Failed to copy SqlString.String: %ls", pwzData); // find the database information for this string hr = WcaGetRecordString(hRec, ssqSqlDb, &pwzData); ExitOnFailure1(hr, "Failed to get SqlString.SqlDb_ for SqlString '%ls'", psss->wzKey); hr = ::StringCchCopyW(psss->wzSqlDb, countof(psss->wzSqlDb), pwzData); ExitOnFailure1(hr, "Failed to copy SqlString.SqlDb_: %ls", pwzData); hr = WcaGetRecordInteger(hRec, ssqAttributes, &psss->iAttributes); ExitOnFailure1(hr, "Failed to get SqlString.Attributes for SqlString '%ls'", psss->wzKey); //get the sequence number for the string (note that this will be sequenced with scripts too) hr = WcaGetRecordInteger(hRec, ssqSequence, &psss->iSequence); ExitOnFailure1(hr, "Failed to get SqlString.Sequence for SqlString '%ls'", psss->wzKey); // execute SQL hr = WcaGetRecordFormattedString(hRec, ssqSQL, &pwzData); ExitOnFailure1(hr, "Failed to get SqlString.SQL for SqlString '%ls'", psss->wzKey); Assert(!psss->pwzSql); hr = StrAllocString(&psss->pwzSql, pwzData, 0); ExitOnFailure1(hr, "Failed to alloc string for SqlString '%ls'", psss->wzKey); *ppsssList = AddSqlStrToList(*ppsssList, psss); psss = NULL; // set the sss to NULL so it doesn't get freed below } if (E_NOMOREITEMS == hr) { hr = S_OK; } ExitOnFailure(hr, "Failure occured while reading SqlString table"); LExit: // if anything was left over after an error clean it all up if (psss) { ScaSqlStrsFreeList(psss); } ReleaseStr(pwzData); ReleaseStr(pwzComponent); return hr; }