fldsets.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 28k
Category:

Windows Kernel

Development Platform:

Visual C++

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