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.

755 lines
20 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. #ifndef UNIX
  178. // Explicit prototype because only the A/W prototypes exist in the headers
  179. STDAPI_(BOOL) SHGetSpecialFolderPath(HWND hwndOwner, LPTSTR lpszPath, int nFolder, BOOL fCreate);
  180. #else
  181. #ifdef UNICODE
  182. #define SHGetSpecialFolderPath SHGetSpecialFolderPathW
  183. #else
  184. #define SHGetSpecialFolderPath SHGetSpecialFolderPathA
  185. #endif
  186. #endif
  187. BOOL _AorW_SHGetSpecialFolderPath(HWND hwndOwner, /*OUT*/ LPTSTR pszPath, int nFolder, BOOL fCreate)
  188. {
  189. THUNKMSG(TEXT("SHGetSpecialFolderPath"));
  190. if (g_fRunningOnNT)
  191. {
  192. WCHAR wzPath[MAX_PATH];
  193. BOOL fRet = SHGetSpecialFolderPath(hwndOwner, (LPTSTR)wzPath, nFolder, fCreate);
  194. if (fRet)
  195. SHUnicodeToTChar(wzPath, pszPath, MAX_PATH);
  196. return fRet;
  197. }
  198. else
  199. {
  200. CHAR szPath[MAX_PATH];
  201. BOOL fRet = SHGetSpecialFolderPath(hwndOwner, (LPTSTR)szPath, nFolder, fCreate);
  202. if (fRet)
  203. SHAnsiToTChar(szPath, pszPath, MAX_PATH);
  204. return fRet;
  205. }
  206. }
  207. HRESULT _AorW_SHILCreateFromPath(/*IN OPTIONAL*/LPCTSTR pszPath, LPITEMIDLIST *ppidl, DWORD *rgfInOut)
  208. {
  209. WCHAR wzPath[MAX_PATH];
  210. CHAR szPath[MAX_PATH];
  211. THUNKMSG(TEXT("SHILCreateFromPath"));
  212. if (pszPath)
  213. {
  214. if (g_fRunningOnNT)
  215. {
  216. SHTCharToUnicode(pszPath, wzPath, ARRAYSIZE(wzPath));
  217. pszPath = (LPCTSTR)wzPath; // overload the pointer to pass through...
  218. }
  219. else
  220. {
  221. SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  222. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  223. }
  224. }
  225. return SHILCreateFromPath(pszPath, ppidl, rgfInOut);
  226. }
  227. LPITEMIDLIST _AorW_SHSimpleIDListFromPath(/*IN OPTIONAL*/ LPCTSTR pszPath)
  228. {
  229. WCHAR wzPath[MAX_PATH];
  230. CHAR szPath[MAX_PATH];
  231. THUNKMSG(TEXT("SHSimpleIDListFromPath"));
  232. if (pszPath)
  233. {
  234. if (g_fRunningOnNT)
  235. {
  236. SHTCharToUnicode(pszPath, wzPath, ARRAYSIZE(wzPath));
  237. pszPath = (LPCTSTR)wzPath; // overload the pointer to pass through...
  238. }
  239. else
  240. {
  241. SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  242. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  243. }
  244. }
  245. return SHSimpleIDListFromPath(pszPath);
  246. }
  247. #define ISNOT_RESOURCE(pItem) ((pItem) && HIWORD((pItem)) && LOWORD((pItem)))
  248. int FindDoubleTerminator(LPCTSTR pszStr)
  249. {
  250. int nIndex = 1;
  251. // Find the double terminator
  252. while (pszStr[nIndex] || pszStr[nIndex-1])
  253. nIndex++;
  254. return nIndex;
  255. }
  256. #define TEMP_SMALL_BUF_SZ 256
  257. BOOL WINAPI _AorW_GetFileNameFromBrowse(HWND hwnd, /*IN OUT*/ LPTSTR pszFilePath, UINT cchFilePath,
  258. /*IN OPTIONAL*/ LPCTSTR pszWorkingDir, /*IN OPTIONAL*/ LPCTSTR pszDefExt,
  259. /*IN OPTIONAL*/ LPCTSTR pszFilters, /*IN OPTIONAL*/ LPCTSTR pszTitle)
  260. {
  261. WCHAR wszPath[MAX_PATH];
  262. WCHAR wszDir[MAX_PATH];
  263. WCHAR wszExt[TEMP_SMALL_BUF_SZ];
  264. WCHAR wszTitle[TEMP_SMALL_BUF_SZ];
  265. #ifndef UNICODE
  266. WCHAR wszFilters[TEMP_SMALL_BUF_SZ*2];
  267. #else // UNICODE
  268. CHAR szFilters[TEMP_SMALL_BUF_SZ*2];
  269. #endif // UNICODE
  270. CHAR szPath[MAX_PATH];
  271. CHAR szDir[MAX_PATH];
  272. CHAR szExt[TEMP_SMALL_BUF_SZ];
  273. CHAR szTitle[TEMP_SMALL_BUF_SZ];
  274. BOOL bResult;
  275. THUNKMSG(TEXT("GetFileNameFromBrowse"));
  276. // thunk strings to unicode
  277. if (g_fRunningOnNT)
  278. {
  279. // always move pszFilePath stuff to wszPath buffer. Should never be a resourceid.
  280. SHTCharToUnicode(pszFilePath, wszPath, ARRAYSIZE(wszPath));
  281. pszFilePath = (LPTSTR)wszPath;
  282. if (ISNOT_RESOURCE(pszWorkingDir)) //not a resource
  283. {
  284. SHTCharToUnicode(pszWorkingDir, wszDir, ARRAYSIZE(wszDir));
  285. pszWorkingDir = (LPCTSTR)wszDir;
  286. }
  287. if (ISNOT_RESOURCE(pszDefExt)) //not a resource
  288. {
  289. SHTCharToUnicode(pszDefExt, wszExt, ARRAYSIZE(wszExt));
  290. pszDefExt = (LPCTSTR)wszExt;
  291. }
  292. if (ISNOT_RESOURCE(pszFilters)) //not a resource
  293. {
  294. #ifndef UNICODE
  295. int nIndex = FindDoubleTerminator(pszFilters);
  296. // nIndex+1 looks like bunk unless it goes past the terminator
  297. MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)pszFilters, nIndex+1, wszFilters, ARRAYSIZE(wszFilters));
  298. pszFilters = (LPCTSTR)wszFilters;
  299. #endif // UNICODE
  300. }
  301. if (ISNOT_RESOURCE(pszTitle)) //not a resource
  302. {
  303. SHTCharToUnicode(pszTitle, wszTitle, ARRAYSIZE(wszTitle));
  304. pszTitle = (LPCTSTR)wszTitle;
  305. }
  306. }
  307. else
  308. {
  309. // always move pszFilePath stuff to wszPath buffer. Should never be a resourceid.
  310. SHTCharToAnsi(pszFilePath, szPath, ARRAYSIZE(szPath));
  311. pszFilePath = (LPTSTR)szPath;
  312. if (ISNOT_RESOURCE(pszWorkingDir)) //not a resource
  313. {
  314. SHTCharToAnsi(pszWorkingDir, szDir, ARRAYSIZE(szDir));
  315. pszWorkingDir = (LPCTSTR)szDir;
  316. }
  317. if (ISNOT_RESOURCE(pszDefExt)) //not a resource
  318. {
  319. SHTCharToAnsi(pszDefExt, szExt, ARRAYSIZE(szExt));
  320. pszDefExt = (LPCTSTR)szExt;
  321. }
  322. if (ISNOT_RESOURCE(pszFilters)) //not a resource
  323. {
  324. #ifdef UNICODE
  325. int nIndex = FindDoubleTerminator(pszFilters);
  326. // nIndex+1 looks like bunk unless it goes past the terminator
  327. WideCharToMultiByte(CP_ACP, 0, (LPCTSTR)pszFilters, nIndex+1, szFilters, ARRAYSIZE(szFilters), NULL, NULL);
  328. pszFilters = (LPCTSTR)szFilters;
  329. #endif // UNICODE
  330. }
  331. if (ISNOT_RESOURCE(pszTitle)) //not a resource
  332. {
  333. SHTCharToAnsi(pszTitle, szTitle, ARRAYSIZE(szTitle));
  334. pszTitle = (LPCTSTR)szTitle;
  335. }
  336. }
  337. bResult = GetFileNameFromBrowse(hwnd, pszFilePath, cchFilePath, pszWorkingDir, pszDefExt, pszFilters, pszTitle);
  338. // thunk string back to multibyte
  339. if (g_fRunningOnNT)
  340. SHUnicodeToTChar(wszPath, pszFilePath, cchFilePath);
  341. else
  342. SHAnsiToTChar(szPath, pszFilePath, cchFilePath);
  343. return bResult;
  344. }
  345. BOOL _AorW_Win32DeleteFile(/*IN*/ LPCTSTR pszFileName)
  346. {
  347. WCHAR wzPath[MAX_PATH];
  348. CHAR szPath[MAX_PATH];
  349. THUNKMSG(TEXT("Win32DeleteFile"));
  350. if (g_fRunningOnNT)
  351. {
  352. SHTCharToUnicode(pszFileName, wzPath, ARRAYSIZE(wzPath));
  353. pszFileName = (LPCTSTR)wzPath; // overload the pointer to pass through...
  354. }
  355. else
  356. {
  357. SHTCharToAnsi(pszFileName, szPath, ARRAYSIZE(szPath));
  358. pszFileName = (LPCTSTR)szPath; // overload the pointer to pass through...
  359. }
  360. return Win32DeleteFile(pszFileName);
  361. }
  362. BOOL _AorW_PathYetAnotherMakeUniqueName(LPTSTR pszUniqueName,
  363. LPCTSTR pszPath,
  364. LPCTSTR pszShort,
  365. LPCTSTR pszFileSpec)
  366. {
  367. THUNKMSG(TEXT("PathYetAnotherMakeUniqueName"));
  368. if (UseUnicodeShell32())
  369. {
  370. WCHAR wszUniqueName[MAX_PATH];
  371. WCHAR wszPath[MAX_PATH];
  372. WCHAR wszShort[32];
  373. WCHAR wszFileSpec[MAX_PATH];
  374. BOOL fRet;
  375. SHTCharToUnicode(pszPath, wszPath, ARRAYSIZE(wszPath));
  376. pszPath = (LPCTSTR)wszPath; // overload the pointer to pass through...
  377. if (pszShort)
  378. {
  379. SHTCharToUnicode(pszShort, wszShort, ARRAYSIZE(wszShort));
  380. pszShort = (LPCTSTR)wszShort; // overload the pointer to pass through...
  381. }
  382. if (pszFileSpec)
  383. {
  384. SHTCharToUnicode(pszFileSpec, wszFileSpec, ARRAYSIZE(wszFileSpec));
  385. pszFileSpec = (LPCTSTR)wszFileSpec; // overload the pointer to pass through...
  386. }
  387. fRet = PathYetAnotherMakeUniqueName((LPTSTR)wszUniqueName, pszPath, pszShort, pszFileSpec);
  388. if (fRet)
  389. SHUnicodeToTChar(wszUniqueName, pszUniqueName, MAX_PATH);
  390. return fRet;
  391. }
  392. else
  393. {
  394. CHAR szUniqueName[MAX_PATH];
  395. CHAR szPath[MAX_PATH];
  396. CHAR szShort[32];
  397. CHAR szFileSpec[MAX_PATH];
  398. BOOL fRet;
  399. SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  400. pszPath = (LPCTSTR)szPath; // overload the pointer to pass through...
  401. if (pszShort)
  402. {
  403. SHTCharToAnsi(pszShort, szShort, ARRAYSIZE(szShort));
  404. pszShort = (LPCTSTR)szShort; // overload the pointer to pass through...
  405. }
  406. if (pszFileSpec)
  407. {
  408. SHTCharToAnsi(pszFileSpec, szFileSpec, ARRAYSIZE(szFileSpec));
  409. pszFileSpec = (LPCTSTR)szFileSpec; // overload the pointer to pass through...
  410. }
  411. fRet = PathYetAnotherMakeUniqueName((LPTSTR)szUniqueName, pszPath, pszShort, pszFileSpec);
  412. if (fRet)
  413. SHAnsiToTChar(szUniqueName, pszUniqueName, MAX_PATH);
  414. return fRet;
  415. }
  416. }
  417. BOOL _AorW_PathResolve(/*IN OUT*/ LPTSTR pszPath, /*IN OPTIONAL*/ LPCTSTR rgpszDirs[], UINT fFlags)
  418. {
  419. THUNKMSG(TEXT("PathResolve"));
  420. if (g_fRunningOnNT)
  421. {
  422. WCHAR wzPath[MAX_PATH];
  423. WCHAR wzDir[MAX_PATH];
  424. BOOL fRet;
  425. SHTCharToUnicode(pszPath, wzPath, ARRAYSIZE(wzPath));
  426. if (rgpszDirs && rgpszDirs[0])
  427. {
  428. SHTCharToUnicode(rgpszDirs[0], wzDir, ARRAYSIZE(wzDir));
  429. rgpszDirs[0] = (LPCTSTR)wzDir; // overload the pointer to pass through...
  430. if (rgpszDirs[1])
  431. {
  432. // Super Hack, we assume dirs has only one element since it's the only case
  433. // this is called in SHDOCVW.
  434. AssertMsg(0, TEXT("PathResolve thunk needs to be fixed to handle more than one dirs."));
  435. rgpszDirs[1] = NULL;
  436. }
  437. }
  438. fRet = PathResolve((LPTSTR)wzPath, rgpszDirs, fFlags);
  439. if (fRet)
  440. SHUnicodeToTChar(wzPath, pszPath, MAX_PATH);
  441. return fRet;
  442. }
  443. else
  444. {
  445. CHAR szPath[MAX_PATH];
  446. CHAR szDir[MAX_PATH];
  447. BOOL fRet;
  448. SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  449. if (rgpszDirs && rgpszDirs[0])
  450. {
  451. SHTCharToAnsi(rgpszDirs[0], szDir, ARRAYSIZE(szDir));
  452. rgpszDirs[0] = (LPCTSTR)szDir; // overload the pointer to pass through...
  453. if (rgpszDirs[1])
  454. {
  455. // Super Hack, we assume dirs has only one element since it's the only case
  456. // this is called in SHDOCVW.
  457. AssertMsg(0, TEXT("PathResolve thunk needs to be fixed to handle more than one dirs."));
  458. rgpszDirs[1] = NULL;
  459. }
  460. }
  461. fRet = PathResolve((LPTSTR)szPath, rgpszDirs, fFlags);
  462. if (fRet)
  463. SHAnsiToTChar(szPath, pszPath, MAX_PATH);
  464. return fRet;
  465. }
  466. }
  467. #ifndef UNIX
  468. // Explicit prototype because only the A/W prototypes exist in the headers
  469. BOOL IsLFNDrive(LPCTSTR pszPath);
  470. #else
  471. #ifdef UNICODE
  472. #define IsLFNDrive IsLFNDriveW
  473. #else
  474. #define IsLFNDrive IsLFNDriveA
  475. #endif
  476. #endif
  477. BOOL _AorW_IsLFNDrive(/*IN*/ LPTSTR pszPath)
  478. {
  479. THUNKMSG(TEXT("IsLFNDrive"));
  480. if (g_fRunningOnNT)
  481. {
  482. WCHAR wszPath[MAX_PATH];
  483. SHTCharToUnicode(pszPath, wszPath, ARRAYSIZE(wszPath));
  484. return IsLFNDrive((LPTSTR)wszPath);
  485. }
  486. else
  487. {
  488. CHAR szPath[MAX_PATH];
  489. SHTCharToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  490. return IsLFNDrive((LPTSTR)szPath);
  491. }
  492. }
  493. int _AorW_PickIconDlg(
  494. IN HWND hwnd,
  495. IN OUT LPTSTR pszIconPath,
  496. IN UINT cchIconPath,
  497. IN OUT int * piIconIndex)
  498. {
  499. int nRet;
  500. WCHAR wszPath[MAX_PATH];
  501. CHAR szPath[MAX_PATH];
  502. LPTSTR psz = pszIconPath;
  503. UINT cch = cchIconPath;
  504. if (g_fRunningOnNT)
  505. {
  506. SHTCharToUnicode(pszIconPath, wszPath, ARRAYSIZE(wszPath));
  507. psz = (LPTSTR)wszPath; // overload the pointer to pass through...
  508. cch = SIZECHARS(wszPath);
  509. }
  510. else
  511. {
  512. SHTCharToAnsi(pszIconPath, szPath, ARRAYSIZE(wszPath));
  513. psz = (LPTSTR)szPath; // overload the pointer to pass through...
  514. cch = SIZECHARS(szPath);
  515. }
  516. nRet = PickIconDlg(hwnd, psz, cch, piIconIndex);
  517. if (g_fRunningOnNT)
  518. SHUnicodeToTChar(wszPath, pszIconPath, cchIconPath);
  519. else
  520. SHAnsiToTChar(szPath, pszIconPath, cchIconPath);
  521. return nRet;
  522. }
  523. //
  524. // Now the thunks that allow us to run on Windows 95.
  525. //
  526. //
  527. //
  528. // This thunks a unicode string to ANSI, but if it's an ordinal, then
  529. // we just leave it alone.
  530. //
  531. LPSTR Thunk_UnicodeToAnsiOrOrdinal(LPCWSTR pwsz, LPSTR pszBuf, UINT cchBuf)
  532. {
  533. if (HIWORD64(pwsz)) {
  534. SHUnicodeToAnsi(pwsz, pszBuf, cchBuf);
  535. return pszBuf;
  536. } else {
  537. return (LPSTR)pwsz;
  538. }
  539. }
  540. #define THUNKSTRING(pwsz, sz) Thunk_UnicodeToAnsiOrOrdinal(pwsz, sz, ARRAYSIZE(sz))
  541. //
  542. // This function is new for IE4, so on IE3,
  543. // we emulate (poorly) with ExtractIcon.
  544. //
  545. //
  546. // Win95 exported ILCreateFromPathA under the name ILCreateFromPath.
  547. // Fortunately, NT kept the same ordinal.
  548. //
  549. //
  550. // If linking with Win95 header files, then call it ILCreateFromPath.
  551. //
  552. #ifdef UNICODE
  553. STDAPI_(LPITEMIDLIST) _ILCreateFromPathA(LPCSTR pszPath)
  554. {
  555. if (g_fRunningOnNT) {
  556. WCHAR wszPath[MAX_PATH];
  557. SHAnsiToUnicode(pszPath, wszPath, ARRAYSIZE(wszPath));
  558. return ILCreateFromPath((LPVOID)wszPath);
  559. } else {
  560. return ILCreateFromPath((LPVOID)pszPath);
  561. }
  562. }
  563. #else
  564. STDAPI_(LPITEMIDLIST) _ILCreateFromPathW(LPCWSTR pszPath)
  565. {
  566. if (g_fRunningOnNT) {
  567. return ILCreateFromPath((LPVOID)pszPath);
  568. } else {
  569. CHAR szPath[MAX_PATH];
  570. SHUnicodeToAnsi(pszPath, szPath, ARRAYSIZE(szPath));
  571. return ILCreateFromPath((LPVOID)szPath);
  572. }
  573. }
  574. #endif
  575. STDAPI_(int) _AorW_SHCreateDirectory(HWND hwnd, LPCTSTR pszPath)
  576. {
  577. if (g_fRunningOnNT)
  578. {
  579. WCHAR wsz[MAX_PATH];
  580. SHTCharToUnicode(pszPath, wsz, ARRAYSIZE(wsz));
  581. return SHCreateDirectory(hwnd, (LPCTSTR)wsz);
  582. }
  583. else
  584. {
  585. CHAR sz[MAX_PATH];
  586. SHTCharToAnsi(pszPath, sz, ARRAYSIZE(sz));
  587. return SHCreateDirectory(hwnd, (LPCTSTR)sz);
  588. }
  589. }
  590. #ifdef UNICODE
  591. //
  592. // Either ptsz1 or ptsz2 can be NULL, so be careful when thunking.
  593. //
  594. STDAPI_(int) _AorW_ShellAbout(HWND hWnd, LPCTSTR ptsz1, LPCTSTR ptsz2, HICON hIcon)
  595. {
  596. if (g_fRunningOnNT)
  597. {
  598. return ShellAboutW(hWnd, ptsz1, ptsz2, hIcon);
  599. }
  600. else
  601. {
  602. CHAR sz1[MAX_PATH], sz2[MAX_PATH];
  603. LPSTR psz1, psz2;
  604. if (ptsz1) {
  605. psz1 = sz1;
  606. SHTCharToAnsi(ptsz1, sz1, ARRAYSIZE(sz1));
  607. } else {
  608. psz1 = NULL;
  609. }
  610. if (ptsz2) {
  611. psz2 = sz2;
  612. SHTCharToAnsi(ptsz2, sz2, ARRAYSIZE(sz2));
  613. } else {
  614. psz2 = NULL;
  615. }
  616. return ShellAboutA(hWnd, psz1, psz2, hIcon);
  617. }
  618. }
  619. #endif
  620. #endif // _X86_