Source code of Windows XP (NT5)
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.

488 lines
14 KiB

  1. #include "priv.h"
  2. // no wrappers are needed on non-x86 since this is only for win9x interop
  3. #ifdef _X86_
  4. #include <mluisupp.h>
  5. //============================================================================
  6. // This file contains a bunch of Unicode/Ansi thunks to handle calling
  7. // some internal functions that on Windows 95 the strings are Ansi,
  8. // whereas the string on NT are unicode
  9. //============================================================================
  10. // First undefine everything that we are intercepting as to not forward back to us...
  11. #undef ILCreateFromPath
  12. #undef PathCleanupSpec
  13. #undef PathQualify
  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 Win32DeleteFile
  23. #undef PathYetAnotherMakeUniqueName
  24. #undef PathResolve
  25. #undef IsLFNDrive
  26. #undef Shell_GetCachedImageIndex
  27. #undef SHRunControlPanel
  28. #undef PickIconDlg
  29. #undef SHCreateDirectory
  30. #if 0
  31. #define TF_THUNK TF_CUSTOM1
  32. #else
  33. #define TF_THUNK 0
  34. #endif
  35. #define THUNKMSG(psz) TraceMsg(TF_THUNK, "shdv THUNK::%s", psz)
  36. // FEATURE:: need to properly handle not having ILGetdisplaynameex...
  37. typedef BOOL (*PFNILGETDISPLAYNAMEEX)(LPSHELLFOLDER psfRoot, LPCITEMIDLIST pidl, LPTSTR pszName, int fType);
  38. #ifndef ANSI_SHELL32_ON_UNIX
  39. #define UseUnicodeShell32() (g_fRunningOnNT)
  40. #else
  41. #define UseUnicodeShell32() (FALSE)
  42. #endif
  43. //=================================================================================
  44. // Now the thunks...
  45. int _AorW_SHRunControlPanel(LPCTSTR pszOrig_cmdline, HWND errwnd)
  46. {
  47. CHAR szPath[MAX_PATH];
  48. if (!UseUnicodeShell32())
  49. {
  50. UnicodeToAnsi(pszOrig_cmdline, szPath, ARRAYSIZE(szPath));
  51. pszOrig_cmdline = (LPCTSTR)szPath; // overload the pointer to pass through...
  52. }
  53. return SHRunControlPanel(pszOrig_cmdline, errwnd);
  54. }
  55. int _AorW_Shell_GetCachedImageIndex(LPCTSTR pszIconPath, int iIconIndex, UINT uIconFlags)
  56. {
  57. CHAR szPath[MAX_PATH];
  58. if (!UseUnicodeShell32())
  59. {
  60. UnicodeToAnsi(pszIconPath, szPath, ARRAYSIZE(szPath));
  61. pszIconPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  62. }
  63. return Shell_GetCachedImageIndex(pszIconPath, iIconIndex, uIconFlags);
  64. }
  65. // the reverse, do it for wide strings also..
  66. int _WorA_Shell_GetCachedImageIndex(LPCWSTR pszIconPath, int iIconIndex, UINT uIconFlags)
  67. {
  68. CHAR szPath[MAX_PATH];
  69. if (!UseUnicodeShell32())
  70. {
  71. UnicodeToAnsi(pszIconPath, szPath, ARRAYSIZE(szPath));
  72. pszIconPath = (LPCWSTR)szPath; // overload the pointer to pass through...
  73. }
  74. return Shell_GetCachedImageIndex( (LPCTSTR) pszIconPath, iIconIndex, uIconFlags);
  75. }
  76. // Explicit prototype because only the A/W prototypes exist in the headers
  77. WINSHELLAPI LPITEMIDLIST WINAPI ILCreateFromPath(LPCTSTR pszPath);
  78. LPITEMIDLIST _AorW_ILCreateFromPath(LPCTSTR pszPath)
  79. {
  80. CHAR szPath[MAX_PATH];
  81. THUNKMSG(TEXT("ILCreateFromPath"));
  82. if (!UseUnicodeShell32())
  83. {
  84. UnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  85. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  86. }
  87. return ILCreateFromPath(pszPath);
  88. }
  89. int _AorW_PathCleanupSpec(LPCTSTR pszDir, LPTSTR pszSpec)
  90. {
  91. THUNKMSG(TEXT("PathCleanupSpec"));
  92. if (!UseUnicodeShell32())
  93. {
  94. CHAR szDir[MAX_PATH];
  95. CHAR szSpec[MAX_PATH];
  96. LPSTR pszDir2 = szDir;
  97. int iRet;
  98. if (pszDir) {
  99. UnicodeToAnsi(pszDir, szDir, ARRAYSIZE(szDir));
  100. } else {
  101. pszDir2 = NULL;
  102. }
  103. UnicodeToAnsi(pszSpec, szSpec, ARRAYSIZE(szSpec));
  104. iRet = PathCleanupSpec((LPTSTR)pszDir2, (LPTSTR)szSpec);
  105. AnsiToUnicode(szSpec, pszSpec, MAX_PATH);
  106. return iRet;
  107. }
  108. else
  109. return PathCleanupSpec(pszDir, pszSpec);
  110. }
  111. void _AorW_PathQualify(LPTSTR pszDir)
  112. {
  113. THUNKMSG(TEXT("PathQualify"));
  114. if (!UseUnicodeShell32())
  115. {
  116. CHAR szDir[MAX_PATH];
  117. UnicodeToAnsi(pszDir, szDir, ARRAYSIZE(szDir));
  118. PathQualify((LPTSTR)szDir);
  119. AnsiToUnicode(szDir, pszDir, MAX_PATH);
  120. }
  121. else
  122. PathQualify(pszDir);
  123. }
  124. LONG WINAPI _AorW_PathProcessCommand(LPCTSTR lpSrc, LPTSTR lpDest, int iDestMax, DWORD dwFlags)
  125. {
  126. LONG lReturnValue;
  127. THUNKMSG(TEXT("PathProcessCommand"));
  128. if (!UseUnicodeShell32())
  129. {
  130. CHAR szSrc[MAX_PATH];
  131. CHAR szDest[MAX_PATH];
  132. UnicodeToAnsi(lpSrc, szSrc, ARRAYSIZE(szSrc));
  133. lReturnValue = PathProcessCommand((LPTSTR)szSrc, (LPTSTR)szDest, iDestMax, dwFlags);
  134. AnsiToUnicode(szDest, lpDest, iDestMax);
  135. }
  136. else
  137. lReturnValue = PathProcessCommand(lpSrc, lpDest, iDestMax, dwFlags);
  138. return(lReturnValue);
  139. }
  140. HRESULT _AorW_SHCLSIDFromString(LPCTSTR lpsz, LPCLSID lpclsid)
  141. {
  142. CHAR szPath[MAX_PATH];
  143. THUNKMSG(TEXT("SHCLSIDFromString"));
  144. if (!UseUnicodeShell32())
  145. {
  146. UnicodeToAnsi(lpsz, szPath, ARRAYSIZE(szPath));
  147. lpsz = (LPCTSTR)szPath; // overload the pointer to pass through...
  148. }
  149. return SHCLSIDFromString(lpsz, lpclsid);
  150. }
  151. #ifndef UNIX
  152. // Explicit prototype because only the A/W prototypes exist in the headers
  153. WINSHELLAPI BOOL WINAPI SHGetSpecialFolderPath(HWND hwndOwner, LPTSTR lpszPath, int nFolder, BOOL fCreate);
  154. #else
  155. #ifdef UNICODE
  156. #define SHGetSpecialFolderPath SHGetSpecialFolderPathW
  157. #else
  158. #define SHGetSpecialFolderPath SHGetSpecialFolderPathA
  159. #endif
  160. #endif
  161. BOOL _AorW_SHGetSpecialFolderPath(HWND hwndOwner, LPTSTR pszPath, int nFolder, BOOL fCreate)
  162. {
  163. THUNKMSG(TEXT("SHGetSpecialFolderPath"));
  164. if (!UseUnicodeShell32())
  165. {
  166. CHAR szPath[MAX_PATH];
  167. BOOL fRet = SHGetSpecialFolderPath(hwndOwner, (LPTSTR)szPath, nFolder, fCreate);
  168. if (fRet)
  169. AnsiToUnicode(szPath, pszPath, MAX_PATH);
  170. return fRet;
  171. }
  172. else
  173. return SHGetSpecialFolderPath(hwndOwner, pszPath, nFolder, fCreate);
  174. }
  175. HRESULT _AorW_SHILCreateFromPath(LPCTSTR pszPath, LPITEMIDLIST *ppidl, DWORD *rgfInOut)
  176. {
  177. WCHAR wszPath[MAX_PATH];
  178. CHAR szPath[MAX_PATH];
  179. THUNKMSG(TEXT("SHILCreateFromPath"));
  180. if (pszPath)
  181. {
  182. //
  183. // Shell32 will blindly copy pszPath into a MAX_PATH buffer. This
  184. // results in a exploitable buffer overrun. Do not pass more than
  185. // MAX_PATH characters.
  186. //
  187. if (!UseUnicodeShell32())
  188. {
  189. UnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  190. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  191. }
  192. else if (lstrlenW(pszPath) >= MAX_PATH)
  193. {
  194. StrCpyN(wszPath, pszPath, ARRAYSIZE(wszPath));
  195. pszPath = wszPath; // overload the pointer to pass through...
  196. }
  197. }
  198. return SHILCreateFromPath(pszPath, ppidl, rgfInOut);
  199. }
  200. LPITEMIDLIST _AorW_SHSimpleIDListFromPath(LPCTSTR pszPath)
  201. {
  202. CHAR szPath[MAX_PATH];
  203. THUNKMSG(TEXT("SHSimpleIDListFromPath"));
  204. if (!UseUnicodeShell32() && pszPath)
  205. {
  206. UnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  207. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  208. }
  209. return SHSimpleIDListFromPath(pszPath);
  210. }
  211. #define TEMP_SMALL_BUF_SZ 256
  212. BOOL WINAPI _AorW_GetFileNameFromBrowse(HWND hwnd, LPTSTR pszFilePath, UINT cchFilePath,
  213. LPCTSTR pszWorkingDir, LPCTSTR pszDefExt, LPCTSTR pszFilters, LPCTSTR pszTitle)
  214. {
  215. CHAR szPath[MAX_PATH];
  216. CHAR szDir[MAX_PATH];
  217. CHAR szExt[TEMP_SMALL_BUF_SZ];
  218. CHAR szFilters[TEMP_SMALL_BUF_SZ*2];
  219. CHAR szTitle[TEMP_SMALL_BUF_SZ];
  220. LPTSTR pszPath = pszFilePath;
  221. BOOL bResult;
  222. THUNKMSG(TEXT("GetFileNameFromBrowse"));
  223. // thunk strings to ansi
  224. if (!UseUnicodeShell32())
  225. {
  226. // always move szFilePath stuff to wszPath buffer. Should never be a resourceid.
  227. UnicodeToAnsi((LPCTSTR)pszFilePath, szPath, ARRAYSIZE(szPath));
  228. pszPath = (LPTSTR)szPath;
  229. if (!IS_INTRESOURCE(pszWorkingDir)) //not a resource
  230. {
  231. UnicodeToAnsi((LPCTSTR)pszWorkingDir, szDir, ARRAYSIZE(szDir));
  232. pszWorkingDir = (LPCTSTR)szDir;
  233. }
  234. if (!IS_INTRESOURCE(pszDefExt)) //not a resource
  235. {
  236. UnicodeToAnsi((LPCTSTR)pszDefExt, szExt, ARRAYSIZE(szExt));
  237. pszDefExt = (LPCTSTR)szExt;
  238. }
  239. if (!IS_INTRESOURCE(pszFilters)) //not a resource
  240. {
  241. int l=1;
  242. while (*(pszFilters+l) != 0 || *(pszFilters+l-1) != 0)
  243. l++;
  244. WideCharToMultiByte(CP_ACP, 0, (LPCTSTR)pszFilters, l+1, szFilters,
  245. ARRAYSIZE(szFilters), NULL, NULL);
  246. pszFilters = (LPCTSTR)szFilters;
  247. }
  248. if (!IS_INTRESOURCE(pszTitle)) //not a resource
  249. {
  250. UnicodeToAnsi((LPCTSTR)pszTitle, szTitle, ARRAYSIZE(szTitle));
  251. pszTitle = (LPCTSTR)szTitle;
  252. }
  253. }
  254. bResult = GetFileNameFromBrowse(hwnd, pszPath, cchFilePath, pszWorkingDir, pszDefExt, pszFilters, pszTitle);
  255. if (!UseUnicodeShell32())
  256. {
  257. AnsiToUnicode(szPath, pszFilePath, cchFilePath);
  258. }
  259. return (bResult);
  260. }
  261. IStream * _AorW_OpenRegStream(HKEY hkey, LPCTSTR pszSubkey, LPCTSTR pszValue, DWORD grfMode)
  262. {
  263. CHAR szSubkey[MAX_PATH]; // large enough to hold most any name...
  264. CHAR szValue[MAX_PATH]; // dito.
  265. if (!UseUnicodeShell32())
  266. {
  267. UnicodeToAnsi(pszSubkey, szSubkey, ARRAYSIZE(szSubkey));
  268. pszSubkey = (LPCTSTR)szSubkey;
  269. if (pszValue)
  270. {
  271. UnicodeToAnsi(pszValue, szValue, ARRAYSIZE(szValue));
  272. pszValue = (LPCTSTR)szValue;
  273. }
  274. }
  275. return OpenRegStream(hkey, pszSubkey, pszValue, grfMode);
  276. }
  277. BOOL
  278. _AorW_Win32DeleteFile(LPCTSTR lpszFileName)
  279. {
  280. CHAR szPath[MAX_PATH];
  281. THUNKMSG(TEXT("Win32DeleteFile"));
  282. if (!UseUnicodeShell32())
  283. {
  284. UnicodeToAnsi(lpszFileName, szPath, ARRAYSIZE(szPath));
  285. lpszFileName = (LPCTSTR)szPath; // overload the pointer to pass through...
  286. }
  287. return Win32DeleteFile(lpszFileName);
  288. }
  289. BOOL
  290. _AorW_PathYetAnotherMakeUniqueName(LPTSTR pszUniqueName,
  291. LPCTSTR pszPath,
  292. LPCTSTR pszShort,
  293. LPCTSTR pszFileSpec)
  294. {
  295. CHAR szUniqueName[MAX_PATH];
  296. CHAR szPath[MAX_PATH];
  297. CHAR szShort[32];
  298. CHAR szFileSpec[MAX_PATH];
  299. BOOL fRet;
  300. THUNKMSG(TEXT("PathYetAnotherMakeUniqueName"));
  301. if (!UseUnicodeShell32())
  302. {
  303. UnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  304. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  305. if (pszShort)
  306. {
  307. UnicodeToAnsi(pszShort, szShort, ARRAYSIZE(szShort));
  308. pszShort = (LPCTSTR)szShort; // overload the pointer to pass through...
  309. }
  310. if (pszFileSpec)
  311. {
  312. UnicodeToAnsi(pszFileSpec, szFileSpec, ARRAYSIZE(szFileSpec));
  313. pszFileSpec = (LPCTSTR)szFileSpec; // overload the pointer to pass through...
  314. }
  315. fRet = PathYetAnotherMakeUniqueName((LPTSTR)szUniqueName, pszPath, pszShort, pszFileSpec);
  316. if (fRet)
  317. AnsiToUnicode(szUniqueName, pszUniqueName, MAX_PATH);
  318. return fRet;
  319. }
  320. else
  321. return PathYetAnotherMakeUniqueName(pszUniqueName, pszPath, pszShort, pszFileSpec);
  322. }
  323. BOOL
  324. _AorW_PathResolve(LPTSTR lpszPath, LPCTSTR rgpszDirs[], UINT fFlags)
  325. {
  326. CHAR szPath[MAX_PATH];
  327. CHAR szDir[MAX_PATH];
  328. BOOL fRet;
  329. THUNKMSG(TEXT("PathResolve"));
  330. if (!UseUnicodeShell32())
  331. {
  332. // WARNING!!!
  333. // Super Hack, we assume dirs has only one element since it's the only case
  334. // this is called in SHDOCVW.
  335. UnicodeToAnsi(lpszPath, szPath, ARRAYSIZE(szPath));
  336. if (rgpszDirs && rgpszDirs[0])
  337. {
  338. UnicodeToAnsi(rgpszDirs[0], szDir, ARRAYSIZE(szDir));
  339. rgpszDirs[0] = (LPCTSTR)szDir; // overload the pointer to pass through...
  340. if (rgpszDirs[1])
  341. {
  342. AssertMsg(0, TEXT("PathResolve thunk needs to be fixed to handle more than one dirs."));
  343. rgpszDirs[1] = NULL;
  344. }
  345. }
  346. fRet = PathResolve((LPTSTR)szPath, rgpszDirs, fFlags);
  347. if (fRet)
  348. AnsiToUnicode(szPath, lpszPath, MAX_PATH);
  349. return fRet;
  350. }
  351. else
  352. return PathResolve(lpszPath, rgpszDirs, fFlags);
  353. }
  354. // Explicit prototype because only the A/W prototypes exist in the headers
  355. // For UNIX, the old prototype should be defined, because there is no export
  356. // by ordinal there and IsLFNDrive is exported from shell32 just this way.
  357. #ifndef UNIX
  358. BOOL IsLFNDrive(LPCTSTR pszPath);
  359. #else
  360. # ifdef UNICODE
  361. # define IsLFNDrive IsLFNDriveW
  362. # else
  363. # define IsLFNDrive IsLFNDriveA
  364. # endif
  365. #endif
  366. BOOL
  367. _AorW_IsLFNDrive(LPTSTR lpszPath)
  368. {
  369. CHAR szPath[MAX_PATH];
  370. THUNKMSG(TEXT("IsLFNDrive"));
  371. if (!UseUnicodeShell32())
  372. {
  373. UnicodeToAnsi(lpszPath, szPath, ARRAYSIZE(szPath));
  374. return IsLFNDrive((LPCTSTR)szPath);
  375. }
  376. return IsLFNDrive((LPCTSTR)lpszPath);
  377. }
  378. int _AorW_PickIconDlg(
  379. IN HWND hwnd,
  380. IN OUT LPTSTR pszIconPath,
  381. IN UINT cchIconPath,
  382. IN OUT int * piIconIndex)
  383. {
  384. int nRet;
  385. if (UseUnicodeShell32())
  386. {
  387. nRet = PickIconDlg(hwnd, pszIconPath, cchIconPath, piIconIndex);
  388. }
  389. else
  390. {
  391. CHAR szPath[MAX_PATH];
  392. UINT cch = ARRAYSIZE(szPath);
  393. UnicodeToAnsi(pszIconPath, szPath, cch);
  394. nRet = PickIconDlg(hwnd, (LPTSTR)szPath, cch, piIconIndex);
  395. AnsiToUnicode(szPath, pszIconPath, cchIconPath);
  396. }
  397. return nRet;
  398. }
  399. STDAPI_(int) _AorW_SHCreateDirectory(HWND hwnd, LPCTSTR pszPath)
  400. {
  401. if (UseUnicodeShell32())
  402. {
  403. WCHAR wsz[MAX_PATH];
  404. SHTCharToUnicode(pszPath, wsz, ARRAYSIZE(wsz));
  405. return SHCreateDirectory(hwnd, (LPCTSTR)wsz);
  406. }
  407. else
  408. {
  409. CHAR sz[MAX_PATH];
  410. SHTCharToAnsi(pszPath, sz, ARRAYSIZE(sz));
  411. return SHCreateDirectory(hwnd, (LPCTSTR)sz);
  412. }
  413. }
  414. #endif // _X86_