/******************************************************************** StrAllocFormattedArgs - allocates or reuses dynamic string memory and formats it with the passed in args NOTE: caller is responsible for freeing ppwz even if function fails ********************************************************************/ extern "C" HRESULT DAPI StrAllocFormattedArgs( __inout LPWSTR* ppwz, __in LPCWSTR wzFormat, __in va_list args ) { Assert(ppwz && wzFormat && *wzFormat); HRESULT hr = S_OK; DWORD_PTR cch = 0; LPWSTR pwzOriginal = NULL; DWORD_PTR cchOriginal = 0; if (*ppwz) { cch = MemSize(*ppwz); // get the count in bytes so we can check if it failed (returns -1) if (-1 == cch) ExitOnFailure(hr = E_INVALIDARG, "failed to get size of destination string"); cch /= sizeof(WCHAR); //convert the count in bytes to count in characters cchOriginal = lstrlenW(*ppwz); } if (0 == cch) // if there is no space in the string buffer { cch = 256; hr = StrAlloc(ppwz, cch); ExitOnFailure1(hr, "failed to allocate string to format: %S", wzFormat); } // format the message (grow until it fits or there is a failure) do { hr = StringCchVPrintfW(*ppwz, cch, wzFormat, args); if (STRSAFE_E_INSUFFICIENT_BUFFER == hr) { if (!pwzOriginal) { // this allows you to pass the original string as a formatting argument and not crash // save the original string and free it after the printf is complete pwzOriginal = *ppwz; *ppwz = NULL; // StringCchVPrintfW starts writing to the string... // NOTE: this hack only works with sprintf(&pwz, "%s ...", pwz, ...); pwzOriginal[cchOriginal] = 0; } cch *= 2; hr = StrAlloc(ppwz, cch); ExitOnFailure1(hr, "failed to allocate string to format: %S", wzFormat); hr = S_FALSE; } } while (S_FALSE == hr); ExitOnFailure(hr, "failed to format string"); LExit: ReleaseStr((void*) pwzOriginal); return hr; }
/******************************************************************** WcaGetFormattedString - gets a formatted string value from the active install ********************************************************************/ extern "C" HRESULT WIXAPI WcaGetFormattedString( __in_z LPCWSTR wzString, __out LPWSTR* ppwzData ) { if (!wzString || !*wzString || !ppwzData) { return E_INVALIDARG; } HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; PMSIHANDLE hRecord = ::MsiCreateRecord(1); DWORD_PTR cch = 0; er = ::MsiRecordSetStringW(hRecord, 0, wzString); ExitOnWin32Error1(er, hr, "Failed to set record field 0 with '%ls'", wzString); if (!*ppwzData) { WCHAR szEmpty[1] = L""; er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecord, szEmpty, (DWORD *)&cch); if (ERROR_MORE_DATA == er || ERROR_SUCCESS == er) { hr = StrAlloc(ppwzData, ++cch); } else { hr = HRESULT_FROM_WIN32(er); } ExitOnFailure1(hr, "Failed to allocate string for formatted string: '%ls'", wzString); } else { hr = StrMaxLength(*ppwzData, &cch); ExitOnFailure(hr, "Failed to get previous size of property data string"); } er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecord, *ppwzData, (DWORD *)&cch); if (ERROR_MORE_DATA == er) { hr = StrAlloc(ppwzData, ++cch); ExitOnFailure1(hr, "Failed to allocate string for formatted string: '%ls'", wzString); er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecord, *ppwzData, (DWORD *)&cch); } ExitOnWin32Error1(er, hr, "Failed to get formatted string: '%ls'", wzString); LExit: return hr; }
/******************************************************************** RegKeyEnum - enumerates a registry key. *********************************************************************/ extern "C" HRESULT DAPI RegKeyEnum( __in HKEY hk, __in DWORD dwIndex, __deref_out_z LPWSTR* psczKey ) { HRESULT hr = S_OK; DWORD er = ERROR_SUCCESS; DWORD cch = 0; if (psczKey && *psczKey) { hr = StrMaxLength(*psczKey, reinterpret_cast<DWORD_PTR*>(&cch)); ExitOnFailure(hr, "Failed to determine length of string."); } if (2 > cch) { cch = 2; hr = StrAlloc(psczKey, cch); ExitOnFailure(hr, "Failed to allocate string to minimum size."); } er = vpfnRegEnumKeyExW(hk, dwIndex, *psczKey, &cch, NULL, NULL, NULL, NULL); if (ERROR_MORE_DATA == er) { er = vpfnRegQueryInfoKeyW(hk, NULL, NULL, NULL, NULL, &cch, NULL, NULL, NULL, NULL, NULL, NULL); ExitOnWin32Error(er, hr, "Failed to get max size of subkey name under registry key."); ++cch; // add one because RegQueryInfoKeyW() returns the length of the subkeys without the null terminator. hr = StrAlloc(psczKey, cch); ExitOnFailure(hr, "Failed to allocate string bigger for enum registry key."); er = vpfnRegEnumKeyExW(hk, dwIndex, *psczKey, &cch, NULL, NULL, NULL, NULL); } else if (ERROR_NO_MORE_ITEMS == er) { ExitFunction1(hr = E_NOMOREITEMS); } ExitOnWin32Error(er, hr, "Failed to enum registry key."); // Always ensure the registry key name is null terminated. #pragma prefast(push) #pragma prefast(disable:26018) (*psczKey)[cch] = L'\0'; // note that cch will always be one less than the size of the buffer because that's how RegEnumKeyExW() works. #pragma prefast(pop) LExit: return hr; }
HRESULT MqiMessageQueueVerify( MQI_MESSAGE_QUEUE_LIST* pList ) { HRESULT hr = S_OK; LPWSTR pwzFormatName = NULL; DWORD dwCount = 128; for (MQI_MESSAGE_QUEUE* pItm = pList->pFirst; pItm; pItm = pItm->pNext) { // queues that are being installed only if (!WcaIsInstalling(pItm->isInstalled, pItm->isAction)) continue; // get format name hr = StrAlloc(&pwzFormatName, dwCount); ExitOnFailure(hr, "Failed to allocate format name string"); do { hr = gpfnMQPathNameToFormatName(pItm->wzPathName, pwzFormatName, &dwCount); switch (hr) { case MQ_ERROR_QUEUE_NOT_FOUND: break; // break case MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL: hr = StrAlloc(&pwzFormatName, dwCount); ExitOnFailure(hr, "Failed to reallocate format name string"); hr = S_FALSE; // retry break; default: ExitOnFailure(hr, "Failed to get format name"); hr = S_OK; } } while (S_FALSE == hr); if (MQ_ERROR_QUEUE_NOT_FOUND == hr) { continue; } pItm->fExists = TRUE; pList->iInstallCount--; // clean up ReleaseNullStr(pwzFormatName); } hr = S_OK; LExit: ReleaseStr(pwzFormatName); return hr; }
PLINK_FILE FsmReadCFile( FILE *fd ) { PLINK_FILE pFileBase = NULL, pFile; UCHAR auchLine[ MAX_LINE_LEN ]; BOOL boolOldFsmCode = FALSE; PSZ pszToken, pszTmp; USHORT i; // PSZ pszLine = (PSZ)auchLine; while (fgets( auchLine, MAX_LINE_LEN - 1, fd ) != NULL) { if (!boolOldFsmCode) { NEW( pFile ); pFile->pszLine = StrAlloc( auchLine ); pFile->usState = FSM_NORMAL_C_LINE; pFileBase = LinkElement( pFileBase, pFile ); if (!memcmp( auchLine, "#ifdef", sizeof( "#ifdef" ) - 1 )) { // I don't trust on sscanf ... pszToken = StrNotBrk( &auchLine[sizeof( "#ifdef" )], " \t"); pszTmp = StrBrk( pszToken, " \t\n\r"); *pszTmp = 0; for (i = 0; aFsmCTokens[i].pszToken != NULL; i++) { if (!_stricmp( aFsmCTokens[i].pszToken, pszToken )) { pFile->usState = aFsmCTokens[i].usToken; boolOldFsmCode = TRUE; break; } } } } else { if (!memcmp( auchLine, "#endif", sizeof( "#endif" ) - 1)) { boolOldFsmCode = FALSE; NEW( pFile ); pFile->usState = FSM_NORMAL_C_LINE; pFile->pszLine = StrAlloc( auchLine ); pFileBase = LinkElement( pFileBase, pFile ); } } } return pFileBase; }
/******************************************************************** WcaGetProperty - gets a string property value from the active install ********************************************************************/ extern "C" HRESULT WIXAPI WcaGetProperty( __in_z LPCWSTR wzProperty, __inout LPWSTR* ppwzData ) { if (!wzProperty || !*wzProperty || !ppwzData) { return E_INVALIDARG; } HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; DWORD_PTR cch = 0; if (!*ppwzData) { WCHAR szEmpty[1] = L""; er = ::MsiGetPropertyW(WcaGetInstallHandle(), wzProperty, szEmpty, (DWORD *)&cch); if (ERROR_MORE_DATA == er || ERROR_SUCCESS == er) { hr = StrAlloc(ppwzData, ++cch); } else { hr = HRESULT_FROM_WIN32(er); } ExitOnFailure1(hr, "Failed to allocate string for Property '%ls'", wzProperty); } else { hr = StrMaxLength(*ppwzData, &cch); ExitOnFailure(hr, "Failed to get previous size of property data string."); } er = ::MsiGetPropertyW(WcaGetInstallHandle(), wzProperty, *ppwzData, (DWORD *)&cch); if (ERROR_MORE_DATA == er) { Assert(*ppwzData); hr = StrAlloc(ppwzData, ++cch); ExitOnFailure1(hr, "Failed to allocate string for Property '%ls'", wzProperty); er = ::MsiGetPropertyW(WcaGetInstallHandle(), wzProperty, *ppwzData, (DWORD *)&cch); } ExitOnWin32Error1(er, hr, "Failed to get data for property '%ls'", wzProperty); LExit: return hr; }
/******************************************************************** WcaGetTargetPath - gets the target path for a specified folder ********************************************************************/ extern "C" HRESULT WIXAPI WcaGetTargetPath( __in_z LPCWSTR wzFolder, __out LPWSTR* ppwzData ) { if (!wzFolder || !*wzFolder || !ppwzData) return E_INVALIDARG; HRESULT hr = S_OK; UINT er = ERROR_SUCCESS; DWORD_PTR cch = 0; if (!*ppwzData) { WCHAR szEmpty[1] = L""; er = ::MsiGetTargetPathW(WcaGetInstallHandle(), wzFolder, szEmpty, (DWORD*)&cch); if (ERROR_MORE_DATA == er || ERROR_SUCCESS == er) { ++cch; //Add one for the null terminator hr = StrAlloc(ppwzData, cch); } else { hr = HRESULT_FROM_WIN32(er); } ExitOnFailure1(hr, "Failed to allocate string for target path of folder: '%ls'", wzFolder); } else { hr = StrMaxLength(*ppwzData, &cch); ExitOnFailure(hr, "Failed to get previous size of string"); } er = ::MsiGetTargetPathW(WcaGetInstallHandle(), wzFolder, *ppwzData, (DWORD*)&cch); if (ERROR_MORE_DATA == er) { ++cch; hr = StrAlloc(ppwzData, cch); ExitOnFailure1(hr, "Failed to allocate string for target path of folder: '%ls'", wzFolder); er = ::MsiGetTargetPathW(WcaGetInstallHandle(), wzFolder, *ppwzData, (DWORD*)&cch); } ExitOnWin32Error1(er, hr, "Failed to get target path for folder '%ls'", wzFolder); LExit: return hr; }
/******************************************************************** StrAllocString - allocates or reuses dynamic string memory and copies in an existing string NOTE: caller is responsible for freeing ppwz even if function fails NOTE: cchSource does not have to equal the length of wzSource NOTE: if cchSource == 0, length of wzSource is used instead ********************************************************************/ extern "C" HRESULT DAPI StrAllocString( __inout LPWSTR* ppwz, __in LPCWSTR wzSource, __in DWORD_PTR cchSource ) { Assert(ppwz && wzSource); // && *wzSource); HRESULT hr = S_OK; DWORD_PTR cch = 0; if (*ppwz) { cch = MemSize(*ppwz); // get the count in bytes so we can check if it failed (returns -1) if (-1 == cch) ExitOnFailure(hr = E_INVALIDARG, "failed to get size of destination string"); cch /= sizeof(WCHAR); //convert the count in bytes to count in characters } if (0 == cchSource) cchSource = lstrlenW(wzSource); if (cch < cchSource + 1) { cch = cchSource + 1; // add one for the null terminator hr = StrAlloc(ppwz, cch); ExitOnFailure1(hr, "failed to allocate string from string: %S", wzSource); } // copy everything (the NULL terminator will be included) hr = StringCchCopyNExW(*ppwz, cch, wzSource, cchSource, NULL, NULL, STRSAFE_FILL_BEHIND_NULL); LExit: return hr; }
/******************************************************************** RegValueEnum - enumerates a registry value. *********************************************************************/ HRESULT DAPI RegValueEnum( __in HKEY hk, __in DWORD dwIndex, __deref_out_z LPWSTR* psczName, __out_opt DWORD *pdwType ) { HRESULT hr = S_OK; DWORD er = ERROR_SUCCESS; DWORD cbValueName = 0; er = vpfnRegQueryInfoKeyW(hk, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &cbValueName, NULL, NULL, NULL); ExitOnWin32Error(er, hr, "Failed to get max size of value name under registry key."); // Add one for null terminator ++cbValueName; hr = StrAlloc(psczName, cbValueName); ExitOnFailure(hr, "Failed to allocate array for registry value name"); er = vpfnRegEnumValueW(hk, dwIndex, *psczName, &cbValueName, NULL, pdwType, NULL, NULL); if (ERROR_NO_MORE_ITEMS == er) { ExitFunction1(hr = E_NOMOREITEMS); } ExitOnWin32Error(er, hr, "Failed to enumerate registry value"); LExit: return hr; }
/* ------------------ field operations ------------------------- */ bool Field( cAppCharP item, cAppCharP key, char** field ) { char* b; char* e; char* t= (char*)item; *field= NULL; while (true) { b= strstr( t,key ); if (!b) break; /* <key> available ? */ e= strstr( b,"\r" ); if (!e) e= strstr( b,"\n" ); /* get the end of this field */ if (b==item || *(b-1)=='\r' || *(b-1)=='\n') { b+= strlen( key )+1; if (*(b-1)==':') { /* correctly separated ? */ if (!e) *field= StrAlloc ( b ); /* either the rest */ else *field= StrAllocN( b, e-b, false ); /* or till next field */ return true; } /* if */ if (!e) break; } /* if */ t= e+1; /* go to the next field */ } /* loop */ return false; } /* Field */
const char *DELEGATE_Version(){ CStr(buf,128); if( Version == 0 ){ sprintf(buf,"%s (%s) %s", DELEGATE_version(), AUTHOR, DATE); Version = StrAlloc(buf); } return Version; }
/******************************************************************** WcaGetRecordString() - gets a string field out of a record ********************************************************************/ extern "C" HRESULT WIXAPI WcaGetRecordString( __in MSIHANDLE hRec, __in UINT uiField, __inout LPWSTR* ppwzData ) { if (!hRec || !ppwzData) return E_INVALIDARG; HRESULT hr = S_OK; UINT er; DWORD_PTR cch = 0; if (!*ppwzData) { WCHAR szEmpty[1] = L""; er = ::MsiRecordGetStringW(hRec, uiField, szEmpty, (DWORD*)&cch); if (ERROR_MORE_DATA == er || ERROR_SUCCESS == er) { hr = StrAlloc(ppwzData, ++cch); } else { hr = HRESULT_FROM_WIN32(er); } ExitOnFailure(hr, "Failed to allocate memory for record string"); } else { hr = StrMaxLength(*ppwzData, &cch); ExitOnFailure(hr, "Failed to get previous size of string"); } er = ::MsiRecordGetStringW(hRec, uiField, *ppwzData, (DWORD*)&cch); if (ERROR_MORE_DATA == er) { hr = StrAlloc(ppwzData, ++cch); ExitOnFailure(hr, "Failed to allocate memory for record string"); er = ::MsiRecordGetStringW(hRec, uiField, *ppwzData, (DWORD*)&cch); } ExitOnWin32Error(er, hr, "Failed to get string from record"); LExit: return hr; }
const char *DELEGATE_verdate(){ CStr(buf,128); if( verdate == 0 ){ sprintf(buf,"%s/%s (%s)",NAME,VERSION,DATE); verdate = StrAlloc(buf); } return verdate; }
const char *DELEGATE_Ver(){ CStr(buf,128); if( Ver == 0 ){ sprintf(buf,"%s/%s (%s) by %s (%s)", NAME,VERSION, DATE, AUTHOR, A_ORG); Ver = StrAlloc(buf); } return Ver; }
const char *DELEGATE_version(){ CStr(buf,128); if( version == 0 ){ sprintf(buf,"%s/%s by %s", NAME,VERSION, A_EMAIL); version = StrAlloc(buf); } return version; }
static String GapPrintPoly(const Poly_t *pol) { String s = StrAlloc(10); int i; StrAppend(&s, "["); for (i = 0; i < pol->Degree; ++i) StrAppendF(&s,"%s,",FfToGap(pol->Data[i])); StrAppendF(&s,"%s]",FfToGap(pol->Data[i])); return s; }
/******************************************************************** WcaGetRecordFormattedString() - gets formatted string filed from record ********************************************************************/ extern "C" HRESULT WIXAPI WcaGetRecordFormattedString( __in MSIHANDLE hRec, __in UINT uiField, __inout LPWSTR* ppwzData ) { if (!hRec || !ppwzData) { return E_INVALIDARG; } HRESULT hr = S_OK; UINT er; DWORD_PTR cch = 0; PMSIHANDLE hRecFormat; // get the format string hr = WcaGetRecordString(hRec, uiField, ppwzData); ExitOnFailure(hr, "failed to get string from record"); if (!**ppwzData) { ExitFunction(); } // hide the nulls '[~]' so we can get them back after formatting HideNulls(*ppwzData); // set up the format record hRecFormat = ::MsiCreateRecord(1); ExitOnNull(hRecFormat, hr, E_UNEXPECTED, "Failed to create record to format string"); hr = WcaSetRecordString(hRecFormat, 0, *ppwzData); ExitOnFailure(hr, "failed to set string to format record"); // format the string hr = StrMaxLength(*ppwzData, &cch); ExitOnFailure(hr, "failed to get max length of string"); er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecFormat, *ppwzData, (DWORD*)&cch); if (ERROR_MORE_DATA == er) { hr = StrAlloc(ppwzData, ++cch); ExitOnFailure(hr, "Failed to allocate memory for record string"); er = ::MsiFormatRecordW(WcaGetInstallHandle(), hRecFormat, *ppwzData, (DWORD*)&cch); } ExitOnWin32Error(er, hr, "Failed to format string"); // put the nulls back RevealNulls(*ppwzData); LExit: return hr; }
static HRESULT DeleteMessageQueue( MQI_MESSAGE_QUEUE_ATTRIBUTES* pAttrs ) { HRESULT hr = S_OK; LPWSTR pwzFormatName = NULL; DWORD dwCount = 128; // get format name hr = StrAlloc(&pwzFormatName, dwCount); ExitOnFailure(hr, "Failed to allocate format name string"); do { hr = gpfnMQPathNameToFormatName(pAttrs->pwzPathName, pwzFormatName, &dwCount); switch (hr) { case MQ_ERROR_QUEUE_NOT_FOUND: ExitFunction1(hr = S_OK); // nothing to delete case MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL: hr = StrAlloc(&pwzFormatName, dwCount); ExitOnFailure(hr, "Failed to reallocate format name string"); hr = S_FALSE; // retry break; default: ExitOnFailure(hr, "Failed to get format name"); hr = S_OK; } } while (S_FALSE == hr); // delete queue hr = gpfnMQDeleteQueue(pwzFormatName); ExitOnFailure(hr, "Failed to delete queue"); hr = S_OK; LExit: // clean up ReleaseStr(pwzFormatName); return hr; }
/******************************************************************** StrAllocPrefix - allocates or reuses dynamic string memory and prefixes a string NOTE: caller is responsible for freeing ppwz even if function fails NOTE: cchPrefix does not have to equal the length of wzPrefix NOTE: if cchPrefix == 0, length of wzPrefix is used instead ********************************************************************/ extern "C" HRESULT DAPI StrAllocPrefix( __inout LPWSTR* ppwz, __in LPCWSTR wzPrefix, __in DWORD_PTR cchPrefix ) { Assert(ppwz && wzPrefix); HRESULT hr = S_OK; DWORD_PTR cch = 0; DWORD_PTR cchLen = 0; if (*ppwz) { cch = MemSize(*ppwz); // get the count in bytes so we can check if it failed (returns -1) if (-1 == cch) ExitOnFailure(hr = E_INVALIDARG, "failed to get size of destination string"); cch /= sizeof(WCHAR); //convert the count in bytes to count in characters StringCchLengthW(*ppwz, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen)); } Assert(cchLen <= cch); if (0 == cchPrefix) { StringCchLengthW(wzPrefix, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchPrefix)); } if (cch - cchLen < cchPrefix + 1) { cch = cchPrefix + cchLen + 1; hr = StrAlloc(ppwz, cch); ExitOnFailure1(hr, "failed to allocate string from string: %S", wzPrefix); } if (*ppwz) { DWORD_PTR cb = cch * sizeof(WCHAR); DWORD_PTR cbPrefix = cchPrefix * sizeof(WCHAR); memmove(*ppwz + cchPrefix, *ppwz, cb - cbPrefix); memcpy(*ppwz, wzPrefix, cbPrefix); } else { ExitOnFailure(hr = E_UNEXPECTED, "for some reason our buffer is still null"); } LExit: return hr; }
/************************************************************************* * StrDuplicate */ char *StrDuplicate(const char *source) { char *target; assert(VALID(source)); target = StrAlloc(StrLength(source) + 1); if (target) { StrCopy(target, source); } return target; }
const char *DELEGATE_copyright(){ CStr(buf,0x2000); int len; if( copyright == 0 ){ strcpy(buf,COPYRIGHT); if( LICENSEE != 0 && *LICENSEE != 0 ){ strcat(buf,"\r\nLicensee: "); len = strlen(buf); XStrncpy(QVStr(buf+len,buf),LICENSEE,sizeof(buf)-len); } copyright = StrAlloc(buf); } return copyright; }
char * CreateManpageName( char * entry, int section, /* FIXME: unused */ int flags) { char * cp; char page[BUFSIZ]; char sect[BUFSIZ]; ParseEntry(entry, NULL, sect, page); #ifndef CRAY if ( (cp = rindex(page, '.')) != NULL) { if ( (int)strlen(cp) > 2 ) { *cp++ = '('; while( (cp[1] != '\0') ) { *cp = *(cp + 1); cp++; } *cp++ = ')'; *cp = '\0'; } else *cp = '\0'; } #else /* CRAY - pick up the Cray name from the section */ if ( (cp = rindex(page, '.')) == NULL) cp = page + strlen(page); if ((flags & MSUFFIX) && strlen(sect) > 4) { char *p = sect + 4; *cp++ = '('; while (*p) *cp++ = *p++; *cp++ = ')'; } *cp = '\0'; #endif /* CRAY */ return(StrAlloc(page)); }
/******************************************************************** StrAllocConcat - allocates or reuses dynamic string memory and adds an existing string NOTE: caller is responsible for freeing ppwz even if function fails NOTE: cchSource does not have to equal the length of wzSource NOTE: if cchSource == 0, length of wzSource is used instead ********************************************************************/ extern "C" HRESULT DAPI StrAllocConcat( __inout LPWSTR* ppwz, __in LPCWSTR wzSource, __in DWORD_PTR cchSource ) { Assert(ppwz && wzSource); // && *wzSource); HRESULT hr = S_OK; DWORD_PTR cch = 0; DWORD_PTR cchLen = 0; if (*ppwz) { cch = MemSize(*ppwz); // get the count in bytes so we can check if it failed (returns -1) if (-1 == cch) ExitOnFailure(hr = E_INVALIDARG, "failed to get size of destination string"); cch /= sizeof(WCHAR); //convert the count in bytes to count in characters StringCchLengthW(*ppwz, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchLen)); } Assert(cchLen <= cch); if (0 == cchSource) StringCchLengthW(wzSource, STRSAFE_MAX_CCH, reinterpret_cast<UINT_PTR*>(&cchSource)); if (cch - cchLen < cchSource + 1) { cch = (cchSource + cchLen + 1) * 2; hr = StrAlloc(ppwz, cch); ExitOnFailure1(hr, "failed to allocate string from string: %S", wzSource); } if (*ppwz) hr = StringCchCatNExW(*ppwz, cch, wzSource, cchSource, NULL, NULL, STRSAFE_FILL_BEHIND_NULL); else ExitOnFailure(hr = E_UNEXPECTED, "for some reason our buffer is still null"); LExit: return hr; }
/************************************************************************* * StrDuplicateMax */ char *StrDuplicateMax(const char *source, size_t max) { char *target; size_t len; assert(VALID(source)); assert(max > 0); /* Make room for string plus a terminating zero */ len = StrLength(source) + 1; if (len > max) { len = max; } target = StrAlloc(len); if (target) { StrCopyMax(target, len, source); } return target; }
DAPI_(HRESULT) PathCanonicalizePath( __in_z LPCWSTR wzPath, __deref_out_z LPWSTR* psczCanonicalized ) { HRESULT hr = S_OK; int cch = MAX_PATH + 1; hr = StrAlloc(psczCanonicalized, cch); ExitOnFailure(hr, "Failed to allocate string for the canonicalized path."); if (::PathCanonicalizeW(*psczCanonicalized, wzPath)) { hr = S_OK; } else { ExitFunctionWithLastError(hr); } LExit: return hr; }
static String GapPrintWord(const WgData_t *b, long n) { String buffer = StrAlloc(10); WgDescribeWord((WgData_t *)b, n); int *x; StrAppend(&buffer, "["); for (x = b->Description; *x != -1; ) { int first = 1; if (x != b->Description) StrAppend(&buffer, ","); StrAppend(&buffer, "["); do { long gen = *x++; if (!first) StrAppend(&buffer, ","); first = 0; StrAppendF(&buffer,"%d", gen + 1); } while (*x != -1); StrAppend(&buffer, "]"); ++x; } StrAppend(&buffer, "]"); return buffer; }
DAPI_(HRESULT) BalConditionEvaluate( __in BAL_CONDITION* pCondition, __in IBootstrapperEngine* pEngine, __out BOOL* pfResult, __out_z_opt LPWSTR* psczMessage ) { HRESULT hr = S_OK; DWORD_PTR cchMessage = 0; hr = pEngine->EvaluateCondition(pCondition->sczCondition, pfResult); ExitOnFailure(hr, "Failed to evaluate condition with bootstrapper engine."); if (psczMessage) { if (*psczMessage) { hr = StrMaxLength(*psczMessage, &cchMessage); ExitOnFailure(hr, "Failed to get length of message."); } hr = pEngine->FormatString(pCondition->sczMessage, *psczMessage, reinterpret_cast<DWORD*>(&cchMessage)); if (E_MOREDATA == hr) { ++cchMessage; hr = StrAlloc(psczMessage, cchMessage); ExitOnFailure(hr, "Failed to allocate string for condition's formatted message."); hr = pEngine->FormatString(pCondition->sczMessage, *psczMessage, reinterpret_cast<DWORD*>(&cchMessage)); } ExitOnFailure(hr, "Failed to format condition's message."); } LExit: return hr; }
/******************************************************************** ResReadString NOTE: ppwzString should be freed with StrFree() ********************************************************************/ extern "C" HRESULT DAPI ResReadString( __in HINSTANCE hinst, __in UINT uID, __deref_out_z LPWSTR* ppwzString ) { Assert(hinst && ppwzString); HRESULT hr = S_OK; DWORD cch = 64; // first guess DWORD cchReturned = 0; do { hr = StrAlloc(ppwzString, cch); ExitOnFailureDebugTrace1(hr, "Failed to allocate string for resource id: %d", uID); cchReturned = ::LoadStringW(hinst, uID, *ppwzString, cch); if (0 == cchReturned) { ExitWithLastError1(hr, "Failed to load string resource id: %d", uID); } // if the returned string count is one character too small, it's likely we have // more data to read if (cchReturned + 1 == cch) { cch *= 2; hr = S_FALSE; } } while (S_FALSE == hr); ExitOnFailure1(hr, "Failed to load string resource id: %d", uID); LExit: return hr; }
static HRESULT SerializeJsonString( __out_z LPWSTR* psczJsonString, __in_z LPCWSTR wzString ) { HRESULT hr = S_OK; DWORD cchRequired = 3; // start with enough space for null terminated empty quoted string (aka: ""\0) for (LPCWSTR pch = wzString; *pch; ++pch) { // If it is a special JSON character, add space for the escape backslash. if (L'"' == *pch || L'\\' == *pch || L'/' == *pch || L'\b' == *pch || L'\f' == *pch || L'\n' == *pch || L'\r' == *pch || L'\t' == *pch) { ++cchRequired; } ++cchRequired; } hr = StrAlloc(psczJsonString, cchRequired); ExitOnFailure(hr, "Failed to allocate space for JSON string."); LPWSTR pchTarget = *psczJsonString; *pchTarget = L'\"'; ++pchTarget; for (LPCWSTR pch = wzString; *pch; ++pch, ++pchTarget) { // If it is a special JSON character, handle it or just add the character as is. switch (*pch) { case L'"': *pchTarget = L'\\'; ++pchTarget; *pchTarget = L'"'; break; case L'\\': *pchTarget = L'\\'; ++pchTarget; *pchTarget = L'\\'; break; case L'/': *pchTarget = L'\\'; ++pchTarget; *pchTarget = L'/'; break; case L'\b': *pchTarget = L'\\'; ++pchTarget; *pchTarget = L'b'; break; case L'\f': *pchTarget = L'\\'; ++pchTarget; *pchTarget = L'f'; break; case L'\n': *pchTarget = L'\\'; ++pchTarget; *pchTarget = L'n'; break; case L'\r': *pchTarget = L'\\'; ++pchTarget; *pchTarget = L'r'; break; case L'\t': *pchTarget = L'\\'; ++pchTarget; *pchTarget = L't'; break; default: *pchTarget = *pch; break; } } *pchTarget = L'\"'; ++pchTarget; *pchTarget = L'\0'; LExit: return hr; }
static HRESULT SetMessageQueuePermissions( MQI_MESSAGE_QUEUE_PERMISSION_ATTRIBUTES* pAttrs, BOOL fRevoke ) { HRESULT hr = S_OK; DWORD er = ERROR_SUCCESS; DWORD dw = 0; LPWSTR pwzAccount = NULL; LPWSTR pwzFormatName = NULL; PSECURITY_DESCRIPTOR psd = NULL; PACL pAclExisting = NULL; PACL pAclNew = NULL; BOOL fDaclPresent = FALSE; BOOL fDaclDefaulted = FALSE; PSID psid = NULL; EXPLICIT_ACCESSW ea; SECURITY_DESCRIPTOR sdNew; ::ZeroMemory(&ea, sizeof(ea)); ::ZeroMemory(&sdNew, sizeof(sdNew)); // get format name dw = 128; hr = StrAlloc(&pwzFormatName, dw); ExitOnFailure(hr, "Failed to allocate format name string"); do { hr = gpfnMQPathNameToFormatName(pAttrs->pwzPathName, pwzFormatName, &dw); if (MQ_ERROR_FORMATNAME_BUFFER_TOO_SMALL == hr) { hr = StrAlloc(&pwzFormatName, dw); ExitOnFailure(hr, "Failed to reallocate format name string"); hr = S_FALSE; // retry } else { ExitOnFailure(hr, "Failed to get format name"); hr = S_OK; } } while (S_FALSE == hr); // get queue security information dw = 256; psd = (PSECURITY_DESCRIPTOR)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dw); ExitOnNull(psd, hr, E_OUTOFMEMORY, "Failed to allocate buffer for security descriptor"); do { hr = gpfnMQGetQueueSecurity(pwzFormatName, DACL_SECURITY_INFORMATION, psd, dw, &dw); if (MQ_ERROR_SECURITY_DESCRIPTOR_TOO_SMALL == hr) { psd = ::HeapReAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, psd, dw); ExitOnNull(psd, hr, E_OUTOFMEMORY, "Failed to reallocate buffer for security descriptor"); hr = S_FALSE; // retry } else { ExitOnFailure(hr, "Failed to get queue security information"); hr = S_OK; } } while (S_FALSE == hr); // get dacl if (!::GetSecurityDescriptorDacl(psd, &fDaclPresent, &pAclExisting, &fDaclDefaulted)) ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to get DACL for security descriptor"); if (!fDaclPresent || !pAclExisting) ExitOnFailure(hr = E_ACCESSDENIED, "Failed to get DACL for security descriptor, access denied"); // build account name string hr = PcaBuildAccountName(pAttrs->pwzDomain, pAttrs->pwzName, &pwzAccount); ExitOnFailure(hr, "Failed to build account name string"); // get sid for account name hr = PcaAccountNameToSid(pwzAccount, &psid); ExitOnFailure(hr, "Failed to get SID for account name"); // set acl entry SetAccessPermissions(pAttrs->iPermissions, &ea.grfAccessPermissions); ea.grfAccessMode = fRevoke ? REVOKE_ACCESS : SET_ACCESS; ea.grfInheritance = NO_INHERITANCE; ::BuildTrusteeWithSidW(&ea.Trustee, psid); er = ::SetEntriesInAclW(1, &ea, pAclExisting, &pAclNew); ExitOnFailure(hr = HRESULT_FROM_WIN32(er), "Failed to set ACL entry"); // create new security descriptor if (!::InitializeSecurityDescriptor(&sdNew, SECURITY_DESCRIPTOR_REVISION)) ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to initialize security descriptor"); if (!::SetSecurityDescriptorDacl(&sdNew, TRUE, pAclNew, FALSE)) ExitOnFailure(hr = HRESULT_FROM_WIN32(::GetLastError()), "Failed to set DACL for security descriptor"); // set queue security information hr = gpfnMQSetQueueSecurity(pwzFormatName, DACL_SECURITY_INFORMATION, &sdNew); ExitOnFailure(hr, "Failed to set queue security information"); // log WcaLog(LOGMSG_VERBOSE, "Permission set for message queue, key: %S, PathName: '%S'", pAttrs->pwzKey, pAttrs->pwzPathName); hr = S_OK; LExit: // clean up ReleaseStr(pwzFormatName); ReleaseStr(pwzAccount); if (psd) ::HeapFree(::GetProcessHeap(), 0, psd); if (psid) ::HeapFree(::GetProcessHeap(), 0, psid); if (pAclNew) ::LocalFree(pAclNew); return hr; }