windows-nt/Source/XPSP1/NT/com/mobile/syncmgr/lib/widewrap.cpp
2020-09-26 16:20:57 +08:00

4746 lines
102 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1993 - 1998
//
// File: widewrap.cxx
//
// Contents: Unicode wrapper API
//
// Functions: About fifty Win32 function wrappers
//
// Notes: 'sz' is used instead of the "correct" hungarian 'psz'
// throughout to enhance readability.
//
// Not all of every Win32 function is wrapped here. Some
// obscurely-documented features may not be handled correctly
// in these wrappers. Caller beware.
//
// History: 28-Dec-93 ErikGav Created
// 06-14-94 KentCe Various Chicago build fixes.
// 21-Dec-94 BruceMa Use olewcstombs + other fixes
// 21-Feb-95 BruceMa Add support for AreFileApisANSI
// 29-Feb-96 JeffE Add lots of wide character rtns
// 15-Jul-98 SitaramR Fixed MultiByte <-> Unicode conversions
//
//----------------------------------------------------------------------------
//
// Bugs noticed don't have time to fix.
// Feb 4th 1997
//
// 1. delete(FileX (and many others) why is it sz[MAX_PATH*2]?
// 2. Return from UnicodeToAnsi/UnicodeToAnsiOem is being ignored
// 3. Convert/ConvertOem - since return from UnicodeToAnsi[Oem] is
// being ignored, bogus ANSI/OEM string could come back causing
// problems later. E.g, in LoadLibraryX we could end up passing
// bogus stuff to LoadLibraryA
// 4. GetDriveTypeX (and many other places) "return 0" is the wrong
// thing change if (sz == ERR) to return DRIVE_UNKNOWN
// 5. SearchPathX do lpPath and lpExtension need to be ConvertOem?
// 6. Convert/ConvertOem are bad names. Use better names.
//
//----------------------------------------------------------------------------
#include "lib.h"
#define HFINDFILE HANDLE
#define ERR ((char*) -1)
#define CairoleAssert // Review - replace with our asserts
#define Win4Assert
#undef ALLOC
#undef FREE
#ifdef __cplusplus
extern "C" {
#endif
// notes:
// ConvertWideCharToMultiByte if pass in null doesn't change output
// string, should it set it to NULL.
CRITICAL_SECTION g_CritSectCommonLib;
BOOL g_fWideWrap_Unicode = FALSE;
// list of wide functions not available on Win9x + IE4
// Shell32!SHGetFileInfoW
// Shell32!Shell_NotifyIconW
typedef BOOL (WINAPI *SHELL_NOTIFYICONW)(DWORD dwMessage, PNOTIFYICONDATAW lpData );
typedef BOOL (WINAPI *SHELL_NOTIFYICONA)(DWORD dwMessage, PNOTIFYICONDATAA lpData );
typedef DWORD_PTR (WINAPI *SHGETFILEINFOW)(LPCWSTR pszPath,
DWORD dwFileAttributes, SHFILEINFOW FAR *psfi,
UINT cbFileInfo,UINT uFlags);
typedef DWORD_PTR (WINAPI *SHGETFILEINFOA)(LPCSTR pszPath,
DWORD dwFileAttributes, SHFILEINFOA FAR *psfi,
UINT cbFileInfo,UINT uFlags);
STRING_FILENAME(szShell32, "SHELL32.DLL");
STRING_INTERFACE(szShell_NotifyIconW,"Shell_NotifyIconW");
STRING_INTERFACE(szShell_NotifyIconA,"Shell_NotifyIconA");
STRING_INTERFACE(szShGetFileInfoA,"SHGetFileInfoA");
STRING_INTERFACE(szShGetFileInfoW,"SHGetFileInfoW");
BOOL g_fLoadedShell32 = FALSE;
HINSTANCE g_hinstShell32 = NULL;
SHELL_NOTIFYICONW g_pfShell_NotifyIconW = NULL;
SHELL_NOTIFYICONA g_pfShell_NotifyIconA = NULL;
SHGETFILEINFOW g_pfShGetFileInfoW = NULL;
SHGETFILEINFOA g_pfShGetFileInfoA = NULL;
// list of exports we use from OleAut32.
typedef BSTR (APIENTRY *PFNSYSALLOCSTRING)(const OLECHAR *);
typedef void (APIENTRY *PFNSYSFREESTRING)(BSTR);
typedef HRESULT (APIENTRY *PFNLOADREGTYPELIB)(REFGUID rguid,
WORD wVerMajor,WORD wVerMinor,LCID lcid,ITypeLib FAR* FAR* pptlib);
STRING_FILENAME(szOleAut32Dll, "OLEAUT32.DLL");
STRING_INTERFACE(szSysAllocString,"SysAllocString");
STRING_INTERFACE(szSysFreeString,"SysFreeString");
STRING_INTERFACE(szLoadRegTypeLib,"LoadRegTypeLib");
BOOL g_fLoadedOleAut32 = FALSE;
HINSTANCE g_hinstOleAut32 = NULL;
PFNSYSALLOCSTRING g_pfSysAllocString = NULL;
PFNSYSFREESTRING g_pfSysFreeString = NULL;
PFNLOADREGTYPELIB g_pfLoadRegTypeLib = NULL;
// list of exports we use from UserEnv.
typedef BOOL (APIENTRY *PFNGETUSERPROFILEDIRECTORY)(HANDLE hToken,LPWSTR lpProfileDir,LPDWORD lpcchSize);
STRING_FILENAME(szUserEnvDll, "USERENV.DLL");
STRING_INTERFACE(szGetUserProfileDirectory,"GetUserProfileDirectoryW");
BOOL g_fLoadedUserEnv = FALSE;
HINSTANCE g_hinstUserEnv = NULL;
PFNGETUSERPROFILEDIRECTORY g_pfGetUserProfileDirectory = NULL;
// list of exports used from User32.dll
typedef BOOL (WINAPI *PFNALLOWSETFOREGROUNDWINDOW)(DWORD dwProcessId);
STRING_FILENAME(szUser32Dll, "USER32.DLL");
STRING_INTERFACE(szAllowSetForegroundWindow,"AllowSetForegroundWindow");
BOOL g_fLoadedUser32 = FALSE;
HINSTANCE g_hinstUser32 = NULL;
PFNALLOWSETFOREGROUNDWINDOW g_pfAllowSetForegroundWindow = NULL;
// delcartions for imports from imm32.dll
typedef HIMC (WINAPI *PFNIMMASSOCIATECONTEXT)(HWND hWnd,HIMC hIMC);
STRING_FILENAME(szIMM32Dll, "IMM32.DLL");
STRING_INTERFACE(szImmAssociateContext,"ImmAssociateContext");
BOOL g_fLoadedIMM32 = FALSE;
HINSTANCE g_hinstIMM32 = NULL;
PFNIMMASSOCIATECONTEXT g_pfImmAssociateContext = NULL;
// global vars
OSVERSIONINFOA g_OSVersionInfo; // osVersionInfo.
// Note: this should really be in its own file but due to closeness
// of IE5 release leave here for now.
// must be called before any other routine to setup variables and
// try to dynamically load wide exports not available on Win9x
// globals shared by Common.
// !!! InitCommonLib function is not thread safe. must be called on main thread before
// other threads are created
void InitCommonLib(BOOL fUnicode)
{
InitializeCriticalSection(&g_CritSectCommonLib);
g_fWideWrap_Unicode = fUnicode;
g_OSVersionInfo.dwOSVersionInfoSize = sizeof(g_OSVersionInfo);
if (!GetVersionExA(&g_OSVersionInfo))
{
AssertSz(0,"GetVersionEx Failed");
// if Can't get Version information base it off of Unicode Flag
g_OSVersionInfo.dwPlatformId = fUnicode ?
(VER_PLATFORM_WIN32_NT) : (VER_PLATFORM_WIN32_WINDOWS);
}
// g_fWideWrap_Unicode = FALSE;
}
// must be called to Uninit CommonLib.
// !!Warning COM has already been unitialized at this point.
// !!Warning, not thread safe.
void UnInitCommonLib(void)
{
DeleteCriticalSection(&g_CritSectCommonLib);
}
// returns TRUE if WideWrap is set to Unicode, False if ANSI
BOOL WideWrapIsUnicode()
{
BOOL fIsUnicode;
CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
cCritSect.Enter();
fIsUnicode = g_fWideWrap_Unicode;
cCritSect.Leave();
return fIsUnicode;
}
//+---------------------------------------------------------------------------
//
// Function: GetUserTextualSid
//
// Synopsis: Get a user SID and convert to its string representation
//
//----------------------------------------------------------------------------
BOOL
GetUserTextualSid(
LPTSTR TextualSid, // buffer for Textual representaion of Sid
LPDWORD cchSidSize // required/provided TextualSid buffersize
)
{
if (!g_fWideWrap_Unicode)
{
TextualSid[0] = TEXT('\0');
*cchSidSize = 0;
return TRUE;
}
HANDLE hToken;
BYTE buf[MAX_PATH];
PTOKEN_USER ptgUser = (PTOKEN_USER)buf;
DWORD cbBuffer=MAX_PATH;
BOOL bSuccess;
PSID pSid;
PSID_IDENTIFIER_AUTHORITY psia;
DWORD dwSubAuthorities;
DWORD dwCounter;
DWORD cchSidCopy;
//
// obtain current process token
//
if(!OpenProcessToken(
GetCurrentProcess(), // target current process
TOKEN_QUERY, // TOKEN_QUERY access
&hToken // resultant hToken
))
{
return FALSE;
}
//
// obtain user identified by current process' access token
//
bSuccess = GetTokenInformation(
hToken, // identifies access token
TokenUser, // TokenUser info type
ptgUser, // retrieved info buffer
cbBuffer, // size of buffer passed-in
&cbBuffer // required buffer size
);
// close token handle. do this even if error above
CloseHandle(hToken);
if(!bSuccess)
{
return FALSE;
}
pSid = ptgUser->User.Sid;
//
// test if Sid passed in is valid
//
if(!IsValidSid(pSid)) return FALSE;
// obtain SidIdentifierAuthority
psia = GetSidIdentifierAuthority(pSid);
// obtain sidsubauthority count
dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
//
// compute approximate buffer length
// S-SID_REVISION- + identifierauthority- + subauthorities- + NULL
//
cchSidCopy = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
//
// check provided buffer length.
// If not large enough, indicate proper size and setlasterror
//
if(*cchSidSize < cchSidCopy) {
*cchSidSize = cchSidCopy;
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
//
// prepare S-SID_REVISION-
//
cchSidCopy = wsprintf(TextualSid, TEXT("S-%lu-"), SID_REVISION );
//
// prepare SidIdentifierAuthority
//
if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) {
cchSidCopy += wsprintf(TextualSid + cchSidCopy,
TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
(USHORT)psia->Value[0],
(USHORT)psia->Value[1],
(USHORT)psia->Value[2],
(USHORT)psia->Value[3],
(USHORT)psia->Value[4],
(USHORT)psia->Value[5]);
} else {
cchSidCopy += wsprintf(TextualSid + cchSidCopy,
TEXT("%lu"),
(ULONG)(psia->Value[5] ) +
(ULONG)(psia->Value[4] << 8) +
(ULONG)(psia->Value[3] << 16) +
(ULONG)(psia->Value[2] << 24) );
}
//
// loop through SidSubAuthorities
//
for(dwCounter = 0 ; dwCounter < dwSubAuthorities ; dwCounter++) {
cchSidCopy += wsprintf(TextualSid + cchSidCopy, TEXT("-%lu"),
*GetSidSubAuthority(pSid, dwCounter) );
}
//
// tell the caller how many chars we provided, not including NULL
//
*cchSidSize = cchSidCopy;
return TRUE;
}
// loads exports we need from the shell32dll
void LoadShell32Dll()
{
if (g_fLoadedShell32)
return;
CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
cCritSect.Enter();
// make sure not loaded again in case someone took lock first
if (!g_fLoadedShell32)
{
g_hinstShell32 = LoadLibrary(szShell32);
if (g_hinstShell32)
{
g_pfShell_NotifyIconW = (SHELL_NOTIFYICONW) GetProcAddress(g_hinstShell32, szShell_NotifyIconW);
g_pfShell_NotifyIconA = (SHELL_NOTIFYICONA) GetProcAddress(g_hinstShell32, szShell_NotifyIconA);
g_pfShGetFileInfoW = (SHGETFILEINFOW) GetProcAddress(g_hinstShell32, szShGetFileInfoW);
g_pfShGetFileInfoA = (SHGETFILEINFOA) GetProcAddress(g_hinstShell32, szShGetFileInfoA);
}
// should always get the Ansi exports
Assert(g_pfShell_NotifyIconA);
Assert(g_pfShGetFileInfoA);
g_fLoadedShell32 = TRUE;
}
cCritSect.Leave();
}
// load exports from OleAutomation
// up to caller to check exports they need are valid after making this call
void LoadOleAut32Dll()
{
if (g_fLoadedOleAut32)
return;
CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
cCritSect.Enter();
// make sure not loaded again in case someone took lock first
if (!g_fLoadedOleAut32)
{
g_hinstOleAut32 = LoadLibrary(szOleAut32Dll);
if (g_hinstOleAut32)
{
g_pfSysAllocString = (PFNSYSALLOCSTRING) GetProcAddress(g_hinstOleAut32, szSysAllocString);
g_pfSysFreeString = (PFNSYSFREESTRING) GetProcAddress(g_hinstOleAut32, szSysFreeString);
g_pfLoadRegTypeLib = (PFNLOADREGTYPELIB) GetProcAddress(g_hinstOleAut32, szLoadRegTypeLib);
}
// should always get the exports.
Assert(g_pfSysAllocString);
Assert(g_pfSysFreeString);
Assert(g_pfLoadRegTypeLib);
g_fLoadedOleAut32 = TRUE;
}
cCritSect.Leave();
}
STDAPI_(BSTR) SysAllocStringX(const OLECHAR *sz)
{
LoadOleAut32Dll();
Assert(g_pfSysAllocString);
if (g_pfSysAllocString)
{
return (*g_pfSysAllocString)(sz);
}
return NULL;
}
STDAPI_(void) SysFreeStringX(BSTR bsz)
{
LoadOleAut32Dll();
Assert(g_pfSysFreeString);
if (g_pfSysFreeString)
{
(*g_pfSysFreeString)(bsz);
}
}
STDAPI LoadRegTypeLibX(REFGUID rguid, WORD wVerMajor, WORD wVerMinor,
LCID lcid, ITypeLib ** pptlib)
{
LoadOleAut32Dll();
Assert(g_pfLoadRegTypeLib);
if (g_pfLoadRegTypeLib)
{
return (*g_pfLoadRegTypeLib)(rguid,wVerMajor,wVerMinor,lcid,pptlib);
}
return E_OUTOFMEMORY;
}
void LoadUserEnvDll()
{
if (g_fLoadedUserEnv)
return;
CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
cCritSect.Enter();
// make sure not loaded again in case someone took lock first
if (!g_fLoadedUserEnv)
{
g_hinstUserEnv = LoadLibrary(szUserEnvDll);
if (g_hinstUserEnv)
{
g_pfGetUserProfileDirectory = (PFNGETUSERPROFILEDIRECTORY) GetProcAddress(g_hinstUserEnv, szGetUserProfileDirectory);
}
// should always get the exports.
Assert(g_pfGetUserProfileDirectory);
g_fLoadedUserEnv = TRUE;
}
cCritSect.Leave();
}
BOOL
WINAPI
GetUserProfileDirectoryX(HANDLE hToken,LPWSTR lpProfileDir,LPDWORD lpcchSize)
{
LoadUserEnvDll();
Assert(g_pfGetUserProfileDirectory);
if (g_pfGetUserProfileDirectory)
{
return (*g_pfGetUserProfileDirectory)(hToken,lpProfileDir,lpcchSize);
}
// by definition on falue size is filled with necessary buffer size.
// since we don't know this set it to zero. If caller then reallocates and
// tries again it will still fail
*lpcchSize = 0;
return FALSE;
}
// delay load for User
void LoadUser32Dll()
{
if (g_fLoadedUser32)
return;
CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
cCritSect.Enter();
// make sure not loaded again in case someone took lock first
if (!g_fLoadedUser32)
{
g_hinstUser32 = LoadLibrary(szUser32Dll);
if (g_hinstUser32)
{
g_pfAllowSetForegroundWindow =
(PFNALLOWSETFOREGROUNDWINDOW) GetProcAddress(g_hinstUser32,
szAllowSetForegroundWindow);
}
g_fLoadedUser32 = TRUE;
}
cCritSect.Leave();
}
BOOL WINAPI AllowSetForegroundWindowX(
DWORD dwProcessId)
{
LoadUser32Dll();
// okay to not get export since might not be on NT 5.0
if (g_pfAllowSetForegroundWindow)
{
return (*g_pfAllowSetForegroundWindow)(dwProcessId);
}
return FALSE;
}
// delay load for IME calls
void LoadIMM32Dll()
{
if (g_fLoadedIMM32)
return;
CCriticalSection cCritSect(&g_CritSectCommonLib,GetCurrentThreadId());
cCritSect.Enter();
// make sure not loaded again in case someone took lock first
if (!g_fLoadedIMM32)
{
g_hinstIMM32 = LoadLibrary(szIMM32Dll);
if (g_hinstIMM32)
{
g_pfImmAssociateContext =
(PFNIMMASSOCIATECONTEXT) GetProcAddress(g_hinstIMM32,
szImmAssociateContext);
}
g_fLoadedIMM32 = TRUE;
}
cCritSect.Leave();
}
HIMC WINAPI ImmAssociateContextX(HWND hWnd,HIMC hIMC)
{
LoadIMM32Dll();
// okay to not get export since might not be on NT 5.0
if (g_pfImmAssociateContext)
{
return (*g_pfImmAssociateContext)(hWnd,hIMC);
}
return NULL;
}
int LoadStringX( HINSTANCE hInstance, UINT uID,LPWSTR lpwszBuffer,int nBufferMax)
{
int iReturn = 0;
if (g_fWideWrap_Unicode)
{
iReturn = LoadStringW(hInstance,uID,lpwszBuffer,nBufferMax);
return iReturn;
}
XArray<CHAR> xszString;
BOOL fOk = xszString.Init( nBufferMax );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
iReturn = LoadStringA(hInstance, uID, xszString.Get(), nBufferMax);
if ( iReturn == 0 )
return 0;
XArray<WCHAR> xwszBuffer;
fOk = ConvertMultiByteToWideChar( xszString.Get(), iReturn+1, xwszBuffer );
if ( !fOk )
return 0;
iReturn = lstrlenX( xwszBuffer.Get() );
if ( iReturn >= nBufferMax)
{
//
// Truncate to fit
//
iReturn = nBufferMax -1;
lstrcpynX( lpwszBuffer, xwszBuffer.Get(), iReturn );
lpwszBuffer[iReturn] = 0;
}
else
lstrcpyX( lpwszBuffer, xwszBuffer.Get() );
return iReturn;
}
#if 0
HANDLE WINAPI CreateFileX(LPCWSTR pwsz, DWORD fdwAccess, DWORD fdwShareMask,
LPSECURITY_ATTRIBUTES lpsa, DWORD fdwCreate, DWORD fdwAttrsAndFlags,
HANDLE hTemplateFile)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("CreateFile\n");
#endif
CHAR sz[MAX_PATH * 2];
UnicodeToAnsiOem(sz, pwsz, sizeof(sz));
return CreateFileA(sz, fdwAccess, fdwShareMask, lpsa, fdwCreate,
fdwAttrsAndFlags, hTemplateFile);
}
#endif
BOOL WINAPI DeleteFileX(LPCWSTR pwsz)
{
BOOL fReturn = FALSE;
Assert(pwsz);
if (g_fWideWrap_Unicode)
{
fReturn = DeleteFileW(pwsz);
}
else
{
XArray<CHAR> xszString;
BOOL fOk = ConvertWideCharToMultiByte( pwsz, xszString );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
fReturn = DeleteFileA(xszString.Get());
}
return fReturn;
}
BOOL WINAPI ExpandEnvironmentStringsX(
LPCWSTR lpSrc,
LPWSTR lpDstW,
DWORD nSize
)
{
BOOL fReturn = FALSE;
Assert(lpSrc);
Assert(lpDstW);
if (g_fWideWrap_Unicode)
{
fReturn = ExpandEnvironmentStringsW(lpSrc,lpDstW,nSize);
}
else
{
XArray<CHAR> xszSrc;
XArray<CHAR> xszDst;
BOOL fOk = ConvertWideCharToMultiByte( lpSrc, xszSrc);
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
fOk = xszDst.Init( nSize + 1);
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
fReturn = ExpandEnvironmentStringsA(xszSrc.Get(), xszDst.Get(), nSize);
XArray<WCHAR> xszDstW;
fOk = ConvertMultiByteToWideChar( xszDst.Get(), xszDstW);
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
wcscpy(lpDstW,xszDstW.Get());
}
return fReturn;
}
#if 0
UINT WINAPI RegisterClipboardFormatX(LPCWSTR pwszFormat)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RegisterClipboardFormat\n");
#endif
UINT ret;
CHAR sz[200];
UnicodeToAnsi(sz, pwszFormat, sizeof(sz));
ret = RegisterClipboardFormatA(sz);
return ret;
}
int WINAPI GetClipboardFormatNameX(UINT format, LPWSTR pwsz,
int cchMaxCount)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("GetClipboardFormatName\n");
#endif
LPSTR sz;
int i;
sz = (char *) ALLOC(cchMaxCount*sizeof(char));
if (sz == NULL)
{
return 0;
}
i = GetClipboardFormatNameA(format, sz, cchMaxCount);
if (i)
{
AnsiToUnicode(pwsz, sz, lstrlenA(sz) + 1);
}
if (sz)
{
FREE( sz);
}
return i;
}
#endif
LONG APIENTRY RegOpenKeyX(HKEY hKey, LPCWSTR pwszSubKey, PHKEY phkResult)
{
return RegOpenKeyEx(hKey,pwszSubKey,NULL,KEY_READ | KEY_WRITE,phkResult);
}
#if 0
LONG APIENTRY RegQueryValueX(HKEY hKey, LPCWSTR pwszSubKey, LPWSTR pwszValue,
PLONG lpcbValue)
{
LONG ret;
if (g_fWideWrap_Unicode)
{
ret = RegQueryValueW(hKey, pwszSubKey, pwszValue, lpcbValue);
return ret;
}
LONG cbOldSize = *lpcbValue;
LONG cb;
XArray<CHAR> xszSubKey;
BOOL fOk = ConvertWideCharToMultiByte( pwszSubKey, xszSubKey );
if ( !fOk )
return ERROR_OUTOFMEMORY;
ret = RegQueryValueA(hKey, xszSubKey.Get(), NULL, &cb);
// If the caller was just asking for the size of the value, jump out
// now, without actually retrieving and converting the value.
if (pwszValue == NULL)
{
// Adjust size of buffer to report, to account for CHAR -> WCHAR
*lpcbValue = cb * sizeof(WCHAR);
}
if (ret == ERROR_SUCCESS)
{
// If the caller was asking for the value, but allocated too small
// of a buffer, set the buffer size and jump out.
if (*lpcbValue < (LONG) (cb * sizeof(WCHAR)))
{
// Adjust size of buffer to report, to account for CHAR -> WCHAR
*lpcbValue = cb * sizeof(WCHAR);
return ERROR_MORE_DATA;
}
// Otherwise, retrieve and convert the value.
XArray<CHAR> xszValue;
fOk = xszValue.Init( cb );
if ( !fOk )
return ERROR_OUTOFMEMORY;
ret = RegQueryValueA(hKey, xszSubKey.Get(), xszValue.Get(), &cb);
if (ret == ERROR_SUCCESS)
{
XArray<WCHAR> xwszValueOut;
fOk = ConvertMultiByteToWideChar( xszValue.Get(), xwszValueOut );
if ( !fOk )
return ERROR_OUTOFMEMORY;
// Adjust size of buffer to report, to account for CHAR -> WCHAR
*lpcbValue = lstrlenX(xwszValueOut.Get()) * sizeof(WCHAR);
if ( *lpcbValue < cbOldSize )
lstrcpyX( pwszValue, xwszValueOut.Get() );
else
return ERROR_MORE_DATA;
}
}
return ret;
}
#endif
LONG APIENTRY RegSetValueExX(
HKEY hKey,
LPCWSTR lpValueName,
DWORD Reserved,
DWORD dwType,
CONST BYTE* lpData,
DWORD cbData
)
{
LONG lResult = E_UNEXPECTED;
if (g_fWideWrap_Unicode)
{
lResult = RegSetValueExW(hKey,lpValueName,Reserved,dwType,lpData,cbData);
}
else
{
LPSTR lpValueNameA = NULL;
LPSTR lpDataA = NULL;
Assert(0 == Reserved);
Assert(lpData);
// only supports dwType of REG_SZ and REG_DWORD
if ( (dwType != REG_SZ) && (dwType != REG_DWORD) && (dwType != REG_BINARY))
{
Assert(dwType == REG_SZ || dwType == REG_DWORD || dwType == REG_BINARY);
return E_INVALIDARG;
}
XArray<CHAR> xszValueName;
BOOL fOk = ConvertWideCharToMultiByte( lpValueName, xszValueName );
if ( !fOk )
return ERROR_OUTOFMEMORY;
lpValueNameA = xszValueName.Get();
XArray<CHAR> xszData;
if (dwType == REG_SZ)
{
fOk = ConvertWideCharToMultiByte( (WCHAR *)lpData, xszData );
if ( !fOk )
return ERROR_OUTOFMEMORY;
lpDataA = xszData.Get();
lpData = (BYTE *) lpDataA;
if (lpDataA)
{
cbData = lstrlenA(lpDataA) + 1;
}
}
if (lpData)
{
lResult = RegSetValueExA(hKey,lpValueNameA,Reserved,dwType,lpData,cbData);
}
}
return lResult;
}
#if 0
LONG APIENTRY RegSetValueX(HKEY hKey, LPCWSTR lpSubKey, DWORD dwType,
LPCWSTR lpData, DWORD cbData)
{
LONG ret;
if (g_fWideWrap_Unicode)
{
ret = RegSetValueW( hKey, lpSubKey, dwType, lpData, cbData);
return ret;
}
XArray<CHAR> xszKey;
BOOL fOk = ConvertWideCharToMultiByte( lpSubKey, xszKey );
if ( !fOk )
return ERROR_OUTOFMEMORY;
if ( dwType == REG_EXPAND_SZ
|| dwType == REG_MULTI_SZ
|| dwType == REG_SZ )
{
//
// Convert string data to multibyte
//
XArray<CHAR> xszValue;
fOk = ConvertWideCharToMultiByte( lpData, cbData, xszValue );
if ( !fOk )
return ERROR_OUTOFMEMORY;
ret = RegSetValueA(hKey, xszKey.Get(), dwType, xszValue.Get(), lstrlenA(xszValue.Get()) + 1 );
}
else
ret = RegSetValueA(hKey, xszKey.Get(), dwType, (LPSTR)lpData, cbData);
return ret;
}
#endif
LONG
APIENTRY
RegDeleteValueX (
HKEY hKey,
LPCWSTR lpValueName
)
{
LONG ret;
if (g_fWideWrap_Unicode)
{
ret = RegDeleteValueW( hKey,lpValueName);
return ret;
}
XArray<CHAR> xszValue;
BOOL fOk = ConvertWideCharToMultiByte( lpValueName, xszValue );
if ( !fOk )
return ERROR_OUTOFMEMORY;
ret = RegDeleteValueA(hKey,xszValue.Get());
return ret;
}
LONG
APIENTRY
RegCreateKeyExXp(
HKEY hKey,
LPCWSTR lpSubKey,
DWORD Reserved,
LPWSTR lpClass,
DWORD dwOptions,
REGSAM samDesired,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
PHKEY phkResult,
LPDWORD lpdwDisposition,
BOOL fSetSecurity)
{
LONG lResult = E_UNEXPECTED;
DWORD dwDispositionLocal;
LPDWORD lpdwDispositionLocal;
lpdwDispositionLocal = lpdwDisposition ? lpdwDisposition : &dwDispositionLocal;
if (g_fWideWrap_Unicode)
{
lResult = RegCreateKeyExW(hKey,lpSubKey,Reserved,
lpClass,dwOptions,samDesired,lpSecurityAttributes,
phkResult,lpdwDispositionLocal);
}
else
{
lResult = ERROR_SUCCESS;
XArray<CHAR> xszSubKey;
XArray<CHAR> xszClass;
LPSTR lpSubKeyA;
LPSTR lpClassA;
BOOL fOk = ConvertWideCharToMultiByte( lpSubKey, xszSubKey );
if ( !fOk )
{
lResult = ERROR_OUTOFMEMORY;
}
if (ERROR_SUCCESS == lResult)
{
lpSubKeyA = xszSubKey.Get();
fOk = ConvertWideCharToMultiByte( lpClass, xszClass );
if ( !fOk )
{
lResult = ERROR_OUTOFMEMORY;
}
}
if (ERROR_SUCCESS == lResult)
{
lpClassA = xszClass.Get();
lResult = RegCreateKeyExA(hKey,lpSubKeyA,Reserved,
lpClassA,dwOptions,samDesired,lpSecurityAttributes,
phkResult,lpdwDispositionLocal);
}
}
// On NT Set the Security of any keys we create to Access Everyone
if (VER_PLATFORM_WIN32_NT == g_OSVersionInfo.dwPlatformId)
{
// on a success and the disposition is a new key setup the security.
if ( (ERROR_SUCCESS == lResult) && (REG_CREATED_NEW_KEY == *lpdwDispositionLocal))
{
// NOTE; if create included subkeys \\connection\\clsid only the
// last key is set by SetRegSecurity.
#ifdef _SETSECURITY
SetRegKeySecurityEveryone(hKey,lpSubKey);
#endif // _SETSECURITY
}
}
#ifdef _SETSECURITY
if ((ERROR_ACCESS_DENIED == lResult) && (fSetSecurity) )
{
SyncMgrExecCmd_ResetRegSecurity();
lResult = RegCreateKeyExXp(hKey,lpSubKey,Reserved,lpClass,dwOptions,samDesired,
lpSecurityAttributes,phkResult,lpdwDisposition,FALSE /* fSetSecurity */);
}
#endif // _SETSECURITY
return lResult;
}
LONG
APIENTRY
RegCreateKeyExX(
HKEY hKey,
LPCWSTR lpSubKey,
DWORD Reserved,
LPWSTR lpClass,
DWORD dwOptions,
REGSAM samDesired,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
PHKEY phkResult,
LPDWORD lpdwDisposition
)
{
return RegCreateKeyExXp(hKey,lpSubKey,Reserved,lpClass,dwOptions,samDesired,
lpSecurityAttributes,phkResult,
lpdwDisposition,FALSE /* fSetSecurity */);
}
BOOL GetUserNameX(
LPWSTR lpBuffer,
LPDWORD pnSize
)
{
BOOL fReturn = FALSE;
if (g_fWideWrap_Unicode)
{
fReturn = GetUserNameW(lpBuffer,pnSize);
}
else
{
DWORD dwSizeA = *pnSize;
DWORD dwOldSize = dwSizeA;
XArray<CHAR> xszBufIn;
BOOL fOk = xszBufIn.Init( dwSizeA );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
fReturn = GetUserNameA( xszBufIn.Get(), &dwSizeA );
if (fReturn)
{
XArray<WCHAR> xwszBufOut;
fOk = ConvertMultiByteToWideChar( xszBufIn.Get(), xwszBufOut );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
*pnSize = lstrlenX(xwszBufOut.Get()) + 1;
if ( *pnSize < dwOldSize )
{
lstrcpyX( lpBuffer, xwszBufOut.Get() );
return TRUE;
}
else
{
SetLastError( ERROR_MORE_DATA );
return FALSE;
}
}
}
return fReturn;
}
UINT WINAPI RegisterWindowMessageX(LPCWSTR lpString)
{
UINT ret;
if (g_fWideWrap_Unicode)
{
ret = RegisterWindowMessageW(lpString);
return ret;
}
XArray<CHAR> xszString;
BOOL fOk = ConvertWideCharToMultiByte( lpString, xszString );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
ret = RegisterWindowMessageA( xszString.Get() );
return ret;
}
LONG
APIENTRY
RegOpenKeyExXp(
HKEY hKey,
LPCWSTR lpSubKey,
DWORD ulOptions,
REGSAM samDesired,
PHKEY phkResult,
BOOL fSetSecurity)
{
LONG ret;
if (g_fWideWrap_Unicode)
{
ret = RegOpenKeyExW( hKey, lpSubKey, ulOptions, samDesired, phkResult );
}
else
{
XArray<CHAR> xszSubKey;
BOOL fOk = ConvertWideCharToMultiByte( lpSubKey, xszSubKey );
if ( !fOk )
return ERROR_OUTOFMEMORY;
ret = RegOpenKeyExA(hKey, xszSubKey.Get(), ulOptions, samDesired, phkResult);
}
#ifdef _SETSECURITY
if ((ERROR_ACCESS_DENIED == ret) && (fSetSecurity) )
{
SyncMgrExecCmd_ResetRegSecurity();
ret = RegOpenKeyExXp(hKey,lpSubKey,ulOptions,samDesired,phkResult,FALSE /* fSetSecurity */);
}
#endif // _SETSECURITY
return ret;
}
LONG
APIENTRY
RegOpenKeyExX (
HKEY hKey,
LPCWSTR lpSubKey,
DWORD ulOptions,
REGSAM samDesired,
PHKEY phkResult
)
{
return RegOpenKeyExXp(hKey,lpSubKey,ulOptions,samDesired,phkResult,TRUE /* fSetSecurity */);
}
LONG
APIENTRY
RegQueryValueExX(
HKEY hKey,
LPCWSTR lpValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
)
{
LONG ret;
if (g_fWideWrap_Unicode)
{
ret = RegQueryValueExW( hKey, lpValueName, lpReserved, lpType, lpData, lpcbData );
return ret;
}
LPBYTE lpTempBuffer;
DWORD dwTempType;
DWORD cb, cbRequired;
LPSTR sz;
DWORD dwDataOldSize = 0;
if ( lpcbData != NULL )
dwDataOldSize = *lpcbData;
XArray<CHAR> xszValueName;
BOOL fOk = ConvertWideCharToMultiByte( lpValueName, xszValueName );
if ( !fOk )
return ERROR_OUTOFMEMORY;
sz = xszValueName.Get();
ret = RegQueryValueExA(hKey, sz, lpReserved, &dwTempType, NULL, &cb);
// If the caller was just asking for the size of the value, jump out
// now, without actually retrieving and converting the value.
if (lpData == NULL)
{
switch (dwTempType)
{
case REG_EXPAND_SZ:
case REG_MULTI_SZ:
case REG_SZ:
// Adjust size of buffer to report, to account for CHAR -> WCHAR
if (lpcbData != NULL)
*lpcbData = cb * sizeof(WCHAR);
break;
default:
if (lpcbData != NULL)
*lpcbData = cb;
break;
}
// Set the type, if required.
if (lpType != NULL)
{
*lpType = dwTempType;
}
goto Exit;
}
if (ret == ERROR_SUCCESS)
{
//
// Determine the size of buffer needed
//
switch (dwTempType)
{
case REG_EXPAND_SZ:
case REG_MULTI_SZ:
case REG_SZ:
cbRequired = cb * sizeof(WCHAR);
break;
default:
cbRequired = cb;
break;
}
// If the caller was asking for the value, but allocated too small
// of a buffer, set the buffer size and jump out.
if (lpcbData != NULL && *lpcbData < cbRequired)
{
// Adjust size of buffer to report, to account for CHAR -> WCHAR
*lpcbData = cbRequired;
// Set the type, if required.
if (lpType != NULL)
{
*lpType = dwTempType;
}
ret = ERROR_MORE_DATA;
goto Exit;
}
// Otherwise, retrieve and convert the value.
XArray<CHAR> xszTempBuffer;
XArray<WCHAR> xwszValueOut;
BOOL fOk;
switch (dwTempType)
{
case REG_EXPAND_SZ:
case REG_MULTI_SZ:
case REG_SZ:
fOk = xszTempBuffer.Init( cbRequired );
if ( !fOk )
return ERROR_OUTOFMEMORY;
lpTempBuffer = (BYTE *) xszTempBuffer.Get();
ret = RegQueryValueExA(hKey,
sz,
lpReserved,
&dwTempType,
lpTempBuffer,
&cb);
if (ret == ERROR_SUCCESS)
{
switch (dwTempType)
{
case REG_EXPAND_SZ:
case REG_SZ:
fOk = ConvertMultiByteToWideChar( (char *) lpTempBuffer,
cb,
xwszValueOut );
if ( !fOk )
return ERROR_OUTOFMEMORY;
*lpcbData = (lstrlenX(xwszValueOut.Get()) + 1) * sizeof(WCHAR);
if ( *lpcbData < dwDataOldSize )
lstrcpyX( (WCHAR *)lpData, xwszValueOut.Get() );
else
return ERROR_MORE_DATA;
// Set the type, if required.
if (lpType != NULL)
{
*lpType = dwTempType;
}
break;
case REG_MULTI_SZ:
AssertSz(0,"E_NOTIMPL");
#if MULTI_SZ
LPWSTR pwszTempWide;
LPSTR pszTempNarrow;
ULONG ulStringLength;
Assert( !"MultiToWideChar conversion is improper" );
pszTempNarrow = (LPSTR) lpTempBuffer;
pwszTempWide = (LPWSTR) lpData;
while (*pszTempNarrow != NULL)
{
ulStringLength = lstrlenA(pszTempNarrow) + 1;
AnsiToUnicode(pwszTempWide,
pszTempNarrow,
ulStringLength);
// Compiler will scale appropriately here
pszTempNarrow += ulStringLength;
pwszTempWide += ulStringLength;
}
*pwszTempWide = NULL; // let's not forget MULTI_SZ end NULL
#endif // MULTI_SZ
break;
}
}
break;
default:
//
// No conversion of out parameters needed. Just call narrow
// version with args passed in, and return directly.
//
ret = RegQueryValueExA(hKey,
sz,
lpReserved,
lpType,
lpData,
lpcbData);
}
}
Exit:
return ret;
}
HWND
WINAPI
CreateWindowExX( DWORD dwExStyle,
LPCWSTR lpClassName,
LPCWSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hWndParent ,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam )
{
HWND ret = NULL;
if (g_fWideWrap_Unicode)
{
ret = CreateWindowExW( dwExStyle,
lpClassName,
lpWindowName,
dwStyle,
X,
Y,
nWidth,
nHeight,
hWndParent,
hMenu,
hInstance,
lpParam );
return ret;
}
LPSTR szClass;
BOOL fOk;
XArray<CHAR> xszClass;
if (HIWORD(lpClassName) == 0)
szClass = (LPSTR) lpClassName;
else
{
fOk = ConvertWideCharToMultiByte( lpClassName, xszClass );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
szClass = xszClass.Get();
}
XArray<CHAR> xszWindow;
fOk = ConvertWideCharToMultiByte( lpWindowName, xszWindow );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
ret = CreateWindowExA ( dwExStyle,
szClass,
xszWindow.Get(),
dwStyle,
X,
Y,
nWidth,
nHeight,
hWndParent,
hMenu,
hInstance,
lpParam);
return ret;
}
#if 0
HWND
WINAPI
CreateWindowX( LPCWSTR lpClassName,
LPCWSTR lpWindowName,
DWORD dwStyle,
int X,
int Y,
int nWidth,
int nHeight,
HWND hWndParent ,
HMENU hMenu,
HINSTANCE hInstance,
LPVOID lpParam )
{
#ifdef DEBUG_OUTPUT
OutputDebugString("CreateWindow\n");
#endif
return CreateWindowExX(0, lpClassName, lpWindowName, dwStyle, X, Y,
nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
}
#endif
HWND WINAPI CreateDialogParamX(
HINSTANCE hInstance,
LPCWSTR lpwszTemplateName,
HWND hWndParent,
DLGPROC lpDialogFunc,
LPARAM dwInitParam
)
{
HWND hwndDialog = NULL;
if (g_fWideWrap_Unicode)
{
hwndDialog = CreateDialogParamW( hInstance,
lpwszTemplateName,
hWndParent,
lpDialogFunc,
dwInitParam );
return hwndDialog;
}
LPSTR pszTemplateName;
XArray<CHAR> xszTemplate;
if (HIWORD(lpwszTemplateName) == 0)
{
//
// Is it an atom?
//
pszTemplateName = (LPSTR) lpwszTemplateName;
}
else
{
//
// Otherwise convert the string
//
BOOL fOk = ConvertWideCharToMultiByte( lpwszTemplateName, xszTemplate );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
pszTemplateName = xszTemplate.Get();
}
if (pszTemplateName)
hwndDialog = CreateDialogParamA(hInstance,pszTemplateName,hWndParent,lpDialogFunc,dwInitParam);
return hwndDialog;
}
INT_PTR
WINAPI
DialogBoxParamX(
IN HINSTANCE hInstance,
IN LPCWSTR lpTemplateName,
IN HWND hWndParent,
IN DLGPROC lpDialogFunc,
IN LPARAM dwInitParam)
{
INT_PTR iReturn = -1;
if (g_fWideWrap_Unicode)
{
iReturn = DialogBoxParamW(hInstance,lpTemplateName,hWndParent,lpDialogFunc,dwInitParam);
}
else
{
LPSTR lpTemplateNameA;
Assert(0 == HIWORD(lpTemplateName)); // only support atoms
if (0 == HIWORD(lpTemplateName))
{
lpTemplateNameA = (LPSTR) lpTemplateName;
iReturn = DialogBoxParamA(hInstance,lpTemplateNameA,hWndParent,lpDialogFunc,dwInitParam);
}
}
return iReturn;
}
ATOM
WINAPI
RegisterClassX(
CONST WNDCLASSW *lpWndClass)
{
ATOM ret;
if (g_fWideWrap_Unicode)
{
ret = RegisterClassW( lpWndClass );
return ret;
}
WNDCLASSA wc;
Win4Assert(sizeof(WNDCLASSA) == sizeof(WNDCLASSW));
memcpy(&wc, lpWndClass, sizeof(WNDCLASS));
XArray<CHAR> xszMenu;
BOOL fOk = ConvertWideCharToMultiByte( lpWndClass->lpszMenuName, xszMenu );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
wc.lpszMenuName = xszMenu.Get();
XArray<CHAR> xszClass;
if (HIWORD(lpWndClass->lpszClassName) == 0)
wc.lpszClassName = (LPSTR) lpWndClass->lpszClassName;
else
{
fOk = ConvertWideCharToMultiByte( lpWndClass->lpszClassName, xszClass );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
wc.lpszClassName = xszClass.Get();
}
ret = RegisterClassA(&wc);
return ret;
}
#if 0
BOOL
WINAPI
UnregisterClassX(
LPCWSTR lpClassName,
HINSTANCE hInstance)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("UnregisterClass\n");
#endif
LPSTR sz;
BOOL ret;
BOOL fAtom = FALSE;
if (HIWORD(lpClassName) == 0)
{
sz = (LPSTR) lpClassName;
fAtom = TRUE;
}
else
{
sz = Convert(lpClassName);
if (sz == ERR)
return FALSE;
}
ret = UnregisterClassA(sz, hInstance);
if (!fAtom) FREE(sz);
return ret;
}
HANDLE
WINAPI
GetPropX(
HWND hWnd,
LPCWSTR lpString)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("GetProp\n");
#endif
HANDLE ret;
LPSTR sz;
BOOL fAtom = FALSE;
if (HIWORD(lpString)==0)
{
fAtom = TRUE;
sz = (LPSTR) lpString;
}
else
{
sz = Convert(lpString);
if (sz == ERR)
return NULL;
}
ret = GetPropA(hWnd, sz);
if (!fAtom) FREE(sz);
return ret;
}
BOOL
WINAPI
SetPropX(
HWND hWnd,
LPCWSTR lpString,
HANDLE hData)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("SetProp\n");
#endif
BOOL ret;
LPSTR sz;
BOOL fAtom = FALSE;
if (HIWORD(lpString)==0)
{
sz = (LPSTR) lpString;
fAtom = TRUE;
}
else
{
sz = Convert(lpString);
if (sz == ERR)
return NULL;
}
ret = SetPropA(hWnd, sz, hData);
if (!fAtom) FREE(sz);
return ret;
}
HANDLE
WINAPI
RemovePropX(
HWND hWnd,
LPCWSTR lpString)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RemoveProp\n");
#endif
HANDLE ret;
LPSTR sz;
BOOL fAtom = FALSE;
if (HIWORD(lpString)==0)
{
sz = (LPSTR) lpString;
fAtom = TRUE;
}
else
{
sz = Convert(lpString);
if (sz == ERR)
return NULL;
}
ret = RemovePropA(hWnd, sz);
if (!fAtom) FREE(sz);
return ret;
}
UINT
WINAPI
GetProfileIntX(
LPCWSTR lpAppName,
LPCWSTR lpKeyName,
INT nDefault
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("GetProfileInt\n");
#endif
LPSTR szApp;
LPSTR szKey;
UINT ret;
szApp = Convert(lpAppName);
if (szApp==ERR)
{
return nDefault;
}
szKey = Convert(lpKeyName);
if (szApp==ERR)
{
if (szApp)
FREE( szApp);
return nDefault;
}
ret = GetProfileIntA(szApp, szKey, nDefault);
if (szApp)
FREE( szApp);
if (szKey)
FREE( szKey);
return ret;
}
ATOM
WINAPI
GlobalAddAtomX(
LPCWSTR lpString
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("GlobalAddAtom\n");
#endif
ATOM ret;
LPSTR sz;
sz = Convert(lpString);
if (sz==ERR)
{
return NULL;
}
ret = GlobalAddAtomA(sz);
if (sz)
FREE(sz);
return ret;
}
UINT
WINAPI
GlobalGetAtomNameX(
ATOM nAtom,
LPWSTR pwszBuffer,
int nSize
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("GlobalGetAtomName\n");
#endif
LPSTR sz;
UINT ret;
sz = (char *) ALLOC(nSize*sizeof(char));
if (sz == NULL)
{
return 0;
}
ret = GlobalGetAtomNameA(nAtom, sz, nSize);
if (ret)
{
AnsiToUnicode(pwszBuffer, sz, lstrlenA(sz) + 1);
}
if (sz)
FREE(sz);
return ret;
}
#endif
DWORD
WINAPI
GetModuleFileNameX(
HINSTANCE hModule,
LPWSTR pwszFilename,
DWORD nSize
)
{
DWORD ret;
if (g_fWideWrap_Unicode)
{
ret = GetModuleFileNameW( hModule, pwszFilename, nSize );
return ret;
}
XArray<CHAR> xszFileName;
BOOL fOk = xszFileName.Init( nSize );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
ret = GetModuleFileNameA(hModule, xszFileName.Get(), nSize);
if (ret == 0 )
return ret;
XArray<WCHAR> xwszName;
fOk = ConvertMultiByteToWideChar( xszFileName.Get(), ret, xwszName );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
ret = lstrlenX( xwszName.Get() );
if ( ret >= nSize)
{
//
// Truncate to fit
//
ret = nSize -1;
lstrcpynX( pwszFilename, xwszName.Get(), ret );
pwszFilename[ret] = 0;
}
else
lstrcpyX( pwszFilename, xwszName.Get() );
return ret;
}
#if 0
LPWSTR
WINAPI
CharPrevX(
LPCWSTR lpszStart,
LPCWSTR lpszCurrent)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("CharPrev\n");
#endif
if (lpszCurrent == lpszStart)
{
return (LPWSTR) lpszStart;
}
else
{
return (LPWSTR) lpszCurrent - 1;
}
}
HFONT WINAPI CreateFontX(int a, int b, int c, int d, int e, DWORD f,
DWORD g, DWORD h, DWORD i, DWORD j, DWORD k,
DWORD l, DWORD m, LPCWSTR pwsz)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("CreateFont\n");
#endif
LPSTR sz;
HFONT ret;
sz = Convert(pwsz);
if (sz == ERR)
{
return NULL;
}
ret = CreateFontA(a,b,c,d,e,f,g,h,i,j,k,l,m,sz);
if (sz)
FREE(sz);
return ret;
}
#endif
HINSTANCE
WINAPI
LoadLibraryX(
LPCWSTR pwszFileName
)
{
HINSTANCE ret;
if (g_fWideWrap_Unicode)
{
ret = LoadLibraryW( pwszFileName );
return ret;
}
XArray<CHAR> xszName;
BOOL fOk = ConvertWideCharToMultiByte( pwszFileName, xszName, TRUE );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
ret = LoadLibraryA( xszName.Get() );
return ret;
}
#if 0
HMODULE
WINAPI
LoadLibraryExX(
LPCWSTR lpLibFileName,
HANDLE hFile,
DWORD dwFlags
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("LoadLibrary\n");
#endif
HINSTANCE ret;
LPSTR sz;
sz = ConvertOem(lpLibFileName);
if (sz == ERR)
{
return NULL;
}
ret = LoadLibraryExA(sz, hFile, dwFlags);
if (sz)
FREE(sz);
return ret;
}
#endif
LONG
APIENTRY
RegDeleteKeyXp(
HKEY hKey,
LPCWSTR pwszSubKey,
BOOL fSetSecurity
)
{
LONG ret;
if (g_fWideWrap_Unicode)
{
ret = RegDeleteKeyW( hKey, pwszSubKey );
}
else
{
XArray<CHAR> xszSubKey;
BOOL fOk = ConvertWideCharToMultiByte( pwszSubKey, xszSubKey );
if ( !fOk )
return ERROR_OUTOFMEMORY;
ret = RegDeleteKeyA(hKey, xszSubKey.Get() );
}
if ((ERROR_ACCESS_DENIED == ret) && (fSetSecurity) )
{
SyncMgrExecCmd_ResetRegSecurity();
ret = RegDeleteKeyXp(hKey,pwszSubKey,FALSE /*fSetSecurity*/);
}
return ret;
}
LONG
APIENTRY
RegDeleteKeyX(
HKEY hKey,
LPCWSTR pwszSubKey
)
{
return RegDeleteKeyXp(hKey,pwszSubKey,TRUE /*fSetSecurity*/);
}
BOOL
APIENTRY
CreateProcessX(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
{
BOOL ret = FALSE;
if (g_fWideWrap_Unicode)
{
ret = CreateProcessW( lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation );
return ret;
}
STARTUPINFOA si;
LPSTR szApp = NULL;
LPSTR szCommand = NULL;
LPSTR szDir = NULL;
memcpy(&si, lpStartupInfo, sizeof(STARTUPINFO));
si.lpTitle = NULL;
XArray<CHAR> xszDesktop;
BOOL fOk = ConvertWideCharToMultiByte( lpStartupInfo->lpDesktop, xszDesktop );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
si.lpDesktop = xszDesktop.Get();
XArray<CHAR> xszTitle;
fOk = ConvertWideCharToMultiByte( lpStartupInfo->lpTitle, xszTitle );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
si.lpTitle = xszTitle.Get();
XArray<CHAR> xszAppName;
fOk = ConvertWideCharToMultiByte( lpApplicationName, xszAppName, TRUE );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
szApp = xszAppName.Get();
XArray<CHAR> xszCommand;
fOk = ConvertWideCharToMultiByte( lpCommandLine, xszCommand, TRUE );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
szCommand = xszCommand.Get();
XArray<CHAR> xszCurDir;
fOk = ConvertWideCharToMultiByte( lpCurrentDirectory, xszCurDir, TRUE );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
szDir = xszCurDir.Get();
ret = CreateProcessA(szApp, szCommand, lpProcessAttributes,
lpThreadAttributes, bInheritHandles, dwCreationFlags,
lpEnvironment, szDir, &si, lpProcessInformation);
return ret;
}
LONG
APIENTRY
RegEnumKeyExX(
HKEY hKey,
DWORD dwIndex,
LPWSTR lpName,
LPDWORD lpcbName,
LPDWORD lpReserved,
LPWSTR lpClass,
LPDWORD lpcbClass,
PFILETIME lpftLastWriteTime
)
{
LONG ret = ERROR_OUTOFMEMORY;
if (g_fWideWrap_Unicode)
{
ret = RegEnumKeyExW( hKey,
dwIndex,
lpName,
lpcbName,
lpReserved,
lpClass,
lpcbClass,
lpftLastWriteTime );
return ret;
}
LPSTR szName;
XArray<CHAR> xszName;
BOOL fOk = xszName.Init( *lpcbName );
if ( !fOk )
return ERROR_OUTOFMEMORY;
szName = xszName.Get();
DWORD dwNameOldSize = *lpcbName;
DWORD dwClassOldSize = 0;
LPSTR szClass = NULL;
XArray<CHAR> xszClass;
if (lpClass != NULL)
{
fOk = xszClass.Init( *lpcbClass );
if ( !fOk )
return ERROR_OUTOFMEMORY;
szClass = xszClass.Get();
dwClassOldSize = *lpcbClass;
}
//
// Return lengths do not include zero char.
//
ret = RegEnumKeyExA(hKey, dwIndex, szName, lpcbName, lpReserved,
szClass, lpcbClass, lpftLastWriteTime);
if (ret == ERROR_SUCCESS)
{
XArray<WCHAR> xwszNameOut;
fOk = ConvertMultiByteToWideChar( szName,
*lpcbName + 1,
xwszNameOut );
if ( !fOk )
return ERROR_OUTOFMEMORY;
if ( lstrlenX(xwszNameOut.Get()) < dwNameOldSize )
lstrcpyX( lpName, xwszNameOut.Get() );
else
return ERROR_MORE_DATA;
if (szClass)
{
XArray<WCHAR> xwszClassOut;
fOk = ConvertMultiByteToWideChar( szClass,
*lpcbClass + 1,
xwszClassOut );
if ( !fOk )
return ERROR_OUTOFMEMORY;
if ( lstrlenX(xwszClassOut.Get()) < dwClassOldSize)
lstrcpyX( lpClass, xwszClassOut.Get() );
else
return ERROR_MORE_DATA;
}
}
return ret;
}
#if 0
BOOL
WINAPI
AppendMenuX(
HMENU hMenu,
UINT uFlags,
UINT uIDnewItem,
LPCWSTR lpnewItem
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("AppendMenu\n");
#endif
BOOL ret;
LPSTR sz;
if (uFlags == MF_STRING)
{
sz = Convert(lpnewItem);
if (sz==ERR)
{
return FALSE;
}
}
else
{
sz = (LPSTR) lpnewItem;
}
ret = AppendMenuA(hMenu, uFlags, uIDnewItem, sz);
if (uFlags == MF_STRING)
{
if (sz)
FREE(sz);
}
return ret;
}
HANDLE
WINAPI
OpenEventX(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCWSTR lpName
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("OpenEvent\n");
#endif
LPSTR sz;
HANDLE ret;
sz = Convert(lpName);
if (sz == ERR)
{
return NULL;
}
ret = OpenEventA(dwDesiredAccess, bInheritHandle, sz);
if (sz)
FREE(sz);
return ret;
}
#endif
HANDLE
WINAPI
CreateEventX(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCWSTR lpName
)
{
HANDLE ret;
if (g_fWideWrap_Unicode)
{
ret = CreateEventW( lpEventAttributes,
bManualReset,
bInitialState,
lpName );
return ret;
}
XArray<CHAR> xszName;
BOOL fOk = ConvertWideCharToMultiByte( lpName, xszName );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
ret = CreateEventA(lpEventAttributes, bManualReset, bInitialState, xszName.Get() );
return ret;
}
HANDLE
WINAPI
CreateMutexX(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bInitialOwner,
LPCWSTR lpName
)
{
HANDLE ret;
if (g_fWideWrap_Unicode)
{
ret = CreateMutexW( lpEventAttributes,
bInitialOwner,
lpName );
return ret;
}
XArray<CHAR> xszName;
BOOL fOk = ConvertWideCharToMultiByte( lpName, xszName );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
ret = CreateMutexA(lpEventAttributes,bInitialOwner, xszName.Get() );
return ret;
}
#if 0
UINT
WINAPI
GetDriveTypeX(
LPCWSTR lpRootPathName
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("GetDriveType\n");
#endif
LPSTR sz;
UINT ret;
sz = ConvertOem(lpRootPathName);
if (sz == ERR)
{
return 0;
}
ret = GetDriveTypeA(sz);
if (sz)
FREE(sz);
return ret;
}
DWORD
WINAPI
GetFileAttributesX(
LPCWSTR lpFileName
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("GetFileAttributes\n");
#endif
LPSTR sz;
DWORD ret;
sz = ConvertOem(lpFileName);
if (sz == ERR)
return 0xFFFFFFFF;
ret = GetFileAttributesA(sz);
if (sz)
FREE(sz);
return ret;
}
#endif
LONG
APIENTRY
RegEnumKeyX(
HKEY hKey,
DWORD dwIndex,
LPWSTR lpName,
DWORD cbName
)
{
LONG ret;
if (g_fWideWrap_Unicode)
{
ret = RegEnumKeyW( hKey,
dwIndex,
lpName,
cbName );
return ret;
}
CHAR sz[MAX_PATH+1];
//
// Return lengths do not include zero char.
//
Assert( cbName <= MAX_PATH + 1 );
ret = RegEnumKeyA(hKey, dwIndex, sz, cbName);
if (ret == ERROR_SUCCESS)
{
XArray<WCHAR> xwszName;
BOOL fOk = ConvertMultiByteToWideChar( sz, xwszName );
if ( !fOk )
return ERROR_OUTOFMEMORY;
if ( lstrlenX(xwszName.Get()) < cbName)
{
lstrcpyX( lpName, xwszName.Get() );
}
else
return ERROR_MORE_DATA;
}
return ret;
}
#if 0
LONG
APIENTRY
RegEnumValueX(
HKEY hkey,
DWORD dwIndex,
LPWSTR wszName,
LPDWORD pcbName,
LPDWORD pReserved,
LPDWORD ptype,
LPBYTE pValue,
LPDWORD pcbValue)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RegEnumValue\n");
#endif
// CHAR szName[KEY_LEN+1];
CHAR szName[MAX_PATH+1]; // reiview this length
LONG ret;
DWORD dwGivenSize= *pcbName;
Win4Assert(dwGivenSize <= MAX_PATH+1);
//
// Return lengths do not include zero char.
//
ret = RegEnumValueA(hkey, dwIndex, szName, pcbName, pReserved, ptype, pValue, pcbValue);
if (ret == ERROR_SUCCESS)
{
AnsiToUnicode(wszName, szName, dwGivenSize);
}
return ret;
}
HFINDFILE
WINAPI
FindFirstFileX(
LPCWSTR lpFileName,
LPWIN32_FIND_DATAW pwszFd
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("FindFirstFile\n");
#endif
WIN32_FIND_DATAA fd;
CHAR sz[MAX_PATH * 2];
HFINDFILE ret;
int len = lstrlenX(lpFileName) + 1;
UnicodeToAnsiOem(sz, lpFileName, sizeof(sz));
ret = FindFirstFileA(sz, &fd);
if (ret != INVALID_HANDLE_VALUE)
{
memcpy(pwszFd, &fd, sizeof(FILETIME)*3 + sizeof(DWORD)*5);
AnsiToUnicodeOem(pwszFd->cFileName, fd.cFileName,
lstrlenA(fd.cFileName) + 1);
AnsiToUnicodeOem(pwszFd->cAlternateFileName, fd.cAlternateFileName,
14);
}
return ret;
}
#endif
//+---------------------------------------------------------------------------
//
// Function: wsprintfX
//
// Synopsis: internal implementation of wsprintf
//
// Arguments: [pwszOut] --
// [pwszFormat] --
// [...] --
//
// Returns: size of string.
//
// History: 26-Aug-98 Rogerg
//
//
//----------------------------------------------------------------------------
#ifndef _M_ALPHA
int WINAPIV wsprintfX(LPWSTR pwszOut, LPCWSTR pwszFormat, ...)
{
va_list arglist;
LPCWSTR pwszFmtPos;
LPWSTR pwszBufPos;
ULONG cbSkipLen;
// need to loop through format pushing items into the out buffer.
// Then use the out buffer string as what is actually passed to
// the real API.
pwszFmtPos = pwszFormat;
pwszBufPos = pwszOut;
va_start(arglist, pwszFormat);
while (*pwszFmtPos) {
cbSkipLen = 0;
if (*(pwszFmtPos) == '%')
{
switch (*(pwszFmtPos + 1))
{
case 'l':
{
Assert('u' == *(pwszFmtPos + 2));
cbSkipLen = 3; // go ahead and skip %lu
//fall through
}
case 'u':
{
DWORD dw = va_arg(arglist,ULONG);
_ltow(dw, pwszBufPos, 10 );
pwszBufPos += lstrlenX(pwszBufPos);
if (0 == cbSkipLen)
{
cbSkipLen = 2; // if no %lu case, skip %u
}
break;
}
case 'w':
{
Assert('s' == *(pwszFmtPos + 2));
cbSkipLen = 3; // go ahead and skip %ws
// fall through
}
case 's':
{
DWORD cch;
WCHAR *pwsz = va_arg(arglist, LPWSTR);
if (0 == cbSkipLen)
{
cbSkipLen = 2; // if no %ws case, skip %s
}
Assert(pwsz);
if (pwsz)
{
cch = lstrlenX(pwsz);
lstrcpynX(pwszBufPos,pwsz,cch);
pwszBufPos += cch;
}
break;
}
case 'd':
{
DWORD dw = va_arg(arglist,long);
_itow(dw, pwszBufPos, 10 );
pwszBufPos += lstrlenX(pwszBufPos);
cbSkipLen = 2; // go ahead and skip %d
break;
}
default:
AssertSz(0,"Uknown % passed to wsprintf");
break;
}
}
if (cbSkipLen)
{
pwszFmtPos += cbSkipLen;
}
else
{
*pwszBufPos = *pwszFmtPos;
*pwszBufPos++;
*pwszFmtPos++;
}
}
*pwszBufPos = NULL; // terminate the string.
return lstrlenX(pwszOut);
}
#endif // #ifndef _M_ALPHA
BOOL
WINAPI
GetComputerNameX(
LPWSTR pwszName,
LPDWORD lpcchBuffer
)
{
BOOL ret;
if (g_fWideWrap_Unicode)
{
ret = GetComputerNameW( pwszName, lpcchBuffer );
return ret;
}
DWORD OldSize = *lpcchBuffer;
XArray<CHAR> xszNameIn;
BOOL fOk = xszNameIn.Init( OldSize );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
ret = GetComputerNameA( xszNameIn.Get(), lpcchBuffer );
if ( ret == 0 )
return ret;
XArray<WCHAR> xwszNameOut;
fOk = ConvertMultiByteToWideChar( xszNameIn.Get(), xwszNameOut );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
*lpcchBuffer = lstrlenX( xwszNameOut.Get() );
if ( *lpcchBuffer < OldSize - 1 )
{
lstrcpyX( pwszName, xwszNameOut.Get() );
return ret;
}
else
{
SetLastError( ERROR_MORE_DATA );
return 0;
}
}
LRESULT
DefWindowProcX(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam)
{
if (g_fWideWrap_Unicode)
{
return DefWindowProcW(hWnd,Msg,wParam,lParam);
}
else
{
return DefWindowProcA(hWnd,Msg,wParam,lParam);
}
}
#if 0
DWORD
WINAPI
GetFullPathNameX(
LPCWSTR lpFileName,
DWORD cchBuffer,
LPWSTR lpPathBuffer,
LPWSTR *lppFilePart
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("GetFullPathName\n");
#endif
LPSTR szFileName;
CHAR szPathBuffer[MAX_PATH];
LPSTR szFilePart;
DWORD ret;
szFileName = ConvertOem(lpFileName);
if (szFileName == ERR)
return 0;
ret = GetFullPathNameA(szFileName, cchBuffer, szPathBuffer, &szFilePart);
AnsiToUnicodeOem(lpPathBuffer, szPathBuffer, cchBuffer);
*lppFilePart = lpPathBuffer + (szFilePart - szPathBuffer);
if (szFileName)
FREE( szFileName);
return ret;
}
DWORD
WINAPI
GetShortPathNameX(
LPCWSTR lpszFullPath,
LPWSTR lpszShortPath,
DWORD cchBuffer
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("GetShortPathName\n");
#endif
LPSTR szFullPath;
CHAR szShortBuffer[MAX_PATH];
DWORD ret;
szFullPath = Convert(lpszFullPath);
if (szFullPath == ERR)
return 0;
if (lpszShortPath == NULL)
{
ret = GetShortPathNameA(szFullPath, NULL, cchBuffer);
}
else
{
ret = GetShortPathNameA(szFullPath, szShortBuffer, sizeof(szShortBuffer));
if (ret != 0)
{
//
// Only convert the actual data, not the whole buffer.
//
if (cchBuffer > ret + 1)
cchBuffer = ret + 1;
AnsiToUnicode(lpszShortPath, szShortBuffer, cchBuffer);
}
}
FREE( szFullPath);
return ret;
}
#endif
DWORD
WINAPI
SearchPathX(
LPCWSTR lpPath,
LPCWSTR lpFileName,
LPCWSTR lpExtension,
DWORD nBufferLength,
LPWSTR lpBuffer,
LPWSTR *lpFilePart
)
{
DWORD ret;
if (g_fWideWrap_Unicode)
{
ret = SearchPathW( lpPath,
lpFileName,
lpExtension,
nBufferLength,
lpBuffer,
lpFilePart );
return ret;
}
LPSTR lpszFileName;
CHAR szBuffer[MAX_PATH];
XArray<CHAR> xszFileName;
BOOL fOk = ConvertWideCharToMultiByte( lpFileName, xszFileName, TRUE );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
lpszFileName = xszFileName.Get();
ret = SearchPathA(NULL, lpszFileName, NULL, sizeof(szBuffer), szBuffer, NULL);
if ( ret == 0 )
return ret;
XArray<WCHAR> xwszBufOut;
fOk = ConvertMultiByteToWideChar( szBuffer, xwszBufOut, TRUE );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
if ( lstrlenX(xwszBufOut.Get()) < nBufferLength )
{
lstrcpyX( lpBuffer, xwszBufOut.Get() );
return ret;
}
else
{
SetLastError( ERROR_MORE_DATA );
return 0;
}
return ret;
}
#if 0
ATOM
WINAPI
GlobalFindAtomX(
LPCWSTR lpString
)
{
LPSTR lpszString;
ATOM retAtom;
#ifdef DEBUG_OUTPUT
OutputDebugString("GlobalFindAtom\n");
#endif
lpszString = Convert(lpString);
if (lpszString == ERR)
return 0;
retAtom = GlobalFindAtomA(lpszString);
FREE( lpszString);
return retAtom;
}
int
WINAPI
GetClassNameX(
HWND hWnd,
LPWSTR lpClassName,
int nMaxCount)
{
LPSTR lpszClassName = NULL;
int ret;
#ifdef DEBUG_OUTPUT
OutputDebugString("GetClassName\n");
#endif
lpszClassName = (CHAR *) ALLOC(nMaxCount);
if (lpszClassName == NULL)
{
SetLastError (ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
ret = GetClassNameA(hWnd, lpszClassName, nMaxCount);
if (ret)
{
AnsiToUnicode(lpClassName, lpszClassName, lstrlenA(lpszClassName) + 1);
}
FREE( lpszClassName);
return ret;
}
LPWSTR
WINAPI
CharLowerX(
LPWSTR lpsz)
{
if (((DWORD)lpsz & 0xffff0000) == 0)
{
return (LPWSTR)towlower ((wchar_t)lpsz);
} else {
return _wcslwr (lpsz);
}
}
LPWSTR
WINAPI
CharUpperX(
LPWSTR lpsz)
{
if (((DWORD)lpsz & 0xffff0000) == 0)
{
return (LPWSTR)towupper ((wchar_t)lpsz);
} else {
return _wcsupr (lpsz);
}
}
BOOL
WINAPI
GetStringTypeX(
DWORD dwInfoType,
LPCWSTR lpSrcStr,
int cchSrc,
LPWORD lpCharType)
{
// Convert the source string to MBS. If we don't get the same number
// of characters, this algorithm doesn't work.
int OriginalLength = cchSrc == -1 ? lstrlenX (lpSrcStr) + 1 : cchSrc;
LPSTR lpConvertedString = (LPSTR) ALLOC(OriginalLength+1);
if (lpConvertedString == NULL)
{
SetLastError (ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
if (WideCharToMultiByte (CP_ACP,
WC_COMPOSITECHECK,
lpSrcStr,
cchSrc,
lpConvertedString,
OriginalLength,
NULL,
NULL) != OriginalLength)
{
FREE( lpConvertedString);
SetLastError (ERROR_NO_UNICODE_TRANSLATION);
return FALSE;
}
BOOL Result;
Result = GetStringTypeA (GetThreadLocale (),
dwInfoType,
lpConvertedString,
OriginalLength,
lpCharType);
FREE( lpConvertedString);
return Result;
}
BOOL
WINAPI
IsCharAlphaX(
WCHAR ch)
{
return iswctype (ch, _UPPER | _LOWER);
}
BOOL
WINAPI
IsCharAlphaNumericX(
WCHAR ch)
{
return iswctype (ch, _UPPER | _LOWER | _DIGIT);
}
#endif
LPWSTR
WINAPI
lstrcatX(
LPWSTR lpString1,
LPCWSTR lpString2
)
{
LPWSTR lpDest = lpString1;
Assert(lpString1);
Assert(lpString2);
while (*lpDest) {
lpDest++;
}
while (*lpDest++ = *lpString2++) ;
return lpString1;
}
int
WINAPI
lstrcmpX(
LPCWSTR lpString1,
LPCWSTR lpString2
)
{
Assert(lpString1);
Assert(lpString2);
return wcscmp(lpString1, lpString2);
}
int
strnicmpX(
LPWSTR lpString1,
LPWSTR lpString2,
size_t count
)
{
int nRet = 0;
Assert(lpString1);
Assert(lpString2);
while (count-- &&
!(nRet = toupper(*lpString1)
- toupper(*lpString2)) &&
*lpString1)
{
lpString1++;
lpString2++;
}
return nRet;
}
LPWSTR
WINAPI
lstrcpyX(
LPWSTR lpString1,
LPCWSTR lpString2
)
{
LPWSTR lpDest = lpString1;
Assert(lpString1);
Assert(lpString2);
while( *lpDest++ = *lpString2++ )
;
return lpString1;
}
LPWSTR
WINAPI
lstrcpynX(
LPWSTR lpString1,
LPCWSTR lpString2,
int iMaxLength
)
{
LPWSTR dst;
Assert(lpString1);
Assert(lpString2);
if (iMaxLength)
{
dst = lpString1;
while (iMaxLength && *lpString2)
{
*dst++ = *lpString2++;
iMaxLength--;
}
*dst = L'\0';
}
return lpString1;
}
int
WINAPI
lstrcmpiX(
LPCWSTR lpString1,
LPCWSTR lpString2
)
{
Assert(lpString1);
Assert(lpString2);
return _wcsicmp(lpString1, lpString2);
}
DWORD
WINAPI
lstrlenX(
LPCWSTR lpString
)
{
LPWSTR eos = (LPWSTR) lpString;
Assert(lpString)
if (!lpString)
return 0;
__try
{
while (*eos++);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
AssertSz(0,"Invalid String");
return 0;
}
return (int) (eos - lpString - 1);
}
BOOL
WINAPI
SetFileAttributesX(
LPCWSTR lpFileName,
DWORD dwFileAttributes
)
{
BOOL fReturn = FALSE;
if (g_fWideWrap_Unicode)
{
return SetFileAttributesW(lpFileName,dwFileAttributes);
}
else
{
XArray<CHAR> xszFileName;
BOOL fOk;
fOk = ConvertWideCharToMultiByte(lpFileName,xszFileName);
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
fReturn = SetFileAttributesA(xszFileName.Get(),dwFileAttributes);
}
return fReturn;
}
int
WINAPI
MessageBoxX(
HWND hWnd,
LPCWSTR lpText,
LPCWSTR lpCaption,
UINT uType)
{
int iReturn = 0; // MessageBox returns 0 if fails because out of memory
if (g_fWideWrap_Unicode)
{
return MessageBoxW(hWnd,lpText,lpCaption,uType);
}
else
{
XArray<CHAR> xszText;
XArray<CHAR> xszCaption;
BOOL fOkText,fOkCaption;
Assert(lpText && lpCaption);
fOkText = ConvertWideCharToMultiByte(lpText,xszText);
fOkCaption = ConvertWideCharToMultiByte(lpCaption,xszCaption);
if (!fOkText || !fOkCaption)
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
iReturn = MessageBoxA(hWnd,xszText.Get(),xszCaption.Get(),uType);
}
return iReturn;
}
#if 0
HANDLE
WINAPI
CreateFileMappingX(
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCWSTR lpName
)
{
LPSTR lpszAName=NULL;
HANDLE ret;
#ifdef DEBUG_OUTPUT
OutputDebugString("CreateFileMapping\n");
#endif
lpszAName = Convert(lpName);
if (lpszAName == ERR)
{
return 0;
}
ret = CreateFileMappingA(
hFile,
lpFileMappingAttributes,
flProtect,
dwMaximumSizeHigh,
dwMaximumSizeLow,
lpszAName);
if(NULL != lpszAName)
FREE( lpszAName);
return ret;
}
HANDLE
WINAPI
OpenFileMappingX(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCWSTR lpName
)
{
LPSTR lpszAName=NULL;
HANDLE ret;
#ifdef DEBUG_OUTPUT
OutputDebugString("CreateFileMapping\n");
#endif
lpszAName = Convert(lpName);
if (lpszAName == ERR)
{
return 0;
}
ret = OpenFileMappingA(
dwDesiredAccess,
bInheritHandle,
lpszAName);
if(NULL != lpszAName)
FREE( lpszAName);
return ret;
}
#endif
DWORD_PTR
WINAPI
SHGetFileInfoX(
LPCWSTR pszPath,
DWORD dwFileAttributes,
SHFILEINFOW FAR *psfi,
UINT cbFileInfo,
UINT uFlags)
{
DWORD_PTR dw = 0;
LoadShell32Dll();
if (g_fWideWrap_Unicode && g_pfShGetFileInfoW)
{
dw = g_pfShGetFileInfoW( pszPath,
dwFileAttributes,
psfi,
cbFileInfo,
uFlags );
return dw;
}
if (NULL == g_pfShGetFileInfoA)
{
Assert(g_pfShGetFileInfoA); // should always have the ansi export
return 0;
}
XArray<CHAR> xszPath;
BOOL fOk = ConvertWideCharToMultiByte( pszPath, xszPath, TRUE );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
SHFILEINFOA sfi;
Assert(cbFileInfo == sizeof(SHFILEINFOW));
Assert(psfi);
memset(&sfi, 0, sizeof(sfi));
dw = g_pfShGetFileInfoA( xszPath.Get(), dwFileAttributes, &sfi, sizeof(sfi), uFlags);
if (dw)
{
psfi->hIcon = sfi.hIcon;
psfi->iIcon = sfi.iIcon;
psfi->dwAttributes = sfi.dwAttributes;
XArray<WCHAR> xwszDisplay;
fOk = ConvertMultiByteToWideChar( sfi.szDisplayName, xwszDisplay, TRUE );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
XArray<WCHAR> xwszType;
fOk = ConvertMultiByteToWideChar( sfi.szTypeName, xwszType, TRUE );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
if ( lstrlenX(xwszDisplay.Get()) < ARRAY_SIZE(psfi->szDisplayName)
&& lstrlenX(xwszType.Get()) < ARRAY_SIZE(psfi->szTypeName) )
{
lstrcpyX( psfi->szDisplayName, xwszDisplay.Get() );
lstrcpyX( psfi->szTypeName, xwszType.Get() );
return dw;
}
else
return 0;
}
return 0;
}
HICON LoadIconX(
HINSTANCE hInstance,
LPCWSTR lpIconName
)
{
Assert(0 == HIWORD(lpIconName)); // only support resource IDs
return LoadIconA(hInstance,(LPSTR) lpIconName);
}
HCURSOR LoadCursorX(
HINSTANCE hInstance,
LPCWSTR lpCursorName
)
{
Assert(0 == HIWORD(lpCursorName)); // only support resource IDs
return LoadCursorA(hInstance,(LPSTR) lpCursorName);
}
HANDLE LoadImageX(
HINSTANCE hinst,
LPCWSTR lpszName,
UINT uType,
int cxDesired,
int cyDesired,
UINT fuLoad
)
{
HANDLE hReturn = NULL;
if (g_fWideWrap_Unicode)
{
return LoadImageW(hinst,lpszName,uType,cxDesired,cyDesired,fuLoad);
}
else
{
XArray<CHAR> xszName;
LPSTR pszNameA;
BOOL fOk = TRUE;
Assert(lpszName);
if (0 == HIWORD(lpszName))
{
pszNameA = (LPSTR) lpszName;
}
else
{
fOk = ConvertWideCharToMultiByte(lpszName,xszName);
if (!fOk)
{
SetLastError(E_OUTOFMEMORY);
return NULL;
}
pszNameA = xszName.Get();
}
hReturn = LoadImageA(hinst,pszNameA,uType,cxDesired,cyDesired,fuLoad);
}
return hReturn;
}
HRSRC FindResourceX(
HMODULE hModule,
LPCWSTR lpName,
LPCWSTR lpType
)
{
HRSRC hResult = NULL;
if (g_fWideWrap_Unicode)
{
return FindResourceW(hModule,lpName,lpType);
}
else
{
XArray<CHAR> xszName;
XArray<CHAR> xszType;
LPSTR pszNameA,pszTypeA;
BOOL fOkName = TRUE,fOkType = TRUE;
Assert(lpType && lpName);
// if hiword is zero it is an ID
if (0 == HIWORD(lpName))
{
pszNameA = (LPSTR) lpName;
}
else
{
fOkName = ConvertWideCharToMultiByte(lpName,xszName);
}
if (0 == HIWORD(lpType))
{
pszTypeA = (LPSTR) lpType;
}
else
{
fOkType = ConvertWideCharToMultiByte(lpType,xszType);
}
if (!fOkName || !fOkType)
{
SetLastError(E_OUTOFMEMORY);
return NULL;
}
hResult = FindResourceA(hModule,pszNameA,pszTypeA);
}
return hResult;
}
BOOL
WINAPI
Shell_NotifyIconX(
DWORD dwMessage,
PNOTIFYICONDATAW lpData)
{
BOOL fResult = FALSE;
LoadShell32Dll();
if (g_fWideWrap_Unicode && g_pfShell_NotifyIconW)
{
fResult = g_pfShell_NotifyIconW( dwMessage, lpData );
return fResult;
}
if (NULL == g_pfShell_NotifyIconA)
{
Assert(g_pfShell_NotifyIconA); // should always have the ansi export
return FALSE;
}
NOTIFYICONDATAA DataA;
DataA.cbSize = sizeof(NOTIFYICONDATAA);
DataA.hWnd = lpData->hWnd;
DataA.uID = lpData->uID;
DataA.uFlags = lpData->uFlags;
DataA.uCallbackMessage = lpData->uCallbackMessage;
DataA.hIcon = lpData->hIcon;
*DataA.szTip = '\0';
if (DataA.uFlags & NIF_TIP)
{
XArray<CHAR> xszTip;
BOOL fOk = ConvertWideCharToMultiByte( lpData->szTip, xszTip );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
ULONG ccLen = lstrlenA( xszTip.Get() );
if ( ccLen >= ARRAY_SIZE(DataA.szTip) )
ccLen = ARRAY_SIZE(DataA.szTip) - 1;
strncpy( DataA.szTip, xszTip.Get(), ccLen+1 );
}
fResult = g_pfShell_NotifyIconA(dwMessage,&DataA);
return fResult;
}
// helper function for sending listview item messages
BOOL ListView_SendItemMessage(HWND hwnd,UINT MsgW,UINT MsgA,LV_ITEMW *pItem,
BOOL fInParam,BOOL fOutParam)
{
BOOL fReturn = FALSE;
if (g_fWideWrap_Unicode /* ListView_GetUnicodeFormat(hwnd) */)
{
fReturn = (BOOL)SendMessageW((hwnd), MsgW, 0, (LPARAM)(LV_ITEMW FAR*)(pItem));
}
else
{
LV_ITEMA itemA;
Assert(sizeof(LV_ITEMA) == sizeof(LV_ITEMW))
memcpy(&itemA,pItem,sizeof(LV_ITEMA));
DWORD dwOldSize = pItem->cchTextMax;
BOOL fOk;
XArray<CHAR> xszText;
if ((itemA.mask & LVIF_TEXT) && (LPSTR_TEXTCALLBACKA != itemA.pszText))
{
itemA.pszText = NULL;
if (fInParam)
{
fOk = ConvertWideCharToMultiByte( pItem->pszText, xszText );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
itemA.pszText = xszText.Get();
itemA.cchTextMax = lstrlenA(itemA.pszText) + 1;
}
else
{
fOk = xszText.Init( itemA.cchTextMax );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
itemA.pszText = xszText.Get();
}
}
if (itemA.pszText || !(itemA.mask & LVIF_TEXT) )
{
fReturn = (BOOL)SendMessageA((hwnd), MsgA, 0, (LPARAM)(LV_ITEMA FAR*)(&itemA));
if (fOutParam && fReturn)
{
LPWSTR pszTextW = pItem->pszText;
memcpy(pItem,&itemA,sizeof(LV_ITEMA));
pItem->pszText = pszTextW;
if ( (itemA.mask & LVIF_TEXT) )
{
XArray<WCHAR> xwszTextOut;
fOk = ConvertMultiByteToWideChar( itemA.pszText, xwszTextOut );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
if ( lstrlenX(xwszTextOut.Get()) >= dwOldSize )
return FALSE;
lstrcpyX( pItem->pszText, xwszTextOut.Get() );
}
}
}
}
return fReturn;
}
BOOL
ListView_GetItemX(
HWND hwnd,
LV_ITEM * pitem)
{
return ListView_SendItemMessage(hwnd,LVM_GETITEMW,LVM_GETITEMA,pitem,FALSE,TRUE);
}
BOOL
ListView_SetItemX(
HWND hwnd,
LV_ITEM * pitem)
{
return ListView_SendItemMessage(hwnd,LVM_SETITEMW,LVM_SETITEMA,pitem,TRUE,FALSE);
}
BOOL
ListView_InsertItemX(
HWND hwnd,
LV_ITEM * pitem)
{
return ListView_SendItemMessage(hwnd,LVM_INSERTITEMW,LVM_INSERTITEMA,pitem,TRUE,FALSE);
}
// helper function for sending listview column messages
BOOL ListView_SendColumnMessage(HWND hwnd,int iCol,UINT MsgW,UINT MsgA,LV_COLUMN *pColumn,
BOOL fInParam,BOOL fOutParam,BOOL fReturnsIndex)
{
BOOL fReturn = FALSE;
if (g_fWideWrap_Unicode /* ListView_GetUnicodeFormat(hwnd) */)
{
fReturn = (BOOL)SendMessageW((hwnd), MsgW, iCol, (LPARAM)(LV_COLUMNW FAR*)(pColumn));
}
else
{
LV_COLUMNA ColumnA;
Assert(sizeof(LV_COLUMNA) == sizeof(LV_COLUMNW))
memcpy(&ColumnA,pColumn,sizeof(LV_COLUMNA));
ColumnA.pszText = NULL;
DWORD dwOldSize = pColumn->cchTextMax;
BOOL fOk;
XArray<CHAR> xszText;
if (ColumnA.mask & LVCF_TEXT)
{
if (fInParam)
{
fOk = ConvertWideCharToMultiByte( pColumn->pszText, xszText );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
ColumnA.pszText = xszText.Get();
ColumnA.cchTextMax = lstrlenA(ColumnA.pszText) + 1;
}
else
{
fOk = xszText.Init( ColumnA.cchTextMax );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
ColumnA.pszText = xszText.Get();
}
}
if (ColumnA.pszText || !(ColumnA.mask & LVCF_TEXT))
{
fReturn = (BOOL)SendMessageA((hwnd), MsgA,iCol, (LPARAM)(LV_COLUMNA FAR*)(&ColumnA));
if ( ((fReturnsIndex && fReturn != -1)
|| (fReturn && !fReturnsIndex)) && fOutParam)
{
LPWSTR pszTextW = pColumn->pszText;
memcpy(pColumn,&ColumnA,sizeof(LV_COLUMNA));
pColumn->pszText = pszTextW;
if (ColumnA.mask & LVCF_TEXT)
{
XArray<WCHAR> xwszTextOut;
fOk = ConvertMultiByteToWideChar( ColumnA.pszText, xwszTextOut );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
if ( lstrlenX(xwszTextOut.Get()) >= dwOldSize )
return FALSE;
lstrcpyX( pColumn->pszText, xwszTextOut.Get() );
}
}
}
}
return fReturn;
}
BOOL
ListView_SetColumnX(
HWND hwnd,
int iCol,
LV_COLUMN * pColumn)
{
return ListView_SendColumnMessage(hwnd,iCol,LVM_SETCOLUMNW,LVM_SETCOLUMNA,pColumn,TRUE,FALSE,FALSE);
}
int
ListView_InsertColumnX(
HWND hwnd,
int iCol,
LV_COLUMN * pColumn)
{
return ListView_SendColumnMessage(hwnd,iCol,LVM_INSERTCOLUMNW,LVM_INSERTCOLUMNA,pColumn,TRUE,FALSE,TRUE);
}
HPROPSHEETPAGE
WINAPI CreatePropertySheetPageX(LPCPROPSHEETPAGEW ppsh)
{
HPROPSHEETPAGE fhReturn = NULL;
if (g_fWideWrap_Unicode)
{
fhReturn = CreatePropertySheetPageW(ppsh);
}
else
{
// only support pages that don't have any strings to convert
Assert(sizeof(LPCPROPSHEETPAGEW) == sizeof(LPCPROPSHEETPAGEA));
Assert(0 == HIWORD(ppsh->pszTemplate));
Assert(0 == HIWORD(ppsh->pszIcon));
Assert(0 == HIWORD(ppsh->pszTitle));
Assert(NULL == ppsh->pszHeaderTitle); // these aren't defined in _WIN32_IE < 0x0400
Assert(NULL == ppsh->pszHeaderSubTitle);
// since not strings can call Ansi version
fhReturn = CreatePropertySheetPageA((LPCPROPSHEETPAGEA) ppsh);
}
return fhReturn;
}
INT_PTR
WINAPI PropertySheetX(
LPCPROPSHEETHEADERW ppsh)
{
INT_PTR piReturn = -1;
// don't support passing in an array or property sheet structures
// or loading the icon
Assert(!(ppsh->dwFlags & PSH_PROPSHEETPAGE));
Assert(!(ppsh->dwFlags & PSH_USEICONID));
if (g_fWideWrap_Unicode)
{
piReturn = PropertySheetW(ppsh);
}
else
{
PROPSHEETHEADERA pshA;
Assert(sizeof(PROPSHEETHEADERA) == sizeof(PROPSHEETHEADERW));
memcpy(&pshA,ppsh,sizeof(pshA));
// if have a title an not a resource id allocate a string
XArray<CHAR> xszCaption;
if (0 != HIWORD(ppsh->pszCaption))
{
BOOL fOk = ConvertWideCharToMultiByte( ppsh->pszCaption, xszCaption );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return piReturn;
}
pshA.pszCaption = xszCaption.Get();
}
piReturn = PropertySheetA(&pshA);
}
return piReturn;
}
// helper function for sending listview column messages
BOOL ComboEx_SendComboMessage(
HWND hwnd,UINT MsgW,UINT MsgA,
PCCOMBOEXITEMW pComboExItemW,
BOOL fInParam,BOOL fOutParam,BOOL fReturnsIndex)
{
BOOL fReturn = FALSE;
if (g_fWideWrap_Unicode)
{
fReturn = (BOOL)SendMessageW((hwnd), MsgW, 0, (LPARAM) pComboExItemW);
}
else
{
COMBOBOXEXITEMA ComboExItemA;
Assert(sizeof(COMBOBOXEXITEMA) == sizeof(COMBOBOXEXITEMW))
memcpy(&ComboExItemA,pComboExItemW,sizeof(COMBOBOXEXITEMA));
ComboExItemA.pszText = NULL;
DWORD dwOldSize = pComboExItemW->cchTextMax;
BOOL fOk;
XArray<CHAR> xszText;
if (ComboExItemA.mask & CBEIF_TEXT )
{
if (fInParam)
{
fOk = ConvertWideCharToMultiByte( pComboExItemW->pszText, xszText );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
ComboExItemA.pszText = xszText.Get();
ComboExItemA.cchTextMax = lstrlenA(ComboExItemA.pszText) + 1;
}
else
{
fOk = xszText.Init( ComboExItemA.cchTextMax );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
ComboExItemA.pszText = xszText.Get();
}
}
if (ComboExItemA.pszText || !(ComboExItemA.mask & CBEIF_TEXT ))
{
fReturn = (BOOL)SendMessageA((hwnd), MsgA, 0, (LPARAM) &ComboExItemA);
if ( ((fReturnsIndex && fReturn != -1)
|| (fReturn && !fReturnsIndex)) && fOutParam)
{
LPWSTR pszTextW = pComboExItemW->pszText;
memcpy((void*) pComboExItemW,&ComboExItemA,sizeof(COMBOBOXEXITEMA));
(LPWSTR) pComboExItemW->pszText = pszTextW;
if (ComboExItemA.mask & CBEIF_TEXT )
{
XArray<WCHAR> xwszTextOut;
fOk = ConvertMultiByteToWideChar( ComboExItemA.pszText, xwszTextOut );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
if ( lstrlenX(xwszTextOut.Get()) >= dwOldSize )
return FALSE;
lstrcpyX( pComboExItemW->pszText, xwszTextOut.Get() );
}
}
}
}
return fReturn;
}
int ComboEx_InsertItemX(HWND hwnd,PCCOMBOEXITEMW pComboExItemW)
{
return ComboEx_SendComboMessage(hwnd,CBEM_INSERTITEMW,CBEM_INSERTITEMA,
pComboExItemW,TRUE,FALSE,TRUE);
}
BOOL ComboEx_GetItemX(HWND hwnd,PCCOMBOEXITEMW pComboExItemW)
{
return ComboEx_SendComboMessage(hwnd,CBEM_GETITEMW,CBEM_GETITEMA,
pComboExItemW,FALSE,TRUE,FALSE);
}
int TabCtrl_InsertItemX(HWND hwnd,int iItem,LPTCITEMW ptcItem)
{
int iReturn = -1;
if (g_fWideWrap_Unicode)
{
iReturn = (int)SendMessage(hwnd,TCM_INSERTITEMW, (WPARAM)iItem,
(LPARAM) ptcItem);
}
else
{
TCITEMA tcItemA;
XArray<CHAR> xszText;
BOOL fOk;
Assert(sizeof(TCITEMA) == sizeof(TCITEMW));
memcpy(&tcItemA,ptcItem,sizeof(tcItemA));
if (ptcItem->mask & TCIF_TEXT)
{
fOk = ConvertWideCharToMultiByte( ptcItem->pszText, xszText);
if ( !fOk )
{
return -1;
}
tcItemA.pszText = xszText.Get();
}
iReturn = (int)SendMessage(hwnd,TCM_INSERTITEMA,(WPARAM)iItem,(LPARAM) &tcItemA);
}
return iReturn;
}
BOOL Animate_OpenX(HWND hwnd,LPWSTR szName)
{
// only support resource IDs
Assert(0 == HIWORD(szName));
return (BOOL)SendMessage(hwnd,ACM_OPENA,0,(LPARAM) szName);
}
BOOL
DateTime_SetFormatX(
HWND hwnd,
LPCWSTR pszTimeFormat)
{
BOOL fReturn = FALSE;
if (g_fWideWrap_Unicode)
{
return (BOOL)SendMessage(hwnd,DTM_SETFORMATW,0,(LPARAM) pszTimeFormat);
}
else
{
XArray<CHAR> xszTimeFormat;
BOOL fOk;
Assert(pszTimeFormat);
fOk = ConvertWideCharToMultiByte(pszTimeFormat,xszTimeFormat);
if (!fOk)
{
SetLastError(E_OUTOFMEMORY);
return FALSE;
}
fReturn = (BOOL)SendMessage(hwnd,DTM_SETFORMATA,0,(LPARAM) xszTimeFormat.Get());
}
return fReturn;
}
int
WINAPI
GetDateFormatX(
LCID Locale,
DWORD dwFlags,
CONST SYSTEMTIME *lpDate,
LPCWSTR lpFormat,
LPWSTR lpDateStr,
int cchDate)
{
int iReturn = 0;
if (g_fWideWrap_Unicode)
{
return GetDateFormatW(Locale,dwFlags,lpDate,lpFormat,lpDateStr,cchDate);
}
else
{
XArray<CHAR> xszFormat;
XArray<CHAR> xszDateStr;
BOOL fOkFormat,fOkDateStr = TRUE;
Assert(lpDateStr || cchDate == 0);
fOkFormat = ConvertWideCharToMultiByte(lpFormat,xszFormat);
if (cchDate)
{
fOkDateStr = xszDateStr.Init(cchDate);
}
if (!fOkFormat || !fOkDateStr)
{
SetLastError(E_OUTOFMEMORY);
return FALSE;
}
iReturn = GetDateFormatA(Locale,dwFlags,lpDate,xszFormat.Get(),xszDateStr.Get(),cchDate);
if (iReturn && cchDate)
{
XArray<WCHAR> xwszDateStr;
BOOL fOk;
fOk = ConvertMultiByteToWideChar(xszDateStr.Get(), xwszDateStr );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
int cwcLen = lstrlenX( xwszDateStr.Get() );
if ( cwcLen >= cchDate)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
else
{
iReturn = cwcLen+1;
lstrcpynX( lpDateStr, xwszDateStr.Get(),iReturn);
}
}
}
return iReturn;
}
int
WINAPI
GetTimeFormatX(
LCID Locale,
DWORD dwFlags,
CONST SYSTEMTIME *lpTime,
LPCWSTR lpFormat,
LPWSTR lpTimeStr,
int cchTime)
{
int iReturn = 0;
if (g_fWideWrap_Unicode)
{
return GetTimeFormatW(Locale,dwFlags,lpTime,lpFormat,lpTimeStr,cchTime);
}
else
{
XArray<CHAR> xszFormat;
XArray<CHAR> xszTimeStr;
BOOL fOkFormat,fOkTimeStr = TRUE;
Assert(lpTimeStr || cchTime == 0);
fOkFormat = ConvertWideCharToMultiByte(lpFormat,xszFormat);
if (cchTime)
{
fOkTimeStr = xszTimeStr.Init(cchTime);
}
if (!fOkFormat || !fOkTimeStr)
{
SetLastError(E_OUTOFMEMORY);
return 0;
}
iReturn = GetTimeFormatA(Locale,dwFlags,lpTime,xszFormat.Get(),xszTimeStr.Get(),cchTime);
if (iReturn && cchTime)
{
XArray<WCHAR> xwszTimeStr;
BOOL fOk = ConvertMultiByteToWideChar(xszTimeStr.Get(), xwszTimeStr );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
int cwcLen = lstrlenX( xwszTimeStr.Get() );
if ( cwcLen >= cchTime)
{
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return 0;
}
iReturn = cwcLen + 1;
lstrcpynX( lpTimeStr, xwszTimeStr.Get(),iReturn);
}
}
return iReturn;
}
int DrawTextX(
HDC hDC,
LPCWSTR lpString,
int nCount,
LPRECT lpRect,
UINT uFormat
)
{
int iReturn = 0;
if (g_fWideWrap_Unicode)
{
iReturn = DrawTextW(hDC,lpString,nCount,lpRect,uFormat);
}
else
{
XArray<CHAR> xszString;
BOOL fOk = ConvertWideCharToMultiByte( lpString, xszString );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
nCount = lstrlenA(xszString.Get());
iReturn = DrawTextA(hDC,xszString.Get(),nCount,lpRect,uFormat);
}
return iReturn;
}
HWND
WINAPI
FindWindowExX(
HWND hwndParent,
HWND hwndChildAfter,
LPCWSTR lpszClass,
LPCWSTR lpszWindow
)
{
HWND hwnd = NULL;
if (g_fWideWrap_Unicode)
{
hwnd = FindWindowExW(hwndParent,hwndChildAfter,lpszClass,
lpszWindow);
}
else
{
LPSTR lpszWindowA;
XArray<CHAR> xszWindow;
if ( lpszWindow )
{
BOOL fOk = ConvertWideCharToMultiByte( lpszWindow, xszWindow );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
lpszWindowA = xszWindow.Get();
}
else
lpszWindowA = NULL;
LPSTR lpszClassA = NULL;
LPSTR ClassArg = NULL;
XArray<CHAR> xszClass;
if (0 != HIWORD(lpszClass))
{
BOOL fOk = ConvertWideCharToMultiByte( lpszClass, xszClass );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
ClassArg = lpszClassA = xszClass.Get();
}
else
{
ClassArg = (LPSTR) lpszClass;
}
hwnd = FindWindowExA(hwndParent,hwndChildAfter,ClassArg,
lpszWindowA);
}
return hwnd;
}
HWND
WINAPI
FindWindowX(
IN LPCWSTR lpszClass,
IN LPCWSTR lpszWindow)
{
HWND hwnd = NULL;
if (g_fWideWrap_Unicode)
{
hwnd = FindWindowW(lpszClass,lpszWindow);
}
else
{
LPSTR lpszWindowA;
XArray<CHAR> xszWindow;
if ( lpszWindow )
{
BOOL fOk = ConvertWideCharToMultiByte( lpszWindow, xszWindow );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
lpszWindowA = xszWindow.Get();
}
else
lpszWindowA = NULL;
LPSTR lpszClassA = NULL;
LPSTR ClassArg = NULL;
XArray<CHAR> xszClass;
if (0 != HIWORD(lpszClass))
{
BOOL fOk = ConvertWideCharToMultiByte( lpszClass, xszClass );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return NULL;
}
ClassArg = lpszClassA = xszClass.Get();
}
else
{
ClassArg = (LPSTR) lpszClass;
}
hwnd = FindWindowA(ClassArg,lpszWindowA);
}
return hwnd;
}
BOOL SetWindowTextX(
HWND hWnd,
LPCWSTR lpString
)
{
BOOL fReturn = FALSE;
Assert(lpString);
if (g_fWideWrap_Unicode)
{
fReturn = SetWindowTextW(hWnd,lpString);
}
else
{
XArray<CHAR> xszString;
BOOL fOk = ConvertWideCharToMultiByte( lpString, xszString );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
// !!! This function turns around and calls WM_SETTEXT which doesn't
// have a A and W version so if have a misatch between what the
// window expects and us sending Ansi garbage will appear.
fReturn = SetWindowTextA(hWnd,xszString.Get());
}
return fReturn;
}
int ListBox_AddStringX(
HWND hWnd,
LPCWSTR lpString
)
{
int iReturn;
Assert(lpString);
if (g_fWideWrap_Unicode)
{
iReturn = (int)SendMessageW(hWnd,LB_ADDSTRING, 0L, (LPARAM)(LPCTSTR)(lpString));
}
else
{
XArray<CHAR> xszString;
BOOL fOk = ConvertWideCharToMultiByte( lpString, xszString );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
// !!! This function turns around and sends LB_ADDSTRING which doesn't
// have a A and W version so if have a misatch between what the
// window expects and us sending Ansi garbage will appear.
iReturn = (int)SendMessageA(hWnd,LB_ADDSTRING, 0L, (LPARAM)(LPCSTR)(xszString.Get()));
}
return iReturn;
}
int GetWindowTextX(
HWND hWnd,
LPTSTR lpString,
int nMaxCount
)
{
int iReturn = 0;
Assert(lpString && (nMaxCount > 0));
if (g_fWideWrap_Unicode)
{
iReturn = GetWindowTextW(hWnd,lpString,nMaxCount);
}
else
{
int nMaxCountA = nMaxCount;
XArray<CHAR> xszString;
BOOL fOk = xszString.Init( nMaxCountA );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
LPSTR lpStringA = xszString.Get();
if (lpStringA)
{
*lpString = NULL;
iReturn = GetWindowTextA(hWnd,lpStringA,nMaxCountA);
if (iReturn)
{
XArray<WCHAR> xwszStringOut;
BOOL fOk = ConvertMultiByteToWideChar( lpStringA, xwszStringOut );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
int cwcLen = lstrlenX( xwszStringOut.Get() );
if ( cwcLen >= nMaxCount )
cwcLen = nMaxCount - 1;
iReturn = cwcLen + 1;
lstrcpynX( lpString, xwszStringOut.Get(),iReturn);
}
}
}
return iReturn;
}
BOOL
WINAPI
WinHelpX(
HWND hWndMain,
LPCWSTR lpszHelp,
UINT uCommand,
ULONG_PTR dwData
)
{
if (g_fWideWrap_Unicode)
{
WinHelpW(hWndMain,lpszHelp,uCommand,dwData);
}
else
{
LPSTR lpszHelpA = NULL;
XArray<CHAR> xszHelp;
if (lpszHelp)
{
BOOL fOk = ConvertWideCharToMultiByte( lpszHelp, xszHelp );
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return FALSE;
}
lpszHelpA = xszHelp.Get();
}
if (lpszHelpA || (NULL == lpszHelp))
{
WinHelpA(hWndMain,lpszHelpA,uCommand,dwData);
}
}
return FALSE;
}
HFONT
WINAPI
CreateFontIndirectX(
CONST LOGFONTW *pLogFontW)
{
HFONT hfReturn = NULL;
if (g_fWideWrap_Unicode)
{
return CreateFontIndirectW(pLogFontW);
}
else
{
LOGFONTA LogFontA;
XArray<CHAR> xszLogFont;
BOOL fOk = ConvertWideCharToMultiByte( pLogFontW->lfFaceName, xszLogFont);
int cchFontA;
// all items in the logFont structure up
// until the lfFaceName are the same
memcpy(&LogFontA,pLogFontW,sizeof(LogFontA));
if (!fOk)
{
return NULL;
}
cchFontA = lstrlenA(xszLogFont.Get());
if (cchFontA >= LF_FACESIZE)
{
return NULL;
}
strncpy(LogFontA.lfFaceName,xszLogFont.Get(),cchFontA + 1);
hfReturn = CreateFontIndirectA(&LogFontA);
}
return hfReturn;
}
DWORD
WINAPI
FormatMessageX(
DWORD dwFlags,
LPCVOID lpSource,
DWORD dwMessageId,
DWORD dwLanguageId,
LPWSTR lpBuffer,
DWORD nSize,
va_list *Arguments
)
{
DWORD dwReturn = 0;
// we don't support arguments
Assert(NULL == Arguments);
Assert(lpBuffer);
if (Arguments || (NULL == lpBuffer))
{
return 0;
}
if (g_fWideWrap_Unicode)
{
return FormatMessageW(dwFlags,lpSource,dwMessageId,dwLanguageId,
lpBuffer,nSize,Arguments);
}
else
{
XArray<CHAR> xszBuffer;
BOOL fOk = xszBuffer.Init(nSize);
if (!fOk)
{
return 0;
}
dwReturn = FormatMessageA(dwFlags,lpSource,dwMessageId,dwLanguageId,
xszBuffer.Get(),nSize,Arguments);
if (dwReturn)
{
XArray<WCHAR> xwszStringOut;
BOOL fOk = ConvertMultiByteToWideChar(xszBuffer.Get(), xwszStringOut );
*lpBuffer = NULL;
if ( !fOk )
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
// if buffer isn't big enough fail
int cwcLen = lstrlenX( xwszStringOut.Get() );
if ( cwcLen >= (int) nSize )
{
return 0;
}
dwReturn = cwcLen + 1;
lstrcpynX( lpBuffer, xwszStringOut.Get(),dwReturn);
}
}
return dwReturn;
}
// code stolen from base\process.cp
BOOL
WINAPI
IsBadStringPtrX(
LPCWSTR lpsz,
UINT cchMax
)
{
LPCWSTR EndAddress;
LPCWSTR StartAddress;
WCHAR c;
// If the structure has zero length, then do not probe the structure for
// read accessibility.
if (cchMax != 0)
{
if (lpsz == NULL)
{
return TRUE;
}
StartAddress = lpsz;
EndAddress = (LPCWSTR)((PSZ)StartAddress + (cchMax*2) - 2);
__try
{
c = *(WCHAR *)StartAddress;
while ( c && StartAddress != EndAddress )
{
StartAddress++;
c = *(WCHAR *)StartAddress;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return TRUE;
}
}
return FALSE;
}
BOOL
APIENTRY
GetTextExtentPointX(
HDC hdc,
LPCWSTR lpszStr,
int cchString, // specifies length of in param string.
LPSIZE lpSize
)
{
BOOL fReturn = FALSE;
if (g_fWideWrap_Unicode)
{
return GetTextExtentPointW(hdc,lpszStr,cchString,lpSize);
}
else
{
XArray<CHAR> xsStr;
int cchStringA;
BOOL fOk;
Assert(lpszStr && (cchString > 0));
// verify cchString is the stringLength or
// the calculation of cchStringA will not be accurate.
Assert(cchString == (int) lstrlenX(lpszStr));
fOk = ConvertWideCharToMultiByte(lpszStr,xsStr);
if (!fOk)
{
SetLastError(E_OUTOFMEMORY);
return FALSE;
}
cchStringA = lstrlenA(xsStr.Get());
fReturn = GetTextExtentPointA(hdc,xsStr.Get(),cchStringA,lpSize);
}
return fReturn;
}
#ifdef __cplusplus
}
#endif