blob: f3c2ef019746156944f71e50487df05e85a7e350 [file] [log] [blame]
Dimitrie O. Paun82ce2cc2003-03-31 19:41:55 +00001/*
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 Davison5101dfc2003-04-27 00:33:07 +000026#include <winreg.h>
27#include <wine/debug.h>
28
29WINE_DEFAULT_DEBUG_CHANNEL(winecfg);
Dimitrie O. Paun82ce2cc2003-03-31 19:41:55 +000030
31#include "winecfg.h"
32
33
34/*****************************************************************************
35 */
36WINECFG_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
50fail:
51 /* FIXME: do something nice */
52 printf("Out of memory");
53 exit(1);
54}
55
56
57/*****************************************************************************
58 */
59int 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 Hearn4e1afc62003-08-30 00:27:08 +000077 * 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 Davison5101dfc2003-04-27 00:33:07 +000088 */
Mike Hearn4e1afc62003-08-30 00:27:08 +000089int getConfigValue (HKEY hCurrent, char *subkey, char *valueName, char *retVal, int length, char *defaultResult)
Matthew Davison5101dfc2003-04-27 00:33:07 +000090{
Mike Hearn4e1afc62003-08-30 00:27:08 +000091 CHAR *buffer;
92 DWORD dataLength;
93 HKEY hSubKey = NULL;
94 DWORD res = 1; /* assume failure */
Matthew Davison5101dfc2003-04-27 00:33:07 +000095
Mike Hearn4e1afc62003-08-30 00:27:08 +000096 WINE_TRACE("subkey=%s, valueName=%s, defaultResult=%s\n", subkey, valueName, defaultResult);
97
Matthew Davison5101dfc2003-04-27 00:33:07 +000098 if( (res=RegOpenKeyEx( hCurrent, subkey, 0, KEY_ALL_ACCESS, &hSubKey ))
99 !=ERROR_SUCCESS )
100 {
101 if( res==ERROR_FILE_NOT_FOUND )
102 {
Mike Hearn4e1afc62003-08-30 00:27:08 +0000103 WINE_TRACE("Section key not present - using default\n");
104 strncpy(retVal, defaultResult, length);
Matthew Davison5101dfc2003-04-27 00:33:07 +0000105 }
106 else
107 {
Mike Hearn4e1afc62003-08-30 00:27:08 +0000108 WINE_ERR("RegOpenKey failed on wine config key (res=%ld)\n", res);
Matthew Davison5101dfc2003-04-27 00:33:07 +0000109 }
110 goto end;
111 }
Mike Hearn4e1afc62003-08-30 00:27:08 +0000112
Matthew Davison5101dfc2003-04-27 00:33:07 +0000113 res = RegQueryValueExA( hSubKey, valueName, NULL, NULL, NULL, &dataLength);
Mike Hearn4e1afc62003-08-30 00:27:08 +0000114 if( res == ERROR_FILE_NOT_FOUND )
Matthew Davison5101dfc2003-04-27 00:33:07 +0000115 {
116 WINE_TRACE("Value not present - using default\n");
Mike Hearn4e1afc62003-08-30 00:27:08 +0000117 strncpy(retVal, defaultResult, length);
Matthew Davison5101dfc2003-04-27 00:33:07 +0000118 goto end;
119 }
120
121 if( res!=ERROR_SUCCESS )
122 {
Mike Hearn4e1afc62003-08-30 00:27:08 +0000123 WINE_ERR("Couldn't query value's length (res=%ld)\n", res );
Matthew Davison5101dfc2003-04-27 00:33:07 +0000124 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 Davison5101dfc2003-04-27 00:33:07 +0000131 goto end;
132 }
133
Mike Hearn4e1afc62003-08-30 00:27:08 +0000134 RegQueryValueEx(hSubKey, valueName, NULL, NULL, (LPBYTE)buffer, &dataLength);
135 strncpy(retVal, buffer, length);
Matthew Davison5101dfc2003-04-27 00:33:07 +0000136 free(buffer);
Mike Hearn4e1afc62003-08-30 00:27:08 +0000137 res = 0;
Matthew Davison5101dfc2003-04-27 00:33:07 +0000138
139end:
Mike Hearn4e1afc62003-08-30 00:27:08 +0000140 if( hSubKey!=NULL )
Matthew Davison5101dfc2003-04-27 00:33:07 +0000141 RegCloseKey( hSubKey );
142
143 return res;
144
145}
146
147/*****************************************************************************
Mike Hearn4e1afc62003-08-30 00:27:08 +0000148 * 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 */
158int 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;
171end:
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. Paun82ce2cc2003-03-31 19:41:55 +0000179 * 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 */
188int loadConfig (WINECFG_DESC* pCfg)
189{
190 const DLL_DESC *pDllDefaults;
Matthew Davison5101dfc2003-04-27 00:33:07 +0000191
192 HKEY hSession=NULL;
193 DWORD res;
Dimitrie O. Paun82ce2cc2003-03-31 19:41:55 +0000194
Mike Hearn4e1afc62003-08-30 00:27:08 +0000195 WINE_TRACE("\n");
196
197 res = RegCreateKey(HKEY_LOCAL_MACHINE, WINE_KEY_ROOT, &hSession);
198 if (res != ERROR_SUCCESS)
Matthew Davison5101dfc2003-04-27 00:33:07 +0000199 {
Mike Hearn4e1afc62003-08-30 00:27:08 +0000200 WINE_ERR("RegOpenKey failed on wine config key (%ld)\n", res);
201 return -1;
Matthew Davison5101dfc2003-04-27 00:33:07 +0000202 }
Mike Hearn4e1afc62003-08-30 00:27:08 +0000203
Matthew Davison5101dfc2003-04-27 00:33:07 +0000204 /* Windows and DOS versions */
Mike Hearn4e1afc62003-08-30 00:27:08 +0000205 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. Paun82ce2cc2003-03-31 19:41:55 +0000208
Matthew Davison5101dfc2003-04-27 00:33:07 +0000209 /* System Paths */
Mike Hearn4e1afc62003-08-30 00:27:08 +0000210 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. Paun82ce2cc2003-03-31 19:41:55 +0000215
Matthew Davison5101dfc2003-04-27 00:33:07 +0000216 /* Graphics driver */
Mike Hearn4e1afc62003-08-30 00:27:08 +0000217 getConfigValue(hSession, "Wine", "GraphicsDriver", pCfg->szGraphDriver, MAX_NAME_LENGTH, "x11drv");
Matthew Davison5101dfc2003-04-27 00:33:07 +0000218
Dimitrie O. Paun82ce2cc2003-03-31 19:41:55 +0000219 /*
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. Paun82ce2cc2003-03-31 19:41:55 +0000249 pCfg->sX11Drv.nXVidMode = 1;
250 pCfg->sX11Drv.nTakeFocus = 1;
251 pCfg->sX11Drv.nDXGrab = 0;
252 pCfg->sX11Drv.nDoubleBuffered = 0;
Dimitrie O. Paun82ce2cc2003-03-31 19:41:55 +0000253 pCfg->sX11Drv.nSynchronous = 1;
Matthew Davison5101dfc2003-04-27 00:33:07 +0000254
255 RegCloseKey( hSession );
Dimitrie O. Paun82ce2cc2003-03-31 19:41:55 +0000256
257 return 0;
258}
259
Dimitrie O. Paun82ce2cc2003-03-31 19:41:55 +0000260/*****************************************************************************
Mike Hearn4e1afc62003-08-30 00:27:08 +0000261 * saveConfig : Stores the configuration structure
262 *
Dimitrie O. Paun82ce2cc2003-03-31 19:41:55 +0000263 * 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 */
268int saveConfig (const WINECFG_DESC* pCfg)
269{
Mike Hearn4e1afc62003-08-30 00:27:08 +0000270 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. Paun82ce2cc2003-03-31 19:41:55 +0000285 return 0;
286}