コード例 #1
0
ファイル: appsynup.cpp プロジェクト: AnalogJ/Wix3.6Toolset
static HRESULT GetUpdateInfoFileName(
    __in LPCWSTR wzApplicationId,
    __out LPWSTR* ppwzUpdateInfoPath
    )
{
    HRESULT hr = S_OK;
    WCHAR wzTempPath[MAX_PATH];
    DWORD cchTempPath = countof(wzTempPath);

    cchTempPath = ::GetTempPathW(cchTempPath, wzTempPath);
    if (0 == cchTempPath)
    {
        ExitWithLastError(hr, "Failed to get temp path.");
    }
    else if (countof(wzTempPath) < cchTempPath)
    {
        hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
        ExitOnFailure(hr, "Failed to get temp path.");
    }

    hr = StrAllocConcat(ppwzUpdateInfoPath, wzTempPath, 0);
    ExitOnFailure(hr, "Failed to allocate path to update info.");

    hr = StrAllocConcat(ppwzUpdateInfoPath, wzApplicationId, 0);
    ExitOnFailure(hr, "Failed to allocate path to update info.");

LExit:
    return hr;
}
コード例 #2
0
ファイル: netfxca.cpp プロジェクト: 925coder/wix3
// Gets the path to ngen.exe
static HRESULT GetNgenPath(
    __out LPWSTR* ppwzNgenPath,
    __in BOOL f64BitFramework
    )
{
    Assert(ppwzNgenPath);
    HRESULT hr = S_OK;

    LPWSTR pwzVersion = NULL;
    LPWSTR pwzWindowsFolder = NULL;

    hr = WcaGetProperty(L"WindowsFolder", &pwzWindowsFolder);
    ExitOnFailure(hr, "failed to get WindowsFolder property");

    hr = StrAllocString(ppwzNgenPath, pwzWindowsFolder, 0);
    ExitOnFailure1(hr, "failed to copy to NgenPath windows folder: %ls", pwzWindowsFolder);

    if (f64BitFramework)
    {
        WcaLog(LOGMSG_VERBOSE, "Searching for ngen under 64-bit framework path");

        hr = StrAllocConcat(ppwzNgenPath, L"Microsoft.NET\\Framework64\\", 0);
        ExitOnFailure(hr, "failed to copy platform portion of ngen path");
    }
    else
    {
        WcaLog(LOGMSG_VERBOSE, "Searching for ngen under 32-bit framework path");

        hr = StrAllocConcat(ppwzNgenPath, L"Microsoft.NET\\Framework\\", 0);
        ExitOnFailure(hr, "failed to copy platform portion of ngen path");
    }

    // We want to run the highest version of ngen possible, because they should be backwards compatible - so let's find the most appropriate directory now
    hr = GetNgenVersion(*ppwzNgenPath, &pwzVersion);
    ExitOnFailure1(hr, "failed to search for ngen under path %ls", *ppwzNgenPath);

    hr = StrAllocConcat(ppwzNgenPath, pwzVersion, 0);
    ExitOnFailure(hr, "failed to copy version portion of ngen path");

    hr = StrAllocConcat(ppwzNgenPath, L"\\ngen.exe", 0);
    ExitOnFailure(hr, "failed to copy \"\\ngen.exe\" portion of ngen path");

LExit:
    ReleaseStr(pwzVersion);
    ReleaseStr(pwzWindowsFolder);

    return hr;
}
コード例 #3
0
ファイル: jsonutil.cpp プロジェクト: AnalogJ/Wix3.6Toolset
static HRESULT DoEnd(
    __in JSON_WRITER* pWriter,
    __in JSON_TOKEN tokenEnd,
    __in_z LPCWSTR wzEndString
    )
{
    HRESULT hr = S_OK;

    ::EnterCriticalSection(&pWriter->cs);

    if (!pWriter->rgTokenStack || 0 == pWriter->cTokens)
    {
        hr = E_UNEXPECTED;
        ExitOnRootFailure(hr, "Failure to pop token because the stack is empty.");
    }
    else
    {
        JSON_TOKEN token = pWriter->rgTokenStack[pWriter->cTokens - 1];
        if ((JSON_TOKEN_ARRAY_END == tokenEnd && JSON_TOKEN_ARRAY_START != token && JSON_TOKEN_ARRAY_VALUE != token) ||
            (JSON_TOKEN_OBJECT_END == tokenEnd && JSON_TOKEN_OBJECT_START != token && JSON_TOKEN_OBJECT_VALUE != token))
        {
            hr = E_UNEXPECTED;
            ExitOnRootFailure1(hr, "Failure to pop token because the stack did not match the expected token: %d", tokenEnd);
        }
    }

    hr = StrAllocConcat(&pWriter->sczJson, wzEndString, 0);
    ExitOnFailure(hr, "Failed to end JSON array or object.");

    --pWriter->cTokens;

LExit:
    ::LeaveCriticalSection(&pWriter->cs);
    return hr;
}
コード例 #4
0
ファイル: jsonutil.cpp プロジェクト: AnalogJ/Wix3.6Toolset
static HRESULT DoKey(
    __in JSON_WRITER* pWriter,
    __in_z LPCWSTR wzKey
    )
{
    HRESULT hr = S_OK;
    JSON_TOKEN token = JSON_TOKEN_NONE;
    BOOL fNeedComma = FALSE;

    ::EnterCriticalSection(&pWriter->cs);

    hr = EnsureTokenStack(pWriter);
    ExitOnFailure(hr, "Failed to ensure token stack for key.");

    token = pWriter->rgTokenStack[pWriter->cTokens - 1];
    switch (token)
    {
    case JSON_TOKEN_OBJECT_START:
        token = JSON_TOKEN_OBJECT_KEY;
        break;

    case JSON_TOKEN_OBJECT_VALUE:
        token = JSON_TOKEN_OBJECT_KEY;
        fNeedComma = TRUE;
        break;

    default: // everything else is not allowed.
        hr = E_UNEXPECTED;
        break;
    }
    ExitOnRootFailure(hr, "Cannot add key to JSON serializer now.");

    if (fNeedComma)
    {
        hr = StrAllocConcat(&pWriter->sczJson, L",", 0);
        ExitOnFailure(hr, "Failed to add comma for key to JSON.");
    }

    hr = StrAllocConcat(&pWriter->sczJson, wzKey, 0);
    ExitOnFailure(hr, "Failed to add key to JSON.");

    pWriter->rgTokenStack[pWriter->cTokens - 1] = token;

LExit:
    ::LeaveCriticalSection(&pWriter->cs);
    return hr;
}
コード例 #5
0
ファイル: downloadengine.cpp プロジェクト: Alyoshak/wix3
static HRESULT OpenRequest(
    __in HINTERNET hConnect,
    __in_z_opt LPCWSTR wzMethod,
    __in INTERNET_SCHEME scheme,
    __in_z LPCWSTR wzResource,
    __in_z_opt LPCWSTR wzQueryString,
    __in_z_opt LPCWSTR wzHeader,
    __out HINTERNET* phUrl
    )
{
    HRESULT hr = S_OK;
    DWORD dwRequestFlags = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD;
    LPWSTR sczResource = NULL;
    HINTERNET hUrl = NULL;

    if (INTERNET_SCHEME_HTTPS == scheme)
    {
        dwRequestFlags |= INTERNET_FLAG_SECURE;
    }

    // Allocate the resource name.
    hr = StrAllocString(&sczResource, wzResource, 0);
    ExitOnFailure(hr, "Failed to allocate string for resource URI.");

    if (wzQueryString && *wzQueryString)
    {
        hr = StrAllocConcat(&sczResource, wzQueryString, 0);
        ExitOnFailure(hr, "Failed to append query strong to resource from URI.");
    }

    // Open the request and add the header if provided.
    hUrl = ::HttpOpenRequestW(hConnect, wzMethod, sczResource, NULL, NULL, BURN_DOWNLOAD_ENGINE_ACCEPT_TYPES, dwRequestFlags, NULL);
    ExitOnNullWithLastError(hUrl, hr, "Failed to open internet request.");

    if (wzHeader && *wzHeader)
    {
        if (!::HttpAddRequestHeadersW(hUrl, wzHeader, static_cast<DWORD>(-1), HTTP_ADDREQ_FLAG_COALESCE))
        {
            ExitWithLastError(hr, "Failed to add header to HTTP request.");
        }
    }

    *phUrl = hUrl;
    hUrl = NULL;

LExit:
    ReleaseInternet(hUrl);
    ReleaseStr(sczResource);
    return hr;
}
コード例 #6
0
ファイル: product.cpp プロジェクト: firegiant/wix4
HRESULT ProductGetLegacyManifestValueName(
    __in_z LPCWSTR wzProductName,
    __deref_out_z LPWSTR* psczManifestValueName
    )
{
    HRESULT hr = S_OK;

    hr = StrAllocString(psczManifestValueName, wzLegacyManifestValuePrefix, 0);
    ExitOnFailure(hr, "Failed to allocate legacy manifest value prefix");

    hr = StrAllocConcat(psczManifestValueName, wzProductName, 0);
    ExitOnFailure(hr, "Failed to concat product name %ls to manifest value name", wzProductName);

LExit:
    return hr;
}
コード例 #7
0
ファイル: secureobj.cpp プロジェクト: sillsdev/FwSupportTools
/******************************************************************
 CaSchedSecureObjects - entry point for CaReadSecureObjects Custom Action

 called as Type 1 CustomAction (binary DLL) from Windows Installer
 in InstallExecuteSequence before CaSecureObjects
******************************************************************/
extern "C" UINT __stdcall SchedSecureObjects(
	__in MSIHANDLE hInstall
	)
{
//	AssertSz(FALSE, "debug SchedSecureObjects");
	HRESULT hr = S_OK;
	UINT er = ERROR_SUCCESS;

	LPWSTR pwzData = NULL;
	LPWSTR pwzTable = NULL;
	LPWSTR pwzTargetPath = NULL;
	LPWSTR pwzFormattedString = NULL;

	int iRoot = 0;
	int iAllUsers = 0;
	LPWSTR pwzKey = NULL;

	PMSIHANDLE hView = NULL;
	PMSIHANDLE hRec = NULL;

	MSIHANDLE hViewObject = NULL; // Don't free this since it's always a copy of either hViewService or hViewCreateFolder
	PMSIHANDLE hViewService = NULL;
	PMSIHANDLE hViewCreateFolder = NULL;
	PMSIHANDLE hViewFile = NULL;
	PMSIHANDLE hViewRegistry = NULL;
	PMSIHANDLE hRecObject = NULL;

	INSTALLSTATE isInstalled;
	INSTALLSTATE isAction;

	LPWSTR pwzCustomActionData = NULL;
	DWORD cchCustomActionData = 0;

	DWORD cObjects = 0;
	eOBJECTTYPE eType = OT_UNKNOWN;

	//
	// initialize
	//
	hr = WcaInitialize(hInstall, "SchedSecureObjects");
	ExitOnFailure(hr, "failed to initialize");

	//
	// loop through all the objects to be secured
	//
	hr = WcaOpenExecuteView(wzQUERY_SECUREOBJECTS, &hView);
	ExitOnFailure(hr, "failed to open view on SecureObjects table");
	while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
	{
		hViewObject = NULL;
		eType = OT_UNKNOWN;

		hr = WcaGetRecordString(hRec, QSO_TABLE, &pwzTable);
		ExitOnFailure(hr, "failed to get object table");

		// ensure we're looking at a known table
		if (0 == lstrcmpW(L"ServiceInstall", pwzTable))
		{
			eType = OT_SERVICE;
		}
		else if (0 == lstrcmpW(L"CreateFolder", pwzTable))
		{
			eType = OT_FOLDER;
		}
		else if (0 == lstrcmpW(L"File", pwzTable))
		{
			eType = OT_FILE;
		}
		else if (0 == lstrcmpW(L"Registry", pwzTable))
		{
			eType = OT_REGISTRY;
		}
		else
		{
			ExitOnFailure1(hr = E_INVALIDARG, "unknown SecureObject.Table: %S", pwzTable);
		}

		// if we haven't opened a view on the ServiceInstall/CreateFolder table, do that now
		if (OT_SERVICE == eType)
		{
			if (!hViewService)
			{
				hr = WcaTableExists(pwzTable);
				if (S_FALSE == hr)
					hr = E_UNEXPECTED;
				ExitOnFailure1(hr, "failed to open %s table to secure object", pwzTable);

				hr = WcaOpenView(wzQUERY_SERVICECOMPONENT, &hViewService);
				ExitOnFailure(hr, "failed to open view on ServiceInstall table");
			}

			hViewObject = hViewService;
		}
		else if (OT_FOLDER == eType)
		{
			if (!hViewCreateFolder)
			{
				hr = WcaTableExists(pwzTable);
				if (S_FALSE == hr)
					hr = E_UNEXPECTED;
				ExitOnFailure1(hr, "failed to open %s table to secure object", pwzTable);

				hr = WcaOpenView(wzQUERY_CREATEFOLDERCOMPONENT, &hViewCreateFolder);
				ExitOnFailure(hr, "failed to open view on CreateFolder table");
			}

			hViewObject = hViewCreateFolder;
		}
		else if (OT_FILE== eType)
		{
			if (!hViewFile)
			{
				hr = WcaTableExists(pwzTable);
				if (S_FALSE == hr)
					hr = E_UNEXPECTED;
				ExitOnFailure1(hr, "failed to open %s table to secure object", pwzTable);

				hr = WcaOpenView(wzQUERY_FILECOMPONENT, &hViewFile);
				ExitOnFailure(hr, "failed to open view on CreateFolder table");
			}

			hViewObject = hViewFile;
		}
		else if (OT_REGISTRY== eType)
		{
			if (!hViewRegistry)
			{
				hr = WcaTableExists(pwzTable);
				if (S_FALSE == hr)
					hr = E_UNEXPECTED;
				ExitOnFailure1(hr, "failed to open %s table to secure object", pwzTable);

				hr = WcaOpenView(wzQUERY_REGISTRYCOMPONENT, &hViewRegistry);
				ExitOnFailure(hr, "failed to open view on CreateFolder table");
			}

			hViewObject = hViewRegistry;
		}

		Assert(hViewObject);

		// execute a view looking for the object's Component_
		hr = WcaExecuteView(hViewObject, hRec);
		ExitOnFailure1(hr, "failed to execute view on %S table", pwzData);
		hr = WcaFetchSingleRecord(hViewObject, &hRecObject);
		ExitOnFailure(hr, "failed to fetch Component for secure object");

		hr = WcaGetRecordString(hRecObject, QSOC_COMPONENT, &pwzData);
		ExitOnFailure(hr, "failed to get Component name for secure object");

		//
		// if we are installing this Component
		//
		er = ::MsiGetComponentStateW(hInstall, pwzData, &isInstalled, &isAction);
		ExitOnFailure1(hr = HRESULT_FROM_WIN32(er), "failed to get install state for Component: %S", pwzData);

		if (WcaIsInstalling(isInstalled, isAction))
		{
			// add the data to the CustomActionData
			hr = WcaGetRecordString(hRecObject, QSOC_OBJECTNAME, &pwzData);
			ExitOnFailure(hr, "failed to get name of object");

			if (OT_SERVICE == eType)
			{
				hr = WcaWriteStringToCaData(pwzData, &pwzCustomActionData);
				ExitOnFailure(hr, "failed to add data to CustomActionData");
			}
			else if (OT_FOLDER == eType)
			{
				hr = WcaGetTargetPath(pwzData, &pwzTargetPath);
				ExitOnFailure1(hr, "failed to get target path for directory id: %S", pwzData);
				hr = WcaWriteStringToCaData(pwzTargetPath, &pwzCustomActionData);
				ExitOnFailure(hr, "failed to add data to CustomActionData");
			}
			else if (OT_FILE == eType)
			{
				hr = StrAllocFormatted(&pwzFormattedString, L"[#%s]", pwzData);
				ExitOnFailure1(hr, "failed to create formatted string for securing file object: %S", pwzData);

				hr = WcaGetFormattedString(pwzFormattedString, &pwzTargetPath);
				ExitOnFailure2(hr, "failed to get file path from formatted string: %S for secure object: %S", pwzFormattedString, pwzData);

				hr = WcaWriteStringToCaData(pwzTargetPath, &pwzCustomActionData);
				ExitOnFailure(hr, "failed to add data to CustomActionData");
			}
			else if (OT_REGISTRY == eType)
			{
				hr = WcaGetRecordInteger(hRecObject, QSOC_REGROOT, &iRoot);
				ExitOnFailure1(hr, "Failed to get reg key root for secure object: %S", pwzData);

				hr = WcaGetRecordFormattedString(hRecObject, QSOC_REGKEY, &pwzKey);
				ExitOnFailure1(hr, "Failed to get reg key for secure object: %S", pwzData);

				// Decode the root value
				if (-1 == iRoot)
				{
					// They didn't specify a root so that means it's either HKCU or HKLM depending on ALLUSERS property
					hr = WcaGetIntProperty(L"ALLUSERS", &iAllUsers);
					ExitOnFailure(hr, "failed to get value of ALLUSERS property");

					if (1 == iAllUsers)
					{
						hr = StrAllocString(&pwzTargetPath, L"MACHINE\\", 0);
						ExitOnFailure(hr, "failed to allocate target registry string with HKLM root");
					}
					else
					{
						hr = StrAllocString(&pwzTargetPath, L"CURRENT_USER\\", 0);
						ExitOnFailure(hr, "failed to allocate target registry string with HKCU root");
					}
				}
				else if (/*msidbRegistryRootClassesRoot*/ 0 == iRoot)
				{
					hr = StrAllocString(&pwzTargetPath, L"CLASSES_ROOT\\", 0);
					ExitOnFailure(hr, "failed to allocate target registry string with HKCR root");
				}
				else if (/*msidbRegistryRootCurrentUser*/ 1 == iRoot)
				{
					hr = StrAllocString(&pwzTargetPath, L"CURRENT_USER\\", 0);
					ExitOnFailure(hr, "failed to allocate target registry string with HKCU root");
				}
				else if (/*msidbRegistryRootLocalMachine*/ 2 == iRoot)
				{
					hr = StrAllocString(&pwzTargetPath, L"MACHINE\\", 0);
					ExitOnFailure(hr, "failed to allocate target registry string with HKLM root");
				}
				else if (/*msidbRegistryRootUsers*/ 3 == iRoot)
				{
					hr = StrAllocString(&pwzTargetPath, L"USERS\\", 0);
					ExitOnFailure(hr, "failed to allocate target registry string with HKU root");
				}
				else
				{
					ExitOnFailure2(hr = E_UNEXPECTED, "Unknown registry key root specified for secure object: '%S' root: %d", pwzData, iRoot);
				}

				hr = StrAllocConcat(&pwzTargetPath, pwzKey, 0);
				ExitOnFailure2(hr, "Failed to concat key: %S for secure object: %S", pwzKey, pwzData);

				hr = WcaWriteStringToCaData(pwzTargetPath, &pwzCustomActionData);
				ExitOnFailure(hr, "failed to add data to CustomActionData");
			}
			else
			{
				AssertSz(FALSE, "How did you get here?");
			}

			hr = WcaWriteStringToCaData(pwzTable, &pwzCustomActionData);
			ExitOnFailure(hr, "failed to add data to CustomActionData");

			hr = WcaGetRecordFormattedString(hRec, QSO_DOMAIN, &pwzData);
			ExitOnFailure(hr, "failed to get domain for user to configure object");
			hr = WcaWriteStringToCaData(pwzData, &pwzCustomActionData);
			ExitOnFailure(hr, "failed to add data to CustomActionData");

			hr = WcaGetRecordFormattedString(hRec, QSO_USER, &pwzData);
			ExitOnFailure(hr, "failed to get user to configure object");
			hr = WcaWriteStringToCaData(pwzData, &pwzCustomActionData);
			ExitOnFailure(hr, "failed to add data to CustomActionData");

			hr = WcaGetRecordString(hRec, QSO_PERMISSION, &pwzData);
			ExitOnFailure(hr, "failed to get domain for user to configure object");
			hr = WcaWriteStringToCaData(pwzData, &pwzCustomActionData);
			ExitOnFailure(hr, "failed to add data to CustomActionData");

			cObjects++;
		}
	}

	// 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");

	//
	// schedule the custom action and add to progress bar
	//
	if (pwzCustomActionData && *pwzCustomActionData)
	{
		Assert(0 < cObjects);

		hr = WcaDoDeferredAction(L"ExecSecureObjects", pwzCustomActionData, cObjects * COST_SECUREOBJECT);
		ExitOnFailure(hr, "failed to schedule ExecSecureObjects action");
	}

LExit:
	ReleaseStr(pwzCustomActionData);
	ReleaseStr(pwzData);
	ReleaseStr(pwzTable);
	ReleaseStr(pwzTargetPath);
	ReleaseStr(pwzFormattedString);
	ReleaseStr(pwzKey);

	if (FAILED(hr))
		er = ERROR_INSTALL_FAILURE;
	return WcaFinalize(er);
}
コード例 #8
0
ファイル: mspengine.cpp プロジェクト: firegiant/wix4
extern "C" HRESULT MspEngineExecutePackage(
    __in_opt HWND hwndParent,
    __in BURN_EXECUTE_ACTION* pExecuteAction,
    __in BURN_VARIABLES* pVariables,
    __in BOOL fRollback,
    __in PFN_MSIEXECUTEMESSAGEHANDLER pfnMessageHandler,
    __in LPVOID pvContext,
    __out BOOTSTRAPPER_APPLY_RESTART* pRestart
    )
{
    HRESULT hr = S_OK;
    INSTALLUILEVEL uiLevel = pExecuteAction->mspTarget.pPackage->Msp.fDisplayInternalUI ? INSTALLUILEVEL_DEFAULT : static_cast<INSTALLUILEVEL>(INSTALLUILEVEL_NONE | INSTALLUILEVEL_SOURCERESONLY);
    WIU_MSI_EXECUTE_CONTEXT context = { };
    WIU_RESTART restart = WIU_RESTART_NONE;

    LPWSTR sczCachedDirectory = NULL;
    LPWSTR sczMspPath = NULL;
    LPWSTR sczPatches = NULL;
    LPWSTR sczProperties = NULL;
    LPWSTR sczObfuscatedProperties = NULL;

    // default to "verbose" logging
    DWORD dwLogMode = WIU_LOG_DEFAULT | INSTALLLOGMODE_VERBOSE;

    // get cached MSP paths
    for (DWORD i = 0; i < pExecuteAction->mspTarget.cOrderedPatches; ++i)
    {
        LPCWSTR wzAppend = NULL;
        BURN_PACKAGE* pMspPackage = pExecuteAction->mspTarget.rgOrderedPatches[i].pPackage;
        AssertSz(BURN_PACKAGE_TYPE_MSP == pMspPackage->type, "Invalid package type added to ordered patches.");

        if (BOOTSTRAPPER_ACTION_STATE_INSTALL == pExecuteAction->mspTarget.action)
        {
            hr = CacheGetCompletedPath(pMspPackage->fPerMachine, pMspPackage->sczCacheId, &sczCachedDirectory);
            ExitOnFailure(hr, "Failed to get cached path for MSP package: %ls", pMspPackage->sczId);

            // Best effort to set the execute package cache folder variable.
            VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE);

            hr = PathConcat(sczCachedDirectory, pMspPackage->rgPayloads[0].pPayload->sczFilePath, &sczMspPath);
            ExitOnFailure(hr, "Failed to build MSP path.");

            wzAppend = sczMspPath;
        }
        else // uninstall
        {
            wzAppend = pMspPackage->Msp.sczPatchCode;
        }

        if (NULL != sczPatches)
        {
            hr = StrAllocConcat(&sczPatches, L";", 0);
            ExitOnFailure(hr, "Failed to semi-colon delimit patches.");
        }

        hr = StrAllocConcat(&sczPatches, wzAppend, 0);
        ExitOnFailure(hr, "Failed to append patch.");
    }

    // Wire up the external UI handler and logging.
    hr = WiuInitializeExternalUI(pfnMessageHandler, uiLevel, hwndParent, pvContext, fRollback, &context);
    ExitOnFailure(hr, "Failed to initialize external UI handler.");

    //if (BURN_LOGGING_LEVEL_DEBUG == logLevel)
    //{
    //    dwLogMode | INSTALLLOGMODE_EXTRADEBUG;
    //}

    if (pExecuteAction->mspTarget.sczLogPath && *pExecuteAction->mspTarget.sczLogPath)
    {
        hr = WiuEnableLog(dwLogMode, pExecuteAction->mspTarget.sczLogPath, 0);
        ExitOnFailure(hr, "Failed to enable logging for package: %ls to: %ls", pExecuteAction->mspTarget.pPackage->sczId, pExecuteAction->mspTarget.sczLogPath);
    }

    // set up properties
    hr = MsiEngineConcatProperties(pExecuteAction->mspTarget.pPackage->Msp.rgProperties, pExecuteAction->mspTarget.pPackage->Msp.cProperties, pVariables, fRollback, &sczProperties, FALSE);
    ExitOnFailure(hr, "Failed to add properties to argument string.");

    hr = MsiEngineConcatProperties(pExecuteAction->mspTarget.pPackage->Msp.rgProperties, pExecuteAction->mspTarget.pPackage->Msp.cProperties, pVariables, fRollback, &sczObfuscatedProperties, TRUE);
    ExitOnFailure(hr, "Failed to add properties to obfuscated argument string.");

    LogId(REPORT_STANDARD, MSG_APPLYING_PATCH_PACKAGE, pExecuteAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pExecuteAction->mspTarget.action), sczPatches, sczObfuscatedProperties, pExecuteAction->mspTarget.sczTargetProductCode);

    //
    // Do the actual action.
    //
    switch (pExecuteAction->mspTarget.action)
    {
    case BOOTSTRAPPER_ACTION_STATE_INSTALL: __fallthrough;
    case BOOTSTRAPPER_ACTION_STATE_REPAIR:
        hr = StrAllocConcatSecure(&sczProperties, L" PATCH=\"", 0);
        ExitOnFailure(hr, "Failed to add PATCH property on install.");

        hr = StrAllocConcatSecure(&sczProperties, sczPatches, 0);
        ExitOnFailure(hr, "Failed to add patches to PATCH property on install.");

        hr = StrAllocConcatSecure(&sczProperties, L"\" REBOOT=ReallySuppress", 0);
        ExitOnFailure(hr, "Failed to add reboot suppression property on install.");

        hr = WiuConfigureProductEx(pExecuteAction->mspTarget.sczTargetProductCode, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, sczProperties, &restart);
        ExitOnFailure(hr, "Failed to install MSP package.");
        break;

    case BOOTSTRAPPER_ACTION_STATE_UNINSTALL:
        hr = StrAllocConcatSecure(&sczProperties, L" REBOOT=ReallySuppress", 0);
        ExitOnFailure(hr, "Failed to add reboot suppression property on uninstall.");

        // Ignore all dependencies, since the Burn engine already performed the check.
        hr = StrAllocFormattedSecure(&sczProperties, L"%ls %ls=ALL", sczProperties, DEPENDENCY_IGNOREDEPENDENCIES);
        ExitOnFailure(hr, "Failed to add the list of dependencies to ignore to the properties.");

        hr = WiuRemovePatches(sczPatches, pExecuteAction->mspTarget.sczTargetProductCode, sczProperties, &restart);
        ExitOnFailure(hr, "Failed to uninstall MSP package.");
        break;
    }

LExit:
    WiuUninitializeExternalUI(&context);

    ReleaseStr(sczCachedDirectory);
    ReleaseStr(sczMspPath);
    StrSecureZeroFreeString(sczProperties);
    ReleaseStr(sczObfuscatedProperties);
    ReleaseStr(sczPatches);

    switch (restart)
    {
        case WIU_RESTART_NONE:
            *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
            break;

        case WIU_RESTART_REQUIRED:
            *pRestart = BOOTSTRAPPER_APPLY_RESTART_REQUIRED;
            break;

        case WIU_RESTART_INITIATED:
            *pRestart = BOOTSTRAPPER_APPLY_RESTART_INITIATED;
            break;
    }

    // Best effort to clear the execute package cache folder variable.
    VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, NULL, TRUE);

    return hr;
}
コード例 #9
0
ファイル: scaweberr.cpp プロジェクト: 925coder/wix3
HRESULT ScaWriteWebError(IMSAdminBase* piMetabase, int iParentType, LPCWSTR wzRoot, SCA_WEB_ERROR* psweList)
{
//    AssertSz(0, "Debug ScaWriteWebError here");
    Assert(*wzRoot && psweList);

    HRESULT hr = S_OK;

    DWORD cchData = 0;
    LPWSTR pwzSearchKey = NULL;
    LPWSTR pwz = NULL;
    LPWSTR pwzErrors = NULL;

    LPWSTR pwzCodeSubCode = NULL;
    LPWSTR pwzAcceptableCodeSubCode = NULL;
    LPCWSTR wzFoundCodeSubCode = NULL;
    DWORD_PTR dwFoundCodeSubCodeIndex = 0xFFFFFFFF;
    BOOL fOldValueFound = FALSE;
    LPWSTR pwzAcceptableErrors = NULL;

    LPWSTR pwzNewError = NULL;

    METADATA_RECORD mr;
    ::ZeroMemory(&mr, sizeof(mr));

    ExitOnNull(piMetabase, hr, E_INVALIDARG, "Failed to write web error, because no metabase was provided");
    ExitOnNull(wzRoot, hr, E_INVALIDARG, "Failed to write web error, because no root was provided");

    // get the set of all valid custom errors from the metabase
    mr.dwMDIdentifier = MD_CUSTOM_ERROR_DESC;
    mr.dwMDAttributes = METADATA_INHERIT;
    mr.dwMDUserType = IIS_MD_UT_SERVER;
    mr.dwMDDataType = ALL_METADATA;
    mr.dwMDDataLen = cchData = 0;
    mr.pbMDData = NULL;

    hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, L"/LM/W3SVC/Info", &mr);
    ExitOnFailure(hr, "Unable to get set of acceptable error codes for this server.");

    pwzAcceptableErrors = reinterpret_cast<LPWSTR>(mr.pbMDData);

    // Check if web errors already exist here
    mr.dwMDIdentifier = MD_CUSTOM_ERROR;
    mr.dwMDAttributes = METADATA_INHERIT;
    mr.dwMDUserType = IIS_MD_UT_SERVER;
    mr.dwMDDataType = ALL_METADATA;
    mr.dwMDDataLen = cchData = 0;
    mr.pbMDData = NULL;

    hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, wzRoot, &mr);
    if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr)
    {
        //
        // If we don't have one already, find an appropriate one to start with
        //

        // we can walk up key by key and look for custom errors to inherit

        hr = StrAllocConcat(&pwzSearchKey, wzRoot, 0);
        ExitOnFailure1(hr, "Failed to copy root string: %ls", wzRoot);

        pwz = pwzSearchKey + lstrlenW(pwzSearchKey);

        while (NULL == pwzErrors)
        {
            // find the last slash
            while (*pwz != '/' && pwz != pwzSearchKey)
                pwz --;

            if (pwz == pwzSearchKey)
                break;

            *pwz = L'\0';

            // Try here.  If it's not found, keep walking up the path
            hr = MetaGetValue(piMetabase, METADATA_MASTER_ROOT_HANDLE, pwzSearchKey, &mr);
            if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr || MD_ERROR_DATA_NOT_FOUND == hr)
                hr = S_FALSE;
            ExitOnFailure1(hr, "failed to discover default error values to start with for web root: %ls while walking up the tree", wzRoot);

            if (S_OK == hr)
            {
                pwzErrors = reinterpret_cast<LPWSTR>(mr.pbMDData);
                break;
            }

            // Don't keep going if we're at the root
            if (0 == lstrcmpW(pwz + 1, L"W3SVC"))
                break;
        }
    }
    else
    {
        pwzErrors = reinterpret_cast<LPWSTR>(mr.pbMDData);
    }
    ExitOnFailure1(hr, "failed to discover default error values to start with for web root: %ls", wzRoot);

    // The above code should have come up with some value to start pwzErrors off with.  Make sure it did.
    if (NULL == pwzErrors)
    {
        ExitOnFailure1(hr = E_UNEXPECTED, "failed to discover default error values to start with for web root: %ls", wzRoot);
    }

    // Loop through the web errors
    for (SCA_WEB_ERROR* pswe = psweList; pswe; pswe = pswe->psweNext)
    {
        // Assume that we will have to replace 
        fOldValueFound = TRUE;

        // If the subcode is 0, that means "*" in MD_CUSTOM_ERROR (thus the special formatting logic)
        if (0 == pswe->iSubCode)
        {
            hr = StrAllocFormatted(&pwzCodeSubCode, L"%d,*", pswe->iErrorCode);
            ExitOnFailure(hr, "failed to create error code string while installing web error");
        }
        else
        {
            hr = StrAllocFormatted(&pwzCodeSubCode, L"%d,%d", pswe->iErrorCode, pswe->iSubCode);
            ExitOnFailure(hr, "failed to create error code,subcode string while installing web error");
        }

        hr = MultiSzFindSubstring(pwzErrors, pwzCodeSubCode, &dwFoundCodeSubCodeIndex, &wzFoundCodeSubCode);
        ExitOnFailure1(hr, "failed to find existing error code,subcode: %ls", pwzCodeSubCode);

        // If we didn't find this error code/sub code pair in the list already, make sure it's acceptable to add
        if (S_FALSE == hr)
        {
            //
            // Make sure this error code/sub code pair is in the "acceptable" list
            //

            // If the subcode is 0, that means "0" in MD_CUSTOM_ERROR_DESC (no special formatting logic needed)
            hr = StrAllocFormatted(&pwzAcceptableCodeSubCode, L"%d,%d", pswe->iErrorCode, pswe->iSubCode);
            ExitOnFailure(hr, "failed to create error code,subcode string while installing web error");

            // We don't care where it is, just whether it's there or not
            hr = MultiSzFindSubstring(pwzAcceptableErrors, pwzAcceptableCodeSubCode, NULL, NULL);
            ExitOnFailure1(hr, "failed to find whether or not error code, subcode: %ls is supported", pwzCodeSubCode);

            if (S_FALSE == hr)
            {
                WcaLog(LOGMSG_VERBOSE, "Skipping error code, subcode: %ls because it is not supported by the server.", pwzCodeSubCode);
                continue;
            }

            // If we didn't find it (and its an acceptable error) then we have nothing to replace
            fOldValueFound = FALSE;
        }

        // Set up the new error string if needed
        if (*(pswe->wzFile))
        {
            hr = StrAllocFormatted(&pwzNewError, L"%s,FILE,%s", pwzCodeSubCode, pswe->wzFile);
            ExitOnFailure2(hr, "failed to create new error code string with code,subcode: %ls, file: %ls", pwzCodeSubCode, pswe->wzFile);
        }
        else if (*(pswe->wzURL))
        {
            hr = StrAllocFormatted(&pwzNewError, L"%s,URL,%s", pwzCodeSubCode, pswe->wzURL);
            ExitOnFailure2(hr, "failed to create new error code string with code,subcode: %ls, file: %ls", pwzCodeSubCode, pswe->wzFile);
        }
        else if (fOldValueFound)
        {
            // If no File or URL was specified, they want a default error so remove the old value from the MULTISZ and move on
            hr = MultiSzRemoveString(&pwzErrors, dwFoundCodeSubCodeIndex);
            ExitOnFailure1(hr, "failed to remove string for error code sub code: %ls in order to make it 'default'", pwzCodeSubCode);
            continue;
        }

        // If we have something to replace, replace it, otherwise, put it at the beginning (order shouldn't matter)
        if (fOldValueFound)
        {
            hr = MultiSzReplaceString(&pwzErrors, dwFoundCodeSubCodeIndex, pwzNewError);
            ExitOnFailure1(hr, "failed to replace old error string with new error string for error code,subcode: %ls", pwzCodeSubCode);
        }
        else
        {
            hr = MultiSzPrepend(&pwzErrors, NULL, pwzNewError);
            ExitOnFailure1(hr, "failed to prepend new error string for error code,subcode: %ls", pwzCodeSubCode);
        }
    }

    // now write the CustomErrors to the metabase
    if (weptWeb == iParentType)
    {
        hr = ScaWriteMetabaseValue(piMetabase, wzRoot, L"/Root", MD_CUSTOM_ERROR, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, pwzErrors);
        ExitOnFailure(hr, "Failed to write Web Error to /Root");
    }
    else
    {
        hr = ScaWriteMetabaseValue(piMetabase, wzRoot, NULL, MD_CUSTOM_ERROR, METADATA_INHERIT, IIS_MD_UT_FILE, MULTISZ_METADATA, pwzErrors);
        ExitOnFailure(hr, "Failed to write Web Error");
    }

LExit:
    ReleaseStr(pwzErrors);
    ReleaseStr(pwzSearchKey);
    ReleaseStr(pwzCodeSubCode);
    ReleaseStr(pwzAcceptableCodeSubCode);
    ReleaseStr(pwzAcceptableErrors);

    return hr;
}
コード例 #10
0
ファイル: msuengine.cpp プロジェクト: AnalogJ/Wix3.6Toolset
extern "C" HRESULT MsuEngineExecutePackage(
    __in BURN_EXECUTE_ACTION* pExecuteAction,
    __in BOOL fRollback,
    __in PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler,
    __in LPVOID pvContext,
    __out BOOTSTRAPPER_APPLY_RESTART* pRestart
    )
{
    HRESULT hr = S_OK;
    int nResult = IDNOACTION;
    LPWSTR sczCachedDirectory = NULL;
    LPWSTR sczMsuPath = NULL;
    LPWSTR sczSystemPath = NULL;
    LPWSTR sczWusaPath = NULL;
    LPWSTR sczCommand = NULL;
    SC_HANDLE schWu = NULL;
    BOOL fWuWasDisabled = FALSE;
    STARTUPINFOW si = { };
    PROCESS_INFORMATION pi = { };
    GENERIC_EXECUTE_MESSAGE message = { };
    DWORD dwExitCode = 0;
    BOOL fDoDependency = FALSE;

    // get wusa.exe path
    hr = PathGetKnownFolder(CSIDL_SYSTEM, &sczSystemPath);
    ExitOnFailure(hr, "Failed to find System32 directory.");

    hr = PathConcat(sczSystemPath, L"wusa.exe", &sczWusaPath);
    ExitOnFailure(hr, "Failed to allocate WUSA.exe path.");

    // build command
    switch (pExecuteAction->msuPackage.action)
    {
    case BOOTSTRAPPER_ACTION_STATE_INSTALL:
        // get cached executable path
        hr = CacheGetCompletedPath(TRUE, pExecuteAction->msuPackage.pPackage->sczCacheId, &sczCachedDirectory);
        ExitOnFailure1(hr, "Failed to get cached path for package: %ls", pExecuteAction->msuPackage.pPackage->sczId);

        hr = PathConcat(sczCachedDirectory, pExecuteAction->msuPackage.pPackage->rgPayloads[0].pPayload->sczFilePath, &sczMsuPath);
        ExitOnFailure(hr, "Failed to build executable path.");

        // format command
        hr = StrAllocFormatted(&sczCommand, L"\"%ls\" \"%ls\" /quiet /norestart", sczWusaPath, sczMsuPath);
        ExitOnFailure(hr, "Failed to format MSU install command.");
        break;

    case BOOTSTRAPPER_ACTION_STATE_UNINSTALL:
        // format command
        hr = StrAllocFormatted(&sczCommand, L"\"%ls\" /uninstall /kb:%ls /quiet /norestart", sczWusaPath, pExecuteAction->msuPackage.pPackage->Msu.sczKB);
        ExitOnFailure(hr, "Failed to format MSU uninstall command.");
        break;

    default:
        hr = E_UNEXPECTED;
        ExitOnFailure(hr, "Failed to get action arguments for MSU package.");
    }

    if (pExecuteAction->msuPackage.sczLogPath && *pExecuteAction->msuPackage.sczLogPath)
    {
        hr = StrAllocConcat(&sczCommand, L" /log:", 0);
        ExitOnFailure(hr, "Failed to append log switch to MSU command-line.");

        hr = StrAllocConcat(&sczCommand, pExecuteAction->msuPackage.sczLogPath, 0);
        ExitOnFailure(hr, "Failed to append log path to MSU command-line.");
    }

    LogId(REPORT_STANDARD, MSG_APPLYING_PACKAGE, LoggingRollbackOrExecute(fRollback), pExecuteAction->msuPackage.pPackage->sczId, LoggingActionStateToString(pExecuteAction->msuPackage.action), sczMsuPath ? sczMsuPath : pExecuteAction->msuPackage.pPackage->Msu.sczKB, sczCommand);

    hr = EnsureWUServiceEnabled(&schWu, &fWuWasDisabled);
    ExitOnFailure(hr, "Failed to ensure WU service was enabled to install MSU package.");

    // create process
    si.cb = sizeof(si);
    if (!::CreateProcessW(sczWusaPath, sczCommand, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi))
    {
        ExitWithLastError1(hr, "Failed to CreateProcess on path: %ls", sczWusaPath);
    }

    do
    {
        message.type = GENERIC_EXECUTE_MESSAGE_PROGRESS;
        message.dwAllowedResults = MB_OKCANCEL;
        message.progress.dwPercentage = 50;
        nResult = pfnGenericMessageHandler(&message, pvContext);
        hr = (IDOK == nResult || IDNOACTION == nResult) ? S_OK : IDCANCEL == nResult ? HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) : HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE);
        ExitOnRootFailure(hr, "Bootstrapper application aborted during MSU progress.");

        // wait for process to terminate
        hr = ProcWaitForCompletion(pi.hProcess, 500, &dwExitCode);
        if (HRESULT_FROM_WIN32(WAIT_TIMEOUT) != hr)
        {
            ExitOnFailure1(hr, "Failed to wait for executable to complete: %ls", sczWusaPath);
        }
    } while (HRESULT_FROM_WIN32(WAIT_TIMEOUT) == hr);

    // get process exit code
    if (!::GetExitCodeProcess(pi.hProcess, &dwExitCode))
    {
        ExitWithLastError(hr, "Failed to get process exit code.");
    }

    // We'll normalize the restart required error code from wusa.exe just in case. Most likely
    // that on reboot we'll actually get WU_S_REBOOT_REQUIRED.
    if (HRESULT_FROM_WIN32(ERROR_SUCCESS_REBOOT_REQUIRED) == static_cast<HRESULT>(dwExitCode))
    {
        dwExitCode = ERROR_SUCCESS_REBOOT_REQUIRED;
    }

    // handle exit code
    switch (dwExitCode)
    {
    case S_OK: __fallthrough;
    case WU_S_ALREADY_INSTALLED:
        fDoDependency = TRUE;
        __fallthrough;
    case S_FALSE: __fallthrough;
    case WU_E_NOT_APPLICABLE:
        *pRestart = BOOTSTRAPPER_APPLY_RESTART_NONE;
        hr = S_OK;
        break;

    case ERROR_SUCCESS_REBOOT_REQUIRED: __fallthrough;
    case WU_S_REBOOT_REQUIRED:
        fDoDependency = TRUE;
        *pRestart = BOOTSTRAPPER_APPLY_RESTART_REQUIRED;
        hr = S_OK;
        break;

    default:
        hr = E_UNEXPECTED;
        break;
    }

    if (fDoDependency)
    {
        if (BOOTSTRAPPER_ACTION_STATE_INSTALL == pExecuteAction->msuPackage.action)
        {
            hr = DependencyRegisterPackage(pExecuteAction->msuPackage.pPackage);
            ExitOnFailure(hr, "Failed to register the package dependency providers.");
        }
        else if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pExecuteAction->msuPackage.action)
        {
            hr = DependencyUnregisterPackage(pExecuteAction->msuPackage.pPackage);
            ExitOnFailure(hr, "Failed to unregister the package dependency providers.");
        }
    }

LExit:
    ReleaseStr(sczCachedDirectory);
    ReleaseStr(sczMsuPath);
    ReleaseStr(sczSystemPath);
    ReleaseStr(sczWusaPath);
    ReleaseStr(sczCommand);

    ReleaseHandle(pi.hProcess);
    ReleaseHandle(pi.hThread);

    if (fWuWasDisabled)
    {
        SetServiceStartType(schWu, SERVICE_DISABLED);
    }

    return hr;
}
コード例 #11
0
ファイル: updateexe.cpp プロジェクト: FernandoNunes/wix3
int __cdecl wmain(
    __in int argc,
    __in WCHAR * argv[]
    )
{
    HRESULT hr = S_OK;
    LPWSTR pwzCommandLine = NULL;

    LPWSTR wzAppId = NULL;
    GUID guidApp;

    DWORD64 dw64Version;
    LPWSTR pwzFeedUri = NULL;
    LPWSTR pwzApplicationPath = NULL;
    LPWSTR pwzApplicationDirectory = NULL;

    DWORD64 dw64NextUpdateTime = 0;
    BOOL fUpdateReady = FALSE;
    DWORD64 dw64UpdateVersion = 0;
    LPWSTR pwzFeedPath = NULL;
    LPWSTR pwzSetupPath = NULL;

    DWORD dwTimeToLive = 0;
    LPWSTR pwzApplicationId = NULL;
    LPWSTR pwzApplicationSource = NULL;

    BOOL bDeleteUpdateInfoPath = FALSE;
    BOOL bDeleteUpdateBinaryPath = FALSE;
    HANDLE hProcess = INVALID_HANDLE_VALUE;
    HANDLE hUpdateMutex = INVALID_HANDLE_VALUE;

    //
    // Process command-line arguments.
    //
    for (int i=1; i<argc; i++)
    {
        if (argv[i][0] == L'-' || argv[i][0] == L'/')
        {
            if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"ac", -1))
            {
                if (wzAppId)
                {
                    ExitOnFailure(hr = E_INVALIDARG, "May only specify one -ac switch.");
                }

                wzAppId = argv[++i];
                hr = ::CLSIDFromString(wzAppId, &guidApp);
                ExitOnFailure(hr, "Failed to parse the -ac argument.");
            }
        }
        else
        {
            ExitOnFailure1(hr = E_INVALIDARG, "Bad commandline argument: %S", argv[i]);
        }
    }
    ExitOnNull(wzAppId, hr, E_INVALIDARG, "Must specify a -ac switch.");

    hr = GetUpdateMutex(&guidApp, &hUpdateMutex);
    if (FAILED(hr))
    {
        TraceError(hr, "Failed to query the update mutex.  Proceeding as if this process didn't acquire the mutex.");
    }

    hr = RssUpdateGetAppInfo(wzAppId, &dw64Version, &pwzFeedUri, &pwzApplicationPath);
    ExitOnFailure(hr, "Failed to get app info.");

    // If we acquired the update lock and there is already an update downloaded, install that now.
    if (INVALID_HANDLE_VALUE != hUpdateMutex)
    {
        Trace(REPORT_DEBUG, "Got the update mutex.  Will check for updates on local machine before launching app.");

        // If an update is available and higher version that the application currently on the local 
        // machine, launch the install and bail.
        hr = RssUpdateTryLaunchUpdate(wzAppId, dw64Version, &hProcess, &dw64NextUpdateTime);
        if (SUCCEEDED(hr))
        {
            if (hProcess)
            {
                ::CloseHandle(hProcess);
                ExitFunction(); // bail since we're doing an update
            }
        }
    }
    else
    {
        Trace(REPORT_DEBUG, "Didn't get the update mutex.  Won't check for updates.");
    }

    hr = PathExpand(&pwzCommandLine, pwzApplicationPath, PATH_EXPAND_FULLPATH);
    ExitOnFailure(hr, "Failed to expand application path.");

    if (pwzCommandLine && L'\"' != pwzCommandLine[0])
    {
        // Get the working directory.
        hr = PathGetDirectory(pwzCommandLine, &pwzApplicationDirectory);
        ExitOnFailure(hr, "Failed to get application directory from command-line.");

        // Put quotes around the command line.
        hr = StrAllocPrefix(&pwzCommandLine, L"\"", 0);
        ExitOnFailure(hr, "Failed to prefix command-line with quote.");

        hr = StrAllocConcat(&pwzCommandLine, L"\"", 0);
        ExitOnFailure(hr, "Failed to concat command-line with quote.");
    }

    Trace1(REPORT_DEBUG, "Launching the target app with commandline: %ls.", pwzCommandLine);
    hr = LaunchTarget(pwzCommandLine, pwzApplicationDirectory, &hProcess);
    ExitOnFailure1(hr, "Failed to launch %ls", pwzCommandLine);

    // If we acquired the update lock then check to see if enough time has passed such that we look for more updates.
    if (INVALID_HANDLE_VALUE != hUpdateMutex)
    {
        hr = RssUpdateCheckFeed(wzAppId, dw64Version, pwzFeedUri, dw64NextUpdateTime);

        hr = S_OK;
    }

LExit:
    if (INVALID_HANDLE_VALUE != hUpdateMutex)
    {
        ::CloseHandle(hUpdateMutex);
    }

    if (INVALID_HANDLE_VALUE != hProcess)
    {
        ::CloseHandle(hProcess);
    }

    if (bDeleteUpdateInfoPath)
    {
        ::DeleteFileW(pwzFeedPath);
    }

    if (bDeleteUpdateBinaryPath)
    {
        ::DeleteFileW(pwzSetupPath);
    }

    ReleaseStr(pwzApplicationSource);
    ReleaseStr(pwzApplicationId);
    ReleaseStr(pwzSetupPath);
    ReleaseStr(pwzFeedPath);
    ReleaseStr(pwzApplicationPath);
    ReleaseStr(pwzFeedUri);
    ReleaseStr(pwzCommandLine);
    ReleaseStr(pwzApplicationDirectory);

    return SCODE_CODE(hr);
}
コード例 #12
0
ファイル: appsynup.cpp プロジェクト: AnalogJ/Wix3.6Toolset
HRESULT RssUpdateGetUpdateInfo(
    __in LPCWSTR wzApplicationId,
    __out_opt DWORD64* pdw64NextUpdate,
    __out_opt BOOL* pfUpdateReady,
    __out_opt DWORD64* pdw64UpdateVersion,
    __out_opt LPWSTR* ppwzLocalFeedPath,
    __out_opt LPWSTR* ppwzLocalSetupPath
    )
{
    HRESULT hr = S_OK;
    LPWSTR pwzUpdateInfoPath = NULL;
    HANDLE hFile = INVALID_HANDLE_VALUE;

    DWORD dwRead = 0;
    DWORD dwExpected = 0;
    DWORD64 dw64NextUpdate = 0;
    DWORD64 dw64UpdateVersion = 0;
    BOOL fUpdateReady = TRUE;
    WCHAR wzBuffer[1024 * 64];
    LPWSTR pwzLocalFeedPath = NULL;
    LPWSTR pwzLocalSetupPath = NULL;

    hr = GetUpdateInfoFileName(wzApplicationId, &pwzUpdateInfoPath);
    ExitOnFailure(hr, "Failed to allocate path to update info.");

    hFile = ::CreateFileW(pwzUpdateInfoPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (INVALID_HANDLE_VALUE == hFile)
    {
        ExitWithLastError(hr, "Failed to open update info.");
    }

    dwExpected = sizeof(dw64NextUpdate);
    if (!::ReadFile(hFile, &dw64NextUpdate, dwExpected, &dwRead, NULL))
    {
        ExitWithLastError(hr, "Failed to read next update time from update info.");
    }
    else if (dwExpected != dwRead)
    {
        hr = E_UNEXPECTED;
        ExitOnFailure(hr, "Failed to find next update time at beginning of update info.");
    }

    dwExpected = sizeof(dw64UpdateVersion);
    if (!::ReadFile(hFile, &dw64UpdateVersion, dwExpected, &dwRead, NULL))
    {
        ExitWithLastError(hr, "Failed to read update version from update info.");
    }
    else if (0 == dwRead) // no other update information
    {
        fUpdateReady = FALSE;
    }
    else if (dwExpected != dwRead)
    {
        hr = E_UNEXPECTED;
        ExitOnFailure(hr, "Failed to find update version in update info.");
    }

    if (fUpdateReady)
    {
        dwExpected = sizeof(WCHAR) * 2;
        if (!::ReadFile(hFile, wzBuffer, dwExpected, &dwRead, NULL))
        {
            ExitWithLastError(hr, "Failed to read newline after next update time in update info.");
        }
        else if (dwExpected != dwRead || wzBuffer[0] != L'\r' || wzBuffer[1] != L'\n')
        {
            hr = E_UNEXPECTED;
            ExitOnFailure(hr, "Failed to find newline after next update time in update info.");
        }

        LPWSTR pwcCrLn = NULL;
        do
        {
            dwExpected = sizeof(wzBuffer) - sizeof(WCHAR); // leave space to null terminate the buffer
            if (!::ReadFile(hFile, wzBuffer, dwExpected, &dwRead, NULL))
            {
                ExitWithLastError(hr, "Failed to read buffer in update info.");
            }
            else if (0 == dwRead)
            {
                break;
            }

            Assert(dwRead / sizeof(WCHAR) < countof(wzBuffer));
            wzBuffer[dwRead / sizeof(WCHAR)] = L'\0';

            pwcCrLn = wcsstr(wzBuffer, L"\r\n");
            if (pwcCrLn)
            {
                *pwcCrLn = L'\0';

                hr = StrAllocConcat(&pwzLocalFeedPath, wzBuffer, 0);
                ExitOnFailure(hr, "Failed to copy buffer into feed path.");

                pwcCrLn += 2;
                if (*pwcCrLn)
                {
                    hr = StrAllocString(&pwzLocalSetupPath, pwcCrLn, 0);
                    ExitOnFailure(hr, "Failed to copy remaining buffer into setup path.");
                }
            }
            else
            {
                hr = StrAllocConcat(&pwzLocalFeedPath, wzBuffer, 0);
                ExitOnFailure(hr, "Failed to copy buffer into feed path.");
            }
        } while (!pwcCrLn);

        do
        {
            dwExpected = sizeof(wzBuffer) - sizeof(WCHAR); // leave space to null terminate the buffer
            if (!::ReadFile(hFile, wzBuffer, dwExpected, &dwRead, NULL))
            {
                ExitWithLastError(hr, "Failed to read buffer in update info.");
            }
            else if (0 == dwRead)
            {
                break;
            }

            Assert(dwRead / sizeof(WCHAR) < countof(wzBuffer));
            wzBuffer[dwRead / sizeof(WCHAR)] = L'\0';

            hr = StrAllocConcat(&pwzLocalSetupPath, wzBuffer, 0);
            ExitOnFailure(hr, "Failed to copy buffer into setup path.");
        } while (0 < dwRead);

        if (!pwzLocalSetupPath)
        {
            hr = E_UNEXPECTED;
            ExitOnFailure(hr, "Failed to parse update info.");
        }
    }

    if (pfUpdateReady)
    {
        *pfUpdateReady = fUpdateReady;
    }

    if (pdw64NextUpdate)
    {
        *pdw64NextUpdate = dw64NextUpdate;
    }

    if (fUpdateReady && pdw64UpdateVersion)
    {
        *pdw64UpdateVersion = dw64UpdateVersion;
    }

    if (fUpdateReady && ppwzLocalFeedPath)
    {
        hr = StrAllocString(ppwzLocalFeedPath, pwzLocalFeedPath, 0);
        ExitOnFailure(hr, "Failed to allocate local feed path.");
    }

    if (fUpdateReady && ppwzLocalSetupPath)
    {
        hr = StrAllocString(ppwzLocalSetupPath, pwzLocalSetupPath, 0);
        ExitOnFailure(hr, "Failed to allocate local setup path.");
    }

LExit:
    ReleaseStr(pwzLocalSetupPath);
    ReleaseStr(pwzLocalFeedPath);
    ReleaseFile(hFile);
    ReleaseStr(pwzUpdateInfoPath);
    return hr;
}
コード例 #13
0
ファイル: jsonutil.cpp プロジェクト: AnalogJ/Wix3.6Toolset
static HRESULT DoStart(
    __in JSON_WRITER* pWriter,
    __in JSON_TOKEN tokenStart,
    __in_z LPCWSTR wzStartString
    )
{
    Assert(JSON_TOKEN_ARRAY_START == tokenStart || JSON_TOKEN_OBJECT_START == tokenStart);

    HRESULT hr = S_OK;
    JSON_TOKEN token = JSON_TOKEN_NONE;
    BOOL fNeedComma = FALSE;
    BOOL fPushToken = TRUE;

    ::EnterCriticalSection(&pWriter->cs);

    hr = EnsureTokenStack(pWriter);
    ExitOnFailure(hr, "Failed to ensure token stack for start.");

    token = pWriter->rgTokenStack[pWriter->cTokens - 1];
    switch (token)
    {
    case JSON_TOKEN_NONE:
        token = tokenStart;
        fPushToken = FALSE;
        break;

    case JSON_TOKEN_ARRAY_START: // array start changes to array value.
        token = JSON_TOKEN_ARRAY_VALUE;
        break;

    case JSON_TOKEN_ARRAY_VALUE:
    case JSON_TOKEN_ARRAY_END:
    case JSON_TOKEN_OBJECT_END:
        fNeedComma = TRUE;
        break;

    default: // everything else is not allowed.
        hr = E_UNEXPECTED;
        break;
    }
    ExitOnRootFailure(hr, "Cannot start array or object to JSON serializer now.");

    if (fNeedComma)
    {
        hr = StrAllocConcat(&pWriter->sczJson, L",", 0);
        ExitOnFailure(hr, "Failed to add comma for start array or object to JSON.");
    }

    hr = StrAllocConcat(&pWriter->sczJson, wzStartString, 0);
    ExitOnFailure(hr, "Failed to start JSON array or object.");

    pWriter->rgTokenStack[pWriter->cTokens - 1] = token;
    if (fPushToken)
    {
        pWriter->rgTokenStack[pWriter->cTokens] = tokenStart;
        ++pWriter->cTokens;
    }

LExit:
    ::LeaveCriticalSection(&pWriter->cs);
    return hr;
}
コード例 #14
0
ファイル: secureobj.cpp プロジェクト: BMurri/wix3
static HRESULT GetTargetPath(
    __in eOBJECTTYPE eType,
    __in LPCWSTR pwzSecureObject,
    __out LPWSTR* ppwzTargetPath
    )
{
    HRESULT hr = S_OK;

    PMSIHANDLE hView = NULL;
    PMSIHANDLE hRecObject = NULL;
    PMSIHANDLE hRec = NULL;

    int iRoot = 0;
    int iAllUsers = 0;
    LPWSTR pwzKey = NULL;
    LPWSTR pwzFormattedString = NULL;

    if (OT_SERVICE == eType)
    {
        hr = WcaTableExists(L"ServiceInstall");
        if (S_FALSE == hr)
        {
            hr = E_UNEXPECTED;
        }
        ExitOnFailure(hr, "failed to open ServiceInstall table to secure object");

        hr = WcaOpenView(wzQUERY_SERVICEINSTALL, &hView);
        ExitOnFailure(hr, "failed to open view on ServiceInstall table");

        // create a record that stores the object to secure
        hRec = MsiCreateRecord(1);
        MsiRecordSetStringW(hRec, 1, pwzSecureObject);

        // execute a view looking for the object's ServiceInstall.ServiceInstall row.
        hr = WcaExecuteView(hView, hRec);
        ExitOnFailure(hr, "failed to execute view on ServiceInstall table");
        hr = WcaFetchSingleRecord(hView, &hRecObject);
        ExitOnFailure(hr, "failed to fetch ServiceInstall row for secure object");

        hr = WcaGetRecordFormattedString(hRecObject, QSSI_NAME, ppwzTargetPath);
        ExitOnFailure1(hr, "failed to get service name for secure object: %ls", pwzSecureObject);
    }
    else if (OT_FOLDER == eType)
    {
        hr = WcaGetTargetPath(pwzSecureObject, ppwzTargetPath);
        ExitOnFailure1(hr, "failed to get target path for directory id: %ls", pwzSecureObject);
    }
    else if (OT_FILE == eType)
    {
        hr = StrAllocFormatted(&pwzFormattedString, L"[#%s]", pwzSecureObject);
        ExitOnFailure1(hr, "failed to create formatted string for securing file object: %ls", pwzSecureObject);

        hr = WcaGetFormattedString(pwzFormattedString, ppwzTargetPath);
        ExitOnFailure2(hr, "failed to get file path from formatted string: %ls for secure object: %ls", pwzFormattedString, pwzSecureObject);
    }
    else if (OT_REGISTRY == eType)
    {
        hr = WcaTableExists(L"Registry");
        if (S_FALSE == hr)
        {
            hr = E_UNEXPECTED;
        }
        ExitOnFailure(hr, "failed to open Registry table to secure object");

        hr = WcaOpenView(wzQUERY_REGISTRY, &hView);
        ExitOnFailure(hr, "failed to open view on Registry table");

        // create a record that stores the object to secure
        hRec = MsiCreateRecord(1);
        MsiRecordSetStringW(hRec, 1, pwzSecureObject);

        // execute a view looking for the object's Registry row
        hr = WcaExecuteView(hView, hRec);
        ExitOnFailure(hr, "failed to execute view on Registry table");
        hr = WcaFetchSingleRecord(hView, &hRecObject);
        ExitOnFailure(hr, "failed to fetch Registry row for secure object");

        hr = WcaGetRecordInteger(hRecObject, QSOC_REGROOT, &iRoot);
        ExitOnFailure1(hr, "Failed to get reg key root for secure object: %ls", pwzSecureObject);

        hr = WcaGetRecordFormattedString(hRecObject, QSOC_REGKEY, &pwzKey);
        ExitOnFailure1(hr, "Failed to get reg key for secure object: %ls", pwzSecureObject);

        // Decode the root value
        if (-1 == iRoot)
        {
            // They didn't specify a root so that means it's either HKCU or HKLM depending on ALLUSERS property
            hr = WcaGetIntProperty(L"ALLUSERS", &iAllUsers);
            ExitOnFailure(hr, "failed to get value of ALLUSERS property");

            if (1 == iAllUsers)
            {
                hr = StrAllocString(ppwzTargetPath, L"MACHINE\\", 0);
                ExitOnFailure(hr, "failed to allocate target registry string with HKLM root");
            }
            else
            {
                hr = StrAllocString(ppwzTargetPath, L"CURRENT_USER\\", 0);
                ExitOnFailure(hr, "failed to allocate target registry string with HKCU root");
            }
        }
        else if (msidbRegistryRootClassesRoot == iRoot)
        {
            hr = StrAllocString(ppwzTargetPath, L"CLASSES_ROOT\\", 0);
            ExitOnFailure(hr, "failed to allocate target registry string with HKCR root");
        }
        else if (msidbRegistryRootCurrentUser == iRoot)
        {
            hr = StrAllocString(ppwzTargetPath, L"CURRENT_USER\\", 0);
            ExitOnFailure(hr, "failed to allocate target registry string with HKCU root");
        }
        else if (msidbRegistryRootLocalMachine == iRoot)
        {
            hr = StrAllocString(ppwzTargetPath, L"MACHINE\\", 0);
            ExitOnFailure(hr, "failed to allocate target registry string with HKLM root");
        }
        else if (msidbRegistryRootUsers == iRoot)
        {
            hr = StrAllocString(ppwzTargetPath, L"USERS\\", 0);
            ExitOnFailure(hr, "failed to allocate target registry string with HKU root");
        }
        else
        {
            ExitOnFailure2(hr = E_UNEXPECTED, "Unknown registry key root specified for secure object: '%ls' root: %d", pwzSecureObject, iRoot);
        }
        
        hr = StrAllocConcat(ppwzTargetPath, pwzKey, 0);
        ExitOnFailure2(hr, "Failed to concat key: %ls for secure object: %ls", pwzKey, pwzSecureObject);
    }
    else
    {
        AssertSz(FALSE, "How did you get here?");
        ExitOnFailure1(hr = E_UNEXPECTED, "Unknown secure object type: %d", eType);
    }

LExit:
    ReleaseStr(pwzFormattedString);
    ReleaseStr(pwzKey);

    return hr;
}
コード例 #15
0
ファイル: netfxca.cpp プロジェクト: 925coder/wix3
static HRESULT CreateInstallCommand(
    __out LPWSTR* ppwzCommandLine,
    __in LPCWSTR pwzNgenPath,
    __in LPCWSTR pwzFile,
    __in int iPriority,
    __in int iAttributes,
    __in LPCWSTR pwzFileApp,
    __in LPCWSTR pwzDirAppBase
    )
{
    Assert(ppwzCommandLine && pwzNgenPath && *pwzNgenPath && pwzFile && *pwzFile&& pwzFileApp && pwzDirAppBase);
    HRESULT hr = S_OK;

    LPWSTR pwzQueueString = NULL;

    hr = StrAllocFormatted(ppwzCommandLine, L"%s install %s", pwzNgenPath, pwzFile);
    ExitOnFailure(hr, "failed to assemble install command line");

    if (iPriority > 0)
    {
        hr = StrAllocFormatted(&pwzQueueString, L" /queue:%d", iPriority);
        ExitOnFailure(hr, "failed to format queue string");

        hr = StrAllocConcat(ppwzCommandLine, pwzQueueString, 0);
        ExitOnFailure(hr, "failed to add queue string to NGEN command line");
    }

    if (NGEN_DEBUG & iAttributes)
    {
        hr = StrAllocConcat(ppwzCommandLine, L" /Debug", 0);
        ExitOnFailure(hr, "failed to add debug to NGEN command line");
    }

    if (NGEN_PROFILE & iAttributes)
    {
        hr = StrAllocConcat(ppwzCommandLine, L" /Profile", 0);
        ExitOnFailure(hr, "failed to add profile to NGEN command line");
    }

    if (NGEN_NODEP & iAttributes)
    {
        hr = StrAllocConcat(ppwzCommandLine, L" /NoDependencies", 0);
        ExitOnFailure(hr, "failed to add no dependencies to NGEN command line");
    }

    // If it's more than just two quotes around an empty string
    if (EMPTY_FORMATTED_LENGTH_QUOTED_FILE < lstrlenW(pwzFileApp))
    {
        hr = StrAllocConcat(ppwzCommandLine, L" /ExeConfig:", 0);
        ExitOnFailure(hr, "failed to add exe config to NGEN command line");

        hr = StrAllocConcat(ppwzCommandLine, pwzFileApp, 0);
        ExitOnFailure(hr, "failed to add file app to NGEN command line");
    }

    // If it's more than just two quotes around a backslash
    if (EMPTY_FORMATTED_LENGTH_QUOTED_DIRECTORY < lstrlenW(pwzDirAppBase))
    {
        hr = StrAllocConcat(ppwzCommandLine, L" /AppBase:", 0);
        ExitOnFailure(hr, "failed to add app base to NGEN command line");

        hr = StrAllocConcat(ppwzCommandLine, pwzDirAppBase, 0);
        ExitOnFailure(hr, "failed to add dir app base to NGEN command line");
    }

LExit:
    return hr;
}
コード例 #16
0
ファイル: pathutil.cpp プロジェクト: AnalogJ/Wix3.6Toolset
DAPI_(HRESULT) PathCommandLineAppend(
    __deref_out_z LPWSTR* psczCommandLine,
    __in_z LPCWSTR wzArgument
    )
{
    HRESULT hr = S_OK;
    LPWSTR sczQuotedArg = NULL;
    BOOL fRequiresQuoting = FALSE;
    DWORD dwMaxEscapedSize = 0;

    // Loop through the argugment determining if it needs to be quoted and what the maximum
    // size would be if there are escape characters required.
    for (LPCWSTR pwz = wzArgument; *pwz; ++pwz)
    {
        // Arguments with whitespace need quoting.
        if (L' ' == *pwz || L'\t' == *pwz || L'\n' == *pwz || L'\v' == *pwz)
        {
            fRequiresQuoting = TRUE;
        }
        else if (L'"' == *pwz) // quotes need quoting and sometimes escaping.
        {
            fRequiresQuoting = TRUE;
            ++dwMaxEscapedSize;
        }
        else if (L'\\' == *pwz) // some backslashes need escaping, so we'll count them all to make sure there is room.
        {
            ++dwMaxEscapedSize;
        }

        ++dwMaxEscapedSize;
    }

    // If we found anything in the argument that requires our argument to be quoted
    if (fRequiresQuoting)
    {
        hr = StrAlloc(&sczQuotedArg, dwMaxEscapedSize + 3); // plus three for the start and end quote plus null terminator.
        ExitOnFailure(hr, "Failed to allocate argument to be quoted.");

        LPCWSTR pwz = wzArgument; 
        LPWSTR pwzQuoted = sczQuotedArg;

        *pwzQuoted = L'"';
        ++pwzQuoted;
        while (*pwz)
        {
            DWORD dwBackslashes = 0;
            while (L'\\' == *pwz)
            {
                ++dwBackslashes;
                ++pwz;
            }

            // Escape all backslashes at the end of the string.
            if (!*pwz)
            {
                dwBackslashes *= 2;
            }
            else if (L'"' == *pwz) // escape all backslashes before the quote and escape the quote itself.
            {
                dwBackslashes = dwBackslashes * 2 + 1;
            }
            // the backslashes don't have to be escaped.

            // Add the appropriate number of backslashes
            for (DWORD i = 0; i < dwBackslashes; ++i)
            {
                *pwzQuoted = L'\\';
                ++pwzQuoted;
            }

            // If there is a character, add it after all the escaped backslashes
            if (*pwz)
            {
                *pwzQuoted = *pwz;
                ++pwz;
                ++pwzQuoted;
            }
        }

        *pwzQuoted = L'"';
        ++pwzQuoted;
        *pwzQuoted = L'\0'; // ensure the arg is null terminated.
    }

    // If there is already data in the command line, append a space before appending the
    // argument.
    if (*psczCommandLine && **psczCommandLine)
    {
        hr = StrAllocConcat(psczCommandLine, L" ", 0);
        ExitOnFailure(hr, "Failed to append space to command line with existing data.");
    }

    hr = StrAllocConcat(psczCommandLine, sczQuotedArg ? sczQuotedArg : wzArgument, 0);
    ExitOnFailure(hr, "Failed to copy command line argument.");

LExit:
    ReleaseStr(sczQuotedArg);

    return hr;
}
コード例 #17
0
ファイル: pseudobundle.cpp プロジェクト: 925coder/wix3
extern "C" HRESULT PseudoBundleInitialize(
    __in DWORD64 qwEngineVersion,
    __in BURN_PACKAGE* pPackage,
    __in BOOL fPerMachine,
    __in_z LPCWSTR wzId,
    __in BOOTSTRAPPER_RELATION_TYPE relationType,
    __in BOOTSTRAPPER_PACKAGE_STATE state,
    __in_z LPCWSTR wzFilePath,
    __in_z LPCWSTR wzLocalSource,
    __in_z_opt LPCWSTR wzDownloadSource,
    __in DWORD64 qwSize,
    __in BOOL fVital,
    __in_z_opt LPCWSTR wzInstallArguments,
    __in_z_opt LPCWSTR wzRepairArguments,
    __in_z_opt LPCWSTR wzUninstallArguments,
    __in_opt BURN_DEPENDENCY_PROVIDER* pDependencyProvider,
    __in_opt BYTE* pbHash,
    __in DWORD cbHash
    )
{
    HRESULT hr = S_OK;
    LPWSTR sczRelationTypeCommandLineSwitch = NULL;

    LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType);
    if (wzRelationTypeCommandLine)
    {
        hr = StrAllocFormatted(&sczRelationTypeCommandLineSwitch, L" -%ls", wzRelationTypeCommandLine);
    }

    // Initialize the single payload, and fill out all the necessary fields
    pPackage->rgPayloads = (BURN_PACKAGE_PAYLOAD *)MemAlloc(sizeof(BURN_PACKAGE_PAYLOAD), TRUE); 
    ExitOnNull(pPackage->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn package payload inside of related bundle struct");
    pPackage->cPayloads = 1;

    pPackage->rgPayloads->pPayload = (BURN_PAYLOAD *)MemAlloc(sizeof(BURN_PAYLOAD), TRUE); 
    ExitOnNull(pPackage->rgPayloads, hr, E_OUTOFMEMORY, "Failed to allocate space for burn payload inside of related bundle struct");
    pPackage->rgPayloads->pPayload->packaging = BURN_PAYLOAD_PACKAGING_EXTERNAL;
    pPackage->rgPayloads->pPayload->qwFileSize = qwSize;

    hr = StrAllocString(&pPackage->rgPayloads->pPayload->sczKey, wzId, 0);
    ExitOnFailure(hr, "Failed to copy key for pseudo bundle payload.");

    hr = StrAllocString(&pPackage->rgPayloads->pPayload->sczFilePath, wzFilePath, 0);
    ExitOnFailure(hr, "Failed to copy filename for pseudo bundle.");

    hr = StrAllocString(&pPackage->rgPayloads->pPayload->sczSourcePath, wzLocalSource, 0);
    ExitOnFailure(hr, "Failed to copy local source path for pseudo bundle.");

    if (wzDownloadSource && *wzDownloadSource)
    {
        hr = StrAllocString(&pPackage->rgPayloads->pPayload->downloadSource.sczUrl, wzDownloadSource, 0);
        ExitOnFailure(hr, "Failed to copy download source for pseudo bundle.");
    }

    if (pbHash)
    {
        pPackage->rgPayloads->pPayload->pbHash = static_cast<BYTE*>(MemAlloc(cbHash, FALSE));
        ExitOnNull(pPackage->rgPayloads->pPayload->pbHash, hr, E_OUTOFMEMORY, "Failed to allocate memory for pseudo bundle payload hash.");

        pPackage->rgPayloads->pPayload->cbHash = cbHash;
        memcpy_s(pPackage->rgPayloads->pPayload->pbHash, pPackage->rgPayloads->pPayload->cbHash, pbHash, cbHash);
    }

    pPackage->rgPayloads->fCached = (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == state || BOOTSTRAPPER_PACKAGE_STATE_CACHED == state);

    pPackage->Exe.fPseudoBundle = TRUE;

    pPackage->type = BURN_PACKAGE_TYPE_EXE;
    pPackage->fPerMachine = fPerMachine;
    pPackage->currentState = state;
    pPackage->cache = (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == state || BOOTSTRAPPER_PACKAGE_STATE_CACHED == state) ? BURN_CACHE_STATE_COMPLETE : BURN_CACHE_STATE_NONE;
    pPackage->qwInstallSize = qwSize;
    pPackage->qwSize = qwSize;
    pPackage->fVital = fVital;

    hr = StrAllocString(&pPackage->sczId, wzId, 0);
    ExitOnFailure(hr, "Failed to copy key for pseudo bundle.");

    hr = StrAllocString(&pPackage->sczCacheId, wzId, 0);
    ExitOnFailure(hr, "Failed to copy cache id for pseudo bundle.");

    // If we are a self updating bundle, we don't have to have Install arguments.
    if (wzInstallArguments)
    {
        hr = StrAllocString(&pPackage->Exe.sczInstallArguments, wzInstallArguments, 0);
        ExitOnFailure(hr, "Failed to copy install arguments for related bundle package");
    }

    if (sczRelationTypeCommandLineSwitch)
    {
        hr = StrAllocConcat(&pPackage->Exe.sczInstallArguments, sczRelationTypeCommandLineSwitch, 0);
        ExitOnFailure(hr, "Failed to append relation type to install arguments for related bundle package");
    }

    if (wzRepairArguments)
    {
        hr = StrAllocString(&pPackage->Exe.sczRepairArguments, wzRepairArguments, 0);
        ExitOnFailure(hr, "Failed to copy repair arguments for related bundle package");

        if (sczRelationTypeCommandLineSwitch)
        {
            hr = StrAllocConcat(&pPackage->Exe.sczRepairArguments, sczRelationTypeCommandLineSwitch, 0);
            ExitOnFailure(hr, "Failed to append relation type to repair arguments for related bundle package");
        }

        pPackage->Exe.fRepairable = TRUE;
    }

    if (wzUninstallArguments)
    {
        hr = StrAllocString(&pPackage->Exe.sczUninstallArguments, wzUninstallArguments, 0);
        ExitOnFailure(hr, "Failed to copy uninstall arguments for related bundle package");

        if (sczRelationTypeCommandLineSwitch)
        {
            hr = StrAllocConcat(&pPackage->Exe.sczUninstallArguments, sczRelationTypeCommandLineSwitch, 0);
            ExitOnFailure(hr, "Failed to append relation type to uninstall arguments for related bundle package");
        }

        pPackage->fUninstallable = TRUE;
    }

    // Only support progress from engines that are compatible (aka: version greater than or equal to last protocol breaking change *and* versions that are older or the same as this engine).
    pPackage->Exe.protocol = (FILEMAKEVERSION(3, 6, 2221, 0) <= qwEngineVersion && qwEngineVersion <= FILEMAKEVERSION(rmj, rmm, rup, 0)) ? BURN_EXE_PROTOCOL_TYPE_BURN : BURN_EXE_PROTOCOL_TYPE_NONE;

    if (pDependencyProvider)
    {
        pPackage->rgDependencyProviders = (BURN_DEPENDENCY_PROVIDER*)MemAlloc(sizeof(BURN_DEPENDENCY_PROVIDER), TRUE);
        ExitOnNull(pPackage->rgDependencyProviders, hr, E_OUTOFMEMORY, "Failed to allocate memory for dependency providers.");
        pPackage->cDependencyProviders = 1;

        pPackage->rgDependencyProviders[0].fImported = pDependencyProvider->fImported;

        hr = StrAllocString(&pPackage->rgDependencyProviders[0].sczKey, pDependencyProvider->sczKey, 0);
        ExitOnFailure(hr, "Failed to copy key for pseudo bundle.");

        hr = StrAllocString(&pPackage->rgDependencyProviders[0].sczVersion, pDependencyProvider->sczVersion, 0);
        ExitOnFailure(hr, "Failed to copy version for pseudo bundle.");

        hr = StrAllocString(&pPackage->rgDependencyProviders[0].sczDisplayName, pDependencyProvider->sczDisplayName, 0);
        ExitOnFailure(hr, "Failed to copy display name for pseudo bundle.");
    }

LExit:
    ReleaseStr(sczRelationTypeCommandLineSwitch);

    return hr;
}
コード例 #18
0
ファイル: scasched.cpp プロジェクト: 925coder/wix3
/********************************************************************
ConfigureIIs - CUSTOM ACTION ENTRY POINT for installing IIs settings

********************************************************************/
extern "C" UINT __stdcall ConfigureIIs(
    __in MSIHANDLE hInstall
    )
{
    //AssertSz(FALSE, "debug ConfigureIIs here");
    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;
    LPWSTR pwzScriptKey = NULL;
    LPWSTR pwzBackupId = NULL;
    LPWSTR pwzCustomActionData = NULL; // CustomActionData for ConfigureIIs custom action

    // initialize
    hr = WcaInitialize(hInstall, "ConfigureIIs");
    ExitOnFailure(hr, "Failed to initialize");

    // check for the prerequsite tables
    if (S_OK != WcaTableExists(L"IIsWebSite") && S_OK != WcaTableExists(L"IIsFilter") && S_OK != WcaTableExists(L"IIsProperty") && 
        S_OK != WcaTableExists(L"IIsWebServiceExtension") && S_OK != WcaTableExists(L"IIsAppPool"))
    {
        WcaLog(LOGMSG_VERBOSE, "skipping IIs CustomAction, no IIsWebSite table, no IIsFilter table, no IIsProperty table, no IIsWebServiceExtension, and no IIsAppPool table");
        ExitFunction1(hr = S_FALSE);
    }

    // Get a CaScript key
    hr = WcaCaScriptCreateKey(&pwzScriptKey);
    ExitOnFailure(hr, "Failed to get encoding key.");

    // Generate a unique string to be used for this product's transaction
    // This prevents a name collision when doing a major upgrade
    hr = WcaGetProperty(L"ProductCode", &pwzBackupId);
    ExitOnFailure(hr, "failed to get ProductCode");

    hr = StrAllocConcat(&pwzBackupId, L"ScaConfigureIIs", 0);
    ExitOnFailure(hr, "failed to concat ScaConfigureIIs");

    // make sure the operations below are wrapped in a "transaction"
    // use IIS7 transaction logic even if using Iis6 compat because Backup/Restore don't work with metabase compatibility
    if (MSICONDITION_TRUE == ::MsiEvaluateConditionW(hInstall, IIS7CONDITION))
    {
        hr = ScaIIS7ConfigTransaction(pwzBackupId);
        MessageExitOnFailure(hr, msierrIISFailedSchedTransaction, "failed to start IIS7 transaction");
    }
    else
    {
        hr = ScaMetabaseTransaction(pwzBackupId);
        MessageExitOnFailure(hr, msierrIISFailedSchedTransaction, "failed to start IIS transaction");
    }

    // Write the CaScript key to the ConfigureIIS custom action data
    hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData);
    ExitOnFailure(hr, "Failed to add encoding key to CustomActionData.");

    // Wrap vcsUserDeferredQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"User"))
    {
        hr = WcaWrapQuery(vcsUserDeferredQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap User query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap User empty query");
    }

    // Wrap vcsWebSvcExtQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebServiceExtension"))
    {
        hr = WcaWrapQuery(vcsWebSvcExtQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3 | efmcColumn4, 1, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebServiceExtension query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebServiceExtension empty query");
    }

    // Wrap vcsAppPoolQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsAppPool"))
    {
        hr = WcaWrapQuery(vcsAppPoolQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn15 | efmcColumn16, 3, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsAppPool query");

        hr = WcaWrapQuery(vcsComponentAttrQuery, &pwzCustomActionData, 0, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap Component query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsAppPool empty query");
    }

    // Wrap vcsMimeMapQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsMimeMap"))
    {
        hr = WcaWrapQuery(vcsMimeMapQuery, &pwzCustomActionData, efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsMimeMap query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsMimeMap empty query");
    }

    // Wrap vcsHttpHeaderQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsHttpHeader"))
    {
        hr = WcaWrapQuery(vcsHttpHeaderQuery, &pwzCustomActionData, efmcColumn1 | efmcColumn4, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsHttpHeader query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsHttpHeader empty query");
    }

    // Wrap vcsWebErrorQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebError"))
    {
        hr = WcaWrapQuery(vcsWebErrorQuery, &pwzCustomActionData, efmcColumn5 | efmcColumn6, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebError query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebError empty query");
    }

    // Wrap vcsWebDirPropertiesQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebDirProperties"))
    {
        hr = WcaWrapQuery(vcsWebDirPropertiesQuery, &pwzCustomActionData, efmcColumn8 | efmcColumn10 | efmcColumn12 | efmcColumn15, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebDirProperties query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebDirProperties empty query");
    }

    // Wrap vcsSslCertificateQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"Certificate") && S_OK == WcaTableExists(L"CertificateHash") && S_OK == WcaTableExists(L"IIsWebSiteCertificates"))
    {
        hr = WcaWrapQuery(vcsSslCertificateQuery, &pwzCustomActionData, 0, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap SslCertificate query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap SslCertificate empty query");
    }

    // Wrap vcsWebLogQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebLog"))
    {
        hr = WcaWrapQuery(vcsWebLogQuery, &pwzCustomActionData, efmcColumn2, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebLog query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebLog empty query");
    }

    // Wrap vcsWebApplicationQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebApplication"))
    {
        hr = WcaWrapQuery(vcsWebApplicationQuery, &pwzCustomActionData, efmcColumn1, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebApplication query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebApplication empty query");
    }

    // Wrap vcsWebAppExtensionQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebApplicationExtension"))
    {
        hr = WcaWrapQuery(vcsWebAppExtensionQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebApplicationExtension query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebApplicationExtension empty query");
    }

    // Wrap vcsWebQuery, vcsWebAddressQuery, and vcsWebBaseQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebAddress") && S_OK == WcaTableExists(L"IIsWebSite"))
    {
        hr = WcaWrapQuery(vcsWebQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn12 | efmcColumn13 | efmcColumn14, 2, 6);
        ExitOnFailure(hr, "Failed to wrap IIsWebSite query");

        hr = WcaWrapQuery(vcsWebAddressQuery, &pwzCustomActionData, efmcColumn3 | efmcColumn4 | efmcColumn5, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebAddress query");

        hr = WcaWrapQuery(vcsWebBaseQuery, &pwzCustomActionData, efmcColumn2 | efmcColumn3 | efmcColumn4 | efmcColumn5 | efmcColumn7, 0xFFFFFFFF, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebBase query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebSite empty query");

        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebAddress empty query");

        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebBase empty query");
    }

    // Wrap vcsWebDirQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebDir"))
    {
        hr = WcaWrapQuery(vcsWebDirQuery, &pwzCustomActionData, efmcColumn4, 3, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsWebDir query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebDir empty query");
    }

    // Wrap vcsVDirQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsWebVirtualDir"))
    {
        hr = WcaWrapQuery(vcsVDirQuery, &pwzCustomActionData, efmcColumn4, 3, 5);
        ExitOnFailure(hr, "Failed to wrap IIsWebVirtualDir query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsWebVirtualDir empty query");
    }

    // Wrap vcsFilterQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsFilter"))
    {
        hr = WcaWrapQuery(vcsFilterQuery, &pwzCustomActionData, efmcColumn4 | efmcColumn5, 3, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsFilter query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsFilter empty query");
    }

    // Wrap vcsPropertyQuery to send to deferred CA
    if (S_OK == WcaTableExists(L"IIsProperty"))
    {
        hr = WcaWrapQuery(vcsPropertyQuery, &pwzCustomActionData, efmcColumn4, 2, 0xFFFFFFFF);
        ExitOnFailure(hr, "Failed to wrap IIsProperty query");
    }
    else
    {
        hr = WcaWrapEmptyQuery(&pwzCustomActionData);
        ExitOnFailure(hr, "Failed to wrap IIsProperty empty query");
    }

    if (MSICONDITION_TRUE == ::MsiEvaluateConditionW(hInstall, USEIIS7CONDITION))
    {
        // This must remain trace only, CA data may contain password
        WcaLog(LOGMSG_TRACEONLY, "Custom Action Data for ConfigureIIS7Exec will be: %ls", pwzCustomActionData);

        hr = WcaDoDeferredAction(L"ConfigureIIs7Exec", pwzCustomActionData, ConfigureIIsCost);
        ExitOnFailure(hr, "Failed to schedule ConfigureIIs7Exec custom action");

        ReleaseNullStr(pwzCustomActionData);

        // Write the CaScript key to the ConfigureIIS custom action data
        hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData);
        ExitOnFailure(hr, "Failed to add script key to CustomActionData.");

        hr = WcaDoDeferredAction(L"WriteIIS7ConfigChanges", pwzCustomActionData, WriteIIS7ConfigChangesCost);
        ExitOnFailure(hr, "Failed to schedule WriteMetabaseChanges custom action");
    }
    else
    {
        // This must remain trace only, CA data may contain password
        WcaLog(LOGMSG_TRACEONLY, "Custom Action Data for ConfigureIISExec will be: %ls", pwzCustomActionData);

        hr = WcaDoDeferredAction(L"ConfigureIIsExec", pwzCustomActionData, ConfigureIIsCost);
        ExitOnFailure(hr, "Failed to schedule ConfigureIISExec custom action");

        ReleaseNullStr(pwzCustomActionData);

        // Write the CaScript key to the ConfigureIIS custom action data
        hr = WcaWriteStringToCaData(pwzScriptKey, &pwzCustomActionData);
        ExitOnFailure(hr, "Failed to add script key to CustomActionData.");

        hr = WcaDoDeferredAction(L"WriteMetabaseChanges", pwzCustomActionData, WriteMetabaseChangesCost);
        ExitOnFailure(hr, "Failed to schedule WriteMetabaseChanges custom action");
    }

LExit:
    ReleaseStr(pwzScriptKey);
    ReleaseStr(pwzBackupId);
    ReleaseStr(pwzCustomActionData);

    er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
    return WcaFinalize(er);
}
コード例 #19
0
ファイル: legsync.cpp プロジェクト: firegiant/wix4
static HRESULT ReadRegKeyWriteLegacyDb(
    __in CFGDB_STRUCT *pcdb,
    __in LEGACY_SYNC_PRODUCT_SESSION *pSyncProductSession,
    __in LEGACY_REGISTRY_KEY *pRegKey,
    __in_z LPCWSTR wzSubKey
    )
{
    HRESULT hr = S_OK;
    HKEY hkKey = NULL;
    DWORD dwType = 0;
    DWORD dwIndex = 0;
    LPWSTR sczValueName = NULL;
    LPWSTR sczSubkeyName = NULL;
    LPWSTR sczSubkeyPath = NULL;

    hr = RegOpen(ManifestConvertToRootKey(pRegKey->dwRoot), wzSubKey, KEY_READ, &hkKey);
    if (E_FILENOTFOUND == hr)
    {
        ExitFunction1(hr = S_OK);
    }
    ExitOnFailure(hr, "Failed to open regkey: %ls", wzSubKey);

    dwIndex = 0;
    while (E_NOMOREITEMS != (hr = RegValueEnum(hkKey, dwIndex, &sczValueName, &dwType)))
    {
        ExitOnFailure(hr, "Failed to enumerate value %u", dwIndex);

        hr = ReadRegValueWriteLegacyDb(pcdb, pSyncProductSession, pRegKey, hkKey, wzSubKey, sczValueName, dwType);
        ExitOnFailure(hr, "Failed to write registry value setting: %ls", sczValueName);

        ++dwIndex;
    }

    // Recurse and handle subkeys as well
    dwIndex = 0;
    while (E_NOMOREITEMS != (hr = RegKeyEnum(hkKey, dwIndex, &sczSubkeyName)))
    {
        ExitOnFailure(hr, "Failed to enumerate key %u", dwIndex);

        hr = StrAllocString(&sczSubkeyPath, wzSubKey, 0);
        ExitOnFailure(hr, "Failed to allocate copy of subkey name");

        hr = PathBackslashTerminate(&sczSubkeyPath);
        ExitOnFailure(hr, "Failed to ensure path is terminated with a backslash");

        hr = StrAllocConcat(&sczSubkeyPath, sczSubkeyName, 0);
        ExitOnFailure(hr, "Failed to concatenate subkey name to subkey path");

        hr = ReadRegKeyWriteLegacyDb(pcdb, pSyncProductSession, pRegKey, sczSubkeyPath);
        ExitOnFailure(hr, "Failed to read regkey and write settings for root: %u, subkey: %ls", pRegKey->dwRoot, sczSubkeyPath);

        ++dwIndex;
    }

    if (E_NOMOREITEMS == hr)
    {
        hr = S_OK;
    }

LExit:
    ReleaseRegKey(hkKey);
    ReleaseStr(sczValueName);
    ReleaseStr(sczSubkeyName);
    ReleaseStr(sczSubkeyPath);

    return hr;
}
コード例 #20
0
ファイル: legsync.cpp プロジェクト: firegiant/wix4
static HRESULT DeleteEmptyRegistryKeyChildren(
    __in DWORD dwRoot,
    __in_z LPCWSTR wzSubKey
    )
{
    HRESULT hr = S_OK;
    HKEY hkKey = NULL;
    DWORD dwIndex = 0;
    BOOL fNoValues = FALSE;
    LPWSTR sczValueName = NULL;
    LPWSTR sczSubkeyName = NULL;
    LPWSTR sczSubkeyPath = NULL;
    DWORD dwSubKeyPathLen = 0;

    hr = RegOpen(ManifestConvertToRootKey(dwRoot), wzSubKey, KEY_READ, &hkKey);
    if (E_FILENOTFOUND == hr)
    {
        ExitFunction1(hr = S_OK);
    }
    ExitOnFailure(hr, "Failed to open regkey: %ls", wzSubKey);

    if (E_NOMOREITEMS == RegValueEnum(hkKey, dwIndex, &sczValueName, NULL))
    {
        fNoValues = TRUE;
    }

    // Recurse and handle subkeys as well
    dwIndex = 0;
    while (E_NOMOREITEMS != (hr = RegKeyEnum(hkKey, dwIndex, &sczSubkeyName)))
    {
        ExitOnFailure(hr, "Failed to enumerate key %u", dwIndex);

        hr = StrAllocString(&sczSubkeyPath, wzSubKey, 0);
        ExitOnFailure(hr, "Failed to allocate copy of subkey name");

        dwSubKeyPathLen = lstrlenW(sczSubkeyPath);

        if (0 == dwSubKeyPathLen)
        {
            hr = E_INVALIDARG;
            ExitOnFailure(hr, "Encountered empty keyname while enumerating subkeys under key: %ls", wzSubKey);
        }
        else if (L'\\' != sczSubkeyPath[dwSubKeyPathLen - 1])
        {
            hr = StrAllocConcat(&sczSubkeyPath, L"\\", 1);
            ExitOnFailure(hr, "Failed to concatenate backslash to copy of regkey name");
        }

        hr = StrAllocConcat(&sczSubkeyPath, sczSubkeyName, 0);
        ExitOnFailure(hr, "Failed to concatenate subkey name to subkey path");

        hr = DeleteEmptyRegistryKeyChildren(dwRoot, sczSubkeyPath);
        // Increment and ignore the error if we didn't delete the subkey
        if (HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) == hr)
        {
            ++dwIndex;
            hr = S_OK;
        }
        ExitOnFailure(hr, "Failed to read regkey and write settings for root: %u, subkey: %ls", dwRoot, sczSubkeyPath);
    }

    // If there are no keys and no values under it, delete it
    if (fNoValues && 0 == dwIndex)
    {
        hr = RegDelete(ManifestConvertToRootKey(dwRoot), wzSubKey, REG_KEY_DEFAULT, FALSE);
        ExitOnFailure(hr, "Failed to delete registry key at root: %u, subkey: %ls", dwRoot, wzSubKey);

        ExitFunction1(hr = S_OK);
    }
    else
    {
        ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY));
    }

LExit:
    ReleaseRegKey(hkKey);
    ReleaseStr(sczValueName);
    ReleaseStr(sczSubkeyName);
    ReleaseStr(sczSubkeyPath);

    return hr;
}
コード例 #21
0
ファイル: netshortcuts.cpp プロジェクト: BMurri/wix3
/******************************************************************
 WixSchedInternetShortcuts - entry point

********************************************************************/
extern "C" UINT __stdcall WixSchedInternetShortcuts(
    __in MSIHANDLE hInstall
)
{
    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;

    UINT uiCost = 0;

    PMSIHANDLE hView = NULL;
    PMSIHANDLE hRec = NULL;

    MSIHANDLE hCreateFolderTable = NULL;
    MSIHANDLE hCreateFolderColumns = NULL;

    LPWSTR pwzCustomActionData = NULL;
    LPWSTR pwzComponent = NULL;
    LPWSTR pwzDirectory = NULL;
    LPWSTR pwzFilename = NULL;
    LPWSTR pwzTarget = NULL;
    LPWSTR pwzShortcutPath = NULL;
    int iAttr = 0;
    LPWSTR pwzIconFile = NULL;
    int iIconIndex = 0;
    IUniformResourceLocatorW* piURL = NULL;
    IShellLinkW* piShellLink = NULL;
    BOOL fInitializedCom = FALSE;

    hr = WcaInitialize(hInstall, "WixSchedInternetShortcuts");
    ExitOnFailure(hr, "failed to initialize WixSchedInternetShortcuts.");

    // anything to do?
    if (S_OK != WcaTableExists(L"WixInternetShortcut"))
    {
        WcaLog(LOGMSG_STANDARD, "WixInternetShortcut table doesn't exist, so there are no Internet shortcuts to process");
        goto LExit;
    }

    // check to see if we can create a shortcut - Server Core and others may not have a shell registered.  
    hr = ::CoInitialize(NULL);
    ExitOnFailure(hr, "failed to initialize COM");
    fInitializedCom = TRUE;

    hr = ::CoCreateInstance(CLSID_InternetShortcut, NULL, CLSCTX_ALL, IID_IUniformResourceLocatorW, (void**)&piURL);
    if (S_OK != hr)
    {
        WcaLog(LOGMSG_STANDARD, "failed to create an instance of IUniformResourceLocatorW, skipping shortcut creation");
        ExitFunction1(hr = S_OK);
    }

    hr = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_ALL, IID_IShellLinkW, (void**)&piShellLink);
    if (S_OK != hr)
    {
        WcaLog(LOGMSG_STANDARD, "failed to create an instance of IShellLinkW, skipping shortcut creation");
        ExitFunction1(hr = S_OK);
    }

    // query and loop through all the shortcuts
    hr = WcaOpenExecuteView(vcsShortcutsQuery, &hView);
    ExitOnFailure(hr, "failed to open view on WixInternetShortcut table");

    while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
    {
        // read column values
        hr = WcaGetRecordString(hRec, esqComponent, &pwzComponent);
        ExitOnFailure(hr, "failed to get shortcut component");
        hr = WcaGetRecordString(hRec, esqDirectory, &pwzDirectory);
        ExitOnFailure(hr, "failed to get shortcut directory");
        hr = WcaGetRecordString(hRec, esqFilename, &pwzFilename);
        ExitOnFailure(hr, "failed to get shortcut filename");
        hr = WcaGetRecordFormattedString(hRec, esqTarget, &pwzTarget);
        ExitOnFailure(hr, "failed to get shortcut target");
        hr = WcaGetRecordInteger(hRec, esqAttributes, &iAttr);
        ExitOnFailure(hr, "failed to get shortcut attributes");
        hr = WcaGetRecordFormattedString(hRec, esqIconFile, &pwzIconFile);
        ExitOnFailure(hr, "failed to get shortcut icon file");
        hr = WcaGetRecordInteger(hRec, esqIconIndex, &iIconIndex);
        ExitOnFailure(hr, "failed to get shortcut icon index");

        // skip processing this WixInternetShortcut row if the component isn't being configured
        WCA_TODO todo = WcaGetComponentToDo(pwzComponent);
        if (WCA_TODO_UNKNOWN == todo)
        {
            WcaLog(LOGMSG_VERBOSE, "Skipping shortcut for null-action component '%ls'", pwzComponent);
            continue;
        }

        // we need to create the directory where the shortcut is supposed to live; rather
        // than doing so in our deferred custom action, use the CreateFolder table to have MSI 
        // make (and remove) them on our behalf (including the correct cleanup of parent directories).
        MSIDBERROR dbError = MSIDBERROR_NOERROR;
        WcaLog(LOGMSG_STANDARD, "Adding folder '%ls', component '%ls' to the CreateFolder table", pwzDirectory, pwzComponent);
        hr = WcaAddTempRecord(&hCreateFolderTable, &hCreateFolderColumns, L"CreateFolder", &dbError, 0, 2, pwzDirectory, pwzComponent);
        if (MSIDBERROR_DUPLICATEKEY == dbError)
        {
            WcaLog(LOGMSG_STANDARD, "Folder '%ls' already exists in the CreateFolder table; the above error is harmless", pwzDirectory);
            hr = S_OK;
        }
        ExitOnFailure(hr, "Couldn't add temporary CreateFolder row");

        // only if we're installing/reinstalling do we need to schedule the deferred CA
        // (uninstallation is handled via permanent RemoveFile rows and temporary CreateFolder rows)
        if (WCA_TODO_INSTALL == todo || WCA_TODO_REINSTALL == todo)
        {
            // turn the Directory_ id into a path
            hr = WcaGetTargetPath(pwzDirectory, &pwzShortcutPath);
            ExitOnFailure(hr, "failed to allocate string for shortcut directory");

            // append the shortcut filename
            hr = StrAllocConcat(&pwzShortcutPath, pwzFilename, 0);
            ExitOnFailure(hr, "failed to allocate string for shortcut filename");

            // write the shortcut path and target to custom action data for deferred CAs
            hr = WcaWriteStringToCaData(pwzShortcutPath, &pwzCustomActionData);
            ExitOnFailure(hr, "failed to write shortcut path to custom action data");
            hr = WcaWriteStringToCaData(pwzTarget, &pwzCustomActionData);
            ExitOnFailure(hr, "failed to write shortcut target to custom action data");
            hr = WcaWriteIntegerToCaData(iAttr, &pwzCustomActionData);
            ExitOnFailure(hr, "failed to write shortcut attributes to custom action data");
            hr = WcaWriteStringToCaData(pwzIconFile, &pwzCustomActionData);
            ExitOnFailure(hr, "failed to write icon file to custom action data");
            hr = WcaWriteIntegerToCaData(iIconIndex, &pwzCustomActionData);
            ExitOnFailure(hr, "failed to write icon index to custom action data");

            uiCost += COST_INTERNETSHORTCUT;
        }
    }

    if (E_NOMOREITEMS == hr)
    {
        hr = S_OK;
    }
    ExitOnFailure(hr, "Failure occured while processing WixInternetShortcut table");

    // if we have any shortcuts to install
    if (pwzCustomActionData && *pwzCustomActionData)
    {
        // add cost to progress bar
        hr = WcaProgressMessage(uiCost, TRUE);
        ExitOnFailure(hr, "failed to extend progress bar for InternetShortcuts");

        // provide custom action data to deferred and rollback CAs
        hr = WcaSetProperty(PLATFORM_DECORATION(L"WixRollbackInternetShortcuts"), pwzCustomActionData);
        ExitOnFailure(hr, "failed to set WixRollbackInternetShortcuts rollback custom action data");
        hr = WcaSetProperty(PLATFORM_DECORATION(L"WixCreateInternetShortcuts"), pwzCustomActionData);
        ExitOnFailure(hr, "failed to set WixCreateInternetShortcuts custom action data");
    }

LExit:
    if (hCreateFolderTable)
    {
        ::MsiCloseHandle(hCreateFolderTable);
    }

    if (hCreateFolderColumns)
    {
        ::MsiCloseHandle(hCreateFolderColumns);
    }

    ReleaseStr(pwzCustomActionData);
    ReleaseStr(pwzComponent);
    ReleaseStr(pwzDirectory);
    ReleaseStr(pwzFilename);
    ReleaseStr(pwzTarget);
    ReleaseStr(pwzShortcutPath);
    ReleaseObject(piShellLink);
    ReleaseObject(piURL);

    if (fInitializedCom)
    {
        ::CoUninitialize();
    }

    er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
    return WcaFinalize(er);
}
コード例 #22
0
ファイル: qtexec.cpp プロジェクト: BobSilent/wix3
static HRESULT HandleOutput(
    __in BOOL fLogOutput,
    __in HANDLE hRead
    )
{
    BYTE *pBuffer = NULL;
    LPWSTR szLog = NULL;
    LPWSTR szTemp = NULL;
    LPWSTR pEnd = NULL;
    LPWSTR pNext = NULL;
    LPWSTR sczEscaped = NULL;
    LPSTR szWrite = NULL;
    DWORD dwBytes = OUTPUT_BUFFER;
    BOOL bFirst = TRUE;
    BOOL bUnicode = TRUE;
    HRESULT hr = S_OK;

    // Get buffer for output
    pBuffer = static_cast<BYTE *>(MemAlloc(OUTPUT_BUFFER, FALSE));
    ExitOnNull(pBuffer, hr, E_OUTOFMEMORY, "Failed to allocate buffer for output.");

    while (0 != dwBytes)
    {
        ::ZeroMemory(pBuffer, OUTPUT_BUFFER);
        if (!::ReadFile(hRead, pBuffer, OUTPUT_BUFFER - 1, &dwBytes, NULL) && GetLastError() != ERROR_BROKEN_PIPE)
        {
            ExitOnLastError(hr, "Failed to read from handle.");
        }

        if (fLogOutput)
        {
            // Check for UNICODE or ANSI output
            if (bFirst)
            {
                if ((isgraph(pBuffer[0]) && isgraph(pBuffer[1])) ||
                    (isgraph(pBuffer[0]) && isspace(pBuffer[1])) ||
                    (isspace(pBuffer[0]) && isgraph(pBuffer[1])) ||
                    (isspace(pBuffer[0]) && isspace(pBuffer[1])))
                {
                    bUnicode = FALSE;
                }

                bFirst = FALSE;
            }

            // Keep track of output
            if (bUnicode)
            {
                hr = StrAllocConcat(&szLog, (LPCWSTR)pBuffer, 0);
                ExitOnFailure(hr, "Failed to concatenate output strings");
            }
            else
            {
                hr = StrAllocStringAnsi(&szTemp, (LPCSTR)pBuffer, 0, CP_OEMCP);
                ExitOnFailure(hr, "Failed to allocate output string");
                hr = StrAllocConcat(&szLog, szTemp, 0);
                ExitOnFailure(hr, "Failed to concatenate output strings");
            }

            // Log each line of the output
            pNext = szLog;
            pEnd = wcschr(szLog, L'\r');
            if (NULL == pEnd)
            {
                pEnd = wcschr(szLog, L'\n');
            }
            while (pEnd && *pEnd)
            {
                // Find beginning of next line
                pEnd[0] = 0;
                ++pEnd;
                if ((pEnd[0] == L'\r') || (pEnd[0] == L'\n'))
                {
                    ++pEnd;
                }

                // Log output
                hr = StrAllocString(&sczEscaped, pNext, 0);
                ExitOnFailure(hr, "Failed to allocate copy of string");

                hr = StrReplaceStringAll(&sczEscaped, L"%", L"%%");
                ExitOnFailure(hr, "Failed to escape percent signs in string");

                hr = StrAnsiAllocString(&szWrite, sczEscaped, 0, CP_OEMCP);
                ExitOnFailure(hr, "Failed to convert output to ANSI");
                WcaLog(LOGMSG_STANDARD, szWrite);

                // Next line
                pNext = pEnd;
                pEnd = wcschr(pNext, L'\r');
                if (NULL == pEnd)
                {
                    pEnd = wcschr(pNext, L'\n');
                }
            }

            hr = StrAllocString(&szTemp, pNext, 0);
            ExitOnFailure(hr, "Failed to allocate string");

            hr = StrAllocString(&szLog, szTemp, 0);
            ExitOnFailure(hr, "Failed to allocate string");
        }
    }

    // Print any text that didn't end with a new line
    if (szLog && *szLog)
    {
        hr = StrReplaceStringAll(&szLog, L"%", L"%%");
        ExitOnFailure(hr, "Failed to escape percent signs in string");

        hr = StrAnsiAllocString(&szWrite, szLog, 0, CP_OEMCP);
        ExitOnFailure(hr, "Failed to convert output to ANSI");

        WcaLog(LOGMSG_VERBOSE, szWrite);
    }

LExit:
    ReleaseMem(pBuffer);

    ReleaseStr(szLog);
    ReleaseStr(szTemp);
    ReleaseStr(szWrite);
    ReleaseStr(sczEscaped);

    return hr;
}