windows-nt/Source/XPSP1/NT/com/oleutest/olebind/widewrap.cxx
2020-09-26 16:20:57 +08:00

1841 lines
33 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1993 - 1993.
//
// File: widewrap.cxx
//
// Contents: Unicode wrapper API, used only on Chicago
//
// 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.
//
// These are privately exported for use by the Shell.
//
// 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
//
//----------------------------------------------------------------------------
#include <windows.h>
#include "widewrap.h"
size_t olembstowcs(WCHAR *pwsz, const char *psz, size_t cCh);
size_t olewcstombs(char *psz, const WCHAR *pwsz , size_t cCh);
inline size_t olembstowcs(WCHAR *pwsz, const char *psz, size_t cCh)
{
return MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, psz, -1, pwsz, cCh);
}
inline size_t olewcstombs(char *psz, const WCHAR *pwsz , size_t cCh)
{
return WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, pwsz, -1, psz,
cCh, NULL, NULL);
}
#ifdef _CHICAGO_
#define HFINDFILE HANDLE
#define ERR ((char*) -1)
//
// BUGBUG: 9869
//
// The length of a Unicode string (in chars) and a DBCS string are not
// always equal. We need to review all WideChar to MultiByte conversions
// logic to verify that the proper result buffer size is used.
//
// Make the below Win95 only change to get the Win95 FE build out.
//
int UnicodeToAnsi(LPSTR sz, LPCWSTR pwsz, LONG cb)
{
int ret;
ret = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, pwsz, -1, sz, cb, NULL, NULL);
#if DBG==1
if (ret == -1)
{
DebugBreak();
}
#endif
return ret;
}
int UnicodeToAnsiOem(LPSTR sz, LPCWSTR pwsz, LONG cb)
{
int ret;
if (AreFileApisANSI())
{
ret = WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, pwsz, -1, sz,
cb, NULL, NULL);
}
else
{
ret = WideCharToMultiByte(CP_OEMCP, WC_COMPOSITECHECK, pwsz, -1, sz,
cb, NULL, NULL);
}
#if DBG==1
if (ret == -1)
{
DebugBreak();
}
#endif
return ret;
}
#if DBG==1
int AnsiToUnicode(LPWSTR pwsz, LPCSTR sz, LONG cb)
{
int ret;
ret = olembstowcs(pwsz, sz, cb);
if (ret == -1)
{
DebugBreak();
}
return ret;
}
#else
#define AnsiToUnicode olembstowcs
#endif
int AnsiToUnicodeOem(LPWSTR pwsz, LPCSTR sz, LONG cb)
{
int ret;
if (AreFileApisANSI())
{
ret = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, cb, pwsz, cb);
}
else
{
ret = MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, sz, cb, pwsz, cb);
}
#if DBG==1
if (ret == -1)
{
DebugBreak();
}
#endif
return ret;
}
LPSTR Convert(LPCWSTR pwsz)
{
LONG len;
LPSTR sz = NULL;
if (pwsz == NULL)
goto Exit;
#if DBG==1
// some Win32 API accept atoms in their string parameters
#endif
len = (wcslen(pwsz) + 1) * 2;
sz = new CHAR[len];
if (sz==NULL)
{
sz = ERR;
goto Exit;
}
__try
{
UnicodeToAnsi(sz, pwsz, len);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
#if DBG==1
MessageBoxA(NULL, "GP fault in unicode conversion -- caught",
NULL, MB_OK);
#endif
if (sz)
delete sz;
sz = ERR;
}
Exit:
return sz;
}
LPSTR ConvertOem(LPCWSTR pwsz)
{
LONG len;
LPSTR sz = NULL;
if (pwsz == NULL)
goto Exit;
#if DBG==1
// some Win32 API accept atoms in their string parameters
#endif
len = (wcslen(pwsz) + 1) * 2;
sz = new CHAR[len];
if (sz==NULL)
{
sz = ERR;
goto Exit;
}
__try
{
UnicodeToAnsiOem(sz, pwsz, len);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
#if DBG==1
MessageBoxA(NULL, "GP fault in unicode conversion -- caught",
NULL, MB_OK);
#endif
if (sz)
delete sz;
sz = ERR;
}
Exit:
return sz;
}
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);
}
BOOL WINAPI DeleteFileX(LPCWSTR pwsz)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("DeleteFile\n");
#endif
CHAR sz[MAX_PATH * 2];
UnicodeToAnsi(sz, pwsz, sizeof(sz));
return DeleteFileA(sz);
}
LONG APIENTRY RegOpenKeyX(HKEY hKey, LPCWSTR pwszSubKey, PHKEY phkResult)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RegOpenKey\n");
#endif
LONG ret;
LPSTR sz;
sz = Convert(pwszSubKey);
if (sz == ERR)
{
return ERROR_OUTOFMEMORY;
}
ret = RegOpenKeyA(hKey, sz, phkResult);
if (sz)
delete sz;
return ret;
}
LONG APIENTRY RegQueryValueX(HKEY hKey, LPCWSTR pwszSubKey, LPWSTR pwszValue,
PLONG lpcbValue)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RegQueryValue\n");
#endif
LONG cb, ret;
LPSTR szValue = NULL;
LPSTR sz;
sz = Convert(pwszSubKey);
if (sz == ERR)
{
return ERROR_OUTOFMEMORY;
}
ret = RegQueryValueA(hKey, sz, 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);
goto Exit;
}
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);
ret = ERROR_MORE_DATA;
goto Exit;
}
// Otherwise, retrieve and convert the value.
szValue = new CHAR[cb];
if (szValue == NULL)
{
ret = ERROR_OUTOFMEMORY;
goto Exit;
}
ret = RegQueryValueA(hKey, sz, szValue, &cb);
if (ret == ERROR_SUCCESS)
{
AnsiToUnicode(pwszValue, szValue, cb);
// Adjust size of buffer to report, to account for CHAR -> WCHAR
*lpcbValue = cb * sizeof(WCHAR);
}
}
Exit:
if (szValue)
delete szValue;
if (sz)
delete sz;
return ret;
}
LONG APIENTRY RegSetValueX(HKEY hKey, LPCWSTR lpSubKey, DWORD dwType,
LPCWSTR lpData, DWORD cbData)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RegSetValue\n");
#endif
LPSTR szKey = NULL;
LPSTR szValue = NULL;
LONG ret = ERROR_OUTOFMEMORY;
szKey = Convert(lpSubKey);
if (szKey == ERR)
{
szKey = NULL;
goto Exit;
}
szValue = Convert(lpData);
if (szValue == ERR)
{
szValue = NULL;
goto Exit;
}
ret = RegSetValueA(hKey, szKey, dwType, szValue, cbData);
Exit:
if (szKey)
delete szKey;
if (szValue)
delete szValue;
return ret;
}
LONG APIENTRY RegSetValueExX(HKEY hKey,
LPCWSTR lpSubKey,
DWORD dwReserved,
DWORD dwType,
LPBYTE lpData,
DWORD cbData)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RegSetValueEx\n");
#endif
LPSTR szKey = NULL;
LPBYTE szValue = lpData;
LONG ret = ERROR_OUTOFMEMORY;
szKey = Convert(lpSubKey);
if (szKey == ERR)
{
szKey = NULL;
goto Exit;
}
if (dwType == REG_SZ)
{
szValue = (LPBYTE) Convert((LPWSTR)lpData);
}
if (szValue == (LPBYTE) ERR)
{
szValue = NULL;
goto Exit;
}
ret = RegSetValueExA(hKey, szKey, dwReserved, dwType, szValue, cbData);
Exit:
if (szKey)
delete szKey;
if ((szValue != lpData) && (szValue != (LPBYTE)ERR))
delete szValue;
return ret;
}
UINT WINAPI RegisterWindowMessageX(LPCWSTR lpString)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RegisterWindowMessage\n");
#endif
UINT ret;
#if 0
LPSTR sz;
sz = Convert(lpString);
if (sz == ERR)
{
return 0;
}
#else
// BUGBUG: CairOLE calls this from libmain -- have to use static buffer
CHAR sz[200];
UnicodeToAnsi(sz, lpString, sizeof(sz));
#endif
ret = RegisterWindowMessageA(sz);
#if 0
delete sz;
#endif
return ret;
}
LONG
APIENTRY
RegOpenKeyExX (
HKEY hKey,
LPCWSTR lpSubKey,
DWORD ulOptions,
REGSAM samDesired,
PHKEY phkResult
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RegOpenKeyEx\n");
#endif
LONG ret;
LPSTR sz;
sz = Convert(lpSubKey);
if (sz == ERR)
{
return ERROR_OUTOFMEMORY;
}
ret = RegOpenKeyExA(hKey, sz, ulOptions, samDesired, phkResult);
if (sz)
delete sz;
return ret;
}
LONG
APIENTRY
RegQueryValueExX(
HKEY hKey,
LPWSTR lpValueName,
LPDWORD lpReserved,
LPDWORD lpType,
LPBYTE lpData,
LPDWORD lpcbData
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RegQueryValueEx\n");
#endif
LPBYTE lpTempBuffer;
DWORD dwTempType;
DWORD cb, cbRequired;
LONG ret;
LPSTR sz;
LPWSTR pwszTempWide;
LPSTR pszTempNarrow;
ULONG ulStringLength;
sz = Convert(lpValueName);
if (sz == ERR)
{
return ERROR_OUTOFMEMORY;
}
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.
switch (dwTempType)
{
case REG_EXPAND_SZ:
case REG_MULTI_SZ:
case REG_SZ:
lpTempBuffer = new BYTE[cbRequired];
if (lpTempBuffer == NULL)
{
return ERROR_OUTOFMEMORY;
}
ret = RegQueryValueExA(hKey,
sz,
lpReserved,
&dwTempType,
lpTempBuffer,
&cb);
if (ret == ERROR_SUCCESS)
{
switch (dwTempType)
{
case REG_EXPAND_SZ:
case REG_SZ:
AnsiToUnicode((LPWSTR) lpData, (LPSTR) lpTempBuffer, cb);
// Adjust size of buffer to report, to account for CHAR -> WCHAR
*lpcbData = cbRequired;
// Set the type, if required.
if (lpType != NULL)
{
*lpType = dwTempType;
}
break;
case REG_MULTI_SZ:
pszTempNarrow = (LPSTR) lpTempBuffer;
pwszTempWide = (LPWSTR) lpData;
while (pszTempNarrow != NULL)
{
ulStringLength = strlen(pszTempNarrow) + 1;
AnsiToUnicode(pwszTempWide,
pszTempNarrow,
ulStringLength);
// Compiler will scale appropriately here
pszTempNarrow += ulStringLength;
pwszTempWide += ulStringLength;
}
break;
}
}
if (lpTempBuffer)
delete lpTempBuffer;
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:
if (sz)
delete sz;
return ret;
}
ATOM
WINAPI
RegisterClassX(
CONST WNDCLASSW *lpWndClass)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RegisterClass\n");
#endif
WNDCLASSA wc;
ATOM ret;
BOOL fAtom = FALSE;
memcpy(&wc, lpWndClass, sizeof(WNDCLASS));
wc.lpszMenuName = Convert(lpWndClass->lpszMenuName);
if (wc.lpszMenuName==ERR)
{
return NULL;
}
if (HIWORD(lpWndClass->lpszClassName) == 0)
{
wc.lpszClassName = (LPSTR) lpWndClass->lpszClassName;
fAtom = TRUE;
}
else
{
wc.lpszClassName = Convert(lpWndClass->lpszClassName);
if (wc.lpszClassName==ERR)
{
if ((LPSTR) wc.lpszMenuName)
delete (LPSTR) wc.lpszMenuName;
return NULL;
}
}
ret = RegisterClassA(&wc);
if ((LPSTR) wc.lpszMenuName)
delete (LPSTR) wc.lpszMenuName;
if (!fAtom) delete (LPSTR) wc.lpszClassName;
return ret;
}
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) delete 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) delete 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) delete 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) delete 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)
delete szApp;
return nDefault;
}
ret = GetProfileIntA(szApp, szKey, nDefault);
if (szApp)
delete szApp;
if (szKey)
delete 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)
delete sz;
return ret;
}
UINT
WINAPI
GlobalGetAtomNameX(
ATOM nAtom,
LPWSTR pwszBuffer,
int nSize
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("GlobalGetAtomName\n");
#endif
LPSTR sz;
UINT ret;
sz = new CHAR[nSize];
if (sz == NULL)
{
return 0;
}
ret = GlobalGetAtomNameA(nAtom, sz, nSize);
if (ret)
{
AnsiToUnicode(pwszBuffer, sz, lstrlenA(sz) + 1);
}
if (sz)
delete sz;
return ret;
}
DWORD
WINAPI
GetModuleFileNameX(
HINSTANCE hModule,
LPWSTR pwszFilename,
DWORD nSize
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("GetModuleFileName\n");
#endif
LPSTR sz;
DWORD ret;
sz = new CHAR[nSize];
if (sz == NULL)
{
return 0;
}
ret = GetModuleFileNameA(hModule, sz, nSize);
if (ret)
{
AnsiToUnicode(pwszFilename, sz, lstrlenA(sz) + 1);
}
if (sz)
delete sz;
return ret;
}
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)
delete sz;
return ret;
}
HINSTANCE
WINAPI
LoadLibraryX(
LPCWSTR pwszFileName
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("LoadLibrary\n");
#endif
HINSTANCE ret;
LPSTR sz;
sz = Convert(pwszFileName);
if (sz == ERR)
{
return NULL;
}
ret = LoadLibraryA(sz);
if (sz)
delete sz;
return ret;
}
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)
delete sz;
return ret;
}
LONG
APIENTRY
RegDeleteKeyX(
HKEY hKey,
LPCWSTR pwszSubKey
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RegDeleteKey\n");
#endif
LONG ret;
LPSTR sz;
sz = Convert(pwszSubKey);
if (sz == ERR)
{
return ERROR_OUTOFMEMORY;
}
ret = RegDeleteKeyA(hKey, sz);
if (sz)
delete sz;
return ret;
}
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
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("CreateProcess\n");
#endif
STARTUPINFOA si;
BOOL ret = FALSE;
LPSTR szApp = NULL;
LPSTR szCommand = NULL;
LPSTR szDir = NULL;
memcpy(&si, lpStartupInfo, sizeof(STARTUPINFO));
si.lpTitle = NULL;
si.lpDesktop = Convert(lpStartupInfo->lpDesktop);
if (si.lpDesktop == ERR)
{
si.lpDesktop = NULL;
goto Error;
}
si.lpTitle = Convert(lpStartupInfo->lpTitle);
if (si.lpTitle == ERR)
{
si.lpTitle = NULL;
goto Error;
}
szApp = Convert(lpApplicationName);
if (szApp == ERR)
{
szApp = NULL;
goto Error;
}
szCommand = ConvertOem(lpCommandLine);
if (szCommand == ERR)
{
szCommand = NULL;
goto Error;
}
szDir = Convert(lpCurrentDirectory);
if (szDir == ERR)
{
szDir = NULL;
goto Error;
}
ret = CreateProcessA(szApp, szCommand, lpProcessAttributes,
lpThreadAttributes, bInheritHandles, dwCreationFlags,
lpEnvironment, szDir, &si, lpProcessInformation);
Error:
if (si.lpDesktop)
delete si.lpDesktop;
if (si.lpTitle)
delete si.lpTitle;
if (szApp)
delete szApp;
if (szCommand)
delete szCommand;
if (szDir)
delete szDir;
return ret;
}
LONG
APIENTRY
RegEnumKeyExX(
HKEY hKey,
DWORD dwIndex,
LPWSTR lpName,
LPDWORD lpcbName,
LPDWORD lpReserved,
LPWSTR lpClass,
LPDWORD lpcbClass,
PFILETIME lpftLastWriteTime
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RegEnumKeyEx\n");
#endif
LPSTR szName;
LPSTR szClass = NULL;
LONG ret = ERROR_OUTOFMEMORY;
szName = new CHAR[*lpcbName];
if (szName == NULL)
goto Exit;
if (lpClass != NULL)
{
szClass = new CHAR[*lpcbClass + 1];
if (szName == NULL)
goto Exit;
}
//
// Return lengths do not include zero char.
//
ret = RegEnumKeyExA(hKey, dwIndex, szName, lpcbName, lpReserved,
szClass, lpcbClass, lpftLastWriteTime);
if (ret == ERROR_SUCCESS)
{
AnsiToUnicode(lpName, szName, *lpcbName + 1);
if (szClass)
{
AnsiToUnicode(lpClass, szClass, *lpcbClass + 1);
}
}
Exit:
return ret;
}
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)
delete 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)
delete sz;
return ret;
}
HANDLE
WINAPI
CreateEventX(
LPSECURITY_ATTRIBUTES lpEventAttributes,
BOOL bManualReset,
BOOL bInitialState,
LPCWSTR lpName
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("CreateEvent\n");
#endif
LPSTR sz;
HANDLE ret;
sz = Convert(lpName);
if (sz == ERR)
{
return NULL;
}
ret = CreateEventA(lpEventAttributes, bManualReset, bInitialState, sz);
if (sz)
delete sz;
return ret;
}
UINT
WINAPI
GetDriveTypeX(
LPCWSTR lpRootPathName
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("GetDriveType\n");
#endif
LPSTR sz;
UINT ret;
sz = Convert(lpRootPathName);
if (sz == ERR)
{
return 0;
}
ret = GetDriveTypeA(sz);
if (sz)
delete 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)
delete sz;
return ret;
}
LONG
APIENTRY
RegEnumKeyX(
HKEY hKey,
DWORD dwIndex,
LPWSTR lpName,
DWORD cbName
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("RegEnumKey\n");
#endif
CHAR sz[MAX_PATH+1];
LONG ret;
//
// Return lengths do not include zero char.
//
ret = RegEnumKeyA(hKey, dwIndex, sz, cbName);
if (ret == ERROR_SUCCESS)
{
AnsiToUnicode(lpName, sz, lstrlenA(sz) + 1);
}
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 = wcslen(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;
}
//+---------------------------------------------------------------------------
//
// Function: wsprintfX
//
// Synopsis: Nightmare string function
//
// Arguments: [pwszOut] --
// [pwszFormat] --
// [...] --
//
// Returns:
//
// History: 1-06-94 ErikGav Created
//
// Notes: If you're reading this, you're probably having a problem with
// this function. Make sure that your "%s" in the format string
// says "%ws" if you are passing wide strings.
//
// %s on NT means "wide string"
// %s on Chicago means "ANSI string"
//
//----------------------------------------------------------------------------
int WINAPIV wsprintfX(LPWSTR pwszOut, LPCWSTR pwszFormat, ...)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("wsprintf\n");
#endif
LPSTR szFormat;
LPWSTR pwszTemp = NULL;
int i = 0;
// Convert the format string over
szFormat = Convert(pwszFormat);
if (szFormat == ERR)
{
szFormat = NULL;
goto Exit;
}
// magic voodoo follows:
//
// 1. Call wvsprintf passing the varargs
// 2. Use the pwszOut as a temp buffer to hold the ANSI output
// 3. Save the returned characters
i = wvsprintfA((LPSTR) pwszOut, szFormat,
(LPSTR) ((BYTE*)&pwszFormat) + sizeof(pwszFormat));
// allocate a buffer for the Ansi to Unicode conversion
pwszTemp = new WCHAR[i+1];
// convert the string
AnsiToUnicode(pwszTemp, (LPSTR) pwszOut, i+1);
// copy it to the out buffer
wcsncpy(pwszOut, pwszTemp, i+1);
Exit:
if (pwszTemp)
delete pwszTemp;
if (szFormat)
delete szFormat;
return i;
}
BOOL
WINAPI
GetComputerNameX(
LPWSTR pwszName,
LPDWORD lpcchBuffer
)
{
#ifdef DEBUG_OUTPUT
OutputDebugString("GetComputerName\n");
#endif
BOOL ret;
LPSTR sz;
sz = new CHAR[*lpcchBuffer];
ret = GetComputerNameA(sz, lpcchBuffer);
if (ret)
{
AnsiToUnicode(pwszName, sz, *lpcchBuffer);
}
if (sz)
delete sz;
return ret;
}
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);
AnsiToUnicode(lpPathBuffer, szPathBuffer, cchBuffer);
*lppFilePart = lpPathBuffer + (szFilePart - szPathBuffer);
if (szFileName)
delete 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));
//
// Only convert the actual data, not the whole buffer.
//
if (cchBuffer > ret + 1)
cchBuffer = ret + 1;
AnsiToUnicode(lpszShortPath, szShortBuffer, cchBuffer);
}
delete szFullPath;
return ret;
}
DWORD
WINAPI
SearchPathX(
LPCWSTR lpPath,
LPCWSTR lpFileName,
LPCWSTR lpExtension,
DWORD nBufferLength,
LPWSTR lpBuffer,
LPWSTR *lpFilePart
)
{
LPSTR lpszFileName;
CHAR szBuffer[MAX_PATH];
DWORD ret;
#ifdef DEBUG_OUTPUT
OutputDebugString("SearchPath\n");
#endif
lpszFileName = Convert(lpFileName);
if (lpszFileName == ERR)
return 0;
ret = SearchPathA(NULL, lpszFileName, NULL, sizeof(szBuffer), szBuffer, NULL);
AnsiToUnicode(lpBuffer, szBuffer, lstrlenA(szBuffer) + 1);
delete lpszFileName;
return ret;
}
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);
delete lpszString;
return retAtom;
}
int
WINAPI
GetClassNameX(
HWND hWnd,
LPWSTR lpClassName,
int nMaxCount)
{
LPSTR lpszClassName;
int ret;
#ifdef DEBUG_OUTPUT
OutputDebugString("GetClassName\n");
#endif
lpszClassName = Convert(lpClassName);
if (lpszClassName == ERR)
return 0;
ret = GetClassNameA(hWnd, lpszClassName, nMaxCount);
delete lpszClassName;
return ret;
}
int
WINAPI
lstrlenX(LPCWSTR lpString)
{
return wcslen(lpString);
}
LPWSTR
WINAPI
lstrcatX(
LPWSTR lpString1,
LPCWSTR lpString2)
{
return wcscat(lpString1, lpString2);
}
int
WINAPI
lstrcmpX(
LPCWSTR lpString1,
LPCWSTR lpString2
)
{
return wcscmp(lpString1, lpString2);
}
int
WINAPI
lstrcmpiX(
LPCWSTR lpString1,
LPCWSTR lpString2
)
{
return _wcsicmp(lpString1, lpString2);
}
LPWSTR
WINAPI
lstrcpyX(
LPWSTR lpString1,
LPCWSTR lpString2
)
{
return wcscpy(lpString1, lpString2);
}
HANDLE
WINAPI
CreateFileMappingX(
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCWSTR lpName
)
{
LPSTR lpszAName;
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);
delete lpszAName;
return ret;
}
HANDLE
WINAPI
OpenFileMappingX(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
LPCWSTR lpName
)
{
LPSTR lpszAName;
HANDLE ret;
#ifdef DEBUG_OUTPUT
OutputDebugString("CreateFileMapping\n");
#endif
lpszAName = Convert(lpName);
if (lpszAName == ERR)
{
return 0;
}
ret = OpenFileMappingA(
dwDesiredAccess,
bInheritHandle,
lpszAName);
delete lpszAName;
return ret;
}
#endif // CHICAGO