Main Page | Modules | Class Hierarchy | Class List | Directories | File List | Class Members | File Members | Related Pages

registry.c

00001 /*
00002  * Modified for use with MPlayer, detailed CVS changelog at
00003  * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
00004  * $Id: registry.c 11593 2005-06-28 18:02:01Z courmisch $
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 //#undef TRACE
00025 //#define TRACE printf
00026 
00027 extern char *get_path ( char * );
00028 
00029 // ...can be set before init_registry() call
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, &reg_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,&regs[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,&regs[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, &reg_size, 4);
00143         for(i=0; i<reg_size; i++)
00144         {
00145                 unsigned len=strlen(regs[i].name);
00146                 write(fd, &regs[i].type, 4);
00147                 write(fd, &len, 4);
00148                 write(fd, regs[i].name, len);
00149                 write(fd, &regs[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         //creating new value in registry
00276         {
00277                 if(regs==0)
00278                     create_registry();
00279                 regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1));
00280                 //regs=(struct reg_value*)my_realloc(regs, sizeof(struct reg_value)*(reg_size+1));
00281                 v=regs+reg_size;
00282                 reg_size++;
00283         }
00284         else
00285         //replacing old one
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         // can't be free-ed - it's static and probably thread
00306         // unsafe structure which is stored in glibc
00307 
00308 #ifdef MPLAYER
00309         regpathname = get_path("registry");
00310         localregpathname = regpathname;
00311 #else
00312         // regpathname is an external pointer
00313         //
00314         // registry.c is holding it's own internal pointer
00315         // localregpathname  - which is being allocate/deallocated
00316 
00317         if (localregpathname == 0)
00318         {
00319             const char* pthn = regpathname;
00320             if (!regpathname)
00321             {
00322                 // avifile - for now reading data from user's home
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 /*      t=find_handle_2(key, subkey);
00370 
00371         if(t==0)
00372                 return -1;
00373 
00374         if(t==(reg_handle_t*)-1)
00375                 return -1;
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     //        TRACE("Creating/Opening key %s\n", name);
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         //              return 0;
00466     }
00467 
00468     t=insert_handle(generate_handle(), fullname);
00469     *newkey=t->handle;
00470     free(fullname);
00471     return 0;
00472 }
00473 
00474 /*
00475 LONG RegEnumValue(
00476   HKEY hKey,              // handle to key to query
00477   DWORD dwIndex,          // index of value to query
00478   LPTSTR lpValueName,     // address of buffer for value string
00479   LPDWORD lpcbValueName,  // address for size of value buffer
00480   LPDWORD lpReserved,     // reserved
00481   LPDWORD lpType,         // address of buffer for type code
00482   LPBYTE lpData,          // address of buffer for value data
00483   LPDWORD lpcbData        // address for size of data buffer
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     // currenly just made to support MSZH & ZLIB
00491     //printf("Reg Enum 0x%x %d  %s %d   data: %p %d  %d >%s<\n", hkey, index,
00492     //       value, *val_count, data, *count, reg_size, data);
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             //printf("Found handle  %s\n", v->name);
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 }

Generated on Tue Dec 20 10:14:21 2005 for vlc-0.8.4a by  doxygen 1.4.2