BSTR TP_SysAllocStringByteLen(LPCSTR psz, size_t len) { #ifdef WINDOWS return SysAllocStringByteLen(psz, (UINT)len); #else BSTR bstr; ULONG cbTotal = 0; if (FAILED(CbSysStringSize(len, TRUE, &cbTotal))) return NULL; bstr = (BSTR)TP_CoTaskMemAlloc(cbTotal); if (bstr != NULL) { #if defined(_WIN64) *(DWORD *)((char *)bstr + sizeof (DWORD)) = (DWORD)len; #else *(DWORD *)bstr = (DWORD)len; #endif bstr = (WCHAR*) ((char*) bstr + sizeof(DWORD_PTR)); if (psz != NULL) { memcpy(bstr, psz, len); } // NULL-terminate with both a narrow and wide zero. *((char *)bstr + len) = '\0'; *(WCHAR *)((char *)bstr + ((len + 1) & ~1)) = 0; } return bstr; #endif }
BSTR TP_SysAllocStringLen(LPWSTR psz, size_t len) { ULONG cbTotal = 0; if (FAILED(CbSysStringSize((ULONG)len, FALSE, &cbTotal))) return NULL; BSTR bstr = (BSTR)TP_CoTaskMemAlloc(cbTotal); if(bstr != NULL){ #if defined(_WIN64) // NOTE: There are some apps which peek back 4 bytes to look at the size of the BSTR. So, in case of 64-bit code, // we need to ensure that the BSTR length can be found by looking one DWORD before the BSTR pointer. *(DWORD_PTR *)bstr = (DWORD_PTR) 0; bstr = (BSTR) ((char *) bstr + sizeof (DWORD)); #endif *(DWORD *)bstr = (DWORD)len * sizeof(OLECHAR); bstr = (BSTR) ((char*) bstr + sizeof(DWORD)); if(psz != NULL){ memcpy(bstr, psz, len * sizeof(OLECHAR)); } bstr[len] = '\0'; // always 0 terminate } return bstr; }
/*** *BSTR SysAllocStringLen(char*, unsigned int) *Purpose: * Allocation a bstr of the given length and initialize with * the pasted in string * *Entry: * [optional] * *Exit: * return value = BSTR, NULL if the allocation failed. * ***********************************************************************/ STDAPI_(BSTR) SysAllocStringLen(const OLECHAR *psz, UINT len) { BSTR bstr; DWORD cbTotal = 0; if (FAILED(CbSysStringSize(len, FALSE, &cbTotal))) return NULL; bstr = (OLECHAR *)HeapAlloc(GetProcessHeap(), 0, cbTotal); if(bstr != NULL){ #if defined(_WIN64) // NOTE: There are some apps which peek back 4 bytes to look at the size of the BSTR. So, in case of 64-bit code, // we need to ensure that the BSTR length can be found by looking one DWORD before the BSTR pointer. *(DWORD_PTR *)bstr = (DWORD_PTR) 0; bstr = (BSTR) ((char *) bstr + sizeof (DWORD)); #endif *(DWORD FAR*)bstr = (DWORD)len * sizeof(OLECHAR); bstr = (BSTR) ((char*) bstr + sizeof(DWORD)); if(psz != NULL){ memcpy(bstr, psz, len * sizeof(OLECHAR)); } bstr[len] = '\0'; // always 0 terminate } return bstr; }
SysAllocStringByteLen(const char FAR* psz, unsigned int len) { BSTR bstr; DWORD cbTotal = 0; if (FAILED(CbSysStringSize(len, TRUE, &cbTotal))) return FALSE; bstr = (OLECHAR *)HeapAlloc(GetProcessHeap(), 0, cbTotal); if (bstr != NULL) { #if defined(_WIN64) *(DWORD FAR*)((char *)bstr + sizeof (DWORD)) = (DWORD)len; #else *(DWORD FAR*)bstr = (DWORD)len; #endif bstr = (WCHAR*) ((char*) bstr + sizeof(DWORD_PTR)); if (psz != NULL) { memcpy(bstr, psz, len); } // NULL-terminate with both a narrow and wide zero. *((char *)bstr + len) = '\0'; *(WCHAR *)((char *)bstr + ((len + 1) & ~1)) = 0; } return bstr; }
/*** *BSTR SysAllocStringLen(char*, unsigned int) *Purpose: * Allocation a bstr of the given length and initialize with * the pasted in string * *Entry: * [optional] * *Exit: * return value = BSTR, NULL if the allocation failed. * ***********************************************************************/ STDAPI_(BSTR) SysAllocStringLen(const OLECHAR *psz, UINT len) { BSTR bstr; DWORD cbTotal; _ASSERTE(len <= CCH_BSTRMAX); // assert if way too big a request if (len > CCH_BSTRMAX) return NULL; // fail gracefully in retail w/o overflowing cbTotal = CbSysStringSize(len, FALSE); bstr = (OLECHAR *)HeapAlloc(GetProcessHeap(), 0, cbTotal); if(bstr != NULL){ *(DWORD FAR*)bstr = (DWORD)len * sizeof(OLECHAR); bstr = (BSTR) ((char*) bstr + sizeof(DWORD)); if(psz != NULL){ memcpy(bstr, psz, len * sizeof(OLECHAR)); } bstr[len] = '\0'; // always 0 terminate } return bstr; }
SysAllocStringByteLen(const char FAR* psz, unsigned int len) { BSTR bstr; DWORD cbTotal; _ASSERTE(len <= CB_BSTRMAX); // assert if way too big a request if (len > CB_BSTRMAX) return NULL; // fail gracefully in retail w/o overflowing cbTotal = CbSysStringSize(len, TRUE); bstr = (OLECHAR *)HeapAlloc(GetProcessHeap(), 0, cbTotal); if (bstr != NULL) { *(DWORD FAR*)bstr = (DWORD)len; bstr = (WCHAR*) ((char*) bstr + sizeof(DWORD_PTR)); if (psz != NULL) { memcpy(bstr, psz, len); } // NULL-terminate with both a narrow and wide zero. *((char *)bstr + len) = '\0'; *(WCHAR *)((char *)bstr + ((len + 1) & ~1)) = 0; } return bstr; }