#include "shellprv.h" #pragma hdrstop #define GUIDSIZE (GUIDSTR_MAX+1) // // This function uses SHGetIniStringUTF7 to access the string, so it is valid // to use SZ_CANBEUNICODE on the key name. // HRESULT SHGetSetFolderSetting(LPCTSTR pszIniFile, DWORD dwReadWrite, LPCTSTR pszSection, LPCTSTR pszKey, LPTSTR pszValue, DWORD cchValueSize) { HRESULT hr = S_OK; //They just want to read. if (dwReadWrite == FCS_READ) { if (pszValue) { if (!SHGetIniStringUTF7(pszSection,pszKey, pszValue, cchValueSize, pszIniFile)) hr = E_FAIL; } } //They want to write the value regardless whether the value is already there or not. if (dwReadWrite == FCS_FORCEWRITE) { SHSetIniStringUTF7(pszSection, pszKey, pszValue, pszIniFile); } //Write only if the value is not already present. if (dwReadWrite == FCS_WRITE) { TCHAR szBuf[MAX_PATH]; BOOL fWrite = TRUE; szBuf[0] = 0; //See if the value already exists ? SHGetIniStringUTF7(pszSection,pszKey, szBuf, ARRAYSIZE(szBuf), pszIniFile); if (!szBuf[0]) { //Write only if the value is not already in the file SHSetIniStringUTF7(pszSection, pszKey, pszValue, pszIniFile); } } return hr; } // SHGetSetFolderSetting for path values HRESULT SHGetSetFolderSettingPath(LPCTSTR pszIniFile, DWORD dwReadWrite, LPCTSTR pszSection, LPCTSTR pszKey, LPTSTR pszValue, DWORD cchValueSize) { HRESULT hr; TCHAR szTemp[MAX_PATH], szTemp2[MAX_PATH]; if ((dwReadWrite == FCS_FORCEWRITE) || (dwReadWrite == FCS_WRITE)) // We write { if (pszValue) { lstrcpyn(szTemp, pszValue, ARRAYSIZE(szTemp)); hr = SubstituteWebDir(szTemp, ARRAYSIZE(szTemp)); if (SUCCEEDED(hr)) { if (PathUnExpandEnvStrings(szTemp, szTemp2, ARRAYSIZE(szTemp2))) { pszValue = szTemp2; } else { pszValue = szTemp; } } else { // some problem substituting due to not enough buffer space, // lets not un-expand that value - use the original value. } } hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, pszSection, pszKey, pszValue, 0); } else { hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, pszSection, pszKey, szTemp, ARRAYSIZE(szTemp)); if (SUCCEEDED(hr)) // We've read a path { SHExpandEnvironmentStrings(szTemp, pszValue, cchValueSize); // This is a path, so expand the env vars in it hr = ExpandOtherVariables(pszValue, cchValueSize); // expand and make sure they fit } } return hr; } // Read/write desktop.ini settings HRESULT SHGetSetLogo(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite) { HRESULT hr = S_FALSE; if (pfcs->dwMask & FCSM_LOGO) { hr = SHGetSetFolderSettingPath(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), SZ_CANBEUNICODE TEXT("Logo"), pfcs->pszLogo, pfcs->cchLogo); } return hr; } // Read/write desktop.ini settings HRESULT SHGetSetInfoTip(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite) { HRESULT hr = S_FALSE; if (pfcs->dwMask & FCSM_INFOTIP) { hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), SZ_CANBEUNICODE TEXT("InfoTip"), pfcs->pszInfoTip, pfcs->cchInfoTip); } return hr; } // Read/write desktop.ini settings HRESULT SHGetSetIconFile(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite) { HRESULT hr = S_FALSE; if (pfcs->dwMask & FCSM_ICONFILE) { hr = SHGetSetFolderSettingPath(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), SZ_CANBEUNICODE TEXT("IconFile"), pfcs->pszIconFile, pfcs->cchIconFile); } return hr; } // Read/write desktop.ini settings HRESULT SHGetSetVID(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite) { HRESULT hr = S_FALSE; TCHAR szVID[GUIDSIZE]; if (pfcs->dwMask & FCSM_VIEWID) { if (dwReadWrite == FCS_READ) { if (pfcs->pvid) { hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT("ExtShellFolderViews"), TEXT("Default"), szVID, ARRAYSIZE(szVID)); if (hr == S_OK) SHCLSIDFromString(szVID, pfcs->pvid); } } else if (pfcs->pvid) { SHStringFromGUID(pfcs->pvid, szVID, ARRAYSIZE(szVID)); SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT("ExtShellFolderViews"), TEXT("Default"), szVID, ARRAYSIZE(szVID)); hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT("ExtShellFolderViews"), szVID, szVID, ARRAYSIZE(szVID)); } else { // if we get here we assume that they want to nuke the whole section if(0 != WritePrivateProfileString(TEXT("ExtShellFolderViews"), NULL, NULL, pszIniFile)) { hr = S_OK; } } } return hr; } // Read/write desktop.ini settings HRESULT SHGetSetCLSID(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite) { HRESULT hr = S_FALSE; TCHAR szCLSID[GUIDSIZE]; if (pfcs->dwMask & FCSM_CLSID) { if (dwReadWrite == FCS_READ) { if (pfcs->pclsid) { SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("CLSID2"), szCLSID, ARRAYSIZE(szCLSID)); hr = SHCLSIDFromString(szCLSID, pfcs->pclsid); } } else if (pfcs->pclsid) { SHStringFromGUID(pfcs->pclsid, szCLSID, ARRAYSIZE(szCLSID)); hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("CLSID2"), szCLSID, ARRAYSIZE(szCLSID)); } else { hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("CLSID2"), NULL, 0); } } return hr; } // Read/write desktop.ini settings HRESULT SHGetSetFlags(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite) { HRESULT hr = S_FALSE; TCHAR szFlags[20]; if (pfcs->dwMask & FCSM_FLAGS) { if (dwReadWrite == FCS_READ) { hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("Flags"), szFlags, ARRAYSIZE(szFlags)); pfcs->dwFlags = StrToInt(szFlags); } else { wnsprintf(szFlags, ARRAYSIZE(szFlags), TEXT("%d"), (int)pfcs->dwFlags); hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("Flags"), szFlags, ARRAYSIZE(szFlags)); } } return hr; } // Read/write desktop.ini settings HRESULT SHGetSetIconIndex(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite) { TCHAR szIconIndex[20]; HRESULT hr = S_FALSE; if (pfcs->dwMask & FCSM_ICONFILE) { if (dwReadWrite == FCS_READ) { hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("IconIndex"), szIconIndex, ARRAYSIZE(szIconIndex)); pfcs->iIconIndex = StrToInt(szIconIndex); } else if (pfcs->pszIconFile) { wnsprintf(szIconIndex, ARRAYSIZE(szIconIndex), TEXT("%d"), (int)pfcs->iIconIndex); hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("IconIndex"), szIconIndex, ARRAYSIZE(szIconIndex)); } else { hr = SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT(".ShellClassInfo"), TEXT("IconIndex"), NULL, 0); } } return hr; } const LPCTSTR c_szWebViewTemplateVersions[] = { SZ_CANBEUNICODE TEXT("WebViewTemplate.NT5"), SZ_CANBEUNICODE TEXT("PersistMoniker") }; // Read/write desktop.ini settings HRESULT SHGetSetWebViewTemplate(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszIniFile, DWORD dwReadWrite) { int i; TCHAR szVID[GUIDSIZE], szTemp[MAX_PATH]; HRESULT hr = S_FALSE; if (pfcs->dwMask & FCSM_WEBVIEWTEMPLATE) { if (!SHStringFromGUID(&VID_WebView, szVID, ARRAYSIZE(szVID))) { hr = E_FAIL; } if ((!pfcs->pszWebViewTemplate || !pfcs->pszWebViewTemplate[0]) && (dwReadWrite == FCS_FORCEWRITE)) // We have to remove webview { WritePrivateProfileString(szVID, NULL, NULL, pszIniFile); WritePrivateProfileString(TEXT("ExtShellFolderViews"), szVID, NULL, pszIniFile); if (SHGetSetFolderSetting(pszIniFile, FCS_READ, TEXT("ExtShellFolderViews"), TEXT("Default"), szTemp, ARRAYSIZE(szTemp)) == S_OK && StrCmpI(szTemp, szVID) == 0) { WritePrivateProfileString(TEXT("ExtShellFolderViews"), TEXT("Default"), NULL, pszIniFile); } } else { TCHAR szKey[MAX_PATH]; if (!pfcs->pszWebViewTemplateVersion || !pfcs->pszWebViewTemplateVersion[0] || (lstrcmpi(pfcs->pszWebViewTemplateVersion, TEXT("IE4")) == 0)) { // They don't know which version template they want. Let's try from the latest version down. if (dwReadWrite & FCS_READ) { for (i = 0; i < ARRAYSIZE(c_szWebViewTemplateVersions); i++) { lstrcpyn(szKey, c_szWebViewTemplateVersions[i], ARRAYSIZE(szKey)); if (SHGetSetFolderSetting(pszIniFile, FCS_READ, szVID, szKey, szTemp, ARRAYSIZE(szTemp)) == S_OK) { break; } } } else { lstrcpyn(szKey, c_szWebViewTemplateVersions[ARRAYSIZE(c_szWebViewTemplateVersions) - 1], ARRAYSIZE(szKey)); } } else { lstrcpyn(szKey, SZ_CANBEUNICODE TEXT("WebViewTemplate."), ARRAYSIZE(szKey)); StrCatBuff(szKey, pfcs->pszWebViewTemplateVersion, ARRAYSIZE(szKey)); } if (dwReadWrite == FCS_FORCEWRITE) { // Remove all old templates for (i = 0; i < ARRAYSIZE(c_szWebViewTemplateVersions); i++) { SHGetSetFolderSetting(pszIniFile, FCS_FORCEWRITE, szVID, c_szWebViewTemplateVersions[i], NULL, 0); } } hr = SHGetSetFolderSettingPath(pszIniFile, dwReadWrite, szVID, szKey, pfcs->pszWebViewTemplate, pfcs->cchWebViewTemplate); if (SUCCEEDED(hr)) { if ((dwReadWrite == FCS_FORCEWRITE) || (dwReadWrite == FCS_WRITE)) { // If we have set the template, make sure that the VID_Webview = VID_WebView line under "ExtShellFolderViews" is present if (pfcs->pszWebViewTemplate) { SHGetSetFolderSetting(pszIniFile, dwReadWrite, TEXT("ExtShellFolderViews"), szVID, szVID, ARRAYSIZE(szVID)); } } } } } return hr; } // Read/write desktop.ini settings HRESULT SHGetSetFCS(LPSHFOLDERCUSTOMSETTINGS pfcs, LPCTSTR pszPath, DWORD dwReadWrite) { HRESULT hret = S_OK, hr; TCHAR szIniFile[MAX_PATH]; DWORD dwValueReturned = 0; // Get the pathname for desktop.ini PathCombine(szIniFile, pszPath, TEXT("Desktop.ini")); hr = SHGetSetVID(pfcs, szIniFile, dwReadWrite); if (S_OK == hr) { dwValueReturned |= FCSM_VIEWID; } hr = SHGetSetWebViewTemplate(pfcs, szIniFile, dwReadWrite); if (S_OK == hr) { dwValueReturned |= FCSM_WEBVIEWTEMPLATE; } hr = SHGetSetInfoTip(pfcs, szIniFile, dwReadWrite); if (S_OK == hr) { dwValueReturned |= FCSM_INFOTIP; } hr = SHGetSetCLSID(pfcs, szIniFile, dwReadWrite); if (S_OK == hr) { dwValueReturned |= FCSM_CLSID; } hr = SHGetSetFlags(pfcs, szIniFile, dwReadWrite); if (S_OK == hr) { dwValueReturned |= FCSM_FLAGS; } hr = SHGetSetIconFile(pfcs, szIniFile, dwReadWrite); if (S_OK == hr) { dwValueReturned |= FCSM_ICONFILE; } hr = SHGetSetIconIndex(pfcs, szIniFile, dwReadWrite); if (S_OK == hr) { dwValueReturned |= FCSM_ICONFILE; } hr = SHGetSetLogo(pfcs, szIniFile, dwReadWrite); if (S_OK == hr) { dwValueReturned |= FCSM_LOGO; } if (SUCCEEDED(hret) && (dwReadWrite & FCS_FORCEWRITE)) { // Make desktop.ini hidden SetFileAttributes(szIniFile, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM); // Make this a system folder, so that we look for desktop.ini when we navigate to this folder. PathMakeSystemFolder(pszPath); } if (dwReadWrite & FCS_READ) { // If we were asked to get something and we are not returning anything, return error. if (pfcs->dwMask && !dwValueReturned) { hret = E_FAIL; } pfcs->dwMask = dwValueReturned; } return hret; } HRESULT SHAllocAndThunkUnicodeToTChar(LPWSTR pwsz, LPTSTR* ppsz, int cchReturnBuffer) { HRESULT hr = S_OK; if (!ppsz || !pwsz) { hr = E_INVALIDARG; } else { int cch; if (cchReturnBuffer > 0) { // if the user specified the size of the return buffer, alloc that ammount cch = cchReturnBuffer; } else { // since the user did not specify the size, alloc just enough to hold the string cch = lstrlenW(pwsz) + 1; } *ppsz = (LPTSTR)LocalAlloc(LPTR, cch * sizeof(TCHAR)); if (!*ppsz) { hr = E_OUTOFMEMORY; } else { SHUnicodeToTChar(pwsz, *ppsz, cch); } } return hr; } HRESULT SHAllocAndThunkAnsiToTChar(LPSTR psz, LPTSTR* ppsz, int cchReturnBuffer) { HRESULT hr = S_OK; if (!ppsz || !psz) { hr = E_INVALIDARG; } else { int cch; if (cchReturnBuffer > 0) { // if the user specified the size of the return buffer, alloc that ammount cch = cchReturnBuffer; } else { // since the user did not specify the size, alloc just enough to hold the string cch = lstrlenA(psz) + 1; } *ppsz = (LPTSTR)LocalAlloc(LPTR, cch * sizeof(TCHAR)); if (!*ppsz) { hr = E_OUTOFMEMORY; } else { SHAnsiToTChar(psz, *ppsz, cch); } } return hr; } // Read/write desktop.ini settings - Unicode (thunking function) HRESULT SHGetSetFolderCustomSettingsW(LPSHFOLDERCUSTOMSETTINGSW pfcsW, LPCWSTR pwszPath, DWORD dwReadWrite) { HRESULT hr = S_OK; if (pfcsW->dwSize >= sizeof(SHFOLDERCUSTOMSETTINGSW) && pwszPath) { TCHAR szPath[MAX_PATH], *pszWebViewTemplate = NULL, *pszWebViewTemplateVersion = NULL; TCHAR *pszInfoTip = NULL, *pszIconFile = NULL, *pszLogo = NULL; SHUnicodeToTChar(pwszPath, szPath, ARRAYSIZE(szPath)); if (dwReadWrite == FCS_WRITE || dwReadWrite == FCS_FORCEWRITE) { if (pfcsW->dwMask & FCSM_WEBVIEWTEMPLATE && pfcsW->pszWebViewTemplate) { hr = SHAllocAndThunkUnicodeToTChar(pfcsW->pszWebViewTemplate, &pszWebViewTemplate, pfcsW->cchWebViewTemplate); if (SUCCEEDED(hr) && pfcsW->pszWebViewTemplateVersion) { hr = SHAllocAndThunkUnicodeToTChar(pfcsW->pszWebViewTemplateVersion, &pszWebViewTemplateVersion, 0); } } if (pfcsW->dwMask & FCSM_INFOTIP && pfcsW->pszInfoTip && SUCCEEDED(hr)) { hr = SHAllocAndThunkUnicodeToTChar(pfcsW->pszInfoTip, &pszInfoTip, pfcsW->cchInfoTip); } if (pfcsW->dwMask & FCSM_ICONFILE && pfcsW->pszIconFile && SUCCEEDED(hr)) { hr = SHAllocAndThunkUnicodeToTChar(pfcsW->pszIconFile, &pszIconFile, pfcsW->cchIconFile); } if (pfcsW->dwMask & FCSM_LOGO && pfcsW->pszLogo && SUCCEEDED(hr)) { hr = SHAllocAndThunkUnicodeToTChar(pfcsW->pszLogo, &pszLogo, pfcsW->cchLogo); } } else if (dwReadWrite == FCS_READ) { if (pfcsW->dwMask & FCSM_WEBVIEWTEMPLATE && pfcsW->pszWebViewTemplate && pfcsW->cchWebViewTemplate > 0) { pszWebViewTemplate = (LPTSTR)LocalAlloc(LPTR, pfcsW->cchWebViewTemplate * sizeof(TCHAR)); if (!pszWebViewTemplate) { hr = E_OUTOFMEMORY; } else { pszWebViewTemplate[0] = 0; if (pfcsW->pszWebViewTemplateVersion) { hr = SHAllocAndThunkUnicodeToTChar(pfcsW->pszWebViewTemplateVersion, &pszWebViewTemplateVersion, 0); } } } if (pfcsW->dwMask & FCSM_INFOTIP && pfcsW->pszInfoTip && pfcsW->cchInfoTip > 0 && SUCCEEDED(hr)) { pszInfoTip = (LPTSTR)LocalAlloc(LPTR, pfcsW->cchInfoTip * sizeof(TCHAR)); if (!pszInfoTip) { hr = E_OUTOFMEMORY; } else { pszInfoTip[0] = 0; } } if (pfcsW->dwMask & FCSM_ICONFILE && pfcsW->pszIconFile && pfcsW->cchIconFile > 0 && SUCCEEDED(hr)) { pszIconFile = (LPTSTR)LocalAlloc(LPTR, pfcsW->cchIconFile * sizeof(TCHAR)); if (!pszIconFile) { hr = E_OUTOFMEMORY; } else { pszIconFile[0] = 0; } } if (pfcsW->dwMask & FCSM_LOGO && pfcsW->pszLogo && pfcsW->cchLogo > 0 && SUCCEEDED(hr)) { pszLogo = (LPTSTR)LocalAlloc(LPTR, pfcsW->cchLogo * sizeof(TCHAR)); if (!pszLogo) { hr = E_OUTOFMEMORY; } else { pszLogo[0] = 0; } } } else { hr = E_INVALIDARG; } if (SUCCEEDED(hr)) { SHFOLDERCUSTOMSETTINGS fcs; fcs.dwSize = sizeof(LPSHFOLDERCUSTOMSETTINGS); fcs.dwMask = pfcsW->dwMask; fcs.pvid = pfcsW->pvid; fcs.pszWebViewTemplate = pszWebViewTemplate; fcs.cchWebViewTemplate = pfcsW->cchWebViewTemplate; fcs.pszWebViewTemplateVersion = pszWebViewTemplateVersion; fcs.pszInfoTip = pszInfoTip; fcs.cchInfoTip = pfcsW->cchInfoTip; fcs.pclsid = pfcsW->pclsid; fcs.dwFlags = pfcsW->dwFlags; fcs.pszIconFile = pszIconFile; fcs.cchIconFile = pfcsW->cchIconFile; fcs.iIconIndex = pfcsW->iIconIndex; fcs.pszLogo = pszLogo; fcs.cchLogo = pfcsW->cchLogo; hr = SHGetSetFCS(&fcs, szPath, dwReadWrite); if (SUCCEEDED(hr)) { if (dwReadWrite == FCS_READ) { if (fcs.dwMask & FCSM_WEBVIEWTEMPLATE && fcs.pszWebViewTemplate) { SHTCharToUnicode(fcs.pszWebViewTemplate, pfcsW->pszWebViewTemplate, pfcsW->cchWebViewTemplate); } if (fcs.dwMask & FCSM_INFOTIP && fcs.pszInfoTip) { SHTCharToUnicode(fcs.pszInfoTip, pfcsW->pszInfoTip, pfcsW->cchInfoTip); } if (fcs.dwMask & FCSM_ICONFILE && fcs.pszIconFile) { SHTCharToUnicode(fcs.pszIconFile, pfcsW->pszIconFile, pfcsW->cchIconFile); } if (fcs.dwMask & FCSM_LOGO && fcs.pszLogo) { SHTCharToUnicode(fcs.pszLogo, pfcsW->pszLogo, pfcsW->cchLogo); } pfcsW->dwFlags = fcs.dwFlags; pfcsW->iIconIndex = fcs.iIconIndex; pfcsW->dwMask = fcs.dwMask; } } } // Free allocated memory if (pszWebViewTemplate) { LocalFree(pszWebViewTemplate); } if (pszWebViewTemplateVersion) { LocalFree(pszWebViewTemplateVersion); } if (pszInfoTip) { LocalFree(pszInfoTip); } if (pszIconFile) { LocalFree(pszIconFile); } if (pszLogo) { LocalFree(pszLogo); } } else { hr = E_INVALIDARG; } return hr; } // Read/write desktop.ini settings - ANSI (thunking function) HRESULT SHGetSetFolderCustomSettingsA(LPSHFOLDERCUSTOMSETTINGSA pfcsA, LPCSTR pszPath, DWORD dwReadWrite) { HRESULT hr = S_OK; if (pfcsA->dwSize >= sizeof(SHFOLDERCUSTOMSETTINGSA) && pszPath) { TCHAR szPath[MAX_PATH], *pszWebViewTemplate = NULL, *pszWebViewTemplateVersion = NULL; TCHAR *pszInfoTip = NULL, *pszIconFile =NULL, *pszLogo = NULL; SHAnsiToTChar(pszPath, szPath, ARRAYSIZE(szPath)); if (dwReadWrite == FCS_WRITE || dwReadWrite == FCS_FORCEWRITE) { if (pfcsA->dwMask & FCSM_WEBVIEWTEMPLATE && pfcsA->pszWebViewTemplate) { hr = SHAllocAndThunkAnsiToTChar(pfcsA->pszWebViewTemplate, &pszWebViewTemplate, pfcsA->cchWebViewTemplate); if (SUCCEEDED(hr) && pfcsA->pszWebViewTemplateVersion) { hr = SHAllocAndThunkAnsiToTChar(pfcsA->pszWebViewTemplateVersion, &pszWebViewTemplateVersion, 0); } } if (pfcsA->dwMask & FCSM_INFOTIP && pfcsA->pszInfoTip && SUCCEEDED(hr)) { hr = SHAllocAndThunkAnsiToTChar(pfcsA->pszInfoTip, &pszInfoTip, pfcsA->cchInfoTip); } if (pfcsA->dwMask & FCSM_ICONFILE && pfcsA->pszIconFile && SUCCEEDED(hr)) { hr = SHAllocAndThunkAnsiToTChar(pfcsA->pszIconFile, &pszIconFile, pfcsA->cchIconFile); } if (pfcsA->dwMask & FCSM_LOGO && pfcsA->pszLogo && SUCCEEDED(hr)) { hr = SHAllocAndThunkAnsiToTChar(pfcsA->pszLogo, &pszLogo, pfcsA->cchLogo); } } else if (dwReadWrite == FCS_READ) { if (pfcsA->dwMask & FCSM_WEBVIEWTEMPLATE && pfcsA->pszWebViewTemplate && pfcsA->cchWebViewTemplate > 0) { pszWebViewTemplate = (LPTSTR)LocalAlloc(LPTR, pfcsA->cchWebViewTemplate * sizeof(TCHAR)); if (!pszWebViewTemplate) { hr = E_OUTOFMEMORY; } else { pszWebViewTemplate[0] = 0; if (pfcsA->pszWebViewTemplateVersion) { hr = SHAllocAndThunkAnsiToTChar(pfcsA->pszWebViewTemplateVersion, &pszWebViewTemplateVersion, 0); } } } if (pfcsA->dwMask & FCSM_INFOTIP && pfcsA->pszInfoTip && pfcsA->cchInfoTip > 0 && SUCCEEDED(hr)) { pszInfoTip = (LPTSTR)LocalAlloc(LPTR, pfcsA->cchInfoTip * sizeof(TCHAR)); if (!pszInfoTip) { hr = E_OUTOFMEMORY; } else { pszInfoTip[0] = 0; } } if (pfcsA->dwMask & FCSM_ICONFILE && pfcsA->pszIconFile && pfcsA->cchIconFile > 0 && SUCCEEDED(hr)) { pszIconFile = (LPTSTR)LocalAlloc(LPTR, pfcsA->cchIconFile * sizeof(TCHAR)); if (!pszIconFile) { hr = E_OUTOFMEMORY; } else { pszIconFile[0] = 0; } } if (pfcsA->dwMask & FCSM_LOGO && pfcsA->pszLogo && pfcsA->cchLogo > 0 && SUCCEEDED(hr)) { pszLogo = (LPTSTR)LocalAlloc(LPTR, pfcsA->cchLogo * sizeof(TCHAR)); if (!pszLogo) { hr = E_OUTOFMEMORY; } else { pszLogo[0] = 0; } } } else { hr = E_INVALIDARG; } if (SUCCEEDED(hr)) { SHFOLDERCUSTOMSETTINGS fcs; fcs.dwSize = sizeof(LPSHFOLDERCUSTOMSETTINGS); fcs.dwMask = pfcsA->dwMask; fcs.pvid = pfcsA->pvid; fcs.pszWebViewTemplate = pszWebViewTemplate; fcs.cchWebViewTemplate = pfcsA->cchWebViewTemplate; fcs.pszWebViewTemplateVersion = pszWebViewTemplateVersion; fcs.pszInfoTip = pszInfoTip; fcs.cchInfoTip = pfcsA->cchInfoTip; fcs.pclsid = pfcsA->pclsid; fcs.dwFlags = pfcsA->dwFlags; fcs.pszIconFile = pszIconFile; fcs.cchIconFile = pfcsA->cchIconFile; fcs.iIconIndex = pfcsA->iIconIndex; fcs.pszLogo = pszLogo; fcs.cchLogo = pfcsA->cchLogo; hr = SHGetSetFCS(&fcs, szPath, dwReadWrite); if (SUCCEEDED(hr)) { if (dwReadWrite == FCS_READ) { if (fcs.dwMask & FCSM_WEBVIEWTEMPLATE && fcs.pszWebViewTemplate) { SHTCharToAnsi(fcs.pszWebViewTemplate, pfcsA->pszWebViewTemplate, pfcsA->cchWebViewTemplate); } if (fcs.dwMask & FCSM_INFOTIP && fcs.pszInfoTip) { SHTCharToAnsi(fcs.pszInfoTip, pfcsA->pszInfoTip, pfcsA->cchInfoTip); } if (fcs.dwMask & FCSM_ICONFILE && fcs.pszIconFile) { SHTCharToAnsi(fcs.pszIconFile, pfcsA->pszIconFile, pfcsA->cchIconFile); } if (fcs.dwMask & FCSM_LOGO && fcs.pszLogo) { SHTCharToAnsi(fcs.pszLogo, pfcsA->pszLogo, pfcsA->cchLogo); } pfcsA->dwFlags = fcs.dwFlags; pfcsA->iIconIndex = fcs.iIconIndex; pfcsA->dwMask = fcs.dwMask; } } } // Free allocated memory if (pszWebViewTemplate) { LocalFree(pszWebViewTemplate); } if (pszWebViewTemplateVersion) { LocalFree(pszWebViewTemplateVersion); } if (pszInfoTip) { LocalFree(pszInfoTip); } if (pszIconFile) { LocalFree(pszIconFile); } if (pszLogo) { LocalFree(pszLogo); } } else { hr = E_INVALIDARG; } return hr; }