//+--------------------------------------------------------------------------- // // 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 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 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 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 xszSrc; XArray 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 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 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 xszValue; fOk = xszValue.Init( cb ); if ( !fOk ) return ERROR_OUTOFMEMORY; ret = RegQueryValueA(hKey, xszSubKey.Get(), xszValue.Get(), &cb); if (ret == ERROR_SUCCESS) { XArray 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 xszValueName; BOOL fOk = ConvertWideCharToMultiByte( lpValueName, xszValueName ); if ( !fOk ) return ERROR_OUTOFMEMORY; lpValueNameA = xszValueName.Get(); XArray 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 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 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 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 xszSubKey; XArray 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 xszBufIn; BOOL fOk = xszBufIn.Init( dwSizeA ); if ( !fOk ) { SetLastError( ERROR_OUTOFMEMORY ); return FALSE; } fReturn = GetUserNameA( xszBufIn.Get(), &dwSizeA ); if (fReturn) { XArray 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 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 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 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 xszTempBuffer; XArray 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 xszClass; if (HIWORD(lpClassName) == 0) szClass = (LPSTR) lpClassName; else { fOk = ConvertWideCharToMultiByte( lpClassName, xszClass ); if ( !fOk ) { SetLastError( ERROR_OUTOFMEMORY ); return NULL; } szClass = xszClass.Get(); } XArray 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 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 xszMenu; BOOL fOk = ConvertWideCharToMultiByte( lpWndClass->lpszMenuName, xszMenu ); if ( !fOk ) { SetLastError( ERROR_OUTOFMEMORY ); return 0; } wc.lpszMenuName = xszMenu.Get(); XArray 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 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 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 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 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 xszDesktop; BOOL fOk = ConvertWideCharToMultiByte( lpStartupInfo->lpDesktop, xszDesktop ); if ( !fOk ) { SetLastError( ERROR_OUTOFMEMORY ); return 0; } si.lpDesktop = xszDesktop.Get(); XArray xszTitle; fOk = ConvertWideCharToMultiByte( lpStartupInfo->lpTitle, xszTitle ); if ( !fOk ) { SetLastError( ERROR_OUTOFMEMORY ); return 0; } si.lpTitle = xszTitle.Get(); XArray xszAppName; fOk = ConvertWideCharToMultiByte( lpApplicationName, xszAppName, TRUE ); if ( !fOk ) { SetLastError( ERROR_OUTOFMEMORY ); return 0; } szApp = xszAppName.Get(); XArray xszCommand; fOk = ConvertWideCharToMultiByte( lpCommandLine, xszCommand, TRUE ); if ( !fOk ) { SetLastError( ERROR_OUTOFMEMORY ); return 0; } szCommand = xszCommand.Get(); XArray 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 xszName; BOOL fOk = xszName.Init( *lpcbName ); if ( !fOk ) return ERROR_OUTOFMEMORY; szName = xszName.Get(); DWORD dwNameOldSize = *lpcbName; DWORD dwClassOldSize = 0; LPSTR szClass = NULL; XArray 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 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 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 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 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 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 xszNameIn; BOOL fOk = xszNameIn.Init( OldSize ); if ( !fOk ) { SetLastError( ERROR_OUTOFMEMORY ); return 0; } ret = GetComputerNameA( xszNameIn.Get(), lpcchBuffer ); if ( ret == 0 ) return ret; XArray 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 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 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 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 xszText; XArray 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 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 xwszDisplay; fOk = ConvertMultiByteToWideChar( sfi.szDisplayName, xwszDisplay, TRUE ); if ( !fOk ) { SetLastError( ERROR_OUTOFMEMORY ); return 0; } XArray 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 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 xszName; XArray 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 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 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 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 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 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 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 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 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 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 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 xszFormat; XArray 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 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 xszFormat; XArray 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 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 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 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 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 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 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 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 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 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 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 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 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 xszBuffer; BOOL fOk = xszBuffer.Init(nSize); if (!fOk) { return 0; } dwReturn = FormatMessageA(dwFlags,lpSource,dwMessageId,dwLanguageId, xszBuffer.Get(),nSize,Arguments); if (dwReturn) { XArray 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 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