Dimitrie O. Paun | 82ce2cc | 2003-03-31 19:41:55 +0000 | [diff] [blame] | 1 | /* |
| 2 | * WineCfg configuration management |
| 3 | * |
| 4 | * Copyright 2002 Jaco Greeff |
| 5 | * Copyright 2003 Dimitrie O. Paun |
| 6 | * |
| 7 | * This library is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU Lesser General Public |
| 9 | * License as published by the Free Software Foundation; either |
| 10 | * version 2.1 of the License, or (at your option) any later version. |
| 11 | * |
| 12 | * This library is distributed in the hope that it will be useful, |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | * Lesser General Public License for more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU Lesser General Public |
| 18 | * License along with this library; if not, write to the Free Software |
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 20 | * |
| 21 | */ |
| 22 | |
| 23 | #include <stdio.h> |
| 24 | #include <limits.h> |
| 25 | #include <windows.h> |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 26 | #include <winreg.h> |
| 27 | #include <wine/debug.h> |
| 28 | |
| 29 | WINE_DEFAULT_DEBUG_CHANNEL(winecfg); |
Dimitrie O. Paun | 82ce2cc | 2003-03-31 19:41:55 +0000 | [diff] [blame] | 30 | |
| 31 | #include "winecfg.h" |
| 32 | |
| 33 | |
| 34 | /***************************************************************************** |
| 35 | */ |
| 36 | WINECFG_DESC* allocConfig(void) |
| 37 | { |
| 38 | WINECFG_DESC* pWineCfg = malloc (sizeof (WINECFG_DESC)); |
| 39 | |
| 40 | if (!pWineCfg) goto fail; |
| 41 | ZeroMemory(pWineCfg, sizeof(*pWineCfg)); |
| 42 | |
| 43 | pWineCfg->pDlls = DPA_Create(100); |
| 44 | if (!pWineCfg->pDlls) goto fail; |
| 45 | pWineCfg->pApps = DPA_Create(100); |
| 46 | if (!pWineCfg->pApps) goto fail; |
| 47 | |
| 48 | return pWineCfg; |
| 49 | |
| 50 | fail: |
| 51 | /* FIXME: do something nice */ |
| 52 | printf("Out of memory"); |
| 53 | exit(1); |
| 54 | } |
| 55 | |
| 56 | |
| 57 | /***************************************************************************** |
| 58 | */ |
| 59 | int freeConfig (WINECFG_DESC* pCfg) |
| 60 | { |
| 61 | int i; |
| 62 | |
| 63 | for (i = 0; i < pCfg->pDlls->nItemCount; i++) |
| 64 | free (DPA_GetPtr(pCfg->pDlls, i)); |
| 65 | DPA_Destroy(pCfg->pDlls); |
| 66 | |
| 67 | for (i = 0; i < pCfg->pApps->nItemCount; i++) |
| 68 | free (DPA_GetPtr(pCfg->pApps, i)); |
| 69 | DPA_Destroy(pCfg->pApps); |
| 70 | |
| 71 | free (pCfg); |
| 72 | |
| 73 | return 0; |
| 74 | } |
| 75 | |
| 76 | /***************************************************************************** |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 77 | * getConfigValue: Retrieves a configuration value from the registry |
| 78 | * |
| 79 | * HKEY hCurrent : the registry key that the configuration is rooted at |
| 80 | * char *subKey : the name of the config section |
| 81 | * char *valueName : the name of the config value |
| 82 | * char *retVal : pointer to the start of a buffer that has room for >= length chars |
| 83 | * int length : length of the buffer pointed to by retVal |
| 84 | * char *defaultResult : if the key isn't found, return this value instead |
| 85 | * |
| 86 | * Returns 0 upon success, non-zero otherwise |
| 87 | * |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 88 | */ |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 89 | int getConfigValue (HKEY hCurrent, char *subkey, char *valueName, char *retVal, int length, char *defaultResult) |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 90 | { |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 91 | CHAR *buffer; |
| 92 | DWORD dataLength; |
| 93 | HKEY hSubKey = NULL; |
| 94 | DWORD res = 1; /* assume failure */ |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 95 | |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 96 | WINE_TRACE("subkey=%s, valueName=%s, defaultResult=%s\n", subkey, valueName, defaultResult); |
| 97 | |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 98 | if( (res=RegOpenKeyEx( hCurrent, subkey, 0, KEY_ALL_ACCESS, &hSubKey )) |
| 99 | !=ERROR_SUCCESS ) |
| 100 | { |
| 101 | if( res==ERROR_FILE_NOT_FOUND ) |
| 102 | { |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 103 | WINE_TRACE("Section key not present - using default\n"); |
| 104 | strncpy(retVal, defaultResult, length); |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 105 | } |
| 106 | else |
| 107 | { |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 108 | WINE_ERR("RegOpenKey failed on wine config key (res=%ld)\n", res); |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 109 | } |
| 110 | goto end; |
| 111 | } |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 112 | |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 113 | res = RegQueryValueExA( hSubKey, valueName, NULL, NULL, NULL, &dataLength); |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 114 | if( res == ERROR_FILE_NOT_FOUND ) |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 115 | { |
| 116 | WINE_TRACE("Value not present - using default\n"); |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 117 | strncpy(retVal, defaultResult, length); |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 118 | goto end; |
| 119 | } |
| 120 | |
| 121 | if( res!=ERROR_SUCCESS ) |
| 122 | { |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 123 | WINE_ERR("Couldn't query value's length (res=%ld)\n", res ); |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 124 | goto end; |
| 125 | } |
| 126 | |
| 127 | buffer=malloc( dataLength ); |
| 128 | if( buffer==NULL ) |
| 129 | { |
| 130 | WINE_ERR("Couldn't allocate %lu bytes for the value\n", dataLength ); |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 131 | goto end; |
| 132 | } |
| 133 | |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 134 | RegQueryValueEx(hSubKey, valueName, NULL, NULL, (LPBYTE)buffer, &dataLength); |
| 135 | strncpy(retVal, buffer, length); |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 136 | free(buffer); |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 137 | res = 0; |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 138 | |
| 139 | end: |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 140 | if( hSubKey!=NULL ) |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 141 | RegCloseKey( hSubKey ); |
| 142 | |
| 143 | return res; |
| 144 | |
| 145 | } |
| 146 | |
| 147 | /***************************************************************************** |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 148 | * setConfigValue : Sets a configuration key in the registry |
| 149 | * |
| 150 | * HKEY hCurrent : the registry key that the configuration is rooted at |
| 151 | * char *subKey : the name of the config section |
| 152 | * char *valueName : the name of the config value |
| 153 | * char *value : the value to set the configuration key to |
| 154 | * |
| 155 | * Returns 0 on success, non-zero otherwise |
| 156 | * |
| 157 | */ |
| 158 | int setConfigValue (HKEY hCurrent, char *subkey, char *valueName, const char *value) { |
| 159 | DWORD res = 1; |
| 160 | HKEY key = NULL; |
| 161 | |
| 162 | WINE_TRACE("subkey=%s, valueName=%s, value=%s\n", subkey, valueName, value); |
| 163 | |
| 164 | res = RegCreateKey(hCurrent, subkey, &key); |
| 165 | if (res != ERROR_SUCCESS) goto end; |
| 166 | |
| 167 | res = RegSetValueEx(key, valueName, 0, REG_SZ, value, strlen(value) + 1); |
| 168 | if (res != ERROR_SUCCESS) goto end; |
| 169 | |
| 170 | res = 0; |
| 171 | end: |
| 172 | if (key) RegCloseKey(key); |
| 173 | if (res != 0) WINE_ERR("Unable to set configuration key %s in section %s to %s, res=%ld\n", valueName, subkey, value, res); |
| 174 | return res; |
| 175 | } |
| 176 | |
| 177 | |
| 178 | /***************************************************************************** |
Dimitrie O. Paun | 82ce2cc | 2003-03-31 19:41:55 +0000 | [diff] [blame] | 179 | * Name : loadConfig |
| 180 | * Description: Loads and populates a configuration structure |
| 181 | * Parameters : pCfg |
| 182 | * Returns : 0 on success, -1 otherwise |
| 183 | * |
| 184 | * FIXME: We are supposed to load these values from the registry. |
| 185 | * This is not active yet, so just setup some (hopefully) |
| 186 | * sane defaults |
| 187 | */ |
| 188 | int loadConfig (WINECFG_DESC* pCfg) |
| 189 | { |
| 190 | const DLL_DESC *pDllDefaults; |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 191 | |
| 192 | HKEY hSession=NULL; |
| 193 | DWORD res; |
Dimitrie O. Paun | 82ce2cc | 2003-03-31 19:41:55 +0000 | [diff] [blame] | 194 | |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 195 | WINE_TRACE("\n"); |
| 196 | |
| 197 | res = RegCreateKey(HKEY_LOCAL_MACHINE, WINE_KEY_ROOT, &hSession); |
| 198 | if (res != ERROR_SUCCESS) |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 199 | { |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 200 | WINE_ERR("RegOpenKey failed on wine config key (%ld)\n", res); |
| 201 | return -1; |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 202 | } |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 203 | |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 204 | /* Windows and DOS versions */ |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 205 | getConfigValue(hSession, "Version", "Windows", pCfg->szWinVer, MAX_VERSION_LENGTH, "win95"); |
| 206 | getConfigValue(hSession, "Version", "DOS", pCfg->szDOSVer, MAX_VERSION_LENGTH, "6.22"); |
| 207 | getConfigValue(hSession, "Tweak.Layout", "WineLook", pCfg->szWinLook, MAX_VERSION_LENGTH, "win95"); |
Dimitrie O. Paun | 82ce2cc | 2003-03-31 19:41:55 +0000 | [diff] [blame] | 208 | |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 209 | /* System Paths */ |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 210 | getConfigValue(hSession, "Wine", "Windows", pCfg->szWinDir, MAX_PATH, "c:\\Windows"); |
| 211 | getConfigValue(hSession, "Wine", "System", pCfg->szWinSysDir, MAX_PATH, "c:\\Windows\\System"); |
| 212 | getConfigValue(hSession, "Wine", "Temp", pCfg->szWinTmpDir, MAX_PATH, "c:\\Windows\\Temp"); |
| 213 | getConfigValue(hSession, "Wine", "Profile", pCfg->szWinProfDir, MAX_PATH, "c:\\Windows\\Profiles\\Administrator"); |
| 214 | getConfigValue(hSession, "Wine", "Path", pCfg->szWinPath, MAX_PATH, "c:\\Windows;c:\\Windows\\System"); |
Dimitrie O. Paun | 82ce2cc | 2003-03-31 19:41:55 +0000 | [diff] [blame] | 215 | |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 216 | /* Graphics driver */ |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 217 | getConfigValue(hSession, "Wine", "GraphicsDriver", pCfg->szGraphDriver, MAX_NAME_LENGTH, "x11drv"); |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 218 | |
Dimitrie O. Paun | 82ce2cc | 2003-03-31 19:41:55 +0000 | [diff] [blame] | 219 | /* |
| 220 | * DLL defaults for all applications is built using |
| 221 | * the default DLL structure |
| 222 | */ |
| 223 | for (pDllDefaults = getDLLDefaults (); *pDllDefaults->szName; pDllDefaults++) |
| 224 | { |
| 225 | DLL_DESC *pDll = malloc(sizeof(DLL_DESC)); |
| 226 | memcpy (pDll, pDllDefaults, sizeof(DLL_DESC)); |
| 227 | DPA_InsertPtr(pCfg->pDlls, INT_MAX, pDll); |
| 228 | } |
| 229 | |
| 230 | /* |
| 231 | * Application defaults on a per application |
| 232 | * level (if not set, this defaults to what |
| 233 | * is already there) |
| 234 | */ |
| 235 | /* FIXME: TODO */ |
| 236 | |
| 237 | /* |
| 238 | * X11Drv defaults |
| 239 | */ |
| 240 | strcpy(pCfg->sX11Drv.szX11Display, ":0.0"); |
| 241 | pCfg->sX11Drv.nSysColors = 100; |
| 242 | pCfg->sX11Drv.nPrivateMap = 0; |
| 243 | pCfg->sX11Drv.nPerfect = 0; |
| 244 | pCfg->sX11Drv.nDepth = 16; |
| 245 | pCfg->sX11Drv.nManaged = 1; |
| 246 | pCfg->sX11Drv.nDesktopSizeX = 640; |
| 247 | pCfg->sX11Drv.nDesktopSizeY = 480; |
| 248 | pCfg->sX11Drv.nDGA = 1; |
Dimitrie O. Paun | 82ce2cc | 2003-03-31 19:41:55 +0000 | [diff] [blame] | 249 | pCfg->sX11Drv.nXVidMode = 1; |
| 250 | pCfg->sX11Drv.nTakeFocus = 1; |
| 251 | pCfg->sX11Drv.nDXGrab = 0; |
| 252 | pCfg->sX11Drv.nDoubleBuffered = 0; |
Dimitrie O. Paun | 82ce2cc | 2003-03-31 19:41:55 +0000 | [diff] [blame] | 253 | pCfg->sX11Drv.nSynchronous = 1; |
Matthew Davison | 5101dfc | 2003-04-27 00:33:07 +0000 | [diff] [blame] | 254 | |
| 255 | RegCloseKey( hSession ); |
Dimitrie O. Paun | 82ce2cc | 2003-03-31 19:41:55 +0000 | [diff] [blame] | 256 | |
| 257 | return 0; |
| 258 | } |
| 259 | |
Dimitrie O. Paun | 82ce2cc | 2003-03-31 19:41:55 +0000 | [diff] [blame] | 260 | /***************************************************************************** |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 261 | * saveConfig : Stores the configuration structure |
| 262 | * |
Dimitrie O. Paun | 82ce2cc | 2003-03-31 19:41:55 +0000 | [diff] [blame] | 263 | * Returns : 0 on success, -1 otherwise |
| 264 | * |
| 265 | * FIXME: This is where we are to write the changes to the registry. |
| 266 | * This is not setup yet, so do nothing and say ok. |
| 267 | */ |
| 268 | int saveConfig (const WINECFG_DESC* pCfg) |
| 269 | { |
Mike Hearn | 4e1afc6 | 2003-08-30 00:27:08 +0000 | [diff] [blame^] | 270 | HKEY key; |
| 271 | DWORD res; |
| 272 | |
| 273 | WINE_TRACE("\n"); |
| 274 | |
| 275 | res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WINE_KEY_ROOT, 0, KEY_ALL_ACCESS, &key); |
| 276 | if (res != ERROR_SUCCESS) { |
| 277 | WINE_ERR("Failed to open Wine config registry branch, res=%ld\n", res); |
| 278 | return -1; |
| 279 | } |
| 280 | |
| 281 | /* Windows and DOS versions */ |
| 282 | setConfigValue(key, "Version", "Windows", pCfg->szWinVer); |
| 283 | |
| 284 | WINE_FIXME("We don't write out the entire configuration yet\n"); |
Dimitrie O. Paun | 82ce2cc | 2003-03-31 19:41:55 +0000 | [diff] [blame] | 285 | return 0; |
| 286 | } |