//+---------------------------------------------------------------------------- // // File: cmutoa.cpp // // Module: CMUTOA.DLL // // Synopsis: This dll is a Unicode to Ansi wrapper that exports AU functions // that have the function header of the W version of a windows API // but internally do all the conversions necessary so that the Ansi // version of the API (A version) can be called. This dll was implemented // so that a Unicode CM could still run on win9x. The idea was borrowed // from F. Avery Bishop's April 1999 MSJ article "Design a Single Unicode // App that Runs on Both Windows 98 and Windows 2000" // // Copyright (c) 1999 Microsoft Corporation // // Author: quintinb Created 04/25/99 // //+---------------------------------------------------------------------------- #include #include #include #include #include #include #include #include "cmutoa.h" #include "cmdebug.h" #include "cm_def.h" #include "cmutil.h" #include "cmras.h" #include "raslink.h" // raslink text constants #define _CMUTOA_MODULE #include "raslink.cpp" // // Globals // DWORD g_dwTlsIndex; // // Function Headers // LRESULT WINAPI SendMessageAU(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); int WINAPI wvsprintfAU(OUT LPWSTR pszwDest, IN LPCWSTR pszwFmt, IN va_list arglist); int WINAPI lstrlenAU(IN LPCWSTR lpString); //+---------------------------------------------------------------------------- // // Function: DllMain // // Synopsis: Main Entry point for the DLL, notice that we use thread local // storage and initialize it here. // // Arguments: HANDLE hDll - instance handle to the dll // DWORD dwReason - reason the function was called // LPVOID lpReserved - // // Returns: BOOL - TRUE on success // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL APIENTRY DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved) { if (dwReason == DLL_PROCESS_ATTACH) { CMTRACE(TEXT("=====================================================")); CMTRACE1(TEXT(" CMUTOA.DLL - LOADING - Process ID is 0x%x "), GetCurrentProcessId()); CMTRACE(TEXT("=====================================================")); g_dwTlsIndex = TlsAlloc(); if (g_dwTlsIndex == TLS_OUT_OF_INDEXES) { return FALSE; } DisableThreadLibraryCalls((HMODULE) hDll); } else if (dwReason == DLL_PROCESS_DETACH) { CMTRACE(TEXT("=====================================================")); CMTRACE1(TEXT(" CMUTOA.DLL - UNLOADING - Process ID is 0x%x "), GetCurrentProcessId()); CMTRACE(TEXT("=====================================================")); // // free the tls index // if (g_dwTlsIndex != TLS_OUT_OF_INDEXES) { TlsFree(g_dwTlsIndex); } } return TRUE; } //+---------------------------------------------------------------------------- // // Function: CharNextAU // // Synopsis: Unicode to Ansi wrapper for the win32 CharNext API. // // Arguments: LPCWSTR lpsz - The string to return the next character of // // Returns: LPWSTR -- the Next character in the string, unless the current // char is a NULL terminator and then the input param // is returned. // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LPWSTR WINAPI CharNextAU(IN LPCWSTR lpsz) { LPWSTR pszReturn = (LPWSTR)lpsz; if (lpsz && (L'\0' != *lpsz)) { pszReturn++; // this is what _wcsinc does } return pszReturn; } //+---------------------------------------------------------------------------- // // Function: CharPrevAU // // Synopsis: Unicode to Ansi wrapper for the win32 CharPrev API. // // Arguments: LPCWSTR lpszStart - start of the string // LPCWSTR lpsz - The current position in the string for which we // want the previous char of // // // Returns: LPWSTR -- the Previous character in the string, unless the current // char is less than or equal to the Start of the string or // a NULL string is passed to the function, then lpszStart // is returned. // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LPWSTR WINAPI CharPrevAU(IN LPCWSTR lpszStart, IN LPCWSTR lpszCurrent) { LPWSTR pszReturn = (LPWSTR)lpszCurrent; if (lpszStart && lpszCurrent && (lpszCurrent > lpszStart)) { pszReturn--; // this is what _wcsdec does } else { CMASSERTMSG(FALSE, TEXT("NULL String passed to CharPrevAU")); pszReturn = (LPWSTR)lpszStart; } return pszReturn; } typedef WINUSERAPI LPSTR (WINAPI *CharLowerOrUpperA)(LPSTR); //+---------------------------------------------------------------------------- // // Function: LowerOrUpperHelper // // Synopsis: Helper function called by either CharLowerAU or CharUpperAU which have // basically the same functionality except for the calling of CharLowerA or // CharUpperA, respectively. // // Arguments: LPWSTR lpsz -- either a pointer to a string to convert to its // lower/upper character version or a single character stored // in the low word of the pointer to find the lowercase/uppercase // character for. // // Returns: LPWSTR -- lower/upper case version of the string passed in (same as lpsz // because it is converted in place) or lower/upper case version // of the character stored in the Low word of lpsz. // // History: quintinb Created 01/03/2000 // //+---------------------------------------------------------------------------- LPWSTR WINAPI LowerOrUpperHelper(IN OUT LPWSTR lpsz, CharLowerOrUpperA pfnLowerOrUpper) { LPWSTR pszwReturn = lpsz; LPSTR pszAnsiTmp = NULL; if (lpsz) { // // CharLower/CharUpper can be used in two ways. There is a Character mode where the Loword of the // pointer passed in actually stores the numeric value of the character to get the lowercase/uppercase // value of. There is also the traditional use, where the whole string is passed in. Thus // we have to detect which mode we are in and handle it accordingly. // if (0 == HIWORD(lpsz)) { // // Character Mode // CHAR szAnsiTmp[2]; WCHAR szwWideTmp[2]; szwWideTmp[0] = (WCHAR)LOWORD(lpsz); szwWideTmp[1] = L'\0'; int iChars = WzToSz(szwWideTmp, szAnsiTmp, 2); if (iChars && (iChars <= 2)) { pfnLowerOrUpper(szAnsiTmp); iChars = SzToWz(szAnsiTmp, szwWideTmp, 2); if (iChars && (iChars <= 2)) { lpsz = (LPWSTR) ((WORD)szwWideTmp[0]); pszwReturn = lpsz; } else { CMASSERTMSG(FALSE, TEXT("LowerOrUpperHelper-- Failed to convert szAnsiTmp back to szwWideTmp.")); } } else { CMASSERTMSG(FALSE, TEXT("LowerOrUpperHelper -- Failed to convert szwWideTmp to szAnsiTmp.")); } } else { // // String Mode // pszAnsiTmp = WzToSzWithAlloc(lpsz); if (!pszAnsiTmp) { goto exit; } pfnLowerOrUpper(pszAnsiTmp); // // Convert back into UNICODE chars in lpsz // int iCharCount = (lstrlenAU(lpsz) + 1); // include NULL int iChars = SzToWz(pszAnsiTmp, lpsz, iCharCount); if (!iChars || (iChars > iCharCount)) { CMASSERTMSG(FALSE, TEXT("LowerOrUpperHelper -- Failed to convert pszAnsiTmp to lpsz.")); goto exit; } } } exit: CmFree(pszAnsiTmp); return pszwReturn; } //+---------------------------------------------------------------------------- // // Function: CharLowerAU // // Synopsis: Unicode to Ansi wrapper for the win32 CharLower API. Notice that // we support both the string input parameter and the single character // input method. // // Arguments: LPWSTR lpsz -- either a pointer to a string to convert to its // lower character version or a single character stored // in the low word of the pointer to find the lowercase // character for. // // Returns: LPWSTR -- lower case version of the string passed in (same as lpsz // because it is converted in place) or lower case version // of the character stored in the Low word of lpsz. // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LPWSTR WINAPI CharLowerAU(IN OUT LPWSTR lpsz) { return LowerOrUpperHelper(lpsz, CharLowerA); } //+---------------------------------------------------------------------------- // // Function: CharUpperAU // // Synopsis: Unicode to Ansi wrapper for the win32 CharUpper API. Notice that // we support both the string input parameter and the single character // input method. // // Arguments: LPWSTR lpsz -- either a pointer to a string to convert to its // upper character version or a single character stored // in the low word of the pointer to find the uppercase // character for. // // Returns: LPWSTR -- upper case version of the string passed in (same as lpsz // because it is converted in place) or upper case version // of the character stored in the Low word of lpsz. // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LPWSTR WINAPI CharUpperAU(IN OUT LPWSTR lpsz) { return LowerOrUpperHelper(lpsz, CharUpperA); } //+---------------------------------------------------------------------------- // // Function: CreateDialogParamAU // // Synopsis: Unicode to Ansi wrapper for the win32 CreateDialogParam API. Notice that // we support both a full string for the lpTemplateName param or only // a int from MAKEINTRESOURCE (a resource identifier stored in the string // pointer var). // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HWND WINAPI CreateDialogParamAU(IN HINSTANCE hInstance, IN LPCWSTR lpTemplateName, IN HWND hWndParent, IN DLGPROC lpDialogFunc, IN LPARAM dwInitParam) { HWND hWndReturn = NULL; CHAR szAnsiTemplateName[MAX_PATH+1]; LPSTR pszAnsiTemplateName; MYDBGASSERT(hInstance); MYDBGASSERT(lpTemplateName); MYDBGASSERT(lpDialogFunc); if (hInstance && lpTemplateName && lpDialogFunc) { if (HIWORD(lpTemplateName)) { // // We have a full template name that we must convert // pszAnsiTemplateName = szAnsiTemplateName; int iChars = WzToSz(lpTemplateName, pszAnsiTemplateName, MAX_PATH); if (!iChars || (MAX_PATH < iChars)) { goto exit; } } else { // // All we need is a cast // pszAnsiTemplateName = (LPSTR)lpTemplateName; } hWndReturn = CreateDialogParamA(hInstance, pszAnsiTemplateName, hWndParent, lpDialogFunc, dwInitParam); } exit: return hWndReturn; } //+---------------------------------------------------------------------------- // // Function: CreateDirectoryAU // // Synopsis: Unicode to Ansi wrapper for the win32 CreateDirectory API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL WINAPI CreateDirectoryAU(IN LPCWSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes) { BOOL bRet = FALSE; LPSTR pszPathName = WzToSzWithAlloc(lpPathName); if (pszPathName) { bRet = CreateDirectoryA(pszPathName, lpSecurityAttributes); CmFree(pszPathName); } return bRet; } //+---------------------------------------------------------------------------- // // Function: CreateEventAU // // Synopsis: Unicode to Ansi wrapper for the win32 CreateEvent API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HANDLE WINAPI CreateEventAU(IN LPSECURITY_ATTRIBUTES lpEventAttributes, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName) { CHAR szAnsiName[MAX_PATH+1]; // lpName is limited to MAX_PATH chars according to the docs. HANDLE hReturn = NULL; LPSTR pszAnsiName = NULL; if (lpName) // lpName could be NULL { pszAnsiName = szAnsiName; int uNumChars = WzToSz(lpName, pszAnsiName, MAX_PATH); if (!uNumChars || (MAX_PATH < uNumChars)) { CMTRACE(TEXT("CreateEventAU -- Unable to convert lpName")); SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto exit; } } hReturn = CreateEventA(lpEventAttributes, bManualReset, bInitialState, pszAnsiName); exit: return hReturn; } //+---------------------------------------------------------------------------- // // Function: CreateFileMappingAU // // Synopsis: Unicode to Ansi wrapper for the win32 CreateFileMapping API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HANDLE WINAPI CreateFileMappingAU(IN HANDLE hFile, IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes, IN DWORD flProtect, IN DWORD dwMaximumSizeHigh, IN DWORD dwMaximumSizeLow, IN LPCWSTR lpName) { HANDLE hHandle = NULL; LPSTR pszName = NULL; if (lpName) // could be NULL { pszName = WzToSzWithAlloc(lpName); } if (pszName || (NULL == lpName)) { hHandle = CreateFileMappingA(hFile, lpFileMappingAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, pszName); CmFree(pszName); } return hHandle; } //+---------------------------------------------------------------------------- // // Function: CreateFileAU // // Synopsis: Unicode to Ansi wrapper for the win32 CreateFile API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HANDLE WINAPI CreateFileAU(IN LPCWSTR lpFileName, IN DWORD dwDesiredAccess, IN DWORD dwShareMode, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes, IN DWORD dwCreationDisposition, IN DWORD dwFlagsAndAttributes, IN HANDLE hTemplateFile) { HANDLE hHandle = INVALID_HANDLE_VALUE; LPSTR pszFileName = WzToSzWithAlloc(lpFileName); if (pszFileName) { hHandle = CreateFileA(pszFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); CmFree(pszFileName); } return hHandle; } //+---------------------------------------------------------------------------- // // Function: CreateMutexAU // // Synopsis: Unicode to Ansi wrapper for the win32 CreateMutex API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HANDLE WINAPI CreateMutexAU(IN LPSECURITY_ATTRIBUTES lpMutexAttributes, IN BOOL bInitialOwner, IN LPCWSTR lpName) { HANDLE hHandle = NULL; LPSTR pszName = NULL; if (lpName) // lpName can be NULL, creates an unnamed mutex { pszName = WzToSzWithAlloc(lpName); } if (pszName || (NULL == lpName)) { hHandle = CreateMutexA(lpMutexAttributes, bInitialOwner, pszName); CmFree(pszName); } return hHandle; } //+---------------------------------------------------------------------------- // // Function: CreateProcessAU // // Synopsis: Unicode to Ansi wrapper for the win32 CreateProcess API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL WINAPI CreateProcessAU(IN LPCWSTR lpApplicationName, IN LPWSTR lpCommandLine, IN LPSECURITY_ATTRIBUTES lpProcessAttributes, IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN BOOL bInheritHandles, IN DWORD dwCreationFlags, IN LPVOID lpEnvironment, IN LPCWSTR lpCurrentDirectory, IN LPSTARTUPINFOW lpStartupInfo, OUT LPPROCESS_INFORMATION lpProcessInformation) { BOOL bSuccess = FALSE; // // Convert the string parameters. Since the environment block is controlled by // a flag (whether it is Ansi or Unicode) we shouldn't have to touch it here. // LPSTR pszAppName = WzToSzWithAlloc(lpApplicationName); // WzToSzWithAlloc will return NULL if the input is NULL LPSTR pszCmdLine = WzToSzWithAlloc(lpCommandLine); LPSTR pszCurrentDir = WzToSzWithAlloc(lpCurrentDirectory); // // Set up the StartUp Info struct. Note that we don't convert it but pass a blank // structure. If someone needs startupinfo then they will have to write the conversion // code. We currently don't use it anywhere. // STARTUPINFOA StartUpInfoA; ZeroMemory(&StartUpInfoA, sizeof(STARTUPINFOA)); StartUpInfoA.cb = sizeof(STARTUPINFOA); #ifdef DEBUG STARTUPINFOW CompareStartupInfoWStruct; ZeroMemory(&CompareStartupInfoWStruct, sizeof(STARTUPINFOW)); CompareStartupInfoWStruct.cb = sizeof(STARTUPINFOW); CMASSERTMSG((0 == memcmp(lpStartupInfo, &CompareStartupInfoWStruct, sizeof(STARTUPINFOW))), TEXT("CreateProcessAU -- Non-NULL STARTUPINFOW struct passed. Conversion code needs to be written.")); #endif // // If we have the Command Line or an App Name go ahead // if (pszAppName || pszCmdLine) { bSuccess = CreateProcessA(pszAppName, pszCmdLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, pszCurrentDir, &StartUpInfoA, lpProcessInformation); } // // Cleanup // CmFree(pszAppName); CmFree(pszCmdLine); CmFree(pszCurrentDir); return bSuccess; } //+---------------------------------------------------------------------------- // // Function: CreateWindowExAU // // Synopsis: Unicode to Ansi wrapper for the win32 CreateWindowEx API. Note that // we only allow MAX_PATH chars for the ClassName and the WindowName // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HWND WINAPI CreateWindowExAU(DWORD dwExStyle, LPCWSTR lpClassNameW, LPCWSTR lpWindowNameW, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam) { CHAR szClassNameA [MAX_PATH+1]; CHAR szWindowNameA[MAX_PATH+1]; HWND hReturn = NULL; if (lpClassNameW && lpWindowNameW) { MYDBGASSERT(MAX_PATH >= lstrlenAU(lpClassNameW)); MYDBGASSERT(MAX_PATH >= lstrlenAU(lpWindowNameW)); if (WzToSz(lpClassNameW, szClassNameA, MAX_PATH)) { if (WzToSz(lpWindowNameW, szWindowNameA, MAX_PATH)) { hReturn = CreateWindowExA(dwExStyle, szClassNameA, szWindowNameA, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam); } } } return hReturn; } //+---------------------------------------------------------------------------- // // Function: DeleteFileAU // // Synopsis: Unicode to Ansi wrapper for the win32 DeleteFile API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL WINAPI DeleteFileAU(IN LPCWSTR lpFileName) { BOOL bReturn = FALSE; LPSTR pszAnsiFileName = WzToSzWithAlloc(lpFileName); // WzToSzWithAlloc will return NULL if lpFileName is NULL if (pszAnsiFileName) { DeleteFileA(pszAnsiFileName); CmFree(pszAnsiFileName); } return bReturn; } //+---------------------------------------------------------------------------- // // Function: DialogBoxParamAU // // Synopsis: Unicode to Ansi wrapper for the win32 DialogBoxParam API. Note that // we don't support the use of a full string name, only ints for the // lpTemplateName param. We will assert if one is used. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- INT_PTR WINAPI DialogBoxParamAU(HINSTANCE hInstance, LPCWSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) { MYDBGASSERT(0 == HIWORD(lpTemplateName)); // we don't support or use the full string name return DialogBoxParamA(hInstance, (LPCSTR) lpTemplateName, hWndParent, lpDialogFunc, dwInitParam); } //+---------------------------------------------------------------------------- // // Function: ExpandEnvironmentStringsAU // // Synopsis: Unicode to Ansi wrapper for the win32 ExpandEnvironmentStrings API. // We support allowing the user to size the string by passing in the // following Str, NULL, 0 just as the API reference mentions. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- DWORD WINAPI ExpandEnvironmentStringsAU(IN LPCWSTR lpSrc, OUT LPWSTR lpDst, IN DWORD nSize) { DWORD dwReturn = 0; if (lpSrc) { // // // Since the user could pass in 0 for the size and a NULL pszAnsiDst because they // want to size the destination string, we want to handle that case. However, // Win98 and Win95 machines (not counting WinME) don't honor sizing the buffer // using a NULL lpDst. We will "fool" these machines by using a buffer of size 1. // Thus they could call it with Str, NULL, 0 and then allocate the correct size and // call again. Note that we will return an error if the user passes Str, NULL, x // because we have no buffer to copy the data returned from ExpandEnvironmentStringsA // into. // LPSTR pszAnsiSrc = WzToSzWithAlloc(lpSrc); LPSTR pszAnsiDst = (LPSTR)CmMalloc((nSize+1)*sizeof(CHAR)); if (pszAnsiSrc && pszAnsiDst) { dwReturn = ExpandEnvironmentStringsA(pszAnsiSrc, pszAnsiDst, nSize); if (dwReturn && (dwReturn <= nSize)) { // // Then the function succeeded and there was sufficient buffer space to hold // the expanded string. Thus we should convert the results and store it back // in lpDst. if (lpDst) { if (!SzToWz(pszAnsiDst, lpDst, nSize)) { CMTRACE(TEXT("ExpandEnvironmentStringsAU -- SzToWz conversion of output param failed.")); dwReturn = 0; } } else { CMTRACE(TEXT("ExpandEnvironmentStringsAU -- NULL pointer passed for lpDst")); dwReturn = 0; SetLastError(ERROR_INVALID_PARAMETER); } } } else { CMTRACE(TEXT("ExpandEnvironmentStringsAU -- NULL pointer returned for pszAnsiSrc or pszAnsiDst")); SetLastError(ERROR_NOT_ENOUGH_MEMORY); } CmFree(pszAnsiSrc); CmFree(pszAnsiDst); } else { CMTRACE(TEXT("ExpandEnvironmentStringsAU -- NULL pointer passed for lpSrc")); SetLastError(ERROR_INVALID_PARAMETER); } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: FindResourceExAU // // Synopsis: Unicode to Ansi wrapper for the win32 FindResourceEx API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HRSRC WINAPI FindResourceExAU(IN HMODULE hModule, IN LPCWSTR lpType, IN LPCWSTR lpName, IN WORD wLanguage) { HRSRC hReturn = NULL; LPSTR pszType = NULL; LPSTR pszName = NULL; // // Check the input parameters // if (lpType && lpName) { // // Two cases for the lpType and the lpName params. These could just be identifiers. We will know // if the high word is zero. In that case we just need to do a cast and pass it through. If not // then we need to actually convert the strings. // if (0 == HIWORD(lpType)) { pszType = (LPSTR)lpType; } else { pszType = WzToSzWithAlloc(lpType); } if (0 == HIWORD(lpName)) { pszName = (LPSTR)lpName; } else { pszName = WzToSzWithAlloc(lpName); } // // Finally call FindResourceEx // if (pszName && pszType) { hReturn = FindResourceExA(hModule, pszType, pszName, wLanguage); } else { SetLastError(ERROR_NOT_ENOUGH_MEMORY); } } else { SetLastError(ERROR_INVALID_PARAMETER); } // // Clean up // if (0 != HIWORD(pszType)) { CmFree(pszType); } if (0 != HIWORD(pszName)) { CmFree(pszName); } return hReturn; } //+---------------------------------------------------------------------------- // // Function: FindWindowExAU // // Synopsis: Unicode to Ansi wrapper for the win32 FindWindowEx API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HWND WINAPI FindWindowExAU(IN HWND hwndParent, IN HWND hwndChildAfter, IN LPCWSTR pszClass, IN LPCWSTR pszWindow) { HWND hReturn = NULL; LPSTR pszAnsiWindow = NULL; LPSTR pszAnsiClass = NULL; if (pszClass) { // // We have two cases for pszClass. It can either be a resource ID (high word zero, // low word contains the ID) in which case we just need to do a cast or // it could be a NULL terminated string. // if (0 == HIWORD(pszClass)) { pszAnsiClass = (LPSTR)pszClass; } else { pszAnsiClass = WzToSzWithAlloc(pszClass); } // // pszWindow could be NULL. That will match all Window titles. // if (pszWindow) { pszAnsiWindow = WzToSzWithAlloc(pszWindow); } // // Check our allocations and call FindWindowExA // if (pszAnsiClass && (!pszWindow || pszAnsiWindow)) { hReturn = FindWindowExA(hwndParent, hwndChildAfter, pszAnsiClass, pszAnsiWindow); } else { SetLastError(ERROR_NOT_ENOUGH_MEMORY); } } else { SetLastError(ERROR_INVALID_PARAMETER); } // // Cleanup // if (0 != HIWORD(pszAnsiClass)) { CmFree(pszAnsiClass); } CmFree(pszAnsiWindow); return hReturn; } //+---------------------------------------------------------------------------- // // Function: GetDateFormatAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetDateFormat API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: sumitc Created 11/20/00 // //+---------------------------------------------------------------------------- int WINAPI GetDateFormatAU(IN LCID Locale, IN DWORD dwFlags, IN CONST SYSTEMTIME *lpDate, IN LPCWSTR lpFormat, OUT LPWSTR lpDateStr, IN int cchDate) { int iReturn = 0; LPSTR pszAnsiFormat = NULL; LPSTR pszAnsiBuffer = NULL; if (lpFormat) { pszAnsiFormat = WzToSzWithAlloc(lpFormat); if (!pszAnsiFormat) { CMASSERTMSG(FALSE, TEXT("GetDateFormatAU -- Conversion of lpFormat Failed.")); goto exit; } } else { pszAnsiFormat = (LPSTR)lpFormat; // Could be NULL } if (lpDateStr && cchDate) { pszAnsiBuffer = (LPSTR) CmMalloc(cchDate * sizeof(CHAR)); } iReturn = GetDateFormatA(Locale, dwFlags, lpDate, pszAnsiFormat, pszAnsiBuffer, cchDate); if (iReturn && lpDateStr && cchDate && pszAnsiBuffer) { SzToWz(pszAnsiBuffer, lpDateStr, cchDate); } exit: CmFree(pszAnsiFormat); CmFree(pszAnsiBuffer); return iReturn; } //+---------------------------------------------------------------------------- // // Function: GetDlgItemTextAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetDlgItemText API. Note that // this function makes a WM_GETTEXT window message call using GetDlgItem // and SendMessageAU. This is how the win32 API function is implemented. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- UINT WINAPI GetDlgItemTextAU(IN HWND hDlg, IN int nIDDlgItem, OUT LPWSTR pszwString, IN int nMaxCount) { return (int) SendMessageAU(GetDlgItem(hDlg, nIDDlgItem), WM_GETTEXT, (WPARAM) nMaxCount, (LPARAM) pszwString); } //+---------------------------------------------------------------------------- // // Function: GetFileAttributesAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetFileAttributes API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: sumitc Created 11/08/00 // //+---------------------------------------------------------------------------- DWORD WINAPI GetFileAttributesAU(LPCWSTR lpFileName) { DWORD dwReturn = -1; LPSTR pszAnsiFileName = WzToSzWithAlloc(lpFileName); if (pszAnsiFileName) { dwReturn = GetFileAttributesA(pszAnsiFileName); CmFree(pszAnsiFileName); } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: GetModuleFileNameAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetModuleFileName API. // Note that we only allow MAX_PATH chars for the module name. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- DWORD WINAPI GetModuleFileNameAU(HMODULE hModule, LPWSTR lpFileName, DWORD nSize) { DWORD dwReturn = 0; CHAR pszAnsiFileName[MAX_PATH] = {'\0'} ; MYDBGASSERT(MAX_PATH >= nSize); dwReturn = GetModuleFileNameA(hModule, pszAnsiFileName, __min(nSize, MAX_PATH)); if(dwReturn && lpFileName) { SzToWz(pszAnsiFileName, lpFileName, __min(nSize, MAX_PATH)); } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: GetModuleHandleAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetModuleHandle API. // Note that we only allow MAX_PATH chars for the module name. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: sumitc Created 10/20/2000 // //+---------------------------------------------------------------------------- HMODULE WINAPI GetModuleHandleAU(LPCWSTR lpModuleName) { HMODULE hMod = NULL; LPSTR pszAnsiModuleName = WzToSzWithAlloc(lpModuleName); if (pszAnsiModuleName) { hMod = GetModuleHandleA(pszAnsiModuleName); CmFree(pszAnsiModuleName); } return hMod; } //+---------------------------------------------------------------------------- // // Function: GetPrivateProfileIntAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetPrivateProfileInt API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- UINT WINAPI GetPrivateProfileIntAU(IN LPCWSTR lpAppName, IN LPCWSTR lpKeyName, IN INT nDefault, IN LPCWSTR lpFileName) { UINT uReturn = nDefault; if (lpAppName && lpKeyName && lpFileName) { CHAR pszAnsiAppName[MAX_PATH+1]; CHAR pszAnsiKeyName[MAX_PATH+1]; CHAR pszAnsiFileName[MAX_PATH+1]; BOOL bSuccess = TRUE; int nChars; nChars = WzToSz(lpAppName, pszAnsiAppName, MAX_PATH); bSuccess = bSuccess && nChars && (MAX_PATH >= nChars); nChars = WzToSz(lpKeyName, pszAnsiKeyName, MAX_PATH); bSuccess = bSuccess && nChars && (MAX_PATH >= nChars); nChars = WzToSz(lpFileName, pszAnsiFileName, MAX_PATH); bSuccess = bSuccess && nChars && (MAX_PATH >= nChars); if (bSuccess) { uReturn = GetPrivateProfileIntA(pszAnsiAppName, pszAnsiKeyName, nDefault, pszAnsiFileName); } CMASSERTMSG(bSuccess, TEXT("GetPrivateProfileIntAU -- Failed to convert lpAppName, lpKeyName, or lpFileName")); } return uReturn; } //+---------------------------------------------------------------------------- // // Function: GetPrivateProfileStringAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetPrivateProfileString API. // Note that either lpAppName or lpKeyName could be NULL. This means // that our return buffer will contain multiple lines of NULL terminated // text. We must use MultiByteToWideChar directly with a size param // to properly convert such a situation. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- DWORD WINAPI GetPrivateProfileStringAU(IN LPCWSTR lpAppName, IN LPCWSTR lpKeyName, IN LPCWSTR lpDefault, OUT LPWSTR lpReturnedString, IN DWORD nSize, IN LPCWSTR lpFileName) { // // Declare all the temp vars we need // LPSTR pszAnsiAppName = NULL; LPSTR pszAnsiKeyName = NULL; LPSTR pszAnsiReturnedString = NULL; CHAR szAnsiAppName[MAX_PATH+1]; CHAR szAnsiKeyName[MAX_PATH+1]; CHAR szAnsiDefault[MAX_PATH+1]; CHAR szAnsiFileName[MAX_PATH+1]; DWORD dwReturn = 0; int nChars; // // Check the inputs, note that either lpAppName or lpKeyName may be NULL (or both) // if (lpDefault && lpReturnedString && nSize && lpFileName) { if (lpAppName) // pszAnsiAppName already initialized to NULL { pszAnsiAppName = szAnsiAppName; nChars = WzToSz(lpAppName, pszAnsiAppName, MAX_PATH); if (!nChars || (MAX_PATH < nChars)) { // // Conversion failed. // goto exit; } } if (lpKeyName) // pszAnsiKeyName already initialized to NULL { pszAnsiKeyName = szAnsiKeyName; nChars = WzToSz(lpKeyName, szAnsiKeyName, MAX_PATH); if (!nChars || (MAX_PATH < nChars)) { // // Conversion failed. // goto exit; } } nChars = WzToSz(lpDefault, szAnsiDefault, MAX_PATH); if (!nChars || (MAX_PATH < nChars)) { goto exit; } nChars = WzToSz(lpFileName, szAnsiFileName, MAX_PATH); if (!nChars || (MAX_PATH < nChars)) { goto exit; } // // Alloc the Ansi return Buffer // pszAnsiReturnedString = (LPSTR)CmMalloc(nSize*sizeof(CHAR)); if (pszAnsiReturnedString) { dwReturn = GetPrivateProfileStringA(pszAnsiAppName, pszAnsiKeyName, szAnsiDefault, pszAnsiReturnedString, nSize, szAnsiFileName); if (dwReturn) { if (pszAnsiAppName && pszAnsiKeyName) { if (!SzToWz(pszAnsiReturnedString, lpReturnedString, nSize)) { dwReturn = 0; } } else { // // We have multiple lines of text in the return buffer, use MultiByteToWideChar // with a size specifier // if (!MultiByteToWideChar(CP_ACP, 0, pszAnsiReturnedString, dwReturn, lpReturnedString, nSize)) { dwReturn = 0; } } } } } exit: CmFree(pszAnsiReturnedString); return dwReturn; } //+---------------------------------------------------------------------------- // // Function: GetStringTypeExAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetStringTypeEx API. Note // that because we only use one char at a time with this API, I have // limited it to a 10 char static buffer to make it faster. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL WINAPI GetStringTypeExAU(IN LCID Locale, IN DWORD dwInfoType, IN LPCWSTR lpSrcStr, IN int cchSrc, OUT LPWORD lpCharType) { BOOL bReturn = FALSE; CHAR szAnsiString[10]; // We should only be using 1 char at a time with this if (lpSrcStr && cchSrc) { MYDBGASSERT(cchSrc <= 10); int nCount = WideCharToMultiByte(CP_ACP, 0, lpSrcStr, cchSrc, szAnsiString, 9, NULL, NULL); if (nCount) // nCount may not exactly equal cchSrc if DBCS chars were necessary { bReturn = GetStringTypeExA(Locale, dwInfoType, szAnsiString, nCount, lpCharType); } } return bReturn; } //+---------------------------------------------------------------------------- // // Function: GetSystemDirectoryAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetSystemDirectory API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- UINT WINAPI GetSystemDirectoryAU(OUT LPWSTR lpBuffer, IN UINT uSize) { UINT uReturn = 0; LPSTR pszAnsiSystemDir; pszAnsiSystemDir = uSize ? (LPSTR)CmMalloc(uSize*sizeof(CHAR)) : NULL; if (pszAnsiSystemDir || (0 == uSize)) { uReturn = GetSystemDirectoryA(pszAnsiSystemDir, uSize); CMASSERTMSG(uReturn, TEXT("GetSystemDirectoryAU -- GetSystemDirectoryAU failed.")); if (uReturn && lpBuffer && (uSize >= uReturn)) { if (!SzToWz(pszAnsiSystemDir, lpBuffer, uSize)) { // // Conversion failed. // CMASSERTMSG(FALSE, TEXT("GetSystemDirectoryAU -- SzToWz conversion failed.")); uReturn = 0; } } } CmFree(pszAnsiSystemDir); return uReturn; } //+---------------------------------------------------------------------------- // // Function: GetTempFileNameAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetTempFileName API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- UINT WINAPI GetTempFileNameAU(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName) { UINT uReturn = 0; if (lpPathName && lpPrefixString && lpTempFileName) { CHAR szAnsiTempFileName[MAX_PATH+1]; CHAR szPathName[MAX_PATH+1]; CHAR szPrefixString[MAX_PATH+1]; BOOL bSuccess = TRUE; int nChars; nChars = WzToSz(lpPathName, szPathName, MAX_PATH); bSuccess = bSuccess && nChars && (MAX_PATH >= nChars); nChars = WzToSz(lpPrefixString, szPrefixString, MAX_PATH); bSuccess = bSuccess && nChars && (MAX_PATH >= nChars); if (bSuccess) { uReturn = GetTempFileNameA(szPathName, szPrefixString, uUnique, szAnsiTempFileName); if (uReturn) { if (!SzToWz(szAnsiTempFileName, lpTempFileName, MAX_PATH)) { CMASSERTMSG(FALSE, TEXT("GetTempFileNameAU -- conversion of output buffer failed.")); uReturn = 0; } } } else { CMASSERTMSG(FALSE, TEXT("GetTempFileNameAU -- conversion of inputs failed.")); SetLastError(ERROR_INVALID_PARAMETER); } } else { SetLastError(ERROR_INVALID_PARAMETER); } return uReturn; } //+---------------------------------------------------------------------------- // // Function: GetTempPathAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetTempPath API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- DWORD WINAPI GetTempPathAU(IN DWORD nBufferLength, OUT LPWSTR lpBuffer) { UINT uReturn = 0; LPSTR pszAnsiBuffer = (LPSTR)CmMalloc(nBufferLength*sizeof(CHAR)); if (pszAnsiBuffer) { uReturn = GetTempPathA(nBufferLength, pszAnsiBuffer); if (uReturn) { if (!SzToWz(pszAnsiBuffer, lpBuffer, nBufferLength)) { CMASSERTMSG(FALSE, TEXT("GetTempPathAU -- conversion of output buffer failed.")); uReturn = 0; } } CmFree(pszAnsiBuffer); } return uReturn; } //+---------------------------------------------------------------------------- // // Function: GetTimeFormatAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetTimeFormat API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: sumitc Created 11/20/00 // //+---------------------------------------------------------------------------- int WINAPI GetTimeFormatAU(IN LCID Locale, IN DWORD dwFlags, IN CONST SYSTEMTIME *lpTime, IN LPCWSTR lpFormat, OUT LPWSTR lpTimeStr, IN int cchTime) { int iReturn = 0; LPSTR pszAnsiFormat = NULL; LPSTR pszAnsiBuffer = NULL; if (lpFormat) { pszAnsiFormat = WzToSzWithAlloc(lpFormat); if (!pszAnsiFormat) { CMASSERTMSG(FALSE, TEXT("GetTimeFormatAU -- Conversion of lpFormat Failed.")); goto exit; } } else { pszAnsiFormat = (LPSTR)lpFormat; // Could be NULL } if (lpTimeStr && cchTime) { pszAnsiBuffer = (LPSTR) CmMalloc(cchTime * sizeof(CHAR)); } iReturn = GetTimeFormatA(Locale, dwFlags, lpTime, pszAnsiFormat, pszAnsiBuffer, cchTime); if (iReturn && lpTimeStr && cchTime && pszAnsiBuffer) { SzToWz(pszAnsiBuffer, lpTimeStr, cchTime); } exit: CmFree(pszAnsiFormat); CmFree(pszAnsiBuffer); return iReturn; } //+---------------------------------------------------------------------------- // // Function: GetUserNameAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetUserName API. // Note that we assume the user name will fit in MAX_PATH chars. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL WINAPI GetUserNameAU(OUT LPWSTR lpBuffer, IN OUT LPDWORD pdwSize) { BOOL bReturn = FALSE; if (lpBuffer && pdwSize && *pdwSize) { MYDBGASSERT(MAX_PATH >= *pdwSize); CHAR szAnsiBuffer[MAX_PATH+1]; // API says UNLEN+1 needed but this is less than MAX_PATH DWORD dwTemp = MAX_PATH; bReturn = GetUserNameA(szAnsiBuffer, &dwTemp); if (bReturn) { if (!SzToWz(szAnsiBuffer, lpBuffer, *pdwSize)) { bReturn = FALSE; } else { *pdwSize = lstrlenAU(lpBuffer) + 1; } } } else { SetLastError(ERROR_INVALID_PARAMETER); } CMASSERTMSG(bReturn, TEXT("GetUserNameAU Failed.")); return bReturn; } //+---------------------------------------------------------------------------- // // Function: GetVersionExAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetVersionEx API. Note that // we check to make sure we aren't passed an OSVERSIONINFOEXW struct // because that struct is currently NT5 only. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL WINAPI GetVersionExAU(IN OUT LPOSVERSIONINFOW lpVersionInformation) { BOOL bReturn = FALSE; if (lpVersionInformation) { OSVERSIONINFOA AnsiVersionInfo; // // Check to make sure we didn't get an OSVERSIONINFOEXW struct instead of a OSVERSIONINFO // the EX version is NT5 only we shouldn't be calling this on NT5. // MYDBGASSERT(lpVersionInformation->dwOSVersionInfoSize != sizeof(_OSVERSIONINFOEXW)); AnsiVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA); bReturn = GetVersionExA(&AnsiVersionInfo); if (bReturn) { //lpVersionInformation.dwOSVersionInfoSize; // should be set appropriately already lpVersionInformation->dwMajorVersion = AnsiVersionInfo.dwMajorVersion; lpVersionInformation->dwMinorVersion = AnsiVersionInfo.dwMinorVersion; lpVersionInformation->dwBuildNumber = AnsiVersionInfo.dwBuildNumber; lpVersionInformation->dwPlatformId = AnsiVersionInfo.dwPlatformId; if (!SzToWz(AnsiVersionInfo.szCSDVersion, lpVersionInformation->szCSDVersion, 128-1)) { bReturn = FALSE; } } } CMASSERTMSG(bReturn, TEXT("GetVersionExAU Failed")); return bReturn; } //+---------------------------------------------------------------------------- // // Function: GetWindowTextAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetWindowText API. This API // is implemented as a WM_GETTEXT message just as the real windows // API is. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- int WINAPI GetWindowTextAU(HWND hWnd, LPWSTR lpStringW, int nMaxChars) { return (int) SendMessageAU(hWnd, WM_GETTEXT, (WPARAM) nMaxChars, (LPARAM) lpStringW); } //+---------------------------------------------------------------------------- // // Function: GetWindowTextAU // // Synopsis: Unicode to Ansi wrapper for the win32 GetWindowText API. This API // is implemented as a WM_GETTEXT message just as the real windows // API is. Note that since MF_STRING is 0, we must check to make sure // that it isn't one of the other menu item choices (MF_OWNERDRAW, // MF_BITMAP, or MF_SEPARATOR). The other MF_ flags are just modifiers // for the above basic types. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL WINAPI InsertMenuAU(IN HMENU hMenu, IN UINT uPosition, IN UINT uFlags, IN UINT_PTR uIDNewItem, IN LPCWSTR lpNewItem) { BOOL bReturn = FALSE; LPSTR pszAnsiNewItem = NULL; BOOL bFreeAnsiNewItem = FALSE; if (hMenu) { // // Since MF_STRING == 0, we must check that it is not MF_OWNERDRAW or MF_BITMAP or // that it is not MF_SEPARATOR // if ((0 == (uFlags & MF_BITMAP)) && (0 == (uFlags & MF_OWNERDRAW)) && (0 == (uFlags & MF_SEPARATOR)) && lpNewItem) { // // Then the menu item actually contains a string and we must convert it. // pszAnsiNewItem = WzToSzWithAlloc(lpNewItem); if (!pszAnsiNewItem) { CMASSERTMSG(FALSE, TEXT("InsertMenuAU -- Conversion of lpNewItem Failed.")); goto exit; } bFreeAnsiNewItem = TRUE; } else { pszAnsiNewItem = (LPSTR)lpNewItem; // Could be NULL } bReturn = InsertMenuA(hMenu, uPosition, uFlags, uIDNewItem, pszAnsiNewItem); } exit: if (bFreeAnsiNewItem) { CmFree(pszAnsiNewItem); } return bReturn; } //+---------------------------------------------------------------------------- // // Function: LoadCursorAU // // Synopsis: Unicode to Ansi wrapper for the win32 LoadCursor API. Note that // lpCursorName could be a string or it could be a resource ID from // MAKEINTRESOURCE. We assume the cursor name will fit in MAX_PATH // chars if it is a string. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HCURSOR WINAPI LoadCursorAU(IN HINSTANCE hInstance, IN LPCWSTR lpCursorName) { LPSTR pszCursorName; CHAR szCursorName[MAX_PATH+1]; HCURSOR hReturn = NULL; if (lpCursorName) { BOOL bSuccess = TRUE; if (0 == HIWORD(lpCursorName)) { pszCursorName = (LPSTR)lpCursorName; } else { int nChars; pszCursorName = szCursorName; nChars = WzToSz(lpCursorName, pszCursorName, MAX_PATH); bSuccess = bSuccess && nChars && (MAX_PATH >= nChars); } if (bSuccess) { hReturn = LoadCursorA(hInstance, pszCursorName); } } else { SetLastError(ERROR_INVALID_PARAMETER); } return hReturn; } //+---------------------------------------------------------------------------- // // Function: LoadIconAU // // Synopsis: Unicode to Ansi wrapper for the win32 LoadIcon API. Note that // lpIconName could be a string or it could be a resource ID from // MAKEINTRESOURCE. We assume the icon name will fit in MAX_PATH // chars if it is a string. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HICON WINAPI LoadIconAU(IN HINSTANCE hInstance, IN LPCWSTR lpIconName) { LPSTR pszIconName; CHAR szIconName[MAX_PATH+1]; HICON hReturn = NULL; if (hInstance && lpIconName) { BOOL bSuccess = TRUE; if (0 == HIWORD(lpIconName)) { pszIconName = (LPSTR)lpIconName; } else { int nChars; pszIconName = szIconName; nChars = WzToSz(lpIconName, pszIconName, MAX_PATH); bSuccess = bSuccess && nChars && (MAX_PATH >= nChars); } if (bSuccess) { hReturn = LoadIconA(hInstance, pszIconName); } } else { SetLastError(ERROR_INVALID_PARAMETER); } return hReturn; } //+---------------------------------------------------------------------------- // // Function: LoadImageAU // // Synopsis: Unicode to Ansi wrapper for the win32 LoadImage API. Note that // pszwName could be a string or it could be a resource ID from // MAKEINTRESOURCE. We assume the image name will fit in MAX_PATH // chars if it is a string. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HANDLE WINAPI LoadImageAU(IN HINSTANCE hInst, IN LPCWSTR pszwName, IN UINT uType, IN int cxDesired, IN int cyDesired, IN UINT fuLoad) { HANDLE hReturn = NULL; MYDBGASSERT(hInst || (LR_LOADFROMFILE & fuLoad)); // we don't support loading OEM images -- implement it if you need it. if (pszwName) { CHAR szAnsiName [MAX_PATH+1]; LPSTR pszAnsiName; if (0 == HIWORD(pszwName)) { pszAnsiName = LPSTR(pszwName); } else { pszAnsiName = szAnsiName; int iChars = WzToSz(pszwName, pszAnsiName, MAX_PATH); if (!iChars || (MAX_PATH < iChars)) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto exit; } } hReturn = LoadImageA(hInst, pszAnsiName, uType, cxDesired, cyDesired, fuLoad); } exit: return hReturn; } //+---------------------------------------------------------------------------- // // Function: LoadLibraryExAU // // Synopsis: Unicode to Ansi wrapper for the win32 LoadLibraryEx API. Note that // we expect the library name to fit in MAX_PATH ANSI chars. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HMODULE WINAPI LoadLibraryExAU(LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags) { CHAR pszLibFileName[MAX_PATH+1]; HMODULE hReturn = NULL; if (lpLibFileName && (NULL == hFile)) // hFile is reserved, it must be NULL { if(WzToSz(lpLibFileName, pszLibFileName, MAX_PATH)) { hReturn = LoadLibraryExA(pszLibFileName, hFile, dwFlags); } } return hReturn; } //+---------------------------------------------------------------------------- // // Function: LoadMenuAU // // Synopsis: Unicode to Ansi wrapper for the win32 LoadMenu API. Note that // lpMenuName could be a string or it could be a resource ID from // MAKEINTRESOURCE. We assume the menu name will fit in MAX_PATH // chars if it is a string. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HMENU WINAPI LoadMenuAU(IN HINSTANCE hInstance, IN LPCWSTR lpMenuName) { HMENU hMenuReturn = NULL; LPSTR pszAnsiMenuName; CHAR szAnsiMenuName[MAX_PATH+1]; if (hInstance && lpMenuName) { if (HIWORD(lpMenuName)) { pszAnsiMenuName = szAnsiMenuName; int iChars = WzToSz(lpMenuName, pszAnsiMenuName, MAX_PATH); if (!iChars || (MAX_PATH < iChars)) { goto exit; } } else { pszAnsiMenuName = (LPSTR)lpMenuName; } hMenuReturn = LoadMenuA(hInstance, pszAnsiMenuName); } exit: return hMenuReturn; } //+---------------------------------------------------------------------------- // // Function: LoadStringAU // // Synopsis: Unicode to Ansi wrapper for the win32 LoadString API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- int WINAPI LoadStringAU(HINSTANCE hInstance, UINT uID, LPWSTR lpBuffer, int nBufferMax) { int iReturn = 0; if (uID && hInstance) // lpBuffer and nBufferMax could be Zero { LPSTR pszAnsiBuffer = nBufferMax ? (LPSTR)CmMalloc(nBufferMax*sizeof(CHAR)) : NULL; if (pszAnsiBuffer || (0 == nBufferMax)) { iReturn = LoadStringA(hInstance, uID, pszAnsiBuffer, nBufferMax); if (lpBuffer && iReturn && (iReturn <= nBufferMax)) { if (!SzToWz(pszAnsiBuffer, lpBuffer, nBufferMax)) { iReturn = 0; } } } CmFree(pszAnsiBuffer); } CMASSERTMSG(iReturn, TEXT("LoadStringAU Failed.")); return iReturn; } //+---------------------------------------------------------------------------- // // Function: lstrcatAU // // Synopsis: Unicode to Ansi wrapper for the win32 lstrcat API. Note that we // use wcscat instead of doing a conversion from Unicode to ANSI, // then using lstrcatA, and then converting back to Unicode again. // That seemed like a lot of effort when wcscat should work just fine. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LPWSTR WINAPI lstrcatAU(IN OUT LPWSTR lpString1, IN LPCWSTR lpString2) { if (lpString2 && lpString2) { return wcscat(lpString1, lpString2); } else { CMASSERTMSG(FALSE, TEXT("NULL String passed to lstrcatAU")); return lpString1; } } //+---------------------------------------------------------------------------- // // Function: lstrcmpAU // // Synopsis: Unicode to Ansi wrapper for the win32 lstrcmp API. Note that we // use wcscmp instead of doing a conversion from Unicode to ANSI, // then using lstrcmpA, and then converting back to Unicode again. // That seemed like a lot of effort when wcscmp should work just fine. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- int WINAPI lstrcmpAU(IN LPCWSTR lpString1, IN LPCWSTR lpString2) { if (lpString1 && lpString2) { return wcscmp(lpString1, lpString2); } else { CMASSERTMSG(FALSE, TEXT("NULL String passed to lstrcmpAU")); // // Wasn't exactly sure what to do on failure since their isn't a failure // return value from lstrcmp. I looked at the current implementation // and they do something like the following. // if (lpString1) { return 1; } else if (lpString2) { return -1; } else { return 0; } } } //+---------------------------------------------------------------------------- // // Function: lstrcmpiAU // // Synopsis: Unicode to Ansi wrapper for the win32 lstrcmpi API. Note that we // use _wcsicmp instead of doing a conversion from Unicode to ANSI, // then using lstrcmpiA, and then converting back to Unicode again. // That seemed like a lot of effort when _wcsicmp should work just fine. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- int WINAPI lstrcmpiAU(IN LPCWSTR lpString1, IN LPCWSTR lpString2) { if (lpString1 && lpString2) { return _wcsicmp(lpString1, lpString2); } else { CMASSERTMSG(FALSE, TEXT("NULL String passed to lstrcmpiAU")); // // Wasn't exactly sure what to do on failure since their isn't a failure // return value from lstrcmp. I looked at the current implementation // and they do something like the following. // if (lpString1) { return 1; } else if (lpString2) { return -1; } else { return 0; } } } //+---------------------------------------------------------------------------- // // Function: lstrcpyAU // // Synopsis: Unicode to Ansi wrapper for the win32 lstrcpy API. Note that we // use wcscpy instead of doing a conversion from Unicode to ANSI, // then using lstrcpyA, and then converting back to Unicode again. // That seemed like a lot of effort when wcscpy should work just fine. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LPWSTR WINAPI lstrcpyAU(OUT LPWSTR pszDest, IN LPCWSTR pszSource) { if (pszDest && pszSource) { return wcscpy(pszDest, pszSource); } else { CMASSERTMSG(FALSE, TEXT("NULL String passed to lstrcpyAU")); return pszDest; } } //+---------------------------------------------------------------------------- // // Function: lstrcpynAU // // Synopsis: Unicode to Ansi wrapper for the win32 lstrcpyn API. Note that we // use wcsncpy instead of doing a conversion from Unicode to ANSI, // then using lstrcpynA, and then converting back to Unicode again. // That seemed like a lot of effort when wcsncpy should work just fine. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LPWSTR WINAPI lstrcpynAU(OUT LPWSTR pszDest, IN LPCWSTR pszSource, IN int iMaxLength) { if (pszDest && pszSource && iMaxLength) { LPWSTR pszReturn = wcsncpy(pszDest, pszSource, iMaxLength); // // wcsncpy and lstrcpy behave differently about terminating NULL // characters. The last char in the lstrcpyn buffer always gets // a TEXT('\0'), whereas wcsncpy doesn't do this. Thus we must // NULL the last char before returning. // pszDest[iMaxLength-1] = TEXT('\0'); return pszReturn; } else { CMASSERTMSG(FALSE, TEXT("Invalid parameter passed to lstrcpynAU")); return pszDest; } } //+---------------------------------------------------------------------------- // // Function: lstrlenAU // // Synopsis: Unicode to Ansi wrapper for the win32 lstrlen API. Note that we // use wcslen instead of doing a conversion from Unicode to ANSI, // then using lstrlenA, and then converting back to Unicode again. // That seemed like a lot of effort when wcslen should work just fine. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- int WINAPI lstrlenAU(IN LPCWSTR lpString) { if (lpString) { return wcslen(lpString); } else { // CMASSERTMSG(FALSE, TEXT("NULL String passed to lstrlenAU")); return 0; } } //+---------------------------------------------------------------------------- // // Function: OpenEventAU // // Synopsis: Unicode to Ansi wrapper for the win32 OpenEvent API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HANDLE WINAPI OpenEventAU(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName) { HANDLE hReturn = NULL; if (lpName) { LPSTR pszAnsiName = WzToSzWithAlloc(lpName); if (pszAnsiName) { hReturn = OpenEventA(dwDesiredAccess, bInheritHandle, pszAnsiName); } CmFree(pszAnsiName); } return hReturn; } //+---------------------------------------------------------------------------- // // Function: OpenFileMappingAU // // Synopsis: Unicode to Ansi wrapper for the win32 OpenFileMapping API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- HANDLE WINAPI OpenFileMappingAU(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCWSTR lpName) { HANDLE hReturn = NULL; if (lpName) { LPSTR pszAnsiName = WzToSzWithAlloc(lpName); if (pszAnsiName) { hReturn = OpenFileMappingA(dwDesiredAccess, bInheritHandle, pszAnsiName); } CmFree(pszAnsiName); } return hReturn; } //+---------------------------------------------------------------------------- // // Function: RegCreateKeyExAU // // Synopsis: Unicode to Ansi wrapper for the win32 RegCreateKeyEx API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LONG APIENTRY RegCreateKeyExAU(IN HKEY hKey, IN LPCWSTR lpSubKey, IN DWORD Reserved, IN LPWSTR lpClass, IN DWORD dwOptions, IN REGSAM samDesired, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes, OUT PHKEY phkResult, OUT LPDWORD lpdwDisposition) { LONG lReturn = ERROR_INVALID_PARAMETER; if (lpSubKey) { LPSTR pszAnsiSubKey = WzToSzWithAlloc(lpSubKey); LPSTR pszAnsiClass = lpClass ? WzToSzWithAlloc(lpClass) : NULL; if (pszAnsiSubKey && (pszAnsiClass || !lpClass)) { lReturn = RegCreateKeyExA(hKey, pszAnsiSubKey, Reserved, pszAnsiClass, dwOptions, samDesired, lpSecurityAttributes, phkResult, lpdwDisposition); } else { lReturn = ERROR_NOT_ENOUGH_MEMORY; } CmFree(pszAnsiSubKey); CmFree(pszAnsiClass); } CMASSERTMSG(ERROR_SUCCESS == lReturn, TEXT("RegCreateKeyExAU Failed.")); return lReturn; } //+---------------------------------------------------------------------------- // // Function: RegDeleteKeyAU // // Synopsis: Unicode to Ansi wrapper for the win32 RegDeleteKey API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LONG APIENTRY RegDeleteKeyAU(IN HKEY hKey, IN LPCWSTR lpSubKey) { LONG lReturn = ERROR_INVALID_PARAMETER; if (lpSubKey) { LPSTR pszAnsiSubKey = WzToSzWithAlloc(lpSubKey); if (pszAnsiSubKey) { lReturn = RegDeleteKeyA(hKey, pszAnsiSubKey); } else { lReturn = ERROR_NOT_ENOUGH_MEMORY; } CmFree(pszAnsiSubKey); } CMASSERTMSG(ERROR_SUCCESS == lReturn, TEXT("RegDeleteKeyAU Failed.")); return lReturn; } //+---------------------------------------------------------------------------- // // Function: RegDeleteValueAU // // Synopsis: Unicode to Ansi wrapper for the win32 RegDeleteValue API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LONG APIENTRY RegDeleteValueAU(IN HKEY hKey, IN LPCWSTR lpValueName) { LONG lReturn = ERROR_INVALID_PARAMETER; if (lpValueName) { LPSTR pszAnsiValueName = WzToSzWithAlloc(lpValueName); if (pszAnsiValueName) { lReturn = RegDeleteValueA(hKey, pszAnsiValueName); CmFree(pszAnsiValueName); } else { lReturn = ERROR_NOT_ENOUGH_MEMORY; } } return lReturn; } //+---------------------------------------------------------------------------- // // Function: RegEnumKeyExAU // // Synopsis: Unicode to Ansi wrapper for the win32 RegEnumKeyEx API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LONG RegEnumKeyExAU(IN HKEY hKey, IN DWORD dwIndex, OUT LPWSTR lpName, IN OUT LPDWORD lpcbName, IN LPDWORD lpReserved, IN OUT LPWSTR lpClass, IN OUT LPDWORD lpcbClass, OUT PFILETIME lpftLastWriteTime) { LONG lReturn = ERROR_INVALID_PARAMETER; if (lpcbName) { MYDBGASSERT((lpName && *lpcbName) || ((NULL == lpName) && (0 == *lpcbName))); LPSTR pszAnsiClass = lpClass ? WzToSzWithAlloc(lpClass) : NULL; LPSTR pszTmpBuffer = lpName ? (LPSTR)CmMalloc(*lpcbName) : NULL; DWORD dwSizeTmp = lpName ? *lpcbName : 0; if (pszTmpBuffer || (NULL == lpName)) { lReturn = RegEnumKeyExA(hKey, dwIndex, pszTmpBuffer, &dwSizeTmp, lpReserved, pszAnsiClass, lpcbClass, lpftLastWriteTime); if ((ERROR_SUCCESS == lReturn) && pszTmpBuffer) { if (!SzToWz(pszTmpBuffer, lpName, (*lpcbName))) { lReturn = ERROR_NOT_ENOUGH_MEMORY; } else { *lpcbName = (lstrlenAU((WCHAR*)lpName) + 1); } } } else { lReturn = ERROR_NOT_ENOUGH_MEMORY; } CmFree(pszTmpBuffer); } return lReturn; } //+---------------------------------------------------------------------------- // // Function: RegisterClassExAU // // Synopsis: Unicode to Ansi wrapper for the win32 RegisterClassEx API. Note // that we don't deal with the lpszMenuName parameter. If this is // needed then conversion code will have to be written. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- ATOM WINAPI RegisterClassExAU(CONST WNDCLASSEXW *lpWcw) { WNDCLASSEXA wca; CHAR szClassName[MAX_PATH]; ATOM ReturnAtom = 0; if (lpWcw->lpszClassName) { if (WzToSz(lpWcw->lpszClassName, szClassName, MAX_PATH)) { wca.cbSize = sizeof(WNDCLASSEXA); wca.lpfnWndProc = lpWcw->lpfnWndProc; wca.style = lpWcw->style; wca.cbClsExtra = lpWcw->cbClsExtra; wca.cbWndExtra = lpWcw->cbWndExtra; wca.hInstance = lpWcw->hInstance; wca.hIcon = lpWcw->hIcon; wca.hCursor = lpWcw->hCursor; wca.hbrBackground = lpWcw->hbrBackground; wca.hIconSm = lpWcw->hIconSm; wca.lpszClassName = szClassName; MYDBGASSERT(NULL == lpWcw->lpszMenuName); wca.lpszMenuName = NULL; // // Now register the class. // ReturnAtom = RegisterClassExA(&wca); if (0 == ReturnAtom) { // // We want to assert failure unless we failed because the class // was already registered. This can happen if something // calls two CM entry points without exiting first. A prime // example of this is rasrcise.exe. Unfortunately, GetLastError() // returns 0 when we try to register the class twice. Thus I // will only assert if the ReturnAtom is 0 and dwError is non-zero. // DWORD dwError = GetLastError(); CMASSERTMSG(!dwError, TEXT("RegisterClassExAU Failed.")); } } } return ReturnAtom; } //+---------------------------------------------------------------------------- // // Function: RegisterWindowMessageAU // // Synopsis: Unicode to Ansi wrapper for the win32 RegisterWindowMessage API. Note // that we expect the message name to fit within MAX_PATH characters. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- UINT WINAPI RegisterWindowMessageAU(IN LPCWSTR lpString) { UINT uReturn = 0; if (lpString) { MYDBGASSERT(MAX_PATH > lstrlenAU(lpString)); CHAR szAnsiString [MAX_PATH+1]; if (WzToSz(lpString, szAnsiString, MAX_PATH)) { uReturn = RegisterWindowMessageA(szAnsiString); } } return uReturn; } //+---------------------------------------------------------------------------- // // Function: RegOpenKeyExAU // // Synopsis: Unicode to Ansi wrapper for the win32 RegOpenKeyEx API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LONG APIENTRY RegOpenKeyExAU(IN HKEY hKey, IN LPCWSTR lpSubKey, IN DWORD ulOptions, IN REGSAM samDesired, OUT PHKEY phkResult) { LONG lReturn = ERROR_INVALID_PARAMETER; if (lpSubKey) { LPSTR pszAnsiSubKey = WzToSzWithAlloc(lpSubKey); if (pszAnsiSubKey) { lReturn = RegOpenKeyExA(hKey, pszAnsiSubKey, ulOptions, samDesired, phkResult); } else { lReturn = ERROR_NOT_ENOUGH_MEMORY; } CmFree(pszAnsiSubKey); } // CMASSERTMSG(ERROR_SUCCESS == lReturn, TEXT("RegOpenKeyExAU Failed.")); return lReturn; } //+---------------------------------------------------------------------------- // // Function: RegQueryValueExAU // // Synopsis: Unicode to Ansi wrapper for the win32 RegQueryValueEx API. Note that // we don't handle the REG_MULTI_SZ type. We would have to have // special code to handle it and we currently don't need it. Be careful // modifying this function unless you have read and thoroughly understood // all of the comments. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LONG APIENTRY RegQueryValueExAU(IN HKEY hKey, IN LPCWSTR lpValueName, IN LPDWORD lpReserved, OUT LPDWORD lpType, IN OUT LPBYTE lpData, IN OUT LPDWORD lpcbData) { LONG lReturn = ERROR_NOT_ENOUGH_MEMORY; // // lpValueName could be NULL or it could be "". In either case they are after the default // entry so just pass NULL (don't convert ""). // LPSTR pszAnsiValueName = (lpValueName && lpValueName[0]) ? WzToSzWithAlloc(lpValueName) : NULL; if (pszAnsiValueName || !lpValueName || (TEXT('\0') == lpValueName[0])) { // // lpData could also be NULL, they may not actually want the value just to see if it exists // LPSTR pszTmpBuffer = lpData ? (LPSTR)CmMalloc(*lpcbData) : NULL; if (pszTmpBuffer || !lpData) { DWORD dwTemp = *lpcbData; // we don't want the original value overwritten lReturn = RegQueryValueExA(hKey, pszAnsiValueName, lpReserved, lpType, (LPBYTE)pszTmpBuffer, &dwTemp); if ((ERROR_SUCCESS == lReturn) && pszTmpBuffer) { if ((REG_SZ == *lpType) || (REG_EXPAND_SZ == *lpType)) { if (!SzToWz(pszTmpBuffer, (WCHAR*)lpData, (*lpcbData)/sizeof(WCHAR))) { lReturn = ERROR_NOT_ENOUGH_MEMORY; } else { *lpcbData = (lstrlenAU((WCHAR*)lpData) + 1) * sizeof(WCHAR); } } else if (REG_MULTI_SZ == *lpType) { // // We currently don't have the parsing logic to convert a Multi_SZ. // Since CM doesn't query any keys that return this type, this shouldn't // be a problem. However, someday we may need to fill in this code. For // now, just assert. // CMASSERTMSG(FALSE, TEXT("RegQueryValueExAU -- Converion and Parsing code for REG_MULTI_SZ UNIMPLEMENTED.")); lReturn = ERROR_CALL_NOT_IMPLEMENTED; // closest I could find to E_NOTIMPL } else { // // Non - text data, nothing to convert so just copy it over // *lpcbData = dwTemp; memcpy(lpData, pszTmpBuffer, dwTemp); } } else { *lpcbData = dwTemp; } CmFree (pszTmpBuffer); } } CmFree(pszAnsiValueName); // CMASSERTMSG(ERROR_SUCCESS == lReturn, TEXT("RegOpenKeyExAU Failed.")); return lReturn; } //+---------------------------------------------------------------------------- // // Function: RegSetValueExAU // // Synopsis: Unicode to Ansi wrapper for the win32 RegSetValueEx API. Note that // this wrapper doesn't support writing REG_MULTI_SZ, this code will // have to be implemented if we ever need it. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LONG APIENTRY RegSetValueExAU(IN HKEY hKey, IN LPCWSTR lpValueName, IN DWORD Reserved, IN DWORD dwType, IN CONST BYTE* lpData, IN DWORD cbData) { LONG lReturn = ERROR_INVALID_PARAMETER; if (lpData) { LPSTR pszAnsiValueName = (lpValueName && lpValueName[0]) ? WzToSzWithAlloc(lpValueName) : NULL; LPSTR pszTmpData = NULL; DWORD dwTmpCbData; if (pszAnsiValueName || !lpValueName || (TEXT('\0') == lpValueName[0])) { if ((REG_EXPAND_SZ == dwType) || (REG_SZ == dwType)) { pszTmpData = WzToSzWithAlloc((WCHAR*)lpData); if (pszTmpData) { dwTmpCbData = lstrlenA(pszTmpData) + 1; } else { lReturn = ERROR_NOT_ENOUGH_MEMORY; } } else if (REG_MULTI_SZ == dwType) { // We currently don't have the parsing logic to convert a Multi_SZ. // Since CM doesn't set any keys that use this type, this shouldn't // be a problem. However, someday we may need to fill in this code. For // now, just assert. // CMASSERTMSG(FALSE, TEXT("RegSetValueExAU -- Converion and Parsing code for REG_MULTI_SZ UNIMPLEMENTED.")); lReturn = ERROR_CALL_NOT_IMPLEMENTED; // closest I could find to E_NOTIMPL } else { // // No text data, leave the buffer alone // pszTmpData = (LPSTR)lpData; dwTmpCbData = cbData; } if (pszTmpData) { lReturn = RegSetValueExA(hKey, pszAnsiValueName, Reserved, dwType, (LPBYTE)pszTmpData, dwTmpCbData); if ((REG_EXPAND_SZ == dwType) || (REG_SZ == dwType)) { CmFree(pszTmpData); } } CmFree(pszAnsiValueName); } else { lReturn = ERROR_NOT_ENOUGH_MEMORY; } } return lReturn; } //+---------------------------------------------------------------------------- // // Function: SearchPathAU // // Synopsis: Unicode to Ansi wrapper for the win32 SearchPath API. Note that // this wrapper uses wcsrchr to fix up the lpFilePart parameter in // the converted return buffer. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- DWORD WINAPI SearchPathAU(IN LPCWSTR lpPath, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart) { DWORD dwReturn = ERROR_INVALID_PARAMETER; if (lpFileName && (L'\0' != lpFileName[0])) { CHAR szAnsiPath[MAX_PATH+1]; CHAR szAnsiFileName[MAX_PATH+1]; CHAR szAnsiExt[MAX_PATH+1]; LPSTR pszAnsiPath; LPSTR pszAnsiExt; int iChars; // // Convert the path if it exists // if (lpPath && (L'\0' != lpPath[0])) { pszAnsiPath = szAnsiPath; MYVERIFY(0 != WzToSz(lpPath, pszAnsiPath, MAX_PATH)); } else { pszAnsiPath = NULL; } // // Convert the extension if it exists // if (lpExtension && (L'\0' != lpExtension[0])) { pszAnsiExt = szAnsiExt; MYVERIFY(0 != WzToSz(lpExtension, pszAnsiExt, MAX_PATH)); } else { pszAnsiExt = NULL; } // // Convert the file name, which must exist // iChars = WzToSz(lpFileName, szAnsiFileName, MAX_PATH); if (iChars && (MAX_PATH >= iChars)) { LPSTR pszAnsiBuffer = (LPSTR)CmMalloc(nBufferLength); if (pszAnsiBuffer) { dwReturn = SearchPathA(pszAnsiPath, szAnsiFileName, pszAnsiExt, nBufferLength, pszAnsiBuffer, NULL); if (dwReturn && lpBuffer) { // // We have a successful search. Now convert the output buffer // iChars = SzToWz(pszAnsiBuffer, lpBuffer, nBufferLength); if (!iChars || (nBufferLength < (DWORD)iChars)) { dwReturn = ERROR_NOT_ENOUGH_MEMORY; } else { // // Fix up lpFilePart // if (lpFilePart) { // // Find the last slash // *lpFilePart = wcsrchr(lpBuffer, L'\\'); if (*lpFilePart) { // // Increment // (*lpFilePart)++; } } } } CmFree(pszAnsiBuffer); } } } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: SendDlgItemMessageAU // // Synopsis: Unicode to Ansi wrapper for the win32 SendDlgItemMessage API. Note that // this wrapper uses GetDlgItem and SendMessage just as the Win32 // implementation of the API does. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LONG_PTR WINAPI SendDlgItemMessageAU(HWND hDlg, int nIDDlgItem, UINT Msg, WPARAM wParam, LPARAM lParam) { LONG lReturn = 0; HWND hWnd = GetDlgItem(hDlg, nIDDlgItem); if (hWnd) { // // Rather than going through SendDlgItemMessageA, we just // do what the system does, i.e., go through // SendMessage // lReturn = SendMessageAU(hWnd, Msg, wParam, lParam); } return lReturn; } //+---------------------------------------------------------------------------- // // Function: SendMessageAU // // Synopsis: Unicode to Ansi wrapper for the win32 SendMessage API. This // wrapper attempts to handle all of the Windows Messages that // need conversion, either before the message is sent or after it // returns. Obviously this is an inexact science. I have checked // and tested all of the message types currently in CM but new ones // may be added at some point. I owe much of this function to // F. Avery Bishop and his sample code. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- LRESULT WINAPI SendMessageAU(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { LRESULT lResult = 0; LPVOID lpTempBuffer = NULL; int nLength = 0; CHAR cCharA[3] ; WCHAR cCharW[3] ; // // Preprocess messages that pass chars and strings via wParam and lParam // switch (Msg) { // // Single Unicode Character in wParam. Convert Unicode character // to ANSI and pass lParam as is. // case EM_SETPASSWORDCHAR: // wParam is char, lParam = 0 case WM_CHAR: //*wParam is char, lParam = key data case WM_SYSCHAR: // wParam is char, lParam = key data // Note that we don't handle LeadByte and TrailBytes for // these two cases. An application should send WM_IME_CHAR // in these cases anyway case WM_DEADCHAR: // wParam is char, lParam = key data case WM_SYSDEADCHAR: // wParam is char, lParam = key data case WM_IME_CHAR: //* cCharW[0] = (WCHAR) wParam ; cCharW[1] = L'\0' ; if (!WzToSz(cCharW, cCharA, 3)) { return FALSE; } if(Msg == WM_IME_CHAR) { wParam = (cCharA[1] & 0x00FF) | (cCharA[0] << 8); } else { wParam = cCharA[0]; } wParam &= 0x0000FFFF; break; // // In the following cases, lParam is pointer to an IN buffer containing // text to send to window. // Preprocess by converting from Unicode to ANSI // case CB_ADDSTRING: // wParam = 0, lParm = lpStr, buffer to add case LB_ADDSTRING: // wParam = 0, lParm = lpStr, buffer to add case CB_DIR: // wParam = file attributes, lParam = lpszFileSpec buffer case LB_DIR: // wParam = file attributes, lParam = lpszFileSpec buffer case CB_FINDSTRING: // wParam = start index, lParam = lpszFind case LB_FINDSTRING: // wParam = start index, lParam = lpszFind case CB_FINDSTRINGEXACT: // wParam = start index, lParam = lpszFind case LB_FINDSTRINGEXACT: // wParam = start index, lParam = lpszFind case CB_INSERTSTRING: //*wParam = index, lParam = lpszString to insert case LB_INSERTSTRING: //*wParam = index, lParam = lpszString to insert case CB_SELECTSTRING: // wParam = start index, lParam = lpszFind case LB_SELECTSTRING: // wParam = start index, lParam = lpszFind case WM_SETTEXT: //*wParam = 0, lParm = lpStr, buffer to set { if (NULL != (LPWSTR) lParam) { nLength = 2*lstrlenAU((LPWSTR)lParam) + 1; // Need double length for DBCS characters lpTempBuffer = (LPVOID)CmMalloc(nLength); } if (!lpTempBuffer || (!WzToSz((LPWSTR)lParam, (LPSTR)lpTempBuffer, nLength))) { CmFree(lpTempBuffer); return FALSE; } lParam = (LPARAM) lpTempBuffer; break ; } } // This is where the actual SendMessage takes place lResult = SendMessageA(hWnd, Msg, wParam, lParam) ; nLength = 0; if(lResult > 0) { switch (Msg) { // // For these cases, lParam is a pointer to an OUT buffer that received text from // SendMessageA in ANSI. Convert to Unicode and send back. // case WM_GETTEXT: // wParam = numCharacters, lParam = lpBuff to RECEIVE string case WM_ASKCBFORMATNAME: // wParam = nBufferSize, lParam = lpBuff to RECEIVE string nLength = (int) wParam; if(!nLength) { break; } case CB_GETLBTEXT: // wParam = index, lParam = lpBuff to RECEIVE string case EM_GETLINE: // wParam = Line no, lParam = lpBuff to RECEIVE string if(!nLength) { nLength = lstrlenA((LPSTR) lParam) + 1 ; } lpTempBuffer = (LPVOID) CmMalloc(nLength*sizeof(WCHAR)); if(!lpTempBuffer || (!SzToWz((LPCSTR) lParam, (LPWSTR) lpTempBuffer, nLength))) { *((LPWSTR) lParam) = L'\0'; CmFree(lpTempBuffer); return FALSE; } lstrcpyAU((LPWSTR) lParam, (LPWSTR) lpTempBuffer) ; } } if(lpTempBuffer != NULL) { CmFree(lpTempBuffer); } return lResult; } //+---------------------------------------------------------------------------- // // Function: SetCurrentDirectoryAU // // Synopsis: Unicode to Ansi wrapper for the win32 SetCurrentDirectory API. // Note that we expect the directory path to fit in MAX_PATH chars. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL SetCurrentDirectoryAU(LPCWSTR pszwPathName) { BOOL bReturn = FALSE; if (pszwPathName && (L'\0' != pszwPathName[0])) { CHAR szAnsiPath[MAX_PATH+1]; int iChars = WzToSz(pszwPathName, szAnsiPath, MAX_PATH); if (iChars && (MAX_PATH >= iChars)) { bReturn = SetCurrentDirectoryA(szAnsiPath); } } return bReturn; } //+---------------------------------------------------------------------------- // // Function: SetDlgItemTextAU // // Synopsis: Unicode to Ansi wrapper for the win32 SetDlgItemText API. // This function calls SendMessageAU with a WM_SETTEXT and the // appropriate Dialog Item from GetDlgItem. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL WINAPI SetDlgItemTextAU(IN HWND hDlg, IN int nIDDlgItem, IN LPCWSTR pszwString) { return (BOOL) (0 < SendMessageAU(GetDlgItem(hDlg, nIDDlgItem), WM_SETTEXT, (WPARAM) 0, (LPARAM) pszwString)); } //+---------------------------------------------------------------------------- // // Function: SetWindowTextAU // // Synopsis: Unicode to Ansi wrapper for the win32 SetWindowText API. // This function calls SendMessageAU with a WM_SETTEXT. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL WINAPI SetWindowTextAU(HWND hWnd, LPCWSTR pszwString) { return (BOOL) (0 < SendMessageAU(hWnd, WM_SETTEXT, 0, (LPARAM) pszwString)); } //+---------------------------------------------------------------------------- // // Function: UnregisterClassAU // // Synopsis: Unicode to Ansi wrapper for the win32 UnregisterClass API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL WINAPI UnregisterClassAU(IN LPCWSTR lpClassName, IN HINSTANCE hInstance) { BOOL bReturn = FALSE; if (lpClassName) { LPSTR pszAnsiClassName = WzToSzWithAlloc(lpClassName); if (pszAnsiClassName) { bReturn = UnregisterClassA(pszAnsiClassName, hInstance); } CmFree(pszAnsiClassName); } return bReturn; } //+---------------------------------------------------------------------------- // // Function: WinHelpAU // // Synopsis: Unicode to Ansi wrapper for the win32 WinHelp API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL WINAPI WinHelpAU(IN HWND hWndMain, IN LPCWSTR lpszHelp, IN UINT uCommand, IN ULONG_PTR dwData) { BOOL bReturn = FALSE; if (lpszHelp) { LPSTR pszAnsiHelp = WzToSzWithAlloc(lpszHelp); if (pszAnsiHelp) { bReturn = WinHelpA(hWndMain, pszAnsiHelp, uCommand, dwData); } CmFree(pszAnsiHelp); } return bReturn; } //+---------------------------------------------------------------------------- // // Function: WritePrivateProfileStringAU // // Synopsis: Unicode to Ansi wrapper for the win32 WritePrivateProfileString API. // Note that we expect lpAppName, lpKeyName, and lpFileName to all // fit in MAX_PATH chars. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL WINAPI WritePrivateProfileStringAU(IN LPCWSTR lpAppName, IN LPCWSTR lpKeyName, IN LPCWSTR lpString, IN LPCWSTR lpFileName) { BOOL bReturn = FALSE; // // Check inputs, but note that either lpKeyName or lpString could be NULL // if (lpAppName && lpFileName) { CHAR szAnsiAppName[MAX_PATH+1]; CHAR szAnsiFileName[MAX_PATH+1]; CHAR szAnsiKeyName[MAX_PATH+1]; LPSTR pszAnsiKeyName = NULL; LPSTR pszAnsiString; if (WzToSz(lpAppName, szAnsiAppName, MAX_PATH)) { if (WzToSz(lpFileName, szAnsiFileName, MAX_PATH)) { if (lpKeyName) { pszAnsiKeyName = szAnsiKeyName; WzToSz(lpKeyName, pszAnsiKeyName, MAX_PATH); } // else pszAnsiKeyName was already init-ed to NULL if (pszAnsiKeyName || !lpKeyName) { pszAnsiString = lpString ? WzToSzWithAlloc(lpString) : NULL; if (pszAnsiString || (!lpString)) { bReturn = WritePrivateProfileStringA(szAnsiAppName, pszAnsiKeyName, pszAnsiString, szAnsiFileName); CmFree(pszAnsiString); } } } } } else { SetLastError(ERROR_INVALID_PARAMETER); } CMASSERTMSG(bReturn, TEXT("WritePrivateProfileStringAU Failed.")); return bReturn; } //+---------------------------------------------------------------------------- // // Function: wsprintfAU // // Synopsis: Unicode to Ansi wrapper for the win32 wsprintf API. // Note that it uses a va_list and calls wvsprintfAU. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- int WINAPIV wsprintfAU(OUT LPWSTR pszwDest, IN LPCWSTR pszwFmt, ...) { va_list arglist; int ret; va_start(arglist, pszwFmt); ret = wvsprintfAU(pszwDest, pszwFmt, arglist); va_end(arglist); return ret; } //+---------------------------------------------------------------------------- // // Function: wvsprintfAU // // Synopsis: Unicode to Ansi wrapper for the win32 wvsprintf API. In order to // avoid parsing the format string to convert the %s to %S and the // %c to %C and then calling wvsprintfA, which is originally how this // function was written but which isn't really very safe because // we don't know the size of the Dest buffer, we will call the // C runtime function vswprintf to directly handle a Unicode string. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 6/24/99 // quintinb Changed algorithm to use // the C runtime vswprintf 02/05/00 // //+---------------------------------------------------------------------------- int WINAPI wvsprintfAU(OUT LPWSTR pszwDest, IN LPCWSTR pszwFmt, IN va_list arglist) { int iReturn = 0; if (pszwDest && pszwFmt) { // // Use the C runtime version of the function // iReturn = vswprintf(pszwDest, pszwFmt, arglist); } return iReturn; } //+---------------------------------------------------------------------------- // // Function: InitCmUToA // // Synopsis: This function is called once cmutoa.dll is loaded. It will init // the passed in UAPIINIT struct with the appropriate function pointers. // // Arguments: PUAPIINIT pUAInit -- pointer to a UAInit struct which contains memory // for all the requested function pointers. // // Returns: BOOL -- always returns TRUE // // History: quintinb Created 6/24/99 // //+---------------------------------------------------------------------------- BOOL InitCmUToA(PUAPIINIT pUAInit) { // // Note that we don't need any translation here, the prototype is the same for A or W // *(pUAInit->pCallWindowProcU) = CallWindowProcA; *(pUAInit->pDefWindowProcU) = DefWindowProcA; *(pUAInit->pDispatchMessageU) = DispatchMessageA; *(pUAInit->pGetClassLongU) = GetClassLongA; *(pUAInit->pGetMessageU) = GetMessageA; *(pUAInit->pGetWindowLongU) = GetWindowLongA; *(pUAInit->pGetWindowTextLengthU) = GetWindowTextLengthA; *(pUAInit->pIsDialogMessageU) = IsDialogMessageA; *(pUAInit->pPeekMessageU) = PeekMessageA; *(pUAInit->pPostMessageU) = PostMessageA; *(pUAInit->pPostThreadMessageU) = PostThreadMessageA; *(pUAInit->pSetWindowLongU) = SetWindowLongA; // // Whereas we need wrappers here to do parameter conversion here // *(pUAInit->pCharLowerU) = CharLowerAU; *(pUAInit->pCharNextU) = CharNextAU; *(pUAInit->pCharPrevU) = CharPrevAU; *(pUAInit->pCharUpperU) = CharUpperAU; *(pUAInit->pCreateDialogParamU) = CreateDialogParamAU; *(pUAInit->pCreateDirectoryU) = CreateDirectoryAU; *(pUAInit->pCreateEventU) = CreateEventAU; *(pUAInit->pCreateFileU) = CreateFileAU; *(pUAInit->pCreateFileMappingU) = CreateFileMappingAU; *(pUAInit->pCreateMutexU) = CreateMutexAU; *(pUAInit->pCreateProcessU) = CreateProcessAU; *(pUAInit->pCreateWindowExU) = CreateWindowExAU; *(pUAInit->pDeleteFileU) = DeleteFileAU; *(pUAInit->pDialogBoxParamU) = DialogBoxParamAU; *(pUAInit->pExpandEnvironmentStringsU) = ExpandEnvironmentStringsAU; *(pUAInit->pFindResourceExU) = FindResourceExAU; *(pUAInit->pFindWindowExU) = FindWindowExAU; *(pUAInit->pGetDateFormatU) = GetDateFormatAU; *(pUAInit->pGetDlgItemTextU) = GetDlgItemTextAU; *(pUAInit->pGetFileAttributesU) = GetFileAttributesAU; *(pUAInit->pGetModuleFileNameU) = GetModuleFileNameAU; *(pUAInit->pGetModuleHandleU) = GetModuleHandleAU; *(pUAInit->pGetPrivateProfileIntU) = GetPrivateProfileIntAU; *(pUAInit->pGetPrivateProfileStringU) = GetPrivateProfileStringAU; *(pUAInit->pGetStringTypeExU) = GetStringTypeExAU; *(pUAInit->pGetSystemDirectoryU) = GetSystemDirectoryAU; *(pUAInit->pGetTempFileNameU) = GetTempFileNameAU; *(pUAInit->pGetTempPathU) = GetTempPathAU; *(pUAInit->pGetTimeFormatU) = GetTimeFormatAU; *(pUAInit->pGetUserNameU) = GetUserNameAU; *(pUAInit->pGetVersionExU) = GetVersionExAU; *(pUAInit->pGetWindowTextU) = GetWindowTextAU; *(pUAInit->pInsertMenuU) = InsertMenuAU; *(pUAInit->pLoadCursorU) = LoadCursorAU; *(pUAInit->pLoadIconU) = LoadIconAU; *(pUAInit->pLoadImageU) = LoadImageAU; *(pUAInit->pLoadLibraryExU) = LoadLibraryExAU; *(pUAInit->pLoadMenuU) = LoadMenuAU; *(pUAInit->pLoadStringU) = LoadStringAU; *(pUAInit->plstrcatU) = lstrcatAU; *(pUAInit->plstrcmpU) = lstrcmpAU; *(pUAInit->plstrcmpiU) = lstrcmpiAU; *(pUAInit->plstrcpyU) = lstrcpyAU; *(pUAInit->plstrcpynU) = lstrcpynAU; *(pUAInit->plstrlenU) = lstrlenAU; *(pUAInit->pOpenEventU) = OpenEventAU; *(pUAInit->pOpenFileMappingU) = OpenFileMappingAU; *(pUAInit->pRegCreateKeyExU) = RegCreateKeyExAU; *(pUAInit->pRegDeleteKeyU) = RegDeleteKeyAU; *(pUAInit->pRegDeleteValueU) = RegDeleteValueAU; *(pUAInit->pRegEnumKeyExU) = RegEnumKeyExAU; *(pUAInit->pRegisterClassExU) = RegisterClassExAU; *(pUAInit->pRegisterWindowMessageU) = RegisterWindowMessageAU; *(pUAInit->pRegOpenKeyExU) = RegOpenKeyExAU; *(pUAInit->pRegQueryValueExU) = RegQueryValueExAU; *(pUAInit->pRegSetValueExU) = RegSetValueExAU; *(pUAInit->pSearchPathU) = SearchPathAU; *(pUAInit->pSendDlgItemMessageU) = SendDlgItemMessageAU; *(pUAInit->pSendMessageU) = SendMessageAU; *(pUAInit->pSetCurrentDirectoryU) = SetCurrentDirectoryAU; *(pUAInit->pSetDlgItemTextU) = SetDlgItemTextAU; *(pUAInit->pSetWindowTextU) = SetWindowTextAU; *(pUAInit->pUnregisterClassU) = UnregisterClassAU; *(pUAInit->pWinHelpU) = WinHelpAU; *(pUAInit->pWritePrivateProfileStringU) = WritePrivateProfileStringAU; *(pUAInit->pwsprintfU) = wsprintfAU; *(pUAInit->pwvsprintfU) = wvsprintfAU; // // Currently this always returns TRUE because none of the above can really // fail. However, in the future we may need more of a meaningful return // value here. // return TRUE; } //+---------------------------------------------------------------------------- // // Function: RasDeleteEntryUA // // Synopsis: Unicode to Ansi wrapper for the win32 RasDeleteEntry API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- DWORD APIENTRY RasDeleteEntryUA(LPCWSTR pszwPhoneBook, LPCWSTR pszwEntry) { DWORD dwReturn = ERROR_INVALID_PARAMETER; // // The phonebook should always be NULL on win9x // MYDBGASSERT(NULL == pszwPhoneBook); RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); MYDBGASSERT(NULL != pAnsiRasLinkage); MYDBGASSERT(NULL != pAnsiRasLinkage->pfnDeleteEntry); if (pszwEntry && pAnsiRasLinkage && pAnsiRasLinkage->pfnDeleteEntry) { CHAR szAnsiEntry [RAS_MaxEntryName + 1]; int iChars = WzToSz(pszwEntry, szAnsiEntry, RAS_MaxEntryName); if (iChars && (RAS_MaxEntryName >= iChars)) { dwReturn = pAnsiRasLinkage->pfnDeleteEntry(NULL, szAnsiEntry); } } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: RasGetEntryPropertiesUA // // Synopsis: Unicode to Ansi wrapper for the win32 RasGetEntryProperties API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- DWORD APIENTRY RasGetEntryPropertiesUA(LPCWSTR pszwPhoneBook, LPCWSTR pszwEntry, LPRASENTRYW pRasEntryW, LPDWORD pdwEntryInfoSize, LPBYTE pbDeviceInfo, LPDWORD pdwDeviceInfoSize) { DWORD dwReturn = ERROR_INVALID_PARAMETER; // // The phonebook should always be NULL on win9x // MYDBGASSERT(NULL == pszwPhoneBook); MYDBGASSERT(NULL == pbDeviceInfo); // We don't use or handle this TAPI param. If we need it, // conversion must be implemented. RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); MYDBGASSERT(NULL != pAnsiRasLinkage); MYDBGASSERT(NULL != pAnsiRasLinkage->pfnGetEntryProperties); if (pszwEntry && pdwEntryInfoSize && pAnsiRasLinkage && pAnsiRasLinkage->pfnGetEntryProperties) { CHAR szAnsiEntry [RAS_MaxEntryName + 1]; RASENTRYA RasEntryA; DWORD dwTmpEntrySize = sizeof(RASENTRYA); ZeroMemory(&RasEntryA, sizeof(RASENTRYA)); int iChars = WzToSz(pszwEntry, szAnsiEntry, RAS_MaxEntryName); if (iChars && (RAS_MaxEntryName >= iChars)) { dwReturn = pAnsiRasLinkage->pfnGetEntryProperties(NULL, szAnsiEntry, &RasEntryA, &dwTmpEntrySize, NULL, NULL); if ((ERROR_SUCCESS == dwReturn) && pRasEntryW) { // // Do conversion of RASENTRYA to RASENTRYW // // pRasEntryW->dwSize -- this param should already be set pRasEntryW->dwfOptions = RasEntryA.dwfOptions; // // Location/phone number. // pRasEntryW->dwCountryID = RasEntryA.dwCountryID; pRasEntryW->dwCountryCode = RasEntryA.dwCountryCode; MYVERIFY(0 != SzToWz(RasEntryA.szAreaCode, pRasEntryW->szAreaCode, RAS_MaxAreaCode)); MYVERIFY(0 != SzToWz(RasEntryA.szLocalPhoneNumber, pRasEntryW->szLocalPhoneNumber, RAS_MaxPhoneNumber)); pRasEntryW->dwAlternateOffset = RasEntryA.dwAlternateOffset; // // PPP/Ip // memcpy(&(pRasEntryW->ipaddr), &(RasEntryA.ipaddr), sizeof(RASIPADDR)); memcpy(&(pRasEntryW->ipaddrDns), &(RasEntryA.ipaddrDns), sizeof(RASIPADDR)); memcpy(&(pRasEntryW->ipaddrDnsAlt), &(RasEntryA.ipaddrDnsAlt), sizeof(RASIPADDR)); memcpy(&(pRasEntryW->ipaddrWins), &(RasEntryA.ipaddrWins), sizeof(RASIPADDR)); memcpy(&(pRasEntryW->ipaddrWinsAlt), &(RasEntryA.ipaddrWinsAlt), sizeof(RASIPADDR)); // // Framing // pRasEntryW->dwFrameSize = RasEntryA.dwFrameSize; pRasEntryW->dwfNetProtocols = RasEntryA.dwfNetProtocols; pRasEntryW->dwFramingProtocol = RasEntryA.dwFramingProtocol; // // Scripting // MYVERIFY(0 != SzToWz(RasEntryA.szScript, pRasEntryW->szScript, MAX_PATH)); // // AutoDial // MYVERIFY(0 != SzToWz(RasEntryA.szAutodialDll, pRasEntryW->szAutodialDll, MAX_PATH)); MYVERIFY(0 != SzToWz(RasEntryA.szAutodialFunc, pRasEntryW->szAutodialFunc, MAX_PATH)); // // Device // MYVERIFY(0 != SzToWz(RasEntryA.szDeviceType, pRasEntryW->szDeviceType, RAS_MaxDeviceType)); MYVERIFY(0 != SzToWz(RasEntryA.szDeviceName, pRasEntryW->szDeviceName, RAS_MaxDeviceName)); // // X.25 -- we don't use x25 // pRasEntryW->szX25PadType[0] = L'\0'; pRasEntryW->szX25Address[0] = L'\0'; pRasEntryW->szX25Facilities[0] = L'\0'; pRasEntryW->szX25UserData[0] = L'\0'; pRasEntryW->dwChannels = 0; // // Reserved // pRasEntryW->dwReserved1 = RasEntryA.dwReserved1; pRasEntryW->dwReserved2 = RasEntryA.dwReserved2; } else if ((ERROR_BUFFER_TOO_SMALL == dwReturn) || !pRasEntryW) { // // We don't know the actual size since we are passing a RASENTRYA, but // the user only knows about RASENTRYW. Thus double the returned size. // *pdwEntryInfoSize = 2*dwTmpEntrySize; } } } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: RasSetEntryPropertiesUA // // Synopsis: Unicode to Ansi wrapper for the win32 RasSetEntryProperties API. // Note that we do not support the pbDeviceInfo // parameter, if you need it you will have to implement it. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- DWORD APIENTRY RasSetEntryPropertiesUA(LPCWSTR pszwPhoneBook, LPCWSTR pszwEntry, LPRASENTRYW pRasEntryW, DWORD dwEntryInfoSize, LPBYTE pbDeviceInfo, DWORD dwDeviceInfoSize) { DWORD dwReturn = ERROR_INVALID_PARAMETER; // // We don't use or handle this TAPI param. If we need it, conversion must be implemented. // Note that 1 is a special value for Windows Millennium (see Millennium bug 127371) // MYDBGASSERT((NULL == pbDeviceInfo) || ((LPBYTE)1 == pbDeviceInfo)); RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); MYDBGASSERT(NULL != pAnsiRasLinkage); MYDBGASSERT(NULL != pAnsiRasLinkage->pfnSetEntryProperties); if (pszwEntry && dwEntryInfoSize && pRasEntryW && pAnsiRasLinkage && pAnsiRasLinkage->pfnSetEntryProperties) { // // The phonebook should always be NULL on Win9x. // MYDBGASSERT(NULL == pszwPhoneBook); CHAR szAnsiEntry [RAS_MaxEntryName + 1]; int iChars = WzToSz(pszwEntry, szAnsiEntry, RAS_MaxEntryName); if (iChars && (RAS_MaxEntryName >= iChars)) { // // Figure out the correct size to use // MYDBGASSERT((sizeof(RASENTRYW) == pRasEntryW->dwSize) ||(sizeof(RASENTRYW_V401) == pRasEntryW->dwSize)); DWORD dwSize; if ((sizeof (RASENTRYW_V401) == pRasEntryW->dwSize) && OS_MIL) { // // Millennium uses the NT4 structure size // dwSize = sizeof(RASENTRYA_V401); } else { dwSize = sizeof(RASENTRYA); } // // Allocate the RasEntryStructure // LPRASENTRYA pAnsiRasEntry = (LPRASENTRYA)CmMalloc(dwSize); if (pAnsiRasEntry) { // // Do conversion of RASENTRYA to RASENTRYW // pAnsiRasEntry->dwSize = dwSize; pAnsiRasEntry->dwfOptions = pRasEntryW->dwfOptions; // // Location/phone number. // pAnsiRasEntry->dwCountryID = pRasEntryW->dwCountryID; pAnsiRasEntry->dwCountryCode = pRasEntryW->dwCountryCode; MYVERIFY(0 != WzToSz(pRasEntryW->szAreaCode, pAnsiRasEntry->szAreaCode, RAS_MaxAreaCode)); MYVERIFY(0 != WzToSz(pRasEntryW->szLocalPhoneNumber, pAnsiRasEntry->szLocalPhoneNumber, RAS_MaxPhoneNumber)); CMASSERTMSG(0 == pRasEntryW->dwAlternateOffset, TEXT("RasSetEntryPropertiesUA -- dwAlternateOffset != 0 is not supported. This will need to be implemented if used.")); pAnsiRasEntry->dwAlternateOffset = 0; // // PPP/Ip // memcpy(&(pAnsiRasEntry->ipaddr), &(pRasEntryW->ipaddr), sizeof(RASIPADDR)); memcpy(&(pAnsiRasEntry->ipaddrDns), &(pRasEntryW->ipaddrDns), sizeof(RASIPADDR)); memcpy(&(pAnsiRasEntry->ipaddrDnsAlt), &(pRasEntryW->ipaddrDnsAlt), sizeof(RASIPADDR)); memcpy(&(pAnsiRasEntry->ipaddrWins), &(pRasEntryW->ipaddrWins), sizeof(RASIPADDR)); memcpy(&(pAnsiRasEntry->ipaddrWinsAlt), &(pRasEntryW->ipaddrWinsAlt), sizeof(RASIPADDR)); // // Framing // pAnsiRasEntry->dwFrameSize = pRasEntryW->dwFrameSize; pAnsiRasEntry->dwfNetProtocols = pRasEntryW->dwfNetProtocols; pAnsiRasEntry->dwFramingProtocol = pRasEntryW->dwFramingProtocol; // // Scripting // MYVERIFY(0 != WzToSz(pRasEntryW->szScript, pAnsiRasEntry->szScript, MAX_PATH)); // // AutoDial // MYVERIFY(0 != WzToSz(pRasEntryW->szAutodialDll, pAnsiRasEntry->szAutodialDll, MAX_PATH)); MYVERIFY(0 != WzToSz(pRasEntryW->szAutodialFunc, pAnsiRasEntry->szAutodialFunc, MAX_PATH)); // // Device // MYVERIFY(0 != WzToSz(pRasEntryW->szDeviceType, pAnsiRasEntry->szDeviceType, RAS_MaxDeviceType)); MYVERIFY(0 != WzToSz(pRasEntryW->szDeviceName, pAnsiRasEntry->szDeviceName, RAS_MaxDeviceName)); // // X.25 -- we don't use x25 // pAnsiRasEntry->szX25PadType[0] = '\0'; pAnsiRasEntry->szX25Address[0] = '\0'; pAnsiRasEntry->szX25Facilities[0] = '\0'; pAnsiRasEntry->szX25UserData[0] = '\0'; pAnsiRasEntry->dwChannels = 0; // // Reserved // pAnsiRasEntry->dwReserved1 = pRasEntryW->dwReserved1; pAnsiRasEntry->dwReserved2 = pRasEntryW->dwReserved2; if (sizeof(RASENTRYA_V401) == dwSize) { // // Copy over the 4.01 data // LPRASENTRYA_V401 pAnsi401RasEntry = (LPRASENTRYA_V401)pAnsiRasEntry; LPRASENTRYW_V401 pWide401RasEntry = (LPRASENTRYW_V401)pRasEntryW; pAnsi401RasEntry->dwSubEntries = pWide401RasEntry->dwSubEntries; pAnsi401RasEntry->dwDialMode = pWide401RasEntry->dwDialMode; pAnsi401RasEntry->dwDialExtraPercent = pWide401RasEntry->dwDialExtraPercent; pAnsi401RasEntry->dwDialExtraSampleSeconds = pWide401RasEntry->dwDialExtraSampleSeconds; pAnsi401RasEntry->dwHangUpExtraPercent = pWide401RasEntry->dwHangUpExtraPercent; pAnsi401RasEntry->dwHangUpExtraSampleSeconds = pWide401RasEntry->dwHangUpExtraSampleSeconds; pAnsi401RasEntry->dwIdleDisconnectSeconds = pWide401RasEntry->dwIdleDisconnectSeconds; } dwReturn = pAnsiRasLinkage->pfnSetEntryProperties(NULL, szAnsiEntry, pAnsiRasEntry, pAnsiRasEntry->dwSize, pbDeviceInfo, 0); CmFree(pAnsiRasEntry); } } } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: RasDialParamsWtoRasDialParamsA // // Synopsis: Wrapper function to handle converting a RasDialParamsW struct to // a RasDialParamsA Struct. Used by RasSetEntryDialParamsUA and // RasDialUA. // // Arguments: LPRASDIALPARAMSW pRdpW - pointer to a RasDialParamsW // LPRASDIALPARAMSA pRdpA - pointer to a RasDialParamsA // // Returns: Nothing // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- void RasDialParamsWtoRasDialParamsA (LPRASDIALPARAMSW pRdpW, LPRASDIALPARAMSA pRdpA) { pRdpA->dwSize = sizeof(RASDIALPARAMSA); MYVERIFY(0 != WzToSz(pRdpW->szEntryName, pRdpA->szEntryName, RAS_MaxEntryName)); MYVERIFY(0 != WzToSz(pRdpW->szPhoneNumber, pRdpA->szPhoneNumber, RAS_MaxPhoneNumber)); MYVERIFY(0 != WzToSz(pRdpW->szCallbackNumber, pRdpA->szCallbackNumber, RAS_MaxCallbackNumber)); MYVERIFY(0 != WzToSz(pRdpW->szUserName, pRdpA->szUserName, UNLEN)); MYVERIFY(0 != WzToSz(pRdpW->szPassword, pRdpA->szPassword, PWLEN)); MYVERIFY(0 != WzToSz(pRdpW->szDomain, pRdpA->szDomain, DNLEN)); } //+---------------------------------------------------------------------------- // // Function: RasDialParamsAtoRasDialParamsW // // Synopsis: Wrapper function to handle converting a RasDialParamsA struct to // a RasDialParamsW Struct. Used by RasGetEntryDialParamsUA. // // Arguments: LPRASDIALPARAMSW pRdpA - pointer to a RasDialParamsA // LPRASDIALPARAMSA pRdpW - pointer to a RasDialParamsW // // Returns: Nothing // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- void RasDialParamsAtoRasDialParamsW (LPRASDIALPARAMSA pRdpA, LPRASDIALPARAMSW pRdpW) { pRdpW->dwSize = sizeof(RASDIALPARAMSW); MYVERIFY(0 != SzToWz(pRdpA->szEntryName, pRdpW->szEntryName, RAS_MaxEntryName)); MYVERIFY(0 != SzToWz(pRdpA->szPhoneNumber, pRdpW->szPhoneNumber, RAS_MaxPhoneNumber)); MYVERIFY(0 != SzToWz(pRdpA->szCallbackNumber, pRdpW->szCallbackNumber, RAS_MaxCallbackNumber)); MYVERIFY(0 != SzToWz(pRdpA->szUserName, pRdpW->szUserName, UNLEN)); MYVERIFY(0 != SzToWz(pRdpA->szPassword, pRdpW->szPassword, PWLEN)); MYVERIFY(0 != SzToWz(pRdpA->szDomain, pRdpW->szDomain, DNLEN)); } //+---------------------------------------------------------------------------- // // Function: RasGetEntryDialParamsUA // // Synopsis: Unicode to Ansi wrapper for the win32 RasGetEntryDialParams API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- DWORD APIENTRY RasGetEntryDialParamsUA(LPCWSTR pszwPhoneBook, LPRASDIALPARAMSW pRasDialParamsW, LPBOOL pbPassword) { DWORD dwReturn = ERROR_BUFFER_INVALID; RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); MYDBGASSERT(NULL != pAnsiRasLinkage); MYDBGASSERT(NULL != pAnsiRasLinkage->pfnGetEntryDialParams); if (pRasDialParamsW && pbPassword && pAnsiRasLinkage && pAnsiRasLinkage->pfnGetEntryDialParams) { // // The phonebook should always be NULL on win9x // MYDBGASSERT(NULL == pszwPhoneBook); RASDIALPARAMSA RasDialParamsA; ZeroMemory(&RasDialParamsA, sizeof(RASDIALPARAMSA)); RasDialParamsA.dwSize = sizeof(RASDIALPARAMSA); int iChars = WzToSz(pRasDialParamsW->szEntryName, RasDialParamsA.szEntryName, RAS_MaxEntryName); if (iChars && (RAS_MaxEntryName >= iChars)) { dwReturn = pAnsiRasLinkage->pfnGetEntryDialParams(NULL, &RasDialParamsA, pbPassword); if (ERROR_SUCCESS == dwReturn) { RasDialParamsAtoRasDialParamsW(&RasDialParamsA, pRasDialParamsW); } } } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: RasSetEntryDialParamsUA // // Synopsis: Unicode to Ansi wrapper for the win32 RasSetEntryDialParams API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- DWORD APIENTRY RasSetEntryDialParamsUA(LPCWSTR pszwPhoneBook, LPRASDIALPARAMSW pRasDialParamsW, BOOL bRemovePassword) { DWORD dwReturn = ERROR_BUFFER_INVALID; RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); MYDBGASSERT(NULL != pAnsiRasLinkage); MYDBGASSERT(NULL != pAnsiRasLinkage->pfnSetEntryDialParams); if (pRasDialParamsW && pAnsiRasLinkage && pAnsiRasLinkage->pfnSetEntryDialParams) { // // The phonebook should always be NULL on win9x // MYDBGASSERT(NULL == pszwPhoneBook); RASDIALPARAMSA RasDialParamsA; RasDialParamsWtoRasDialParamsA (pRasDialParamsW, &RasDialParamsA); dwReturn = pAnsiRasLinkage->pfnSetEntryDialParams(NULL, &RasDialParamsA, bRemovePassword); } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: RasEnumDevicesUA // // Synopsis: Unicode to Ansi wrapper for the win32 RasEnumDevices API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- DWORD RasEnumDevicesUA(LPRASDEVINFOW pRasDevInfo, LPDWORD pdwCb, LPDWORD pdwDevices) { DWORD dwReturn = ERROR_INVALID_PARAMETER; DWORD dwSize; RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); MYDBGASSERT(NULL != pAnsiRasLinkage); MYDBGASSERT(NULL != pAnsiRasLinkage->pfnEnumDevices); if (pdwCb && pdwDevices && pAnsiRasLinkage && pAnsiRasLinkage->pfnEnumDevices) { LPRASDEVINFOA pAnsiDevInfo; if ((NULL == pRasDevInfo) && (0 == *pdwCb)) { // // Then the caller is just trying to size the buffer // dwSize = 0; pAnsiDevInfo = NULL; } else { dwSize = ((*pdwCb)/sizeof(RASDEVINFOW))*sizeof(RASDEVINFOA); pAnsiDevInfo = (LPRASDEVINFOA)CmMalloc(dwSize); if (NULL == pAnsiDevInfo) { return ERROR_NOT_ENOUGH_MEMORY; } pAnsiDevInfo[0].dwSize = sizeof(RASDEVINFOA); } dwReturn = pAnsiRasLinkage->pfnEnumDevices(pAnsiDevInfo, &dwSize, pdwDevices); // // Resize the buffer in terms of RASDEVINFOW structs // *pdwCb = ((dwSize)/sizeof(RASDEVINFOA))*sizeof(RASDEVINFOW); if (ERROR_SUCCESS == dwReturn && pRasDevInfo) { // // Then we need to convert the returned structs // MYDBGASSERT((*pdwDevices)*sizeof(RASDEVINFOW) <= *pdwCb); for (DWORD dwIndex = 0; dwIndex < *pdwDevices; dwIndex++) { MYVERIFY(0 != SzToWz(pAnsiDevInfo[dwIndex].szDeviceType, pRasDevInfo[dwIndex].szDeviceType, RAS_MaxDeviceType)); MYVERIFY(0 != SzToWz(pAnsiDevInfo[dwIndex].szDeviceName, pRasDevInfo[dwIndex].szDeviceName, RAS_MaxDeviceName)); } } // // Free the Ansi buffer // CmFree (pAnsiDevInfo); } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: RasDialUA // // Synopsis: Unicode to Ansi wrapper for the win32 RasDial API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- DWORD APIENTRY RasDialUA(LPRASDIALEXTENSIONS pRasDialExt, LPCWSTR pszwPhoneBook, LPRASDIALPARAMSW pRasDialParamsW, DWORD dwNotifierType, LPVOID pvNotifier, LPHRASCONN phRasConn) { DWORD dwReturn = ERROR_INVALID_PARAMETER; MYDBGASSERT(NULL == pszwPhoneBook); RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); MYDBGASSERT(NULL != pAnsiRasLinkage); MYDBGASSERT(NULL != pAnsiRasLinkage->pfnDial); if (pRasDialParamsW && phRasConn && pAnsiRasLinkage && pAnsiRasLinkage->pfnDial) { RASDIALPARAMSA RasDialParamsA; RasDialParamsWtoRasDialParamsA (pRasDialParamsW, &RasDialParamsA); dwReturn = pAnsiRasLinkage->pfnDial(pRasDialExt, NULL, &RasDialParamsA, dwNotifierType, pvNotifier, phRasConn); } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: RasHangUpUA // // Synopsis: Unicode to Ansi wrapper for the win32 RasHangUp API. Which for // some reason has an ANSI and Unicode form, not sure why. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- DWORD APIENTRY RasHangUpUA(HRASCONN hRasConn) { DWORD dwReturn = ERROR_INVALID_PARAMETER; RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); MYDBGASSERT(NULL != pAnsiRasLinkage); MYDBGASSERT(NULL != pAnsiRasLinkage->pfnHangUp); if (hRasConn && pAnsiRasLinkage && pAnsiRasLinkage->pfnHangUp) { dwReturn = pAnsiRasLinkage->pfnHangUp(hRasConn); } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: RasGetErrorStringUA // // Synopsis: Unicode to Ansi wrapper for the win32 RasGetErrorString API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- DWORD APIENTRY RasGetErrorStringUA(UINT uErrorValue, LPWSTR pszwOutBuf, DWORD dwBufSize) { DWORD dwReturn = ERROR_INVALID_PARAMETER; RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); MYDBGASSERT(NULL != pAnsiRasLinkage); MYDBGASSERT(NULL != pAnsiRasLinkage->pfnGetErrorString); if (pszwOutBuf && dwBufSize && pAnsiRasLinkage && pAnsiRasLinkage->pfnGetErrorString) { LPSTR pszAnsiBuf = (LPSTR)CmMalloc(dwBufSize); if (pszAnsiBuf) { dwReturn = pAnsiRasLinkage->pfnGetErrorString(uErrorValue, pszAnsiBuf, dwBufSize); if (ERROR_SUCCESS == dwReturn) { int iChars = SzToWz(pszAnsiBuf, pszwOutBuf, dwBufSize); if (!iChars || (dwBufSize < (DWORD)iChars)) { dwReturn = ERROR_NOT_ENOUGH_MEMORY; } } } CmFree(pszAnsiBuf); } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: RasGetConnectStatusUA // // Synopsis: Unicode to Ansi wrapper for the win32 RasGetConnectStatus API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- DWORD RasGetConnectStatusUA(HRASCONN hRasConn, LPRASCONNSTATUSW pRasConnStatusW) { DWORD dwReturn = ERROR_INVALID_PARAMETER; RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); MYDBGASSERT(NULL != pAnsiRasLinkage); MYDBGASSERT(NULL != pAnsiRasLinkage->pfnGetConnectStatus); if (pRasConnStatusW && pAnsiRasLinkage && pAnsiRasLinkage->pfnGetConnectStatus) { RASCONNSTATUSA RasConnStatusA; ZeroMemory(&RasConnStatusA, sizeof(RASCONNSTATUSA)); RasConnStatusA.dwSize = sizeof(RASCONNSTATUSA); dwReturn = pAnsiRasLinkage->pfnGetConnectStatus(hRasConn, &RasConnStatusA); if (ERROR_SUCCESS == dwReturn) { pRasConnStatusW->rasconnstate = RasConnStatusA.rasconnstate; pRasConnStatusW->dwError = RasConnStatusA.dwError; int iChars = SzToWz(RasConnStatusA.szDeviceType, pRasConnStatusW->szDeviceType, RAS_MaxDeviceType); if (!iChars || (RAS_MaxDeviceType < iChars)) { dwReturn = ERROR_NOT_ENOUGH_MEMORY; } else { iChars = SzToWz(RasConnStatusA.szDeviceName, pRasConnStatusW->szDeviceName, RAS_MaxDeviceName); if (!iChars || (RAS_MaxDeviceName < iChars)) { dwReturn = ERROR_NOT_ENOUGH_MEMORY; } } } } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: RasSetSubEntryPropertiesUA // // Synopsis: Unicode to Ansi wrapper for the win32 RasSetSubEntryProperties API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: SumitC Created 10/26/99 // //----------------------------------------------------------------------------- DWORD APIENTRY RasSetSubEntryPropertiesUA(LPCWSTR pszwPhoneBook, LPCWSTR pszwSubEntry, DWORD dwSubEntry, LPRASSUBENTRYW pRasSubEntryW, DWORD dwSubEntryInfoSize, LPBYTE pbDeviceConfig, DWORD dwcbDeviceConfig) { DWORD dwReturn = ERROR_INVALID_PARAMETER; MYDBGASSERT(NULL == pbDeviceConfig); // must currently be NULL MYDBGASSERT(0 == dwcbDeviceConfig); // must currently be 0 RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); MYDBGASSERT(NULL != pAnsiRasLinkage); MYDBGASSERT(NULL != pAnsiRasLinkage->pfnSetEntryProperties); if (pszwSubEntry && dwSubEntryInfoSize && pRasSubEntryW && pAnsiRasLinkage && pAnsiRasLinkage->pfnSetSubEntryProperties) { // // The phonebook should always be NULL on win9x // MYDBGASSERT(NULL == pszwPhoneBook); CHAR szAnsiSubEntry [RAS_MaxEntryName + 1]; RASSUBENTRYA AnsiRasSubEntry; ZeroMemory(&AnsiRasSubEntry, sizeof(RASSUBENTRYA)); DWORD dwTmpEntrySize = sizeof(RASSUBENTRYA); int iChars = WzToSz(pszwSubEntry, szAnsiSubEntry, RAS_MaxEntryName); if (iChars && (RAS_MaxEntryName >= iChars)) { // // Do conversion of RASSUBENTRYW to RASSUBENTRYA // AnsiRasSubEntry.dwSize = sizeof(RASSUBENTRYA); AnsiRasSubEntry.dwfFlags = pRasSubEntryW->dwfFlags; // // Device // MYVERIFY(0 != WzToSz(pRasSubEntryW->szDeviceType, AnsiRasSubEntry.szDeviceType, RAS_MaxDeviceType)); MYVERIFY(0 != WzToSz(pRasSubEntryW->szDeviceName, AnsiRasSubEntry.szDeviceName, RAS_MaxDeviceName)); // // Location/phone number. // MYVERIFY(0 != WzToSz(pRasSubEntryW->szLocalPhoneNumber, AnsiRasSubEntry.szLocalPhoneNumber, RAS_MaxPhoneNumber)); CMASSERTMSG(0 == pRasSubEntryW->dwAlternateOffset, TEXT("RasSetSubEntryPropertiesUA -- dwAlternateOffset != 0 is not supported. This will need to be implemented if used.")); AnsiRasSubEntry.dwAlternateOffset = 0; dwReturn = pAnsiRasLinkage->pfnSetSubEntryProperties(NULL, szAnsiSubEntry, dwSubEntry, &AnsiRasSubEntry, dwTmpEntrySize, NULL, 0); } } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: RasDeleteSubEntryUA // // Synopsis: Unicode to Ansi wrapper for the win32 RasDeleteSubEntryUA API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: SumitC Created 12/14/99 // //----------------------------------------------------------------------------- DWORD APIENTRY RasDeleteSubEntryUA(LPCWSTR pszwPhoneBook, LPCWSTR pszwEntry, DWORD dwSubEntryId) { DWORD dwReturn = ERROR_INVALID_PARAMETER; // // The phonebook should always be NULL on win9x // MYDBGASSERT(NULL == pszwPhoneBook); RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); MYDBGASSERT(NULL != pAnsiRasLinkage); MYDBGASSERT(NULL != pAnsiRasLinkage->pfnDeleteSubEntry); if (pszwEntry && pAnsiRasLinkage && pAnsiRasLinkage->pfnDeleteSubEntry) { CHAR szAnsiEntry [RAS_MaxEntryName + 1]; int iChars = WzToSz(pszwEntry, szAnsiEntry, RAS_MaxEntryName); if (iChars && (RAS_MaxEntryName >= iChars)) { dwReturn = pAnsiRasLinkage->pfnDeleteSubEntry(NULL, szAnsiEntry, dwSubEntryId); } } return dwReturn; } //+---------------------------------------------------------------------------- // // Function: FreeCmRasUtoA // // Synopsis: Unloads the RAS dlls (rasapi32.dll and rnaph.dll) and cleans up // the RAS linkage structure. To get more details about the cmutoa // RAS linkage see InitCmRasUtoA and cmdial\ras.cpp\LinkToRas. // // Arguments: Nothing // // Returns: Nothing // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- void FreeCmRasUtoA() { RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); CMASSERTMSG(pAnsiRasLinkage, TEXT("FreeCmRasUtoA -- RasLinkage hasn't been established yet. Why are we calling FreeCmRasUtoA now?")); if (pAnsiRasLinkage) { if (pAnsiRasLinkage->hInstRas) { FreeLibrary(pAnsiRasLinkage->hInstRas); } if (pAnsiRasLinkage->hInstRnaph) { FreeLibrary(pAnsiRasLinkage->hInstRnaph); } CmFree(pAnsiRasLinkage); TlsSetValue(g_dwTlsIndex, (LPVOID)NULL); } } //+---------------------------------------------------------------------------- // // Function: InitCmRasUtoA // // Synopsis: Function to Initialize the Unicode to ANSI conversion layer for // RAS functions. In order to make the LinkToRas stuff work the // same on win9x and on NT (all come from one dll) we have Cmdial32.dll // link to cmutoa and get all of the RAS Entry points through Cmutoa.dll. // In order to make this work, we need to keep function pointers to all of // the RAS Dll's in memory. In order to prevent two cmdial's on different // threads from calling InitCmRasUtoA and FreeCmRasUtoA at the wrong times // (one thread freeing right after another had initialized would leave // the first thread in a broken state), we usesthread local storage // to hold a pointer to a RasLinkageStructA. This makes us thread safe // and allows us to only have to init the RAS pointers once per thread // (having multiple Cmdials in the same thread is pretty unlikely anyway). // See cmdial\ras.cpp\LinkToRas for more details on the cmdial side of // things. // // Arguments: Nothing // // Returns: BOOL -- TRUE if all of the requested APIs were loaded properly. // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- BOOL InitCmRasUtoA() { BOOL bReturn = TRUE; BOOL bTryRnaph = FALSE; // // First Try to get the RasLinkageStruct out of Thread Local Storage, we // may already be initialized. // RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex); CMASSERTMSG(NULL == pAnsiRasLinkage, TEXT("InitCmRasUtoA -- RasLinkage Already established. Why are we calling InitCmRasUtoA more than once?")); if (NULL == pAnsiRasLinkage) { // // Then we haven't linked to RAS yet, first allocate the struct // pAnsiRasLinkage = (RasLinkageStructA*)CmMalloc(sizeof(RasLinkageStructA)); if (!pAnsiRasLinkage) { return FALSE; } // // Now that we have a structure, lets start filling it in. Try getting all of // the entry points out of RasApi32.dll first, then try rnaph.dll if necessary. // pAnsiRasLinkage->hInstRas = LoadLibraryExA("rasapi32.dll", NULL, 0); CMASSERTMSG(NULL != pAnsiRasLinkage->hInstRas, TEXT("InitCmRasUtoA -- Unable to load rasapi32.dll. Failing Ras Link.")); // before doing this, fix up the array based on whether we are on // Millennium or not. The function below exists only on Millennium if (!OS_MIL) { c_ArrayOfRasFuncsA[10] = NULL; //RasSetSubEntryProperties c_ArrayOfRasFuncsA[11] = NULL; //RasDeleteSubEntry } if (pAnsiRasLinkage->hInstRas) { for (int i = 0 ; c_ArrayOfRasFuncsA[i] ; i++) { pAnsiRasLinkage->apvPfnRas[i] = GetProcAddress(pAnsiRasLinkage->hInstRas, c_ArrayOfRasFuncsA[i]); if (!(pAnsiRasLinkage->apvPfnRas[i])) { bTryRnaph = TRUE; } } } // // If we missed a few, then we need to get them from rnaph.dll // if (bTryRnaph) { pAnsiRasLinkage->hInstRnaph = LoadLibraryExA("rnaph.dll", NULL, 0); CMASSERTMSG(NULL != pAnsiRasLinkage->hInstRnaph, TEXT("InitCmRasUtoA -- Unable to load Rnaph.dll. Failing Ras Link.")); if (pAnsiRasLinkage->hInstRnaph) { for (int i = 0 ; c_ArrayOfRasFuncsA[i] ; i++) { if (NULL == pAnsiRasLinkage->apvPfnRas[i]) { pAnsiRasLinkage->apvPfnRas[i] = GetProcAddress(pAnsiRasLinkage->hInstRnaph, c_ArrayOfRasFuncsA[i]); if (!(pAnsiRasLinkage->apvPfnRas[i])) { bReturn = FALSE; } } } } } // // Always save the pAnsiRasLinkage value to thread local storage, if the linkage wasn't successful // we will call FreeCmRasUtoA to clean it up. If it was successful we need to maintain it for later // use. Note that the first thing FreeCmRasUtoA does is get the Ras Linkage struct pointer out of // thread local storage because that is were it would reside under normal operation. // TlsSetValue(g_dwTlsIndex, (LPVOID)pAnsiRasLinkage); if (!bReturn) { // // Ras Linkage failed for some reason. We need to free up any resources we // may have partially filled in. // FreeCmRasUtoA(); } } return bReturn; } //+---------------------------------------------------------------------------- // // Function: SHGetPathFromIDListUA // // Synopsis: Unicode to Ansi wrapper for the win32 SHGetPathFromIDList API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- BOOL SHGetPathFromIDListUA(LPCITEMIDLIST pidl, LPWSTR pszPath) { BOOL bReturn = FALSE; if (pidl && pszPath) { CHAR szAnsiPath[MAX_PATH+1]; bReturn = SHGetPathFromIDListA(pidl, szAnsiPath); if (bReturn) { int iChars = SzToWz(szAnsiPath, pszPath, MAX_PATH); // don't know correct length but // the API says the path should be at // least MAX_PATH if (!iChars || (MAX_PATH < (DWORD)iChars)) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); bReturn = FALSE; } } } return bReturn; } //+---------------------------------------------------------------------------- // // Function: SHGetSpecialFolderLocationUA // // Synopsis: While the win32 SHGetSpecialFolderLocation API doesn't actually // require any conversion between Unicode and ANSI, CM's shell dll // class can only take one dll to take entry points from. Thus I // was forced to add these here so that the class could get all the // shell APIs it needed from cmutoa.dll. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- HRESULT SHGetSpecialFolderLocationUA(HWND hwnd, int csidl, LPITEMIDLIST *ppidl) { return SHGetSpecialFolderLocation(hwnd, csidl, ppidl); } //+---------------------------------------------------------------------------- // // Function: SHGetMallocUA // // Synopsis: While the win32 SHGetMalloc API doesn't actually // require any conversion between Unicode and ANSI, CM's shell dll // class can only take one dll to take entry points from. Thus I // was forced to add these here so that the class could get all the // shell APIs it needed from cmutoa.dll. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- HRESULT SHGetMallocUA(LPMALLOC * ppMalloc) { return SHGetMalloc(ppMalloc); } //+---------------------------------------------------------------------------- // // Function: ShellExecuteExUA // // Synopsis: Unicode to Ansi wrapper for the win32 ShellExecuteEx API. // Note that we do note convert the lpIDList param of the // SHELLEXECUTEINFOW struct because it is just a binary blob. Thus // figuring out how to convert it if we don't know what it is. If // we need this in the future we will have to deal with it on a case // by case basis. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- BOOL ShellExecuteExUA(LPSHELLEXECUTEINFOW pShellInfoW) { BOOL bReturn = FALSE; SHELLEXECUTEINFOA ShellInfoA; ZeroMemory(&ShellInfoA, sizeof(ShellInfoA)); if (pShellInfoW) { ShellInfoA.cbSize = sizeof(ShellInfoA); ShellInfoA.fMask = pShellInfoW->fMask; ShellInfoA.hwnd = pShellInfoW->hwnd; if (pShellInfoW->lpVerb) { ShellInfoA.lpVerb = WzToSzWithAlloc(pShellInfoW->lpVerb); if (NULL == ShellInfoA.lpVerb) { goto exit; } } if (pShellInfoW->lpFile) { ShellInfoA.lpFile = WzToSzWithAlloc(pShellInfoW->lpFile); if (NULL == ShellInfoA.lpFile) { goto exit; } } if (pShellInfoW->lpParameters) { ShellInfoA.lpParameters = WzToSzWithAlloc(pShellInfoW->lpParameters); if (NULL == ShellInfoA.lpParameters) { goto exit; } } if (pShellInfoW->lpDirectory) { ShellInfoA.lpDirectory = WzToSzWithAlloc(pShellInfoW->lpDirectory); if (NULL == ShellInfoA.lpDirectory) { goto exit; } } ShellInfoA.nShow = pShellInfoW->nShow; ShellInfoA.hInstApp = pShellInfoW->hInstApp; // // Since this is a binary blob conversion could be difficult. // We also don't currently use it, so I won't spend the cycles implementing it now. // MYDBGASSERT(NULL == pShellInfoW->lpIDList); ShellInfoA.lpIDList = NULL; if (pShellInfoW->lpClass) { ShellInfoA.lpClass = WzToSzWithAlloc(pShellInfoW->lpClass); if (NULL == ShellInfoA.lpClass) { goto exit; } } ShellInfoA.hkeyClass = pShellInfoW->hkeyClass; ShellInfoA.hIcon = pShellInfoW->hIcon; // hIcon/hMonitor is a union so we only need one of them to get the mem // HANDLE hProcess this is a return param dealt with below. // // Finally call ShellExecuteExA // bReturn = ShellExecuteExA(&ShellInfoA); if (ShellInfoA.hProcess) { // // The Caller asked for the process handle so send it back. // pShellInfoW->hProcess = ShellInfoA.hProcess; } } exit: CmFree((void*)ShellInfoA.lpVerb); CmFree((void*)ShellInfoA.lpFile); CmFree((void*)ShellInfoA.lpParameters); CmFree((void*)ShellInfoA.lpDirectory); CmFree((void*)ShellInfoA.lpClass); return bReturn; } //+---------------------------------------------------------------------------- // // Function: Shell_NotifyIconUA // // Synopsis: Unicode to Ansi wrapper for the win32 Shell_NotifyIcon API. // // Arguments: See the win32 API definition // // Returns: See the win32 API definition // // History: quintinb Created 7/15/99 // //+---------------------------------------------------------------------------- BOOL Shell_NotifyIconUA (DWORD dwMessage, PNOTIFYICONDATAW pnidW) { BOOL bReturn = FALSE; if (pnidW) { NOTIFYICONDATAA nidA; ZeroMemory (&nidA, sizeof(NOTIFYICONDATAA)); nidA.cbSize = sizeof(NOTIFYICONDATAA); nidA.hWnd = pnidW->hWnd; nidA.uID = pnidW->uID; nidA.uFlags = pnidW->uFlags; nidA.uCallbackMessage = pnidW->uCallbackMessage; nidA.hIcon = pnidW->hIcon; int iChars = WzToSz(pnidW->szTip, nidA.szTip, 64); // 64 is the length of the szTip in the 4.0 struct if (!iChars || (64 < iChars)) { nidA.szTip[0] = '\0'; } bReturn = Shell_NotifyIconA(dwMessage, &nidA); } return bReturn; }