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.

838 lines
28 KiB

  1. #include "shellprv.h"
  2. #pragma hdrstop
  3. #define GUIDSIZE (GUIDSTR_MAX+1)
  4. //
  5. // This function uses SHGetIniStringUTF7 to access the string, so it is valid
  6. // to use SZ_CANBEUNICODE on the key name.
  7. //
  8. HRESULT SHGetSetFolderSetting(LPCTSTR pszIniFile, DWORD dwReadWrite, LPCTSTR pszSection,
  9. LPCTSTR pszKey, LPTSTR pszValue, DWORD cchValueSize)
  10. {
  11. HRESULT hr = S_OK;
  12. //They just want to read.
  13. if (dwReadWrite == FCS_READ)
  14. {
  15. if (pszValue)
  16. {
  17. if (!SHGetIniStringUTF7(pszSection,pszKey, pszValue, cchValueSize, pszIniFile))
  18. hr = E_FAIL;
  19. }
  20. }
  21. //They want to write the value regardless whether the value is already there or not.
  22. if (dwReadWrite == FCS_FORCEWRITE)
  23. {
  24. SHSetIniStringUTF7(pszSection, pszKey, pszValue, pszIniFile);
  25. }
  26. //Write only if the value is not already present.
  27. if (dwReadWrite == FCS_WRITE)
  28. {
  29. TCHAR szBuf[MAX_PATH];
  30. BOOL fWrite = TRUE;
  31. szBuf[0] = 0;
  32. //See if the value already exists ?
  33. SHGetIniStringUTF7(pszSection,pszKey, szBuf, ARRAYSIZE(szBuf), pszIniFile);
  34. if (!szBuf[0])
  35. {
  36. //Write only if the value is not already in the file
  37. SHSetIniStringUTF7(pszSection, pszKey, pszValue, pszIniFile);
  38. }
  39. }
  40. return hr;
  41. }
  42. // SHGetSetFolderSetting for path values
  43. HRESULT SHGetSetFolderSettingPath(LPCTSTR pszIniFile, DWORD dwReadWrite, LPCTSTR pszSection,
  44. LPCTSTR pszKey, LPTSTR pszValue, DWORD cchValueSize)
  45. {
  46. HRESULT hr;
  47. TCHAR szTemp[MAX_PATH], szTemp2[MAX_PATH];
  48. if ((dwReadWrite == FCS_FORCEWRITE) || (dwReadWrite == FCS_WRITE)) // We write
  49. {
  50. int cch = cchValueSize;
  51. if (pszValue)
  52. {
  53. lstrcpyn(szTemp, pszValue, ARRAYSIZE(szTemp));
  54. SubstituteWebDir(szTemp, ARRAYSIZE(szTemp));
  55. if (PathUnExpandEnvStrings(szTemp, szTemp2, ARRAYSIZE(szTemp2)))
  56. {
  57. pszValue = szTemp2;
  58. cch = ARRAYSIZE(szTemp2);
  59. }
  60. else
  61. {
  62. pszValue = szTemp;
  63. cch = ARRAYSIZE(szTemp);
  64. }
  65. }
  66. hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, pszSection, pszKey, pszValue, 0);
  67. }
  68. else
  69. {
  70. hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, pszSection, pszKey, szTemp, ARRAYSIZE(szTemp));
  71. if (SUCCEEDED(hr)) // We've read a path
  72. {
  73. SHExpandEnvironmentStrings(szTemp, pszValue, cchValueSize); // This is a path, so expand the env vars in it
  74. ExpandOtherVariables(pszValue, cchValueSize);
  75. }
  76. }
  77. return hr;
  78. }
  79. // Read/write desktop.ini settings
  80. HRESULT SHGetSetLogo(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite)
  81. {
  82. HRESULT hr = S_FALSE;
  83. if (pfcs->dwMask & FCSM_LOGO)
  84. {
  85. hr = SHGetSetFolderSettingPath(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), SZ_CANBEUNICODE TEXT("Logo"),
  86. pfcs->pszLogo, pfcs->cchLogo);
  87. }
  88. return hr;
  89. }
  90. // Read/write desktop.ini settings
  91. HRESULT SHGetSetInfoTip(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite)
  92. {
  93. HRESULT hr = S_FALSE;
  94. if (pfcs->dwMask & FCSM_INFOTIP)
  95. {
  96. hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), SZ_CANBEUNICODE TEXT("InfoTip"),
  97. pfcs->pszInfoTip, pfcs->cchInfoTip);
  98. }
  99. return hr;
  100. }
  101. // Read/write desktop.ini settings
  102. HRESULT SHGetSetIconFile(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite)
  103. {
  104. HRESULT hr = S_FALSE;
  105. if (pfcs->dwMask & FCSM_ICONFILE)
  106. {
  107. hr = SHGetSetFolderSettingPath(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), SZ_CANBEUNICODE TEXT("IconFile"),
  108. pfcs->pszIconFile, pfcs->cchIconFile);
  109. }
  110. return hr;
  111. }
  112. // Read/write desktop.ini settings
  113. HRESULT SHGetSetVID(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite)
  114. {
  115. HRESULT hr = S_FALSE;
  116. TCHAR szVID[GUIDSIZE];
  117. if (pfcs->dwMask & FCSM_VIEWID)
  118. {
  119. if (dwReadWrite == FCS_READ)
  120. {
  121. if (pfcs->pvid)
  122. {
  123. hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT("ExtShellFolderViews"), TEXT("Default"),
  124. szVID, ARRAYSIZE(szVID));
  125. if (hr == S_OK)
  126. SHCLSIDFromString(szVID, pfcs->pvid);
  127. }
  128. }
  129. else if (pfcs->pvid)
  130. {
  131. SHStringFromGUID(pfcs->pvid, szVID, ARRAYSIZE(szVID));
  132. SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT("ExtShellFolderViews"), TEXT("Default"),
  133. szVID, ARRAYSIZE(szVID));
  134. hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT("ExtShellFolderViews"), szVID,
  135. szVID, ARRAYSIZE(szVID));
  136. }
  137. else
  138. {
  139. // if we get here we assume that they want to nuke the whole section
  140. if(0 != WritePrivateProfileString(TEXT("ExtShellFolderViews"), NULL, NULL, pszIniFile))
  141. {
  142. hr = S_OK;
  143. }
  144. }
  145. }
  146. return hr;
  147. }
  148. // Read/write desktop.ini settings
  149. HRESULT SHGetSetCLSID(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite)
  150. {
  151. HRESULT hr = S_FALSE;
  152. TCHAR szCLSID[GUIDSIZE];
  153. if (pfcs->dwMask & FCSM_CLSID)
  154. {
  155. if (dwReadWrite == FCS_READ)
  156. {
  157. if (pfcs->pclsid)
  158. {
  159. SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("CLSID2"),
  160. szCLSID, ARRAYSIZE(szCLSID));
  161. hr = SHCLSIDFromString(szCLSID, pfcs->pclsid);
  162. }
  163. }
  164. else if (pfcs->pclsid)
  165. {
  166. SHStringFromGUID(pfcs->pclsid, szCLSID, ARRAYSIZE(szCLSID));
  167. hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("CLSID2"),
  168. szCLSID, ARRAYSIZE(szCLSID));
  169. }
  170. else
  171. {
  172. hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("CLSID2"),
  173. NULL, 0);
  174. }
  175. }
  176. return hr;
  177. }
  178. // Read/write desktop.ini settings
  179. HRESULT SHGetSetFlags(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite)
  180. {
  181. HRESULT hr = S_FALSE;
  182. TCHAR szFlags[20];
  183. if (pfcs->dwMask & FCSM_FLAGS)
  184. {
  185. if (dwReadWrite == FCS_READ)
  186. {
  187. hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("Flags"),
  188. szFlags, ARRAYSIZE(szFlags));
  189. pfcs->dwFlags = StrToInt(szFlags);
  190. }
  191. else
  192. {
  193. wsprintf(szFlags, TEXT("%d"), (int)pfcs->dwFlags);
  194. hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("Flags"),
  195. szFlags, ARRAYSIZE(szFlags));
  196. }
  197. }
  198. return hr;
  199. }
  200. // Read/write desktop.ini settings
  201. HRESULT SHGetSetIconIndex(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite)
  202. {
  203. TCHAR szIconIndex[20];
  204. HRESULT hr = S_FALSE;
  205. if (pfcs->dwMask & FCSM_ICONFILE)
  206. {
  207. if (dwReadWrite == FCS_READ)
  208. {
  209. hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("IconIndex"),
  210. szIconIndex, ARRAYSIZE(szIconIndex));
  211. pfcs->iIconIndex = StrToInt(szIconIndex);
  212. }
  213. else if (pfcs->pszIconFile)
  214. {
  215. wsprintf(szIconIndex, TEXT("%d"), (int)pfcs->iIconIndex);
  216. hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("IconIndex"),
  217. szIconIndex, ARRAYSIZE(szIconIndex));
  218. }
  219. else
  220. {
  221. hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("IconIndex"),
  222. NULL, 0);
  223. }
  224. }
  225. return hr;
  226. }
  227. const LPCTSTR c_szWebViewTemplateVersions[] =
  228. {
  229. SZ_CANBEUNICODE TEXT("WebViewTemplate.NT5"),
  230. SZ_CANBEUNICODE TEXT("PersistMoniker")
  231. };
  232. // Read/write desktop.ini settings
  233. HRESULT SHGetSetWebViewTemplate(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite)
  234. {
  235. int i;
  236. TCHAR szVID[GUIDSIZE], szTemp[MAX_PATH];
  237. HRESULT hr = S_FALSE;
  238. if (pfcs->dwMask & FCSM_WEBVIEWTEMPLATE)
  239. {
  240. if (!SHStringFromGUID(&VID_WebView, szVID, ARRAYSIZE(szVID)))
  241. {
  242. hr = E_FAIL;
  243. }
  244. if ((!pfcs->pszWebViewTemplate || !pfcs->pszWebViewTemplate[0]) && (dwReadWrite == FCS_FORCEWRITE)) // We have to remove webview
  245. {
  246. WritePrivateProfileString(szVID, NULL, NULL, pszIniFile);
  247. WritePrivateProfileString(TEXT("ExtShellFolderViews"), szVID, NULL, pszIniFile);
  248. if (SHGetSetFolderSetting(pszIniFile, FCS_READ, TEXT("ExtShellFolderViews"), TEXT("Default"), szTemp, ARRAYSIZE(szTemp)) == S_OK
  249. && StrCmpI(szTemp, szVID) == 0)
  250. {
  251. WritePrivateProfileString(TEXT("ExtShellFolderViews"), TEXT("Default"), NULL, pszIniFile);
  252. }
  253. }
  254. else
  255. {
  256. TCHAR szKey[MAX_PATH];
  257. if (!pfcs->pszWebViewTemplateVersion || !pfcs->pszWebViewTemplateVersion[0]
  258. || (lstrcmpi(pfcs->pszWebViewTemplateVersion, TEXT("IE4")) == 0))
  259. { // They don't know which version template they want. Let's try from the latest version down.
  260. if (dwReadWrite & FCS_READ)
  261. {
  262. for (i = 0; i < ARRAYSIZE(c_szWebViewTemplateVersions); i++)
  263. {
  264. lstrcpyn(szKey, c_szWebViewTemplateVersions[i], ARRAYSIZE(szKey));
  265. if (SHGetSetFolderSetting(pszIniFile, FCS_READ, szVID, szKey, szTemp, ARRAYSIZE(szTemp)) == S_OK)
  266. {
  267. break;
  268. }
  269. }
  270. }
  271. else
  272. {
  273. lstrcpyn(szKey, c_szWebViewTemplateVersions[ARRAYSIZE(c_szWebViewTemplateVersions) - 1], ARRAYSIZE(szKey));
  274. }
  275. }
  276. else
  277. {
  278. lstrcpyn(szKey, SZ_CANBEUNICODE TEXT("WebViewTemplate."), ARRAYSIZE(szKey));
  279. StrCatBuff(szKey, pfcs->pszWebViewTemplateVersion, ARRAYSIZE(szKey));
  280. }
  281. if (dwReadWrite == FCS_FORCEWRITE)
  282. {
  283. // Remove all old templates
  284. for (i = 0; i < ARRAYSIZE(c_szWebViewTemplateVersions); i++)
  285. {
  286. SHGetSetFolderSetting(pszIniFile, FCS_FORCEWRITE, szVID, c_szWebViewTemplateVersions[i], NULL, 0);
  287. }
  288. }
  289. hr = SHGetSetFolderSettingPath(pszIniFile, dwReadWrite, szVID, szKey,
  290. pfcs->pszWebViewTemplate, pfcs->cchWebViewTemplate);
  291. if (SUCCEEDED(hr))
  292. {
  293. if ((dwReadWrite == FCS_FORCEWRITE) || (dwReadWrite == FCS_WRITE))
  294. {
  295. // If we have set the template, make sure that the VID_Webview = VID_WebView line under "ExtShellFolderViews" is present
  296. if (pfcs->pszWebViewTemplate)
  297. {
  298. SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT("ExtShellFolderViews"), szVID,
  299. szVID, ARRAYSIZE(szVID));
  300. }
  301. }
  302. }
  303. }
  304. }
  305. return hr;
  306. }
  307. // Read/write desktop.ini settings
  308. HRESULT SHGetSetFCS(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszPath, DWORD dwReadWrite)
  309. {
  310. HRESULT hret = S_OK, hr;
  311. TCHAR szIniFile[MAX_PATH];
  312. DWORD dwValueReturned = 0;
  313. // Get the pathname for desktop.ini
  314. PathCombine(szIniFile, pszPath, TEXT("Desktop.ini"));
  315. hr = SHGetSetVID(pfcs, szIniFile, dwReadWrite);
  316. if (S_OK == hr)
  317. {
  318. dwValueReturned |= FCSM_VIEWID;
  319. }
  320. hr = SHGetSetWebViewTemplate(pfcs, szIniFile, dwReadWrite);
  321. if (S_OK == hr)
  322. {
  323. dwValueReturned |= FCSM_WEBVIEWTEMPLATE;
  324. }
  325. hr = SHGetSetInfoTip(pfcs, szIniFile, dwReadWrite);
  326. if (S_OK == hr)
  327. {
  328. dwValueReturned |= FCSM_INFOTIP;
  329. }
  330. hr = SHGetSetCLSID(pfcs, szIniFile, dwReadWrite);
  331. if (S_OK == hr)
  332. {
  333. dwValueReturned |= FCSM_CLSID;
  334. }
  335. hr = SHGetSetFlags(pfcs, szIniFile, dwReadWrite);
  336. if (S_OK == hr)
  337. {
  338. dwValueReturned |= FCSM_FLAGS;
  339. }
  340. hr = SHGetSetIconFile(pfcs, szIniFile, dwReadWrite);
  341. if (S_OK == hr)
  342. {
  343. dwValueReturned |= FCSM_ICONFILE;
  344. }
  345. hr = SHGetSetIconIndex(pfcs, szIniFile, dwReadWrite);
  346. if (S_OK == hr)
  347. {
  348. dwValueReturned |= FCSM_ICONFILE;
  349. }
  350. hr = SHGetSetLogo(pfcs, szIniFile, dwReadWrite);
  351. if (S_OK == hr)
  352. {
  353. dwValueReturned |= FCSM_LOGO;
  354. }
  355. if (SUCCEEDED(hret) && (dwReadWrite & FCS_FORCEWRITE))
  356. {
  357. // Make desktop.ini hidden
  358. SetFileAttributes(szIniFile, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
  359. // Make this a system folder, so that we look for desktop.ini when we navigate to this folder.
  360. PathMakeSystemFolder(pszPath);
  361. }
  362. if (dwReadWrite & FCS_READ)
  363. {
  364. // If we were asked to get something and we are not returning anything, return error.
  365. if (pfcs->dwMask && !dwValueReturned)
  366. {
  367. hret = E_FAIL;
  368. }
  369. pfcs->dwMask = dwValueReturned;
  370. }
  371. return hret;
  372. }
  373. HRESULT SHAllocAndThunkUnicodeToTChar(LPWSTR pwsz, LPTSTR* ppsz, int cchReturnBuffer)
  374. {
  375. HRESULT hr = S_OK;
  376. if (!ppsz || !pwsz)
  377. {
  378. hr = E_INVALIDARG;
  379. }
  380. else
  381. {
  382. int cch;
  383. if (cchReturnBuffer > 0)
  384. {
  385. // if the user specified the size of the return buffer, alloc that ammount
  386. cch = cchReturnBuffer;
  387. }
  388. else
  389. {
  390. // since the user did not specify the size, alloc just enough to hold the string
  391. cch = lstrlenW(pwsz) + 1;
  392. }
  393. *ppsz = (LPTSTR)LocalAlloc(LPTR, cch * sizeof(TCHAR));
  394. if (!*ppsz)
  395. {
  396. hr = E_OUTOFMEMORY;
  397. }
  398. else
  399. {
  400. SHUnicodeToTChar(pwsz, *ppsz, cch);
  401. }
  402. }
  403. return hr;
  404. }
  405. HRESULT SHAllocAndThunkAnsiToTChar(LPSTR psz, LPTSTR* ppsz, int cchReturnBuffer)
  406. {
  407. HRESULT hr = S_OK;
  408. if (!ppsz || !psz)
  409. {
  410. hr = E_INVALIDARG;
  411. }
  412. else
  413. {
  414. int cch;
  415. if (cchReturnBuffer > 0)
  416. {
  417. // if the user specified the size of the return buffer, alloc that ammount
  418. cch = cchReturnBuffer;
  419. }
  420. else
  421. {
  422. // since the user did not specify the size, alloc just enough to hold the string
  423. cch = lstrlenA(psz) + 1;
  424. }
  425. *ppsz = (LPTSTR)LocalAlloc(LPTR, cch * sizeof(TCHAR));
  426. if (!*ppsz)
  427. {
  428. hr = E_OUTOFMEMORY;
  429. }
  430. else
  431. {
  432. SHAnsiToTChar(psz, *ppsz, cch);
  433. }
  434. }
  435. return hr;
  436. }
  437. // Read/write desktop.ini settings - Unicode (thunking function)
  438. HRESULT SHGetSetFolderCustomSettingsW(LPSHFOLDERCUSTOMSETTINGSW pfcsW, LPCWSTR pwszPath, DWORD dwReadWrite)
  439. {
  440. HRESULT hr = S_OK;
  441. if (pfcsW->dwSize >= sizeof(SHFOLDERCUSTOMSETTINGSW) && pwszPath)
  442. {
  443. TCHAR szPath[MAX_PATH], *pszWebViewTemplate = NULL, *pszWebViewTemplateVersion = NULL;
  444. TCHAR *pszInfoTip = NULL, *pszIconFile = NULL, *pszLogo = NULL;
  445. SHUnicodeToTChar(pwszPath, szPath, ARRAYSIZE(szPath));
  446. if (dwReadWrite == FCS_WRITE || dwReadWrite == FCS_FORCEWRITE)
  447. {
  448. if (pfcsW->dwMask & FCSM_WEBVIEWTEMPLATE && pfcsW->pszWebViewTemplate)
  449. {
  450. hr = SHAllocAndThunkUnicodeToTChar(pfcsW->pszWebViewTemplate, &pszWebViewTemplate, pfcsW->cchWebViewTemplate);
  451. if (SUCCEEDED(hr) && pfcsW->pszWebViewTemplateVersion)
  452. {
  453. hr = SHAllocAndThunkUnicodeToTChar(pfcsW->pszWebViewTemplateVersion, &pszWebViewTemplateVersion, 0);
  454. }
  455. }
  456. if (pfcsW->dwMask & FCSM_INFOTIP && pfcsW->pszInfoTip && SUCCEEDED(hr))
  457. {
  458. hr = SHAllocAndThunkUnicodeToTChar(pfcsW->pszInfoTip, &pszInfoTip, pfcsW->cchInfoTip);
  459. }
  460. if (pfcsW->dwMask & FCSM_ICONFILE && pfcsW->pszIconFile && SUCCEEDED(hr))
  461. {
  462. hr = SHAllocAndThunkUnicodeToTChar(pfcsW->pszIconFile, &pszIconFile, pfcsW->cchIconFile);
  463. }
  464. if (pfcsW->dwMask & FCSM_LOGO && pfcsW->pszLogo && SUCCEEDED(hr))
  465. {
  466. hr = SHAllocAndThunkUnicodeToTChar(pfcsW->pszLogo, &pszLogo, pfcsW->cchLogo);
  467. }
  468. }
  469. else if (dwReadWrite == FCS_READ)
  470. {
  471. if (pfcsW->dwMask & FCSM_WEBVIEWTEMPLATE && pfcsW->pszWebViewTemplate && pfcsW->cchWebViewTemplate > 0)
  472. {
  473. pszWebViewTemplate = (LPTSTR)LocalAlloc(LPTR, pfcsW->cchWebViewTemplate * sizeof(TCHAR));
  474. if (!pszWebViewTemplate)
  475. {
  476. hr = E_OUTOFMEMORY;
  477. }
  478. else
  479. {
  480. pszWebViewTemplate[0] = 0;
  481. if (pfcsW->pszWebViewTemplateVersion)
  482. {
  483. hr = SHAllocAndThunkUnicodeToTChar(pfcsW->pszWebViewTemplateVersion, &pszWebViewTemplateVersion, 0);
  484. }
  485. }
  486. }
  487. if (pfcsW->dwMask & FCSM_INFOTIP && pfcsW->pszInfoTip && pfcsW->cchInfoTip > 0 && SUCCEEDED(hr))
  488. {
  489. pszInfoTip = (LPTSTR)LocalAlloc(LPTR, pfcsW->cchInfoTip * sizeof(TCHAR));
  490. if (!pszInfoTip)
  491. {
  492. hr = E_OUTOFMEMORY;
  493. }
  494. else
  495. {
  496. pszInfoTip[0] = 0;
  497. }
  498. }
  499. if (pfcsW->dwMask & FCSM_ICONFILE && pfcsW->pszIconFile && pfcsW->cchIconFile > 0 && SUCCEEDED(hr))
  500. {
  501. pszIconFile = (LPTSTR)LocalAlloc(LPTR, pfcsW->cchIconFile * sizeof(TCHAR));
  502. if (!pszIconFile)
  503. {
  504. hr = E_OUTOFMEMORY;
  505. }
  506. else
  507. {
  508. pszIconFile[0] = 0;
  509. }
  510. }
  511. if (pfcsW->dwMask & FCSM_LOGO && pfcsW->pszLogo && pfcsW->cchLogo > 0 && SUCCEEDED(hr))
  512. {
  513. pszLogo = (LPTSTR)LocalAlloc(LPTR, pfcsW->cchLogo * sizeof(TCHAR));
  514. if (!pszLogo)
  515. {
  516. hr = E_OUTOFMEMORY;
  517. }
  518. else
  519. {
  520. pszLogo[0] = 0;
  521. }
  522. }
  523. }
  524. else
  525. {
  526. hr = E_INVALIDARG;
  527. }
  528. if (SUCCEEDED(hr))
  529. {
  530. SHFOLDERCUSTOMSETTINGS fcs;
  531. fcs.dwSize = sizeof(LPSHFOLDERCUSTOMSETTINGS);
  532. fcs.dwMask = pfcsW->dwMask;
  533. fcs.pvid = pfcsW->pvid;
  534. fcs.pszWebViewTemplate = pszWebViewTemplate;
  535. fcs.cchWebViewTemplate = pfcsW->cchWebViewTemplate;
  536. fcs.pszWebViewTemplateVersion = pszWebViewTemplateVersion;
  537. fcs.pszInfoTip = pszInfoTip;
  538. fcs.cchInfoTip = pfcsW->cchInfoTip;
  539. fcs.pclsid = pfcsW->pclsid;
  540. fcs.dwFlags = pfcsW->dwFlags;
  541. fcs.pszIconFile = pszIconFile;
  542. fcs.cchIconFile = pfcsW->cchIconFile;
  543. fcs.iIconIndex = pfcsW->iIconIndex;
  544. fcs.pszLogo = pszLogo;
  545. fcs.cchLogo = pfcsW->cchLogo;
  546. hr = SHGetSetFCS(&fcs, szPath, dwReadWrite);
  547. if (SUCCEEDED(hr))
  548. {
  549. if (dwReadWrite == FCS_READ)
  550. {
  551. if (fcs.dwMask & FCSM_WEBVIEWTEMPLATE && fcs.pszWebViewTemplate)
  552. {
  553. SHTCharToUnicode(fcs.pszWebViewTemplate, pfcsW->pszWebViewTemplate, pfcsW->cchWebViewTemplate);
  554. }
  555. if (fcs.dwMask & FCSM_INFOTIP && fcs.pszInfoTip)
  556. {
  557. SHTCharToUnicode(fcs.pszInfoTip, pfcsW->pszInfoTip, pfcsW->cchInfoTip);
  558. }
  559. if (fcs.dwMask & FCSM_ICONFILE && fcs.pszIconFile)
  560. {
  561. SHTCharToUnicode(fcs.pszIconFile, pfcsW->pszIconFile, pfcsW->cchIconFile);
  562. }
  563. if (fcs.dwMask & FCSM_LOGO && fcs.pszLogo)
  564. {
  565. SHTCharToUnicode(fcs.pszLogo, pfcsW->pszLogo, pfcsW->cchLogo);
  566. }
  567. pfcsW->dwFlags = fcs.dwFlags;
  568. pfcsW->iIconIndex = fcs.iIconIndex;
  569. pfcsW->dwMask = fcs.dwMask;
  570. }
  571. }
  572. }
  573. // Free allocated memory
  574. if (pszWebViewTemplate)
  575. {
  576. LocalFree(pszWebViewTemplate);
  577. }
  578. if (pszWebViewTemplateVersion)
  579. {
  580. LocalFree(pszWebViewTemplateVersion);
  581. }
  582. if (pszInfoTip)
  583. {
  584. LocalFree(pszInfoTip);
  585. }
  586. if (pszIconFile)
  587. {
  588. LocalFree(pszIconFile);
  589. }
  590. if (pszLogo)
  591. {
  592. LocalFree(pszLogo);
  593. }
  594. }
  595. else
  596. {
  597. hr = E_INVALIDARG;
  598. }
  599. return hr;
  600. }
  601. // Read/write desktop.ini settings - ANSI (thunking function)
  602. HRESULT SHGetSetFolderCustomSettingsA(LPSHFOLDERCUSTOMSETTINGSA pfcsA, LPCSTR pszPath, DWORD dwReadWrite)
  603. {
  604. HRESULT hr = S_OK;
  605. if (pfcsA->dwSize >= sizeof(SHFOLDERCUSTOMSETTINGSA) && pszPath)
  606. {
  607. TCHAR szPath[MAX_PATH], *pszWebViewTemplate = NULL, *pszWebViewTemplateVersion = NULL;
  608. TCHAR *pszInfoTip = NULL, *pszIconFile =NULL, *pszLogo = NULL;
  609. SHAnsiToTChar(pszPath, szPath, ARRAYSIZE(szPath));
  610. if (dwReadWrite == FCS_WRITE || dwReadWrite == FCS_FORCEWRITE)
  611. {
  612. if (pfcsA->dwMask & FCSM_WEBVIEWTEMPLATE && pfcsA->pszWebViewTemplate)
  613. {
  614. hr = SHAllocAndThunkAnsiToTChar(pfcsA->pszWebViewTemplate, &pszWebViewTemplate, pfcsA->cchWebViewTemplate);
  615. if (SUCCEEDED(hr) && pfcsA->pszWebViewTemplateVersion)
  616. {
  617. hr = SHAllocAndThunkAnsiToTChar(pfcsA->pszWebViewTemplateVersion, &pszWebViewTemplateVersion, 0);
  618. }
  619. }
  620. if (pfcsA->dwMask & FCSM_INFOTIP && pfcsA->pszInfoTip && SUCCEEDED(hr))
  621. {
  622. hr = SHAllocAndThunkAnsiToTChar(pfcsA->pszInfoTip, &pszInfoTip, pfcsA->cchInfoTip);
  623. }
  624. if (pfcsA->dwMask & FCSM_ICONFILE && pfcsA->pszIconFile && SUCCEEDED(hr))
  625. {
  626. hr = SHAllocAndThunkAnsiToTChar(pfcsA->pszIconFile, &pszIconFile, pfcsA->cchIconFile);
  627. }
  628. if (pfcsA->dwMask & FCSM_LOGO && pfcsA->pszLogo && SUCCEEDED(hr))
  629. {
  630. hr = SHAllocAndThunkAnsiToTChar(pfcsA->pszLogo, &pszLogo, pfcsA->cchLogo);
  631. }
  632. }
  633. else if (dwReadWrite == FCS_READ)
  634. {
  635. if (pfcsA->dwMask & FCSM_WEBVIEWTEMPLATE && pfcsA->pszWebViewTemplate && pfcsA->cchWebViewTemplate > 0)
  636. {
  637. pszWebViewTemplate = (LPTSTR)LocalAlloc(LPTR, pfcsA->cchWebViewTemplate * sizeof(TCHAR));
  638. if (!pszWebViewTemplate)
  639. {
  640. hr = E_OUTOFMEMORY;
  641. }
  642. else
  643. {
  644. pszWebViewTemplate[0] = 0;
  645. if (pfcsA->pszWebViewTemplateVersion)
  646. {
  647. hr = SHAllocAndThunkAnsiToTChar(pfcsA->pszWebViewTemplateVersion, &pszWebViewTemplateVersion, 0);
  648. }
  649. }
  650. }
  651. if (pfcsA->dwMask & FCSM_INFOTIP && pfcsA->pszInfoTip && pfcsA->cchInfoTip > 0 && SUCCEEDED(hr))
  652. {
  653. pszInfoTip = (LPTSTR)LocalAlloc(LPTR, pfcsA->cchInfoTip * sizeof(TCHAR));
  654. if (!pszInfoTip)
  655. {
  656. hr = E_OUTOFMEMORY;
  657. }
  658. else
  659. {
  660. pszInfoTip[0] = 0;
  661. }
  662. }
  663. if (pfcsA->dwMask & FCSM_ICONFILE && pfcsA->pszIconFile && pfcsA->cchIconFile > 0 && SUCCEEDED(hr))
  664. {
  665. pszIconFile = (LPTSTR)LocalAlloc(LPTR, pfcsA->cchIconFile * sizeof(TCHAR));
  666. if (!pszIconFile)
  667. {
  668. hr = E_OUTOFMEMORY;
  669. }
  670. else
  671. {
  672. pszIconFile[0] = 0;
  673. }
  674. }
  675. if (pfcsA->dwMask & FCSM_LOGO && pfcsA->pszLogo && pfcsA->cchLogo > 0 && SUCCEEDED(hr))
  676. {
  677. pszLogo = (LPTSTR)LocalAlloc(LPTR, pfcsA->cchLogo * sizeof(TCHAR));
  678. if (!pszLogo)
  679. {
  680. hr = E_OUTOFMEMORY;
  681. }
  682. else
  683. {
  684. pszLogo[0] = 0;
  685. }
  686. }
  687. }
  688. else
  689. {
  690. hr = E_INVALIDARG;
  691. }
  692. if (SUCCEEDED(hr))
  693. {
  694. SHFOLDERCUSTOMSETTINGS fcs;
  695. fcs.dwSize = sizeof(LPSHFOLDERCUSTOMSETTINGS);
  696. fcs.dwMask = pfcsA->dwMask;
  697. fcs.pvid = pfcsA->pvid;
  698. fcs.pszWebViewTemplate = pszWebViewTemplate;
  699. fcs.cchWebViewTemplate = pfcsA->cchWebViewTemplate;
  700. fcs.pszWebViewTemplateVersion = pszWebViewTemplateVersion;
  701. fcs.pszInfoTip = pszInfoTip;
  702. fcs.cchInfoTip = pfcsA->cchInfoTip;
  703. fcs.pclsid = pfcsA->pclsid;
  704. fcs.dwFlags = pfcsA->dwFlags;
  705. fcs.pszIconFile = pszIconFile;
  706. fcs.cchIconFile = pfcsA->cchIconFile;
  707. fcs.iIconIndex = pfcsA->iIconIndex;
  708. fcs.pszLogo = pszLogo;
  709. fcs.cchLogo = pfcsA->cchLogo;
  710. hr = SHGetSetFCS(&fcs, szPath, dwReadWrite);
  711. if (SUCCEEDED(hr))
  712. {
  713. if (dwReadWrite == FCS_READ)
  714. {
  715. if (fcs.dwMask & FCSM_WEBVIEWTEMPLATE && fcs.pszWebViewTemplate)
  716. {
  717. SHTCharToAnsi(fcs.pszWebViewTemplate, pfcsA->pszWebViewTemplate, pfcsA->cchWebViewTemplate);
  718. }
  719. if (fcs.dwMask & FCSM_INFOTIP && fcs.pszInfoTip)
  720. {
  721. SHTCharToAnsi(fcs.pszInfoTip, pfcsA->pszInfoTip, pfcsA->cchInfoTip);
  722. }
  723. if (fcs.dwMask & FCSM_ICONFILE && fcs.pszIconFile)
  724. {
  725. SHTCharToAnsi(fcs.pszIconFile, pfcsA->pszIconFile, pfcsA->cchIconFile);
  726. }
  727. if (fcs.dwMask & FCSM_LOGO && fcs.pszLogo)
  728. {
  729. SHTCharToAnsi(fcs.pszLogo, pfcsA->pszLogo, pfcsA->cchLogo);
  730. }
  731. pfcsA->dwFlags = fcs.dwFlags;
  732. pfcsA->iIconIndex = fcs.iIconIndex;
  733. pfcsA->dwMask = fcs.dwMask;
  734. }
  735. }
  736. }
  737. // Free allocated memory
  738. if (pszWebViewTemplate)
  739. {
  740. LocalFree(pszWebViewTemplate);
  741. }
  742. if (pszWebViewTemplateVersion)
  743. {
  744. LocalFree(pszWebViewTemplateVersion);
  745. }
  746. if (pszInfoTip)
  747. {
  748. LocalFree(pszInfoTip);
  749. }
  750. if (pszIconFile)
  751. {
  752. LocalFree(pszIconFile);
  753. }
  754. if (pszLogo)
  755. {
  756. LocalFree(pszLogo);
  757. }
  758. }
  759. else
  760. {
  761. hr = E_INVALIDARG;
  762. }
  763. return hr;
  764. }