00001
00002
00003
00004
00005
00006
00007 #include "config.h"
00008
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <fcntl.h>
00012 #include <unistd.h>
00013 #include <pwd.h>
00014 #include <sys/types.h>
00015
00016 #include "wine/winbase.h"
00017 #include "wine/winreg.h"
00018 #include "wine/winnt.h"
00019 #include "wine/winerror.h"
00020
00021 #include "ext.h"
00022 #include "registry.h"
00023
00024
00025
00026
00027 extern char *get_path ( char * );
00028
00029
00030 char* regpathname = NULL;
00031
00032 static char* localregpathname = NULL;
00033
00034 typedef struct reg_handle_s
00035 {
00036 int handle;
00037 char* name;
00038 struct reg_handle_s* next;
00039 struct reg_handle_s* prev;
00040 } reg_handle_t;
00041
00042 struct reg_value
00043 {
00044 int type;
00045 char* name;
00046 int len;
00047 char* value;
00048 };
00049
00050 static struct reg_value* regs = NULL;
00051 static int reg_size;
00052 static reg_handle_t* head = NULL;
00053
00054 #define DIR -25
00055
00056 static void create_registry(void);
00057 static void open_registry(void);
00058 static void save_registry(void);
00059 static void init_registry(void);
00060
00061
00062 static void create_registry(void){
00063 if(regs)
00064 {
00065 printf("Logic error: create_registry() called with existing registry\n");
00066 save_registry();
00067 return;
00068 }
00069 regs=(struct reg_value*)malloc(3*sizeof(struct reg_value));
00070 regs[0].type=regs[1].type=DIR;
00071 regs[0].name=(char*)malloc(5);
00072 strcpy(regs[0].name, "HKLM");
00073 regs[1].name=(char*)malloc(5);
00074 strcpy(regs[1].name, "HKCU");
00075 regs[0].value=regs[1].value=NULL;
00076 regs[0].len=regs[1].len=0;
00077 reg_size=2;
00078 head = 0;
00079 save_registry();
00080 }
00081
00082 static void open_registry(void)
00083 {
00084 int fd;
00085 int i;
00086 unsigned int len;
00087 if(regs)
00088 {
00089 printf("Multiple open_registry(>\n");
00090 return;
00091 }
00092 fd = open(localregpathname, O_RDONLY);
00093 if (fd == -1)
00094 {
00095 printf("Creating new registry\n");
00096 create_registry();
00097 return;
00098 }
00099 read(fd, ®_size, 4);
00100 regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value));
00101 head = 0;
00102 for(i=0; i<reg_size; i++)
00103 {
00104 read(fd,®s[i].type,4);
00105 read(fd,&len,4);
00106 regs[i].name=(char*)malloc(len+1);
00107 if(regs[i].name==0)
00108 {
00109 reg_size=i+1;
00110 goto error;
00111 }
00112 read(fd, regs[i].name, len);
00113 regs[i].name[len]=0;
00114 read(fd,®s[i].len,4);
00115 regs[i].value=(char*)malloc(regs[i].len+1);
00116 if(regs[i].value==0)
00117 {
00118 free(regs[i].name);
00119 reg_size=i+1;
00120 goto error;
00121 }
00122 read(fd, regs[i].value, regs[i].len);
00123 regs[i].value[regs[i].len]=0;
00124 }
00125 error:
00126 close(fd);
00127 return;
00128 }
00129
00130 static void save_registry(void)
00131 {
00132 int fd, i;
00133 if (!regs)
00134 init_registry();
00135 fd = open(localregpathname, O_WRONLY | O_CREAT, 00666);
00136 if (fd == -1)
00137 {
00138 printf("Failed to open registry file '%s' for writing.\n",
00139 localregpathname);
00140 return;
00141 }
00142 write(fd, ®_size, 4);
00143 for(i=0; i<reg_size; i++)
00144 {
00145 unsigned len=strlen(regs[i].name);
00146 write(fd, ®s[i].type, 4);
00147 write(fd, &len, 4);
00148 write(fd, regs[i].name, len);
00149 write(fd, ®s[i].len, 4);
00150 write(fd, regs[i].value, regs[i].len);
00151 }
00152 close(fd);
00153 }
00154
00155 void free_registry(void)
00156 {
00157 reg_handle_t* t = head;
00158 while (t)
00159 {
00160 reg_handle_t* f = t;
00161 if (t->name)
00162 free(t->name);
00163 t=t->prev;
00164 free(f);
00165 }
00166 head = 0;
00167 if (regs)
00168 {
00169 int i;
00170 for(i=0; i<reg_size; i++)
00171 {
00172 free(regs[i].name);
00173 free(regs[i].value);
00174 }
00175 free(regs);
00176 regs = 0;
00177 }
00178
00179 if (localregpathname && localregpathname != regpathname)
00180 free(localregpathname);
00181 localregpathname = 0;
00182 }
00183
00184
00185 static reg_handle_t* find_handle_by_name(const char* name)
00186 {
00187 reg_handle_t* t;
00188 for(t=head; t; t=t->prev)
00189 {
00190 if(!strcmp(t->name, name))
00191 {
00192 return t;
00193 }
00194 }
00195 return 0;
00196 }
00197 static struct reg_value* find_value_by_name(const char* name)
00198 {
00199 int i;
00200 for(i=0; i<reg_size; i++)
00201 if(!strcmp(regs[i].name, name))
00202 return regs+i;
00203 return 0;
00204 }
00205 static reg_handle_t* find_handle(int handle)
00206 {
00207 reg_handle_t* t;
00208 for(t=head; t; t=t->prev)
00209 {
00210 if(t->handle==handle)
00211 {
00212 return t;
00213 }
00214 }
00215 return 0;
00216 }
00217 static int generate_handle()
00218 {
00219 static unsigned int zz=249;
00220 zz++;
00221 while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER))
00222 zz++;
00223 return zz;
00224 }
00225
00226 static reg_handle_t* insert_handle(long handle, const char* name)
00227 {
00228 reg_handle_t* t;
00229 t=(reg_handle_t*)malloc(sizeof(reg_handle_t));
00230 if(head==0)
00231 {
00232 t->prev=0;
00233 }
00234 else
00235 {
00236 head->next=t;
00237 t->prev=head;
00238 }
00239 t->next=0;
00240 t->name=(char*)malloc(strlen(name)+1);
00241 strcpy(t->name, name);
00242 t->handle=handle;
00243 head=t;
00244 return t;
00245 }
00246 static char* build_keyname(long key, const char* subkey)
00247 {
00248 char* full_name;
00249 reg_handle_t* t;
00250 if((t=find_handle(key))==0)
00251 {
00252 TRACE("Invalid key\n");
00253 return NULL;
00254 }
00255 if(subkey==NULL)
00256 subkey="<default>";
00257 full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
00258 strcpy(full_name, t->name);
00259 strcat(full_name, "\\");
00260 strcat(full_name, subkey);
00261 return full_name;
00262 }
00263 static struct reg_value* insert_reg_value(int handle, const char* name, int type, const void* value, int len)
00264 {
00265 reg_handle_t* t;
00266 struct reg_value* v;
00267 char* fullname;
00268 if((fullname=build_keyname(handle, name))==NULL)
00269 {
00270 TRACE("Invalid handle\n");
00271 return NULL;
00272 }
00273
00274 if((v=find_value_by_name(fullname))==0)
00275
00276 {
00277 if(regs==0)
00278 create_registry();
00279 regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1));
00280
00281 v=regs+reg_size;
00282 reg_size++;
00283 }
00284 else
00285
00286 {
00287 free(v->value);
00288 free(v->name);
00289 }
00290 TRACE("RegInsert '%s' %p v:%d len:%d\n", name, value, *(int*)value, len);
00291 v->type=type;
00292 v->len=len;
00293 v->value=(char*)malloc(len);
00294 memcpy(v->value, value, len);
00295 v->name=(char*)malloc(strlen(fullname)+1);
00296 strcpy(v->name, fullname);
00297 free(fullname);
00298 save_registry();
00299 return v;
00300 }
00301
00302 static void init_registry(void)
00303 {
00304 TRACE("Initializing registry\n");
00305
00306
00307
00308 #ifdef MPLAYER
00309 regpathname = get_path("registry");
00310 localregpathname = regpathname;
00311 #else
00312
00313
00314
00315
00316
00317 if (localregpathname == 0)
00318 {
00319 const char* pthn = regpathname;
00320 if (!regpathname)
00321 {
00322
00323 struct passwd* pwent;
00324 pwent = getpwuid(geteuid());
00325 pthn = pwent->pw_dir;
00326 }
00327
00328 localregpathname = (char*)malloc(strlen(pthn)+20);
00329 strcpy(localregpathname, pthn);
00330 strcat(localregpathname, "/.registry");
00331 }
00332 #endif
00333
00334 open_registry();
00335 insert_handle(HKEY_LOCAL_MACHINE, "HKLM");
00336 insert_handle(HKEY_CURRENT_USER, "HKCU");
00337 }
00338
00339 static reg_handle_t* find_handle_2(long key, const char* subkey)
00340 {
00341 char* full_name;
00342 reg_handle_t* t;
00343 if((t=find_handle(key))==0)
00344 {
00345 TRACE("Invalid key\n");
00346 return (reg_handle_t*)-1;
00347 }
00348 if(subkey==NULL)
00349 return t;
00350 full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10);
00351 strcpy(full_name, t->name);
00352 strcat(full_name, "\\");
00353 strcat(full_name, subkey);
00354 t=find_handle_by_name(full_name);
00355 free(full_name);
00356 return t;
00357 }
00358
00359 long __stdcall RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
00360 {
00361 char* full_name;
00362 reg_handle_t* t;
00363 struct reg_value* v;
00364 TRACE("Opening key %s\n", subkey);
00365
00366 if(!regs)
00367 init_registry()
00368 ;
00369
00370
00371
00372
00373
00374
00375
00376
00377 full_name=build_keyname(key, subkey);
00378 if(!full_name)
00379 return -1;
00380 TRACE("Opening key Fullname %s\n", full_name);
00381 v=find_value_by_name(full_name);
00382
00383 t=insert_handle(generate_handle(), full_name);
00384 *newkey=t->handle;
00385 free(full_name);
00386
00387 return 0;
00388 }
00389 long __stdcall RegCloseKey(long key)
00390 {
00391 reg_handle_t *handle;
00392 if(key==(long)HKEY_LOCAL_MACHINE)
00393 return 0;
00394 if(key==(long)HKEY_CURRENT_USER)
00395 return 0;
00396 handle=find_handle(key);
00397 if(handle==0)
00398 return 0;
00399 if(handle->prev)
00400 handle->prev->next=handle->next;
00401 if(handle->next)
00402 handle->next->prev=handle->prev;
00403 if(handle->name)
00404 free(handle->name);
00405 if(handle==head)
00406 head=head->prev;
00407 free(handle);
00408 return 1;
00409 }
00410
00411 long __stdcall RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
00412 {
00413 struct reg_value* t;
00414 char* c;
00415 TRACE("Querying value %s\n", value);
00416 if(!regs)
00417 init_registry();
00418
00419 c=build_keyname(key, value);
00420 if (!c)
00421 return 1;
00422 t=find_value_by_name(c);
00423 free(c);
00424 if (t==0)
00425 return 2;
00426 if (type)
00427 *type=t->type;
00428 if (data)
00429 {
00430 memcpy(data, t->value, (t->len<*count)?t->len:*count);
00431 TRACE("returning %d bytes: %d\n", t->len, *(int*)data);
00432 }
00433 if(*count<t->len)
00434 {
00435 *count=t->len;
00436 return ERROR_MORE_DATA;
00437 }
00438 else
00439 {
00440 *count=t->len;
00441 }
00442 return 0;
00443 }
00444 long __stdcall RegCreateKeyExA(long key, const char* name, long reserved,
00445 void* classs, long options, long security,
00446 void* sec_attr, int* newkey, int* status)
00447 {
00448 reg_handle_t* t;
00449 char* fullname;
00450 struct reg_value* v;
00451
00452 if(!regs)
00453 init_registry();
00454
00455 fullname=build_keyname(key, name);
00456 if (!fullname)
00457 return 1;
00458 TRACE("Creating/Opening key %s\n", fullname);
00459 v=find_value_by_name(fullname);
00460 if(v==0)
00461 {
00462 int qw=45708;
00463 v=insert_reg_value(key, name, DIR, &qw, 4);
00464 if (status) *status=REG_CREATED_NEW_KEY;
00465
00466 }
00467
00468 t=insert_handle(generate_handle(), fullname);
00469 *newkey=t->handle;
00470 free(fullname);
00471 return 0;
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 long __stdcall RegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
00488 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
00489 {
00490
00491
00492
00493 reg_handle_t* t = find_handle(hkey);
00494 if (t && index < 10)
00495 {
00496 struct reg_value* v=find_value_by_name(t->name);
00497 if (v)
00498 {
00499 memcpy(data, v->value, (v->len < *count) ? v->len : *count);
00500 if(*count < v->len)
00501 *count = v->len;
00502 if (type)
00503 *type = v->type;
00504
00505 return 0;
00506 }
00507 }
00508 return ERROR_NO_MORE_ITEMS;
00509 }
00510
00511 long __stdcall RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size)
00512 {
00513 struct reg_value* t;
00514 char* c;
00515 TRACE("Request to set value %s %d\n", name, *(const int*)data);
00516 if(!regs)
00517 init_registry();
00518
00519 c=build_keyname(key, name);
00520 if(c==NULL)
00521 return 1;
00522 insert_reg_value(key, name, v2, data, size);
00523 free(c);
00524 return 0;
00525 }
00526
00527 long __stdcall RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName,
00528 LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass,
00529 LPFILETIME lpftLastWriteTime)
00530 {
00531 return ERROR_NO_MORE_ITEMS;
00532 }