1 /*
2 * ReactOS Explorer
3 *
4 * Copyright 2009 Andrew Hill <ash77 at domain reactos.org>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "precomp.h"
22
23 #define DEFBROWSERSTREAM L"Settings"
24 #define DEFAULT_VID GUID_NULL // We don't support WebView
25 #define CURRENT_VERSION ( DEFFOLDERSETTINGS::VER_XP )
26
CopyTo(const S & Src,D & Dst)27 template<class S, class D> static void CopyTo(const S &Src, D &Dst)
28 {
29 Dst.FolderSettings = Src.FolderSettings;
30 }
31
EnsureValid(FOLDERSETTINGS & fs)32 static void EnsureValid(FOLDERSETTINGS &fs)
33 {
34 if ((int)fs.ViewMode < FVM_AUTO || (int)fs.ViewMode > FVM_LAST)
35 fs.ViewMode = SBFOLDERSETTINGS::DEF_FVM;
36
37 fs.fFlags &= ~(FWF_OWNERDATA | FWF_DESKTOP | FWF_TRANSPARENT | FWF_NOCLIENTEDGE |
38 FWF_NOSUBFOLDERS | FWF_NOSCROLL | FWF_NOENUMREFRESH | FWF_NOVISIBLE);
39 }
40
EnsureValid(DEFFOLDERSETTINGS & dfs)41 static void EnsureValid(DEFFOLDERSETTINGS &dfs)
42 {
43 EnsureValid(dfs.FolderSettings);
44 }
45
InitializeDefaults(DEFFOLDERSETTINGS & dfs)46 static void InitializeDefaults(DEFFOLDERSETTINGS &dfs)
47 {
48 C_ASSERT(FIELD_OFFSET(DEFFOLDERSETTINGS, FolderSettings) == 4);
49 C_ASSERT(FIELD_OFFSET(DEFFOLDERSETTINGS, ViewPriority) == DEFFOLDERSETTINGS::SIZE_IE4);
50 C_ASSERT(sizeof(DEFFOLDERSETTINGS) == DEFFOLDERSETTINGS::SIZE_XP);
51
52 *(UINT*)&dfs = FALSE; // Set all unknown flags to FALSE
53 dfs.Statusbar = TRUE;
54 dfs.FolderSettings.ViewMode = SBFOLDERSETTINGS::DEF_FVM;
55 dfs.FolderSettings.fFlags = SBFOLDERSETTINGS::DEF_FWF;
56 dfs.vid = DEFAULT_VID;
57 dfs.Version = CURRENT_VERSION;
58 dfs.Counter = 0;
59 dfs.ViewPriority = VIEW_PRIORITY_CACHEMISS;
60 }
61
Load()62 void SBFOLDERSETTINGS::Load()
63 {
64 DEFFOLDERSETTINGS dfs;
65 CGlobalFolderSettings::Load(dfs);
66 CopyTo(dfs, *this);
67 }
68
CGlobalFolderSettings()69 CGlobalFolderSettings::CGlobalFolderSettings()
70 {
71 }
72
~CGlobalFolderSettings()73 CGlobalFolderSettings::~CGlobalFolderSettings()
74 {
75 }
76
ResetBrowserSettings()77 HRESULT CGlobalFolderSettings::ResetBrowserSettings()
78 {
79 return Save(NULL);
80 }
81
SaveBrowserSettings(const SBFOLDERSETTINGS & sbfs)82 HRESULT CGlobalFolderSettings::SaveBrowserSettings(const SBFOLDERSETTINGS &sbfs)
83 {
84 DEFFOLDERSETTINGS dfs;
85 InitializeDefaults(dfs);
86 CopyTo(sbfs, dfs);
87 return Save(&dfs);
88 }
89
Load(DEFFOLDERSETTINGS & dfs)90 HRESULT CGlobalFolderSettings::Load(DEFFOLDERSETTINGS &dfs)
91 {
92 HKEY hStreamsKey = SHGetShellKey(SHKEY_Key_Explorer, L"Streams", FALSE);
93 if (hStreamsKey)
94 {
95 DWORD cb = sizeof(DEFFOLDERSETTINGS);
96 DWORD err = SHRegGetValueW(hStreamsKey, NULL, DEFBROWSERSTREAM,
97 SRRF_RT_REG_BINARY, NULL, &dfs, &cb);
98 RegCloseKey(hStreamsKey);
99 if (!err && cb >= DEFFOLDERSETTINGS::SIZE_NT4)
100 {
101 if (cb < FIELD_OFFSET(DEFFOLDERSETTINGS, vid))
102 {
103 dfs.FolderSettings.fFlags = SBFOLDERSETTINGS::DEF_FWF;
104 }
105 if (cb < FIELD_OFFSET(DEFFOLDERSETTINGS, Version))
106 {
107 dfs.vid = DEFAULT_VID;
108 }
109 if (cb <= FIELD_OFFSET(DEFFOLDERSETTINGS, ViewPriority))
110 {
111 dfs.Version = CURRENT_VERSION;
112 }
113 dfs.ViewPriority = VIEW_PRIORITY_STALECACHEHIT;
114 EnsureValid(dfs);
115 return S_OK;
116 }
117 }
118 InitializeDefaults(dfs);
119 return S_FALSE;
120 }
121
Save(const DEFFOLDERSETTINGS * pFDS)122 HRESULT CGlobalFolderSettings::Save(const DEFFOLDERSETTINGS *pFDS)
123 {
124 HKEY hStreamsKey = SHGetShellKey(SHKEY_Key_Explorer, L"Streams", TRUE);
125 if (!hStreamsKey)
126 return E_FAIL;
127
128 HRESULT hr = E_INVALIDARG;
129 if (!pFDS)
130 {
131 DWORD err = SHDeleteValueW(hStreamsKey, NULL, DEFBROWSERSTREAM);
132 hr = (!err || err == ERROR_FILE_NOT_FOUND) ? S_OK : HResultFromWin32(err);
133 }
134 else
135 {
136 DWORD cb = sizeof(DEFFOLDERSETTINGS);
137 hr = HResultFromWin32(SHSetValueW(hStreamsKey, NULL, DEFBROWSERSTREAM, REG_BINARY, pFDS, cb));
138 }
139 RegCloseKey(hStreamsKey);
140 return hr;
141 }
142
Get(struct DEFFOLDERSETTINGS * pFDS,UINT cb)143 HRESULT STDMETHODCALLTYPE CGlobalFolderSettings::Get(struct DEFFOLDERSETTINGS *pFDS, UINT cb)
144 {
145 if (cb != sizeof(DEFFOLDERSETTINGS) || !pFDS)
146 return E_INVALIDARG;
147 return Load(*pFDS);
148 }
149
Set(const struct DEFFOLDERSETTINGS * pFDS,UINT cb,UINT unknown)150 HRESULT STDMETHODCALLTYPE CGlobalFolderSettings::Set(const struct DEFFOLDERSETTINGS *pFDS, UINT cb, UINT unknown)
151 {
152 // NULL pFDS means reset
153 if (cb != sizeof(DEFFOLDERSETTINGS) && pFDS)
154 return E_INVALIDARG;
155 return Save(pFDS);
156 }
157