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.

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