OSDN Git Service

* errno.cc (errmap): Handle ERROR_IO_PENDING.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / registry.cc
1 /* registry.cc: registry interface
2
3    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
4
5 This file is part of Cygwin.
6
7 This software is a copyrighted work licensed under the terms of the
8 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
9 details. */
10
11 #include "winsup.h"
12 #include "shared_info.h"
13 #include "registry.h"
14 #include "security.h"
15 #include <cygwin/version.h>
16
17 static char NO_COPY cygnus_class[] = "cygnus";
18
19 reg_key::reg_key (HKEY top, REGSAM access, ...)
20 {
21   va_list av;
22   va_start (av, access);
23   build_reg (top, access, av);
24   va_end (av);
25 }
26
27 reg_key::reg_key (REGSAM access, ...)
28 {
29   va_list av;
30
31   new (this) reg_key (HKEY_CURRENT_USER, access, "SOFTWARE",
32                  CYGWIN_INFO_CYGNUS_REGISTRY_NAME,
33                  CYGWIN_INFO_CYGWIN_REGISTRY_NAME, NULL);
34
35   HKEY top = key;
36   va_start (av, access);
37   build_reg (top, KEY_READ, av);
38   va_end (av);
39   if (top != key)
40     RegCloseKey (top);
41 }
42
43 reg_key::reg_key (REGSAM access)
44 {
45   new (this) reg_key (HKEY_CURRENT_USER, access, "SOFTWARE",
46                  CYGWIN_INFO_CYGNUS_REGISTRY_NAME,
47                  CYGWIN_INFO_CYGWIN_REGISTRY_NAME,
48                  CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME, NULL);
49 }
50
51 void
52 reg_key::build_reg (HKEY top, REGSAM access, va_list av)
53 {
54   char *name;
55   HKEY r = top;
56   key_is_invalid = 0;
57
58   /* FIXME: Most of the time a valid mount area should exist.  Perhaps
59      we should just try an open of the correct key first and only resort
60      to this method in the unlikely situation that it's the first time
61      the current mount areas are being used. */
62
63   while ((name = va_arg (av, char *)) != NULL)
64     {
65       DWORD disp;
66       int res = RegCreateKeyExA (r,
67                                  name,
68                                  0,
69                                  cygnus_class,
70                                  REG_OPTION_NON_VOLATILE,
71                                  access,
72                                  &sec_none_nih,
73                                  &key,
74                                  &disp);
75       if (r != top)
76         RegCloseKey (r);
77       r = key;
78       if (res != ERROR_SUCCESS)
79         {
80           key_is_invalid = res;
81           debug_printf ("failed to create key %s in the registry", name);
82           break;
83         }
84
85       /* If we're considering the mounts key, check if it had to
86          be created and set had_to_create appropriately. */
87       if (strcmp (name, CYGWIN_INFO_CYGWIN_MOUNT_REGISTRY_NAME) == 0)
88         if (disp == REG_CREATED_NEW_KEY)
89           mount_table->had_to_create_mount_areas++;
90     }
91 }
92
93 /* Given the current registry key, return the specific int value
94    requested.  Return def on failure. */
95
96 int
97 reg_key::get_int (const char *name, int def)
98 {
99   DWORD type;
100   DWORD dst;
101   DWORD size = sizeof (dst);
102
103   if (key_is_invalid)
104     return def;
105
106   LONG res = RegQueryValueExA (key, name, 0, &type, (unsigned char *) &dst,
107                                &size);
108
109   if (type != REG_DWORD || res != ERROR_SUCCESS)
110     return def;
111
112   return dst;
113 }
114
115 /* Given the current registry key, set a specific int value. */
116
117 int
118 reg_key::set_int (const char *name, int val)
119 {
120   DWORD value = val;
121   if (key_is_invalid)
122     return key_is_invalid;
123
124   return (int) RegSetValueExA (key, name, 0, REG_DWORD,
125                                (unsigned char *) &value, sizeof (value));
126 }
127
128 /* Given the current registry key, return the specific string value
129    requested.  Return zero on success, non-zero on failure. */
130
131 int
132 reg_key::get_string (const char *name, char *dst, size_t max, const char * def)
133 {
134   DWORD size = max;
135   DWORD type;
136   LONG res;
137
138   if (key_is_invalid)
139     res = key_is_invalid;
140   else
141     res = RegQueryValueExA (key, name, 0, &type, (unsigned char *) dst, &size);
142
143   if ((def != 0) && ((type != REG_SZ) || (res != ERROR_SUCCESS)))
144     strcpy (dst, def);
145   return (int) res;
146 }
147
148 /* Given the current registry key, set a specific string value. */
149
150 int
151 reg_key::set_string (const char *name, const char *src)
152 {
153   if (key_is_invalid)
154     return key_is_invalid;
155   return (int) RegSetValueExA (key, name, 0, REG_SZ, (unsigned char*) src,
156                                strlen (src) + 1);
157 }
158
159 /* Return the handle to key. */
160
161 HKEY
162 reg_key::get_key ()
163 {
164   return key;
165 }
166
167 /* Delete subkey of current key.  Returns the error code from the
168    RegDeleteKeyA invocation. */
169
170 int
171 reg_key::kill (const char *name)
172 {
173   if (key_is_invalid)
174     return key_is_invalid;
175   return RegDeleteKeyA (key, name);
176 }
177
178 /* Delete the value specified by name of current key.  Returns the error code
179    from the RegDeleteValueA invocation. */
180
181 int
182 reg_key::killvalue (const char *name)
183 {
184   if (key_is_invalid)
185     return key_is_invalid;
186   return RegDeleteValueA (key, name);
187 }
188
189 reg_key::~reg_key ()
190 {
191   if (!key_is_invalid)
192     RegCloseKey (key);
193   key_is_invalid = 1;
194 }
195
196 char *
197 get_registry_hive_path (const PSID psid, char *path)
198 {
199   char sid[256];
200   char key[256];
201   HKEY hkey;
202
203   if (!psid || !path)
204     return NULL;
205   cygpsid csid (psid);
206   csid.string (sid);
207   strcpy (key,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\");
208   strcat (key, sid);
209   if (!RegOpenKeyExA (HKEY_LOCAL_MACHINE, key, 0, KEY_READ, &hkey))
210     {
211       char buf[256];
212       DWORD type, siz;
213
214       key[0] = '\0';
215       if (!RegQueryValueExA (hkey, "ProfileImagePath", 0, &type,
216                              (BYTE *)buf, (siz = 256, &siz)))
217         ExpandEnvironmentStringsA (buf, key, 256);
218       RegCloseKey (hkey);
219       if (key[0])
220         return strcpy (path, key);
221     }
222   return NULL;
223 }
224
225 void
226 load_registry_hive (PSID psid)
227 {
228   char sid[256];
229   char path[CYG_MAX_PATH + 1];
230   HKEY hkey;
231   LONG ret;
232
233   if (!psid)
234     return;
235   /* Check if user hive is already loaded. */
236   cygpsid csid (psid);
237   csid.string (sid);
238   if (!RegOpenKeyExA (HKEY_USERS, sid, 0, KEY_READ, &hkey))
239     {
240       debug_printf ("User registry hive for %s already exists", sid);
241       RegCloseKey (hkey);
242       return;
243     }
244   enable_restore_privilege ();
245   if (get_registry_hive_path (psid, path))
246     {
247       strcat (path, "\\NTUSER.DAT");
248       if ((ret = RegLoadKeyA (HKEY_USERS, sid, path)) != ERROR_SUCCESS)
249         debug_printf ("Loading user registry hive for %s failed: %d", sid, ret);
250     }
251 }
252