From a92db01617bb28514b11bae450503daf3877f25c Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 16:09:03 +0800 Subject: [PATCH 01/15] Delete unused coreclr\tools\util --- src/coreclr/tools/util/consoleargs.cpp | 969 ------------------------- src/coreclr/tools/util/consoleargs.h | 71 -- src/coreclr/tools/util/list.h | 24 - src/coreclr/tools/util/tree.h | 239 ------ 4 files changed, 1303 deletions(-) delete mode 100644 src/coreclr/tools/util/consoleargs.cpp delete mode 100644 src/coreclr/tools/util/consoleargs.h delete mode 100644 src/coreclr/tools/util/list.h delete mode 100644 src/coreclr/tools/util/tree.h diff --git a/src/coreclr/tools/util/consoleargs.cpp b/src/coreclr/tools/util/consoleargs.cpp deleted file mode 100644 index 02640bbea9e107..00000000000000 --- a/src/coreclr/tools/util/consoleargs.cpp +++ /dev/null @@ -1,969 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#include -#include "consoleargs.h" -#include - -typedef unsigned char byte; - -size_t SafeStrCopy( _In_ LPCWSTR wszSrc, _In_ size_t cchSrc, _Out_ LPWSTR wszDest, _In_ size_t cchDest) -{ - if (cchSrc == (size_t)-1) - cchSrc = wcslen(wszSrc); - - if (cchSrc >= cchDest) { - SetLastError(ERROR_FILENAME_EXCED_RANGE); - return 0; - } - - if (FAILED(StringCchCopyNW( wszDest, cchDest, wszSrc, cchSrc))) { - SetLastError(ERROR_FILENAME_EXCED_RANGE); - return 0; - } - return cchSrc; -} - -size_t SafeStrLower( _In_ LPCWSTR wszSrc, _In_ size_t cchSrc, _Out_ LPWSTR wszDest, _In_ size_t cchDest) -{ - if (cchSrc == (size_t)-1) - cchSrc = wcslen(wszSrc); - - if (cchSrc >= cchDest) { - SetLastError(ERROR_FILENAME_EXCED_RANGE); - return 0; - } - - SafeStrCopy(wszSrc, cchSrc, wszDest, cchDest); - _wcslwr_s((WCHAR*)wszDest, cchDest); - return wcslen(wszDest); -} - -inline int HexValue (WCHAR c) -{ - return (c >= '0' && c <= '9') ? c - '0' : (c & 0xdf) - 'A' + 10; -} - -#ifndef TARGET_UNIX -// Get canonical file path from a user specified path. wszSrcfileName can include relative paths, etc. -// Much of this function was taken from csc.exe. -DWORD GetCanonFilePath(_In_z_ LPCWSTR wszSrcFileName, _Out_z_cap_(cchDestFileName) LPWSTR wszDestFileName, _In_ DWORD cchDestFileName, _In_ bool fPreserveSrcCasing) -{ - DWORD full_len; - WCHAR * full_path = new WCHAR[cchDestFileName]; // an intermediate buffer - WCHAR * temp_path = new WCHAR[cchDestFileName]; // Used if FindFile fails - WCHAR * full_cur; - WCHAR * out_cur; - WCHAR * out_end; - bool hasDrive = false; - - memset(full_path, 0, cchDestFileName * sizeof(WCHAR)); - out_cur = wszDestFileName; - out_end = out_cur + cchDestFileName; - if (wszSrcFileName != wszDestFileName) - *out_cur = L'\0'; - full_cur = full_path; - - // Replace '\\' with single backslashes in paths, because W_GetFullPathName fails to do this on win9x. - size_t i = 0; - size_t j = 0; - size_t length = wcslen(wszSrcFileName); - while (j= cchDestFileName) { - SetLastError(ERROR_FILENAME_EXCED_RANGE); - goto FAIL; - } - } - temp_path[i] = L'\0'; - - full_len = GetFullPathNameW(temp_path, cchDestFileName, full_path, NULL); - if (wszSrcFileName == wszDestFileName) - wszDestFileName[cchDestFileName-1] = L'\0'; - if (full_len == 0) { - goto FAIL; - } else if (full_len >= cchDestFileName) { - SetLastError(ERROR_FILENAME_EXCED_RANGE); - goto FAIL; - } - - // Allow only 1 ':' for drives and no long paths with "\\?\" - if (((full_path[0] >= L'a' && full_path[0] <= L'z') || - (full_path[0] >= L'A' && full_path[0] <= L'Z')) && - full_path[1] == L':') - hasDrive = true; - - // We don't allow colons (except after the drive letter) - // long paths beginning with "\\?\" - // devices beginning with "\\.\" - // or wildcards - // or characters 0-31 - if (wcschr( full_path + (hasDrive ? 2 : 0), W(':')) != NULL || - wcsncmp( full_path, W("\\\\?\\"), 4) == 0 || - wcsncmp( full_path, W("\\\\.\\"), 4) == 0 || - wcspbrk(full_path, W("?*\x1\x2\x3\x4\x5\x6\x7\x8\x9") - W("\xA\xB\xC\xD\xE\xF\x10\x11\x12\x13\x14\x15") - W("\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\0")) != NULL) { - SetLastError(ERROR_INVALID_NAME); - goto FAIL; - } - - - if (hasDrive) { - size_t len = SafeStrLower( full_path, 3, out_cur, out_end - out_cur); - if (len == 0) - goto FAIL; - - full_cur += 3; - out_cur += len; - - } else if (full_path[0] == L'\\' && full_path[1] == L'\\') { - // Must be a UNC pathname, so lower-case the server and share - // since there's no known way to get the 'correct casing' - WCHAR * slash = wcschr(full_path + 2, L'\\'); - // slash should now point to the backslash between the server and share - if (slash == NULL || slash == full_path + 2) { - SetLastError(ERROR_INVALID_NAME); - goto FAIL; - } - - slash = wcschr(slash + 1, L'\\'); - if (slash == NULL) { - slash = full_path + wcslen(full_path); - } else if (slash[-1] == L'\\') { - // An empty share-name? - SetLastError(ERROR_INVALID_NAME); - goto FAIL; - } else - slash++; - // slash should now point to char after the slash after the share name - // or the end of the sharename if there's no trailing slash - - size_t len = SafeStrLower( full_path, slash - full_path, out_cur, out_end - out_cur); - if (len == 0) - goto FAIL; - - full_cur = slash; - out_cur += len; - - } else { - // Not a drive-leter path or a UNC path, so assume it's invalid - SetLastError(ERROR_INVALID_NAME); - goto FAIL; - } - - // We either have a lower-cased drive letter or a UNC name - // with it's trailing slash - // out_cur points to the trailing NULL - // full_cur points to the character after the slash - - // Now iterate over each element of the path and attempt to canonicalize it - // It's possible for this loop to never run - // (for strings like "C:\" or "\\unc\share" or "\\unc\share2\") - while (*full_cur) { - WIN32_FIND_DATAW find_data; - bool hasSlash = true; - WCHAR * slash = wcschr(full_cur, '\\'); - if (slash == NULL) { - // This means we're on the last element of the path - // so work with everything left in the string - hasSlash = false; - slash = full_cur + wcslen(full_cur); - } - - // Check to make sure we have enough room for the next part of the path - if (out_cur + (slash - full_cur) >= out_end) { - SetLastError(ERROR_FILENAME_EXCED_RANGE); - goto FAIL; - } - - // Copy over the next path part into the output buffer - // so we can run FindFile to get the correct casing/long filename - memcpy(out_cur, full_cur, (BYTE*)slash - (BYTE*)full_cur); - out_cur[slash - full_cur] = L'\0'; - HANDLE hFind = FindFirstFileW(wszDestFileName, &find_data); - if (hFind == INVALID_HANDLE_VALUE) { - size_t temp_len; - - // We coundn't find the file, the general causes are the file doesn't exist - // or we don't have access to it. Either way we still try to get a canonical filename - // but preserve the passed in casing for the filename - - if (!hasSlash && fPreserveSrcCasing) { - // This is the last component in the filename, we should preserve the user's input text - // even if we can't find it - out_cur += slash - full_cur; - full_cur = slash; - break; - } - - // This will succeed even if we don't have access to the file - // (And on NT4 if the filename is already in 8.3 form) - temp_len = GetShortPathNameW(wszDestFileName, temp_path, cchDestFileName); - if (temp_len == 0) { - // GetShortPathName failed, we have no other way of figuring out the - // The filename, so just lowercase it so it hashes in a case-insensitive manner - - if (!hasSlash) { - // If it doesn't have a slash, then it must be the last part of the filename, - // so don't lowercase it, preserve whatever casing the user gave - temp_len = SafeStrCopy( full_cur, slash - full_cur, out_cur, out_end - out_cur); - } else { - temp_len = SafeStrLower( full_cur, slash - full_cur, out_cur, out_end - out_cur); - } - if (temp_len == 0) - goto FAIL; - - full_cur = slash; - out_cur += temp_len; - - } else if (temp_len >= cchDestFileName) { - // The short filename is longer than the whole thing? - // This shouldn't ever happen, right? - SetLastError(ERROR_FILENAME_EXCED_RANGE); - goto FAIL; - } else { - // GetShortPathName succeeded with a path that is less than BUFFER_LEN - // find the last slash and copy it. (We don't want to copy previous - // path components that we've already 'resolved') - // However, GetShortPathName doesn't always correct the casing - // so as a safe-guard, lower-case it (unless it's the last filename) - WCHAR * temp_slash = wcsrchr(temp_path, L'\\'); - - temp_slash++; - size_t len = 0; - if (!hasSlash) { - len = SafeStrCopy( temp_slash, -1, out_cur, out_end - out_cur); - } else { - len = SafeStrLower( temp_slash, -1, out_cur, out_end - out_cur); - } - if (len == 0) - goto FAIL; - - full_cur = slash; - out_cur += len; - - } - } else { - // Copy over the properly cased long filename - FindClose(hFind); - size_t name_len = wcslen(find_data.cFileName); - if (out_cur + name_len + (hasSlash ? 1 : 0) >= out_end) { - SetLastError(ERROR_FILENAME_EXCED_RANGE); - goto FAIL; - } - - // out_cur already has the filename with the input casing, so we can just leave it alone - // if this is not a directory name and the caller asked to perserve the casing - if (hasSlash || !fPreserveSrcCasing) { - memcpy(out_cur, find_data.cFileName, name_len * sizeof(WCHAR)); - } - else if (name_len != (slash - full_cur) || _wcsnicmp(find_data.cFileName, full_cur, name_len) != 0) { - // The user asked us to preserve the casing of the filename - // and the filename is different by more than just casing so report - // an error indicating we can't create the file - SetLastError(ERROR_FILE_EXISTS); - goto FAIL; - } - - out_cur += name_len; - full_cur = slash; - } - - if (hasSlash) { - if (out_cur + 1 >= out_end) { - SetLastError(ERROR_FILENAME_EXCED_RANGE); - goto FAIL; - } - full_cur++; - *out_cur++ = L'\\'; - } - *out_cur = '\0'; - } - - return (DWORD)(out_cur - wszDestFileName); - -FAIL: - if (full_path) - { - delete [] full_path; - } - if (temp_path) - { - delete [] temp_path; - } - return 0; -} -#endif // !TARGET_UNIX - -bool FreeString(LPCWSTR szText) -{ - if (szText) - delete [] (const_cast(szText)); - return true; -} - -bool IsWhitespace(WCHAR c) -{ - return c == L' ' || c == L'\t' || c == L'\n' || c == L'\r'; -} - -void ConsoleArgs::CleanUpArgs() -{ - while (m_listArgs) - { - WStrList * next = m_listArgs->next; - if (m_listArgs->arg) - delete [] m_listArgs->arg; - delete m_listArgs; - m_listArgs = next; - } - - if (m_rgArgs) - delete[] m_rgArgs; - - m_rgArgs = NULL; - - if(m_lastErrorMessage) - { - delete[] m_lastErrorMessage; - } -} - -bool ConsoleArgs::GetFullFileName(LPCWSTR szSource, _Out_writes_(cchFilenameBuffer) LPWSTR filenameBuffer, DWORD cchFilenameBuffer, bool fOutputFilename) -{ -#ifdef TARGET_UNIX - WCHAR tempBuffer[MAX_LONGPATH]; - memset(filenameBuffer, 0, cchFilenameBuffer * sizeof(WCHAR)); - if (!PathCanonicalizeW(tempBuffer, szSource) || - StringCchCopyW(filenameBuffer, cchFilenameBuffer, tempBuffer) != S_OK) -#else - if (0 == GetCanonFilePath( szSource, filenameBuffer, cchFilenameBuffer, fOutputFilename)) -#endif - { - if (filenameBuffer[0] == L'\0') - { - // This could easily fail because of an overflow, but that's OK - // we only want what will fit in the output buffer so we can print - // a good error message - StringCchCopyW(filenameBuffer, cchFilenameBuffer - 4, szSource); - // Don't cat on the ..., only stick it in the last 4 characters - // to indicate truncation (if the string is short than this it just won't print) - StringCchCopyW(filenameBuffer + cchFilenameBuffer - 4, 4, W("...")); - } - return false; - } - return true; -} - -// -// Clear previous error message if any and set the new one by copying into m_lastErrorMessage. -// We are responsible for freeing the memory destruction. -// -void ConsoleArgs::SetErrorMessage(_In_ LPCWSTR pwzMessage) -{ - if (m_lastErrorMessage != nullptr) - { - delete[] m_lastErrorMessage; - } - m_errorOccurred = true; - m_lastErrorMessage = new WCHAR[wcslen(pwzMessage) + 1]; - if (m_lastErrorMessage == nullptr) - { - // - // Out of memory allocating error string - // - m_lastErrorMessage = kOutOfMemory; - return; - } - - wcscpy_s((LPWSTR)m_lastErrorMessage, wcslen(pwzMessage) + 1, pwzMessage); -} - -// -// Create a simple leaf tree node with the given text -// -b_tree * ConsoleArgs::MakeLeaf(LPCWSTR text) -{ - b_tree * t = NULL; - size_t name_len = wcslen(text) + 1; - LPWSTR szCopy = new WCHAR[name_len]; - - if (!szCopy) - { - return NULL; - } - - HRESULT hr; - hr = StringCchCopyW (szCopy, name_len, text); - - t = new b_tree(szCopy); - if (!t) - { - delete [] szCopy; - return NULL; - } - return t; -} - -// -// Free the memory allocated by the tree (recursive) -// -void ConsoleArgs::CleanupTree(b_tree *root) -{ - if (root == NULL) - return ; - root->InOrderWalk(FreeString); - delete root; -} - -// -// Search the binary tree and add the given string -// return true if it was added or false if it already -// exists -// -HRESULT ConsoleArgs::TreeAdd(b_tree **root, LPCWSTR add - ) -{ - // Special case - init the tree if it - // doesn't already exist - if (*root == NULL) - { - *root = MakeLeaf(add - ); - return *root == NULL ? E_OUTOFMEMORY : S_OK; - } - - size_t name_len = wcslen(add - ) + 1; - LPWSTR szCopy = new WCHAR[name_len]; - - if (!szCopy) - { - return NULL; - } - - HRESULT hr = StringCchCopyW (szCopy, name_len, add - ); - // otherwise, just let the template do the work - hr = (*root)->Add(szCopy, _wcsicmp); - - if (hr != S_OK) // S_FALSE means it already existed - delete [] szCopy; - - return hr; -} - -// -// Parse the text into a list of argument -// return the total count -// and set 'args' to point to the last list element's 'next' -// This function assumes the text is NULL terminated -// -void ConsoleArgs::TextToArgs(LPCWSTR szText, WStrList ** listReplace) -{ - WStrList **argLast; - const WCHAR *pCur; - size_t iSlash; - int iCount; - - argLast = listReplace; - pCur = szText; - iCount = 0; - - // Guaranteed that all tokens are no bigger than the entire file. - LPWSTR szTemp = new WCHAR[wcslen(szText) + 1]; - if (!szTemp) - { - return ; - } - while (*pCur != '\0') - { - WCHAR *pPut, *pFirst, *pLast; - WCHAR chIllegal; - -LEADINGWHITE: - while (IsWhitespace( *pCur) && *pCur != '\0') - pCur++; - - if (*pCur == '\0') - break; - else if (*pCur == L'#') - { - while ( *pCur != '\0' && *pCur != '\n') - pCur++; // Skip to end of line - goto LEADINGWHITE; - } - - // The treatment of quote marks is a bit different than the standard - // treatment. We only remove quote marks at the very beginning and end of the - // string. We still consider interior quotemarks for space ignoring purposes. - // All the below are considered a single argument: - // "foo bar" -> foo bar - // "foo bar";"baz" -> "foo bar";"baz" - // fo"o ba"r -> fo"o ba"r - // - // Additionally, in order to allow multi-line arguments we allow a ^ at the - // end of a line to specify "invisible space". A character sequence matching - // "\^(\r\n|\r|\n)[ \t]*" will be completely ignored (whether inside a quoted - // string or not). The below transformations occur (and represent a single - // argument): - // "foo ^ - // bar" -> foo bar - // foo;^ - // bar -> foo;bar - // Notes: - // 1. Comments are not recognized in a multi-line argument - // 2. A caret escapes only one new-line followed by an arbitrary number of - // tabs or blanks. - // The following will be parsed as the names suggest, into several different - // arguments: - // /option1 ^ - // val1_1;^ - // val1_2;^ - // val1_3;^ - // - // /option2 - // /opt^ - // ion3 -> /option1 val1_1;val1_2;val1_3; /option2 /option3 - int cQuotes = 0; - pPut = pFirst = szTemp; - chIllegal = 0; - while ((!IsWhitespace( *pCur) || !!(cQuotes & 1)) && *pCur != '\0') - { - switch (*pCur) - { - // All this weird slash stuff follows the standard argument processing routines - case L'\\': - iSlash = 0; - // Copy and advance while counting slashes - while (*pCur == L'\\') - { - *pPut++ = *pCur++; - iSlash++; - } - - // Slashes not followed by a quote character don't matter now - if (*pCur != L'\"') - break; - - // If there's an odd count of slashes, it's escaping the quote - // Otherwise the quote is a quote - if ((iSlash & 1) == 0) - { - ++cQuotes; - } - *pPut++ = *pCur++; - break; - - case L'\"': - ++cQuotes; - *pPut++ = *pCur++; - break; - - case L'^': - // ignore this sequence: \^[\r\n|\r|\n]( \t)* - if (pCur[1] == L'\r' || pCur[1] == L'\n') - { - if (pCur[1] == L'\r' && pCur[2] == L'\n') - pCur += 3; - else - pCur += 2; - - while (*pCur == L' ' || *pCur == L'\t') - ++pCur; - } - else - { - *pPut++ = *pCur++; // Copy the caret and advance - } - break; - - case L'\x01': - case L'\x02': - case L'\x03': - case L'\x04': - case L'\x05': - case L'\x06': - case L'\x07': - case L'\x08': - case L'\x09': - case L'\x0A': - case L'\x0B': - case L'\x0C': - case L'\x0D': - case L'\x0E': - case L'\x0F': - case L'\x10': - case L'\x11': - case L'\x12': - case L'\x13': - case L'\x14': - case L'\x15': - case L'\x16': - case L'\x17': - case L'\x18': - case L'\x19': - case L'\x1A': - case L'\x1B': - case L'\x1C': - case L'\x1D': - case L'\x1E': - case L'\x1F': - case L'|': - // Save the first legal character and skip over them - if (chIllegal == 0) - chIllegal = *pCur; - pCur++; - break; - - default: - *pPut++ = *pCur++; // Copy the char and advance - break; - } - } - - pLast = pPut; - *pPut++ = '\0'; - - // If the string is surrounded by quotes, with no interior quotes, remove them. - if (cQuotes == 2 && *pFirst == L'\"' && *(pLast - 1) == L'\"') - { - ++pFirst; - --pLast; - *pLast = L'\0'; - } - - if (chIllegal != 0) - { - SetErrorMessage(W("Illegal option character.")); - break; - } - - size_t cchLen = pLast - pFirst + 1; - WCHAR * szArgCopy = new WCHAR[cchLen]; - if (!szArgCopy) - { - SetErrorMessage(W("Out of memory.")); - break; - } - if (FAILED(StringCchCopyW(szArgCopy, cchLen, pFirst))) - { - delete[] szArgCopy; - SetErrorMessage(W("Out of memory.")); - break; - } - WStrList * listArgNew = new WStrList( szArgCopy, (*argLast)); - if (!listArgNew) - { - delete[] szArgCopy; - SetErrorMessage(W("Out of memory.")); - break; - } - - *argLast = listArgNew; - argLast = &listArgNew->next; - } - - delete[] szTemp; - -} - -// -// Pass in the command line args, argc and argv -// -// We expand any response files that may be contained in the args and return a new -// set of args, pargc2 and pppargv2 that contain the full flat command line. -// -bool ConsoleArgs::ExpandResponseFiles(_In_ int argc, _In_reads_(argc) const LPCWSTR * argv, int * pargc2, _Outptr_result_buffer_(*pargc2) LPWSTR ** pppargv2) -{ - *pargc2 = 0; - *pppargv2 = NULL; - WStrList **argLast = &m_listArgs; - while (argc > 0) - { - // Make a copy of the original var args so we can just delete[] everything - // once parsing is done: original args and new args from response files - // mixed in amongst the originals. - LPWSTR copyArg = new WCHAR[wcslen(argv[0]) + 1]; - if (!copyArg) - { - SetErrorMessage(W("Out of memory.")); - return false; - } - wcscpy_s(copyArg, wcslen(argv[0]) + 1, argv[0]); - - WStrList * listArgNew = new WStrList(copyArg, (*argLast)); - if (!listArgNew) - { - SetErrorMessage(W("Out of memory.")); - return false; - } - - *argLast = listArgNew; - argLast = &listArgNew->next; - - argc--; - argv++; - } - - // Process Response Files - ProcessResponseArgs(); - if (m_errorOccurred) - return false; - - // Now convert to an argc/argv form for remaining processing. - int newArgc = 0; - for (WStrList * listCurArg = m_listArgs; listCurArg != NULL; listCurArg = listCurArg->next) - { - if (listCurArg->arg) - ++newArgc; - } - - m_rgArgs = new LPWSTR[newArgc]; - if (!m_rgArgs) - { - SetErrorMessage(W("Out of memory.")); - return false; - } - int i = 0; - for (WStrList * listCurArg = m_listArgs; listCurArg != NULL; listCurArg = listCurArg->next) - { - if (listCurArg->arg) - { - LPWSTR newString = new WCHAR[wcslen(listCurArg->arg) + 1]; - wcscpy_s(newString, wcslen(listCurArg->arg) + 1, listCurArg->arg); - m_rgArgs[i++] = newString; - } - } - - *pargc2 = newArgc; - *pppargv2 = m_rgArgs; - return !m_errorOccurred; -} - -// -// Read file to end, converting to unicode -// ppwzTextBuffer is allocated. Caller is responsible for freeing -// -bool ConsoleArgs::ReadTextFile(LPCWSTR pwzFilename, _Outptr_ LPWSTR *ppwzTextBuffer) -{ - bool success = false; - char *bufA = nullptr; - WCHAR *bufW = nullptr; - - HANDLE hFile = CreateFile(pwzFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); - if (hFile == INVALID_HANDLE_VALUE) - { - SetErrorMessage(W("Cannot open response file.")); - goto ErrExit; - } - - { - DWORD size = GetFileSize(hFile, NULL); - bufA = new char[size]; - - if (!bufA) - { - SetErrorMessage(W("Out of memory")); - goto ErrExit; - } - DWORD numRead = 0; - if (!ReadFile(hFile, bufA, size, &numRead, NULL) || numRead != size) - { - SetErrorMessage(W("Failure reading response file.")); - goto ErrExit; - } - - char *postByteOrderMarks = bufA; - - // - // If there are Byte Order Marks, skip them make sure they are ones that don't - // require us to handle the wrong endianness - // - - byte byte0 = (byte)bufA[0]; - byte byte1 = (byte)bufA[1]; - byte byte2 = (byte)bufA[2]; - byte byte3 = (byte)bufA[3]; - - bool alreadyUtf16 = false; - - if (byte0 == 0xEF && byte1 == 0xBB && byte2 == 0xBF) - { - postByteOrderMarks += 3; - size -= 3; - } - else if (byte0 == 0xFF && byte1 == 0xFE) - { - postByteOrderMarks += 2; - size -= 2; - alreadyUtf16 = true; - } - else if (byte0 == 0xFE && byte1 == 0xFF) - { - SetErrorMessage(W("Invalid response file format. Use little endian encoding with Unicode")); - goto ErrExit; - } - else if ((byte0 == 0xFF && byte1 == 0xFE && byte2 == 0x00 && byte3 == 0x00) || - (byte0 == 0x00 && byte1 == 0x00 && byte2 == 0xFE && byte3 == 0xFF)) - { - SetErrorMessage(W("Invalid response file format. Use ANSI, UTF-8, or UTF-16")); - goto ErrExit; - } - - if (alreadyUtf16) - { - // - // File is already formatted as UTF-16; just copy the bytes into the output buffer - // - int requiredSize = size + 2; // space for 2 nullptr bytes - - // Sanity check - requiredSize better be an even number since we're dealing with UTF-16 - if (requiredSize % 2 != 0) - { - SetErrorMessage(W("Response file corrupt. Expected UTF-16 encoding but we had an odd number of bytes")); - goto ErrExit; - } - - requiredSize /= 2; - - bufW = new WCHAR[requiredSize]; - if (!bufW) - { - SetErrorMessage(W("Out of memory")); - goto ErrExit; - } - - memcpy(bufW, postByteOrderMarks, size); - bufW[requiredSize - 1] = L'\0'; - } - else - { - // - // File is formatted as ANSI or UTF-8 and needs converting to UTF-16 - // - int requiredSize = MultiByteToWideChar(CP_UTF8, 0, postByteOrderMarks, size, nullptr, 0); - bufW = new WCHAR[requiredSize + 1]; - if (!bufW) - { - SetErrorMessage(W("Out of memory")); - goto ErrExit; - } - - if (!MultiByteToWideChar(CP_UTF8, 0, postByteOrderMarks, size, bufW, requiredSize)) - { - SetErrorMessage(W("Failure reading response file.")); - goto ErrExit; - } - - bufW[requiredSize] = L'\0'; - } - - *ppwzTextBuffer = bufW; - - success = true; - } - -ErrExit: - if (bufA) - { - delete[] bufA; - } - CloseHandle(hFile); - return success; -} - -/* - * Process Response files on the command line - */ -void ConsoleArgs::ProcessResponseArgs() -{ - HRESULT hr; - b_tree *response_files = NULL; - - WCHAR szFilename[MAX_LONGPATH]; - - for (WStrList * listCurArg = m_listArgs; - listCurArg != NULL && !m_errorOccurred; - listCurArg = listCurArg->next) - { - WCHAR * szArg = listCurArg->arg; - - // Skip everything except Response files - if (szArg == NULL || szArg[0] != '@') - continue; - - if (wcslen(szArg) == 1) - { - SetErrorMessage(W("No response file specified")); - goto CONTINUE; - } - - // Check for duplicates - if (!GetFullFileName(&szArg[1], szFilename, MAX_LONGPATH, false)) - continue; - - - hr = TreeAdd(&response_files, szFilename); - if (hr == E_OUTOFMEMORY) - { - SetErrorMessage(W("Out of memory.")); - goto CONTINUE; - } - else if (hr == S_FALSE) - { - SetErrorMessage(W("Duplicate response file.")); - goto CONTINUE; - } - - { - LPWSTR pwzFileBuffer; - pwzFileBuffer = nullptr; - if (!ReadTextFile(szFilename, &pwzFileBuffer)) - { - goto CONTINUE; - } - - LPWSTR szActualText = nullptr; -#ifdef TARGET_UNIX - szActualText = pwzFileBuffer; -#else - DWORD dwNumChars = ExpandEnvironmentStrings(pwzFileBuffer, NULL, 0); - LPWSTR szExpandedBuffer = new WCHAR[dwNumChars]; - if (szExpandedBuffer != nullptr) - { - DWORD dwRetVal = ExpandEnvironmentStrings(pwzFileBuffer, szExpandedBuffer, dwNumChars); - - if (dwRetVal != 0) - { - szActualText = szExpandedBuffer; - } - else - { - // Expand failed - - } - } -#endif - - TextToArgs(szActualText, &listCurArg->next); - - delete[] pwzFileBuffer; -#ifndef TARGET_UNIX - delete[] szExpandedBuffer; -#endif - } - -CONTINUE: // remove the response file argument, and continue to the next. - listCurArg->arg = NULL; - } - - CleanupTree(response_files); -} - diff --git a/src/coreclr/tools/util/consoleargs.h b/src/coreclr/tools/util/consoleargs.h deleted file mode 100644 index f82291d61e9d31..00000000000000 --- a/src/coreclr/tools/util/consoleargs.h +++ /dev/null @@ -1,71 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#ifndef __CONSOLEARGS_H__ -#define __CONSOLEARGS_H__ - -#include "list.h" -#include "tree.h" -#include - -#include "palclr.h" - -typedef tree b_tree; -typedef list WStrList; - -const LPCWSTR kOutOfMemory = W("Out of memory"); - -class ConsoleArgs -{ -public: - // Place the fully-qualified filename in the given output buffer - bool GetFullFileName(LPCWSTR szSource, _Out_writes_(cbFilenameBuffer) LPWSTR filenameBuffer, DWORD cbFilenameBuffer, bool fOutputFilename); - - ConsoleArgs() : - m_rgArgs(NULL), - m_listArgs(NULL), - m_errorOccurred(false), - m_lastErrorMessage(nullptr) - { - }; - - ~ConsoleArgs() - { - CleanUpArgs(); - }; - - // returns false if there are errors - bool ExpandResponseFiles(_In_ int argc, _In_reads_(argc) const LPCWSTR * argv, int * pargc2, _Outptr_result_buffer_(*pargc2) LPWSTR ** pppargv2); - - // Frees all memory used by the arg list and the argv/argc array - void CleanUpArgs(); - - LPCWSTR ErrorMessage() - { - if (m_errorOccurred) - { - return m_lastErrorMessage; - } - else - { - return nullptr; - } - } - -private: - void SetErrorMessage(_In_ LPCWSTR pwzMessage); - b_tree * MakeLeaf( LPCWSTR szText); - void CleanupTree( b_tree * root); - HRESULT TreeAdd( b_tree ** root, LPCWSTR szAdd); - void TextToArgs( LPCWSTR szText, WStrList ** listReplace); - bool ReadTextFile(LPCWSTR pwzFilename, _Outptr_ LPWSTR *ppwzTextBuffer); - void ProcessResponseArgs(); - - LPWSTR * m_rgArgs; - WStrList * m_listArgs; - - bool m_errorOccurred; - LPCWSTR m_lastErrorMessage; -}; - -#endif // __CONSOLEARGS_H__ diff --git a/src/coreclr/tools/util/list.h b/src/coreclr/tools/util/list.h deleted file mode 100644 index 5065d2017516c3..00000000000000 --- a/src/coreclr/tools/util/list.h +++ /dev/null @@ -1,24 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#ifndef __GENERIC_LIST_H__ -#define __GENERIC_LIST_H__ - -// Simple parameterized linked list -// with some good ctors -template -struct list -{ - _T arg; - list<_T> *next; - - list(_T t, list<_T> *n) - { - arg = t, next = n; - } - list() : arg(), next(NULL) - { - } -}; - -#endif // __GENERIC_LIST_H__ diff --git a/src/coreclr/tools/util/tree.h b/src/coreclr/tools/util/tree.h deleted file mode 100644 index b54569aead2456..00000000000000 --- a/src/coreclr/tools/util/tree.h +++ /dev/null @@ -1,239 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#ifndef __GENERIC_TREE_H__ -#define __GENERIC_TREE_H__ - -#include - -// Partially balanced binary tree -// it does individual rotations on insertion, but does nto allow deletion. -// thus the worst case depth is not (n), but (n/2) -// Generic parameter is the element type -// Find and Add require a method that compares 2 elements -template -struct tree -{ - _E name; - tree<_E> *lChild; - tree<_E> *rChild; - size_t lDepth; - size_t rDepth; - - tree(_E e) - { - name = e; - lChild = rChild = NULL; - lDepth = rDepth = 0; - } - ~tree() - { - Cleanup(); - } - - bool InOrderWalk( bool (WalkFunc)(_E)) - { - if (lChild != NULL && !lChild->InOrderWalk(WalkFunc)) - return false; - if (!WalkFunc(name)) - return false; - if (rChild != NULL) - return rChild->InOrderWalk(WalkFunc); - return true; - } - - /* - * return the depths of the tree from here down (minimum of 1) - */ - size_t MaxDepth() - { - return lDepth > rDepth ? lDepth + 1 : rDepth + 1; - } - - /* - * Search the binary tree for the given string - * return a pointer to it was added or NULL if it - * doesn't exist - */ - _E * Find(_E SearchVal, int (__cdecl CompFunc)(_E, _E)) - { - int cmp = CompFunc(name, SearchVal); - if (cmp < 0) - { - if (lChild == NULL) - return NULL; - else - return lChild->Find(SearchVal, CompFunc); - } - else if (cmp > 0) - { - if (rChild == NULL) - return NULL; - else - return rChild->Find(SearchVal, CompFunc); - } - else - return &name; - } - - /* - * Search the binary tree and add the given string - * return S_OK if it was added or S_FALSE if it already - * exists (or E_OUTOFMEMORY) - */ - HRESULT Add(_E add - , int (__cdecl CompFunc)(_E, _E)) - { - int cmp = CompFunc(name, add - ); -REDO: - if (cmp == 0) - return S_FALSE; - - if (cmp < 0) - { - if (lChild == NULL) - { - lDepth = 1; - lChild = new tree<_E>(add - ); - if (lChild == NULL) - return E_OUTOFMEMORY; - return S_OK; - } - else if (rDepth < lDepth) - { - tree<_E> *temp = new tree<_E>(name); - if (temp == NULL) - return E_OUTOFMEMORY; - temp->rChild = rChild; - temp->rDepth = rDepth; - if (lChild != NULL && - (cmp = CompFunc(lChild->name, add - )) > 0) - { - // push right - temp->lChild = NULL; - temp->lDepth = 0; - name = add - ; - rChild = temp; - rDepth++; - return S_OK; - } - else if (cmp == 0) - { - temp->rChild = NULL; - delete temp; - return S_FALSE; - } - else - { - // Rotate right - temp->lChild = lChild->rChild; - temp->lDepth = lChild->rDepth; - name = lChild->name; - lDepth = lChild->lDepth; - rDepth = temp->MaxDepth(); - rChild = temp; - temp = lChild->lChild; - lChild->lChild = lChild->rChild = NULL; - delete lChild; - lChild = temp; - goto REDO; - } - } - else - { - HRESULT hr = lChild->Add(add - , CompFunc); - lDepth = lChild->MaxDepth(); - return hr; - } - } - else - { - if (rChild == NULL) - { - rDepth = 1; - rChild = new tree<_E>(add - ); - if (rChild == NULL) - return E_OUTOFMEMORY; - return S_OK; - } - else if (lDepth < rDepth) - { - tree<_E> *temp = new tree<_E>(name); - if (temp == NULL) - return E_OUTOFMEMORY; - temp->lChild = lChild; - temp->lDepth = lDepth; - if (rChild != NULL && - (cmp = CompFunc(rChild->name, add - )) < 0) - { - // push left - temp->rChild = NULL; - temp->rDepth = 0; - name = add - ; - lChild = temp; - lDepth++; - return S_OK; - } - else if (cmp == 0) - { - temp->lChild = NULL; - delete temp; - return S_FALSE; - } - else - { - // Rotate left - temp->rChild = rChild->lChild; - temp->rDepth = rChild->lDepth; - name = rChild->name; - rDepth = rChild->rDepth; - lDepth = temp->MaxDepth(); - lChild = temp; - temp = rChild->rChild; - rChild->rChild = rChild->lChild = NULL; - delete rChild; - rChild = temp; - goto REDO; - } - } - else - { - HRESULT hr = rChild->Add(add - , CompFunc); - rDepth = rChild->MaxDepth(); - return hr; - } - } - } - - /* - * Free the memory allocated by the tree (recursive) - */ - void Cleanup() - { - if (lChild != NULL) - { - lChild->Cleanup(); - delete lChild; - lChild = NULL; - } - if (rChild != NULL) - { - rChild->Cleanup(); - delete rChild; - rChild = NULL; - - } - } - -}; - -#endif // __GENERIC_TREE_H__ From 4aaa6ffc279328dd899fd6799c445a44587f64bf Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 16:22:02 +0800 Subject: [PATCH 02/15] Delete palrt/path.cpp --- src/coreclr/pal/inc/rt/palrt.h | 13 -- src/coreclr/palrt/CMakeLists.txt | 1 - src/coreclr/palrt/path.cpp | 323 ------------------------------- 3 files changed, 337 deletions(-) delete mode 100644 src/coreclr/palrt/path.cpp diff --git a/src/coreclr/pal/inc/rt/palrt.h b/src/coreclr/pal/inc/rt/palrt.h index 9a9fe4d4798739..4c089ce6fac723 100644 --- a/src/coreclr/pal/inc/rt/palrt.h +++ b/src/coreclr/pal/inc/rt/palrt.h @@ -639,16 +639,12 @@ typedef unsigned int ALG_ID; // note: diff in NULL handing and calling convetion #define StrChrW (WCHAR*)PAL_wcschr -STDAPI_(LPWSTR) StrRChrW(LPCWSTR lpStart, LPCWSTR lpEnd, WCHAR wMatch); - #define lstrcmpW PAL_wcscmp #define lstrcmpiW _wcsicmp #ifdef UNICODE #define StrChr StrChrW -#define StrRChr StrRChrW - #define lstrcmp lstrcmpW #define lstrcmpi lstrcmpiW #endif @@ -729,15 +725,6 @@ inline errno_t __cdecl _fopen_unsafe(PAL_FILE * *ff, const char *fileName, const } #endif /* __cplusplus */ -STDAPI_(BOOL) PathIsUNCW(LPCWSTR pszPath); -STDAPI_(BOOL) PathCanonicalizeW(LPWSTR lpszDst, LPCWSTR lpszSrc); - -#ifdef UNICODE -#define PathIsUNC PathIsUNCW -#define PathCanonicalize PathCanonicalizeW - -#endif // UNICODE - /******************* misc ***************************************/ #ifdef __cplusplus diff --git a/src/coreclr/palrt/CMakeLists.txt b/src/coreclr/palrt/CMakeLists.txt index 028d8db3f3d4b5..26c7473391f04d 100644 --- a/src/coreclr/palrt/CMakeLists.txt +++ b/src/coreclr/palrt/CMakeLists.txt @@ -5,7 +5,6 @@ set(PALRT_SOURCES comem.cpp guid.cpp memorystream.cpp - path.cpp variant.cpp ) diff --git a/src/coreclr/palrt/path.cpp b/src/coreclr/palrt/path.cpp deleted file mode 100644 index d3981d324cf0bc..00000000000000 --- a/src/coreclr/palrt/path.cpp +++ /dev/null @@ -1,323 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// - -// -// =========================================================================== -// File: path.cpp -// -// Path APIs ported from shlwapi (especially for Fusion) -// =========================================================================== - -#include "common.h" -#include "strsafe.h" - - -#define CH_SLASH W('/') -#define CH_WHACK W('\\') - -// -// Inline function to check for a double-backslash at the -// beginning of a string -// - -static __inline BOOL DBL_BSLASH(LPCWSTR psz) -{ - return (psz[0] == W('\\') && psz[1] == W('\\')); -} - -// -// Inline function to check for a path separator character. -// - -static __inline BOOL IsPathSeparator(WCHAR ch) -{ - return (ch == CH_SLASH || ch == CH_WHACK); -} - -__inline BOOL ChrCmpW_inline(WCHAR w1, WCHAR wMatch) -{ - return(!(w1 == wMatch)); -} - -STDAPI_(LPWSTR) StrRChrW(LPCWSTR lpStart, LPCWSTR lpEnd, WCHAR wMatch) -{ - LPCWSTR lpFound = NULL; - - RIPMSG(lpStart && IS_VALID_STRING_PTRW(lpStart, -1), "StrRChrW: caller passed bad lpStart"); - RIPMSG(!lpEnd || lpEnd <= lpStart + wcslen(lpStart), "StrRChrW: caller passed bad lpEnd"); - // don't need to check for NULL lpStart - - if (!lpEnd) - lpEnd = lpStart + wcslen(lpStart); - - for ( ; lpStart < lpEnd; lpStart++) - { - if (!ChrCmpW_inline(*lpStart, wMatch)) - lpFound = lpStart; - } - return ((LPWSTR)lpFound); -} - - -// check if a path is a root -// -// returns: -// TRUE -// "\" "X:\" "\\" "\\foo" "\\foo\bar" -// -// FALSE for others including "\\foo\bar\" (!) -// -STDAPI_(BOOL) PathIsRootW(LPCWSTR pPath) -{ - RIPMSG(pPath && IS_VALID_STRING_PTR(pPath, -1), "PathIsRoot: caller passed bad pPath"); - - if (!pPath || !*pPath) - { - return FALSE; - } - - if (!lstrcmpiW(pPath + 1, W(":\\"))) - { - return TRUE; // "X:\" case - } - - if (IsPathSeparator(*pPath) && (*(pPath + 1) == 0)) - { - return TRUE; // "/" or "\" case - } - - if (DBL_BSLASH(pPath)) // smells like UNC name - { - LPCWSTR p; - int cBackslashes = 0; - - for (p = pPath + 2; *p; p++) - { - if (*p == W('\\')) - { - // - // return FALSE for "\\server\share\dir" - // so just check if there is more than one slash - // - // "\\server\" without a share name causes - // problems for WNet APIs. we should return - // FALSE for this as well - // - if ((++cBackslashes > 1) || !*(p+1)) - return FALSE; - } - } - // end of string with only 1 more backslash - // must be a bare UNC, which looks like a root dir - return TRUE; - } - return FALSE; -} - -// -// Return a pointer to the end of the next path component in the string. -// ie return a pointer to the next backslash or terminating NULL. -// -LPCWSTR GetPCEnd(LPCWSTR lpszStart) -{ - LPCWSTR lpszEnd; - LPCWSTR lpszSlash; - - lpszEnd = StrChr(lpszStart, CH_WHACK); - lpszSlash = StrChr(lpszStart, CH_SLASH); - if ((lpszSlash && lpszSlash < lpszEnd) || - !lpszEnd) - { - lpszEnd = lpszSlash; - } - if (!lpszEnd) - { - lpszEnd = lpszStart + wcslen(lpszStart); - } - - return lpszEnd; -} - -// -// Given a pointer to the end of a path component, return a pointer to -// its beginning. -// ie return a pointer to the previous backslash (or start of the string). -// -LPCWSTR PCStart(LPCWSTR lpszStart, LPCWSTR lpszEnd) -{ - LPCWSTR lpszBegin = StrRChrW(lpszStart, lpszEnd, CH_WHACK); - LPCWSTR lpszSlash = StrRChrW(lpszStart, lpszEnd, CH_SLASH); - if (lpszSlash > lpszBegin) - { - lpszBegin = lpszSlash; - } - if (!lpszBegin) - { - lpszBegin = lpszStart; - } - return lpszBegin; -} - -// -// Fix up a few special cases so that things roughly make sense. -// -void NearRootFixups(LPWSTR lpszPath, BOOL fUNC) -{ - // Check for empty path. - if (lpszPath[0] == W('\0')) - { - // Fix up. -#ifndef TARGET_UNIX - lpszPath[0] = CH_WHACK; -#else - lpszPath[0] = CH_SLASH; -#endif - lpszPath[1] = W('\0'); - } - // Check for missing slash. - if (lpszPath[1] == W(':') && lpszPath[2] == W('\0')) - { - // Fix up. - lpszPath[2] = W('\\'); - lpszPath[3] = W('\0'); - } - // Check for UNC root. - if (fUNC && lpszPath[0] == W('\\') && lpszPath[1] == W('\0')) - { - // Fix up. - //lpszPath[0] = W('\\'); // already checked in if guard - lpszPath[1] = W('\\'); - lpszPath[2] = W('\0'); - } -} - -/*---------------------------------------------------------- -Purpose: Canonicalize a path. - -Returns: -Cond: -- -*/ -STDAPI_(BOOL) PathCanonicalizeW(LPWSTR lpszDst, LPCWSTR lpszSrc) -{ - LPCWSTR lpchSrc; - LPCWSTR lpchPCEnd; // Pointer to end of path component. - LPWSTR lpchDst; - BOOL fUNC; - int cchPC; - - RIPMSG(lpszDst && IS_VALID_WRITE_BUFFER(lpszDst, WCHAR, MAX_PATH), "PathCanonicalize: caller passed bad lpszDst"); - RIPMSG(lpszSrc && IS_VALID_STRING_PTR(lpszSrc, -1), "PathCanonicalize: caller passed bad lpszSrc"); - RIPMSG(lpszDst != lpszSrc, "PathCanonicalize: caller passed the same buffer for lpszDst and lpszSrc"); - - if (!lpszDst || !lpszSrc) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - *lpszDst = W('\0'); - - fUNC = PathIsUNCW(lpszSrc); // Check for UNCness. - - // Init. - lpchSrc = lpszSrc; - lpchDst = lpszDst; - - while (*lpchSrc) - { - lpchPCEnd = GetPCEnd(lpchSrc); - cchPC = (int) (lpchPCEnd - lpchSrc)+1; - - if (cchPC == 1 && IsPathSeparator(*lpchSrc)) // Check for slashes. - { - // Just copy them. -#ifndef TARGET_UNIX - *lpchDst = CH_WHACK; -#else - *lpchDst = CH_SLASH; -#endif - lpchDst++; - lpchSrc++; - } - else if (cchPC == 2 && *lpchSrc == W('.')) // Check for dots. - { - // Skip it... - // Are we at the end? - if (*(lpchSrc+1) == W('\0')) - { - lpchSrc++; - - // remove the last slash we copied (if we've copied one), but don't make a mal-formed root - if ((lpchDst > lpszDst) && !PathIsRootW(lpszDst)) - lpchDst--; - } - else - { - lpchSrc += 2; - } - } - else if (cchPC == 3 && *lpchSrc == W('.') && *(lpchSrc + 1) == W('.')) // Check for dot dot. - { - // make sure we aren't already at the root - if (!PathIsRootW(lpszDst)) - { - // Go up... Remove the previous path component. - lpchDst = (LPWSTR)PCStart(lpszDst, lpchDst - 1); - } - else - { - // When we can't back up, skip the trailing backslash - // so we don't copy one again. (C:\..\FOO would otherwise - // turn into C:\\FOO). - if (IsPathSeparator(*(lpchSrc + 2))) - { - lpchSrc++; - } - } - - // skip ".." - lpchSrc += 2; - } - else // Everything else - { - // Just copy it. - int cchRemainingBuffer = MAX_PATH - (lpszDst - lpchDst); - StringCchCopyNW(lpchDst, cchRemainingBuffer, lpchSrc, cchPC); - lpchDst += cchPC - 1; - lpchSrc += cchPC - 1; - } - - // Keep everything nice and tidy. - *lpchDst = W('\0'); - } - - // Check for weirdo root directory stuff. - NearRootFixups(lpszDst, fUNC); - - return TRUE; -} - -//--------------------------------------------------------------------------- -// Returns TRUE if the given string is a UNC path. -// -// TRUE -// "\\foo\bar" -// "\\foo" <- careful -// "\\" -// FALSE -// "\foo" -// "foo" -// "c:\foo" -// -// -STDAPI_(BOOL) PathIsUNCW(LPCWSTR pszPath) -{ - RIPMSG(pszPath && IS_VALID_STRING_PTR(pszPath, -1), "PathIsUNC: caller passed bad pszPath"); - - if (pszPath) - { - return DBL_BSLASH(pszPath); - } - return FALSE; -} From 93dc4a76c674b990e8cfefbe9c56e815a3800606 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 16:32:55 +0800 Subject: [PATCH 03/15] Cleanup strsafe.h --- src/coreclr/pal/inc/strsafe.h | 3343 +-------------------------------- 1 file changed, 24 insertions(+), 3319 deletions(-) diff --git a/src/coreclr/pal/inc/strsafe.h b/src/coreclr/pal/inc/strsafe.h index afbb8b0925588f..b69feb73c25129 100644 --- a/src/coreclr/pal/inc/strsafe.h +++ b/src/coreclr/pal/inc/strsafe.h @@ -110,22 +110,6 @@ typedef __w64 unsigned int size_t; #ifdef STRSAFE_INLINE STRSAFEAPI StringCopyWorkerA(char* pszDest, size_t cchDest, const char* pszSrc); STRSAFEAPI StringCopyWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc); -STRSAFEAPI StringCopyExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCopyExWorkerW(WCHAR* pszDest, size_t cchDest, size_t cbDest, const WCHAR* pszSrc, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCopyNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc); -STRSAFEAPI StringCopyNWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, size_t cchSrc); -STRSAFEAPI StringCopyNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCopyNExWorkerW(WCHAR* pszDest, size_t cchDest, size_t cbDest, const WCHAR* pszSrc, size_t cchSrc, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCatWorkerA(char* pszDest, size_t cchDest, const char* pszSrc); -STRSAFEAPI StringCatWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc); -STRSAFEAPI StringCatExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCatExWorkerW(WCHAR* pszDest, size_t cchDest, size_t cbDest, const WCHAR* pszSrc, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCatNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend); -STRSAFEAPI StringCatNWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, size_t cchMaxAppend); -STRSAFEAPI StringCatNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCatNExWorkerW(WCHAR* pszDest, size_t cchDest, size_t cbDest, const WCHAR* pszSrc, size_t cchMaxAppend, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringLengthWorkerA(const char* psz, size_t cchMax, size_t* pcch); -STRSAFEAPI StringLengthWorkerW(const WCHAR* psz, size_t cchMax, size_t* pcch); #endif // STRSAFE_INLINE #ifndef STRSAFE_NO_CCH_FUNCTIONS @@ -235,3342 +219,63 @@ STRSAFEAPI StringCchCopyW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc) #endif // STRSAFE_INLINE #endif // !STRSAFE_NO_CCH_FUNCTIONS -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI StringCchCopyEx(TCHAR pszDest, - size_t cchDest, - LPCTSTR pszSrc, - LPTSTR* ppszDestEnd, - size_t* pcchRemaining, - DWORD dwFlags); - -Routine Description: - - This routine is a safer version of the C built-in function 'strcpy' with - some additional parameters. In addition to functionality provided by - StringCchCopy, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters. - length must be = (_tcslen(pszSrc) + 1) to hold all of - the source including the null terminator - - pszSrc - source string which must be null terminated - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function copied any data, the result will point to the - null termination character - - pcchRemaining - if pcchRemaining is non-null, the function will return the - number of characters left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - this flag is useful for emulating functions like lstrcpy - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any truncated - string returned when the failure is - STRSAFE_E_INSUFFICIENT_BUFFER - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any truncated string - returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all copied and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the copy operation - failed due to insufficient space. When this error occurs, - the destination buffer is modified to contain a truncated - version of the ideal result and is null terminated. This - is useful for situations where truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchCopyExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCchCopyExW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCchCopyEx StringCchCopyExW -#else -#define StringCchCopyEx StringCchCopyExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCopyExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 - cbDest = cchDest * sizeof(char); - - hr = StringCopyExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} - -STRSAFEAPI StringCchCopyExW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(WCHAR) since cchDest < STRSAFE_MAX_CCH and sizeof(WCHAR) is 2 - cbDest = cchDest * sizeof(WCHAR); - - hr = StringCopyExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI StringCchCopyN(LPTSTR pszDest, - size_t cchDest, - LPCTSTR pszSrc, - size_t cchSrc); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncpy'. - The size of the destination buffer (in characters) is a parameter and - this function will not write past the end of this buffer and it will - ALWAYS null terminate the destination buffer (unless it is zero length). - - This routine is meant as a replacement for strncpy, but it does behave - differently. This function will not pad the destination buffer with extra - null termination characters if cchSrc is greater than the length of pszSrc. - - This function returns a hresult, and not a pointer. It returns a S_OK - if the entire string or the first cchSrc characters were copied without - truncation and the resultant destination string was null terminated, otherwise - it will return a failure code. In failure cases as much of pszSrc will be - copied to pszDest as possible, and pszDest will be null terminated. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters. - length must be = (_tcslen(src) + 1) to hold all of the - source including the null terminator - - pszSrc - source string - - cchSrc - maximum number of characters to copy from source string - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL. See StringCchCopyNEx if you require - the handling of NULL values. - -Return Value: - - S_OK - if there was source data and it was all copied and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all hresult failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the copy operation - failed due to insufficient space. When this error occurs, - the destination buffer is modified to contain a truncated - version of the ideal result and is null terminated. This - is useful for situations where truncation is ok - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -STRSAFEAPI StringCchCopyNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc); -STRSAFEAPI StringCchCopyNW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, size_t cchSrc); -#ifdef UNICODE -#define StringCchCopyN StringCchCopyNW -#else -#define StringCchCopyN StringCchCopyNA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCopyNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc) -{ - HRESULT hr; - - if ((cchDest > STRSAFE_MAX_CCH) || - (cchSrc > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyNWorkerA(pszDest, cchDest, pszSrc, cchSrc); - } - - return hr; -} - -STRSAFEAPI StringCchCopyNW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, size_t cchSrc) -{ - HRESULT hr; - - if ((cchDest > STRSAFE_MAX_CCH) || - (cchSrc > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCopyNWorkerW(pszDest, cchDest, pszSrc, cchSrc); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI StringCchCopyNEx(TCHAR pszDest, - size_t cchDest, - LPCTSTR pszSrc, - size_t cchSrc, - LPTSTR* ppszDestEnd, - size_t* pcchRemaining, - DWORD dwFlags); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncpy' with - some additional parameters. In addition to functionality provided by - StringCchCopyN, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination - string including the null terminator. The flags parameter allows - additional controls. - - This routine is meant as a replacement for strncpy, but it does behave - differently. This function will not pad the destination buffer with extra - null termination characters if cchSrc is greater than the length of pszSrc. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters. - length must be = (_tcslen(pszSrc) + 1) to hold all of - the source including the null terminator - - pszSrc - source string - - cchSrc - maximum number of characters to copy from the source - string - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function copied any data, the result will point to the - null termination character - - pcchRemaining - if pcchRemaining is non-null, the function will return the - number of characters left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - this flag is useful for emulating functions like lstrcpy - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any truncated - string returned when the failure is - STRSAFE_E_INSUFFICIENT_BUFFER - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any truncated string - returned when the failure is STRSAFE_E_INSUFFICIENT_BUFFER. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all copied and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the copy operation - failed due to insufficient space. When this error occurs, - the destination buffer is modified to contain a truncated - version of the ideal result and is null terminated. This - is useful for situations where truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchCopyNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCchCopyNExW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, size_t cchSrc, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCchCopyNEx StringCchCopyNExW -#else -#define StringCchCopyNEx StringCchCopyNExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCopyNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if ((cchDest > STRSAFE_MAX_CCH) || - (cchSrc > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 - cbDest = cchDest * sizeof(char); - - hr = StringCopyNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} - -STRSAFEAPI StringCchCopyNExW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, size_t cchSrc, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if ((cchDest > STRSAFE_MAX_CCH) || - (cchSrc > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(WCHAR) since cchDest < STRSAFE_MAX_CCH and sizeof(WCHAR) is 2 - cbDest = cchDest * sizeof(WCHAR); - - hr = StringCopyNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchSrc, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI StringCchCat(LPTSTR pszDest, - size_t cchDest, - LPCTSTR pszSrc); - -Routine Description: - - This routine is a safer version of the C built-in function 'strcat'. - The size of the destination buffer (in characters) is a parameter and this - function will not write past the end of this buffer and it will ALWAYS - null terminate the destination buffer (unless it is zero length). - - This function returns a hresult, and not a pointer. It returns a S_OK - if the string was concatenated without truncation and null terminated, otherwise - it will return a failure code. In failure cases as much of pszSrc will be - appended to pszDest as possible, and pszDest will be null terminated. - -Arguments: - - pszDest - destination string which must be null terminated - - cchDest - size of destination buffer in characters. - length must be = (_tcslen(pszDest) + _tcslen(pszSrc) + 1) - to hold all of the combine string plus the null - terminator - - pszSrc - source string which must be null terminated - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL. See StringCchCatEx if you require - the handling of NULL values. - -Return Value: - - S_OK - if there was source data and it was all concatenated and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error occurs, - the destination buffer is modified to contain a truncated - version of the ideal result and is null terminated. This - is useful for situations where truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchCatA(char* pszDest, size_t cchDest, const char* pszSrc); -STRSAFEAPI StringCchCatW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc); -#ifdef UNICODE -#define StringCchCat StringCchCatW -#else -#define StringCchCat StringCchCatA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCatA(char* pszDest, size_t cchDest, const char* pszSrc) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatWorkerA(pszDest, cchDest, pszSrc); - } - - return hr; -} - -STRSAFEAPI StringCchCatW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatWorkerW(pszDest, cchDest, pszSrc); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI StringCbCat(LPTSTR pszDest, - size_t cbDest, - LPCTSTR pszSrc); - -Routine Description: - - This routine is a safer version of the C built-in function 'strcat'. - The size of the destination buffer (in bytes) is a parameter and this - function will not write past the end of this buffer and it will ALWAYS - null terminate the destination buffer (unless it is zero length). - - This function returns a hresult, and not a pointer. It returns a S_OK - if the string was concatenated without truncation and null terminated, otherwise - it will return a failure code. In failure cases as much of pszSrc will be - appended to pszDest as possible, and pszDest will be null terminated. - -Arguments: - - pszDest - destination string which must be null terminated - - cbDest - size of destination buffer in bytes. - length must be = ((_tcslen(pszDest) + _tcslen(pszSrc) + 1) * sizeof(TCHAR) - to hold all of the combine string plus the null - terminator - - pszSrc - source string which must be null terminated - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL. See StringCbCatEx if you require - the handling of NULL values. - -Return Value: - - S_OK - if there was source data and it was all concatenated and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error occurs, - the destination buffer is modified to contain a truncated - version of the ideal result and is null terminated. This - is useful for situations where truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbCatA(char* pszDest, size_t cbDest, const char* pszSrc); -STRSAFEAPI StringCbCatW(WCHAR* pszDest, size_t cbDest, const WCHAR* pszSrc); -#ifdef UNICODE -#define StringCbCat StringCbCatW -#else -#define StringCbCat StringCbCatA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbCatA(char* pszDest, size_t cbDest, const char* pszSrc) -{ - HRESULT hr; - size_t cchDest; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatWorkerA(pszDest, cchDest, pszSrc); - } - - return hr; -} - -STRSAFEAPI StringCbCatW(WCHAR* pszDest, size_t cbDest, const WCHAR* pszSrc) -{ - HRESULT hr; - size_t cchDest; - - cchDest = cbDest / sizeof(WCHAR); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatWorkerW(pszDest, cchDest, pszSrc); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI StringCchCatEx(LPTSTR pszDest, - size_t cchDest, - LPCTSTR pszSrc, - LPTSTR* ppszDestEnd, - size_t* pcchRemaining, - DWORD dwFlags); - -Routine Description: - - This routine is a safer version of the C built-in function 'strcat' with - some additional parameters. In addition to functionality provided by - StringCchCat, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string which must be null terminated - - cchDest - size of destination buffer in characters - length must be (_tcslen(pszDest) + _tcslen(pszSrc) + 1) - to hold all of the combine string plus the null - terminator. - - pszSrc - source string which must be null terminated - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function appended any data, the result will point to the - null termination character - - pcchRemaining - if pcchRemaining is non-null, the function will return the - number of characters left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - this flag is useful for emulating functions like lstrcat - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any pre-existing - or truncated string - - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any pre-existing or - truncated string - - STRSAFE_NO_TRUNCATION - if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest - will not contain a truncated string, it will remain unchanged. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all concatenated and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error occurs, - the destination buffer is modified to contain a truncated - version of the ideal result and is null terminated. This - is useful for situations where truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchCatExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCchCatExW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCchCatEx StringCchCatExW -#else -#define StringCchCatEx StringCchCatExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCatExA(char* pszDest, size_t cchDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 - cbDest = cchDest * sizeof(char); - - hr = StringCatExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} - -STRSAFEAPI StringCchCatExW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(WCHAR) since cchDest < STRSAFE_MAX_CCH and sizeof(WCHAR) is 2 - cbDest = cchDest * sizeof(WCHAR); - - hr = StringCatExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI StringCbCatEx(LPTSTR pszDest, - size_t cbDest, - LPCTSTR pszSrc, - LPTSTR* ppszDestEnd, - size_t* pcbRemaining, - DWORD dwFlags); - -Routine Description: - - This routine is a safer version of the C built-in function 'strcat' with - some additional parameters. In addition to functionality provided by - StringCbCat, this routine also returns a pointer to the end of the - destination string and the number of bytes left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string which must be null terminated - - cbDest - size of destination buffer in bytes. - length must be ((_tcslen(pszDest) + _tcslen(pszSrc) + 1) * sizeof(TCHAR) - to hold all of the combine string plus the null - terminator. - - pszSrc - source string which must be null terminated - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function appended any data, the result will point to the - null termination character - - pcbRemaining - if pcbRemaining is non-null, the function will return - the number of bytes left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - this flag is useful for emulating functions like lstrcat - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any pre-existing - or truncated string - - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any pre-existing or - truncated string - - STRSAFE_NO_TRUNCATION - if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest - will not contain a truncated string, it will remain unchanged. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if there was source data and it was all concatenated and the - resultant dest string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error occurs, - the destination buffer is modified to contain a truncated - version of the ideal result and is null terminated. This - is useful for situations where truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbCatExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); -STRSAFEAPI StringCbCatExW(WCHAR* pszDest, size_t cbDest, const WCHAR* pszSrc, WCHAR** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCbCatEx StringCbCatExW -#else -#define StringCbCatEx StringCbCatExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbCatExA(char* pszDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatExWorkerA(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 - *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); - } - } - - return hr; -} - -STRSAFEAPI StringCbCatExW(WCHAR* pszDest, size_t cbDest, const WCHAR* pszSrc, WCHAR** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(WCHAR); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatExWorkerW(pszDest, cchDest, cbDest, pszSrc, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(WCHAR) since cchRemaining < STRSAFE_MAX_CCH and sizeof(WCHAR) is 2 - *pcbRemaining = (cchRemaining * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR)); - } - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI StringCchCatN(LPTSTR pszDest, - size_t cchDest, - LPCTSTR pszSrc, - size_t cchMaxAppend); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncat'. - The size of the destination buffer (in characters) is a parameter as well as - the maximum number of characters to append, excluding the null terminator. - This function will not write past the end of the destination buffer and it will - ALWAYS null terminate pszDest (unless it is zero length). - - This function returns a hresult, and not a pointer. It returns a S_OK - if all of pszSrc or the first cchMaxAppend characters were appended to the - destination string and it was null terminated, otherwise it will return a - failure code. In failure cases as much of pszSrc will be appended to pszDest - as possible, and pszDest will be null terminated. - -Arguments: - - pszDest - destination string which must be null terminated - - cchDest - size of destination buffer in characters. - length must be (_tcslen(pszDest) + min(cchMaxAppend, _tcslen(pszSrc)) + 1) - to hold all of the combine string plus the null - terminator. - - pszSrc - source string - - cchMaxAppend - maximum number of characters to append - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL. See StringCchCatNEx if you require - the handling of NULL values. - -Return Value: - - S_OK - if all of pszSrc or the first cchMaxAppend characters were - concatenated to pszDest and the resultant dest string was - null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error occurs, - the destination buffer is modified to contain a truncated - version of the ideal result and is null terminated. This - is useful for situations where truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchCatNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend); -STRSAFEAPI StringCchCatNW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, size_t cchMaxAppend); -#ifdef UNICODE -#define StringCchCatN StringCchCatNW -#else -#define StringCchCatN StringCchCatNA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCatNA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatNWorkerA(pszDest, cchDest, pszSrc, cchMaxAppend); - } - - return hr; -} - -STRSAFEAPI StringCchCatNW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, size_t cchMaxAppend) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringCatNWorkerW(pszDest, cchDest, pszSrc, cchMaxAppend); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI StringCbCatN(LPTSTR pszDest, - size_t cbDest, - LPCTSTR pszSrc, - size_t cbMaxAppend); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncat'. - The size of the destination buffer (in bytes) is a parameter as well as - the maximum number of bytes to append, excluding the null terminator. - This function will not write past the end of the destination buffer and it will - ALWAYS null terminate pszDest (unless it is zero length). - - This function returns a hresult, and not a pointer. It returns a S_OK - if all of pszSrc or the first cbMaxAppend bytes were appended to the - destination string and it was null terminated, otherwise it will return a - failure code. In failure cases as much of pszSrc will be appended to pszDest - as possible, and pszDest will be null terminated. - -Arguments: - - pszDest - destination string which must be null terminated - - cbDest - size of destination buffer in bytes. - length must be ((_tcslen(pszDest) + min(cbMaxAppend / sizeof(TCHAR), _tcslen(pszSrc)) + 1) * sizeof(TCHAR) - to hold all of the combine string plus the null - terminator. - - pszSrc - source string - - cbMaxAppend - maximum number of bytes to append - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL. See StringCbCatNEx if you require - the handling of NULL values. - -Return Value: - - S_OK - if all of pszSrc or the first cbMaxAppend bytes were - concatenated to pszDest and the resultant dest string was - null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error occurs, - the destination buffer is modified to contain a truncated - version of the ideal result and is null terminated. This - is useful for situations where truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbCatNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend); -STRSAFEAPI StringCbCatNW(WCHAR* pszDest, size_t cbDest, const WCHAR* pszSrc, size_t cbMaxAppend); -#ifdef UNICODE -#define StringCbCatN StringCbCatNW -#else -#define StringCbCatN StringCbCatNA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbCatNA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend) -{ - HRESULT hr; - size_t cchDest; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cchMaxAppend; - - cchMaxAppend = cbMaxAppend / sizeof(char); - - hr = StringCatNWorkerA(pszDest, cchDest, pszSrc, cchMaxAppend); - } - - return hr; -} - -STRSAFEAPI StringCbCatNW(WCHAR* pszDest, size_t cbDest, const WCHAR* pszSrc, size_t cbMaxAppend) -{ - HRESULT hr; - size_t cchDest; - - cchDest = cbDest / sizeof(WCHAR); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cchMaxAppend; - - cchMaxAppend = cbMaxAppend / sizeof(WCHAR); - - hr = StringCatNWorkerW(pszDest, cchDest, pszSrc, cchMaxAppend); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI StringCchCatNEx(LPTSTR pszDest, - size_t cchDest, - LPCTSTR pszSrc, - size_t cchMaxAppend, - LPTSTR* ppszDestEnd, - size_t* pcchRemaining, - DWORD dwFlags); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncat', with - some additional parameters. In addition to functionality provided by - StringCchCatN, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string which must be null terminated - - cchDest - size of destination buffer in characters. - length must be (_tcslen(pszDest) + min(cchMaxAppend, _tcslen(pszSrc)) + 1) - to hold all of the combine string plus the null - terminator. - - pszSrc - source string - - cchMaxAppend - maximum number of characters to append - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function appended any data, the result will point to the - null termination character - - pcchRemaining - if pcchRemaining is non-null, the function will return the - number of characters left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")) - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any pre-existing - or truncated string - - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any pre-existing or - truncated string - - STRSAFE_NO_TRUNCATION - if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest - will not contain a truncated string, it will remain unchanged. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if all of pszSrc or the first cchMaxAppend characters were - concatenated to pszDest and the resultant dest string was - null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error occurs, - the destination buffer is modified to contain a truncated - version of the ideal result and is null terminated. This - is useful for situations where truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCchCatNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -STRSAFEAPI StringCchCatNExW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, size_t cchMaxAppend, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCchCatNEx StringCchCatNExW -#else -#define StringCchCatNEx StringCchCatNExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchCatNExA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(char) since cchDest < STRSAFE_MAX_CCH and sizeof(char) is 1 - cbDest = cchDest * sizeof(char); - - hr = StringCatNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} - -STRSAFEAPI StringCchCatNExW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, size_t cchMaxAppend, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr; - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cbDest; - - // safe to multiply cchDest * sizeof(WCHAR) since cchDest < STRSAFE_MAX_CCH and sizeof(WCHAR) is 2 - cbDest = cchDest * sizeof(WCHAR); - - hr = StringCatNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, pcchRemaining, dwFlags); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI StringCbCatNEx(LPTSTR pszDest, - size_t cbDest, - LPCTSTR pszSrc, - size_t cbMaxAppend - LPTSTR* ppszDestEnd, - size_t* pcchRemaining, - DWORD dwFlags); - -Routine Description: - - This routine is a safer version of the C built-in function 'strncat', with - some additional parameters. In addition to functionality provided by - StringCbCatN, this routine also returns a pointer to the end of the - destination string and the number of bytes left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string which must be null terminated - - cbDest - size of destination buffer in bytes. - length must be ((_tcslen(pszDest) + min(cbMaxAppend / sizeof(TCHAR), _tcslen(pszSrc)) + 1) * sizeof(TCHAR) - to hold all of the combine string plus the null - terminator. - - pszSrc - source string - - cbMaxAppend - maximum number of bytes to append - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function appended any data, the result will point to the - null termination character - - pcbRemaining - if pcbRemaining is non-null, the function will return the - number of bytes left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")) - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. This will overwrite any pre-existing - or truncated string - - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. This will overwrite any pre-existing or - truncated string - - STRSAFE_NO_TRUNCATION - if the function returns STRSAFE_E_INSUFFICIENT_BUFFER, pszDest - will not contain a truncated string, it will remain unchanged. - -Notes: - Behavior is undefined if source and destination strings overlap. - - pszDest and pszSrc should not be NULL unless the STRSAFE_IGNORE_NULLS flag - is specified. If STRSAFE_IGNORE_NULLS is passed, both pszDest and pszSrc - may be NULL. An error may still be returned even though NULLS are ignored - due to insufficient space. - -Return Value: - - S_OK - if all of pszSrc or the first cbMaxAppend bytes were - concatenated to pszDest and the resultant dest string was - null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all failure cases - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that the operation - failed due to insufficient space. When this error occurs, - the destination buffer is modified to contain a truncated - version of the ideal result and is null terminated. This - is useful for situations where truncation is ok. - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function - ---*/ - -STRSAFEAPI StringCbCatNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); -STRSAFEAPI StringCbCatNExW(WCHAR* pszDest, size_t cbDest, const WCHAR* pszSrc, size_t cbMaxAppend, WCHAR** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags); -#ifdef UNICODE -#define StringCbCatNEx StringCbCatNExW -#else -#define StringCbCatNEx StringCbCatNExA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbCatNExA(char* pszDest, size_t cbDest, const char* pszSrc, size_t cbMaxAppend, char** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(char); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cchMaxAppend; - - cchMaxAppend = cbMaxAppend / sizeof(char); - - hr = StringCatNExWorkerA(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(char) since cchRemaining < STRSAFE_MAX_CCH and sizeof(char) is 1 - *pcbRemaining = (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)); - } - } - - return hr; -} - -STRSAFEAPI StringCbCatNExW(WCHAR* pszDest, size_t cbDest, const WCHAR* pszSrc, size_t cbMaxAppend, WCHAR** ppszDestEnd, size_t* pcbRemaining, unsigned long dwFlags) -{ - HRESULT hr; - size_t cchDest; - size_t cchRemaining = 0; - - cchDest = cbDest / sizeof(WCHAR); - - if (cchDest > STRSAFE_MAX_CCH) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cchMaxAppend; - - cchMaxAppend = cbMaxAppend / sizeof(WCHAR); - - hr = StringCatNExWorkerW(pszDest, cchDest, cbDest, pszSrc, cchMaxAppend, ppszDestEnd, &cchRemaining, dwFlags); - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (pcbRemaining) - { - // safe to multiply cchRemaining * sizeof(WCHAR) since cchRemaining < STRSAFE_MAX_CCH and sizeof(WCHAR) is 2 - *pcbRemaining = (cchRemaining * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR)); - } - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI StringCchGets(LPTSTR pszDest, - size_t cchDest); - -Routine Description: - - This routine is a safer version of the C built-in function 'gets'. - The size of the destination buffer (in characters) is a parameter and - this function will not write past the end of this buffer and it will - ALWAYS null terminate the destination buffer (unless it is zero length). - - This routine is not a replacement for fgets. That function does not replace - newline characters with a null terminator. - - This function returns a hresult, and not a pointer. It returns a S_OK - if any characters were read from stdin and copied to pszDest and pszDest was - null terminated, otherwise it will return a failure code. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters. - -Notes: - pszDest should not be NULL. See StringCchGetsEx if you require the handling - of NULL values. - - cchDest must be > 1 for this function to succeed. - -Return Value: - - S_OK - data was read from stdin and copied, and the resultant dest - string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all hresult failure cases - - STRSAFE_E_END_OF_FILE - - this return value indicates an error or end-of-file condition, - use feof or ferror to determine which one has occurred. - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that there was insufficient - space in the destination buffer to copy any data - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -#endif // !STRSAFE_NO_CCH_FUNCTIONS - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI StringCbGets(LPTSTR pszDest, - size_t cbDest); - -Routine Description: - - This routine is a safer version of the C built-in function 'gets'. - The size of the destination buffer (in bytes) is a parameter and - this function will not write past the end of this buffer and it will - ALWAYS null terminate the destination buffer (unless it is zero length). - - This routine is not a replacement for fgets. That function does not replace - newline characters with a null terminator. - - This function returns a hresult, and not a pointer. It returns a S_OK - if any characters were read from stdin and copied to pszDest and pszDest was - null terminated, otherwise it will return a failure code. - -Arguments: - - pszDest - destination string - - cbDest - size of destination buffer in bytes. - -Notes: - pszDest should not be NULL. See StringCbGetsEx if you require the handling - of NULL values. - - cbDest must be > sizeof(TCHAR) for this function to succeed. - -Return Value: - - S_OK - data was read from stdin and copied, and the resultant dest - string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all hresult failure cases - - STRSAFE_E_END_OF_FILE - - this return value indicates an error or end-of-file condition, - use feof or ferror to determine which one has occurred. - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that there was insufficient - space in the destination buffer to copy any data - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -#endif // !STRSAFE_NO_CB_FUNCTIONS - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI StringCchGetsEx(LPTSTR pszDest, - size_t cchDest, - LPTSTR* ppszDestEnd, - size_t* pcchRemaining, - DWORD dwFlags); - -Routine Description: - - This routine is a safer version of the C built-in function 'gets' with - some additional parameters. In addition to functionality provided by - StringCchGets, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string - - cchDest - size of destination buffer in characters. - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function copied any data, the result will point to the - null termination character - - pcchRemaining - if pcchRemaining is non-null, the function will return the - number of characters left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. - -Notes: - pszDest should not be NULL unless the STRSAFE_IGNORE_NULLS flag is specified. - If STRSAFE_IGNORE_NULLS is passed and pszDest is NULL, an error may still be - returned even though NULLS are ignored - - cchDest must be > 1 for this function to succeed. - -Return Value: - - S_OK - data was read from stdin and copied, and the resultant dest - string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all hresult failure cases - - STRSAFE_E_END_OF_FILE - - this return value indicates an error or end-of-file condition, - use feof or ferror to determine which one has occurred. - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that there was insufficient - space in the destination buffer to copy any data - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -#endif // !STRSAFE_NO_CCH_FUNCTIONS - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI StringCbGetsEx(LPTSTR pszDest, - size_t cbDest, - LPTSTR* ppszDestEnd, - size_t* pcbRemaining, - DWORD dwFlags); - -Routine Description: - - This routine is a safer version of the C built-in function 'gets' with - some additional parameters. In addition to functionality provided by - StringCbGets, this routine also returns a pointer to the end of the - destination string and the number of characters left in the destination string - including the null terminator. The flags parameter allows additional controls. - -Arguments: - - pszDest - destination string - - cbDest - size of destination buffer in bytes. - - ppszDestEnd - if ppszDestEnd is non-null, the function will return a - pointer to the end of the destination string. If the - function copied any data, the result will point to the - null termination character - - pcbRemaining - if pbRemaining is non-null, the function will return the - number of bytes left in the destination string, - including the null terminator - - dwFlags - controls some details of the string copy: - - STRSAFE_FILL_BEHIND_NULL - if the function succeeds, the low byte of dwFlags will be - used to fill the uninitialize part of destination buffer - behind the null terminator - - STRSAFE_IGNORE_NULLS - treat NULL string pointers like empty strings (TEXT("")). - - STRSAFE_FILL_ON_FAILURE - if the function fails, the low byte of dwFlags will be - used to fill all of the destination buffer, and it will - be null terminated. - - STRSAFE_NO_TRUNCATION / - STRSAFE_NULL_ON_FAILURE - if the function fails, the destination buffer will be set - to the empty string. - -Notes: - pszDest should not be NULL unless the STRSAFE_IGNORE_NULLS flag is specified. - If STRSAFE_IGNORE_NULLS is passed and pszDest is NULL, an error may still be - returned even though NULLS are ignored - - cbDest must be > sizeof(TCHAR) for this function to succeed - -Return Value: - - S_OK - data was read from stdin and copied, and the resultant dest - string was null terminated - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all hresult failure cases - - STRSAFE_E_END_OF_FILE - - this return value indicates an error or end-of-file condition, - use feof or ferror to determine which one has occurred. - - STRSAFE_E_INSUFFICIENT_BUFFER / - HRESULT_CODE(hr) == ERROR_INSUFFICIENT_BUFFER - - this return value is an indication that there was insufficient - space in the destination buffer to copy any data - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -#endif // !STRSAFE_NO_CB_FUNCTIONS - -#ifndef STRSAFE_NO_CCH_FUNCTIONS -/*++ - -STDAPI StringCchLength(LPCTSTR psz, - size_t cchMax, - size_t* pcch); - -Routine Description: - - This routine is a safer version of the C built-in function 'strlen'. - It is used to make sure a string is not larger than a given length, and - it optionally returns the current length in characters not including - the null terminator. - - This function returns a hresult, and not a pointer. It returns a S_OK - if the string is non-null and the length including the null terminator is - less than or equal to cchMax characters. - -Arguments: - - psz - string to check the length of - - cchMax - maximum number of characters including the null terminator - that psz is allowed to contain - - pcch - if the function succeeds and pcch is non-null, the current length - in characters of psz excluding the null terminator will be returned. - This out parameter is equivalent to the return value of strlen(psz) - -Notes: - psz can be null but the function will fail - - cchMax should be greater than zero or the function will fail - -Return Value: - - S_OK - psz is non-null and the length including the null terminator is - less than or equal to cchMax characters - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all hresult failure cases - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -STRSAFEAPI StringCchLengthA(const char* psz, size_t cchMax, size_t* pcch); -STRSAFEAPI StringCchLengthW(const WCHAR* psz, size_t cchMax, size_t* pcch); -#ifdef UNICODE -#define StringCchLength StringCchLengthW -#else -#define StringCchLength StringCchLengthA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCchLengthA(const char* psz, size_t cchMax, size_t* pcch) -{ - HRESULT hr; - - if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringLengthWorkerA(psz, cchMax, pcch); - } - - return hr; -} - -STRSAFEAPI StringCchLengthW(const WCHAR* psz, size_t cchMax, size_t* pcch) -{ - HRESULT hr; - - if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringLengthWorkerW(psz, cchMax, pcch); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CCH_FUNCTIONS - - -#ifndef STRSAFE_NO_CB_FUNCTIONS -/*++ - -STDAPI StringCbLength(LPCTSTR psz, - size_t cbMax, - size_t* pcb); - -Routine Description: - - This routine is a safer version of the C built-in function 'strlen'. - It is used to make sure a string is not larger than a given length, and - it optionally returns the current length in bytes not including - the null terminator. - - This function returns a hresult, and not a pointer. It returns a S_OK - if the string is non-null and the length including the null terminator is - less than or equal to cbMax bytes. - -Arguments: - - psz - string to check the length of - - cbMax - maximum number of bytes including the null terminator - that psz is allowed to contain - - pcb - if the function succeeds and pcb is non-null, the current length - in bytes of psz excluding the null terminator will be returned. - This out parameter is equivalent to the return value of strlen(psz) * sizeof(TCHAR) - -Notes: - psz can be null but the function will fail - - cbMax should be greater than or equal to sizeof(TCHAR) or the function will fail - -Return Value: - - S_OK - psz is non-null and the length including the null terminator is - less than or equal to cbMax bytes - - failure - you can use the macro HRESULT_CODE() to get a win32 error - code for all hresult failure cases - - It is strongly recommended to use the SUCCEEDED() / FAILED() macros to test the - return value of this function. - ---*/ - -STRSAFEAPI StringCbLengthA(const char* psz, size_t cchMax, size_t* pcch); -STRSAFEAPI StringCbLengthW(const WCHAR* psz, size_t cchMax, size_t* pcch); -#ifdef UNICODE -#define StringCbLength StringCbLengthW -#else -#define StringCbLength StringCbLengthA -#endif // !UNICODE - -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCbLengthA(const char* psz, size_t cbMax, size_t* pcb) -{ - HRESULT hr; - size_t cchMax; - size_t cch = 0; - - cchMax = cbMax / sizeof(char); - - if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringLengthWorkerA(psz, cchMax, &cch); - } - - if (SUCCEEDED(hr) && pcb) - { - // safe to multiply cch * sizeof(char) since cch < STRSAFE_MAX_CCH and sizeof(char) is 1 - *pcb = cch * sizeof(char); - } - - return hr; -} - -STRSAFEAPI StringCbLengthW(const WCHAR* psz, size_t cbMax, size_t* pcb) -{ - HRESULT hr; - size_t cchMax; - size_t cch = 0; - - cchMax = cbMax / sizeof(WCHAR); - - if ((psz == NULL) || (cchMax > STRSAFE_MAX_CCH)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = StringLengthWorkerW(psz, cchMax, &cch); - } - - if (SUCCEEDED(hr) && pcb) - { - // safe to multiply cch * sizeof(WCHAR) since cch < STRSAFE_MAX_CCH and sizeof(WCHAR) is 2 - *pcb = cch * sizeof(WCHAR); - } - - return hr; -} -#endif // STRSAFE_INLINE -#endif // !STRSAFE_NO_CB_FUNCTIONS - - -// these are the worker functions that actually do the work -#ifdef STRSAFE_INLINE -STRSAFEAPI StringCopyWorkerA(char* pszDest, size_t cchDest, const char* pszSrc) -{ - HRESULT hr = S_OK; - - if (cchDest == 0) - { - // can not null terminate a zero-byte dest buffer - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - while (cchDest && (*pszSrc != '\0')) - { - *pszDest++ = *pszSrc++; - cchDest--; - } - - if (cchDest == 0) - { - // we are going to truncate pszDest - pszDest--; - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDest= '\0'; - } - - return hr; -} - -STRSAFEAPI StringCopyWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc) -{ - HRESULT hr = S_OK; - - if (cchDest == 0) - { - // can not null terminate a zero-byte dest buffer - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - while (cchDest && (*pszSrc != L'\0')) - { - *pszDest++ = *pszSrc++; - cchDest--; - } - - if (cchDest == 0) - { - // we are going to truncate pszDest - pszDest--; - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDest= L'\0'; - } - - return hr; -} - -STRSAFEAPI StringCopyExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - char* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(char)) || - // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest != 0) || (cbDest != 0)) - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - - if (pszSrc == NULL) - { - pszSrc = ""; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - pszDestEnd = pszDest; - cchRemaining = 0; - - // only fail if there was actually src data to copy - if (*pszSrc != '\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - while (cchRemaining && (*pszSrc != '\0')) - { - *pszDestEnd++= *pszSrc++; - cchRemaining--; - } - - if (cchRemaining > 0) - { - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char))); - } - } - else - { - // we are going to truncate pszDest - pszDestEnd--; - cchRemaining++; - - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDestEnd = '\0'; - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = '\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = '\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringCopyExWorkerW(WCHAR* pszDest, size_t cchDest, size_t cbDest, const WCHAR* pszSrc, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - WCHAR* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(WCHAR)) || - // cbDest == (cchDest * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest != 0) || (cbDest != 0)) - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - - if (pszSrc == NULL) - { - pszSrc = u""; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - pszDestEnd = pszDest; - cchRemaining = 0; - - // only fail if there was actually src data to copy - if (*pszSrc != u'\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - while (cchRemaining && (*pszSrc != u'\0')) - { - *pszDestEnd++= *pszSrc++; - cchRemaining--; - } - - if (cchRemaining > 0) - { - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR))); - } - } - else - { - // we are going to truncate pszDest - pszDestEnd--; - cchRemaining++; - - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDestEnd = u'\0'; - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = L'\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = L'\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringCopyNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchSrc) -{ - HRESULT hr = S_OK; - - if (cchDest == 0) - { - // can not null terminate a zero-byte dest buffer - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - while (cchDest && cchSrc && (*pszSrc != '\0')) - { - *pszDest++= *pszSrc++; - cchDest--; - cchSrc--; - } - - if (cchDest == 0) - { - // we are going to truncate pszDest - pszDest--; - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDest= '\0'; - } - - return hr; -} - -STRSAFEAPI StringCopyNWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, size_t cchSrc) -{ - HRESULT hr = S_OK; - - if (cchDest == 0) - { - // can not null terminate a zero-byte dest buffer - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - while (cchDest && cchSrc && (*pszSrc != L'\0')) - { - *pszDest++= *pszSrc++; - cchDest--; - cchSrc--; - } - - if (cchDest == 0) - { - // we are going to truncate pszDest - pszDest--; - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDest= L'\0'; - } - - return hr; -} - -STRSAFEAPI StringCopyNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - char* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(char)) || - // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest != 0) || (cbDest != 0)) - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - - if (pszSrc == NULL) - { - pszSrc = ""; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - pszDestEnd = pszDest; - cchRemaining = 0; - - // only fail if there was actually src data to copy - if (*pszSrc != '\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - while (cchRemaining && cchSrc && (*pszSrc != '\0')) - { - *pszDestEnd++= *pszSrc++; - cchRemaining--; - cchSrc--; - } - - if (cchRemaining > 0) - { - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char))); - } - } - else - { - // we are going to truncate pszDest - pszDestEnd--; - cchRemaining++; - - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDestEnd = '\0'; - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = '\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = '\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringCopyNExWorkerW(WCHAR* pszDest, size_t cchDest, size_t cbDest, const WCHAR* pszSrc, size_t cchSrc, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - WCHAR* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(WCHAR)) || - // cbDest == (cchDest * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest != 0) || (cbDest != 0)) - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - - if (pszSrc == NULL) - { - pszSrc = u""; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - pszDestEnd = pszDest; - cchRemaining = 0; - - // only fail if there was actually src data to copy - if (*pszSrc != L'\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - while (cchRemaining && cchSrc && (*pszSrc != L'\0')) - { - *pszDestEnd++= *pszSrc++; - cchRemaining--; - cchSrc--; - } - - if (cchRemaining > 0) - { - if (dwFlags & STRSAFE_FILL_BEHIND_NULL) - { - memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR))); - } - } - else - { - // we are going to truncate pszDest - pszDestEnd--; - cchRemaining++; - - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - - *pszDestEnd = L'\0'; - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = L'\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = L'\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringCatWorkerA(char* pszDest, size_t cchDest, const char* pszSrc) -{ - HRESULT hr; - size_t cchDestCurrent; - - hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - hr = StringCopyWorkerA(pszDest + cchDestCurrent, - cchDest - cchDestCurrent, - pszSrc); - } - - return hr; -} - -STRSAFEAPI StringCatWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc) -{ - HRESULT hr; - size_t cchDestCurrent; - - hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - hr = StringCopyWorkerW(pszDest + cchDestCurrent, - cchDest - cchDestCurrent, - pszSrc); - } - - return hr; -} - -STRSAFEAPI StringCatExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - char* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(char)) || - // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cchDestCurrent; - - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest == 0) && (cbDest == 0)) - { - cchDestCurrent = 0; - } - else - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - else - { - hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (pszSrc == NULL) - { - pszSrc = ""; - } - } - else - { - hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - // only fail if there was actually src data to append - if (*pszSrc != '\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass - // those flags through - hr = StringCopyExWorkerA(pszDestEnd, - cchRemaining, - (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)), - pszSrc, - &pszDestEnd, - &cchRemaining, - dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - // STRSAFE_NO_TRUNCATION is taken care of by StringCopyExWorkerA() - - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else - if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = '\0'; - } - } - - if (dwFlags & STRSAFE_NULL_ON_FAILURE) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = '\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringCatExWorkerW(WCHAR* pszDest, size_t cchDest, size_t cbDest, const WCHAR* pszSrc, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) -{ - HRESULT hr = S_OK; - WCHAR* pszDestEnd = pszDest; - size_t cchRemaining = 0; - - // ASSERT(cbDest == (cchDest * sizeof(WCHAR)) || - // cbDest == (cchDest * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - size_t cchDestCurrent; - - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest == 0) && (cbDest == 0)) - { - cchDestCurrent = 0; - } - else - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - else - { - hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (pszSrc == NULL) - { - pszSrc = u""; - } - } - else - { - hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - // only fail if there was actually src data to append - if (*pszSrc != L'\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass - // those flags through - hr = StringCopyExWorkerW(pszDestEnd, - cchRemaining, - (cchRemaining * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR)), - pszSrc, - &pszDestEnd, - &cchRemaining, - dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - // STRSAFE_NO_TRUNCATION is taken care of by StringCopyExWorkerW() - - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = L'\0'; - } - } - - if (dwFlags & STRSAFE_NULL_ON_FAILURE) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = L'\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) - { - *ppszDestEnd = pszDestEnd; - } - - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } - } - - return hr; -} - -STRSAFEAPI StringCatNWorkerA(char* pszDest, size_t cchDest, const char* pszSrc, size_t cchMaxAppend) -{ - HRESULT hr; - size_t cchDestCurrent; - - hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - hr = StringCopyNWorkerA(pszDest + cchDestCurrent, - cchDest - cchDestCurrent, - pszSrc, - cchMaxAppend); - } - - return hr; -} - -STRSAFEAPI StringCatNWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc, size_t cchMaxAppend) -{ - HRESULT hr; - size_t cchDestCurrent; - - hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - hr = StringCopyNWorkerW(pszDest + cchDestCurrent, - cchDest - cchDestCurrent, - pszSrc, - cchMaxAppend); - } - - return hr; -} - -STRSAFEAPI StringCatNExWorkerA(char* pszDest, size_t cchDest, size_t cbDest, const char* pszSrc, size_t cchMaxAppend, char** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +// these are the worker functions that actually do the work +#ifdef STRSAFE_INLINE +STRSAFEAPI StringCopyWorkerA(char* pszDest, size_t cchDest, const char* pszSrc) { HRESULT hr = S_OK; - char* pszDestEnd = pszDest; - size_t cchRemaining = 0; - size_t cchDestCurrent = 0; - // ASSERT(cbDest == (cchDest * sizeof(char)) || - // cbDest == (cchDest * sizeof(char)) + (cbDest % sizeof(char))); - - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) + if (cchDest == 0) { + // can not null terminate a zero-byte dest buffer hr = STRSAFE_E_INVALID_PARAMETER; } else { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest == 0) && (cbDest == 0)) - { - cchDestCurrent = 0; - } - else - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - else - { - hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (pszSrc == NULL) - { - pszSrc = ""; - } - } - else - { - hr = StringLengthWorkerA(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - // only fail if there was actually src data to append - if (*pszSrc != '\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass - // those flags through - hr = StringCopyNExWorkerA(pszDestEnd, - cchRemaining, - (cchRemaining * sizeof(char)) + (cbDest % sizeof(char)), - pszSrc, - cchMaxAppend, - &pszDestEnd, - &cchRemaining, - dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); - } - } - } - - if (FAILED(hr)) - { - if (pszDest) + while (cchDest && (*pszSrc != '\0')) { - // STRSAFE_NO_TRUNCATION is taken care of by StringCopyNExWorkerA() - - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = '\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = '\0'; - } - } + *pszDest++ = *pszSrc++; + cchDest--; } - } - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) + if (cchDest == 0) { - *ppszDestEnd = pszDestEnd; + // we are going to truncate pszDest + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; } - if (pcchRemaining) - { - *pcchRemaining = cchRemaining; - } + *pszDest= '\0'; } return hr; } -STRSAFEAPI StringCatNExWorkerW(WCHAR* pszDest, size_t cchDest, size_t cbDest, const WCHAR* pszSrc, size_t cchMaxAppend, WCHAR** ppszDestEnd, size_t* pcchRemaining, unsigned long dwFlags) +STRSAFEAPI StringCopyWorkerW(WCHAR* pszDest, size_t cchDest, const WCHAR* pszSrc) { HRESULT hr = S_OK; - WCHAR* pszDestEnd = pszDest; - size_t cchRemaining = 0; - size_t cchDestCurrent = 0; - - - // ASSERT(cbDest == (cchDest * sizeof(WCHAR)) || - // cbDest == (cchDest * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR))); - // only accept valid flags - if (dwFlags & (~STRSAFE_VALID_FLAGS)) + if (cchDest == 0) { + // can not null terminate a zero-byte dest buffer hr = STRSAFE_E_INVALID_PARAMETER; } else { - if (dwFlags & STRSAFE_IGNORE_NULLS) - { - if (pszDest == NULL) - { - if ((cchDest == 0) && (cbDest == 0)) - { - cchDestCurrent = 0; - } - else - { - // NULL pszDest and non-zero cchDest/cbDest is invalid - hr = STRSAFE_E_INVALID_PARAMETER; - } - } - else - { - hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (pszSrc == NULL) - { - pszSrc = u""; - } - } - else - { - hr = StringLengthWorkerW(pszDest, cchDest, &cchDestCurrent); - - if (SUCCEEDED(hr)) - { - pszDestEnd = pszDest + cchDestCurrent; - cchRemaining = cchDest - cchDestCurrent; - } - } - - if (SUCCEEDED(hr)) - { - if (cchDest == 0) - { - // only fail if there was actually src data to append - if (*pszSrc != L'\0') - { - if (pszDest == NULL) - { - hr = STRSAFE_E_INVALID_PARAMETER; - } - else - { - hr = STRSAFE_E_INSUFFICIENT_BUFFER; - } - } - } - else - { - // we handle the STRSAFE_FILL_ON_FAILURE and STRSAFE_NULL_ON_FAILURE cases below, so do not pass - // those flags through - hr = StringCopyNExWorkerW(pszDestEnd, - cchRemaining, - (cchRemaining * sizeof(WCHAR)) + (cbDest % sizeof(WCHAR)), - pszSrc, - cchMaxAppend, - &pszDestEnd, - &cchRemaining, - dwFlags & (~(STRSAFE_FILL_ON_FAILURE | STRSAFE_NULL_ON_FAILURE))); - } - } - } - - if (FAILED(hr)) - { - if (pszDest) - { - // STRSAFE_NO_TRUNCATION is taken care of by StringCopyNExWorkerW() - - if (dwFlags & STRSAFE_FILL_ON_FAILURE) - { - memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest); - - if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - } - else if (cchDest > 0) - { - pszDestEnd = pszDest + cchDest - 1; - cchRemaining = 1; - - // null terminate the end of the string - *pszDestEnd = L'\0'; - } - } - - if (dwFlags & (STRSAFE_NULL_ON_FAILURE)) - { - if (cchDest > 0) - { - pszDestEnd = pszDest; - cchRemaining = cchDest; - - // null terminate the beginning of the string - *pszDestEnd = L'\0'; - } - } - } - } - - if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER)) - { - if (ppszDestEnd) + while (cchDest && (*pszSrc != L'\0')) { - *ppszDestEnd = pszDestEnd; + *pszDest++ = *pszSrc++; + cchDest--; } - if (pcchRemaining) + if (cchDest == 0) { - *pcchRemaining = cchRemaining; + // we are going to truncate pszDest + pszDest--; + hr = STRSAFE_E_INSUFFICIENT_BUFFER; } - } - - return hr; -} - -STRSAFEAPI StringLengthWorkerA(const char* psz, size_t cchMax, size_t* pcch) -{ - HRESULT hr = S_OK; - size_t cchMaxPrev = cchMax; - - while (cchMax && (*psz != '\0')) - { - psz++; - cchMax--; - } - - if (cchMax == 0) - { - // the string is longer than cchMax - hr = STRSAFE_E_INVALID_PARAMETER; - } - - if (SUCCEEDED(hr) && pcch) - { - *pcch = cchMaxPrev - cchMax; - } - - return hr; -} - -STRSAFEAPI StringLengthWorkerW(const WCHAR* psz, size_t cchMax, size_t* pcch) -{ - HRESULT hr = S_OK; - size_t cchMaxPrev = cchMax; - - while (cchMax && (*psz != L'\0')) - { - psz++; - cchMax--; - } - - if (cchMax == 0) - { - // the string is longer than cchMax - hr = STRSAFE_E_INVALID_PARAMETER; - } - if (SUCCEEDED(hr) && pcch) - { - *pcch = cchMaxPrev - cchMax; + *pszDest= L'\0'; } return hr; From c65e3ebf1fd70d8e3342b294c5f276b21b47eeaf Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Fri, 23 Sep 2022 16:16:08 +0800 Subject: [PATCH 04/15] Delete nls.h --- src/coreclr/classlibnative/inc/nls.h | 33 ---------------------------- 1 file changed, 33 deletions(-) delete mode 100644 src/coreclr/classlibnative/inc/nls.h diff --git a/src/coreclr/classlibnative/inc/nls.h b/src/coreclr/classlibnative/inc/nls.h deleted file mode 100644 index b453aa843fc330..00000000000000 --- a/src/coreclr/classlibnative/inc/nls.h +++ /dev/null @@ -1,33 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -//////////////////////////////////////////////////////////////////////////// -// -// Module: NLS -// - -// -// Purpose: This module defines the common header information for -// the Globalization classes. -// -// Date: August 12, 1998 -// -//////////////////////////////////////////////////////////////////////////// - - -#ifndef _NLS_H_ -#define _NLS_H_ - - -// -// Constant Declarations. -// - -#define HIGH_SURROGATE_START 0xd800 -#define HIGH_SURROGATE_END 0xdbff -#define LOW_SURROGATE_START 0xdc00 -#define LOW_SURROGATE_END 0xdfff - -#define PRIVATE_USE_BEGIN 0xe000 -#define PRIVATE_USE_END 0xf8ff - -#endif // _NLS_H_ From 02db5b531c035f40782a1a72747d04d98bb28bc7 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 16:52:11 +0800 Subject: [PATCH 05/15] Delete shlwapi.h --- src/coreclr/dlls/mscoree/mscoree.cpp | 2 -- src/coreclr/dlls/mscorpe/ceefilegenwriter.cpp | 1 - src/coreclr/pal/inc/rt/shlwapi.h | 12 ------- src/coreclr/palrt/shlwapip.h | 34 ------------------- src/coreclr/vm/assemblynative.cpp | 1 - src/coreclr/vm/ceemain.cpp | 2 -- src/coreclr/vm/domainassembly.cpp | 2 -- src/coreclr/vm/nativeimage.cpp | 2 -- 8 files changed, 56 deletions(-) delete mode 100644 src/coreclr/pal/inc/rt/shlwapi.h delete mode 100644 src/coreclr/palrt/shlwapip.h diff --git a/src/coreclr/dlls/mscoree/mscoree.cpp b/src/coreclr/dlls/mscoree/mscoree.cpp index c985b88ab30c2e..b09c0d12431f3a 100644 --- a/src/coreclr/dlls/mscoree/mscoree.cpp +++ b/src/coreclr/dlls/mscoree/mscoree.cpp @@ -28,8 +28,6 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error. // Handle lifetime of loaded library. //***************************************************************************** -#include - #ifdef TARGET_WINDOWS extern "C" BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved); #endif // TARGET_WINDOWS diff --git a/src/coreclr/dlls/mscorpe/ceefilegenwriter.cpp b/src/coreclr/dlls/mscorpe/ceefilegenwriter.cpp index 4bf5e32e6cb50c..75f9ac4a4d53e2 100644 --- a/src/coreclr/dlls/mscorpe/ceefilegenwriter.cpp +++ b/src/coreclr/dlls/mscorpe/ceefilegenwriter.cpp @@ -13,7 +13,6 @@ #include "corerror.h" #include -#include // The following block contains a template for the default entry point stubs of a COM+ // IL only program. One can emit these stubs (with some fix-ups) and make diff --git a/src/coreclr/pal/inc/rt/shlwapi.h b/src/coreclr/pal/inc/rt/shlwapi.h deleted file mode 100644 index 029a1732591130..00000000000000 --- a/src/coreclr/pal/inc/rt/shlwapi.h +++ /dev/null @@ -1,12 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// - -// -// =========================================================================== -// File: shlwapi.h -// -// =========================================================================== -// dummy shlwapi.h for PAL - -#include "palrt.h" diff --git a/src/coreclr/palrt/shlwapip.h b/src/coreclr/palrt/shlwapip.h deleted file mode 100644 index 490d73f36a9d95..00000000000000 --- a/src/coreclr/palrt/shlwapip.h +++ /dev/null @@ -1,34 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// - -// -// =========================================================================== -// File: shlwapi.h -// -// Header for ported shlwapi stuff -// =========================================================================== - -#ifndef SHLWAPIP_H_INCLUDED -#define SHLWAPIP_H_INCLUDED - -#define SIZEOF(x) sizeof(x) -#define PRIVATE -#define PUBLIC -#ifndef ASSERT -#define ASSERT _ASSERTE -#endif -#define AssertMsg(f,m) _ASSERTE(f) -#define RIP(f) _ASSERTE(f) -#define RIPMSG(f,m) _ASSERTE(f) - -#define IS_VALID_READ_BUFFER(p, t, n) (p != NULL) -#define IS_VALID_WRITE_BUFFER(p, t, n) (p != NULL) - -#define IS_VALID_READ_PTR(p, t) IS_VALID_READ_BUFFER(p, t, 1) -#define IS_VALID_WRITE_PTR(p, t) IS_VALID_WRITE_BUFFER(p, t, 1) - -#define IS_VALID_STRING_PTR(p, c) (p != NULL) -#define IS_VALID_STRING_PTRW(p, c) (p != NULL) - -#endif // ! SHLWAPIP_H_INCLUDED diff --git a/src/coreclr/vm/assemblynative.cpp b/src/coreclr/vm/assemblynative.cpp index cee26dd75c460b..5636de48aa23b3 100644 --- a/src/coreclr/vm/assemblynative.cpp +++ b/src/coreclr/vm/assemblynative.cpp @@ -15,7 +15,6 @@ #include "common.h" -#include #include #include "assemblynative.hpp" #include "dllimport.h" diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index cb6720645c43ff..99bb42f4223e39 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -174,8 +174,6 @@ #include "stacksampler.h" #endif -#include - #ifdef FEATURE_COMINTEROP #include "runtimecallablewrapper.h" #include "mngstdinterfaces.h" diff --git a/src/coreclr/vm/domainassembly.cpp b/src/coreclr/vm/domainassembly.cpp index 2ae508ca073c5b..9fa4b5dd74e9c7 100644 --- a/src/coreclr/vm/domainassembly.cpp +++ b/src/coreclr/vm/domainassembly.cpp @@ -13,8 +13,6 @@ // Headers // -------------------------------------------------------------------------------- -#include - #include "invokeutil.h" #include "eeconfig.h" #include "dynamicmethod.h" diff --git a/src/coreclr/vm/nativeimage.cpp b/src/coreclr/vm/nativeimage.cpp index c51a0c36349827..1bfd266164bcaf 100644 --- a/src/coreclr/vm/nativeimage.cpp +++ b/src/coreclr/vm/nativeimage.cpp @@ -13,8 +13,6 @@ // Headers // -------------------------------------------------------------------------------- -#include - BOOL AssemblyNameIndexHashTraits::Equals(LPCUTF8 a, LPCUTF8 b) { WRAPPER_NO_CONTRACT; From f95cdc436b25233e5b8fb768747ea42b5bfcca1a Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 16:58:54 +0800 Subject: [PATCH 06/15] Cleanup shlwapi leftovers --- src/coreclr/inc/winwrap.h | 2 -- src/coreclr/pal/inc/rt/palrt.h | 15 --------------- 2 files changed, 17 deletions(-) diff --git a/src/coreclr/inc/winwrap.h b/src/coreclr/inc/winwrap.h index 7152d550288ce1..522ae3150e258e 100644 --- a/src/coreclr/inc/winwrap.h +++ b/src/coreclr/inc/winwrap.h @@ -131,8 +131,6 @@ // winbase.h #define WszFormatMessage FormatMessageW -#define Wszlstrcmp lstrcmpW -#define Wszlstrcmpi lstrcmpiW #define WszCreateMutex CreateMutexW #define WszOpenMutex OpenMutexW #define WszCreateEvent CreateEventW diff --git a/src/coreclr/pal/inc/rt/palrt.h b/src/coreclr/pal/inc/rt/palrt.h index 4c089ce6fac723..ee73da2dc00fc8 100644 --- a/src/coreclr/pal/inc/rt/palrt.h +++ b/src/coreclr/pal/inc/rt/palrt.h @@ -634,21 +634,6 @@ typedef unsigned int ALG_ID; #define CSTR_EQUAL 2 #define CSTR_GREATER_THAN 3 -/******************* shlwapi ************************************/ - -// note: diff in NULL handing and calling convetion -#define StrChrW (WCHAR*)PAL_wcschr - -#define lstrcmpW PAL_wcscmp -#define lstrcmpiW _wcsicmp - -#ifdef UNICODE -#define StrChr StrChrW - -#define lstrcmp lstrcmpW -#define lstrcmpi lstrcmpiW -#endif - #ifdef __cplusplus /* From d0df6402867d8c4c85c9feacc4633a0e2bc3cf53 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 17:10:18 +0800 Subject: [PATCH 07/15] Delete winnls.h --- src/coreclr/inc/utilcode.h | 1 - src/coreclr/pal/inc/rt/winnls.h | 12 ------------ src/coreclr/vm/assembly.cpp | 1 - 3 files changed, 14 deletions(-) delete mode 100644 src/coreclr/pal/inc/rt/winnls.h diff --git a/src/coreclr/inc/utilcode.h b/src/coreclr/inc/utilcode.h index 3858ebb2f4320d..d71efbd4f79c82 100644 --- a/src/coreclr/inc/utilcode.h +++ b/src/coreclr/inc/utilcode.h @@ -25,7 +25,6 @@ #include "clrhost.h" #include "debugmacros.h" #include "corhlprpriv.h" -#include "winnls.h" #include "check.h" #include "safemath.h" #include "new.hpp" diff --git a/src/coreclr/pal/inc/rt/winnls.h b/src/coreclr/pal/inc/rt/winnls.h deleted file mode 100644 index 93775e4509cf12..00000000000000 --- a/src/coreclr/pal/inc/rt/winnls.h +++ /dev/null @@ -1,12 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// - -// -// =========================================================================== -// File: winnls.h -// -// =========================================================================== -// dummy winnls.h for PAL - -#include "palrt.h" diff --git a/src/coreclr/vm/assembly.cpp b/src/coreclr/vm/assembly.cpp index 9bb246a62f49e8..034b815c8f437f 100644 --- a/src/coreclr/vm/assembly.cpp +++ b/src/coreclr/vm/assembly.cpp @@ -31,7 +31,6 @@ #include "appdomainnative.hpp" #include "customattribute.h" -#include "winnls.h" #include "caparser.h" #include "../md/compiler/custattr.h" From 2c24c9bc7c552d53b7c26cfe3ba06a300b6db5b0 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 17:16:47 +0800 Subject: [PATCH 08/15] Delete wincrypt.h --- src/coreclr/inc/holder.h | 1 - src/coreclr/inc/winwrap.h | 1 - src/coreclr/pal/inc/rt/wincrypt.h | 12 ------------ 3 files changed, 14 deletions(-) delete mode 100644 src/coreclr/pal/inc/rt/wincrypt.h diff --git a/src/coreclr/inc/holder.h b/src/coreclr/inc/holder.h index 4aa8a0b8fba4f7..552585ca130dde 100644 --- a/src/coreclr/inc/holder.h +++ b/src/coreclr/inc/holder.h @@ -5,7 +5,6 @@ #ifndef __HOLDER_H_ #define __HOLDER_H_ -#include #include "cor.h" #include "staticcontract.h" #include "volatile.h" diff --git a/src/coreclr/inc/winwrap.h b/src/coreclr/inc/winwrap.h index 522ae3150e258e..43e7a298185409 100644 --- a/src/coreclr/inc/winwrap.h +++ b/src/coreclr/inc/winwrap.h @@ -32,7 +32,6 @@ #include #include -#include #include #include "longfilepathwrappers.h" diff --git a/src/coreclr/pal/inc/rt/wincrypt.h b/src/coreclr/pal/inc/rt/wincrypt.h deleted file mode 100644 index ae1520c30eae52..00000000000000 --- a/src/coreclr/pal/inc/rt/wincrypt.h +++ /dev/null @@ -1,12 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// - -// -// =========================================================================== -// File: wincrypt.h -// -// =========================================================================== -// dummy wincrypt.h for PAL - -#include "palrt.h" From 4990d0344c48abd6fd7b6a83a072e0e1c31e69c1 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 17:33:22 +0800 Subject: [PATCH 09/15] Delete weakreference.h --- src/coreclr/pal/inc/rt/weakreference.h | 85 -------------------------- 1 file changed, 85 deletions(-) delete mode 100644 src/coreclr/pal/inc/rt/weakreference.h diff --git a/src/coreclr/pal/inc/rt/weakreference.h b/src/coreclr/pal/inc/rt/weakreference.h deleted file mode 100644 index d0b88d62e6c156..00000000000000 --- a/src/coreclr/pal/inc/rt/weakreference.h +++ /dev/null @@ -1,85 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// - -// -// =========================================================================== -// File: weakreference.h -// -// =========================================================================== -// simplified weakreference.h for PAL - -#include "rpc.h" -#include "rpcndr.h" - -#include "unknwn.h" - -#ifndef __IInspectable_INTERFACE_DEFINED__ -#define __IInspectable_INTERFACE_DEFINED__ - -typedef struct HSTRING__{ - int unused; -} HSTRING__; - -typedef HSTRING__* HSTRING; - -typedef /* [v1_enum] */ -enum TrustLevel - { - BaseTrust = 0, - PartialTrust = ( BaseTrust + 1 ) , - FullTrust = ( PartialTrust + 1 ) - } TrustLevel; - -// AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90 -const IID IID_IInspectable = { 0xaf86e2e0, 0xb12d, 0x4c6a, { 0x9c, 0x5a, 0xd7, 0xaa, 0x65, 0x10, 0x1e, 0x90} }; - -MIDL_INTERFACE("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90") -IInspectable : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE GetIids( - /* [out] */ ULONG * iidCount, - /* [size_is][size_is][out] */ IID * *iids) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetRuntimeClassName( - /* [out] */ HSTRING * className) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetTrustLevel( - /* [out] */ TrustLevel * trustLevel) = 0; -}; -#endif // __IInspectable_INTERFACE_DEFINED__ - -#ifndef __IWeakReference_INTERFACE_DEFINED__ -#define __IWeakReference_INTERFACE_DEFINED__ - -// 00000037-0000-0000-C000-000000000046 -const IID IID_IWeakReference = { 0x00000037, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }; - -MIDL_INTERFACE("00000037-0000-0000-C000-000000000046") -IWeakReference : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE Resolve( - /* [in] */ REFIID riid, - /* [iid_is][out] */ IInspectable **objectReference) = 0; - -}; - -#endif // __IWeakReference_INTERFACE_DEFINED__ - -#ifndef __IWeakReferenceSource_INTERFACE_DEFINED__ -#define __IWeakReferenceSource_INTERFACE_DEFINED__ - -// 00000038-0000-0000-C000-000000000046 -const IID IID_IWeakReferenceSource = { 0x00000038, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }; - -MIDL_INTERFACE("00000038-0000-0000-C000-000000000046") -IWeakReferenceSource : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE GetWeakReference( - /* [retval][out] */ IWeakReference * *weakReference) = 0; -}; - -#endif // __IWeakReferenceSource_INTERFACE_DEFINED__ From e1117dd528f33eb473d3c256037755b61dd10f1c Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 18:23:36 +0800 Subject: [PATCH 10/15] Delete tchar.h --- src/coreclr/inc/crtwrap.h | 1 - src/coreclr/pal/inc/rt/tchar.h | 4 ---- src/coreclr/tools/superpmi/superpmi-shared/standardpch.h | 1 - 3 files changed, 6 deletions(-) delete mode 100644 src/coreclr/pal/inc/rt/tchar.h diff --git a/src/coreclr/inc/crtwrap.h b/src/coreclr/inc/crtwrap.h index 3a54ccfb803b80..d3ab3a28be7c6b 100644 --- a/src/coreclr/inc/crtwrap.h +++ b/src/coreclr/inc/crtwrap.h @@ -13,7 +13,6 @@ #include #include #include -#include #include "debugmacros.h" #include #include diff --git a/src/coreclr/pal/inc/rt/tchar.h b/src/coreclr/pal/inc/rt/tchar.h deleted file mode 100644 index b23533a2940dd7..00000000000000 --- a/src/coreclr/pal/inc/rt/tchar.h +++ /dev/null @@ -1,4 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#include "palrt.h" diff --git a/src/coreclr/tools/superpmi/superpmi-shared/standardpch.h b/src/coreclr/tools/superpmi/superpmi-shared/standardpch.h index e0e83c41d03ab6..c6e102f1d7d15a 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/standardpch.h +++ b/src/coreclr/tools/superpmi/superpmi-shared/standardpch.h @@ -53,7 +53,6 @@ #include #include #include -#include #include #include #include From 3cd8eec971c6bbca994f4338e004af9a757418cf Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 18:40:30 +0800 Subject: [PATCH 11/15] Add back wincrypt used in assembly.cpp --- src/coreclr/pal/inc/rt/wincrypt.h | 12 ++++++++++++ src/coreclr/vm/assembly.cpp | 1 + 2 files changed, 13 insertions(+) create mode 100644 src/coreclr/pal/inc/rt/wincrypt.h diff --git a/src/coreclr/pal/inc/rt/wincrypt.h b/src/coreclr/pal/inc/rt/wincrypt.h new file mode 100644 index 00000000000000..ae1520c30eae52 --- /dev/null +++ b/src/coreclr/pal/inc/rt/wincrypt.h @@ -0,0 +1,12 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// + +// +// =========================================================================== +// File: wincrypt.h +// +// =========================================================================== +// dummy wincrypt.h for PAL + +#include "palrt.h" diff --git a/src/coreclr/vm/assembly.cpp b/src/coreclr/vm/assembly.cpp index 034b815c8f437f..41f761187593ab 100644 --- a/src/coreclr/vm/assembly.cpp +++ b/src/coreclr/vm/assembly.cpp @@ -23,6 +23,7 @@ #include "comdynamic.h" #include "sha1.h" +#include #include "eeconfig.h" From 14091bfafa8ee077ab76463712000b42f0bdbfe2 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 18:48:58 +0800 Subject: [PATCH 12/15] Delete psapi.h --- src/coreclr/pal/inc/rt/psapi.h | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 src/coreclr/pal/inc/rt/psapi.h diff --git a/src/coreclr/pal/inc/rt/psapi.h b/src/coreclr/pal/inc/rt/psapi.h deleted file mode 100644 index b23533a2940dd7..00000000000000 --- a/src/coreclr/pal/inc/rt/psapi.h +++ /dev/null @@ -1,4 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#include "palrt.h" From 189463c24188d62f40dfacc75411dbe94dd1f064 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 20:05:42 +0800 Subject: [PATCH 13/15] Remove use of shlwapip.h --- src/coreclr/palrt/common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/coreclr/palrt/common.h b/src/coreclr/palrt/common.h index 9946ed67e8d967..1040b7c13cec47 100644 --- a/src/coreclr/palrt/common.h +++ b/src/coreclr/palrt/common.h @@ -13,6 +13,5 @@ #include #include -#include "shlwapip.h" #include #endif // _COMMON_H_ From a3c6c5ebc34990478a536367c50e7d6ecc89f218 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 20:26:39 +0800 Subject: [PATCH 14/15] Revert "Delete weakreference.h" This reverts commit 4990d0344c48abd6fd7b6a83a072e0e1c31e69c1. --- src/coreclr/pal/inc/rt/weakreference.h | 85 ++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 src/coreclr/pal/inc/rt/weakreference.h diff --git a/src/coreclr/pal/inc/rt/weakreference.h b/src/coreclr/pal/inc/rt/weakreference.h new file mode 100644 index 00000000000000..d0b88d62e6c156 --- /dev/null +++ b/src/coreclr/pal/inc/rt/weakreference.h @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// + +// +// =========================================================================== +// File: weakreference.h +// +// =========================================================================== +// simplified weakreference.h for PAL + +#include "rpc.h" +#include "rpcndr.h" + +#include "unknwn.h" + +#ifndef __IInspectable_INTERFACE_DEFINED__ +#define __IInspectable_INTERFACE_DEFINED__ + +typedef struct HSTRING__{ + int unused; +} HSTRING__; + +typedef HSTRING__* HSTRING; + +typedef /* [v1_enum] */ +enum TrustLevel + { + BaseTrust = 0, + PartialTrust = ( BaseTrust + 1 ) , + FullTrust = ( PartialTrust + 1 ) + } TrustLevel; + +// AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90 +const IID IID_IInspectable = { 0xaf86e2e0, 0xb12d, 0x4c6a, { 0x9c, 0x5a, 0xd7, 0xaa, 0x65, 0x10, 0x1e, 0x90} }; + +MIDL_INTERFACE("AF86E2E0-B12D-4c6a-9C5A-D7AA65101E90") +IInspectable : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE GetIids( + /* [out] */ ULONG * iidCount, + /* [size_is][size_is][out] */ IID * *iids) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetRuntimeClassName( + /* [out] */ HSTRING * className) = 0; + + virtual HRESULT STDMETHODCALLTYPE GetTrustLevel( + /* [out] */ TrustLevel * trustLevel) = 0; +}; +#endif // __IInspectable_INTERFACE_DEFINED__ + +#ifndef __IWeakReference_INTERFACE_DEFINED__ +#define __IWeakReference_INTERFACE_DEFINED__ + +// 00000037-0000-0000-C000-000000000046 +const IID IID_IWeakReference = { 0x00000037, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }; + +MIDL_INTERFACE("00000037-0000-0000-C000-000000000046") +IWeakReference : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE Resolve( + /* [in] */ REFIID riid, + /* [iid_is][out] */ IInspectable **objectReference) = 0; + +}; + +#endif // __IWeakReference_INTERFACE_DEFINED__ + +#ifndef __IWeakReferenceSource_INTERFACE_DEFINED__ +#define __IWeakReferenceSource_INTERFACE_DEFINED__ + +// 00000038-0000-0000-C000-000000000046 +const IID IID_IWeakReferenceSource = { 0x00000038, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }; + +MIDL_INTERFACE("00000038-0000-0000-C000-000000000046") +IWeakReferenceSource : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE GetWeakReference( + /* [retval][out] */ IWeakReference * *weakReference) = 0; +}; + +#endif // __IWeakReferenceSource_INTERFACE_DEFINED__ From 90fca42c78b4d1e776aaf125725dd0d4f14d56d9 Mon Sep 17 00:00:00 2001 From: Huo Yaoyuan Date: Mon, 17 Oct 2022 20:36:33 +0800 Subject: [PATCH 15/15] Revert changes in wincrypt.h --- src/coreclr/inc/holder.h | 1 + src/coreclr/inc/winwrap.h | 1 + src/coreclr/vm/assembly.cpp | 1 - 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/coreclr/inc/holder.h b/src/coreclr/inc/holder.h index 552585ca130dde..4aa8a0b8fba4f7 100644 --- a/src/coreclr/inc/holder.h +++ b/src/coreclr/inc/holder.h @@ -5,6 +5,7 @@ #ifndef __HOLDER_H_ #define __HOLDER_H_ +#include #include "cor.h" #include "staticcontract.h" #include "volatile.h" diff --git a/src/coreclr/inc/winwrap.h b/src/coreclr/inc/winwrap.h index 43e7a298185409..522ae3150e258e 100644 --- a/src/coreclr/inc/winwrap.h +++ b/src/coreclr/inc/winwrap.h @@ -32,6 +32,7 @@ #include #include +#include #include #include "longfilepathwrappers.h" diff --git a/src/coreclr/vm/assembly.cpp b/src/coreclr/vm/assembly.cpp index 41f761187593ab..034b815c8f437f 100644 --- a/src/coreclr/vm/assembly.cpp +++ b/src/coreclr/vm/assembly.cpp @@ -23,7 +23,6 @@ #include "comdynamic.h" #include "sha1.h" -#include #include "eeconfig.h"