1 // Copyright (c) Microsoft. All rights reserved.
2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
6 #include "platformdefines.h"
8 LPWSTR HackyConvertToWSTR(const char* pszInput)
14 if (NULL == pszInput) return NULL;
17 pStr = (char*)pszInput;
19 while('\0' != *pStr) {cchInput++; pStr++;}
20 pwszOutput = new WCHAR[ cchInput + 1];
22 for(size_t i=0; i<=cchInput; i++)
24 pwszOutput[i] = (WCHAR)pszInput[i];
30 LPSTR HackyConvertToSTR(LPWSTR pwszInput)
35 if (NULL == pwszInput) return NULL;
37 cchInput = wcslen(pwszInput);
38 pszOutput = new char[ cchInput + 1];
40 for(size_t i=0; i<=cchInput; i++)
43 pszOutput[i] = (char)pwszInput[i];
49 error_t TP_scpy_s(LPWSTR strDestination, size_t sizeInWords, LPCWSTR strSource)
52 // copy sizeInBytes bytes of strSource into strDestination
54 if (NULL == strDestination || NULL == strSource) return 1;
57 while(cnt < sizeInWords && '\0' != strSource[cnt])
59 strDestination[cnt] = strSource[cnt];
62 strDestination[cnt] = '\0';
67 error_t TP_scat_s(LPWSTR strDestination, size_t sizeInWords, LPCWSTR strSource)
70 // locate the end (ie. '\0') and TP_scpy_s the string
72 if (NULL == strDestination || NULL == strSource) return 1;
74 strEnd = strDestination;
75 while('\0' != *strEnd) strEnd++;
77 return TP_scpy_s(strEnd, sizeInWords - ((strEnd - strDestination) / sizeof(WCHAR)), strSource);
80 size_t TP_slen(LPCWSTR str)
84 if (NULL == str) return 0;
87 while('\0' != *(str+len)) len++;
92 int TP_scmp_s(LPCSTR str1, LPCSTR str2)
94 // < 0 str1 less than str2
95 // 0 str1 identical to str2
96 // > 0 str1 greater than str2
98 if (NULL == str1 && NULL != str2) return -1;
99 if (NULL != str1 && NULL == str2) return 1;
100 if (NULL == str1 && NULL == str2) return 0;
102 while (*str1 == *str2 && '\0' != *str1 && '\0' != *str2)
108 if ('\0' == *str1 && '\0' == *str2) return 0;
110 if ('\0' != *str1) return -1;
111 if ('\0' != *str2) return 1;
113 return (*str1 > *str2) ? 1 : -1;
116 int TP_wcmp_s(LPCWSTR str1, LPCWSTR str2)
118 // < 0 str1 less than str2
119 // 0 str1 identical to str2
120 // > 0 str1 greater than str2
122 if (NULL == str1 && NULL != str2) return -1;
123 if (NULL != str1 && NULL == str2) return 1;
124 if (NULL == str1 && NULL == str2) return 0;
126 while (*str1 == *str2 && '\0' != *str1 && '\0' != *str2)
132 if ('\0' == *str1 && '\0' == *str2) return 0;
134 if ('\0' != *str1) return -1;
135 if ('\0' != *str2) return 1;
137 return (*str1 > *str2) ? 1 : -1;
140 error_t TP_getenv_s(size_t* pReturnValue, LPWSTR buffer, size_t sizeInWords, LPCWSTR varname)
142 if (NULL == pReturnValue || NULL == varname) return 1;
148 if( 0 != _wgetenv_s(&returnValue, buf, 100, varname) || returnValue<=0 )
152 TP_scpy_s(buffer, sizeInWords, (LPWSTR)buf);
155 pRet = getenv( HackyConvertToSTR((LPWSTR)varname) );
156 if (NULL == pRet) return 2;
157 TP_scpy_s(buffer, sizeInWords, HackyConvertToWSTR(pRet));
162 error_t TP_putenv_s(LPTSTR name, LPTSTR value)
164 if (NULL == name || NULL == value) return 1;
167 if( 0 != _putenv_s(name, value))
173 char *assignment = (char*) malloc(sizeof(char) * (strlen(name) + strlen(value) + 1));
174 sprintf(assignment, "%s=%s", name, value);
176 if (0 != putenv(assignment))
183 void TP_ZeroMemory(LPVOID buffer, size_t sizeInBytes)
187 // clear out the memory with 0's
188 if (NULL == buffer) return;
190 bBuf = (BYTE*)buffer;
191 for(size_t i=0; i<sizeInBytes; i++)
197 error_t TP_itow_s(int num, LPWSTR buffer, size_t sizeInCharacters, int radix)
202 // only support radix == 10 and only positive numbers
203 if (10 != radix) return 1;
204 if (0 > num) return 2;
205 if (NULL == buffer) return 3;
206 if (2 > sizeInCharacters) return 4;
208 // take care of the trivial case
216 // get length of final string (dumb implementation)
225 if (len >= sizeInCharacters) return 5;
227 // convert num into a string (backwards)
229 while(0 < num && 0 < len)
232 buffer[len] = (WCHAR)((num % 10) + '0');
239 error_t TP_itoa_s(int num, LPSTR buffer, size_t sizeInCharacters, int radix)
244 // only support radix == 10 and only positive numbers
245 if (10 != radix) return 1;
246 if (0 > num) return 2;
247 if (NULL == buffer) return 3;
248 if (2 > sizeInCharacters) return 4;
250 // take care of the trivial case
258 // get length of final string (dumb implementation)
267 if (len >= sizeInCharacters) return 5;
269 // convert num into a string (backwards)
271 while(0 < num && 0 < len)
274 buffer[len] = (char)((num % 10) + '0');
281 LPWSTR TP_sstr(LPWSTR str, LPWSTR searchStr)
285 LPWSTR searchCurrent;
287 if (NULL == str || NULL == searchStr) return NULL;
289 // return a pointer to where searchStr
293 searchCurrent = searchStr;
294 while('\0' != *current)
296 if (NULL != start && '\0' == *searchCurrent)
301 if (*current == *searchCurrent)
304 if (NULL == start) start = current;
308 searchCurrent = searchStr;
317 DWORD TP_GetFullPathName(LPWSTR fileName, DWORD nBufferLength, LPWSTR lpBuffer)
320 return GetFullPathNameW(fileName, nBufferLength, lpBuffer, NULL);
322 char nativeFullPath[MAX_PATH];
323 (void)realpath(HackyConvertToSTR(fileName), nativeFullPath);
324 LPWSTR fullPathForCLR = HackyConvertToWSTR(nativeFullPath);
325 wcscpy_s(lpBuffer, MAX_PATH, fullPathForCLR);
326 return wcslen(lpBuffer);
329 DWORD TP_CreateThread(THREAD_ID* tThread, LPTHREAD_START_ROUTINE worker, LPVOID lpParameter)
333 *tThread = CreateThread(
348 // This is a major kludge...64 bit posix threads just can't be cast into a DWORD and there just isn't
349 // a great way to get what we're using for the ID. The fact that we're casting this at all is kind of
350 // silly since we're returing the actual thread handle and everything being done to manipulate the thread
351 // is done with that. Anyhow, the only thing done with the dword returned from this method is a printf
352 // which is good since this DWORD really shouldn't be reliably used. Just in case it is though, return
353 // a value that can be traced back to here.
356 return (DWORD)*tThread;
361 void TP_JoinThread(THREAD_ID tThread)
364 WaitForSingleObject(tThread, INFINITE);
366 pthread_join(tThread, NULL);
370 #define INTSAFE_E_ARITHMETIC_OVERFLOW ((HRESULT)0x80070216L) // 0x216 = 534 = ERROR_ARITHMETIC_OVERFLOW
371 #define ULONG_ERROR (0xffffffffUL)
372 #define WIN32_ALLOC_ALIGN (16 - 1)
374 // ULONGLONG -> ULONG conversion
376 HRESULT ULongLongToULong(ULONGLONG ullOperand, ULONG* pulResult)
378 HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
379 *pulResult = ULONG_ERROR;
381 if (ullOperand <= ULONG_MAX)
383 *pulResult = (ULONG)ullOperand;
390 HRESULT ULongAdd(ULONG ulAugend, ULONG ulAddend,ULONG* pulResult)
392 HRESULT hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
393 *pulResult = ULONG_ERROR;
395 if ((ulAugend + ulAddend) >= ulAugend)
397 *pulResult = (ulAugend + ulAddend);
404 HRESULT ULongMult(ULONG ulMultiplicand, ULONG ulMultiplier, ULONG* pulResult)
406 ULONGLONG ull64Result = UInt32x32To64(ulMultiplicand, ulMultiplier);
408 return ULongLongToULong(ull64Result, pulResult);
411 HRESULT CbSysStringSize(ULONG cchSize, BOOL isByteLen, ULONG *result)
416 // +2 for the null terminator
417 // + DWORD_PTR to store the byte length of the string
418 int constant = sizeof(WCHAR) + sizeof(DWORD_PTR) + WIN32_ALLOC_ALIGN;
422 if (SUCCEEDED(ULongAdd(constant, cchSize, result)))
424 *result = *result & ~WIN32_ALLOC_ALIGN;
430 ULONG temp = 0; // should not use in-place addition in ULongAdd
431 if (SUCCEEDED(ULongMult(cchSize, sizeof(WCHAR), &temp)) &
432 SUCCEEDED(ULongAdd(temp, constant, result)))
434 *result = *result & ~WIN32_ALLOC_ALIGN;
438 return INTSAFE_E_ARITHMETIC_OVERFLOW;
441 BSTR TP_SysAllocString(LPWSTR psz)
444 return SysAllocString(psz);
448 return TP_SysAllocStringLen(psz, (DWORD)wcslen(psz));
452 BSTR TP_SysAllocStringLen(LPWSTR psz, size_t len)
456 if (FAILED(CbSysStringSize((ULONG)len, FALSE, &cbTotal)))
459 BSTR bstr = (BSTR)TP_CoTaskMemAlloc(cbTotal);
464 // 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,
465 // we need to ensure that the BSTR length can be found by looking one DWORD before the BSTR pointer.
466 *(DWORD_PTR *)bstr = (DWORD_PTR) 0;
467 bstr = (BSTR) ((char *) bstr + sizeof (DWORD));
469 *(DWORD *)bstr = (DWORD)len * sizeof(OLECHAR);
471 bstr = (BSTR) ((char*) bstr + sizeof(DWORD));
474 memcpy(bstr, psz, len * sizeof(OLECHAR));
477 bstr[len] = '\0'; // always 0 terminate
483 BSTR TP_SysAllocStringByteLen(LPCSTR psz, size_t len)
486 return SysAllocStringByteLen(psz, (UINT)len);
491 if (FAILED(CbSysStringSize(len, TRUE, &cbTotal)))
494 bstr = (BSTR)TP_CoTaskMemAlloc(cbTotal);
498 *(DWORD *)((char *)bstr + sizeof (DWORD)) = (DWORD)len;
500 *(DWORD *)bstr = (DWORD)len;
503 bstr = (WCHAR*) ((char*) bstr + sizeof(DWORD_PTR));
506 memcpy(bstr, psz, len);
509 // NULL-terminate with both a narrow and wide zero.
510 *((char *)bstr + len) = '\0';
511 *(WCHAR *)((char *)bstr + ((len + 1) & ~1)) = 0;
518 void TP_SysFreeString(BSTR bstr)
521 return SysFreeString(bstr);
525 TP_CoTaskMemFree((BYTE *)bstr - sizeof(DWORD_PTR));
529 size_t TP_SysStringByteLen(BSTR bstr)
532 return SysStringByteLen(bstr);
536 int32_t * p32 = (int32_t *) bstr;
537 int32_t * p32_1 = p32 -1;
538 DWORD * d32 = (DWORD *) bstr;
539 DWORD * d32_1 = d32 - 1;
540 //std::cout << p32 << p32_1 << endl;
541 //std::cout << d32 << d32_1 << endl;
542 return (unsigned int)(((DWORD *)bstr)[-1]);