Example #1
2
UINT __stdcall FillListbox(MSIHANDLE hInstall)
{
	HRESULT hr = S_OK;
	UINT er = ERROR_SUCCESS;

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

	WcaLog(LOGMSG_STANDARD, "Initialized.");

	// TODO: Add your custom action code here.
	MSIHANDLE hTable = NULL;
	MSIHANDLE hColumns = NULL;
	MSIDBERROR dbErr = MSIDBERROR_NOERROR;

	WcaLog(LOGMSG_STANDARD, "AddingTempRecord %d hTable = %x hColumns = %x dbErr = %d.", 0, hTable, hColumns, dbErr);
	hr = WcaAddTempRecord (&hTable, &hColumns, L"ListBox", &dbErr, 0, 3, L"LISTBOXVALUES", 1, L"Item 1");
	WcaLog(LOGMSG_STANDARD, "AddingTempRecord %d hTable = %x hColumns = %x dbErr = %d.", 1, hTable, hColumns, dbErr);
	hr = WcaAddTempRecord (&hTable, &hColumns, L"ListBox", &dbErr, 0, 3, L"LISTBOXVALUES", 2, L"Item 2");
	WcaLog(LOGMSG_STANDARD, "AddingTempRecord %d hTable = %x hColumns = %x dbErr = %d.", 2, hTable, hColumns, dbErr);
	hr = WcaAddTempRecord (&hTable, &hColumns, L"ListBox", &dbErr, 0, 3, L"LISTBOXVALUES", 3, L"Item 3");
	WcaLog(LOGMSG_STANDARD, "AddingTempRecord %d hTable = %x hColumns = %x dbErr = %d.", 3, hTable, hColumns, dbErr);

	if (hTable)
		MsiCloseHandle (hTable);
	if (hColumns)
		MsiCloseHandle (hColumns);

LExit:
	er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
	return WcaFinalize(er);
}
Example #2
0
extern "C" UINT __stdcall FillListbox(MSIHANDLE hInstall) {
    HRESULT hResult = WcaInitialize(hInstall, "FillListbox");
    if (FAILED(hResult)) return ERROR_INSTALL_FAILURE;

    MSIHANDLE hTable = NULL;
    MSIHANDLE hColumns = NULL;

    hResult = WcaAddTempRecord(&hTable, &hColumns, L"ListBox", NULL, 0, 3, L"LISTBOXVALUES", 1, L"Item 1");
    hResult = WcaAddTempRecord(&hTable, &hColumns, L"ListBox", NULL, 0, 3, L"LISTBOXVALUES", 2, L"Item 2");
    hResult = WcaAddTempRecord(&hTable, &hColumns, L"ListBox", NULL, 0, 3, L"LISTBOXVALUES", 3, L"Item 3");

    if (hTable)
        MsiCloseHandle(hTable);
    if (hColumns)
        MsiCloseHandle(hColumns);
    return WcaFinalize(hResult);
}
Example #3
0
/******************************************************************
 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);
}
static HRESULT RecursePath(
    __in_z LPCWSTR wzPath,
    __in_z LPCWSTR wzId,
    __in_z LPCWSTR wzComponent,
    __in_z LPCWSTR wzProperty,
    __in int iMode,
    __inout DWORD* pdwCounter,
    __inout MSIHANDLE* phTable,
    __inout MSIHANDLE* phColumns
    )
{
    HRESULT hr = S_OK;
    DWORD er;
    LPWSTR sczSearch = NULL;
    LPWSTR sczProperty = NULL;
    HANDLE hFind = INVALID_HANDLE_VALUE;
    WIN32_FIND_DATAW wfd;
    LPWSTR sczNext = NULL;

    // First recurse down to all the child directories.
    hr = StrAllocFormatted(&sczSearch, L"%s*", wzPath);
    ExitOnFailure1(hr, "Failed to allocate file search string in path: %S", wzPath);

    hFind = ::FindFirstFileW(sczSearch, &wfd);
    if (INVALID_HANDLE_VALUE == hFind)
    {
        er = ::GetLastError();
        if (ERROR_PATH_NOT_FOUND == er)
        {
            ExitFunction1(hr = S_FALSE);
        }
        else
        {
            hr = HRESULT_FROM_WIN32(er);
        }
        ExitOnFailure1(hr, "Failed to find all files in path: %S", wzPath);
    }

    do
    {
        // Skip files and the dot directories.
        if (FILE_ATTRIBUTE_DIRECTORY != (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || L'.' == wfd.cFileName[0] && (L'\0' == wfd.cFileName[1] || (L'.' == wfd.cFileName[1] && L'\0' == wfd.cFileName[2])))
        {
            continue;
        }

        hr = StrAllocFormatted(&sczNext, L"%s%s\\", wzPath, wfd.cFileName);
        ExitOnFailure2(hr, "Failed to concat filename '%S' to string: %S", wfd.cFileName, wzPath);

        hr = RecursePath(sczNext, wzId, wzComponent, wzProperty, iMode, pdwCounter, phTable, phColumns);
        ExitOnFailure1(hr, "Failed to recurse path: %S", sczNext);
    } while (::FindNextFileW(hFind, &wfd));

    er = ::GetLastError();
    if (ERROR_NO_MORE_FILES == er)
    {
        hr = S_OK;
    }
    else
    {
        hr = HRESULT_FROM_WIN32(er);
        ExitOnFailure1(hr, "Failed while looping through files in directory: %S", wzPath);
    }

    // Finally, set a property that points at our path.
    hr = StrAllocFormatted(&sczProperty, L"_%s_%u", wzProperty, *pdwCounter);
    ExitOnFailure1(hr, "Failed to allocate Property for RemoveFile table with property: %S.", wzProperty);

    ++(*pdwCounter);

    hr = WcaSetProperty(sczProperty, wzPath);
    ExitOnFailure2(hr, "Failed to set Property: %S with path: %S", sczProperty, wzPath);

    // Add the row to remove any files and another row to remove the folder.
    hr = WcaAddTempRecord(phTable, phColumns, L"RemoveFile", NULL, 1, 5, L"RfxFiles", wzComponent, L"*.*", sczProperty, iMode);
    ExitOnFailure2(hr, "Failed to add row to remove all files for WixRemoveFolderEx row: %S under path:", wzId, wzPath);

    hr = WcaAddTempRecord(phTable, phColumns, L"RemoveFile", NULL, 1, 5, L"RfxFolder", wzComponent, NULL, sczProperty, iMode);
    ExitOnFailure2(hr, "Failed to add row to remove folder for WixRemoveFolderEx row: %S under path: %S", wzId, wzPath);

LExit:
    if (INVALID_HANDLE_VALUE != hFind)
    {
        ::FindClose(hFind);
    }

    ReleaseStr(sczNext);
    ReleaseStr(sczProperty);
    ReleaseStr(sczSearch);
    return hr;
}