Esempio n. 1
0
extern "C" HRESULT DAPI ShelGetKnownFolder(
    __out_z LPWSTR* psczFolderPath,
    __in REFKNOWNFOLDERID rfidFolder
    )
{
    HRESULT hr = S_OK;
    HMODULE hShell32Dll = NULL;
    PFN_SHGetKnownFolderPath pfn = NULL;
    LPWSTR pwzPath = NULL;

    hr = LoadSystemLibrary(L"shell32.dll", &hShell32Dll);
    if (E_MODNOTFOUND == hr)
    {
        TraceError(hr, "Failed to load shell32.dll");
        ExitFunction1(hr = E_NOTIMPL);
    }
    ExitOnFailure(hr, "Failed to load shell32.dll.");

    pfn = reinterpret_cast<PFN_SHGetKnownFolderPath>(::GetProcAddress(hShell32Dll, "SHGetKnownFolderPath"));
    ExitOnNull(pfn, hr, E_NOTIMPL, "Failed to find SHGetKnownFolderPath entry point.");

    hr = pfn(rfidFolder, KF_FLAG_CREATE, NULL, &pwzPath);
    ExitOnFailure(hr, "Failed to get known folder path.");

    hr = StrAllocString(psczFolderPath, pwzPath, 0);
    ExitOnFailure1(hr, "Failed to copy shell folder path: %ls", pwzPath);

    hr = PathBackslashTerminate(psczFolderPath);
    ExitOnFailure1(hr, "Failed to backslash terminate shell folder path: %ls", *psczFolderPath);

LExit:
    if (pwzPath)
    {
        ::CoTaskMemFree(pwzPath);
    }

    if (hShell32Dll)
    {
        ::FreeLibrary(hShell32Dll);
    }

    return hr;
}
Esempio n. 2
0
/********************************************************************
 ShelGetFolder() - gets a folder by CSIDL.

*******************************************************************/
extern "C" HRESULT DAPI ShelGetFolder(
    __out_z LPWSTR* psczFolderPath,
    __in int csidlFolder
    )
{
    HRESULT hr = S_OK;
    WCHAR wzPath[MAX_PATH];

    hr = ::SHGetFolderPathW(NULL, csidlFolder | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, wzPath);
    ExitOnFailure1(hr, "Failed to get folder path for CSIDL: %d", csidlFolder);

    hr = StrAllocString(psczFolderPath, wzPath, 0);
    ExitOnFailure1(hr, "Failed to copy shell folder path: %ls", wzPath);

    hr = PathBackslashTerminate(psczFolderPath);
    ExitOnFailure1(hr, "Failed to backslash terminate shell folder path: %ls", *psczFolderPath);

LExit:
    return hr;
}
Esempio n. 3
0
static HRESULT DeleteEmptyDirectoryChildren(
    __in_z LPCWSTR wzPath
    )
{
    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;
    WIN32_FIND_DATAW wfd = { };
    HANDLE hFind = NULL;
    LPWSTR sczSubDirWithWildcard = NULL;
    LPWSTR sczPath = NULL;

    hr = PathConcat(wzPath, L"*", &sczSubDirWithWildcard);
    ExitOnFailure(hr, "Failed to concatenate wildcard character to directory name for search");

    hFind = ::FindFirstFileW(sczSubDirWithWildcard, &wfd);
    if (INVALID_HANDLE_VALUE == hFind)
    {
        er = ::GetLastError();
        hr = HRESULT_FROM_WIN32(er);
        if (E_PATHNOTFOUND == hr)
        {
            ExitFunction();
        }
        ExitWithLastError(hr, "Failed to find first file with query: %ls", sczSubDirWithWildcard);
    }

    do
    {
        // Safety / silence code analysis tools
        wfd.cFileName[MAX_PATH - 1] = L'\0';

        // Don't use "." or ".."
        if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, wfd.cFileName, -1, L".", -1))
        {
            continue;
        }
        else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, wfd.cFileName, -1, L"..", -1))
        {
            continue;
        }

        hr = PathConcat(wzPath, wfd.cFileName, &sczPath);
        ExitOnFailure(hr, "Failed to concat filename '%ls' to directory: %ls", wfd.cFileName, wzPath);

        // If we found a directory, recurse!
        if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
            hr = PathBackslashTerminate(&sczPath);
            ExitOnFailure(hr, "Failed to ensure path is backslash terminated: %ls", sczPath);

            hr = DeleteEmptyDirectoryChildren(sczPath);
            if (HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) == hr)
            {
                hr = S_OK;
            }
            else
            {
                ExitOnFailure(hr, "Failed to recurse to directory: %ls", sczPath);

                hr = DirEnsureDelete(sczPath, FALSE, FALSE);
                if (HRESULT_FROM_WIN32(ERROR_DIR_NOT_EMPTY) == hr)
                {
                    hr = S_OK;
                }
                ExitOnFailure(hr, "Failed to delete directory: %ls", sczPath);
            }
        }
        else
        {
            continue;
        }
    }
    while (::FindNextFileW(hFind, &wfd));

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

LExit:
    // There was nothing to read, it's still success
    if (HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) == hr)
    {
        hr = S_OK;
    }
    if (NULL != hFind)
    {
        FindClose(hFind);
    }
    ReleaseStr(sczSubDirWithWildcard);
    ReleaseStr(sczPath);

    return hr;
}
extern "C" UINT WINAPI WixRemoveFoldersEx(
    __in MSIHANDLE hInstall
    )
{
    //AssertSz(FALSE, "debug WixRemoveFoldersEx");

    HRESULT hr = S_OK;
    PMSIHANDLE hView;
    PMSIHANDLE hRec;
    LPWSTR sczId = NULL;
    LPWSTR sczComponent = NULL;
    LPWSTR sczProperty = NULL;
    LPWSTR sczPath = NULL;
    LPWSTR sczExpandedPath = NULL;
    int iMode = 0;
    DWORD dwCounter = 0;
    DWORD_PTR cchLen = 0;
    MSIHANDLE hTable = NULL;
    MSIHANDLE hColumns = NULL;

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

    // anything to do?
    if (S_OK != WcaTableExists(L"WixRemoveFolderEx"))
    {
        WcaLog(LOGMSG_STANDARD, "WixRemoveFolderEx table doesn't exist, so there are no folders to remove.");
        ExitFunction();
    }

    // query and loop through all the remove folders exceptions
    hr = WcaOpenExecuteView(vcsRemoveFolderExQuery, &hView);
    ExitOnFailure(hr, "Failed to open view on WixRemoveFolderEx table");

    while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
    {
        hr = WcaGetRecordString(hRec, rfqId, &sczId);
        ExitOnFailure(hr, "Failed to get remove folder identity.");

        hr = WcaGetRecordString(hRec, rfqComponent, &sczComponent);
        ExitOnFailure(hr, "Failed to get remove folder component.");

        hr = WcaGetRecordString(hRec, rfqProperty, &sczProperty);
        ExitOnFailure(hr, "Failed to get remove folder property.");

        hr = WcaGetRecordInteger(hRec, feqMode, &iMode);
        ExitOnFailure(hr, "Failed to get remove folder mode");

        hr = WcaGetProperty(sczProperty, &sczPath);
        ExitOnFailure2(hr, "Failed to resolve remove folder property: %S for row: %S", sczProperty, sczId);

        // fail early if the property isn't set as you probably don't want your installers trying to delete SystemFolder
        // StringCchLengthW succeeds only if the string is zero characters plus 1 for the terminating null
        hr = ::StringCchLengthW(sczPath, 1, reinterpret_cast<UINT_PTR*>(&cchLen));
        if (SUCCEEDED(hr))
        {
            ExitOnFailure2(hr = E_INVALIDARG, "Missing folder property: %S for row: %S", sczProperty, sczId);
        }

        hr = PathExpand(&sczExpandedPath, sczPath, PATH_EXPAND_ENVIRONMENT);
        ExitOnFailure2(hr, "Failed to expand path: %S for row: %S", sczPath, sczId);
        
        hr = PathBackslashTerminate(&sczExpandedPath);
        ExitOnFailure1(hr, "Failed to backslash-terminate path: %S", sczExpandedPath);
    
        WcaLog(LOGMSG_STANDARD, "Recursing path: %S for row: %S.", sczExpandedPath, sczId);
        hr = RecursePath(sczExpandedPath, sczId, sczComponent, sczProperty, iMode, &dwCounter, &hTable, &hColumns);
        ExitOnFailure2(hr, "Failed while navigating path: %S for row: %S", sczPath, sczId);
    }

    // reaching the end of the list is actually a good thing, not an error
    if (E_NOMOREITEMS == hr)
    {
        hr = S_OK;
    }
    ExitOnFailure(hr, "Failure occured while processing WixRemoveFolderEx table");

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

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

    ReleaseStr(sczExpandedPath);
    ReleaseStr(sczPath);
    ReleaseStr(sczProperty);
    ReleaseStr(sczComponent);
    ReleaseStr(sczId);

    DWORD er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
    return WcaFinalize(er);
}
Esempio n. 5
0
static HRESULT ReadRegKeyWriteLegacyDb(
    __in CFGDB_STRUCT *pcdb,
    __in LEGACY_SYNC_PRODUCT_SESSION *pSyncProductSession,
    __in LEGACY_REGISTRY_KEY *pRegKey,
    __in_z LPCWSTR wzSubKey
    )
{
    HRESULT hr = S_OK;
    HKEY hkKey = NULL;
    DWORD dwType = 0;
    DWORD dwIndex = 0;
    LPWSTR sczValueName = NULL;
    LPWSTR sczSubkeyName = NULL;
    LPWSTR sczSubkeyPath = NULL;

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

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

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

        ++dwIndex;
    }

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

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

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

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

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

        ++dwIndex;
    }

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

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

    return hr;
}