예제 #1
0
파일: OsInfo.cpp 프로젝트: BMurri/wix3
/********************************************************************
SetPropertyWellKnownSID

 Set a property with the localized name of a well known windows SID
********************************************************************/
static HRESULT SetPropertyWellKnownSID(
    __in WELL_KNOWN_SID_TYPE sidType,
    __in LPCWSTR wzPropertyName,
    __in BOOL fIncludeDomainName
    )
{
    HRESULT hr = S_OK;
    PSID psid = NULL;
    WCHAR wzRefDomain[MAX_PATH] = {0};
    SID_NAME_USE nameUse;
    DWORD refSize = MAX_PATH;
    WCHAR wzName[MAX_PATH] = {0};
    LPWSTR pwzPropertyValue = NULL;
    DWORD size = MAX_PATH;

    hr = AclGetWellKnownSid(sidType, &psid);
    ExitOnFailure1(hr, "Failed to get SID; skipping account %ls", wzPropertyName);

    if (!::LookupAccountSidW(NULL, psid, wzName, &size, wzRefDomain, &refSize, &nameUse))
    {
        ExitWithLastError1(hr, "Failed to look up account for SID; skipping account %ls.", wzPropertyName);
    }

    if (fIncludeDomainName)
    {
        hr = StrAllocFormatted(&pwzPropertyValue, L"%s\\%s", wzRefDomain, wzName);
        ExitOnFailure(hr, "Failed to format property value");

        hr = WcaSetProperty(wzPropertyName, pwzPropertyValue);
        ExitOnFailure(hr, "Failed write domain\\name property");
    }
    else
    {
        hr = WcaSetProperty(wzPropertyName, wzName);
        ExitOnFailure(hr, "Failed write name-only property");
    }
 
LExit:
    if (NULL != psid)
    {
        ::LocalFree(psid);
    }
    ReleaseStr(pwzPropertyValue);
    return hr;
}
예제 #2
0
/* 
  Check for if directory is empty during install, 
  sets "<PROPERTY>_NOT_EMPTY" otherise
*/
extern "C" UINT __stdcall CheckDirectoryEmpty(MSIHANDLE hInstall, 
  const wchar_t *PropertyName)
{
  HRESULT hr = S_OK;
  UINT er = ERROR_SUCCESS;
  hr = WcaInitialize(hInstall, __FUNCTION__);
  ExitOnFailure(hr, "Failed to initialize");
  WcaLog(LOGMSG_STANDARD, "Initialized.");

  
  wchar_t buf[MAX_PATH];
  DWORD len = MAX_PATH;
  MsiGetPropertyW(hInstall, PropertyName, buf, &len);
  wcscat_s(buf, MAX_PATH, L"*.*");
  
  WcaLog(LOGMSG_STANDARD, "Checking files in %S", buf);
  WIN32_FIND_DATAW data;
  HANDLE h;
  bool empty;
  h= FindFirstFile(buf, &data);
  if (h !=  INVALID_HANDLE_VALUE)
  {
     empty= true;
     for(;;)
     {
       if (wcscmp(data.cFileName, L".") || wcscmp(data.cFileName, L".."))
       {
         empty= false;
         break;
       }
       if (!FindNextFile(h, &data))
         break;
     }
     FindClose(h);
  }
  else
  {
    /* Non-existent directory, we handle it as empty */
    empty = true;
  }

  if(empty)
    WcaLog(LOGMSG_STANDARD, "Directory %S is empty or non-existent", 
    PropertyName);
  else
    WcaLog(LOGMSG_STANDARD, "Directory %S is NOT empty", PropertyName);

  wcscpy_s(buf, MAX_PATH, PropertyName);
  wcscat_s(buf, L"NOTEMPTY");
  WcaSetProperty(buf, empty? L"":L"1");

LExit:
  return WcaFinalize(er); 
}
예제 #3
0
파일: qtexecca.cpp 프로젝트: bleissem/wix3
HRESULT BuildCommandLine(
    __in LPCWSTR wzProperty,
    __out LPWSTR *ppwzCommand
)
{
    Assert(ppwzCommand);

    HRESULT hr = S_OK;
    BOOL fScheduled = ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_SCHEDULED);
    BOOL fRollback = ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_ROLLBACK);
    BOOL fCommit = ::MsiGetMode(WcaGetInstallHandle(), MSIRUNMODE_COMMIT);

    if (fScheduled || fRollback || fCommit)
    {
        if (WcaIsPropertySet("CustomActionData"))
        {
            hr = WcaGetProperty( L"CustomActionData", ppwzCommand);
            ExitOnFailure(hr, "Failed to get CustomActionData");
        }
    }
    else if (WcaIsUnicodePropertySet(wzProperty))
    {
        hr = WcaGetFormattedProperty(wzProperty, ppwzCommand);
        ExitOnFailure(hr, "Failed to get %ls", wzProperty);
        hr = WcaSetProperty(wzProperty, L""); // clear out the property now that we've read it
        ExitOnFailure(hr, "Failed to set %ls", wzProperty);
    }

    if (!*ppwzCommand)
    {
        ExitOnFailure(hr = E_INVALIDARG, "Failed to get command line data");
    }

    if (L'"' != **ppwzCommand)
    {
        WcaLog(LOGMSG_STANDARD, "Command string must begin with quoted application name.");
        ExitOnFailure(hr = E_INVALIDARG, "invalid command line property value");
    }

LExit:
    return hr;
}
예제 #4
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);
}
예제 #5
0
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;
}
예제 #6
0
void CheckServiceConfig(
  wchar_t *my_servicename,    /* SERVICENAME property in this installation*/
  wchar_t *datadir,           /* DATADIR property in this installation*/
  wchar_t *bindir,            /* INSTALLDIR\bin */
  wchar_t *other_servicename, /* Service to check against */
  QUERY_SERVICE_CONFIGW * config /* Other service's config */
  )
{

  bool same_bindir = false;
  wchar_t * commandline= config->lpBinaryPathName;
  int numargs;
  wchar_t **argv= CommandLineToArgvW(commandline, &numargs);
  WcaLog(LOGMSG_VERBOSE, "CommandLine= %S", commandline);
  if(!argv  ||  !argv[0]  || ! wcsstr(argv[0], L"mysqld"))
  {
    goto end;
  }

  WcaLog(LOGMSG_STANDARD, "MySQL service %S found: CommandLine= %S", 
    other_servicename, commandline);
  if (wcsstr(argv[0], bindir))
  {
    WcaLog(LOGMSG_STANDARD, "executable under bin directory");
    same_bindir = true;
  }

  bool is_my_service = (_wcsicmp(my_servicename, other_servicename) == 0);
  if(!is_my_service)
  {
    WcaLog(LOGMSG_STANDARD, "service does not match current service");
    /* 
      TODO probably the best thing possible would be to add temporary
      row to MSI ServiceConfig table with remove on uninstall
    */
  }
  else if (!same_bindir)
  {
    WcaLog(LOGMSG_STANDARD, 
      "Service name matches, but not the executable path directory, mine is %S", 
      bindir);
    WcaSetProperty(L"SERVICENAME", L"");
  }

  /* Check if data directory is used */
  if(!datadir || numargs <= 1 ||  wcsncmp(argv[1],L"--defaults-file=",16) != 0)
  {
    goto end;
  }

  wchar_t current_datadir_buf[MAX_PATH]={0};
  wchar_t normalized_current_datadir[MAX_PATH+1];
  wchar_t *current_datadir= current_datadir_buf;
  wchar_t *defaults_file= argv[1]+16;
  defaults_file= strip_quotes(defaults_file);

  WcaLog(LOGMSG_STANDARD, "parsed defaults file is %S", defaults_file);

  if (GetPrivateProfileStringW(L"mysqld", L"datadir", NULL, current_datadir, 
    MAX_PATH, defaults_file) == 0)
  {
    WcaLog(LOGMSG_STANDARD, 
      "Cannot find datadir in ini file '%S'", defaults_file);
    goto end;
  }

  WcaLog(LOGMSG_STANDARD, "datadir from defaults-file is %S", current_datadir);
  strip_quotes(current_datadir);

  /* Convert to Windows path */
  if (GetFullPathNameW(current_datadir, MAX_PATH, normalized_current_datadir, 
    NULL))
  {
    /* Add backslash to be compatible with directory formats in MSI */
    wcsncat(normalized_current_datadir, L"\\", MAX_PATH+1);
    WcaLog(LOGMSG_STANDARD, "normalized current datadir is '%S'", 
      normalized_current_datadir);
  }

  if (_wcsicmp(datadir, normalized_current_datadir) == 0 && !same_bindir)
  {
    WcaLog(LOGMSG_STANDARD, 
      "database directory from current installation, but different mysqld.exe");
    WcaSetProperty(L"CLEANUPDATA", L"");
  }

end:
  LocalFree((HLOCAL)argv);
}
예제 #7
0
파일: netfxca.cpp 프로젝트: 925coder/wix3
/******************************************************************
 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);
}
예제 #8
0
파일: OsInfo.cpp 프로젝트: BMurri/wix3
/********************************************************************
WixQueryOsDirs - entry point for WixQueryOsDirs custom action

 Called as Type 1 custom action (DLL from the Binary table) from 
 Windows Installer to set properties that identify predefined directories
********************************************************************/
extern "C" UINT __stdcall WixQueryOsDirs(
    __in MSIHANDLE hInstall
    )
{
    HRESULT hr = S_OK;
    DWORD er = ERROR_SUCCESS;

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

    // get the paths of the CSIDLs that represent real paths and for which MSI
    // doesn't yet have standard folder properties
    WCHAR path[MAX_PATH];
    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_ADMINTOOLS, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_ADMINTOOLS", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_ALTSTARTUP, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_ALTSTARTUP", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_CDBURN_AREA, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_CDBURN_AREA", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_ADMINTOOLS, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_COMMON_ADMINTOOLS", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_ALTSTARTUP, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_COMMON_ALTSTARTUP", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_COMMON_DOCUMENTS", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_FAVORITES, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_COMMON_FAVORITES", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_MUSIC, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_COMMON_MUSIC", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_PICTURES, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_COMMON_PICTURES", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COMMON_VIDEO, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_COMMON_VIDEO", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_COOKIES, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_COOKIES", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_DESKTOP", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_HISTORY, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_HISTORY", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_INTERNET_CACHE, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_INTERNET_CACHE", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_MYMUSIC, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_MYMUSIC", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_MYPICTURES, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_MYPICTURES", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_MYVIDEO, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_MYVIDEO", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_NETHOOD, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_NETHOOD", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_PERSONAL", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_PRINTHOOD, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_PRINTHOOD", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_PROFILE", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_RECENT, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_RECENT", path);
    }

    if (ERROR_SUCCESS == ::SHGetFolderPathW(NULL, CSIDL_RESOURCES, NULL, SHGFP_TYPE_CURRENT, path))
    {
        WcaSetProperty(L"WIX_DIR_RESOURCES", path);
    }

LExit:
    if (FAILED(hr))
        er = ERROR_INSTALL_FAILURE;
    return WcaFinalize(er);
}