Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

373 lines
11 KiB

  1. #include "priv.h"
  2. #include <strsafe.h>
  3. // no wrappers are needed on non-x86 since this is only for win9x interop
  4. #ifdef _X86_
  5. #include <mluisupp.h>
  6. //============================================================================
  7. // This file contains a bunch of Unicode/Ansi thunks to handle calling
  8. // some internal functions that on Windows 95 the strings are Ansi,
  9. // whereas the string on NT are unicode
  10. //============================================================================
  11. // First undefine everything that we are intercepting as to not forward back to us...
  12. #undef ILCreateFromPath
  13. #undef PathCleanupSpec
  14. #undef PathProcessCommand
  15. #undef SHCLSIDFromString
  16. #undef SHGetSpecialFolderPath
  17. #undef SHILCreateFromPath
  18. #undef SHSimpleIDListFromPath
  19. #undef ShellMessageBox
  20. #undef GetFileNameFromBrowse
  21. #undef OpenRegStream
  22. #undef PathYetAnotherMakeUniqueName
  23. #undef Shell_GetCachedImageIndex
  24. #undef SHRunControlPanel
  25. #undef PickIconDlg
  26. #undef SHCreateDirectory
  27. #define TF_THUNK 0
  28. #define THUNKMSG(psz) TraceMsg(TF_THUNK, "shdv THUNK::%s", psz)
  29. // FEATURE:: need to properly handle not having ILGetdisplaynameex...
  30. typedef BOOL (*PFNILGETDISPLAYNAMEEX)(LPSHELLFOLDER psfRoot, LPCITEMIDLIST pidl, LPTSTR pszName, int fType);
  31. #ifndef ANSI_SHELL32_ON_UNIX
  32. #define UseUnicodeShell32() (g_fRunningOnNT)
  33. #else
  34. #define UseUnicodeShell32() (FALSE)
  35. #endif
  36. //=================================================================================
  37. // Now the thunks...
  38. int _AorW_SHRunControlPanel(LPCTSTR pszOrig_cmdline, HWND errwnd)
  39. {
  40. CHAR szPath[MAX_PATH];
  41. if (!UseUnicodeShell32())
  42. {
  43. UnicodeToAnsi(pszOrig_cmdline, szPath, ARRAYSIZE(szPath));
  44. pszOrig_cmdline = (LPCTSTR)szPath; // overload the pointer to pass through...
  45. }
  46. return SHRunControlPanel(pszOrig_cmdline, errwnd);
  47. }
  48. int _AorW_Shell_GetCachedImageIndex(LPCTSTR pszIconPath, int iIconIndex, UINT uIconFlags)
  49. {
  50. CHAR szPath[MAX_PATH];
  51. if (!UseUnicodeShell32())
  52. {
  53. UnicodeToAnsi(pszIconPath, szPath, ARRAYSIZE(szPath));
  54. pszIconPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  55. }
  56. return Shell_GetCachedImageIndex(pszIconPath, iIconIndex, uIconFlags);
  57. }
  58. // Explicit prototype because only the A/W prototypes exist in the headers
  59. WINSHELLAPI LPITEMIDLIST WINAPI ILCreateFromPath(LPCTSTR pszPath);
  60. LPITEMIDLIST _AorW_ILCreateFromPath(LPCTSTR pszPath)
  61. {
  62. CHAR szPath[MAX_PATH];
  63. THUNKMSG(TEXT("ILCreateFromPath"));
  64. if (!UseUnicodeShell32())
  65. {
  66. UnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  67. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  68. }
  69. return ILCreateFromPath(pszPath);
  70. }
  71. int _AorW_PathCleanupSpec(LPCTSTR pszDir, LPTSTR pszSpec)
  72. {
  73. THUNKMSG(TEXT("PathCleanupSpec"));
  74. if (!UseUnicodeShell32())
  75. {
  76. CHAR szDir[MAX_PATH];
  77. CHAR szSpec[MAX_PATH];
  78. LPSTR pszDir2 = szDir;
  79. int iRet;
  80. if (pszDir) {
  81. UnicodeToAnsi(pszDir, szDir, ARRAYSIZE(szDir));
  82. } else {
  83. pszDir2 = NULL;
  84. }
  85. UnicodeToAnsi(pszSpec, szSpec, ARRAYSIZE(szSpec));
  86. iRet = PathCleanupSpec((LPTSTR)pszDir2, (LPTSTR)szSpec);
  87. AnsiToUnicode(szSpec, pszSpec, MAX_PATH);
  88. return iRet;
  89. }
  90. else
  91. return PathCleanupSpec(pszDir, pszSpec);
  92. }
  93. LONG WINAPI _AorW_PathProcessCommand(LPCTSTR lpSrc, LPTSTR lpDest, int iDestMax, DWORD dwFlags)
  94. {
  95. LONG lReturnValue;
  96. THUNKMSG(TEXT("PathProcessCommand"));
  97. if (!UseUnicodeShell32())
  98. {
  99. CHAR szSrc[MAX_PATH];
  100. CHAR szDest[MAX_PATH];
  101. UnicodeToAnsi(lpSrc, szSrc, ARRAYSIZE(szSrc));
  102. lReturnValue = PathProcessCommand((LPTSTR)szSrc, (LPTSTR)szDest, iDestMax, dwFlags);
  103. AnsiToUnicode(szDest, lpDest, iDestMax);
  104. }
  105. else
  106. lReturnValue = PathProcessCommand(lpSrc, lpDest, iDestMax, dwFlags);
  107. return(lReturnValue);
  108. }
  109. HRESULT _AorW_SHCLSIDFromString(LPCTSTR lpsz, LPCLSID lpclsid)
  110. {
  111. CHAR szPath[MAX_PATH];
  112. THUNKMSG(TEXT("SHCLSIDFromString"));
  113. if (!UseUnicodeShell32())
  114. {
  115. UnicodeToAnsi(lpsz, szPath, ARRAYSIZE(szPath));
  116. lpsz = (LPCTSTR)szPath; // overload the pointer to pass through...
  117. }
  118. return SHCLSIDFromString(lpsz, lpclsid);
  119. }
  120. #ifndef UNIX
  121. // Explicit prototype because only the A/W prototypes exist in the headers
  122. WINSHELLAPI BOOL WINAPI SHGetSpecialFolderPath(HWND hwndOwner, LPTSTR lpszPath, int nFolder, BOOL fCreate);
  123. #else
  124. #ifdef UNICODE
  125. #define SHGetSpecialFolderPath SHGetSpecialFolderPathW
  126. #else
  127. #define SHGetSpecialFolderPath SHGetSpecialFolderPathA
  128. #endif
  129. #endif
  130. BOOL _AorW_SHGetSpecialFolderPath(HWND hwndOwner, LPTSTR pszPath, int nFolder, BOOL fCreate)
  131. {
  132. THUNKMSG(TEXT("SHGetSpecialFolderPath"));
  133. if (!UseUnicodeShell32())
  134. {
  135. CHAR szPath[MAX_PATH];
  136. BOOL fRet = SHGetSpecialFolderPath(hwndOwner, (LPTSTR)szPath, nFolder, fCreate);
  137. if (fRet)
  138. AnsiToUnicode(szPath, pszPath, MAX_PATH);
  139. return fRet;
  140. }
  141. else
  142. return SHGetSpecialFolderPath(hwndOwner, pszPath, nFolder, fCreate);
  143. }
  144. HRESULT _AorW_SHILCreateFromPath(LPCTSTR pszPath, LPITEMIDLIST *ppidl, DWORD *rgfInOut)
  145. {
  146. CHAR szPath[MAX_PATH];
  147. THUNKMSG(TEXT("SHILCreateFromPath"));
  148. if (pszPath)
  149. {
  150. //
  151. // Shell32 will blindly copy pszPath into a MAX_PATH buffer. This
  152. // results in a exploitable buffer overrun. Do not pass more than
  153. // MAX_PATH characters.
  154. //
  155. if (!UseUnicodeShell32())
  156. {
  157. UnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  158. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  159. }
  160. else if (lstrlenW(pszPath) >= MAX_PATH)
  161. {
  162. *ppidl = NULL;
  163. return E_FAIL;
  164. }
  165. }
  166. return SHILCreateFromPath(pszPath, ppidl, rgfInOut);
  167. }
  168. LPITEMIDLIST _AorW_SHSimpleIDListFromPath(LPCTSTR pszPath)
  169. {
  170. CHAR szPath[MAX_PATH];
  171. THUNKMSG(TEXT("SHSimpleIDListFromPath"));
  172. if (!UseUnicodeShell32() && pszPath)
  173. {
  174. UnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  175. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  176. }
  177. return SHSimpleIDListFromPath(pszPath);
  178. }
  179. #define TEMP_SMALL_BUF_SZ 256
  180. BOOL WINAPI _AorW_GetFileNameFromBrowse(HWND hwnd, LPTSTR pszFilePath, UINT cchFilePath,
  181. LPCTSTR pszWorkingDir, LPCTSTR pszDefExt, LPCTSTR pszFilters, LPCTSTR pszTitle)
  182. {
  183. CHAR szPath[MAX_PATH];
  184. CHAR szDir[MAX_PATH];
  185. CHAR szExt[TEMP_SMALL_BUF_SZ];
  186. CHAR szFilters[TEMP_SMALL_BUF_SZ*2];
  187. CHAR szTitle[TEMP_SMALL_BUF_SZ];
  188. LPTSTR pszPath = pszFilePath;
  189. BOOL bResult;
  190. THUNKMSG(TEXT("GetFileNameFromBrowse"));
  191. // thunk strings to ansi
  192. if (!UseUnicodeShell32())
  193. {
  194. // always move szFilePath stuff to wszPath buffer. Should never be a resourceid.
  195. UnicodeToAnsi((LPCTSTR)pszFilePath, szPath, ARRAYSIZE(szPath));
  196. pszPath = (LPTSTR)szPath;
  197. if (!IS_INTRESOURCE(pszWorkingDir)) //not a resource
  198. {
  199. UnicodeToAnsi((LPCTSTR)pszWorkingDir, szDir, ARRAYSIZE(szDir));
  200. pszWorkingDir = (LPCTSTR)szDir;
  201. }
  202. if (!IS_INTRESOURCE(pszDefExt)) //not a resource
  203. {
  204. UnicodeToAnsi((LPCTSTR)pszDefExt, szExt, ARRAYSIZE(szExt));
  205. pszDefExt = (LPCTSTR)szExt;
  206. }
  207. if (!IS_INTRESOURCE(pszFilters)) //not a resource
  208. {
  209. int l=1;
  210. while (*(pszFilters+l) != 0 || *(pszFilters+l-1) != 0)
  211. l++;
  212. WideCharToMultiByte(CP_ACP, 0, (LPCTSTR)pszFilters, l+1, szFilters,
  213. ARRAYSIZE(szFilters), NULL, NULL);
  214. pszFilters = (LPCTSTR)szFilters;
  215. }
  216. if (!IS_INTRESOURCE(pszTitle)) //not a resource
  217. {
  218. UnicodeToAnsi((LPCTSTR)pszTitle, szTitle, ARRAYSIZE(szTitle));
  219. pszTitle = (LPCTSTR)szTitle;
  220. }
  221. }
  222. bResult = GetFileNameFromBrowse(hwnd, pszPath, cchFilePath, pszWorkingDir, pszDefExt, pszFilters, pszTitle);
  223. if (!UseUnicodeShell32())
  224. {
  225. AnsiToUnicode(szPath, pszFilePath, cchFilePath);
  226. }
  227. return (bResult);
  228. }
  229. IStream * _AorW_OpenRegStream(HKEY hkey, LPCTSTR pszSubkey, LPCTSTR pszValue, DWORD grfMode)
  230. {
  231. CHAR szSubkey[MAX_PATH]; // large enough to hold most any name...
  232. CHAR szValue[MAX_PATH]; // dito.
  233. if (!UseUnicodeShell32())
  234. {
  235. UnicodeToAnsi(pszSubkey, szSubkey, ARRAYSIZE(szSubkey));
  236. pszSubkey = (LPCTSTR)szSubkey;
  237. if (pszValue)
  238. {
  239. UnicodeToAnsi(pszValue, szValue, ARRAYSIZE(szValue));
  240. pszValue = (LPCTSTR)szValue;
  241. }
  242. }
  243. return OpenRegStream(hkey, pszSubkey, pszValue, grfMode);
  244. }
  245. BOOL
  246. _AorW_PathYetAnotherMakeUniqueName(LPTSTR pszUniqueName,
  247. LPCTSTR pszPath,
  248. LPCTSTR pszShort,
  249. LPCTSTR pszFileSpec)
  250. {
  251. CHAR szUniqueName[MAX_PATH];
  252. CHAR szPath[MAX_PATH];
  253. CHAR szShort[32];
  254. CHAR szFileSpec[MAX_PATH];
  255. BOOL fRet;
  256. THUNKMSG(TEXT("PathYetAnotherMakeUniqueName"));
  257. if (!UseUnicodeShell32())
  258. {
  259. UnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  260. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  261. if (pszShort)
  262. {
  263. UnicodeToAnsi(pszShort, szShort, ARRAYSIZE(szShort));
  264. pszShort = (LPCTSTR)szShort; // overload the pointer to pass through...
  265. }
  266. if (pszFileSpec)
  267. {
  268. UnicodeToAnsi(pszFileSpec, szFileSpec, ARRAYSIZE(szFileSpec));
  269. pszFileSpec = (LPCTSTR)szFileSpec; // overload the pointer to pass through...
  270. }
  271. fRet = PathYetAnotherMakeUniqueName((LPTSTR)szUniqueName, pszPath, pszShort, pszFileSpec);
  272. if (fRet)
  273. AnsiToUnicode(szUniqueName, pszUniqueName, MAX_PATH);
  274. return fRet;
  275. }
  276. else
  277. return PathYetAnotherMakeUniqueName(pszUniqueName, pszPath, pszShort, pszFileSpec);
  278. }
  279. int _AorW_PickIconDlg(
  280. IN HWND hwnd,
  281. IN OUT LPTSTR pszIconPath,
  282. IN UINT cchIconPath,
  283. IN OUT int * piIconIndex)
  284. {
  285. int nRet;
  286. if (UseUnicodeShell32())
  287. {
  288. nRet = PickIconDlg(hwnd, pszIconPath, cchIconPath, piIconIndex);
  289. }
  290. else
  291. {
  292. CHAR szPath[MAX_PATH];
  293. UINT cch = ARRAYSIZE(szPath);
  294. UnicodeToAnsi(pszIconPath, szPath, cch);
  295. nRet = PickIconDlg(hwnd, (LPTSTR)szPath, cch, piIconIndex);
  296. AnsiToUnicode(szPath, pszIconPath, cchIconPath);
  297. }
  298. return nRet;
  299. }
  300. STDAPI_(int) _AorW_SHCreateDirectory(HWND hwnd, LPCTSTR pszPath)
  301. {
  302. if (UseUnicodeShell32())
  303. {
  304. WCHAR wsz[MAX_PATH];
  305. SHTCharToUnicode(pszPath, wsz, ARRAYSIZE(wsz));
  306. return SHCreateDirectory(hwnd, (LPCTSTR)wsz);
  307. }
  308. else
  309. {
  310. CHAR sz[MAX_PATH];
  311. SHTCharToAnsi(pszPath, sz, ARRAYSIZE(sz));
  312. return SHCreateDirectory(hwnd, (LPCTSTR)sz);
  313. }
  314. }
  315. #endif // _X86_