1 /* 2 * PROJECT: ReactOS Applications Manager 3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) 4 * PURPOSE: Functions to load / save settings from reg. 5 * COPYRIGHT: Copyright 2020 He Yang (1160386205@qq.com) 6 */ 7 8 #include "rapps.h" 9 #include "settings.h" 10 11 12 class SettingsField 13 { 14 public: 15 virtual ~SettingsField() 16 { 17 ; 18 } 19 virtual BOOL 20 Save(CRegKey &key) = 0; 21 virtual BOOL 22 Load(CRegKey &key) = 0; 23 }; 24 25 class SettingsFieldBool : public SettingsField 26 { 27 public: 28 SettingsFieldBool(BOOL *pValue, LPCWSTR szRegName) : m_pValueStore(pValue), m_RegName(szRegName) 29 { 30 } 31 32 virtual BOOL 33 Save(CRegKey &key) override 34 { 35 return key.SetDWORDValue(m_RegName, (DWORD)(*m_pValueStore)) == ERROR_SUCCESS; 36 } 37 virtual BOOL 38 Load(CRegKey &key) override 39 { 40 DWORD dwField; 41 LONG lResult = key.QueryDWORDValue(m_RegName, dwField); 42 if (lResult != ERROR_SUCCESS) 43 { 44 return FALSE; 45 } 46 *m_pValueStore = (BOOL)dwField; 47 return TRUE; 48 } 49 50 private: 51 BOOL *m_pValueStore; // where to read/store the value 52 LPCWSTR m_RegName; // key name in registery 53 }; 54 55 class SettingsFieldInt : public SettingsField 56 { 57 public: 58 SettingsFieldInt(INT *pValue, LPCWSTR szRegName) : m_pValueStore(pValue), m_RegName(szRegName) 59 { 60 } 61 62 virtual BOOL 63 Save(CRegKey &key) override 64 { 65 return key.SetDWORDValue(m_RegName, (DWORD)(*m_pValueStore)) == ERROR_SUCCESS; 66 } 67 virtual BOOL 68 Load(CRegKey &key) override 69 { 70 DWORD dwField; 71 LONG lResult = key.QueryDWORDValue(m_RegName, dwField); 72 if (lResult != ERROR_SUCCESS) 73 { 74 return FALSE; 75 } 76 *m_pValueStore = (INT)dwField; 77 return TRUE; 78 } 79 80 private: 81 INT *m_pValueStore; // where to read/store the value 82 LPCWSTR m_RegName; // key name in registery 83 }; 84 85 class SettingsFieldString : public SettingsField 86 { 87 public: 88 SettingsFieldString(WCHAR *pString, ULONG cchLen, LPCWSTR szRegName) 89 : m_pStringStore(pString), m_StringLen(cchLen), m_RegName(szRegName) 90 { 91 } 92 93 virtual BOOL 94 Save(CRegKey &key) override 95 { 96 return key.SetStringValue(m_RegName, m_pStringStore) == ERROR_SUCCESS; 97 } 98 virtual BOOL 99 Load(CRegKey &key) override 100 { 101 ULONG nChar = m_StringLen - 1; // make sure the terminating L'\0' 102 LONG lResult = key.QueryStringValue(m_RegName, m_pStringStore, &nChar); 103 return lResult == ERROR_SUCCESS; 104 } 105 106 private: 107 WCHAR *m_pStringStore; // where to read/store the value 108 ULONG m_StringLen; // string length, in chars 109 LPCWSTR m_RegName; // key name in registery 110 }; 111 112 void 113 AddInfoFields(ATL::CAtlList<SettingsField *> &infoFields, SETTINGS_INFO &settings) 114 { 115 infoFields.AddTail(new SettingsFieldBool(&(settings.bSaveWndPos), L"bSaveWndPos")); 116 infoFields.AddTail(new SettingsFieldBool(&(settings.bUpdateAtStart), L"bUpdateAtStart")); 117 infoFields.AddTail(new SettingsFieldBool(&(settings.bLogEnabled), L"bLogEnabled")); 118 infoFields.AddTail(new SettingsFieldString(settings.szDownloadDir, MAX_PATH, L"szDownloadDir")); 119 infoFields.AddTail(new SettingsFieldBool(&(settings.bDelInstaller), L"bDelInstaller")); 120 infoFields.AddTail(new SettingsFieldBool(&(settings.Maximized), L"WindowPosMaximized")); 121 infoFields.AddTail(new SettingsFieldInt(&(settings.Left), L"WindowPosLeft")); 122 infoFields.AddTail(new SettingsFieldInt(&(settings.Top), L"WindowPosTop")); 123 infoFields.AddTail(new SettingsFieldInt(&(settings.Width), L"WindowPosWidth")); 124 infoFields.AddTail(new SettingsFieldInt(&(settings.Height), L"WindowPosHeight")); 125 infoFields.AddTail(new SettingsFieldInt(&(settings.Proxy), L"ProxyMode")); 126 infoFields.AddTail(new SettingsFieldString((settings.szProxyServer), MAX_PATH, L"ProxyServer")); 127 infoFields.AddTail(new SettingsFieldString((settings.szNoProxyFor), MAX_PATH, L"NoProxyFor")); 128 infoFields.AddTail(new SettingsFieldBool(&(settings.bUseSource), L"bUseSource")); 129 infoFields.AddTail(new SettingsFieldString((settings.szSourceURL), INTERNET_MAX_URL_LENGTH, L"SourceURL")); 130 131 return; 132 } 133 134 BOOL 135 SaveAllSettings(CRegKey &key, SETTINGS_INFO &settings) 136 { 137 BOOL bAllSuccess = TRUE; 138 ATL::CAtlList<SettingsField *> infoFields; 139 140 AddInfoFields(infoFields, settings); 141 142 POSITION InfoListPosition = infoFields.GetHeadPosition(); 143 while (InfoListPosition) 144 { 145 SettingsField *Info = infoFields.GetNext(InfoListPosition); 146 if (!Info->Save(key)) 147 { 148 bAllSuccess = FALSE; 149 // TODO: error log 150 } 151 delete Info; 152 } 153 return bAllSuccess; 154 } 155 156 BOOL 157 LoadAllSettings(CRegKey &key, SETTINGS_INFO &settings) 158 { 159 BOOL bAllSuccess = TRUE; 160 ATL::CAtlList<SettingsField *> infoFields; 161 162 AddInfoFields(infoFields, settings); 163 164 POSITION InfoListPosition = infoFields.GetHeadPosition(); 165 while (InfoListPosition) 166 { 167 SettingsField *Info = infoFields.GetNext(InfoListPosition); 168 if (!Info->Load(key)) 169 { 170 bAllSuccess = FALSE; 171 // TODO: error log 172 } 173 delete Info; 174 } 175 return bAllSuccess; 176 } 177 178 VOID 179 FillDefaultSettings(PSETTINGS_INFO pSettingsInfo) 180 { 181 CStringW szDownloadDir; 182 ZeroMemory(pSettingsInfo, sizeof(SETTINGS_INFO)); 183 184 pSettingsInfo->bSaveWndPos = TRUE; 185 pSettingsInfo->bUpdateAtStart = FALSE; 186 pSettingsInfo->bLogEnabled = TRUE; 187 pSettingsInfo->bUseSource = FALSE; 188 189 if (FAILED(SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, szDownloadDir.GetBuffer(MAX_PATH)))) 190 { 191 szDownloadDir.ReleaseBuffer(); 192 if (!szDownloadDir.GetEnvironmentVariableW(L"SystemDrive")) 193 { 194 szDownloadDir = L"C:"; 195 } 196 } 197 else 198 { 199 szDownloadDir.ReleaseBuffer(); 200 } 201 202 PathAppendW(szDownloadDir.GetBuffer(MAX_PATH), L"\\RAPPS Downloads"); 203 szDownloadDir.ReleaseBuffer(); 204 205 CStringW::CopyChars( 206 pSettingsInfo->szDownloadDir, _countof(pSettingsInfo->szDownloadDir), szDownloadDir.GetString(), 207 szDownloadDir.GetLength() + 1); 208 209 pSettingsInfo->bDelInstaller = FALSE; 210 pSettingsInfo->Maximized = FALSE; 211 pSettingsInfo->Left = CW_USEDEFAULT; 212 pSettingsInfo->Top = CW_USEDEFAULT; 213 pSettingsInfo->Width = 680; 214 pSettingsInfo->Height = 450; 215 } 216 217 BOOL 218 LoadSettings(PSETTINGS_INFO pSettingsInfo) 219 { 220 ATL::CRegKey RegKey; 221 if (RegKey.Open(HKEY_CURRENT_USER, L"Software\\ReactOS\\" RAPPS_NAME, KEY_READ) != ERROR_SUCCESS) 222 { 223 return FALSE; 224 } 225 226 return LoadAllSettings(RegKey, *pSettingsInfo); 227 } 228 229 BOOL 230 SaveSettings(HWND hwnd, PSETTINGS_INFO pSettingsInfo) 231 { 232 WINDOWPLACEMENT wp; 233 ATL::CRegKey RegKey; 234 235 if (pSettingsInfo->bSaveWndPos) 236 { 237 wp.length = sizeof(wp); 238 GetWindowPlacement(hwnd, &wp); 239 240 pSettingsInfo->Left = wp.rcNormalPosition.left; 241 pSettingsInfo->Top = wp.rcNormalPosition.top; 242 pSettingsInfo->Width = wp.rcNormalPosition.right - wp.rcNormalPosition.left; 243 pSettingsInfo->Height = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top; 244 pSettingsInfo->Maximized = 245 (wp.showCmd == SW_MAXIMIZE || (wp.showCmd == SW_SHOWMINIMIZED && (wp.flags & WPF_RESTORETOMAXIMIZED))); 246 } 247 248 if (RegKey.Create(HKEY_CURRENT_USER, L"Software\\ReactOS\\" RAPPS_NAME, NULL, 249 REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, NULL) != ERROR_SUCCESS) 250 { 251 return FALSE; 252 } 253 254 return SaveAllSettings(RegKey, *pSettingsInfo); 255 } 256