static HRESULT DownloadUpdateFeed( __in_z LPCWSTR wzBundleId, __in BURN_USER_EXPERIENCE* pUX, __in BURN_UPDATE* pUpdate, __out_opt LPWSTR* psczTempFile ) { HRESULT hr = S_OK; DOWNLOAD_SOURCE downloadSource = { }; DOWNLOAD_CACHE_CALLBACK cacheCallback = { }; DOWNLOAD_AUTHENTICATION_CALLBACK authenticationCallback = { }; DETECT_AUTHENTICATION_REQUIRED_DATA authenticationData = { }; LPWSTR sczUpdateId = NULL; LPWSTR sczDestinationPath = NULL; LPWSTR sczError = NULL; DWORD64 qwDownloadSize = 0; // Always do our work in the working folder, even if cached. hr = PathCreateTimeBasedTempFile(NULL, L"UpdateFeed", NULL, L"xml", &sczDestinationPath, NULL); ExitOnFailure(hr, "Failed to create UpdateFeed based on current system time."); // Do we need a means of the BA to pass in a username and password? If so, we should copy it to downloadSource here hr = StrAllocString(&downloadSource.sczUrl, pUpdate->sczUpdateSource, 0); ExitOnFailure(hr, "Failed to copy update url."); cacheCallback.pfnProgress = NULL; //UpdateProgressRoutine; cacheCallback.pfnCancel = NULL; // TODO: set this cacheCallback.pv = NULL; //pProgress; authenticationData.pUX = pUX; authenticationData.wzPackageOrContainerId = wzBundleId; authenticationCallback.pv = static_cast<LPVOID>(&authenticationData); authenticationCallback.pfnAuthenticate = &AuthenticationRequired; hr = DownloadUrl(&downloadSource, qwDownloadSize, sczDestinationPath, &cacheCallback, &authenticationCallback); ExitOnFailure2(hr, "Failed attempt to download update feed from URL: '%ls' to: '%ls'", downloadSource.sczUrl, sczDestinationPath); if (psczTempFile) { hr = StrAllocString(psczTempFile, sczDestinationPath, 0); ExitOnFailure(hr, "Failed to copy temp file string."); } LExit: ReleaseStr(downloadSource.sczUrl); ReleaseStr(downloadSource.sczUser); ReleaseStr(downloadSource.sczPassword); ReleaseStr(sczUpdateId); ReleaseStr(sczDestinationPath); ReleaseStr(sczError); return hr; }
static HRESULT ParseWxlControl( __in IXMLDOMNode* pixn, __in DWORD dwIdx, __in WIX_LOCALIZATION* pWixLoc ) { HRESULT hr = S_OK; LOC_CONTROL* pLocControl = NULL; BSTR bstrText = NULL; pLocControl = pWixLoc->rgLocControls + dwIdx; // Id hr = XmlGetAttribute(pixn, L"Control", &bstrText); ExitOnFailure(hr, "Failed to get Xml attribute Control in Wxl file."); hr = StrAllocString(&pLocControl->wzControl, bstrText, 0); ExitOnFailure(hr, "Failed to duplicate Xml attribute Control in Wxl file."); ReleaseNullBSTR(bstrText); // X pLocControl->nX = LOC_CONTROL_NOT_SET; hr = XmlGetAttributeNumber(pixn, L"X", reinterpret_cast<DWORD*>(&pLocControl->nX)); ExitOnFailure(hr, "Failed to get control X attribute."); // Y pLocControl->nY = LOC_CONTROL_NOT_SET; hr = XmlGetAttributeNumber(pixn, L"Y", reinterpret_cast<DWORD*>(&pLocControl->nY)); ExitOnFailure(hr, "Failed to get control Y attribute."); // Width pLocControl->nWidth = LOC_CONTROL_NOT_SET; hr = XmlGetAttributeNumber(pixn, L"Width", reinterpret_cast<DWORD*>(&pLocControl->nWidth)); ExitOnFailure(hr, "Failed to get control width attribute."); // Height pLocControl->nHeight = LOC_CONTROL_NOT_SET; hr = XmlGetAttributeNumber(pixn, L"Height", reinterpret_cast<DWORD*>(&pLocControl->nHeight)); ExitOnFailure(hr, "Failed to get control height attribute."); // Text hr = XmlGetText(pixn, &bstrText); ExitOnFailure(hr, "Failed to get control text in Wxl file."); hr = StrAllocString(&pLocControl->wzText, bstrText, 0); ExitOnFailure(hr, "Failed to duplicate control text in Wxl file."); LExit: ReleaseBSTR(bstrText); return hr; }
/******************************************************************* PipeCreateNameAndSecret - *******************************************************************/ extern "C" HRESULT PipeCreateNameAndSecret( __out_z LPWSTR *psczConnectionName, __out_z LPWSTR *psczSecret ) { HRESULT hr = S_OK; WCHAR wzGuid[GUID_STRING_LENGTH]; LPWSTR sczConnectionName = NULL; LPWSTR sczSecret = NULL; // Create the unique pipe name. hr = GuidFixedCreate(wzGuid); ExitOnRootFailure(hr, "Failed to create pipe guid."); hr = StrAllocFormatted(&sczConnectionName, L"BurnPipe.%s", wzGuid); ExitOnFailure(hr, "Failed to allocate pipe name."); // Create the unique client secret. hr = GuidFixedCreate(wzGuid); ExitOnRootFailure(hr, "Failed to create pipe secret."); hr = StrAllocString(&sczSecret, wzGuid, 0); ExitOnFailure(hr, "Failed to allocate pipe secret."); *psczConnectionName = sczConnectionName; sczConnectionName = NULL; *psczSecret = sczSecret; sczSecret = NULL; LExit: ReleaseStr(sczSecret); ReleaseStr(sczConnectionName); return hr; }
DAPI_(HRESULT) PathGetParentPath( __in_z LPCWSTR wzPath, __out LPWSTR *psczParent ) { HRESULT hr = S_OK; LPCWSTR wzParent = NULL; for (LPCWSTR wz = wzPath; *wz; ++wz) { if (wz[1] && (L'\\' == *wz || L'/' == *wz)) { wzParent = wz; } } if (wzParent) { DWORD cchPath = static_cast<DWORD>(wzParent - wzPath) + 1; hr = StrAllocString(psczParent, wzPath, cchPath); ExitOnFailure(hr, "Failed to copy directory."); } else { ReleaseNullStr(psczParent); } LExit: return hr; }
extern "C" HRESULT DAPI Iis7GetPropertyString( __in IAppHostElement *pElement, __in LPCWSTR wzPropName, __in LPWSTR* psczGet ) { HRESULT hr = S_OK; VARIANT vtGet; ::VariantInit(&vtGet); hr = Iis7GetPropertyVariant(pElement, wzPropName, &vtGet); ExitOnFailure1(hr, "Failed to get iis7 property variant with name: %ls", wzPropName); if (!ISSTRINGVARIANT(vtGet.vt)) { hr = E_UNEXPECTED; ExitOnFailure1(hr, "Tried to get property as a string, but type was %d instead.", vtGet.vt); } hr = StrAllocString(psczGet, vtGet.bstrVal, 0); LExit: ReleaseVariant(vtGet); return hr; }
extern "C" HRESULT DAPI LocAddString( __in WIX_LOCALIZATION* pWixLoc, __in_z LPCWSTR wzId, __in_z LPCWSTR wzLocString, __in BOOL bOverridable ) { HRESULT hr = S_OK; ++pWixLoc->cLocStrings; pWixLoc->rgLocStrings = static_cast<LOC_STRING*>(MemReAlloc(pWixLoc->rgLocStrings, sizeof(LOC_STRING) * pWixLoc->cLocStrings, TRUE)); ExitOnNull(pWixLoc->rgLocStrings, hr, E_OUTOFMEMORY, "Failed to reallocate memory for localization strings."); LOC_STRING* pLocString = pWixLoc->rgLocStrings + (pWixLoc->cLocStrings - 1); hr = StrAllocFormatted(&pLocString->wzId, L"#(loc.%s)", wzId); ExitOnFailure(hr, "Failed to set localization string Id."); hr = StrAllocString(&pLocString->wzText, wzLocString, 0); ExitOnFailure(hr, "Failed to set localization string Text."); pLocString->bOverridable = bOverridable; LExit: return hr; }
extern "C" HRESULT CatalogElevatedUpdateCatalogFile( __in BURN_CATALOGS* pCatalogs, __in_z LPCWSTR wzId, __in_z LPCWSTR wzPath ) { HRESULT hr = S_OK; BURN_CATALOG* pCatalog = NULL; // Find the catalog hr = CatalogFindById(pCatalogs, wzId, &pCatalog); ExitOnFailure(hr, "Failed to locate catalog information."); if (NULL == pCatalog->sczLocalFilePath) { hr = StrAllocString(&pCatalog->sczLocalFilePath, wzPath, 0); ExitOnFailure(hr, "Failed to allocated catalog path."); // Get a handle to the file pCatalog->hFile = ::CreateFileW(pCatalog->sczLocalFilePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (INVALID_HANDLE_VALUE == pCatalog->hFile) { ExitWithLastError1(hr, "Failed to open catalog in working path: %ls", pCatalog->sczLocalFilePath); } } LExit: return hr; }
HRESULT SendQwordString( __in DWORD dwThreadId, __in DWORD dwMessageId, __in DWORD dwDatabaseIndex, __in DWORD64 qwQword1, __in_z LPCWSTR wzString1 ) { HRESULT hr = S_OK; QWORD_STRING *pQwordString = NULL; pQwordString = static_cast<QWORD_STRING *>(MemAlloc(sizeof(QWORD_STRING), TRUE)); pQwordString->qwQword1 = qwQword1; if (NULL != wzString1) { hr = StrAllocString(&pQwordString->sczString1, wzString1, 0); ExitOnFailure1(hr, "Failed to allocate copy of string1: %ls", wzString1); } if (!::PostThreadMessageW(dwThreadId, dwMessageId, dwDatabaseIndex, reinterpret_cast<LPARAM>(pQwordString))) { ExitWithLastError1(hr, "Failed to send message %u to worker thread", dwMessageId); } pQwordString = NULL; LExit: ReleaseQwordString(pQwordString); return hr; }
/******************************************************************* LoadSystemLibraryWithPath - Fully qualifies the path to a module in the Windows system directory and loads it and returns the path Returns E_MODNOTFOUND - The module could not be found. * - Another error occured. ********************************************************************/ extern "C" HRESULT DAPI LoadSystemLibraryWithPath( __in_z LPCWSTR wzModuleName, __out HMODULE *phModule, __deref_out_z_opt LPWSTR* psczPath ) { HRESULT hr = S_OK; DWORD cch = 0; WCHAR wzPath[MAX_PATH] = { }; cch = ::GetSystemDirectoryW(wzPath, MAX_PATH); ExitOnNullWithLastError(cch, hr, "Failed to get the Windows system directory."); if (L'\\' != wzPath[cch - 1]) { hr = ::StringCchCatNW(wzPath, MAX_PATH, L"\\", 1); ExitOnRootFailure(hr, "Failed to terminate the string with a backslash."); } hr = ::StringCchCatW(wzPath, MAX_PATH, wzModuleName); ExitOnRootFailure1(hr, "Failed to create the fully-qualified path to %ls.", wzModuleName); *phModule = ::LoadLibraryW(wzPath); ExitOnNullWithLastError1(*phModule, hr, "Failed to load the library %ls.", wzModuleName); if (psczPath) { hr = StrAllocString(psczPath, wzPath, MAX_PATH); ExitOnFailure(hr, "Failed to copy the path to library."); } LExit: return hr; }
HRESULT SendBackgroundStatusCallback( __in DWORD dwThreadId, __in HRESULT hrStatus, __in BACKGROUND_STATUS_TYPE type, __in_z LPCWSTR wzString1, __in_z LPCWSTR wzString2, __in_z LPCWSTR wzString3 ) { HRESULT hr = S_OK; BACKGROUND_STATUS_CALLBACK *pBackgroundStatusCallback = NULL; pBackgroundStatusCallback = static_cast<BACKGROUND_STATUS_CALLBACK *>(MemAlloc(sizeof(BACKGROUND_STATUS_CALLBACK), TRUE)); pBackgroundStatusCallback->hrStatus = hrStatus; pBackgroundStatusCallback->type = type; if (NULL != wzString1) { hr = StrAllocString(&pBackgroundStatusCallback->sczString1, wzString1, 0); ExitOnFailure1(hr, "Failed to allocate copy of string1: %ls", wzString1); } if (NULL != wzString2) { hr = StrAllocString(&pBackgroundStatusCallback->sczString2, wzString2, 0); ExitOnFailure1(hr, "Failed to allocate copy of string2: %ls", wzString2); } if (NULL != wzString3) { hr = StrAllocString(&pBackgroundStatusCallback->sczString3, wzString3, 0); ExitOnFailure1(hr, "Failed to allocate copy of string3: %ls", wzString3); } if (!::PostThreadMessageW(dwThreadId, WM_BROWSE_BACKGROUND_STATUS_CALLBACK, reinterpret_cast<WPARAM>(pBackgroundStatusCallback), 0)) { ExitWithLastError(hr, "Failed to send message WM_BROWSE_BACKGROUND_STATUS_CALLBACK to worker thread"); } pBackgroundStatusCallback = NULL; LExit: ReleaseBackgroundStatusCallback(pBackgroundStatusCallback); return hr; }
HRESULT SendStringTriplet( __in DWORD dwThreadId, __in DWORD dwMessageId, __in DWORD dwDatabaseIndex, __in_z LPCWSTR wzString1, __in_z LPCWSTR wzString2, __in_z LPCWSTR wzString3 ) { HRESULT hr = S_OK; STRING_TRIPLET *pStringTriplet = NULL; pStringTriplet = static_cast<STRING_TRIPLET *>(MemAlloc(sizeof(STRING_TRIPLET), TRUE)); if (NULL != wzString1) { hr = StrAllocString(&pStringTriplet->sczString1, wzString1, 0); ExitOnFailure1(hr, "Failed to allocate copy of string1: %ls", wzString1); } if (NULL != wzString2) { hr = StrAllocString(&pStringTriplet->sczString2, wzString2, 0); ExitOnFailure1(hr, "Failed to allocate copy of string2: %ls", wzString2); } if (NULL != wzString3) { hr = StrAllocString(&pStringTriplet->sczString3, wzString3, 0); ExitOnFailure1(hr, "Failed to allocate copy of string3: %ls", wzString3); } if (!::PostThreadMessageW(dwThreadId, dwMessageId, dwDatabaseIndex, reinterpret_cast<LPARAM>(pStringTriplet))) { ExitWithLastError1(hr, "Failed to send message %u to worker thread", dwMessageId); } pStringTriplet = NULL; LExit: ReleaseStringTriplet(pStringTriplet); return hr; }
DAPI_(HRESULT) BalInfoAddRelatedBundleAsPackage( __in BAL_INFO_PACKAGES* pPackages, __in LPCWSTR wzId, __in BOOTSTRAPPER_RELATION_TYPE relationType, __in BOOL /*fPerMachine*/ ) { HRESULT hr = S_OK; BAL_INFO_PACKAGE_TYPE type = BAL_INFO_PACKAGE_TYPE_UNKNOWN; BAL_INFO_PACKAGE* pPackage = NULL; // Ensure we have a supported relation type. switch (relationType) { case BOOTSTRAPPER_RELATION_ADDON: type = BAL_INFO_PACKAGE_TYPE_BUNDLE_ADDON; break; case BOOTSTRAPPER_RELATION_PATCH: type = BAL_INFO_PACKAGE_TYPE_BUNDLE_PATCH; break; case BOOTSTRAPPER_RELATION_UPGRADE: type = BAL_INFO_PACKAGE_TYPE_BUNDLE_UPGRADE; break; default: ExitOnFailure1(hr = E_INVALIDARG, "Unknown related bundle type: %u", relationType); } // Check to see if the bundle is already in the list of packages. for (DWORD i = 0; i < pPackages->cPackages; ++i) { if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzId, -1, pPackages->rgPackages[i].sczId, -1)) { ExitFunction1(hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS)); } } // Add the related bundle as a package. hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pPackages->rgPackages), pPackages->cPackages + 1, sizeof(BAL_INFO_PACKAGE), 2); ExitOnFailure(hr, "Failed to allocate memory for related bundle package information."); pPackage = pPackages->rgPackages + pPackages->cPackages; ++pPackages->cPackages; hr = StrAllocString(&pPackage->sczId, wzId, 0); ExitOnFailure(hr, "Failed to copy related bundle package id."); pPackage->type = type; // TODO: try to look up the DisplayName and Description in Add/Remove Programs with the wzId. LExit: return hr; }
HRESULT ProductSet( __in CFGDB_STRUCT *pcdb, __in_z LPCWSTR wzProductName, __in_z LPCWSTR wzVersion, __in_z LPCWSTR wzPublicKey, __in BOOL fDontCreate, __out_opt BOOL *pfLegacy ) { HRESULT hr = S_OK; SCE_ROW_HANDLE sceRow = NULL; pcdb->fProductSet = FALSE; pcdb->fProductIsLegacy = FALSE; pcdb->dwAppID = DWORD_MAX; if (fDontCreate) { // Just query for an existing product - if it exists, we'll use it hr = ProductFindRow(pcdb, PRODUCT_INDEX_TABLE, wzProductName, wzVersion, wzPublicKey, &sceRow); if (E_NOTFOUND == hr) { ExitFunction(); } ExitOnFailure(hr, "Failed to query for product"); hr = SceGetColumnDword(sceRow, PRODUCT_ID, &pcdb->dwAppID); ExitOnFailure(hr, "Failed to get App ID of application"); hr = SceGetColumnBool(sceRow, PRODUCT_IS_LEGACY, &pcdb->fProductIsLegacy); ExitOnFailure(hr, "Failed to get IsLegacy flag of application"); } else { hr = ProductEnsureCreated(pcdb, wzProductName, wzVersion, wzPublicKey, &pcdb->dwAppID, &pcdb->fProductIsLegacy); ExitOnFailure(hr, "Failed to ensure product exists: %ls", wzProductName); } // Get the AppID (of either the found row, or the recently created row) hr = StrAllocString(&pcdb->sczProductName, wzProductName, 0); ExitOnFailure(hr, "Failed to copy product name string"); if (pfLegacy) { *pfLegacy = pcdb->fProductIsLegacy; } pcdb->fProductSet = TRUE; LExit: ReleaseSceRow(sceRow); return hr; }
extern "C" HRESULT WINAPI UpdateThreadCheck( __in LPCWSTR wzAppId, __in BOOL fTryExecuteUpdate ) { HRESULT hr = S_OK; BOOL fLocked = FALSE; BACKGROUND_UPDATE_THREAD_CONTEXT* pContext = NULL; ::EnterCriticalSection(&vUpdateThreadLock); fLocked = TRUE; if (vhUpdateThread) { DWORD er = ::WaitForSingleObject(vhUpdateThread, 0); if (WAIT_OBJECT_0 == er) { ::CloseHandle(vhUpdateThread); vhUpdateThread = NULL; } else { hr = S_FALSE; ExitFunction(); } } pContext = static_cast<BACKGROUND_UPDATE_THREAD_CONTEXT*>(MemAlloc(sizeof(BACKGROUND_UPDATE_THREAD_CONTEXT), TRUE)); ExitOnNull(pContext, hr, E_OUTOFMEMORY, "Failed to allocate memory for context."); hr= StrAllocString(&pContext->pwzApplicationId, wzAppId, 0); ExitOnFailure(hr, "Failed to copy app id into context."); pContext->fExecuteUpdate = fTryExecuteUpdate; vhUpdateThread = ::CreateThread(NULL, 0, BackgroundUpdateThread, reinterpret_cast<LPVOID>(pContext), 0, NULL); ExitOnNullWithLastError(vhUpdateThread, hr, "Failed to create background update thread."); pContext = NULL; LExit: if (pContext) { ReleaseStr(pContext->pwzApplicationId); MemFree(pContext); } if (fLocked) { ::LeaveCriticalSection(&vUpdateThreadLock); } return hr; }
/******************************************************************* PipeCreateNameAndSecret - *******************************************************************/ extern "C" HRESULT PipeCreateNameAndSecret( __out_z LPWSTR *psczConnectionName, __out_z LPWSTR *psczSecret ) { HRESULT hr = S_OK; RPC_STATUS rs = RPC_S_OK; UUID guid = { }; WCHAR wzGuid[39]; LPWSTR sczConnectionName = NULL; LPWSTR sczSecret = NULL; // Create the unique pipe name. rs = ::UuidCreate(&guid); hr = HRESULT_FROM_RPC(rs); ExitOnFailure(hr, "Failed to create pipe guid."); if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid))) { hr = E_OUTOFMEMORY; ExitOnRootFailure(hr, "Failed to convert pipe guid into string."); } hr = StrAllocFormatted(&sczConnectionName, L"BurnPipe.%s", wzGuid); ExitOnFailure(hr, "Failed to allocate pipe name."); // Create the unique client secret. rs = ::UuidCreate(&guid); hr = HRESULT_FROM_RPC(rs); ExitOnRootFailure(hr, "Failed to create pipe guid."); if (!::StringFromGUID2(guid, wzGuid, countof(wzGuid))) { hr = E_OUTOFMEMORY; ExitOnRootFailure(hr, "Failed to convert pipe guid into string."); } hr = StrAllocString(&sczSecret, wzGuid, 0); ExitOnFailure(hr, "Failed to allocate pipe secret."); *psczConnectionName = sczConnectionName; sczConnectionName = NULL; *psczSecret = sczSecret; sczSecret = NULL; LExit: ReleaseStr(sczSecret); ReleaseStr(sczConnectionName); return hr; }
static HRESULT OpenRequest( __in HINTERNET hConnect, __in_z_opt LPCWSTR wzMethod, __in INTERNET_SCHEME scheme, __in_z LPCWSTR wzResource, __in_z_opt LPCWSTR wzQueryString, __in_z_opt LPCWSTR wzHeader, __out HINTERNET* phUrl ) { HRESULT hr = S_OK; DWORD dwRequestFlags = INTERNET_FLAG_KEEP_CONNECTION | INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD; LPWSTR sczResource = NULL; HINTERNET hUrl = NULL; if (INTERNET_SCHEME_HTTPS == scheme) { dwRequestFlags |= INTERNET_FLAG_SECURE; } // Allocate the resource name. hr = StrAllocString(&sczResource, wzResource, 0); ExitOnFailure(hr, "Failed to allocate string for resource URI."); if (wzQueryString && *wzQueryString) { hr = StrAllocConcat(&sczResource, wzQueryString, 0); ExitOnFailure(hr, "Failed to append query strong to resource from URI."); } // Open the request and add the header if provided. hUrl = ::HttpOpenRequestW(hConnect, wzMethod, sczResource, NULL, NULL, BURN_DOWNLOAD_ENGINE_ACCEPT_TYPES, dwRequestFlags, NULL); ExitOnNullWithLastError(hUrl, hr, "Failed to open internet request."); if (wzHeader && *wzHeader) { if (!::HttpAddRequestHeadersW(hUrl, wzHeader, static_cast<DWORD>(-1), HTTP_ADDREQ_FLAG_COALESCE)) { ExitWithLastError(hr, "Failed to add header to HTTP request."); } } *phUrl = hUrl; hUrl = NULL; LExit: ReleaseInternet(hUrl); ReleaseStr(sczResource); return hr; }
/******************************************************************** FileSpecToString *********************************************************************/ static HRESULT FileSpecToString( __in const SQL_FILESPEC* psf, __out LPWSTR* ppwz ) { Assert(psf && ppwz); HRESULT hr = S_OK; LPWSTR pwz = NULL; hr = StrAllocString(&pwz, L"(", 1024); ExitOnFailure(hr, "failed to allocate string for database file info"); ExitOnNull(*psf->wzName, hr, E_INVALIDARG, "logical name not specified in database file info"); ExitOnNull(*psf->wzFilename, hr, E_INVALIDARG, "filename not specified in database file info"); hr = StrAllocFormatted(&pwz, L"%sNAME=%s", pwz, psf->wzName); ExitOnFailure1(hr, "failed to format database file info name: %ls", psf->wzName); hr = StrAllocFormatted(&pwz, L"%s, FILENAME='%s'", pwz, psf->wzFilename); ExitOnFailure1(hr, "failed to format database file info filename: %ls", psf->wzFilename); if (0 != psf->wzSize[0]) { hr = StrAllocFormatted(&pwz, L"%s, SIZE=%s", pwz, psf->wzSize); ExitOnFailure1(hr, "failed to format database file info size: %s", psf->wzSize); } if (0 != psf->wzMaxSize[0]) { hr = StrAllocFormatted(&pwz, L"%s, MAXSIZE=%s", pwz, psf->wzMaxSize); ExitOnFailure1(hr, "failed to format database file info maxsize: %s", psf->wzMaxSize); } if (0 != psf->wzGrow[0]) { hr = StrAllocFormatted(&pwz, L"%s, FILEGROWTH=%s", pwz, psf->wzGrow); ExitOnFailure1(hr, "failed to format database file info growth: %s", psf->wzGrow); } hr = StrAllocFormatted(&pwz, L"%s)", pwz); ExitOnFailure(hr, "failed to allocate string for file spec"); *ppwz = pwz; pwz = NULL; // null here so it doesn't get freed below LExit: ReleaseStr(pwz); return hr; }
// Gets the path to ngen.exe static HRESULT GetNgenPath( __out LPWSTR* ppwzNgenPath, __in BOOL f64BitFramework ) { Assert(ppwzNgenPath); HRESULT hr = S_OK; LPWSTR pwzVersion = NULL; LPWSTR pwzWindowsFolder = NULL; hr = WcaGetProperty(L"WindowsFolder", &pwzWindowsFolder); ExitOnFailure(hr, "failed to get WindowsFolder property"); hr = StrAllocString(ppwzNgenPath, pwzWindowsFolder, 0); ExitOnFailure1(hr, "failed to copy to NgenPath windows folder: %ls", pwzWindowsFolder); if (f64BitFramework) { WcaLog(LOGMSG_VERBOSE, "Searching for ngen under 64-bit framework path"); hr = StrAllocConcat(ppwzNgenPath, L"Microsoft.NET\\Framework64\\", 0); ExitOnFailure(hr, "failed to copy platform portion of ngen path"); } else { WcaLog(LOGMSG_VERBOSE, "Searching for ngen under 32-bit framework path"); hr = StrAllocConcat(ppwzNgenPath, L"Microsoft.NET\\Framework\\", 0); ExitOnFailure(hr, "failed to copy platform portion of ngen path"); } // We want to run the highest version of ngen possible, because they should be backwards compatible - so let's find the most appropriate directory now hr = GetNgenVersion(*ppwzNgenPath, &pwzVersion); ExitOnFailure1(hr, "failed to search for ngen under path %ls", *ppwzNgenPath); hr = StrAllocConcat(ppwzNgenPath, pwzVersion, 0); ExitOnFailure(hr, "failed to copy version portion of ngen path"); hr = StrAllocConcat(ppwzNgenPath, L"\\ngen.exe", 0); ExitOnFailure(hr, "failed to copy \"\\ngen.exe\" portion of ngen path"); LExit: ReleaseStr(pwzVersion); ReleaseStr(pwzWindowsFolder); return hr; }
HRESULT ProductGetLegacyManifestValueName( __in_z LPCWSTR wzProductName, __deref_out_z LPWSTR* psczManifestValueName ) { HRESULT hr = S_OK; hr = StrAllocString(psczManifestValueName, wzLegacyManifestValuePrefix, 0); ExitOnFailure(hr, "Failed to allocate legacy manifest value prefix"); hr = StrAllocConcat(psczManifestValueName, wzProductName, 0); ExitOnFailure(hr, "Failed to concat product name %ls to manifest value name", wzProductName); LExit: return hr; }
DAPI_(HRESULT) JsonInitializeReader( __in_z LPCWSTR wzJson, __in JSON_READER* pReader ) { HRESULT hr = S_OK; memset(pReader, 0, sizeof(JSON_READER)); ::InitializeCriticalSection(&pReader->cs); hr = StrAllocString(&pReader->sczJson, wzJson, 0); ExitOnFailure(hr, "Failed to allocate json string."); pReader->pwz = pReader->sczJson; LExit: return hr; }
DAPI_(HRESULT) JsonWriteBool( __in JSON_WRITER* pWriter, __in BOOL fValue ) { HRESULT hr = S_OK; LPWSTR sczValue = NULL; hr = StrAllocString(&sczValue, fValue ? L"true" : L"false", 0); ExitOnFailure(hr, "Failed to convert boolean to string."); hr = DoValue(pWriter, sczValue); ExitOnFailure(hr, "Failed to add boolean to JSON."); LExit: ReleaseStr(sczValue); return hr; }
static HRESULT ParseWxlString( __in IXMLDOMNode* pixn, __in DWORD dwIdx, __in WIX_LOCALIZATION* pWixLoc ) { HRESULT hr = S_OK; LOC_STRING* pLocString = NULL; BSTR bstrText = NULL; pLocString = pWixLoc->rgLocStrings + dwIdx; // Id hr = XmlGetAttribute(pixn, L"Id", &bstrText); ExitOnFailure(hr, "Failed to get Xml attribute Id in Wxl file."); hr = StrAllocFormatted(&pLocString->wzId, L"#(loc.%s)", bstrText); ExitOnFailure(hr, "Failed to duplicate Xml attribute Id in Wxl file."); ReleaseNullBSTR(bstrText); // Overrideable hr = XmlGetAttribute(pixn, L"Overridable", &bstrText); ExitOnFailure(hr, "Failed to get Xml attribute Overridable."); if (S_OK == hr) { pLocString->bOverridable = CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, bstrText, -1, L"yes", -1); } ReleaseNullBSTR(bstrText); // Text hr = XmlGetText(pixn, &bstrText); ExitOnFailure(hr, "Failed to get Xml text in Wxl file."); hr = StrAllocString(&pLocString->wzText, bstrText, 0); ExitOnFailure(hr, "Failed to duplicate Xml text in Wxl file."); LExit: ReleaseBSTR(bstrText); return hr; }
// // ProcessCommandLine - process the provided command line arguments. // static HRESULT ProcessCommandLine( __in_z_opt LPCWSTR wzCommandLine, __out_z LPWSTR* psczThemeFile ) { HRESULT hr = S_OK; int argc = 0; LPWSTR* argv = NULL; if (wzCommandLine && *wzCommandLine) { argv = ::CommandLineToArgvW(wzCommandLine, &argc); ExitOnNullWithLastError(argv, hr, "Failed to get command line."); for (int i = 0; i < argc; ++i) { if (argv[i][0] == L'-' || argv[i][0] == L'/') { if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"lang", -1)) { if (i + 1 >= argc) { ExitOnRootFailure(hr = E_INVALIDARG, "Must specify a language."); } ++i; } } else { hr = StrAllocString(psczThemeFile, argv[i], 0); ExitOnFailure(hr, "Failed to copy path to theme file."); } } } LExit: if (argv) { ::LocalFree(argv); } return hr; }
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; }
static HRESULT GetNonSessionSpecificTempFolder( __deref_out_z LPWSTR* psczNonSessionTempFolder ) { HRESULT hr = S_OK; WCHAR wzTempFolder[MAX_PATH] = { }; DWORD cchTempFolder = 0; DWORD dwSessionId = 0; LPWSTR sczSessionId = 0; DWORD cchSessionId = 0; if (!::GetTempPathW(countof(wzTempFolder), wzTempFolder)) { ExitWithLastError(hr, "Failed to get temp folder."); } hr = ::StringCchLengthW(wzTempFolder, countof(wzTempFolder), reinterpret_cast<size_t*>(&cchTempFolder)); ExitOnFailure(hr, "Failed to get length of temp folder."); // If our session id is in the TEMP path then remove that part so we get the non-session // specific temporary folder. if (::ProcessIdToSessionId(::GetCurrentProcessId(), &dwSessionId)) { hr = StrAllocFormatted(&sczSessionId, L"%u\\", dwSessionId); ExitOnFailure(hr, "Failed to format session id as a string."); hr = ::StringCchLengthW(sczSessionId, STRSAFE_MAX_CCH, reinterpret_cast<size_t*>(&cchSessionId)); ExitOnFailure(hr, "Failed to get length of session id string."); if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzTempFolder + cchTempFolder - cchSessionId, cchSessionId, sczSessionId, cchSessionId)) { cchTempFolder -= cchSessionId; } } hr = StrAllocString(psczNonSessionTempFolder, wzTempFolder, cchTempFolder); ExitOnFailure(hr, "Failed to copy temp folder."); LExit: ReleaseStr(sczSessionId); return hr; }
extern "C" HRESULT LoggingSetPackageVariable( __in BURN_PACKAGE* pPackage, __in_z_opt LPCWSTR wzSuffix, __in BOOL fRollback, __in BURN_LOGGING* pLog, __in BURN_VARIABLES* pVariables, __out_opt LPWSTR* psczLogPath ) { HRESULT hr = S_OK; LPWSTR sczLogPath = NULL; if (BURN_LOGGING_STATE_DISABLED == pLog->state) { if (psczLogPath) { *psczLogPath = NULL; } ExitFunction(); } if ((!fRollback && pPackage->sczLogPathVariable && *pPackage->sczLogPathVariable) || (fRollback && pPackage->sczRollbackLogPathVariable && *pPackage->sczRollbackLogPathVariable)) { hr = StrAllocFormatted(&sczLogPath, L"%ls%hs%ls_%03u_%ls%ls.%ls", pLog->sczPrefix, wzSuffix && *wzSuffix ? "_" : "", wzSuffix && *wzSuffix ? wzSuffix : L"", vdwPackageSequence, pPackage->sczId, fRollback ? L"_rollback" : L"", pLog->sczExtension); ExitOnFailure(hr, "Failed to allocate path for package log."); hr = VariableSetString(pVariables, fRollback ? pPackage->sczRollbackLogPathVariable : pPackage->sczLogPathVariable, sczLogPath, FALSE); ExitOnFailure(hr, "Failed to set log path into variable."); if (psczLogPath) { hr = StrAllocString(psczLogPath, sczLogPath, 0); ExitOnFailure(hr, "Failed to copy package log path."); } } LExit: ReleaseStr(sczLogPath); return hr; }
/******************************************************************** 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; }
extern "C" HRESULT DAPI PolcReadString( __in_z LPCWSTR wzPolicyPath, __in_z LPCWSTR wzPolicyName, __in_z_opt LPCWSTR wzDefault, __deref_out_z LPWSTR* pscz ) { HRESULT hr = S_OK; HKEY hk = NULL; hr = OpenPolicyKey(wzPolicyPath, &hk); if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr) { ExitFunction1(hr = S_FALSE); } ExitOnFailure1(hr, "Failed to open policy key: %ls", wzPolicyPath); hr = RegReadString(hk, wzPolicyName, pscz); if (E_FILENOTFOUND == hr || E_PATHNOTFOUND == hr) { ExitFunction1(hr = S_FALSE); } ExitOnFailure2(hr, "Failed to open policy key: %ls, name: %ls", wzPolicyPath, wzPolicyName); LExit: ReleaseRegKey(hk); if (S_FALSE == hr || FAILED(hr)) { if (NULL == wzDefault) { ReleaseNullStr(*pscz); } else { hr = StrAllocString(pscz, wzDefault, 0); } } return hr; }
static HRESULT EscapeSqlIdentifier( __in_z LPCWSTR wzIdentifier, __deref_out_z LPWSTR* ppwz ) { Assert(ppwz); HRESULT hr = S_OK; LPWSTR pwz = NULL; if (wzIdentifier == NULL) { //Just ignore a NULL identifier and clear out the result ReleaseNullStr(*ppwz); ExitFunction(); } int cchIdentifier = lstrlenW(wzIdentifier); //If an empty string or already escaped just copy if (cchIdentifier == 0 || (wzIdentifier[0] == '[' && wzIdentifier[cchIdentifier-1] == ']')) { hr = StrAllocString(&pwz, wzIdentifier, 0); ExitOnFailure1(hr, "failed to format database name: %ls", wzIdentifier); } else { //escape it hr = StrAllocFormatted(&pwz, L"[%s]", wzIdentifier); ExitOnFailure1(hr, "failed to format escaped database name: %ls", wzIdentifier); } *ppwz = pwz; pwz = NULL; // null here so it doesn't get freed below LExit: ReleaseStr(pwz); return hr; }
DAPI_(HRESULT) PathGetDirectory( __in_z LPCWSTR wzPath, __out LPWSTR *psczDirectory ) { HRESULT hr = S_OK; DWORD cchDirectory = DWORD_MAX; for (LPCWSTR wz = wzPath; *wz; ++wz) { // valid delineators: // \ => Windows path // / => unix and URL path // : => relative path from mapped root if (L'\\' == *wz || L'/' == *wz || (L':' == *wz && wz == wzPath + 1)) { cchDirectory = static_cast<DWORD>(wz - wzPath) + 1; } } if (DWORD_MAX == cchDirectory) { // we were given just a file name, so there's no directory available return S_FALSE; } if (wzPath[0] == L'\"') { ++wzPath; --cchDirectory; } hr = StrAllocString(psczDirectory, wzPath, cchDirectory); ExitOnFailure(hr, "Failed to copy directory."); LExit: return hr; }