#include "priv.h"

// no wrappers are needed on non-x86 since this is only for win9x interop
#ifdef _X86_

//============================================================================
// This file contains a bunch of Unicode/Ansi thunks to handle calling
// some internal functions that on Windows 95 the strings are Ansi,
// whereas the string on NT are unicode
//============================================================================

// First undefine everything that we are intercepting as to not forward back to us...
#undef ILCreateFromPath
#undef PathCleanupSpec
#undef PathQualify
#undef PathProcessCommand
#undef SHCLSIDFromString
#undef SHGetSpecialFolderPath
#undef SHILCreateFromPath
#undef SHSimpleIDListFromPath
#undef GetFileNameFromBrowse
#undef Win32DeleteFile
#undef PathYetAnotherMakeUniqueName
#undef PathResolve
#undef IsLFNDrive
#undef Shell_GetCachedImageIndex
#undef SHRunControlPanel
#undef PickIconDlg
#undef ILCreateFromPathW
#undef SHCreateDirectory

#if 0
#define TF_THUNK    TF_CUSTOM1
#else
#define TF_THUNK    0
#endif

#define THUNKMSG(psz)   TraceMsg(TF_THUNK, "shdv THUNK::%s", psz)

#ifndef ANSI_SHELL32_ON_UNIX

#ifdef DEBUG
#define UseUnicodeShell32() (g_fRunningOnNT && !(g_dwPrototype & PF_FORCEANSI))
#else
#define UseUnicodeShell32() g_fRunningOnNT
#endif

#else

#define UseUnicodeShell32() (FALSE)

#endif

int _AorW_SHRunControlPanel(LPCTSTR pszOrig_cmdline, HWND errwnd)
{
    if (g_fRunningOnNT)
    {
        WCHAR wzPath[MAX_PATH];

        SHTCharToUnicode(pszOrig_cmdline, wzPath, ARRAYSIZE(wzPath));
        return SHRunControlPanel((LPCTSTR)wzPath, errwnd);
    }
    else
    {
        CHAR szPath[MAX_PATH];

        SHTCharToAnsi(pszOrig_cmdline, szPath, ARRAYSIZE(szPath));
        return SHRunControlPanel((LPCTSTR)szPath, errwnd);
    }
}

int _AorW_Shell_GetCachedImageIndex(LPCTSTR pszIconPath, int iIconIndex, UINT uIconFlags)
{
    if (UseUnicodeShell32())
    {
        WCHAR wzPath[MAX_PATH];

        SHTCharToUnicode(pszIconPath, wzPath, ARRAYSIZE(wzPath));
        return Shell_GetCachedImageIndex((LPCTSTR)wzPath, iIconIndex, uIconFlags);
    }
    else
    {
        CHAR szPath[MAX_PATH];

        SHTCharToAnsi(pszIconPath, szPath, ARRAYSIZE(szPath));
        return Shell_GetCachedImageIndex((LPCTSTR)szPath, iIconIndex, uIconFlags);
    }
}

// the reverse, do it for wide strings also..
int _WorA_Shell_GetCachedImageIndex(LPCWSTR pwzIconPath, int iIconIndex, UINT uIconFlags)
{
    CHAR szPath[MAX_PATH];

    if (!g_fRunningOnNT)
    {
        SHUnicodeToAnsi(pwzIconPath, szPath, ARRAYSIZE(szPath));
        pwzIconPath = (LPCWSTR)szPath;  // overload the pointer to pass through...
    }

    return Shell_GetCachedImageIndex((LPCTSTR)pwzIconPath, iIconIndex, uIconFlags);
}

// Explicit prototype because only the A/W prototypes exist in the headers
STDAPI_(LPITEMIDLIST) ILCreateFromPath(LPCTSTR pszPath);

LPITEMIDLIST _AorW_ILCreateFromPath(LPCTSTR pszPath)
{
    WCHAR wzPath[MAX_PATH];
    CHAR szPath[MAX_PATH];

    THUNKMSG(TEXT("ILCreateFromPath"));

    if (g_fRunningOnNT)
    {
        SHTCharToUnicode(pszPath, wzPath, ARRAYSIZE(wzPath));
        pszPath = (LPCTSTR)wzPath;  // overload the pointer to pass through...
    }
    else
    {
        SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
        pszPath = (LPCTSTR)szPath;  // overload the pointer to pass through...
    }

    return ILCreateFromPath(pszPath);
}

int _AorW_PathCleanupSpec(/*IN OPTIONAL*/ LPCTSTR pszDir, /*IN OUT*/ LPTSTR pszSpec)
{
    THUNKMSG(TEXT("PathCleanupSpec"));

    if (g_fRunningOnNT)
    {
        WCHAR wzDir[MAX_PATH];
        WCHAR wzSpec[MAX_PATH];
        LPWSTR pwszDir = wzDir;
        int iRet;

        if (pszDir)
            SHTCharToUnicode(pszDir, wzDir, ARRAYSIZE(wzDir));
        else
            pwszDir = NULL;

        SHTCharToUnicode(pszSpec, wzSpec, ARRAYSIZE(wzSpec));
        iRet = PathCleanupSpec((LPTSTR)pwszDir, (LPTSTR)wzSpec);

        SHUnicodeToTChar(wzSpec, pszSpec, MAX_PATH);
        return iRet;
    }
    else
    {
        CHAR szDir[MAX_PATH];
        CHAR szSpec[MAX_PATH];
        LPSTR pszDir2 = szDir;
        int iRet;

        if (pszDir)
            SHTCharToAnsi(pszDir, szDir, ARRAYSIZE(szDir));
        else
            pszDir2 = NULL;

        SHTCharToAnsi(pszSpec, szSpec, ARRAYSIZE(szSpec));
        iRet = PathCleanupSpec((LPTSTR)pszDir2, (LPTSTR)szSpec);

        SHAnsiToTChar(szSpec, pszSpec, MAX_PATH);
        return iRet;
    }
}

void _AorW_PathQualify(/*IN OUT*/ LPTSTR pszDir)
{
    THUNKMSG(TEXT("PathQualify"));
    if (g_fRunningOnNT)
    {
        WCHAR wszDir[MAX_PATH];

        SHTCharToUnicode(pszDir, wszDir, ARRAYSIZE(wszDir));
        PathQualify((LPTSTR)wszDir);
        SHUnicodeToTChar(wszDir, pszDir, MAX_PATH);
    }
    else
    {
        CHAR szDir[MAX_PATH];

        SHTCharToAnsi(pszDir, szDir, ARRAYSIZE(szDir));
        PathQualify((LPTSTR)szDir);
        SHAnsiToTChar(szDir, pszDir, MAX_PATH);
    }
}

LONG WINAPI _AorW_PathProcessCommand(/*IN*/ LPCTSTR pszSrc, /*OUT*/LPTSTR pszDest, int iDestMax, DWORD dwFlags)
{
    LONG    lReturnValue;

    THUNKMSG(TEXT("PathProcessCommand"));
    if (g_fRunningOnNT)
    {
        WCHAR wszSrc[MAX_PATH];
        WCHAR wszDest[MAX_PATH];

        SHTCharToUnicode(pszSrc, wszSrc, ARRAYSIZE(wszSrc));
        lReturnValue = PathProcessCommand((LPTSTR)wszSrc, (LPTSTR)wszDest, ARRAYSIZE(wszDest), dwFlags);
        SHUnicodeToTChar(wszDest, pszDest, iDestMax);
    }
    else
    {
        CHAR szSrc[MAX_PATH];
        CHAR szDest[MAX_PATH];

        SHTCharToAnsi(pszSrc, szSrc, ARRAYSIZE(szSrc));
        lReturnValue = PathProcessCommand((LPTSTR)szSrc, (LPTSTR)szDest, ARRAYSIZE(szDest), dwFlags);
        SHAnsiToTChar(szDest, pszDest, iDestMax);
    }

    return(lReturnValue);
}

#ifndef UNIX

// Explicit prototype because only the A/W prototypes exist in the headers
STDAPI_(BOOL) SHGetSpecialFolderPath(HWND hwndOwner, LPTSTR lpszPath, int nFolder, BOOL fCreate);

#else

#ifdef UNICODE
#define SHGetSpecialFolderPath SHGetSpecialFolderPathW
#else
#define SHGetSpecialFolderPath SHGetSpecialFolderPathA
#endif

#endif

BOOL _AorW_SHGetSpecialFolderPath(HWND hwndOwner, /*OUT*/ LPTSTR pszPath, int nFolder, BOOL fCreate)
{
    THUNKMSG(TEXT("SHGetSpecialFolderPath"));

    if (g_fRunningOnNT)
    {
        WCHAR wzPath[MAX_PATH];

        BOOL fRet = SHGetSpecialFolderPath(hwndOwner, (LPTSTR)wzPath, nFolder, fCreate);
        if (fRet)
            SHUnicodeToTChar(wzPath, pszPath, MAX_PATH);

        return fRet;
    }
    else
    {
        CHAR szPath[MAX_PATH];

        BOOL fRet = SHGetSpecialFolderPath(hwndOwner, (LPTSTR)szPath, nFolder, fCreate);
        if (fRet)
            SHAnsiToTChar(szPath, pszPath, MAX_PATH);

        return fRet;
    }
}

HRESULT _AorW_SHILCreateFromPath(/*IN OPTIONAL*/LPCTSTR pszPath, LPITEMIDLIST *ppidl, DWORD *rgfInOut)
{
    WCHAR wzPath[MAX_PATH];
    CHAR szPath[MAX_PATH];

    THUNKMSG(TEXT("SHILCreateFromPath"));

    if (pszPath)
    {
        if (g_fRunningOnNT)
        {
            SHTCharToUnicode(pszPath, wzPath, ARRAYSIZE(wzPath));
            pszPath = (LPCTSTR)wzPath;  // overload the pointer to pass through...
        }
        else
        {
            SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
            pszPath = (LPCTSTR)szPath;  // overload the pointer to pass through...
        }
    }

    return SHILCreateFromPath(pszPath, ppidl, rgfInOut);
}

LPITEMIDLIST _AorW_SHSimpleIDListFromPath(/*IN OPTIONAL*/ LPCTSTR pszPath)
{
    WCHAR wzPath[MAX_PATH];
    CHAR szPath[MAX_PATH];

    THUNKMSG(TEXT("SHSimpleIDListFromPath"));

    if (pszPath)
    {
        if (g_fRunningOnNT)
        {
            SHTCharToUnicode(pszPath, wzPath, ARRAYSIZE(wzPath));
            pszPath = (LPCTSTR)wzPath;  // overload the pointer to pass through...
        }
        else
        {
            SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
            pszPath = (LPCTSTR)szPath;  // overload the pointer to pass through...
        }
    }

    return SHSimpleIDListFromPath(pszPath);
}

#define ISNOT_RESOURCE(pItem)      ((pItem) && HIWORD((pItem)) && LOWORD((pItem)))

int FindDoubleTerminator(LPCTSTR pszStr)
{
    int nIndex = 1;

    // Find the double terminator
    while (pszStr[nIndex] || pszStr[nIndex-1])
        nIndex++;

    return nIndex;
}

#define TEMP_SMALL_BUF_SZ  256

BOOL WINAPI _AorW_GetFileNameFromBrowse(HWND hwnd, /*IN OUT*/ LPTSTR pszFilePath, UINT cchFilePath,
        /*IN OPTIONAL*/ LPCTSTR pszWorkingDir, /*IN OPTIONAL*/ LPCTSTR pszDefExt, 
        /*IN OPTIONAL*/ LPCTSTR pszFilters, /*IN OPTIONAL*/ LPCTSTR pszTitle)
{
    WCHAR wszPath[MAX_PATH];
    WCHAR wszDir[MAX_PATH];
    WCHAR wszExt[TEMP_SMALL_BUF_SZ];
    WCHAR wszTitle[TEMP_SMALL_BUF_SZ];

#ifndef UNICODE
    WCHAR wszFilters[TEMP_SMALL_BUF_SZ*2];
#else // UNICODE
    CHAR szFilters[TEMP_SMALL_BUF_SZ*2];
#endif // UNICODE

    CHAR szPath[MAX_PATH];
    CHAR szDir[MAX_PATH];
    CHAR szExt[TEMP_SMALL_BUF_SZ];
    CHAR szTitle[TEMP_SMALL_BUF_SZ];
    BOOL    bResult;
    THUNKMSG(TEXT("GetFileNameFromBrowse"));

    // thunk strings to unicode 
    if (g_fRunningOnNT)
    {
        // always move pszFilePath stuff to wszPath buffer. Should never be a resourceid.
        SHTCharToUnicode(pszFilePath, wszPath, ARRAYSIZE(wszPath));
        pszFilePath = (LPTSTR)wszPath;

        if (ISNOT_RESOURCE(pszWorkingDir)) //not a resource
        {
            SHTCharToUnicode(pszWorkingDir, wszDir, ARRAYSIZE(wszDir));
            pszWorkingDir = (LPCTSTR)wszDir;
        }
        if (ISNOT_RESOURCE(pszDefExt)) //not a resource
        {
            SHTCharToUnicode(pszDefExt, wszExt, ARRAYSIZE(wszExt));
            pszDefExt = (LPCTSTR)wszExt;
        }
        if (ISNOT_RESOURCE(pszFilters)) //not a resource
        {
#ifndef UNICODE
            int nIndex = FindDoubleTerminator(pszFilters);

            // nIndex+1 looks like bunk unless it goes past the terminator
            MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)pszFilters, nIndex+1, wszFilters, ARRAYSIZE(wszFilters));
            pszFilters = (LPCTSTR)wszFilters;
#endif // UNICODE
        }
        if (ISNOT_RESOURCE(pszTitle)) //not a resource
        {
            SHTCharToUnicode(pszTitle, wszTitle, ARRAYSIZE(wszTitle));
            pszTitle = (LPCTSTR)wszTitle;
        }
    }
    else
    {
        // always move pszFilePath stuff to wszPath buffer. Should never be a resourceid.
        SHTCharToAnsi(pszFilePath, szPath, ARRAYSIZE(szPath));
        pszFilePath = (LPTSTR)szPath;

        if (ISNOT_RESOURCE(pszWorkingDir)) //not a resource
        {
            SHTCharToAnsi(pszWorkingDir, szDir, ARRAYSIZE(szDir));
            pszWorkingDir = (LPCTSTR)szDir;
        }
        if (ISNOT_RESOURCE(pszDefExt)) //not a resource
        {
            SHTCharToAnsi(pszDefExt, szExt, ARRAYSIZE(szExt));
            pszDefExt = (LPCTSTR)szExt;
        }
        if (ISNOT_RESOURCE(pszFilters)) //not a resource
        {
#ifdef UNICODE
            int nIndex = FindDoubleTerminator(pszFilters);

            // nIndex+1 looks like bunk unless it goes past the terminator
            WideCharToMultiByte(CP_ACP, 0, (LPCTSTR)pszFilters, nIndex+1, szFilters, ARRAYSIZE(szFilters), NULL, NULL);
            pszFilters = (LPCTSTR)szFilters;
#endif // UNICODE
        }
        if (ISNOT_RESOURCE(pszTitle)) //not a resource
        {
            SHTCharToAnsi(pszTitle, szTitle, ARRAYSIZE(szTitle));
            pszTitle = (LPCTSTR)szTitle;
        }
    }

    bResult = GetFileNameFromBrowse(hwnd, pszFilePath, cchFilePath, pszWorkingDir, pszDefExt, pszFilters, pszTitle);

    // thunk string back to multibyte
    if (g_fRunningOnNT)
        SHUnicodeToTChar(wszPath, pszFilePath, cchFilePath);
    else
        SHAnsiToTChar(szPath, pszFilePath, cchFilePath);

    return bResult;
}

BOOL _AorW_Win32DeleteFile(/*IN*/ LPCTSTR pszFileName)
{
    WCHAR wzPath[MAX_PATH];
    CHAR szPath[MAX_PATH];

    THUNKMSG(TEXT("Win32DeleteFile"));
    if (g_fRunningOnNT)
    {
        SHTCharToUnicode(pszFileName, wzPath, ARRAYSIZE(wzPath));
        pszFileName = (LPCTSTR)wzPath;  // overload the pointer to pass through...
    }
    else
    {
        SHTCharToAnsi(pszFileName, szPath, ARRAYSIZE(szPath));
        pszFileName = (LPCTSTR)szPath;  // overload the pointer to pass through...
    }

    return Win32DeleteFile(pszFileName);
}

BOOL _AorW_PathYetAnotherMakeUniqueName(LPTSTR pszUniqueName,
                                        LPCTSTR pszPath,
                                        LPCTSTR pszShort,
                                        LPCTSTR pszFileSpec)
{
    THUNKMSG(TEXT("PathYetAnotherMakeUniqueName"));
    if (UseUnicodeShell32())
    {
        WCHAR wszUniqueName[MAX_PATH];
        WCHAR wszPath[MAX_PATH];
        WCHAR wszShort[32];
        WCHAR wszFileSpec[MAX_PATH];
        BOOL fRet;

        SHTCharToUnicode(pszPath, wszPath, ARRAYSIZE(wszPath));
        pszPath = (LPCTSTR)wszPath;  // overload the pointer to pass through...

        if (pszShort)
        {
            SHTCharToUnicode(pszShort, wszShort, ARRAYSIZE(wszShort));
            pszShort = (LPCTSTR)wszShort;  // overload the pointer to pass through...
        }

        if (pszFileSpec)
        {
            SHTCharToUnicode(pszFileSpec, wszFileSpec, ARRAYSIZE(wszFileSpec));
            pszFileSpec = (LPCTSTR)wszFileSpec;  // overload the pointer to pass through...
        }

        fRet = PathYetAnotherMakeUniqueName((LPTSTR)wszUniqueName, pszPath, pszShort, pszFileSpec);
        if (fRet)
            SHUnicodeToTChar(wszUniqueName, pszUniqueName, MAX_PATH);

        return fRet;
    }
    else
    {
        CHAR szUniqueName[MAX_PATH];
        CHAR szPath[MAX_PATH];
        CHAR szShort[32];
        CHAR szFileSpec[MAX_PATH];
        BOOL fRet;

        SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
        pszPath = (LPCTSTR)szPath;  // overload the pointer to pass through...

        if (pszShort)
        {
            SHTCharToAnsi(pszShort, szShort, ARRAYSIZE(szShort));
            pszShort = (LPCTSTR)szShort;  // overload the pointer to pass through...
        }

        if (pszFileSpec)
        {
            SHTCharToAnsi(pszFileSpec, szFileSpec, ARRAYSIZE(szFileSpec));
            pszFileSpec = (LPCTSTR)szFileSpec;  // overload the pointer to pass through...
        }

        fRet = PathYetAnotherMakeUniqueName((LPTSTR)szUniqueName, pszPath, pszShort, pszFileSpec);
        if (fRet)
            SHAnsiToTChar(szUniqueName, pszUniqueName, MAX_PATH);

        return fRet;
    }
}

BOOL _AorW_PathResolve(/*IN OUT*/ LPTSTR pszPath, /*IN OPTIONAL*/ LPCTSTR rgpszDirs[], UINT fFlags)
{
    THUNKMSG(TEXT("PathResolve"));
    if (g_fRunningOnNT)
    {
        WCHAR wzPath[MAX_PATH];
        WCHAR wzDir[MAX_PATH];
        BOOL fRet;

        SHTCharToUnicode(pszPath, wzPath, ARRAYSIZE(wzPath));

        if (rgpszDirs && rgpszDirs[0])
        {
            SHTCharToUnicode(rgpszDirs[0], wzDir, ARRAYSIZE(wzDir));
            rgpszDirs[0] = (LPCTSTR)wzDir;  // overload the pointer to pass through...

            if (rgpszDirs[1])
            {
                // Super Hack, we assume dirs has only one element since it's the only case
                // this is called in SHDOCVW.
                AssertMsg(0, TEXT("PathResolve thunk needs to be fixed to handle more than one dirs."));
                rgpszDirs[1] = NULL;
            }
        }

        fRet = PathResolve((LPTSTR)wzPath, rgpszDirs, fFlags);
        if (fRet)
            SHUnicodeToTChar(wzPath, pszPath, MAX_PATH);

        return fRet;
    }
    else
    {
        CHAR szPath[MAX_PATH];
        CHAR szDir[MAX_PATH];
        BOOL fRet;

        SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));

        if (rgpszDirs && rgpszDirs[0])
        {
            SHTCharToAnsi(rgpszDirs[0], szDir, ARRAYSIZE(szDir));
            rgpszDirs[0] = (LPCTSTR)szDir;  // overload the pointer to pass through...

            if (rgpszDirs[1])
            {
                // Super Hack, we assume dirs has only one element since it's the only case
                // this is called in SHDOCVW.
                AssertMsg(0, TEXT("PathResolve thunk needs to be fixed to handle more than one dirs."));
                rgpszDirs[1] = NULL;
            }
        }

        fRet = PathResolve((LPTSTR)szPath, rgpszDirs, fFlags);
        if (fRet)
            SHAnsiToTChar(szPath, pszPath, MAX_PATH);

        return fRet;
    }
}


#ifndef UNIX

// Explicit prototype because only the A/W prototypes exist in the headers
BOOL IsLFNDrive(LPCTSTR pszPath);

#else

#ifdef UNICODE
#define IsLFNDrive IsLFNDriveW
#else
#define IsLFNDrive IsLFNDriveA
#endif

#endif


BOOL _AorW_IsLFNDrive(/*IN*/ LPTSTR pszPath)
{
    THUNKMSG(TEXT("IsLFNDrive"));

    if (g_fRunningOnNT)
    {
        WCHAR wszPath[MAX_PATH];

        SHTCharToUnicode(pszPath, wszPath, ARRAYSIZE(wszPath));
        return IsLFNDrive((LPTSTR)wszPath);
    }
    else
    {
        CHAR szPath[MAX_PATH];

        SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
        return IsLFNDrive((LPTSTR)szPath);
    }
}


int _AorW_PickIconDlg(
    IN     HWND  hwnd, 
    IN OUT LPTSTR pszIconPath, 
    IN     UINT  cchIconPath, 
    IN OUT int * piIconIndex)
{
    int nRet;
    WCHAR wszPath[MAX_PATH];
    CHAR szPath[MAX_PATH];
    LPTSTR psz = pszIconPath;
    UINT cch = cchIconPath;
    
    if (g_fRunningOnNT)
    {
        SHTCharToUnicode(pszIconPath, wszPath, ARRAYSIZE(wszPath));
        psz = (LPTSTR)wszPath;  // overload the pointer to pass through...
        cch = SIZECHARS(wszPath);
    }
    else
    {
        SHTCharToAnsi(pszIconPath, szPath, ARRAYSIZE(wszPath));
        psz = (LPTSTR)szPath;  // overload the pointer to pass through...
        cch = SIZECHARS(szPath);
    }

    nRet = PickIconDlg(hwnd, psz, cch, piIconIndex);

    if (g_fRunningOnNT)
        SHUnicodeToTChar(wszPath, pszIconPath, cchIconPath);
    else
        SHAnsiToTChar(szPath, pszIconPath, cchIconPath);

    return nRet;
}

//
//  Now the thunks that allow us to run on Windows 95.
//
//

//
//  This thunks a unicode string to ANSI, but if it's an ordinal, then
//  we just leave it alone.
//
LPSTR Thunk_UnicodeToAnsiOrOrdinal(LPCWSTR pwsz, LPSTR pszBuf, UINT cchBuf)
{
    if (HIWORD64(pwsz)) {
        SHUnicodeToAnsi(pwsz, pszBuf, cchBuf);
        return pszBuf;
    } else {
        return (LPSTR)pwsz;
    }
}

#define THUNKSTRING(pwsz, sz) Thunk_UnicodeToAnsiOrOrdinal(pwsz, sz, ARRAYSIZE(sz))


//
//  This function is new for IE4, so on IE3,
//  we emulate (poorly) with ExtractIcon.
//

//
//  Win95 exported ILCreateFromPathA under the name ILCreateFromPath.
//  Fortunately, NT kept the same ordinal.
//
//
//  If linking with Win95 header files, then call it ILCreateFromPath.
//

#ifdef UNICODE
STDAPI_(LPITEMIDLIST) _ILCreateFromPathA(LPCSTR pszPath)
{
    if (g_fRunningOnNT) {
        WCHAR wszPath[MAX_PATH];
        SHAnsiToUnicode(pszPath, wszPath, ARRAYSIZE(wszPath));
        return ILCreateFromPath((LPVOID)wszPath);
    } else {
        return ILCreateFromPath((LPVOID)pszPath);
    }
}
#else
STDAPI_(LPITEMIDLIST) _ILCreateFromPathW(LPCWSTR pszPath)
{
    if (g_fRunningOnNT) {
        return ILCreateFromPath((LPVOID)pszPath);
    } else {
        CHAR szPath[MAX_PATH];
        SHUnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
        return ILCreateFromPath((LPVOID)szPath);
    }
}
#endif

        
STDAPI_(int) _AorW_SHCreateDirectory(HWND hwnd, LPCTSTR pszPath)
{
    if (g_fRunningOnNT)
    {
        WCHAR wsz[MAX_PATH];

        SHTCharToUnicode(pszPath, wsz, ARRAYSIZE(wsz));
        return SHCreateDirectory(hwnd, (LPCTSTR)wsz);
    }
    else
    {
        CHAR  sz[MAX_PATH];

        SHTCharToAnsi(pszPath, sz, ARRAYSIZE(sz));
        return SHCreateDirectory(hwnd, (LPCTSTR)sz);
    }
}

#ifdef UNICODE

//
//  Either ptsz1 or ptsz2 can be NULL, so be careful when thunking.
//
STDAPI_(int) _AorW_ShellAbout(HWND hWnd, LPCTSTR ptsz1, LPCTSTR ptsz2, HICON hIcon)
{
    if (g_fRunningOnNT)
    {
        return ShellAboutW(hWnd, ptsz1, ptsz2, hIcon);
    }
    else
    {
        CHAR  sz1[MAX_PATH], sz2[MAX_PATH];
        LPSTR psz1, psz2;

        if (ptsz1) {
            psz1 = sz1;
            SHTCharToAnsi(ptsz1, sz1, ARRAYSIZE(sz1));
        } else {
            psz1 = NULL;
        }

        if (ptsz2) {
            psz2 = sz2;
            SHTCharToAnsi(ptsz2, sz2, ARRAYSIZE(sz2));
        } else {
            psz2 = NULL;
        }

        return ShellAboutA(hWnd, psz1, psz2, hIcon);
    }
}

#endif

#endif // _X86_
