|
|
#include "priv.h"
// no wrappers are needed on non-x86 since this is only for win9x interop
#ifdef _X86_
#include <mluisupp.h>
//============================================================================
// 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 ShellMessageBox
#undef GetFileNameFromBrowse
#undef OpenRegStream
#undef Win32DeleteFile
#undef PathYetAnotherMakeUniqueName
#undef PathResolve
#undef IsLFNDrive
#undef Shell_GetCachedImageIndex
#undef SHRunControlPanel
#undef PickIconDlg
#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)
// FEATURE:: need to properly handle not having ILGetdisplaynameex...
typedef BOOL (*PFNILGETDISPLAYNAMEEX)(LPSHELLFOLDER psfRoot, LPCITEMIDLIST pidl, LPTSTR pszName, int fType);
#ifndef ANSI_SHELL32_ON_UNIX
#define UseUnicodeShell32() (g_fRunningOnNT)
#else
#define UseUnicodeShell32() (FALSE)
#endif
//=================================================================================
// Now the thunks...
int _AorW_SHRunControlPanel(LPCTSTR pszOrig_cmdline, HWND errwnd) { CHAR szPath[MAX_PATH]; if (!UseUnicodeShell32()) { UnicodeToAnsi(pszOrig_cmdline, szPath, ARRAYSIZE(szPath)); pszOrig_cmdline = (LPCTSTR)szPath; // overload the pointer to pass through...
} return SHRunControlPanel(pszOrig_cmdline, errwnd); }
int _AorW_Shell_GetCachedImageIndex(LPCTSTR pszIconPath, int iIconIndex, UINT uIconFlags) { CHAR szPath[MAX_PATH]; if (!UseUnicodeShell32()) { UnicodeToAnsi(pszIconPath, szPath, ARRAYSIZE(szPath)); pszIconPath = (LPCTSTR)szPath; // overload the pointer to pass through...
} return Shell_GetCachedImageIndex(pszIconPath, iIconIndex, uIconFlags); }
// the reverse, do it for wide strings also..
int _WorA_Shell_GetCachedImageIndex(LPCWSTR pszIconPath, int iIconIndex, UINT uIconFlags) { CHAR szPath[MAX_PATH]; if (!UseUnicodeShell32()) { UnicodeToAnsi(pszIconPath, szPath, ARRAYSIZE(szPath)); pszIconPath = (LPCWSTR)szPath; // overload the pointer to pass through...
} return Shell_GetCachedImageIndex( (LPCTSTR) pszIconPath, iIconIndex, uIconFlags); }
// Explicit prototype because only the A/W prototypes exist in the headers
WINSHELLAPI LPITEMIDLIST WINAPI ILCreateFromPath(LPCTSTR pszPath);
LPITEMIDLIST _AorW_ILCreateFromPath(LPCTSTR pszPath) { CHAR szPath[MAX_PATH]; THUNKMSG(TEXT("ILCreateFromPath")); if (!UseUnicodeShell32()) { UnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath)); pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
}
return ILCreateFromPath(pszPath); }
int _AorW_PathCleanupSpec(LPCTSTR pszDir, LPTSTR pszSpec) { THUNKMSG(TEXT("PathCleanupSpec")); if (!UseUnicodeShell32()) { CHAR szDir[MAX_PATH]; CHAR szSpec[MAX_PATH]; LPSTR pszDir2 = szDir; int iRet;
if (pszDir) { UnicodeToAnsi(pszDir, szDir, ARRAYSIZE(szDir)); } else { pszDir2 = NULL; }
UnicodeToAnsi(pszSpec, szSpec, ARRAYSIZE(szSpec));
iRet = PathCleanupSpec((LPTSTR)pszDir2, (LPTSTR)szSpec);
AnsiToUnicode(szSpec, pszSpec, MAX_PATH); return iRet; } else return PathCleanupSpec(pszDir, pszSpec); }
void _AorW_PathQualify(LPTSTR pszDir) { THUNKMSG(TEXT("PathQualify")); if (!UseUnicodeShell32()) { CHAR szDir[MAX_PATH];
UnicodeToAnsi(pszDir, szDir, ARRAYSIZE(szDir)); PathQualify((LPTSTR)szDir); AnsiToUnicode(szDir, pszDir, MAX_PATH); } else PathQualify(pszDir); }
LONG WINAPI _AorW_PathProcessCommand(LPCTSTR lpSrc, LPTSTR lpDest, int iDestMax, DWORD dwFlags) { LONG lReturnValue;
THUNKMSG(TEXT("PathProcessCommand")); if (!UseUnicodeShell32()) { CHAR szSrc[MAX_PATH]; CHAR szDest[MAX_PATH];
UnicodeToAnsi(lpSrc, szSrc, ARRAYSIZE(szSrc)); lReturnValue = PathProcessCommand((LPTSTR)szSrc, (LPTSTR)szDest, iDestMax, dwFlags); AnsiToUnicode(szDest, lpDest, iDestMax); } else lReturnValue = PathProcessCommand(lpSrc, lpDest, iDestMax, dwFlags);
return(lReturnValue); }
HRESULT _AorW_SHCLSIDFromString(LPCTSTR lpsz, LPCLSID lpclsid) { CHAR szPath[MAX_PATH]; THUNKMSG(TEXT("SHCLSIDFromString")); if (!UseUnicodeShell32()) { UnicodeToAnsi(lpsz, szPath, ARRAYSIZE(szPath)); lpsz = (LPCTSTR)szPath; // overload the pointer to pass through...
}
return SHCLSIDFromString(lpsz, lpclsid); }
#ifndef UNIX
// Explicit prototype because only the A/W prototypes exist in the headers
WINSHELLAPI BOOL WINAPI 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, LPTSTR pszPath, int nFolder, BOOL fCreate) { THUNKMSG(TEXT("SHGetSpecialFolderPath")); if (!UseUnicodeShell32()) { CHAR szPath[MAX_PATH]; BOOL fRet = SHGetSpecialFolderPath(hwndOwner, (LPTSTR)szPath, nFolder, fCreate); if (fRet) AnsiToUnicode(szPath, pszPath, MAX_PATH); return fRet; } else return SHGetSpecialFolderPath(hwndOwner, pszPath, nFolder, fCreate); }
HRESULT _AorW_SHILCreateFromPath(LPCTSTR pszPath, LPITEMIDLIST *ppidl, DWORD *rgfInOut) { WCHAR wszPath[MAX_PATH]; CHAR szPath[MAX_PATH];
THUNKMSG(TEXT("SHILCreateFromPath"));
if (pszPath) { //
// Shell32 will blindly copy pszPath into a MAX_PATH buffer. This
// results in a exploitable buffer overrun. Do not pass more than
// MAX_PATH characters.
//
if (!UseUnicodeShell32()) { UnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath)); pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
} else if (lstrlenW(pszPath) >= MAX_PATH) { StrCpyN(wszPath, pszPath, ARRAYSIZE(wszPath)); pszPath = wszPath; // overload the pointer to pass through...
} }
return SHILCreateFromPath(pszPath, ppidl, rgfInOut); }
LPITEMIDLIST _AorW_SHSimpleIDListFromPath(LPCTSTR pszPath) { CHAR szPath[MAX_PATH]; THUNKMSG(TEXT("SHSimpleIDListFromPath")); if (!UseUnicodeShell32() && pszPath) { UnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath)); pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
}
return SHSimpleIDListFromPath(pszPath); }
#define TEMP_SMALL_BUF_SZ 256
BOOL WINAPI _AorW_GetFileNameFromBrowse(HWND hwnd, LPTSTR pszFilePath, UINT cchFilePath, LPCTSTR pszWorkingDir, LPCTSTR pszDefExt, LPCTSTR pszFilters, LPCTSTR pszTitle) { CHAR szPath[MAX_PATH]; CHAR szDir[MAX_PATH]; CHAR szExt[TEMP_SMALL_BUF_SZ]; CHAR szFilters[TEMP_SMALL_BUF_SZ*2]; CHAR szTitle[TEMP_SMALL_BUF_SZ]; LPTSTR pszPath = pszFilePath; BOOL bResult; THUNKMSG(TEXT("GetFileNameFromBrowse"));
// thunk strings to ansi
if (!UseUnicodeShell32()) { // always move szFilePath stuff to wszPath buffer. Should never be a resourceid.
UnicodeToAnsi((LPCTSTR)pszFilePath, szPath, ARRAYSIZE(szPath)); pszPath = (LPTSTR)szPath; if (!IS_INTRESOURCE(pszWorkingDir)) //not a resource
{ UnicodeToAnsi((LPCTSTR)pszWorkingDir, szDir, ARRAYSIZE(szDir)); pszWorkingDir = (LPCTSTR)szDir; } if (!IS_INTRESOURCE(pszDefExt)) //not a resource
{ UnicodeToAnsi((LPCTSTR)pszDefExt, szExt, ARRAYSIZE(szExt)); pszDefExt = (LPCTSTR)szExt; } if (!IS_INTRESOURCE(pszFilters)) //not a resource
{ int l=1; while (*(pszFilters+l) != 0 || *(pszFilters+l-1) != 0) l++; WideCharToMultiByte(CP_ACP, 0, (LPCTSTR)pszFilters, l+1, szFilters, ARRAYSIZE(szFilters), NULL, NULL); pszFilters = (LPCTSTR)szFilters; } if (!IS_INTRESOURCE(pszTitle)) //not a resource
{ UnicodeToAnsi((LPCTSTR)pszTitle, szTitle, ARRAYSIZE(szTitle)); pszTitle = (LPCTSTR)szTitle; } }
bResult = GetFileNameFromBrowse(hwnd, pszPath, cchFilePath, pszWorkingDir, pszDefExt, pszFilters, pszTitle);
if (!UseUnicodeShell32()) { AnsiToUnicode(szPath, pszFilePath, cchFilePath); }
return (bResult); }
IStream * _AorW_OpenRegStream(HKEY hkey, LPCTSTR pszSubkey, LPCTSTR pszValue, DWORD grfMode) { CHAR szSubkey[MAX_PATH]; // large enough to hold most any name...
CHAR szValue[MAX_PATH]; // dito.
if (!UseUnicodeShell32()) {
UnicodeToAnsi(pszSubkey, szSubkey, ARRAYSIZE(szSubkey)); pszSubkey = (LPCTSTR)szSubkey; if (pszValue) { UnicodeToAnsi(pszValue, szValue, ARRAYSIZE(szValue)); pszValue = (LPCTSTR)szValue; } }
return OpenRegStream(hkey, pszSubkey, pszValue, grfMode);
}
BOOL _AorW_Win32DeleteFile(LPCTSTR lpszFileName) { CHAR szPath[MAX_PATH]; THUNKMSG(TEXT("Win32DeleteFile")); if (!UseUnicodeShell32()) { UnicodeToAnsi(lpszFileName, szPath, ARRAYSIZE(szPath)); lpszFileName = (LPCTSTR)szPath; // overload the pointer to pass through...
} return Win32DeleteFile(lpszFileName); }
BOOL _AorW_PathYetAnotherMakeUniqueName(LPTSTR pszUniqueName, LPCTSTR pszPath, LPCTSTR pszShort, LPCTSTR pszFileSpec) { CHAR szUniqueName[MAX_PATH]; CHAR szPath[MAX_PATH]; CHAR szShort[32]; CHAR szFileSpec[MAX_PATH]; BOOL fRet; THUNKMSG(TEXT("PathYetAnotherMakeUniqueName")); if (!UseUnicodeShell32()) { UnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath)); pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
if (pszShort) { UnicodeToAnsi(pszShort, szShort, ARRAYSIZE(szShort)); pszShort = (LPCTSTR)szShort; // overload the pointer to pass through...
}
if (pszFileSpec) { UnicodeToAnsi(pszFileSpec, szFileSpec, ARRAYSIZE(szFileSpec)); pszFileSpec = (LPCTSTR)szFileSpec; // overload the pointer to pass through...
}
fRet = PathYetAnotherMakeUniqueName((LPTSTR)szUniqueName, pszPath, pszShort, pszFileSpec); if (fRet) AnsiToUnicode(szUniqueName, pszUniqueName, MAX_PATH);
return fRet; } else return PathYetAnotherMakeUniqueName(pszUniqueName, pszPath, pszShort, pszFileSpec); }
BOOL _AorW_PathResolve(LPTSTR lpszPath, LPCTSTR rgpszDirs[], UINT fFlags) { CHAR szPath[MAX_PATH]; CHAR szDir[MAX_PATH]; BOOL fRet; THUNKMSG(TEXT("PathResolve")); if (!UseUnicodeShell32()) { // WARNING!!!
// Super Hack, we assume dirs has only one element since it's the only case
// this is called in SHDOCVW.
UnicodeToAnsi(lpszPath, szPath, ARRAYSIZE(szPath));
if (rgpszDirs && rgpszDirs[0]) { UnicodeToAnsi(rgpszDirs[0], szDir, ARRAYSIZE(szDir)); rgpszDirs[0] = (LPCTSTR)szDir; // overload the pointer to pass through...
if (rgpszDirs[1]) { 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) AnsiToUnicode(szPath, lpszPath, MAX_PATH);
return fRet; } else return PathResolve(lpszPath, rgpszDirs, fFlags); }
// Explicit prototype because only the A/W prototypes exist in the headers
// For UNIX, the old prototype should be defined, because there is no export
// by ordinal there and IsLFNDrive is exported from shell32 just this way.
#ifndef UNIX
BOOL IsLFNDrive(LPCTSTR pszPath); #else
# ifdef UNICODE
# define IsLFNDrive IsLFNDriveW
# else
# define IsLFNDrive IsLFNDriveA
# endif
#endif
BOOL _AorW_IsLFNDrive(LPTSTR lpszPath) { CHAR szPath[MAX_PATH]; THUNKMSG(TEXT("IsLFNDrive")); if (!UseUnicodeShell32()) { UnicodeToAnsi(lpszPath, szPath, ARRAYSIZE(szPath)); return IsLFNDrive((LPCTSTR)szPath); } return IsLFNDrive((LPCTSTR)lpszPath); }
int _AorW_PickIconDlg( IN HWND hwnd, IN OUT LPTSTR pszIconPath, IN UINT cchIconPath, IN OUT int * piIconIndex) { int nRet;
if (UseUnicodeShell32()) { nRet = PickIconDlg(hwnd, pszIconPath, cchIconPath, piIconIndex); } else { CHAR szPath[MAX_PATH]; UINT cch = ARRAYSIZE(szPath);
UnicodeToAnsi(pszIconPath, szPath, cch); nRet = PickIconDlg(hwnd, (LPTSTR)szPath, cch, piIconIndex); AnsiToUnicode(szPath, pszIconPath, cchIconPath); }
return nRet; }
STDAPI_(int) _AorW_SHCreateDirectory(HWND hwnd, LPCTSTR pszPath) { if (UseUnicodeShell32()) { 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); } }
#endif // _X86_
|