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.

732 lines
21 KiB

  1. #include "priv.h"
  2. // no wrappers are needed on non-x86 since this is only for win9x interop
  3. #ifdef _X86_
  4. //============================================================================
  5. // This file contains a bunch of Unicode/Ansi thunks to handle calling
  6. // some internal functions that on Windows 95 the strings are Ansi,
  7. // whereas the string on NT are unicode
  8. //============================================================================
  9. // First undefine everything that we are intercepting as to not forward back to us...
  10. #undef ILCreateFromPath
  11. #undef PathCleanupSpec
  12. #undef PathQualify
  13. #undef PathProcessCommand
  14. #undef SHCLSIDFromString
  15. #undef SHGetSpecialFolderPath
  16. #undef SHILCreateFromPath
  17. #undef SHSimpleIDListFromPath
  18. #undef GetFileNameFromBrowse
  19. #undef Win32DeleteFile
  20. #undef PathYetAnotherMakeUniqueName
  21. #undef PathResolve
  22. #undef IsLFNDrive
  23. #undef Shell_GetCachedImageIndex
  24. #undef SHRunControlPanel
  25. #undef PickIconDlg
  26. #undef ILCreateFromPathW
  27. #undef SHCreateDirectory
  28. #if 0
  29. #define TF_THUNK TF_CUSTOM1
  30. #else
  31. #define TF_THUNK 0
  32. #endif
  33. #define THUNKMSG(psz) TraceMsg(TF_THUNK, "shdv THUNK::%s", psz)
  34. #ifndef ANSI_SHELL32_ON_UNIX
  35. #ifdef DEBUG
  36. #define UseUnicodeShell32() (g_fRunningOnNT && !(g_dwPrototype & PF_FORCEANSI))
  37. #else
  38. #define UseUnicodeShell32() g_fRunningOnNT
  39. #endif
  40. #else
  41. #define UseUnicodeShell32() (FALSE)
  42. #endif
  43. int _AorW_SHRunControlPanel(LPCTSTR pszOrig_cmdline, HWND errwnd)
  44. {
  45. if (g_fRunningOnNT)
  46. {
  47. WCHAR wzPath[MAX_PATH];
  48. SHTCharToUnicode(pszOrig_cmdline, wzPath, ARRAYSIZE(wzPath));
  49. return SHRunControlPanel((LPCTSTR)wzPath, errwnd);
  50. }
  51. else
  52. {
  53. CHAR szPath[MAX_PATH];
  54. SHTCharToAnsi(pszOrig_cmdline, szPath, ARRAYSIZE(szPath));
  55. return SHRunControlPanel((LPCTSTR)szPath, errwnd);
  56. }
  57. }
  58. int _AorW_Shell_GetCachedImageIndex(LPCTSTR pszIconPath, int iIconIndex, UINT uIconFlags)
  59. {
  60. if (UseUnicodeShell32())
  61. {
  62. WCHAR wzPath[MAX_PATH];
  63. SHTCharToUnicode(pszIconPath, wzPath, ARRAYSIZE(wzPath));
  64. return Shell_GetCachedImageIndex((LPCTSTR)wzPath, iIconIndex, uIconFlags);
  65. }
  66. else
  67. {
  68. CHAR szPath[MAX_PATH];
  69. SHTCharToAnsi(pszIconPath, szPath, ARRAYSIZE(szPath));
  70. return Shell_GetCachedImageIndex((LPCTSTR)szPath, iIconIndex, uIconFlags);
  71. }
  72. }
  73. // the reverse, do it for wide strings also..
  74. int _WorA_Shell_GetCachedImageIndex(LPCWSTR pwzIconPath, int iIconIndex, UINT uIconFlags)
  75. {
  76. CHAR szPath[MAX_PATH];
  77. if (!g_fRunningOnNT)
  78. {
  79. SHUnicodeToAnsi(pwzIconPath, szPath, ARRAYSIZE(szPath));
  80. pwzIconPath = (LPCWSTR)szPath; // overload the pointer to pass through...
  81. }
  82. return Shell_GetCachedImageIndex((LPCTSTR)pwzIconPath, iIconIndex, uIconFlags);
  83. }
  84. // Explicit prototype because only the A/W prototypes exist in the headers
  85. STDAPI_(LPITEMIDLIST) ILCreateFromPath(LPCTSTR pszPath);
  86. LPITEMIDLIST _AorW_ILCreateFromPath(LPCTSTR pszPath)
  87. {
  88. WCHAR wzPath[MAX_PATH];
  89. CHAR szPath[MAX_PATH];
  90. THUNKMSG(TEXT("ILCreateFromPath"));
  91. if (g_fRunningOnNT)
  92. {
  93. SHTCharToUnicode(pszPath, wzPath, ARRAYSIZE(wzPath));
  94. pszPath = (LPCTSTR)wzPath; // overload the pointer to pass through...
  95. }
  96. else
  97. {
  98. SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  99. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  100. }
  101. return ILCreateFromPath(pszPath);
  102. }
  103. int _AorW_PathCleanupSpec(/*IN OPTIONAL*/ LPCTSTR pszDir, /*IN OUT*/ LPTSTR pszSpec)
  104. {
  105. THUNKMSG(TEXT("PathCleanupSpec"));
  106. if (g_fRunningOnNT)
  107. {
  108. WCHAR wzDir[MAX_PATH];
  109. WCHAR wzSpec[MAX_PATH];
  110. LPWSTR pwszDir = wzDir;
  111. int iRet;
  112. if (pszDir)
  113. SHTCharToUnicode(pszDir, wzDir, ARRAYSIZE(wzDir));
  114. else
  115. pwszDir = NULL;
  116. SHTCharToUnicode(pszSpec, wzSpec, ARRAYSIZE(wzSpec));
  117. iRet = PathCleanupSpec((LPTSTR)pwszDir, (LPTSTR)wzSpec);
  118. SHUnicodeToTChar(wzSpec, pszSpec, MAX_PATH);
  119. return iRet;
  120. }
  121. else
  122. {
  123. CHAR szDir[MAX_PATH];
  124. CHAR szSpec[MAX_PATH];
  125. LPSTR pszDir2 = szDir;
  126. int iRet;
  127. if (pszDir)
  128. SHTCharToAnsi(pszDir, szDir, ARRAYSIZE(szDir));
  129. else
  130. pszDir2 = NULL;
  131. SHTCharToAnsi(pszSpec, szSpec, ARRAYSIZE(szSpec));
  132. iRet = PathCleanupSpec((LPTSTR)pszDir2, (LPTSTR)szSpec);
  133. SHAnsiToTChar(szSpec, pszSpec, MAX_PATH);
  134. return iRet;
  135. }
  136. }
  137. void _AorW_PathQualify(/*IN OUT*/ LPTSTR pszDir)
  138. {
  139. THUNKMSG(TEXT("PathQualify"));
  140. if (g_fRunningOnNT)
  141. {
  142. WCHAR wszDir[MAX_PATH];
  143. SHTCharToUnicode(pszDir, wszDir, ARRAYSIZE(wszDir));
  144. PathQualify((LPTSTR)wszDir);
  145. SHUnicodeToTChar(wszDir, pszDir, MAX_PATH);
  146. }
  147. else
  148. {
  149. CHAR szDir[MAX_PATH];
  150. SHTCharToAnsi(pszDir, szDir, ARRAYSIZE(szDir));
  151. PathQualify((LPTSTR)szDir);
  152. SHAnsiToTChar(szDir, pszDir, MAX_PATH);
  153. }
  154. }
  155. LONG WINAPI _AorW_PathProcessCommand(/*IN*/ LPCTSTR pszSrc, /*OUT*/LPTSTR pszDest, int iDestMax, DWORD dwFlags)
  156. {
  157. LONG lReturnValue;
  158. THUNKMSG(TEXT("PathProcessCommand"));
  159. if (g_fRunningOnNT)
  160. {
  161. WCHAR wszSrc[MAX_PATH];
  162. WCHAR wszDest[MAX_PATH];
  163. SHTCharToUnicode(pszSrc, wszSrc, ARRAYSIZE(wszSrc));
  164. lReturnValue = PathProcessCommand((LPTSTR)wszSrc, (LPTSTR)wszDest, ARRAYSIZE(wszDest), dwFlags);
  165. SHUnicodeToTChar(wszDest, pszDest, iDestMax);
  166. }
  167. else
  168. {
  169. CHAR szSrc[MAX_PATH];
  170. CHAR szDest[MAX_PATH];
  171. SHTCharToAnsi(pszSrc, szSrc, ARRAYSIZE(szSrc));
  172. lReturnValue = PathProcessCommand((LPTSTR)szSrc, (LPTSTR)szDest, ARRAYSIZE(szDest), dwFlags);
  173. SHAnsiToTChar(szDest, pszDest, iDestMax);
  174. }
  175. return(lReturnValue);
  176. }
  177. // Explicit prototype because only the A/W prototypes exist in the headers
  178. STDAPI_(BOOL) SHGetSpecialFolderPath(HWND hwndOwner, LPTSTR lpszPath, int nFolder, BOOL fCreate);
  179. BOOL _AorW_SHGetSpecialFolderPath(HWND hwndOwner, /*OUT*/ LPTSTR pszPath, int nFolder, BOOL fCreate)
  180. {
  181. THUNKMSG(TEXT("SHGetSpecialFolderPath"));
  182. if (g_fRunningOnNT)
  183. {
  184. WCHAR wzPath[MAX_PATH];
  185. BOOL fRet = SHGetSpecialFolderPath(hwndOwner, (LPTSTR)wzPath, nFolder, fCreate);
  186. if (fRet)
  187. SHUnicodeToTChar(wzPath, pszPath, MAX_PATH);
  188. return fRet;
  189. }
  190. else
  191. {
  192. CHAR szPath[MAX_PATH];
  193. BOOL fRet = SHGetSpecialFolderPath(hwndOwner, (LPTSTR)szPath, nFolder, fCreate);
  194. if (fRet)
  195. SHAnsiToTChar(szPath, pszPath, MAX_PATH);
  196. return fRet;
  197. }
  198. }
  199. HRESULT _AorW_SHILCreateFromPath(/*IN OPTIONAL*/LPCTSTR pszPath, LPITEMIDLIST *ppidl, DWORD *rgfInOut)
  200. {
  201. WCHAR wzPath[MAX_PATH];
  202. CHAR szPath[MAX_PATH];
  203. THUNKMSG(TEXT("SHILCreateFromPath"));
  204. if (pszPath)
  205. {
  206. if (g_fRunningOnNT)
  207. {
  208. SHTCharToUnicode(pszPath, wzPath, ARRAYSIZE(wzPath));
  209. pszPath = (LPCTSTR)wzPath; // overload the pointer to pass through...
  210. }
  211. else
  212. {
  213. SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  214. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  215. }
  216. }
  217. return SHILCreateFromPath(pszPath, ppidl, rgfInOut);
  218. }
  219. LPITEMIDLIST _AorW_SHSimpleIDListFromPath(/*IN OPTIONAL*/ LPCTSTR pszPath)
  220. {
  221. WCHAR wzPath[MAX_PATH];
  222. CHAR szPath[MAX_PATH];
  223. THUNKMSG(TEXT("SHSimpleIDListFromPath"));
  224. if (pszPath)
  225. {
  226. if (g_fRunningOnNT)
  227. {
  228. SHTCharToUnicode(pszPath, wzPath, ARRAYSIZE(wzPath));
  229. pszPath = (LPCTSTR)wzPath; // overload the pointer to pass through...
  230. }
  231. else
  232. {
  233. SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  234. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  235. }
  236. }
  237. return SHSimpleIDListFromPath(pszPath);
  238. }
  239. #define ISNOT_RESOURCE(pItem) ((pItem) && HIWORD((pItem)) && LOWORD((pItem)))
  240. int FindDoubleTerminator(LPCTSTR pszStr)
  241. {
  242. int nIndex = 1;
  243. // Find the double terminator
  244. while (pszStr[nIndex] || pszStr[nIndex-1])
  245. nIndex++;
  246. return nIndex;
  247. }
  248. #define TEMP_SMALL_BUF_SZ 256
  249. BOOL WINAPI _AorW_GetFileNameFromBrowse(HWND hwnd, /*IN OUT*/ LPTSTR pszFilePath, UINT cchFilePath,
  250. /*IN OPTIONAL*/ LPCTSTR pszWorkingDir, /*IN OPTIONAL*/ LPCTSTR pszDefExt,
  251. /*IN OPTIONAL*/ LPCTSTR pszFilters, /*IN OPTIONAL*/ LPCTSTR pszTitle)
  252. {
  253. WCHAR wszPath[MAX_PATH];
  254. WCHAR wszDir[MAX_PATH];
  255. WCHAR wszExt[TEMP_SMALL_BUF_SZ];
  256. WCHAR wszTitle[TEMP_SMALL_BUF_SZ];
  257. #ifndef UNICODE
  258. WCHAR wszFilters[TEMP_SMALL_BUF_SZ*2];
  259. #else // UNICODE
  260. CHAR szFilters[TEMP_SMALL_BUF_SZ*2];
  261. #endif // UNICODE
  262. CHAR szPath[MAX_PATH];
  263. CHAR szDir[MAX_PATH];
  264. CHAR szExt[TEMP_SMALL_BUF_SZ];
  265. CHAR szTitle[TEMP_SMALL_BUF_SZ];
  266. BOOL bResult;
  267. THUNKMSG(TEXT("GetFileNameFromBrowse"));
  268. // thunk strings to unicode
  269. if (g_fRunningOnNT)
  270. {
  271. // always move pszFilePath stuff to wszPath buffer. Should never be a resourceid.
  272. SHTCharToUnicode(pszFilePath, wszPath, ARRAYSIZE(wszPath));
  273. pszFilePath = (LPTSTR)wszPath;
  274. if (ISNOT_RESOURCE(pszWorkingDir)) //not a resource
  275. {
  276. SHTCharToUnicode(pszWorkingDir, wszDir, ARRAYSIZE(wszDir));
  277. pszWorkingDir = (LPCTSTR)wszDir;
  278. }
  279. if (ISNOT_RESOURCE(pszDefExt)) //not a resource
  280. {
  281. SHTCharToUnicode(pszDefExt, wszExt, ARRAYSIZE(wszExt));
  282. pszDefExt = (LPCTSTR)wszExt;
  283. }
  284. if (ISNOT_RESOURCE(pszFilters)) //not a resource
  285. {
  286. #ifndef UNICODE
  287. int nIndex = FindDoubleTerminator(pszFilters);
  288. // nIndex+1 looks like bunk unless it goes past the terminator
  289. MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)pszFilters, nIndex+1, wszFilters, ARRAYSIZE(wszFilters));
  290. pszFilters = (LPCTSTR)wszFilters;
  291. #endif // UNICODE
  292. }
  293. if (ISNOT_RESOURCE(pszTitle)) //not a resource
  294. {
  295. SHTCharToUnicode(pszTitle, wszTitle, ARRAYSIZE(wszTitle));
  296. pszTitle = (LPCTSTR)wszTitle;
  297. }
  298. }
  299. else
  300. {
  301. // always move pszFilePath stuff to wszPath buffer. Should never be a resourceid.
  302. SHTCharToAnsi(pszFilePath, szPath, ARRAYSIZE(szPath));
  303. pszFilePath = (LPTSTR)szPath;
  304. if (ISNOT_RESOURCE(pszWorkingDir)) //not a resource
  305. {
  306. SHTCharToAnsi(pszWorkingDir, szDir, ARRAYSIZE(szDir));
  307. pszWorkingDir = (LPCTSTR)szDir;
  308. }
  309. if (ISNOT_RESOURCE(pszDefExt)) //not a resource
  310. {
  311. SHTCharToAnsi(pszDefExt, szExt, ARRAYSIZE(szExt));
  312. pszDefExt = (LPCTSTR)szExt;
  313. }
  314. if (ISNOT_RESOURCE(pszFilters)) //not a resource
  315. {
  316. #ifdef UNICODE
  317. int nIndex = FindDoubleTerminator(pszFilters);
  318. // nIndex+1 looks like bunk unless it goes past the terminator
  319. WideCharToMultiByte(CP_ACP, 0, (LPCTSTR)pszFilters, nIndex+1, szFilters, ARRAYSIZE(szFilters), NULL, NULL);
  320. pszFilters = (LPCTSTR)szFilters;
  321. #endif // UNICODE
  322. }
  323. if (ISNOT_RESOURCE(pszTitle)) //not a resource
  324. {
  325. SHTCharToAnsi(pszTitle, szTitle, ARRAYSIZE(szTitle));
  326. pszTitle = (LPCTSTR)szTitle;
  327. }
  328. }
  329. bResult = GetFileNameFromBrowse(hwnd, pszFilePath, cchFilePath, pszWorkingDir, pszDefExt, pszFilters, pszTitle);
  330. // thunk string back to multibyte
  331. if (g_fRunningOnNT)
  332. SHUnicodeToTChar(wszPath, pszFilePath, cchFilePath);
  333. else
  334. SHAnsiToTChar(szPath, pszFilePath, cchFilePath);
  335. return bResult;
  336. }
  337. BOOL _AorW_Win32DeleteFile(/*IN*/ LPCTSTR pszFileName)
  338. {
  339. WCHAR wzPath[MAX_PATH];
  340. CHAR szPath[MAX_PATH];
  341. THUNKMSG(TEXT("Win32DeleteFile"));
  342. if (g_fRunningOnNT)
  343. {
  344. SHTCharToUnicode(pszFileName, wzPath, ARRAYSIZE(wzPath));
  345. pszFileName = (LPCTSTR)wzPath; // overload the pointer to pass through...
  346. }
  347. else
  348. {
  349. SHTCharToAnsi(pszFileName, szPath, ARRAYSIZE(szPath));
  350. pszFileName = (LPCTSTR)szPath; // overload the pointer to pass through...
  351. }
  352. return Win32DeleteFile(pszFileName);
  353. }
  354. BOOL _AorW_PathYetAnotherMakeUniqueName(LPTSTR pszUniqueName,
  355. LPCTSTR pszPath,
  356. LPCTSTR pszShort,
  357. LPCTSTR pszFileSpec)
  358. {
  359. THUNKMSG(TEXT("PathYetAnotherMakeUniqueName"));
  360. if (UseUnicodeShell32())
  361. {
  362. WCHAR wszUniqueName[MAX_PATH];
  363. WCHAR wszPath[MAX_PATH];
  364. WCHAR wszShort[32];
  365. WCHAR wszFileSpec[MAX_PATH];
  366. BOOL fRet;
  367. SHTCharToUnicode(pszPath, wszPath, ARRAYSIZE(wszPath));
  368. pszPath = (LPCTSTR)wszPath; // overload the pointer to pass through...
  369. if (pszShort)
  370. {
  371. SHTCharToUnicode(pszShort, wszShort, ARRAYSIZE(wszShort));
  372. pszShort = (LPCTSTR)wszShort; // overload the pointer to pass through...
  373. }
  374. if (pszFileSpec)
  375. {
  376. SHTCharToUnicode(pszFileSpec, wszFileSpec, ARRAYSIZE(wszFileSpec));
  377. pszFileSpec = (LPCTSTR)wszFileSpec; // overload the pointer to pass through...
  378. }
  379. fRet = PathYetAnotherMakeUniqueName((LPTSTR)wszUniqueName, pszPath, pszShort, pszFileSpec);
  380. if (fRet)
  381. SHUnicodeToTChar(wszUniqueName, pszUniqueName, MAX_PATH);
  382. return fRet;
  383. }
  384. else
  385. {
  386. CHAR szUniqueName[MAX_PATH];
  387. CHAR szPath[MAX_PATH];
  388. CHAR szShort[32];
  389. CHAR szFileSpec[MAX_PATH];
  390. BOOL fRet;
  391. SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  392. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  393. if (pszShort)
  394. {
  395. SHTCharToAnsi(pszShort, szShort, ARRAYSIZE(szShort));
  396. pszShort = (LPCTSTR)szShort; // overload the pointer to pass through...
  397. }
  398. if (pszFileSpec)
  399. {
  400. SHTCharToAnsi(pszFileSpec, szFileSpec, ARRAYSIZE(szFileSpec));
  401. pszFileSpec = (LPCTSTR)szFileSpec; // overload the pointer to pass through...
  402. }
  403. fRet = PathYetAnotherMakeUniqueName((LPTSTR)szUniqueName, pszPath, pszShort, pszFileSpec);
  404. if (fRet)
  405. SHAnsiToTChar(szUniqueName, pszUniqueName, MAX_PATH);
  406. return fRet;
  407. }
  408. }
  409. BOOL _AorW_PathResolve(/*IN OUT*/ LPTSTR pszPath, /*IN OPTIONAL*/ LPCTSTR rgpszDirs[], UINT fFlags)
  410. {
  411. THUNKMSG(TEXT("PathResolve"));
  412. if (g_fRunningOnNT)
  413. {
  414. WCHAR wzPath[MAX_PATH];
  415. WCHAR wzDir[MAX_PATH];
  416. BOOL fRet;
  417. SHTCharToUnicode(pszPath, wzPath, ARRAYSIZE(wzPath));
  418. if (rgpszDirs && rgpszDirs[0])
  419. {
  420. SHTCharToUnicode(rgpszDirs[0], wzDir, ARRAYSIZE(wzDir));
  421. rgpszDirs[0] = (LPCTSTR)wzDir; // overload the pointer to pass through...
  422. if (rgpszDirs[1])
  423. {
  424. // Super Hack, we assume dirs has only one element since it's the only case
  425. // this is called in SHDOCVW.
  426. AssertMsg(0, TEXT("PathResolve thunk needs to be fixed to handle more than one dirs."));
  427. rgpszDirs[1] = NULL;
  428. }
  429. }
  430. fRet = PathResolve((LPTSTR)wzPath, rgpszDirs, fFlags);
  431. if (fRet)
  432. SHUnicodeToTChar(wzPath, pszPath, MAX_PATH);
  433. return fRet;
  434. }
  435. else
  436. {
  437. CHAR szPath[MAX_PATH];
  438. CHAR szDir[MAX_PATH];
  439. BOOL fRet;
  440. SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  441. if (rgpszDirs && rgpszDirs[0])
  442. {
  443. SHTCharToAnsi(rgpszDirs[0], szDir, ARRAYSIZE(szDir));
  444. rgpszDirs[0] = (LPCTSTR)szDir; // overload the pointer to pass through...
  445. if (rgpszDirs[1])
  446. {
  447. // Super Hack, we assume dirs has only one element since it's the only case
  448. // this is called in SHDOCVW.
  449. AssertMsg(0, TEXT("PathResolve thunk needs to be fixed to handle more than one dirs."));
  450. rgpszDirs[1] = NULL;
  451. }
  452. }
  453. fRet = PathResolve((LPTSTR)szPath, rgpszDirs, fFlags);
  454. if (fRet)
  455. SHAnsiToTChar(szPath, pszPath, MAX_PATH);
  456. return fRet;
  457. }
  458. }
  459. // Explicit prototype because only the A/W prototypes exist in the headers
  460. BOOL IsLFNDrive(LPCTSTR pszPath);
  461. BOOL _AorW_IsLFNDrive(/*IN*/ LPTSTR pszPath)
  462. {
  463. THUNKMSG(TEXT("IsLFNDrive"));
  464. if (g_fRunningOnNT)
  465. {
  466. WCHAR wszPath[MAX_PATH];
  467. SHTCharToUnicode(pszPath, wszPath, ARRAYSIZE(wszPath));
  468. return IsLFNDrive((LPTSTR)wszPath);
  469. }
  470. else
  471. {
  472. CHAR szPath[MAX_PATH];
  473. SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  474. return IsLFNDrive((LPTSTR)szPath);
  475. }
  476. }
  477. int _AorW_PickIconDlg(
  478. IN HWND hwnd,
  479. IN OUT LPTSTR pszIconPath,
  480. IN UINT cchIconPath,
  481. IN OUT int * piIconIndex)
  482. {
  483. int nRet;
  484. WCHAR wszPath[MAX_PATH];
  485. CHAR szPath[MAX_PATH];
  486. LPTSTR psz = pszIconPath;
  487. UINT cch = cchIconPath;
  488. if (g_fRunningOnNT)
  489. {
  490. SHTCharToUnicode(pszIconPath, wszPath, ARRAYSIZE(wszPath));
  491. psz = (LPTSTR)wszPath; // overload the pointer to pass through...
  492. cch = SIZECHARS(wszPath);
  493. }
  494. else
  495. {
  496. SHTCharToAnsi(pszIconPath, szPath, ARRAYSIZE(wszPath));
  497. psz = (LPTSTR)szPath; // overload the pointer to pass through...
  498. cch = SIZECHARS(szPath);
  499. }
  500. nRet = PickIconDlg(hwnd, psz, cch, piIconIndex);
  501. if (g_fRunningOnNT)
  502. SHUnicodeToTChar(wszPath, pszIconPath, cchIconPath);
  503. else
  504. SHAnsiToTChar(szPath, pszIconPath, cchIconPath);
  505. return nRet;
  506. }
  507. //
  508. // Now the thunks that allow us to run on Windows 95.
  509. //
  510. //
  511. //
  512. // This thunks a unicode string to ANSI, but if it's an ordinal, then
  513. // we just leave it alone.
  514. //
  515. LPSTR Thunk_UnicodeToAnsiOrOrdinal(LPCWSTR pwsz, LPSTR pszBuf, UINT cchBuf)
  516. {
  517. if (HIWORD64(pwsz)) {
  518. SHUnicodeToAnsi(pwsz, pszBuf, cchBuf);
  519. return pszBuf;
  520. } else {
  521. return (LPSTR)pwsz;
  522. }
  523. }
  524. #define THUNKSTRING(pwsz, sz) Thunk_UnicodeToAnsiOrOrdinal(pwsz, sz, ARRAYSIZE(sz))
  525. //
  526. // This function is new for IE4, so on IE3,
  527. // we emulate (poorly) with ExtractIcon.
  528. //
  529. //
  530. // Win95 exported ILCreateFromPathA under the name ILCreateFromPath.
  531. // Fortunately, NT kept the same ordinal.
  532. //
  533. //
  534. // If linking with Win95 header files, then call it ILCreateFromPath.
  535. //
  536. #ifdef UNICODE
  537. STDAPI_(LPITEMIDLIST) _ILCreateFromPathA(LPCSTR pszPath)
  538. {
  539. if (g_fRunningOnNT) {
  540. WCHAR wszPath[MAX_PATH];
  541. SHAnsiToUnicode(pszPath, wszPath, ARRAYSIZE(wszPath));
  542. return ILCreateFromPath((LPVOID)wszPath);
  543. } else {
  544. return ILCreateFromPath((LPVOID)pszPath);
  545. }
  546. }
  547. #else
  548. STDAPI_(LPITEMIDLIST) _ILCreateFromPathW(LPCWSTR pszPath)
  549. {
  550. if (g_fRunningOnNT) {
  551. return ILCreateFromPath((LPVOID)pszPath);
  552. } else {
  553. CHAR szPath[MAX_PATH];
  554. SHUnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  555. return ILCreateFromPath((LPVOID)szPath);
  556. }
  557. }
  558. #endif
  559. STDAPI_(int) _AorW_SHCreateDirectory(HWND hwnd, LPCTSTR pszPath)
  560. {
  561. if (g_fRunningOnNT)
  562. {
  563. WCHAR wsz[MAX_PATH];
  564. SHTCharToUnicode(pszPath, wsz, ARRAYSIZE(wsz));
  565. return SHCreateDirectory(hwnd, (LPCTSTR)wsz);
  566. }
  567. else
  568. {
  569. CHAR sz[MAX_PATH];
  570. SHTCharToAnsi(pszPath, sz, ARRAYSIZE(sz));
  571. return SHCreateDirectory(hwnd, (LPCTSTR)sz);
  572. }
  573. }
  574. #ifdef UNICODE
  575. //
  576. // Either ptsz1 or ptsz2 can be NULL, so be careful when thunking.
  577. //
  578. STDAPI_(int) _AorW_ShellAbout(HWND hWnd, LPCTSTR ptsz1, LPCTSTR ptsz2, HICON hIcon)
  579. {
  580. if (g_fRunningOnNT)
  581. {
  582. return ShellAboutW(hWnd, ptsz1, ptsz2, hIcon);
  583. }
  584. else
  585. {
  586. CHAR sz1[MAX_PATH], sz2[MAX_PATH];
  587. LPSTR psz1, psz2;
  588. if (ptsz1) {
  589. psz1 = sz1;
  590. SHTCharToAnsi(ptsz1, sz1, ARRAYSIZE(sz1));
  591. } else {
  592. psz1 = NULL;
  593. }
  594. if (ptsz2) {
  595. psz2 = sz2;
  596. SHTCharToAnsi(ptsz2, sz2, ARRAYSIZE(sz2));
  597. } else {
  598. psz2 = NULL;
  599. }
  600. return ShellAboutA(hWnd, psz1, psz2, hIcon);
  601. }
  602. }
  603. #endif
  604. #endif // _X86_