Mercurial > mplayer.hg
annotate loader/registry.c @ 1550:39119eb74363
*** empty log message ***
author | zybi |
---|---|
date | Thu, 16 Aug 2001 11:42:10 +0000 |
parents | 8e841fe5668b |
children | 392316004607 |
rev | line source |
---|---|
1 | 1 #include <config.h> |
2 | |
3 #include <stdio.h> | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
4 #include <stdlib.h> |
1 | 5 #include <fcntl.h> |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
6 #include <unistd.h> |
1 | 7 #include <pwd.h> |
8 #include <sys/types.h> | |
9 | |
10 #include <wine/winbase.h> | |
11 #include <wine/winreg.h> | |
12 #include <wine/winnt.h> | |
13 #include <wine/winerror.h> | |
14 | |
15 #include <registry.h> | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
16 #include <ext.h> |
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
17 |
128 | 18 //#undef TRACE |
19 //#define TRACE printf | |
1 | 20 struct reg_value |
21 { | |
22 int type; | |
23 char* name; | |
24 int len; | |
25 char* value; | |
26 }; | |
27 | |
28 static int reg_size=0; | |
29 | |
30 static struct reg_value* regs=0; | |
31 | |
32 struct reg_handle_s; | |
33 typedef struct reg_handle_s | |
34 { | |
35 int handle; | |
36 char* name; | |
37 struct reg_handle_s* next; | |
38 struct reg_handle_s* prev; | |
39 } reg_handle_t; | |
40 | |
41 static reg_handle_t* head=0; | |
42 | |
43 #define DIR -25 | |
44 | |
178 | 45 extern char *get_path(char *); |
46 | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
47 static void create_registry(void); |
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
48 static void open_registry(void); |
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
49 static void save_registry(void); |
1 | 50 |
51 | |
52 | |
53 | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
54 static void create_registry(void){ |
1 | 55 if(regs) |
56 { | |
57 printf("Logic error: create_registry() called with existing registry\n"); | |
58 save_registry(); | |
59 return; | |
60 } | |
61 regs=(struct reg_value*)malloc(3*sizeof(struct reg_value)); | |
62 regs[0].type=regs[1].type=DIR; | |
63 regs[0].name=(char*)malloc(5); | |
64 strcpy(regs[0].name, "HKLM"); | |
65 regs[1].name=(char*)malloc(5); | |
66 strcpy(regs[1].name, "HKCU"); | |
67 regs[0].value=regs[1].value=NULL; | |
68 regs[0].len=regs[1].len=0; | |
69 reg_size=2; | |
70 save_registry(); | |
71 } | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
72 static void open_registry(void) |
1 | 73 { |
74 int fd; | |
75 int i; | |
76 int len; | |
178 | 77 // struct passwd* pwent; |
1 | 78 char* pathname; |
79 if(regs) | |
80 { | |
81 printf("Multiple open_registry(>\n"); | |
82 return; | |
83 } | |
178 | 84 // pwent=getpwuid(getuid()); |
85 // pathname=(char*)malloc(strlen(pwent->pw_dir)+20); | |
86 // strcpy(pathname, pwent->pw_dir); | |
87 // strcat(pathname, "/.mplayer/registry"); | |
88 pathname = get_path("registry"); | |
1 | 89 fd=open(pathname, O_RDONLY); |
90 free(pathname); | |
91 if(fd==-1) | |
92 { | |
93 printf("Creating new registry\n"); | |
94 create_registry(); | |
95 return; | |
96 } | |
97 read(fd, ®_size, 4); | |
98 regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value)); | |
99 for(i=0; i<reg_size; i++) | |
100 { | |
101 read(fd,®s[i].type,4); | |
102 read(fd,&len,4); | |
103 regs[i].name=(char*)malloc(len+1); | |
104 if(regs[i].name==0) | |
105 { | |
106 reg_size=i+1; | |
107 goto error; | |
108 } | |
109 read(fd, regs[i].name, len); | |
110 regs[i].name[len]=0; | |
111 read(fd,®s[i].len,4); | |
112 regs[i].value=(char*)malloc(regs[i].len+1); | |
113 if(regs[i].value==0) | |
114 { | |
115 free(regs[i].name); | |
116 reg_size=i+1; | |
117 goto error; | |
118 } | |
119 read(fd, regs[i].value, regs[i].len); | |
120 regs[i].value[regs[i].len]=0; | |
121 } | |
122 error: | |
123 close(fd); | |
124 return; | |
125 } | |
126 | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
127 static void save_registry(void) |
1 | 128 { |
129 int fd, i, len; | |
178 | 130 // struct passwd* pwent; |
1 | 131 char* pathname; |
178 | 132 // pwent=getpwuid(getuid()); |
133 // pathname=(char*)malloc(strlen(pwent->pw_dir)+20); | |
134 // strcpy(pathname, pwent->pw_dir); | |
135 // strcat(pathname, "/.mplayer/registry"); | |
136 pathname = get_path("registry"); | |
1 | 137 fd=open(pathname, O_WRONLY | O_CREAT, 00777); |
138 free(pathname); | |
139 if(fd==-1) | |
140 { | |
141 printf("Failed to open registry file for writing.\n"); | |
142 return; | |
143 } | |
144 write(fd, ®_size, 4); | |
145 for(i=0; i<reg_size; i++) | |
146 { | |
147 write(fd, ®s[i].type, 4); | |
148 len=strlen(regs[i].name); | |
149 write(fd, &len, 4); | |
150 write(fd, regs[i].name, len); | |
151 write(fd, ®s[i].len, 4); | |
152 write(fd, regs[i].value, regs[i].len); | |
153 } | |
154 close(fd); | |
155 } | |
156 static reg_handle_t* find_handle_by_name(const char* name) | |
157 { | |
158 reg_handle_t* t; | |
159 for(t=head; t; t=t->prev) | |
160 { | |
161 if(!strcmp(t->name, name)) | |
162 { | |
163 return t; | |
164 } | |
165 } | |
166 return 0; | |
167 } | |
168 static struct reg_value* find_value_by_name(const char* name) | |
169 { | |
170 int i; | |
171 for(i=0; i<reg_size; i++) | |
172 if(!strcmp(regs[i].name, name)) | |
173 return regs+i; | |
174 return 0; | |
175 } | |
176 static reg_handle_t* find_handle(int handle) | |
177 { | |
178 reg_handle_t* t; | |
179 for(t=head; t; t=t->prev) | |
180 { | |
181 if(t->handle==handle) | |
182 { | |
183 return t; | |
184 } | |
185 } | |
186 return 0; | |
187 } | |
188 static int generate_handle() | |
189 { | |
190 static int zz=249; | |
191 zz++; | |
192 while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER)) | |
193 zz++; | |
194 return zz; | |
195 } | |
196 | |
197 static reg_handle_t* insert_handle(long handle, const char* name) | |
198 { | |
199 reg_handle_t* t; | |
200 t=(reg_handle_t*)malloc(sizeof(reg_handle_t)); | |
201 if(head==0) | |
202 { | |
203 t->prev=0; | |
204 } | |
205 else | |
206 { | |
207 head->next=t; | |
208 t->prev=head; | |
209 } | |
210 t->next=0; | |
211 t->name=(char*)malloc(strlen(name)+1); | |
212 strcpy(t->name, name); | |
213 t->handle=handle; | |
214 head=t; | |
215 return t; | |
216 } | |
217 static char* build_keyname(long key, const char* subkey) | |
218 { | |
219 char* full_name; | |
220 reg_handle_t* t; | |
221 if((t=find_handle(key))==0) | |
222 { | |
223 TRACE("Invalid key\n"); | |
224 return NULL; | |
225 } | |
226 if(subkey==NULL) | |
227 subkey="<default>"; | |
228 full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10); | |
229 strcpy(full_name, t->name); | |
230 strcat(full_name, "\\"); | |
231 strcat(full_name, subkey); | |
232 return full_name; | |
233 } | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
234 static struct reg_value* insert_reg_value(int handle, const char* name, int type, const void* value, int len) |
1 | 235 { |
236 reg_handle_t* t; | |
237 struct reg_value* v; | |
238 char* fullname; | |
239 if((fullname=build_keyname(handle, name))==NULL) | |
240 { | |
241 TRACE("Invalid handle\n"); | |
242 return NULL; | |
243 } | |
244 | |
245 if((v=find_value_by_name(fullname))==0) | |
246 //creating new value in registry | |
247 { | |
248 if(regs==0) | |
249 create_registry(); | |
250 regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1)); | |
251 v=regs+reg_size; | |
252 reg_size++; | |
253 } | |
254 else | |
255 //replacing old one | |
256 { | |
257 free(v->value); | |
258 free(v->name); | |
259 } | |
260 v->type=type; | |
261 v->len=len; | |
262 v->value=(char*)malloc(len); | |
263 memcpy(v->value, value, len); | |
264 v->name=(char*)malloc(strlen(fullname)+1); | |
265 strcpy(v->name, fullname); | |
266 save_registry(); | |
267 return v; | |
268 } | |
269 | |
1307
d8c1b0b38edc
Add prototypes to wine/loader stuff, so that we can catch __stdcall function
jkeil
parents:
340
diff
changeset
|
270 static void init_registry(void) |
1 | 271 { |
340 | 272 #ifdef DETAILED_OUT |
128 | 273 printf("Initializing registry\n"); |
340 | 274 #endif |
1 | 275 open_registry(); |
276 insert_handle(HKEY_LOCAL_MACHINE, "HKLM"); | |
277 insert_handle(HKEY_CURRENT_USER, "HKCU"); | |
278 } | |
279 static reg_handle_t* find_handle_2(long key, const char* subkey) | |
280 { | |
281 char* full_name; | |
282 reg_handle_t* t; | |
283 if((t=find_handle(key))==0) | |
284 { | |
285 TRACE("Invalid key\n"); | |
286 return (reg_handle_t*)-1; | |
287 } | |
288 if(subkey==NULL) | |
289 return t; | |
290 full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10); | |
291 strcpy(full_name, t->name); | |
292 strcat(full_name, "\\"); | |
293 strcat(full_name, subkey); | |
294 t=find_handle_by_name(full_name); | |
295 free(full_name); | |
296 return t; | |
297 } | |
298 | |
299 long RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey) | |
300 { | |
301 char* full_name; | |
302 reg_handle_t* t; | |
303 struct reg_value* v; | |
304 TRACE("Opening key %s\n", subkey); | |
305 | |
306 if(!regs) | |
307 init_registry() | |
308 ; | |
309 /* t=find_handle_2(key, subkey); | |
310 | |
311 if(t==0) | |
312 return -1; | |
313 | |
314 if(t==(reg_handle_t*)-1) | |
315 return -1; | |
316 | |
317 */ full_name=build_keyname(key, subkey); | |
318 if(!full_name) | |
319 return -1; | |
320 v=find_value_by_name(full_name); | |
321 | |
322 t=insert_handle(generate_handle(), full_name); | |
323 *newkey=t->handle; | |
324 free(full_name); | |
325 | |
326 return 0; | |
327 } | |
328 long RegCloseKey(long key) | |
329 { | |
330 reg_handle_t *handle; | |
331 if(key==HKEY_LOCAL_MACHINE) | |
332 return 0; | |
333 if(key==HKEY_CURRENT_USER) | |
334 return 0; | |
335 handle=find_handle(key); | |
336 if(handle==0) | |
337 return 0; | |
338 if(handle->prev) | |
339 handle->prev->next=handle->next; | |
340 if(handle->next) | |
341 handle->next->prev=handle->prev; | |
342 if(handle->name) | |
343 free(handle->name); | |
344 if(handle==head) | |
345 head=head->prev; | |
346 free(handle); | |
347 return 1; | |
348 } | |
349 long RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count) | |
350 { | |
351 struct reg_value* t; | |
352 char* c; | |
353 TRACE("Querying value %s\n", value); | |
354 if(!regs) | |
355 init_registry() | |
356 ; | |
357 c=build_keyname(key, value); | |
358 if(c==NULL) | |
359 return 1; | |
360 if((t=find_value_by_name(c))==0) | |
361 { | |
362 free(c); | |
363 return 2; | |
364 } | |
365 free(c); | |
366 if(type) | |
367 *type=t->type; | |
368 if(data) | |
369 { | |
370 memcpy(data, t->value, (t->len<*count)?t->len:*count); | |
371 TRACE("returning %d bytes: %d\n", t->len, *(int*)data); | |
372 } | |
373 if(*count<t->len) | |
374 { | |
375 *count=t->len; | |
376 return ERROR_MORE_DATA; | |
377 } | |
378 else | |
379 { | |
380 *count=t->len; | |
381 } | |
382 return 0; | |
383 } | |
384 long RegCreateKeyExA(long key, const char* name, long reserved, | |
385 void* classs, long options, long security, | |
386 void* sec_attr, int* newkey, int* status) | |
387 { | |
388 reg_handle_t* t; | |
389 char* fullname; | |
390 struct reg_value* v; | |
391 // TRACE("Creating/Opening key %s\n", name); | |
392 TRACE("Creating/Opening key %s\n", name); | |
393 if(!regs) | |
394 init_registry() | |
395 ; | |
396 fullname=build_keyname(key, name); | |
397 if(fullname==NULL) | |
398 return 1; | |
399 v=find_value_by_name(fullname); | |
400 if(v==0) | |
401 { | |
402 int qw=45708; | |
403 v=insert_reg_value(key, name, DIR, &qw, 4); | |
128 | 404 if (status) *status=REG_CREATED_NEW_KEY; |
1 | 405 // return 0; |
406 } | |
407 else | |
1416 | 408 { |
409 // this is a hack as I don't know how RegEnumValueA works | |
410 if (strstr(fullname, "zlib") || strstr(fullname, "mszh")) | |
411 return 1; | |
412 if (status) *status=REG_OPENED_EXISTING_KEY; | |
413 } | |
1 | 414 |
415 t=insert_handle(generate_handle(), fullname); | |
416 *newkey=t->handle; | |
417 free(fullname); | |
418 return 0; | |
419 } | |
1416 | 420 |
421 long RegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count, | |
422 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count) | |
423 { | |
424 // have no idea how this should work | |
425 //printf("Reg Enum 0x%x %d %p %d data: %p %d %d >%s<\n", hkey, index, value, *val_count, data, *count, reg_size, data); | |
426 { | |
427 reg_handle_t* t = find_handle(hkey); | |
428 if (t) | |
429 { | |
430 struct reg_value* v=find_value_by_name(t->name); | |
431 *count = v->len; | |
432 memcpy(data, v->value, *count); | |
433 *val_count = v->len; | |
434 memcpy(value, v->value, *val_count); | |
435 if (type) | |
436 *type = v->type; | |
437 //printf("Found handle %s\n", v->name); | |
438 return 0; | |
439 } | |
440 } | |
441 | |
442 return -1; | |
443 } | |
444 | |
1 | 445 long RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size) |
446 { | |
447 struct reg_value* t; | |
448 char* c; | |
449 TRACE("Request to set value %s\n", name); | |
450 if(!regs) | |
451 init_registry() | |
452 ; | |
453 c=build_keyname(key, name); | |
454 if(c==NULL) | |
455 return 1; | |
456 insert_reg_value(key, name, v2, data, size); | |
457 free(c); | |
458 return 0; | |
459 } |