Esempio n. 1
0
HRESULT ScaVirtualDirGetComponent(
	__in LPCWSTR wzVirtualDir,
	__out LPWSTR* ppwzData
	)
{
	Assert(wzVirtualDir && *wzVirtualDir);

	HRESULT hr = S_OK;
	PMSIHANDLE hView, hRec;

	hr = WcaTableExists(L"IIsWebVirtualDir");
	if (S_FALSE == hr)
		hr = E_ABORT;
	ExitOnFailure(hr, "IIsWebVirtualDir table does not exist or error");

	hRec = ::MsiCreateRecord(1);
	if (!hRec)
	{
		hr = E_OUTOFMEMORY;
		ExitOnFailure(hr, "Failed to create record for lookup.");
	}
	hr = WcaSetRecordString(hRec, 1, wzVirtualDir);
	ExitOnFailure(hr, "Failed to look up VirtualDir Component");

	hr = WcaOpenView(vcsVDirPropertiesQuery, &hView);
	ExitOnFailure(hr, "Failed to open view on VirtualDir");
	hr = WcaExecuteView(hView, hRec);
	ExitOnFailure(hr, "Failed to exectue view on VirtualDir");

	hr = WcaFetchSingleRecord(hView, &hRec);
	if (S_OK == hr)
	{
#if DEBUG
		// check that vdir matches
		hr = WcaGetRecordString(hRec, vdqVDir, ppwzData);
		ExitOnFailure(hr, "Failed to get IIsWebVirtualDir.VirtualDir");
		Assert(0 == lstrcmpW(*ppwzData, wzVirtualDir));
#endif

		hr = WcaGetRecordString(hRec, vdqComponent, ppwzData);
		ExitOnFailure(hr, "Failed to get Component for VirtualDir");
	}
	else if (E_NOMOREITEMS == hr)
	{
		WcaLog(LOGMSG_STANDARD, "Error: Cannot locate IIsWebVirtualDir.VirtualDir='%S'", wzVirtualDir);
		hr = E_FAIL;
	}
	else
	{
		ExitOnFailure(hr, "Error or found multiple matching VirtualDir rows");
	}

LExit:
	return hr;
}
Esempio n. 2
0
static HRESULT GetUserAccountName(
    LPCWSTR pwzKey,
    LPWSTR* ppwzAccount
    )
{
    HRESULT hr = S_OK;

    PMSIHANDLE hView, hRecKey, hRec;

    LPWSTR pwzDomain = NULL;
    LPWSTR pwzName = NULL;

    // create parameter record
    hRecKey = ::MsiCreateRecord(1);
    ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
    hr = WcaSetRecordString(hRecKey, 1, pwzKey);
    ExitOnFailure(hr, "Failed to set record string");

    // open view
    hr = WcaOpenView(vcsUserQuery, &hView);
    ExitOnFailure(hr, "Failed to open view on User table");
    hr = WcaExecuteView(hView, hRecKey);
    ExitOnFailure(hr, "Failed to execute view on User table");

    // fetch record
    hr = WcaFetchSingleRecord(hView, &hRec);
    if (S_FALSE == hr)
        ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "User not found, key: %S", pwzKey);
    ExitOnFailure(hr, "Failed to fetch user record");

    // get user domain
    hr = WcaGetRecordFormattedString(hRec, uqDomain, &pwzDomain);
    ExitOnFailure(hr, "Failed to get domain");

    // get user name
    hr = WcaGetRecordFormattedString(hRec, uqName, &pwzName);
    ExitOnFailure(hr, "Failed to get name");

    // build account name
    hr = CpiBuildAccountName(pwzDomain, pwzName, ppwzAccount);
    ExitOnFailure(hr, "Failed to build account name");

    hr = S_OK;

LExit:
    // clean up
    ReleaseStr(pwzDomain);
    ReleaseStr(pwzName);

    return hr;
}
Esempio n. 3
0
HRESULT CpiVerifyComponentArchitecure(
    LPCWSTR pwzComponent,
    BOOL* pfMatchingArchitecture
    )
{
    HRESULT hr = S_OK;

    PMSIHANDLE hView, hRecKey, hRec;

    int iAttributes = 0;

    if (S_OK == WcaTableExists(L"Component"))
    {
        // create parameter record
        hRecKey = ::MsiCreateRecord(1);
        ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
        hr = WcaSetRecordString(hRecKey, 1, pwzComponent);
        ExitOnFailure(hr, "Failed to set record string");

        // open view
        hr = WcaOpenView(vcsComponentAttributesQuery, &hView);
        ExitOnFailure(hr, "Failed to open view on ActionText table");
        hr = WcaExecuteView(hView, hRecKey);
        ExitOnFailure(hr, "Failed to execute view on ActionText table");

        // fetch record
        hr = WcaFetchSingleRecord(hView, &hRec);
        if (S_FALSE != hr)
        {
            ExitOnFailure(hr, "Failed to fetch component record");

            hr = WcaGetRecordInteger(hRec, caqAttributes, &iAttributes);
            ExitOnFailure(hr, "Failed to get component attributes");
        }
    }

    // return values
#ifdef _WIN64
    *pfMatchingArchitecture = 256 == (iAttributes & 256);
#else
    *pfMatchingArchitecture = 256 != (iAttributes & 256);
#endif

    hr = S_OK;

LExit:
    return hr;
}
Esempio n. 4
0
/******************************************************************
 FileIdExists - checks if the file ID is found in the File table

 returns S_OK if the file exists; S_FALSE if not; otherwise, error
********************************************************************/
static HRESULT FileIdExists(
    __in_opt LPCWSTR wzFile
    )
{
    HRESULT hr = S_OK;
    PMSIHANDLE hView = NULL;
    PMSIHANDLE hRec = NULL;

    if (!wzFile)
    {
        hr = S_FALSE;
        ExitFunction();
    }

    hRec = ::MsiCreateRecord(1);
    hr = WcaSetRecordString(hRec, fiFile, wzFile);
    ExitOnFailure1(hr, "failed to create a record with the file: %ls", wzFile);

    hr = WcaTableExists(L"File");
    if (S_OK == hr)
    {
        hr = WcaOpenView(vcsFileId, &hView);
        ExitOnFailure(hr, "failed to open view on File table");

        hr = WcaExecuteView(hView, hRec);
        ExitOnFailure(hr, "failed to execute view on File table");

        // Reuse the same record; the handle will be released.
        hr = WcaFetchSingleRecord(hView, &hRec);
        ExitOnFailure(hr, "failed to fetch File from File table");
    }

LExit:

    return hr;
}
Esempio n. 5
0
HRESULT __stdcall ScaGetGroup(
    __in LPCWSTR wzGroup,
    __out SCA_GROUP* pscag
    )
{
    if (!wzGroup || !pscag)
    {
        return E_INVALIDARG;
    }

    HRESULT hr = S_OK;
    PMSIHANDLE hView, hRec;

    LPWSTR pwzData = NULL;

    hRec = ::MsiCreateRecord(1);
    hr = WcaSetRecordString(hRec, 1, wzGroup);
    ExitOnFailure(hr, "Failed to look up Group");

    hr = WcaOpenView(vcsGroupQuery, &hView);
    ExitOnFailure(hr, "Failed to open view on Group table");
    hr = WcaExecuteView(hView, hRec);
    ExitOnFailure(hr, "Failed to execute view on Group table");

    hr = WcaFetchSingleRecord(hView, &hRec);
    if (S_OK == hr)
    {
        hr = WcaGetRecordString(hRec, vgqGroup, &pwzData);
        ExitOnFailure(hr, "Failed to get Group.Group");
        hr = ::StringCchCopyW(pscag->wzKey, countof(pscag->wzKey), pwzData);
        ExitOnFailure(hr, "Failed to copy Group.Group.");

        hr = WcaGetRecordString(hRec, vgqComponent, &pwzData);
        ExitOnFailure(hr, "Failed to get Group.Component_");
        hr = ::StringCchCopyW(pscag->wzComponent, countof(pscag->wzComponent), pwzData);
        ExitOnFailure(hr, "Failed to copy Group.Component_.");

        hr = WcaGetRecordFormattedString(hRec, vgqName, &pwzData);
        ExitOnFailure(hr, "Failed to get Group.Name");
        hr = ::StringCchCopyW(pscag->wzName, countof(pscag->wzName), pwzData);
        ExitOnFailure(hr, "Failed to copy Group.Name.");

        hr = WcaGetRecordFormattedString(hRec, vgqDomain, &pwzData);
        ExitOnFailure(hr, "Failed to get Group.Domain");
        hr = ::StringCchCopyW(pscag->wzDomain, countof(pscag->wzDomain), pwzData);
        ExitOnFailure(hr, "Failed to copy Group.Domain.");
    }
    else if (E_NOMOREITEMS == hr)
    {
        WcaLog(LOGMSG_STANDARD, "Error: Cannot locate Group.Group='%ls'", wzGroup);
        hr = E_FAIL;
    }
    else
    {
        ExitOnFailure(hr, "Error or found multiple matching Group rows");
    }

LExit:
    ReleaseStr(pwzData);

    return hr;
}
Esempio n. 6
0
/******************************************************************
 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);
}
Esempio n. 7
0
HRESULT ScaWebAppExtensionsRead(
    LPCWSTR wzApplication,
    SCA_WEB_APPLICATION_EXTENSION** ppswappextList
)
{
    HRESULT hr = S_OK;
    PMSIHANDLE hView, hRec;

    SCA_WEB_APPLICATION_EXTENSION* pswappext = NULL;
    LPWSTR pwzData = NULL;

    // check pre-requisites
    hr = WcaTableExists(L"IIsWebApplicationExtension");
    if (S_FALSE == hr)
        ExitFunction();

    // convert the string into a msi record
    hRec = ::MsiCreateRecord(1);
    hr = WcaSetRecordString(hRec, 1, wzApplication);
    ExitOnFailure(hr, "Failed to set record to look up Web Application");

    // open and execute the view on the applicatoin extension table
    hr = WcaOpenView(vcsWebAppExtensionQuery, &hView);
    ExitOnFailure(hr, "Failed to open view on IIsWebApplicationExtension table");

    hr = WcaExecuteView(hView, hRec);
    ExitOnFailure1(hr, "Failed to execute view on IIsWebApplicationExtension table looking Application: %S", wzApplication);

    // get the application extention information
    while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
    {
        hr = NewAppExt(&pswappext);
        ExitOnFailure(hr, "failed to create new web app extension");

        // get the extension
        hr = WcaGetRecordString(hRec, wappextqExtension, &pwzData);
        ExitOnFailure(hr, "Failed to get Web Application Extension");
        StringCchCopyW(pswappext->wzExtension, countof(pswappext->wzExtension), pwzData);

        // application extension verbs
        hr = WcaGetRecordString(hRec, wappextqVerbs, &pwzData);
        ExitOnFailure1(hr, "Failed to get Verbs for Application: '%S'", wzApplication);
        StringCchCopyW(pswappext->wzVerbs, countof(pswappext->wzVerbs), pwzData);

        // extension executeable
        hr = WcaGetRecordFormattedString(hRec, wappextqExecutable, &pwzData);
        ExitOnFailure1(hr, "Failed to get Executable for Application: '%S'", wzApplication);
        StringCchCopyW(pswappext->wzExecutable, countof(pswappext->wzExecutable), pwzData);

        hr = WcaGetRecordInteger(hRec, wappextqAttributes, &pswappext->iAttributes);
        if (S_FALSE == hr)
        {
            pswappext->iAttributes = 0;
            hr = S_OK;
        }
        ExitOnFailure(hr, "Failed to get App isolation");

        *ppswappextList = AddAppExtToList(*ppswappextList, pswappext);
        pswappext = NULL;	// set the appext NULL so it doesn't accidentally get freed below
    }

    if (E_NOMOREITEMS == hr)
        hr = S_OK;

LExit:
    // if anything was left over after an error clean it all up
    if (pswappext)
        ScaWebAppExtensionsFreeList(pswappext);

    ReleaseStr(pwzData);

    return hr;
}
Esempio n. 8
0
HRESULT CpiPropertiesRead(
    LPCWSTR pwzQuery,
    LPCWSTR pwzKey,
    CPI_PROPERTY_DEFINITION* pPropDefList,
    CPI_PROPERTY** ppPropList,
    int* piCount
    )
{
    HRESULT hr = S_OK;

    PMSIHANDLE hView, hRecKey, hRec;

    CPI_PROPERTY* pItm = NULL;
    LPWSTR pwzData = NULL;

    int iVersionNT = 0;

    CPI_PROPERTY_DEFINITION* pPropDef;

    *piCount = 0;

    // get NT version
    hr = WcaGetIntProperty(L"VersionNT", &iVersionNT);
    ExitOnFailure(hr, "Failed to set record string");

    // create parameter record
    hRecKey = ::MsiCreateRecord(1);
    ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
    hr = WcaSetRecordString(hRecKey, 1, pwzKey);
    ExitOnFailure(hr, "Failed to set record string");

    // open view
    hr = WcaOpenView(pwzQuery, &hView);
    ExitOnFailure(hr, "Failed to open view on property table");
    hr = WcaExecuteView(hView, hRecKey);
    ExitOnFailure(hr, "Failed to execute view on property table");

    while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
    {
        // create entry
        pItm = (CPI_PROPERTY*)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CPI_PROPERTY));
        if (!pItm)
            ExitFunction1(hr = E_OUTOFMEMORY);

        // get name
        hr = WcaGetRecordString(hRec, pqName, &pwzData);
        ExitOnFailure(hr, "Failed to get name");
        StringCchCopyW(pItm->wzName, countof(pItm->wzName), pwzData);

        // get value
        hr = WcaGetRecordFormattedString(hRec, pqValue, &pItm->pwzValue);
        ExitOnFailure(hr, "Failed to get value");

        // find property definition
        hr = FindPropertyDefinition(pPropDefList, pItm->wzName, &pPropDef);
        ExitOnFailure(hr, "Failed to find property definition");

        if (S_FALSE == hr)
            ExitOnFailure(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unknown property, key: %S, property: %S", pwzKey, pItm->wzName);

        // check version, ignore if catalog version is too low
        if (iVersionNT < pPropDef->iMinVersionNT)
        {
            WcaLog(LOGMSG_VERBOSE, "Skipping property since NT version is too low, key: %S, property: %S", pwzKey, pItm->wzName);
            CpiPropertiesFreeList(pItm);
            pItm = NULL;
            continue;
        }

        // if the property is a user, replace the User table key with a user account name
        if (cpptUser == pPropDef->iType)
        {
            hr = GetUserAccountName(pItm->pwzValue, &pItm->pwzValue);
            ExitOnFailure(hr, "Failed to get user account name");
        }

        // add entry
        ++*piCount;
        if (*ppPropList)
            pItm->pNext = *ppPropList;
        *ppPropList = pItm;
        pItm = NULL;
    }

    if (E_NOMOREITEMS == hr)
        hr = S_OK;

LExit:
    // clean up
    if (pItm)
        CpiPropertiesFreeList(pItm);

    ReleaseStr(pwzData);

    return hr;
}
Esempio n. 9
0
HRESULT ScaWebsRead(
	__in IMSAdminBase* piMetabase,
	__in SCA_WEB** ppswList,
	__in SCA_HTTP_HEADER** ppshhList,
	__in SCA_WEB_ERROR** ppsweList
	)
{
	Assert(piMetabase && ppswList);

	HRESULT hr = S_OK;
	UINT er = ERROR_SUCCESS;

	BOOL fIIsWebSiteTable = FALSE;
	BOOL fIIsWebAddressTable = FALSE;
	BOOL fIIsWebApplicationTable = FALSE;

	PMSIHANDLE hView, hRec;
	PMSIHANDLE hViewAddresses, hRecAddresses;
	PMSIHANDLE hViewApplications, hRecApplications;

	SCA_WEB* psw = NULL;
	LPWSTR pwzData = NULL;

	DWORD dwLen = 0;

	// check to see what tables are available
	fIIsWebSiteTable = (S_OK == WcaTableExists(L"IIsWebSite"));
	fIIsWebAddressTable = (S_OK == WcaTableExists(L"IIsWebAddress"));
	fIIsWebApplicationTable = (S_OK == WcaTableExists(L"IIsWebApplication"));

	if (!fIIsWebSiteTable || !fIIsWebAddressTable)
	{
		WcaLog(LOGMSG_VERBOSE, "Required tables not present");
		hr = S_FALSE;
		goto LExit;
	}

	// open the view on webs' addresses
	hr = WcaOpenView(vcsWebAddressQuery, &hViewAddresses);
	ExitOnFailure(hr, "Failed to open view on IIsWebAddress table");

	// open the view on webs' applications
	if (fIIsWebApplicationTable)
	{
		hr = WcaOpenView(vcsWebApplicationQuery, &hViewApplications);
		ExitOnFailure(hr, "Failed to open view on IIsWebApplication table");
	}

	// loop through all the webs
	hr = WcaOpenExecuteView(vcsWebQuery, &hView);
	ExitOnFailure(hr, "Failed to execute view on IIsWebSite table");
	while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
	{
		psw = NewWeb();
		if (!psw)
		{
			hr = E_OUTOFMEMORY;
			break;
		}

		// get the darwin information
		hr = WcaGetRecordString(hRec, wqWeb, &pwzData);
		ExitOnFailure(hr, "Failed to get Web");
		StringCchCopyW(psw->wzKey, countof(psw->wzKey), pwzData);

		// get component install state
		hr = WcaGetRecordString(hRec, wqComponent, &pwzData);
		ExitOnFailure(hr, "Failed to get Component for Web");
		StringCchCopyW(psw->wzComponent, countof(psw->wzComponent), pwzData);
		if (*(psw->wzComponent))
		{
			psw->fHasComponent = TRUE;

			er = ::MsiGetComponentStateW(WcaGetInstallHandle(), psw->wzComponent, &psw->isInstalled, &psw->isAction);
			hr = HRESULT_FROM_WIN32(er);
			ExitOnFailure(hr, "Failed to get web Component state");
		}

		// get the web's key address
		hr = WcaGetRecordString(hRec, wqAddress, &pwzData);
		ExitOnFailure(hr, "Failed to get Address for Web");
		StringCchCopyW(psw->swaKey.wzKey, countof(psw->swaKey.wzKey), pwzData);

		hr = WcaGetRecordFormattedString(hRec, wqIP, &pwzData);
		ExitOnFailure(hr, "Failed to get IP for Web");
		StringCchCopyW(psw->swaKey.wzIP, countof(psw->swaKey.wzIP), pwzData);

		hr = WcaGetRecordFormattedString(hRec, wqPort, &pwzData);
		ExitOnFailure(hr, "Failed to get Web Address port");
		psw->swaKey.iPort = wcstol(pwzData, NULL, 10);
		if (0 == psw->swaKey.iPort)
			ExitOnFailure1(hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA), "invalid port provided for web site: %S", psw->wzDescription);

		hr = WcaGetRecordFormattedString(hRec, wqHeader, &pwzData);
		ExitOnFailure(hr, "Failed to get Header for Web");
		StringCchCopyW(psw->swaKey.wzHeader, countof(psw->swaKey.wzHeader), pwzData);

		hr = WcaGetRecordInteger(hRec, wqSecure, &psw->swaKey.fSecure);
		ExitOnFailure(hr, "Failed to get if Web is secure");
		if (S_FALSE == hr)
			psw->swaKey.fSecure = FALSE;

		// TODO: fix this to look for the description as well (or is address enough)?
		// find the web root
		dwLen = METADATA_MAX_NAME_LEN;
		hr = ScaWebFindBase(piMetabase, *ppswList,
							psw->wzKey,
							psw->swaKey.wzIP,
							psw->swaKey.iPort,
							psw->swaKey.wzHeader,
							psw->swaKey.fSecure,
							psw->wzWebBase, &dwLen);
		if (S_OK == hr)
		{
			psw->fBaseExists = TRUE;
		}
		else if (S_FALSE == hr && FALSE == psw->fHasComponent) // if we're not installing it, fail if it wasn't found
		{
			ExitOnFailure1(hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "failed to find web site: '%S'", psw->wzKey);
		}
		else if (S_FALSE == hr)
		{
			dwLen = METADATA_MAX_NAME_LEN;
			hr = ScaWebFindFreeBase(piMetabase, *ppswList, psw->wzWebBase, dwLen);
			psw->fBaseExists = FALSE;
		}
		ExitOnFailure(hr, "Failed to find web root");

		// get any extra web addresses
		hr = WcaExecuteView(hViewAddresses, hRec);
		ExitOnFailure(hr, "Failed to execute view on extra IIsWebAddress table");
		while (S_OK == (hr = WcaFetchRecord(hViewAddresses, &hRecAddresses)))
		{
			if (MAX_ADDRESSES_PER_WEB <= psw->cExtraAddresses)
			{
				hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
				ExitOnFailure(hr, "Failure to get more extra web addresses, max exceeded.");
			}

			hr = WcaGetRecordString(hRecAddresses, waqAddress, &pwzData);
			ExitOnFailure(hr, "Failed to get extra web Address");

			// if this isn't the key address add it
			if (0 != lstrcmpW(pwzData, psw->swaKey.wzKey))
			{
				StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey,
					countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzKey), pwzData);

				hr = WcaGetRecordFormattedString(hRecAddresses, waqIP, &pwzData);
				ExitOnFailure(hr, "Failed to get extra web IP");
				StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzIP), pwzData);

				hr = WcaGetRecordFormattedString(hRecAddresses, waqPort, &pwzData);
				ExitOnFailure(hr, "Failed to get port for extra web IP");
				psw->swaExtraAddresses[psw->cExtraAddresses].iPort= wcstol(pwzData, NULL, 10);

				hr = WcaGetRecordFormattedString(hRecAddresses, waqHeader, &pwzData);
				ExitOnFailure(hr, "Failed to get header for extra web IP");
				StringCchCopyW(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader, countof(psw->swaExtraAddresses[psw->cExtraAddresses].wzHeader), pwzData);

				hr = WcaGetRecordInteger(hRecAddresses, waqSecure, &psw->swaExtraAddresses[psw->cExtraAddresses].fSecure);
				ExitOnFailure(hr, "Failed to get if secure extra web IP");
				if (S_FALSE == hr)
					psw->swaExtraAddresses[psw->cExtraAddresses].fSecure = FALSE;

				psw->cExtraAddresses++;
			}
		}

		if (E_NOMOREITEMS == hr)
			hr = S_OK;
		ExitOnFailure(hr, "Failure occured while getting extra web addresses");

		// get the web's description
		hr = WcaGetRecordFormattedString(hRec, wqDescription, &pwzData);
		ExitOnFailure(hr, "Failed to get Description for Web");
		StringCchCopyW(psw->wzDescription, countof(psw->wzDescription), pwzData);

		hr = WcaGetRecordInteger(hRec, wqConnectionTimeout, &psw->iConnectionTimeout);
		ExitOnFailure(hr, "Failed to get connection timeout for Web");

		if (psw->fHasComponent) // If we're installing it, it needs a dir
		{
			// get the web's directory
			hr = WcaGetRecordString(hRec, wqDirectory, &pwzData);
			ExitOnFailure(hr, "Failed to get Directory for Web");

			WCHAR wzPath[MAX_PATH];
			dwLen = countof(wzPath);
			if (INSTALLSTATE_SOURCE == psw->isAction)
				er = ::MsiGetSourcePathW(WcaGetInstallHandle(), pwzData, wzPath, &dwLen);
			else
				er = ::MsiGetTargetPathW(WcaGetInstallHandle(), pwzData, wzPath, &dwLen);
			hr = HRESULT_FROM_WIN32(er);
			ExitOnFailure(hr, "Failed to get Source/TargetPath for Directory");

			if (dwLen > countof(wzPath))
			{
				hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
				ExitOnFailure(hr, "Failed because Source/TargetPath for Directory was greater than MAX_PATH.");
			}

			// remove traling backslash
			if (dwLen > 0 && wzPath[dwLen-1] == L'\\')
				wzPath[dwLen-1] = 0;
			StringCchCopyW(psw->wzDirectory, countof(psw->wzDirectory), wzPath);
		}

		hr = WcaGetRecordInteger(hRec, wqState, &psw->iState);
		ExitOnFailure(hr, "Failed to get state for Web");

		hr = WcaGetRecordInteger(hRec, wqAttributes, &psw->iAttributes);
		ExitOnFailure(hr, "Failed to get attributes for Web");

		// get the dir properties for this web
		hr = WcaGetRecordString(hRec, wqProperties, &pwzData);
		ExitOnFailure(hr, "Failed to get directory properties for Web");
		if (*pwzData)
		{
			hr = ScaGetWebDirProperties(pwzData, &psw->swp);
			ExitOnFailure(hr, "Failed to get directory properties for Web");

			psw->fHasProperties = TRUE;
		}

		// get the application information for this web
		hr = WcaGetRecordString(hRec, wqApplication, &pwzData);
		ExitOnFailure(hr, "Failed to get application identifier for Web");
		if (*pwzData)
		{
			hr = ScaGetWebApplication(NULL, pwzData, &psw->swapp);
			ExitOnFailure(hr, "Failed to get application for Web");

			psw->fHasApplication = TRUE;
		}

		// get the SSL certificates
		hr = ScaSslCertificateRead(psw->wzKey, &(psw->pswscList));
		ExitOnFailure(hr, "Failed to get SSL Certificates.");

		// get the custom headers
		if (*ppshhList)
		{
			hr = ScaGetHttpHeader(hhptWeb, psw->wzKey, ppshhList, &(psw->pshhList));
			ExitOnFailure(hr, "Failed to get Custom HTTP Headers");
		}

		// get the errors
		if (*ppsweList)
		{
			hr = ScaGetWebError(weptWeb, psw->wzKey, ppsweList, &(psw->psweList));
			ExitOnFailure(hr, "Failed to get Custom Errors");
		}

		// get the log information for this web
		hr = WcaGetRecordString(hRec, wqLog, &pwzData);
		ExitOnFailure(hr, "Failed to get log identifier for Web");
		if (*pwzData)
		{
			hr = ScaGetWebLog(piMetabase, pwzData, &psw->swl);
			ExitOnFailure(hr, "Failed to get Log for Web.");

			psw->fHasLog = TRUE;
		}

		*ppswList = AddWebToList(*ppswList, psw);
		psw = NULL; // set the web NULL so it doesn't accidentally get freed below
	}

	if (E_NOMOREITEMS == hr)
		hr = S_OK;

LExit:
	// if anything was left over after an error clean it all up
	if (psw)
		ScaWebsFreeList(psw);

	ReleaseStr(pwzData);

	return hr;
}
Esempio n. 10
0
HRESULT ScaSqlStrsReadScripts(
    __inout SCA_SQLSTR** ppsssList,
    __in SCA_ACTION saAction
    )
{
    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;

    PMSIHANDLE hView, hRec;
    PMSIHANDLE hViewBinary, hRecBinary;
    PMSIHANDLE hViewUser, hRecUser;

    LPWSTR pwzComponent = NULL;
    LPWSTR pwzData = NULL;

    BYTE* pbScript = NULL;
    DWORD cbRead = 0;
    DWORD cbScript = 0;
    DWORD cchScript = 0;

    LPWSTR pwzScriptBuffer = NULL;
    WCHAR* pwzScript = NULL;
    WCHAR* pwz;
    DWORD cch = 0;

    SCA_SQLSTR sss;
    SCA_SQLSTR* psss = NULL;

    if (S_OK != WcaTableExists(L"SqlScript") || S_OK != WcaTableExists(L"SqlDatabase") || S_OK != WcaTableExists(L"Binary"))
    {
        WcaLog(LOGMSG_VERBOSE, "Skipping ScaSqlStrsReadScripts() - SqlScripts and/or SqlDatabase table not present");
        ExitFunction1(hr = S_FALSE);
    }

    // open a view on the binary table
    hr = WcaOpenView(vcsSqlBinaryScriptQuery, &hViewBinary);
    ExitOnFailure(hr, "Failed to open view on Binary table for SqlScripts");

    // loop through all the sql scripts
    hr = WcaOpenExecuteView(vcsSqlScriptQuery, &hView);
    ExitOnFailure(hr, "Failed to open view on SqlScript table");
    while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
    {
        INSTALLSTATE isInstalled = INSTALLSTATE_UNKNOWN;
        INSTALLSTATE isAction = INSTALLSTATE_UNKNOWN;

        hr = WcaGetRecordString(hRec, sscrqComponent, &pwzComponent);
        ExitOnFailure(hr, "Failed to get Component for SQL Script.");

        er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzComponent, &isInstalled, &isAction);
        hr = HRESULT_FROM_WIN32(er);
        ExitOnFailure1(hr, "Failed to get state for component: %ls", pwzComponent);

        // If we're doing install but the Component is not being installed or we're doing
        // uninstall but the Component is not being uninstalled, skip it.
        if ((WcaIsInstalling(isInstalled, isAction) && SCA_ACTION_INSTALL != saAction) ||
            (WcaIsUninstalling(isInstalled, isAction) && SCA_ACTION_UNINSTALL != saAction))
        {
            continue;
        }

        ::ZeroMemory(&sss, sizeof(sss));

        sss.isInstalled = isInstalled;
        sss.isAction = isAction;

        hr = WcaGetRecordString(hRec, sscrqSqlScript, &pwzData);
        ExitOnFailure(hr, "Failed to get SqlScript.Script");
        hr = ::StringCchCopyW(sss.wzKey, countof(sss.wzKey), pwzData);
        ExitOnFailure1(hr, "Failed to copy SqlScript.Script: %ls", pwzData);

        // find the database information for this string
        hr = WcaGetRecordString(hRec, sscrqSqlDb, &pwzData);
        ExitOnFailure1(hr, "Failed to get SqlScript.SqlDb_ for SqlScript '%ls'", sss.wzKey);
        hr = ::StringCchCopyW(sss.wzSqlDb, countof(sss.wzSqlDb), pwzData);
        ExitOnFailure1(hr, "Failed to copy SqlScritp.SqlDbb: %ls", pwzData);

        hr = WcaGetRecordInteger(hRec, sscrqAttributes, &sss.iAttributes);
        ExitOnFailure1(hr, "Failed to get SqlScript.Attributes for SqlScript '%ls'", sss.wzKey);

        hr = WcaGetRecordInteger(hRec, sscrqSequence, &sss.iSequence);
        ExitOnFailure1(hr, "Failed to get SqlScript.Sequence for SqlScript '%ls'", sss.wzKey);

        // get the sql script out of the binary stream
        hr = WcaExecuteView(hViewBinary, hRec);
        ExitOnFailure1(hr, "Failed to open SqlScript.BinaryScript_ for SqlScript '%ls'", sss.wzKey);
        hr = WcaFetchSingleRecord(hViewBinary, &hRecBinary);
        ExitOnFailure1(hr, "Failed to fetch SqlScript.BinaryScript_ for SqlScript '%ls'", sss.wzKey);

        // Note: We need to allocate an extra character on the stream to NULL terminate the SQL script.
        //       The WcaGetRecordStream() function won't let us add extra space on the end of the stream
        //       so we'll read the stream "the old fashioned way".
        //hr = WcaGetRecordStream(hRecBinary, ssbsqData, (BYTE**)&pbScript, &cbScript);
        //ExitOnFailure1(hr, "Failed to read SqlScript.BinaryScript_ for SqlScript '%ls'", sss.wzKey);
        er = ::MsiRecordReadStream(hRecBinary, ssbsqData, NULL, &cbRead);
        hr = HRESULT_FROM_WIN32(er);
        ExitOnFailure(hr, "failed to get size of stream");

        cbScript = cbRead + sizeof(WCHAR); // we may have an ANSI SQL script but leave enough to even NULL terminate a WCHAR string
        hr = WcaAllocStream(&pbScript, cbScript); // this will allocate a fully zeroed out buffer so our string will be NULL terminated
        ExitOnFailure(hr, "failed to allocate data for stream");

        er = ::MsiRecordReadStream(hRecBinary, ssbsqData, reinterpret_cast<char*>(pbScript), &cbRead); //read the buffer but leave the space for the NULL terminator
        hr = HRESULT_FROM_WIN32(er);
        ExitOnFailure(hr, "failed to read from stream");

        Assert(cbRead + sizeof(WCHAR) == cbScript);

        // Check for the UNICODE BOM file marker.
        if ((0xFF == *pbScript) && (0xFE == *(pbScript + 1)))
        {
            // Copy the UNICODE string after the BOM marker (subtract one because we'll skip the BOM marker).
            cchScript = (cbScript / sizeof(WCHAR)) - 1;

            hr = StrAllocString(&pwzScriptBuffer, reinterpret_cast<LPWSTR>(pbScript) + 1, 0);
            ExitOnFailure1(hr, "Failed to allocate WCHAR string of size '%d'", cchScript);
        }
        else
        {
            // We have an ANSI string so convert it to UNICODE.
            cchScript = cbScript;

            hr = StrAllocStringAnsi(&pwzScriptBuffer, reinterpret_cast<LPCSTR>(pbScript), 0, CP_ACP);
            ExitOnFailure1(hr, "Failed to allocate WCHAR string of size '%d'", cchScript);
        }

        // Free the byte buffer since it has been converted to a new UNICODE string, one way or another.
        if (pbScript)
        {
            WcaFreeStream(pbScript);
            pbScript = NULL;
        }

        // Process the SQL script stripping out unnecessary stuff (like comments) and looking for "GO" statements.
        pwzScript = pwzScriptBuffer;
        while (cchScript && pwzScript && *pwzScript)
        {
            // strip off leading whitespace
            while (cchScript && *pwzScript && iswspace(*pwzScript))
            {
                ++pwzScript;
                --cchScript;
            }

            Assert(0 <= cchScript);

            // if there is a SQL comment remove it
            while (cchScript && L'/' == *pwzScript && L'*' == *(pwzScript + 1))
            {
                // go until end of comment
                while (cchScript && *pwzScript && *(pwzScript + 1) && !(L'*' == *pwzScript && L'/' == *(pwzScript + 1)))
                {
                    ++pwzScript;
                    --cchScript;
                }

                Assert(2 <= cchScript);

                if (2 <= cchScript)
                {
                    // to account for */ at end
                    pwzScript+=2;
                    cchScript-=2;
                }

                Assert(0 <= cchScript);

                // strip off any new leading whitespace
                while (cchScript && *pwzScript && iswspace(*pwzScript))
                {
                    ++pwzScript;
                    --cchScript;
                }
            }

            while (cchScript && L'-' == *pwzScript && L'-' == *(pwzScript + 1))
            {
                // go past the new line character
                while (cchScript && *pwzScript && L'\n' != *pwzScript)
                {
                    ++pwzScript;
                    --cchScript;
                }

                Assert(0 <= cchScript);

                if (cchScript && L'\n' == *pwzScript)
                {
                    ++pwzScript;
                    --cchScript;
                }

                Assert(0 <= cchScript);

                // strip off any new leading whitespace
                while (cchScript && *pwzScript && iswspace(*pwzScript))
                {
                    ++pwzScript;
                    --cchScript;
                }
            }

            Assert(0 <= cchScript);

            // try to isolate a "GO" keyword and count the characters in the SQL string
            pwz = pwzScript;
            cch = 0;
            while (cchScript && *pwz)
            {
                //skip past comment lines that might have "go" in them
                //note that these comments are "in the middle" of our function,
                //or possibly at the end of a line
                if (cchScript && L'-' == *pwz && L'-' == *(pwz + 1))
                {
                    // skip past chars until the new line character
                    while (cchScript && *pwz && (L'\n' != *pwz))
                    {
                        ++pwz;
                        ++cch;
                        --cchScript;
                    }
                }

                //skip past comment lines of form /* to */ that might have "go" in them
                //note that these comments are "in the middle" of our function,
                //or possibly at the end of a line
                if (cchScript && L'/' == *pwz && L'*' == *(pwz + 1))
                {
                    // skip past chars until the new line character
                    while (cchScript && *pwz && *(pwz + 1) && !((L'*' == *pwz) && (L'/' == *(pwz + 1))))
                    {
                        ++pwz;
                        ++cch;
                        --cchScript;
                    }

                    if (2 <= cchScript)
                    {
                        // to account for */ at end
                        pwz+=2;
                        cch+=2;
                        cchScript-=2;
                    }
                }

                // Skip past strings that may be part of the SQL statement that might have a "go" in them
                if ( cchScript && L'\'' == *pwz )
                {
                    ++pwz;
                    ++cch;
                    --cchScript;

                    // Skip past chars until the end of the string
                    while ( cchScript && *pwz && !(L'\'' == *pwz) )
                    {
                        ++pwz;
                        ++cch;
                        --cchScript;
                    }
                }

                // Skip past strings that may be part of the SQL statement that might have a "go" in them
                if ( cchScript && L'\"' == *pwz )
                {
                    ++pwz;
                    ++cch;
                    --cchScript;

                    // Skip past chars until the end of the string
                    while ( cchScript && *pwz && !(L'\"' == *pwz) )
                    {
                        ++pwz;
                        ++cch;
                        --cchScript;
                    }
                }

                // if "GO" is isolated
                if ((pwzScript == pwz || iswspace(*(pwz - 1))) && 
                    (L'G' == *pwz || L'g' == *pwz) && 
                    (L'O' == *(pwz + 1) || L'o' == *(pwz + 1)) &&
                    (0 == *(pwz + 2) || iswspace(*(pwz + 2))))
                {
                    *pwz = 0; // null terminate the SQL string on the "G"
                    pwz += 2;
                    cchScript -= 2;
                    break;   // found "GO" now add SQL string to list
                }

                ++pwz;
                ++cch;
                --cchScript;
            }

            Assert(0 <= cchScript);

            if (0 < cch) //don't process if there's nothing to process
            {
                // replace tabs with spaces
                for (LPWSTR pwzTab = wcsstr(pwzScript, L"\t"); pwzTab; pwzTab = wcsstr(pwzTab, L"\t"))
                    *pwzTab = ' ';

                // strip off whitespace at the end of the script string
                for (LPWSTR pwzErase = pwzScript + cch - 1; pwzScript < pwzErase && iswspace(*pwzErase); pwzErase--)
                {
                    *(pwzErase) = 0;
                    cch--;
                }
            }

            if (0 < cch)
            {
                hr = NewSqlStr(&psss);
                ExitOnFailure(hr, "failed to allocate new sql string element");

                // copy everything over
                hr = ::StringCchCopyW(psss->wzKey, countof(psss->wzKey), sss.wzKey);
                ExitOnFailure(hr, "Failed to copy key string to sqlstr object");
                hr = ::StringCchCopyW(psss->wzSqlDb, countof(psss->wzSqlDb), sss.wzSqlDb);
                ExitOnFailure(hr, "Failed to copy DB string to sqlstr object");
                hr = ::StringCchCopyW(psss->wzComponent, countof(psss->wzComponent), sss.wzComponent);
                ExitOnFailure(hr, "Failed to copy component string to sqlstr object");
                psss->isInstalled = sss.isInstalled;
                psss->isAction = sss.isAction;
                psss->iAttributes = sss.iAttributes;
                psss->iSequence = sss.iSequence;

                // cchRequired includes the NULL terminating char
                hr = StrAllocString(&psss->pwzSql, pwzScript, 0);
                ExitOnFailure1(hr, "Failed to allocate string for SQL script: '%ls'", psss->wzKey);

                *ppsssList = AddSqlStrToList(*ppsssList, psss);
                psss = NULL; // set the db NULL so it doesn't accidentally get freed below
            }

            pwzScript = pwz;
        }
    }

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

LExit:
    // if anything was left over after an error clean it all up
    if (psss)
    {
        ScaSqlStrsFreeList(psss);
    }

    if (pbScript)
    {
        WcaFreeStream(pbScript);
    }

    ReleaseStr(pwzScriptBuffer);
    ReleaseStr(pwzData);
    ReleaseStr(pwzComponent);

    return hr;
}
Esempio n. 11
0
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;
}
Esempio n. 12
0
/******************************************************************
 SchedNetFx - entry point for NetFx Custom Action

********************************************************************/
extern "C" UINT __stdcall SchedNetFx(
    __in MSIHANDLE hInstall
    )
{
    // AssertSz(FALSE, "debug SchedNetFx");

    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;

    LPWSTR pwzInstallCustomActionData = NULL;
    LPWSTR pwzUninstallCustomActionData = NULL;
    UINT uiCost = 0;

    PMSIHANDLE hView = NULL;
    PMSIHANDLE hRec = NULL;
    PMSIHANDLE hViewGac = NULL;
    PMSIHANDLE hRecGac = NULL;

    LPWSTR pwzId = NULL;
    LPWSTR pwzData = NULL;
    LPWSTR pwzTemp = NULL;
    LPWSTR pwzFile = NULL;
    int iPriority = 0;
    int iAssemblyCost = 0;
    int iAttributes = 0;
    LPWSTR pwzFileApp = NULL;
    LPWSTR pwzDirAppBase = NULL;
    LPWSTR pwzComponent = NULL;

    INSTALLSTATE isInstalled;
    INSTALLSTATE isAction;

    LPWSTR pwz32Ngen = NULL;
    LPWSTR pwz64Ngen = NULL;

    BOOL f32NgenExeExists = FALSE;
    BOOL f64NgenExeExists = FALSE;

    BOOL fNeedInstallUpdate32 = FALSE;
    BOOL fNeedUninstallUpdate32 = FALSE;
    BOOL fNeedInstallUpdate64 = FALSE;
    BOOL fNeedUninstallUpdate64 = FALSE;

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

    hr = GetNgenPath(&pwz32Ngen, FALSE);
    f32NgenExeExists = SUCCEEDED(hr);
    if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr)
    {
        hr = ERROR_SUCCESS;
        WcaLog(LOGMSG_STANDARD, "Failed to find 32bit ngen. No actions will be scheduled to create native images for 32bit.");
    }
    ExitOnFailure(hr, "failed to get 32bit ngen.exe path");

    hr = GetNgenPath(&pwz64Ngen, TRUE);
    f64NgenExeExists = SUCCEEDED(hr);
    if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr || HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr)
    {
        hr = ERROR_SUCCESS;
        WcaLog(LOGMSG_STANDARD, "Failed to find 64bit ngen. No actions will be scheduled to create native images for 64bit.");
    }
    ExitOnFailure(hr, "failed to get 64bit ngen.exe path");

    // loop through all the NetFx records
    hr = WcaOpenExecuteView(vcsNgenQuery, &hView);
    ExitOnFailure(hr, "failed to open view on NetFxNativeImage table");

    while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
    {
        // Get Id
        hr = WcaGetRecordString(hRec, ngqId, &pwzId);
        ExitOnFailure(hr, "failed to get NetFxNativeImage.NetFxNativeImage");

        // Get File
        hr = WcaGetRecordString(hRec, ngqFile, &pwzData);
        ExitOnFailure1(hr, "failed to get NetFxNativeImage.File_ for record: %ls", pwzId);
        hr = StrAllocFormatted(&pwzTemp, vpwzUnformattedQuotedFile, pwzData);
        ExitOnFailure1(hr, "failed to format file string for file: %ls", pwzData);
        hr = WcaGetFormattedString(pwzTemp, &pwzFile);
        ExitOnFailure1(hr, "failed to get formatted string for file: %ls", pwzData);

        // Get Priority
        hr = WcaGetRecordInteger(hRec, ngqPriority, &iPriority);
        ExitOnFailure1(hr, "failed to get NetFxNativeImage.Priority for record: %ls", pwzId);

        if (0 == iPriority)
            iAssemblyCost = COST_NGEN_BLOCKING;
        else
            iAssemblyCost = COST_NGEN_NONBLOCKING;

        // Get Attributes
        hr = WcaGetRecordInteger(hRec, ngqAttributes, &iAttributes);
        ExitOnFailure1(hr, "failed to get NetFxNativeImage.Attributes for record: %ls", pwzId);

        // Get File_Application or leave pwzFileApp NULL.
        hr = WcaGetRecordFormattedString(hRec, ngqFileApp, &pwzData);
        ExitOnFailure1(hr, "failed to get NetFxNativeImage.File_Application for record: %ls", pwzId);

        // Check if the value resolves to a valid file ID.
        if (S_OK == FileIdExists(pwzData))
        {
            // Resolve the file ID to a path.
            hr = StrAllocFormatted(&pwzTemp, vpwzUnformattedQuotedFile, pwzData);
            ExitOnFailure1(hr, "failed to format file application string for file: %ls", pwzData);

            hr = WcaGetFormattedString(pwzTemp, &pwzFileApp);
            ExitOnFailure1(hr, "failed to get formatted string for file application: %ls", pwzData);
        }
        else
        {
            // Assume record formatted to a path already.
            hr = StrAllocString(&pwzFileApp, pwzData, 0);
            ExitOnFailure1(hr, "failed to allocate string for file path: %ls", pwzData);

            hr = PathEnsureQuoted(&pwzFileApp, FALSE);
            ExitOnFailure1(hr, "failed to quote file path: %ls", pwzData);
        }

        // Get Directory_ApplicationBase or leave pwzDirAppBase NULL.
        hr = WcaGetRecordFormattedString(hRec, ngqDirAppBase, &pwzData);
        ExitOnFailure1(hr, "failed to get NetFxNativeImage.Directory_ApplicationBase for record: %ls", pwzId);

        if (WcaIsUnicodePropertySet(pwzData))
        {
            // Resolve the directory ID to a path.
            hr = StrAllocFormatted(&pwzTemp, vpwzUnformattedQuotedDirectory, pwzData);
            ExitOnFailure1(hr, "failed to format directory application base string for property: %ls", pwzData);

            hr = WcaGetFormattedString(pwzTemp, &pwzDirAppBase);
            ExitOnFailure1(hr, "failed to get formatted string for directory application base: %ls", pwzData);
        }
        else
        {
            // Assume record formatted to a path already.
            hr = StrAllocString(&pwzDirAppBase, pwzData, 0);
            ExitOnFailure1(hr, "failed to allocate string for directory path: %ls", pwzData);

            hr = PathEnsureQuoted(&pwzDirAppBase, TRUE);
            ExitOnFailure1(hr, "failed to quote and backslashify directory: %ls", pwzData);
        }

        // Get Component
        hr = WcaGetRecordString(hRec, ngqComponent, &pwzComponent);
        ExitOnFailure1(hr, "failed to get NetFxNativeImage.Directory_ApplicationBase for record: %ls", pwzId);
        er = ::MsiGetComponentStateW(hInstall, pwzComponent, &isInstalled, &isAction);
        ExitOnWin32Error1(er, hr, "failed to get install state for Component: %ls", pwzComponent);

        //
        // Figure out if it's going to be GAC'd.  The possibility exists that no assemblies are going to be GAC'd 
        // so we have to check for the MsiAssembly table first.
        //
        if (S_OK == WcaTableExists(L"MsiAssembly"))
        {
            hr = WcaOpenView(vcsNgenGac, &hViewGac);
            ExitOnFailure(hr, "failed to open view on File/MsiAssembly table");

            hr = WcaExecuteView(hViewGac, hRec);
            ExitOnFailure(hr, "failed to execute view on File/MsiAssembly table");

            hr = WcaFetchSingleRecord(hViewGac, &hRecGac);
            ExitOnFailure(hr, "failed to fetch File_Assembly from File/MsiAssembly table");

            if (S_FALSE != hr)
            {
                hr = WcaGetRecordString(hRecGac, nggApplication, &pwzData);
                ExitOnFailure(hr, "failed to get MsiAssembly.File_Application");

                // If it's in the GAC replace the file name with the strong name
                if (L'\0' == pwzData[0])
                {
                    hr = GetStrongName(&pwzFile, pwzComponent);
                    ExitOnFailure1(hr, "failed to get strong name for component: %ls", pwzData);
                }
            }
        }

        //
        // Schedule the work
        //
        if (!(iAttributes & NGEN_32BIT) && !(iAttributes & NGEN_64BIT))
            ExitOnFailure1(hr = E_INVALIDARG, "Neither 32bit nor 64bit is specified for NGEN of file: %ls", pwzFile);

        if (WcaIsInstalling(isInstalled, isAction) || WcaIsReInstalling(isInstalled, isAction))
        {
            if (iAttributes & NGEN_32BIT && f32NgenExeExists)
            {
                // Assemble the install command line
                hr = CreateInstallCommand(&pwzData, pwz32Ngen, pwzFile, iPriority, iAttributes, pwzFileApp, pwzDirAppBase);
                ExitOnFailure(hr, "failed to create install command line");

                hr = WcaWriteStringToCaData(pwzData, &pwzInstallCustomActionData);
                ExitOnFailure1(hr, "failed to add install command to custom action data: %ls", pwzData);

                hr = WcaWriteIntegerToCaData(iAssemblyCost, &pwzInstallCustomActionData);
                ExitOnFailure1(hr, "failed to add cost to custom action data: %ls", pwzData);

                uiCost += iAssemblyCost;

                fNeedInstallUpdate32 = TRUE;
            }

            if (iAttributes & NGEN_64BIT && f64NgenExeExists)
            {
                // Assemble the install command line
                hr = CreateInstallCommand(&pwzData, pwz64Ngen, pwzFile, iPriority, iAttributes, pwzFileApp, pwzDirAppBase);
                ExitOnFailure(hr, "failed to create install command line");

                hr = WcaWriteStringToCaData(pwzData, &pwzInstallCustomActionData); // command
                ExitOnFailure1(hr, "failed to add install command to custom action data: %ls", pwzData);

                hr = WcaWriteIntegerToCaData(iAssemblyCost, &pwzInstallCustomActionData); // cost
                ExitOnFailure1(hr, "failed to add cost to custom action data: %ls", pwzData);

                uiCost += iAssemblyCost;

                fNeedInstallUpdate64 = TRUE;
            }
        }
        else if (WcaIsUninstalling(isInstalled, isAction))
        {
            if (iAttributes & NGEN_32BIT && f32NgenExeExists)
            {
                hr = StrAllocFormatted(&pwzData, L"%s uninstall %s", pwz32Ngen, pwzFile);
                ExitOnFailure(hr, "failed to create update 32 command line");

                hr = WcaWriteStringToCaData(pwzData, &pwzUninstallCustomActionData); // command
                ExitOnFailure1(hr, "failed to add install command to custom action data: %ls", pwzData);

                hr = WcaWriteIntegerToCaData(COST_NGEN_NONBLOCKING, &pwzUninstallCustomActionData); // cost
                ExitOnFailure1(hr, "failed to add cost to custom action data: %ls", pwzData);

                uiCost += COST_NGEN_NONBLOCKING;

                fNeedUninstallUpdate32 = TRUE;
            }

            if (iAttributes & NGEN_64BIT && f64NgenExeExists)
            {
                hr = StrAllocFormatted(&pwzData, L"%s uninstall %s", pwz64Ngen, pwzFile);
                ExitOnFailure(hr, "failed to create update 64 command line");

                hr = WcaWriteStringToCaData(pwzData, &pwzUninstallCustomActionData); // command
                ExitOnFailure1(hr, "failed to add install command to custom action data: %ls", pwzData);

                hr = WcaWriteIntegerToCaData(COST_NGEN_NONBLOCKING, &pwzUninstallCustomActionData); // cost
                ExitOnFailure1(hr, "failed to add cost to custom action data: %ls", pwzData);

                uiCost += COST_NGEN_NONBLOCKING;

                fNeedUninstallUpdate64 = TRUE;
            }
        }
    }
    if (E_NOMOREITEMS == hr)
        hr = S_OK;
    ExitOnFailure(hr, "failed while looping through all files to create native images for");

    // If we need 32 bit install update
    if (fNeedInstallUpdate32)
    {
        hr = StrAllocFormatted(&pwzData, L"%s update /queue", pwz32Ngen);
        ExitOnFailure(hr, "failed to create install update 32 command line");

        hr = WcaWriteStringToCaData(pwzData, &pwzInstallCustomActionData); // command
        ExitOnFailure1(hr, "failed to add install command to install custom action data: %ls", pwzData);

        hr = WcaWriteIntegerToCaData(COST_NGEN_NONBLOCKING, &pwzInstallCustomActionData); // cost
        ExitOnFailure1(hr, "failed to add cost to install custom action data: %ls", pwzData);

        uiCost += COST_NGEN_NONBLOCKING;
    }

    // If we need 32 bit uninstall update
    if (fNeedUninstallUpdate32)
    {
        hr = StrAllocFormatted(&pwzData, L"%s update /queue", pwz32Ngen);
        ExitOnFailure(hr, "failed to create uninstall update 32 command line");

        hr = WcaWriteStringToCaData(pwzData, &pwzUninstallCustomActionData); // command
        ExitOnFailure1(hr, "failed to add install command to uninstall custom action data: %ls", pwzData);

        hr = WcaWriteIntegerToCaData(COST_NGEN_NONBLOCKING, &pwzUninstallCustomActionData); // cost
        ExitOnFailure1(hr, "failed to add cost to uninstall custom action data: %ls", pwzData);

        uiCost += COST_NGEN_NONBLOCKING;
    }

    // If we need 64 bit install update
    if (fNeedInstallUpdate64)
    {
        hr = StrAllocFormatted(&pwzData, L"%s update /queue", pwz64Ngen);
        ExitOnFailure(hr, "failed to create install update 64 command line");

        hr = WcaWriteStringToCaData(pwzData, &pwzInstallCustomActionData); // command
        ExitOnFailure1(hr, "failed to add install command to install custom action data: %ls", pwzData);

        hr = WcaWriteIntegerToCaData(COST_NGEN_NONBLOCKING, &pwzInstallCustomActionData); // cost
        ExitOnFailure1(hr, "failed to add cost to install custom action data: %ls", pwzData);

        uiCost += COST_NGEN_NONBLOCKING;
    }

    // If we need 64 bit install update
    if (fNeedUninstallUpdate64)
    {
        hr = StrAllocFormatted(&pwzData, L"%s update /queue", pwz64Ngen);
        ExitOnFailure(hr, "failed to create uninstall update 64 command line");

        hr = WcaWriteStringToCaData(pwzData, &pwzUninstallCustomActionData); // command
        ExitOnFailure1(hr, "failed to add install command to uninstall custom action data: %ls", pwzData);

        hr = WcaWriteIntegerToCaData(COST_NGEN_NONBLOCKING, &pwzUninstallCustomActionData); // cost
        ExitOnFailure1(hr, "failed to add cost to uninstall custom action data: %ls", pwzData);

        uiCost += COST_NGEN_NONBLOCKING;
    }

    // Add to progress bar
    if ((pwzInstallCustomActionData && *pwzInstallCustomActionData) || (pwzUninstallCustomActionData && *pwzUninstallCustomActionData))
    {
        hr = WcaProgressMessage(uiCost, TRUE);
        ExitOnFailure(hr, "failed to extend progress bar for NetFxExecuteNativeImage");
    }

    // Schedule the install custom action
    if (pwzInstallCustomActionData && *pwzInstallCustomActionData)
    {
        hr = WcaSetProperty(L"NetFxExecuteNativeImageInstall", pwzInstallCustomActionData);
        ExitOnFailure(hr, "failed to schedule NetFxExecuteNativeImageInstall action");

        hr = WcaSetProperty(L"NetFxExecuteNativeImageCommitInstall", pwzInstallCustomActionData);
        ExitOnFailure(hr, "failed to schedule NetFxExecuteNativeImageCommitInstall action");
    }

    // Schedule the uninstall custom action
    if (pwzUninstallCustomActionData && *pwzUninstallCustomActionData)
    {
        hr = WcaSetProperty(L"NetFxExecuteNativeImageUninstall", pwzUninstallCustomActionData);
        ExitOnFailure(hr, "failed to schedule NetFxExecuteNativeImageUninstall action");

        hr = WcaSetProperty(L"NetFxExecuteNativeImageCommitUninstall", pwzUninstallCustomActionData);
        ExitOnFailure(hr, "failed to schedule NetFxExecuteNativeImageCommitUninstall action");
    }


LExit:
    ReleaseStr(pwzInstallCustomActionData);
    ReleaseStr(pwzUninstallCustomActionData);
    ReleaseStr(pwzId);
    ReleaseStr(pwzData);
    ReleaseStr(pwzTemp);
    ReleaseStr(pwzFile);
    ReleaseStr(pwzFileApp);
    ReleaseStr(pwzDirAppBase);
    ReleaseStr(pwzComponent);
    ReleaseStr(pwz32Ngen);
    ReleaseStr(pwz64Ngen);

    if (FAILED(hr))
        er = ERROR_INSTALL_FAILURE;
    return WcaFinalize(er);
}
Esempio n. 13
0
static HRESULT GetStrongName(
    __out LPWSTR* ppwzStrongName,
    __in LPCWSTR pwzComponent
    )
{
    Assert(ppwzStrongName);
    HRESULT hr = S_OK;

    PMSIHANDLE hView = NULL;
    PMSIHANDLE hComponentRec = NULL;
    PMSIHANDLE hRec = NULL;

    LPWSTR pwzData = NULL;
    LPWSTR pwzName = NULL;
    LPWSTR pwzVersion = NULL;
    LPWSTR pwzCulture = NULL;
    LPWSTR pwzPublicKeyToken = NULL;

    hComponentRec = ::MsiCreateRecord(1);
    hr = WcaSetRecordString(hComponentRec, 1, pwzComponent);
    ExitOnFailure1(hr, "failed to set component value in record to: %ls", pwzComponent);

    // get the name value records for this component
    hr = WcaOpenView(vcsNgenStrongName, &hView);
    ExitOnFailure(hr, "failed to open view on NetFxNativeImage table");

    hr = WcaExecuteView(hView, hComponentRec);
    ExitOnFailure(hr, "failed to execute strong name view");

    while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
    {
        hr = WcaGetRecordString(hRec, ngsnName, &pwzData);
        ExitOnFailure1(hr, "failed to get MsiAssemblyName.Name for component: %ls", pwzComponent);

        if (0 == lstrcmpW(L"name", pwzData))
        {
            hr = WcaGetRecordString(hRec, ngsnValue, &pwzName);
            ExitOnFailure2(hr, "failed to get MsiAssemblyName.Value for component: %ls Name: %ls", pwzComponent, pwzData);
        }
        else if (0 == lstrcmpW(L"version", pwzData))
        {
            hr = WcaGetRecordString(hRec, ngsnValue, &pwzVersion);
            ExitOnFailure2(hr, "failed to get MsiAssemblyName.Value for component: %ls Name: %ls", pwzComponent, pwzData);
        }
        else if (0 == lstrcmpW(L"culture", pwzData))
        {
            hr = WcaGetRecordString(hRec, ngsnValue, &pwzCulture);
            ExitOnFailure2(hr, "failed to get MsiAssemblyName.Value for component: %ls Name: %ls", pwzComponent, pwzData);
        }
        else if (0 == lstrcmpW(L"publicKeyToken", pwzData))
        {
            hr = WcaGetRecordString(hRec, ngsnValue, &pwzPublicKeyToken);
            ExitOnFailure2(hr, "failed to get MsiAssemblyName.Value for component: %ls Name: %ls", pwzComponent, pwzData);
        }
    }
    if (E_NOMOREITEMS == hr)
        hr = S_OK;
    ExitOnFailure1(hr, "failed while looping through all names and values in MsiAssemblyName table for component: %ls", pwzComponent);

    hr = StrAllocFormatted(ppwzStrongName, L"\"%s, Version=%s, Culture=%s, PublicKeyToken=%s\"", pwzName, pwzVersion, pwzCulture, pwzPublicKeyToken);
    ExitOnFailure1(hr, "failed to format strong name for component: %ls", pwzComponent);

LExit:
    ReleaseStr(pwzData);
    ReleaseStr(pwzName);
    ReleaseStr(pwzVersion);
    ReleaseStr(pwzCulture);
    ReleaseStr(pwzPublicKeyToken);

    return hr;
}
Esempio n. 14
0
HRESULT GetFileSpec(
    __in MSIHANDLE hViewFileSpec,
    __in LPCWSTR wzKey,
    __in SQL_FILESPEC* psf
    )
{
    HRESULT hr = S_OK;
    PMSIHANDLE hRecFileSpec, hRec;
    LPWSTR pwzData = NULL;

    // create a record to do the fetch
    hRecFileSpec = ::MsiCreateRecord(1);
    if (!hRecFileSpec)
    {
        ExitOnFailure1(hr = E_UNEXPECTED, "failed to create record for filespec: %ls", wzKey);
    }
    hr = WcaSetRecordString(hRecFileSpec, 1, wzKey);
    ExitOnFailure1(hr, "failed to set record string for filespec: %ls", wzKey);

    // get the FileSpec record
    hr = WcaExecuteView(hViewFileSpec, hRecFileSpec);
    ExitOnFailure1(hr, "failed to execute view on SqlFileSpec table for filespec: %ls", wzKey);
    hr = WcaFetchSingleRecord(hViewFileSpec, &hRec);
    ExitOnFailure1(hr, "failed to get record for filespec: %ls", wzKey);

    // read the data out of the filespec record
    hr = WcaGetRecordFormattedString(hRec, sfsqName, &pwzData);
    ExitOnFailure1(hr, "Failed to get SqlFileSpec.Name for filespec: %ls", wzKey);
    hr = ::StringCchCopyW(psf->wzName, countof(psf->wzName), pwzData);
    ExitOnFailure1(hr, "Failed to copy SqlFileSpec.Name string: %ls", pwzData);

    hr = WcaGetRecordFormattedString(hRec, sfsqFilename, &pwzData);
    ExitOnFailure1(hr, "Failed to get SqlFileSpec.Filename for filespec: %ls", wzKey);
    if (*pwzData)
    {
        hr = ::StringCchCopyW(psf->wzFilename, countof(psf->wzFilename), pwzData);
        ExitOnFailure1(hr, "Failed to copy filename to filespec object: %ls", pwzData);
    }
    else   // if there is no file, skip this FILESPEC
    {
        WcaLog(LOGMSG_VERBOSE, "No filename specified, skipping FileSpec: %ls", psf->wzName);
        ExitFunction1(hr = S_FALSE);
    }

    hr = WcaGetRecordFormattedString(hRec, sfsqSize, &pwzData);
    ExitOnFailure1(hr, "Failed to get SqlFileSpec.Size for filespec: %ls", wzKey);
    if (*pwzData)
    {
        hr = ::StringCchCopyW(psf->wzSize, countof(psf->wzSize), pwzData);
        ExitOnFailure1(hr, "Failed to copy size to filespec object: %ls", pwzData);
    }
    else
    {
        psf->wzSize[0] = 0;
    }

    hr = WcaGetRecordFormattedString(hRec, sfsqMaxSize, &pwzData);
    ExitOnFailure1(hr, "Failed to get SqlFileSpec.MaxSize for filespec: %ls", wzKey);
    if (*pwzData)
    {
        hr = ::StringCchCopyW(psf->wzMaxSize, countof(psf->wzMaxSize), pwzData);
        ExitOnFailure1(hr, "Failed to copy max size to filespec object: %ls", pwzData);
    }
    else
    {
        psf->wzMaxSize[0] = 0;
    }

    hr = WcaGetRecordFormattedString(hRec, sfsqGrowth, &pwzData);
    ExitOnFailure1(hr, "Failed to get SqlFileSpec.GrowthSize for filespec: %ls", wzKey);
    if (*pwzData)
    {
        hr = ::StringCchCopyW(psf->wzGrow, countof(psf->wzGrow), pwzData);
        ExitOnFailure1(hr, "Failed to copy growth size to filespec object: %ls", pwzData);
    }
    else
    {
        psf->wzGrow[0] = 0;
    }

    hr = S_OK;
LExit:
    ReleaseStr(pwzData);
    return hr;
}
Esempio n. 15
0
HRESULT __stdcall ScaGetUser(
    __in LPCWSTR wzUser,
    __out SCA_USER* pscau
    )
{
    if (!wzUser || !pscau)
    {
        return E_INVALIDARG;
    }

    HRESULT hr = S_OK;
    PMSIHANDLE hView, hRec;

    LPWSTR pwzData = NULL;

    // clear struct and bail right away if no user key was passed to search for
    ::ZeroMemory(pscau, sizeof(*pscau));
    if (!*wzUser)
    {
        ExitFunction1(hr = S_OK);
    }

    hRec = ::MsiCreateRecord(1);
    hr = WcaSetRecordString(hRec, 1, wzUser);
    ExitOnFailure(hr, "Failed to look up User");

    hr = WcaOpenView(vcsUserQuery, &hView);
    ExitOnFailure(hr, "Failed to open view on User table");
    hr = WcaExecuteView(hView, hRec);
    ExitOnFailure(hr, "Failed to execute view on User table");

    hr = WcaFetchSingleRecord(hView, &hRec);
    if (S_OK == hr)
    {
        hr = WcaGetRecordString(hRec, vuqUser, &pwzData);
        ExitOnFailure(hr, "Failed to get User.User");
        hr = ::StringCchCopyW(pscau->wzKey, countof(pscau->wzKey), pwzData);
        ExitOnFailure(hr, "Failed to copy key string to user object");

        hr = WcaGetRecordString(hRec, vuqComponent, &pwzData);
        ExitOnFailure(hr, "Failed to get User.Component_");
        hr = ::StringCchCopyW(pscau->wzComponent, countof(pscau->wzComponent), pwzData);
        ExitOnFailure(hr, "Failed to copy component string to user object");

        hr = WcaGetRecordFormattedString(hRec, vuqName, &pwzData);
        ExitOnFailure(hr, "Failed to get User.Name");
        hr = ::StringCchCopyW(pscau->wzName, countof(pscau->wzName), pwzData);
        ExitOnFailure(hr, "Failed to copy name string to user object");

        hr = WcaGetRecordFormattedString(hRec, vuqDomain, &pwzData);
        ExitOnFailure(hr, "Failed to get User.Domain");
        hr = ::StringCchCopyW(pscau->wzDomain, countof(pscau->wzDomain), pwzData);
        ExitOnFailure(hr, "Failed to copy domain string to user object");

        hr = WcaGetRecordFormattedString(hRec, vuqPassword, &pwzData);
        ExitOnFailure(hr, "Failed to get User.Password");
        hr = ::StringCchCopyW(pscau->wzPassword, countof(pscau->wzPassword), pwzData);
        ExitOnFailure(hr, "Failed to copy password string to user object");
    }
    else if (E_NOMOREITEMS == hr)
    {
        WcaLog(LOGMSG_STANDARD, "Error: Cannot locate User.User='******'", wzUser);
        hr = E_FAIL;
    }
    else
    {
        ExitOnFailure(hr, "Error or found multiple matching User rows");
    }

LExit:
    ReleaseStr(pwzData);

    return hr;
}
Esempio n. 16
0
HRESULT ScaUserRead(
    __out SCA_USER** ppsuList
    )
{
    //Assert(FALSE);
    Assert(ppsuList);

    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;
    PMSIHANDLE hView, hRec, hUserRec, hUserGroupView;

    LPWSTR pwzData = NULL;

    BOOL fUserGroupExists  = FALSE;

    SCA_USER *psu = NULL;

    INSTALLSTATE isInstalled, isAction;

    if (S_OK != WcaTableExists(L"User"))
    {
        WcaLog(LOGMSG_VERBOSE, "User Table does not exist, exiting");
        ExitFunction1(hr = S_FALSE);
    }

    if (S_OK == WcaTableExists(L"UserGroup"))
    {
        fUserGroupExists = TRUE;
    }

    //
    // loop through all the users
    //
    hr = WcaOpenExecuteView(vActionableQuery, &hView);
    ExitOnFailure(hr, "failed to open view on User table");
    while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
    {
        hr = WcaGetRecordString(hRec, vaqComponent, &pwzData);
        ExitOnFailure(hr, "failed to get User.Component");

        er = ::MsiGetComponentStateW(WcaGetInstallHandle(), pwzData, &isInstalled, &isAction);
        hr = HRESULT_FROM_WIN32(er);
        ExitOnFailure(hr, "failed to get Component state for User");

        // don't bother if we aren't installing or uninstalling this component
        if (WcaIsInstalling(isInstalled,  isAction) || WcaIsUninstalling(isInstalled, isAction))
        {
            //
            // Add the user to the list and populate it's values
            //
            hr = AddUserToList(ppsuList);
            ExitOnFailure(hr, "failed to add user to list");

            psu = *ppsuList;

            psu->isInstalled = isInstalled;
            psu->isAction = isAction;
            hr = ::StringCchCopyW(psu->wzComponent, countof(psu->wzComponent), pwzData);
            ExitOnFailure1(hr, "failed to copy component name: %ls", pwzData);

            hr = WcaGetRecordString(hRec, vaqUser, &pwzData);
            ExitOnFailure(hr, "failed to get User.User");
            hr = ::StringCchCopyW(psu->wzKey, countof(psu->wzKey), pwzData);
            ExitOnFailure1(hr, "failed to copy user key: %ls", pwzData);

            hr = WcaGetRecordFormattedString(hRec, vaqName, &pwzData);
            ExitOnFailure(hr, "failed to get User.Name");
            hr = ::StringCchCopyW(psu->wzName, countof(psu->wzName), pwzData);
            ExitOnFailure1(hr, "failed to copy user name: %ls", pwzData);

            hr = WcaGetRecordFormattedString(hRec, vaqDomain, &pwzData);
            ExitOnFailure(hr, "failed to get User.Domain");
            hr = ::StringCchCopyW(psu->wzDomain, countof(psu->wzDomain), pwzData);
            ExitOnFailure1(hr, "failed to copy user domain: %ls", pwzData);

            hr = WcaGetRecordFormattedString(hRec, vaqPassword, &pwzData);
            ExitOnFailure(hr, "failed to get User.Password");
            hr = ::StringCchCopyW(psu->wzPassword, countof(psu->wzPassword), pwzData);
            ExitOnFailure(hr, "failed to copy user password");

            hr = WcaGetRecordInteger(hRec, vaqAttributes, &psu->iAttributes);
            ExitOnFailure(hr, "failed to get User.Attributes"); 

            // Check if this user is to be added to any groups
            if (fUserGroupExists)
            {
                hUserRec = ::MsiCreateRecord(1);
                hr = WcaSetRecordString(hUserRec, 1, psu->wzKey);
                ExitOnFailure(hr, "Failed to create user record for querying UserGroup table");

                hr = WcaOpenView(vcsUserGroupQuery, &hUserGroupView);
                ExitOnFailure1(hr, "Failed to open view on UserGroup table for user %ls", psu->wzKey);
                hr = WcaExecuteView(hUserGroupView, hUserRec);
                ExitOnFailure1(hr, "Failed to execute view on UserGroup table for user: %ls", psu->wzKey);

                while (S_OK == (hr = WcaFetchRecord(hUserGroupView, &hRec)))
                {
                    hr = WcaGetRecordString(hRec, vugqGroup, &pwzData);
                    ExitOnFailure(hr, "failed to get UserGroup.Group");

                    hr = AddGroupToList(&(psu->psgGroups));
                    ExitOnFailure(hr, "failed to add group to list");

                    hr = ScaGetGroup(pwzData, psu->psgGroups);
                    ExitOnFailure1(hr, "failed to get information for group: %ls", pwzData);
                }

                if (E_NOMOREITEMS == hr)
                {
                    hr = S_OK;
                }
                ExitOnFailure(hr, "failed to enumerate selected rows from UserGroup table");
            }
        }
    }

    if (E_NOMOREITEMS == hr)
    {
        hr = S_OK;
    }
    ExitOnFailure(hr, "failed to enumerate selected rows from User table");

LExit:
    ReleaseStr(pwzData);

    return hr;
}
Esempio n. 17
0
HRESULT CpiAddActionTextToActionData(
    LPCWSTR pwzAction,
    LPWSTR* ppwzActionData
    )
{
    HRESULT hr = S_OK;

    PMSIHANDLE hView, hRecKey, hRec;

    LPWSTR pwzDescription = NULL;
    LPWSTR pwzTemplate = NULL;

    if (S_OK == WcaTableExists(L"ActionText"))
    {
        // create parameter record
        hRecKey = ::MsiCreateRecord(1);
        ExitOnNull(hRecKey, hr, E_OUTOFMEMORY, "Failed to create record");
        hr = WcaSetRecordString(hRecKey, 1, pwzAction);
        ExitOnFailure(hr, "Failed to set record string");

        // open view
        hr = WcaOpenView(vcsActionTextQuery, &hView);
        ExitOnFailure(hr, "Failed to open view on ActionText table");
        hr = WcaExecuteView(hView, hRecKey);
        ExitOnFailure(hr, "Failed to execute view on ActionText table");

        // fetch record
        hr = WcaFetchSingleRecord(hView, &hRec);
        if (S_FALSE != hr)
        {
            ExitOnFailure(hr, "Failed to fetch action text record");

            // get description
            hr = WcaGetRecordString(hRec, atqDescription, &pwzDescription);
            ExitOnFailure(hr, "Failed to get description");

            // get template
            hr = WcaGetRecordString(hRec, atqTemplate, &pwzTemplate);
            ExitOnFailure(hr, "Failed to get template");
        }
    }

    // add action name to action data
    hr = WcaWriteStringToCaData(pwzAction, ppwzActionData);
    ExitOnFailure(hr, "Failed to add action name to custom action data");

    // add description to action data
    hr = WcaWriteStringToCaData(pwzDescription ? pwzDescription : L"", ppwzActionData);
    ExitOnFailure(hr, "Failed to add description to custom action data");

    // add template to action data
    hr = WcaWriteStringToCaData(pwzTemplate ? pwzTemplate : L"", ppwzActionData);
    ExitOnFailure(hr, "Failed to add template to custom action data");

    hr = S_OK;

LExit:
    // clean up
    ReleaseStr(pwzDescription);
    ReleaseStr(pwzTemplate);

    return hr;
}