Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

4769 lines
157 KiB

//+----------------------------------------------------------------------------
//
// 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 <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <shlobj.h>
#include <ras.h>
#include <raserror.h>
#include <shellapi.h>
#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: CompareStringAU
//
// Synopsis: Unicode to Ansi wrapper for the win32 CompareString API. This only
// supports the syntax where both cchCount values are -1, i.e. where
// the entire string is being compared.
//
// Arguments: See the win32 API definition
//
// Returns: See the win32 API definition
//
// History: SumitC Created 20-Aug-2001
//
//+----------------------------------------------------------------------------
int WINAPI CompareStringAU(
IN LCID Locale,
IN DWORD dwCmpFlags,
IN LPCWSTR lpString1,
IN int cchCount1,
IN LPCWSTR lpString2,
IN int cchCount2)
{
MYDBGASSERT(cchCount1 == -1);
MYDBGASSERT(cchCount2 == -1);
if ((-1 != cchCount1) || (-1 != cchCount2))
{
return 0;
}
int iReturn = 0;
LPSTR pszAnsiString1 = NULL;
LPSTR pszAnsiString2 = NULL;
if (lpString1)
{
pszAnsiString1 = WzToSzWithAlloc(lpString1);
}
if (lpString2)
{
pszAnsiString2 = WzToSzWithAlloc(lpString2);
}
if (lpString1 && lpString2)
{
iReturn = CompareStringA(Locale, dwCmpFlags, pszAnsiString1, -1, pszAnsiString2, -1);
}
CmFree(pszAnsiString1);
CmFree(pszAnsiString2);
return iReturn;
}
//+----------------------------------------------------------------------------
//
// 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;
//
// Check for possible security violations. Either the lpApplicationName param
// should not be NULL, or at least the lpCommandLine param should have the
// actual exe name in quotes (we do a partial check for the latter).
//
CMASSERTMSG((lpApplicationName || (lpCommandLine && (TEXT('"') == lpCommandLine[0]))),
TEXT("CreateProcessAU -- Security Violation. Either lpApplication name should be non-null, or the app name in lpCommandLine should be delimited with double-quotes"));
//
// 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->pCompareStringU) = CompareStringAU;
*(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 RasDeleteSubEntry 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: RasGetProjectionInfoUA
//
// Synopsis: Unicode to Ansi wrapper for the win32 RasGetProjectionInfo API.
//
// Arguments: See the win32 API definition
//
// Returns: See the win32 API definition
//
// History: SumitC Created 02-Oct-2001
//
//-----------------------------------------------------------------------------
DWORD APIENTRY
RasGetProjectionInfoUA(HRASCONN hRasConn, RASPROJECTION RasProj, LPVOID lpprojection, LPDWORD lpcb)
{
DWORD dwReturn = ERROR_INVALID_PARAMETER;
MYDBGASSERT(RASP_PppIp == RasProj); // this is the only one we support for now.
RasLinkageStructA* pAnsiRasLinkage = (RasLinkageStructA*)TlsGetValue(g_dwTlsIndex);
MYDBGASSERT(NULL != pAnsiRasLinkage);
MYDBGASSERT(NULL != pAnsiRasLinkage->pfnGetProjectionInfo);
if ((RASP_PppIp == RasProj) && pAnsiRasLinkage && pAnsiRasLinkage->pfnGetProjectionInfo)
{
RASPPPIPA AnsiProjInfo;
DWORD dwBufSize = 0;
RASPPPIPW * p = (RASPPPIPW *) lpprojection;
if (p)
{
dwBufSize = sizeof(RASPPPIPA);
ZeroMemory(&AnsiProjInfo, dwBufSize);
AnsiProjInfo.dwSize = dwBufSize;
}
dwReturn = pAnsiRasLinkage->pfnGetProjectionInfo(hRasConn, RASP_PppIp, (p ? (PVOID)&AnsiProjInfo : NULL), &dwBufSize);
if ((ERROR_SUCCESS == dwReturn) && (NULL != p))
{
p->dwSize = sizeof(RASPPPIPW);
// copy any DWORDs over
p->dwError = AnsiProjInfo.dwError;
// but the 2 strings have to be converted
int iChars = SzToWz(AnsiProjInfo.szIpAddress, p->szIpAddress, RAS_MaxIpAddress);
if (!iChars || (iChars > RAS_MaxIpAddress))
{
dwReturn = GetLastError();
CMASSERTMSG(FALSE, TEXT("RasGetProjectionInfoUA -- Failed to convert szIpAddress to Unicode."));
}
else
{
iChars = SzToWz(AnsiProjInfo.szServerIpAddress, p->szServerIpAddress, RAS_MaxIpAddress);
if (!iChars || (iChars > RAS_MaxIpAddress))
{
dwReturn = GetLastError();
CMASSERTMSG(FALSE, TEXT("RasGetProjectionInfoUA -- Failed to convert szServerIpAddress to Unicode."));
}
}
}
}
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[11] = NULL; //RasSetSubEntryProperties
c_ArrayOfRasFuncsA[12] = 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;
}