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