Mercurial > mplayer.hg
view loader/registry.c @ 2836:ec672ea5ac2c
Applied SAMI patch by Evgeny Chukreev <codedj at echo dot ru>
author | atmos4 |
---|---|
date | Sun, 11 Nov 2001 15:41:17 +0000 |
parents | 8e841fe5668b |
children | 392316004607 |
line wrap: on
line source
#include <config.h> #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <pwd.h> #include <sys/types.h> #include <wine/winbase.h> #include <wine/winreg.h> #include <wine/winnt.h> #include <wine/winerror.h> #include <registry.h> #include <ext.h> //#undef TRACE //#define TRACE printf struct reg_value { int type; char* name; int len; char* value; }; static int reg_size=0; static struct reg_value* regs=0; struct reg_handle_s; typedef struct reg_handle_s { int handle; char* name; struct reg_handle_s* next; struct reg_handle_s* prev; } reg_handle_t; static reg_handle_t* head=0; #define DIR -25 extern char *get_path(char *); static void create_registry(void); static void open_registry(void); static void save_registry(void); static void create_registry(void){ if(regs) { printf("Logic error: create_registry() called with existing registry\n"); save_registry(); return; } regs=(struct reg_value*)malloc(3*sizeof(struct reg_value)); regs[0].type=regs[1].type=DIR; regs[0].name=(char*)malloc(5); strcpy(regs[0].name, "HKLM"); regs[1].name=(char*)malloc(5); strcpy(regs[1].name, "HKCU"); regs[0].value=regs[1].value=NULL; regs[0].len=regs[1].len=0; reg_size=2; save_registry(); } static void open_registry(void) { int fd; int i; int len; // struct passwd* pwent; char* pathname; if(regs) { printf("Multiple open_registry(>\n"); return; } // pwent=getpwuid(getuid()); // pathname=(char*)malloc(strlen(pwent->pw_dir)+20); // strcpy(pathname, pwent->pw_dir); // strcat(pathname, "/.mplayer/registry"); pathname = get_path("registry"); fd=open(pathname, O_RDONLY); free(pathname); if(fd==-1) { printf("Creating new registry\n"); create_registry(); return; } read(fd, ®_size, 4); regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value)); for(i=0; i<reg_size; i++) { read(fd,®s[i].type,4); read(fd,&len,4); regs[i].name=(char*)malloc(len+1); if(regs[i].name==0) { reg_size=i+1; goto error; } read(fd, regs[i].name, len); regs[i].name[len]=0; read(fd,®s[i].len,4); regs[i].value=(char*)malloc(regs[i].len+1); if(regs[i].value==0) { free(regs[i].name); reg_size=i+1; goto error; } read(fd, regs[i].value, regs[i].len); regs[i].value[regs[i].len]=0; } error: close(fd); return; } static void save_registry(void) { int fd, i, len; // struct passwd* pwent; char* pathname; // pwent=getpwuid(getuid()); // pathname=(char*)malloc(strlen(pwent->pw_dir)+20); // strcpy(pathname, pwent->pw_dir); // strcat(pathname, "/.mplayer/registry"); pathname = get_path("registry"); fd=open(pathname, O_WRONLY | O_CREAT, 00777); free(pathname); if(fd==-1) { printf("Failed to open registry file for writing.\n"); return; } write(fd, ®_size, 4); for(i=0; i<reg_size; i++) { write(fd, ®s[i].type, 4); len=strlen(regs[i].name); write(fd, &len, 4); write(fd, regs[i].name, len); write(fd, ®s[i].len, 4); write(fd, regs[i].value, regs[i].len); } close(fd); } static reg_handle_t* find_handle_by_name(const char* name) { reg_handle_t* t; for(t=head; t; t=t->prev) { if(!strcmp(t->name, name)) { return t; } } return 0; } static struct reg_value* find_value_by_name(const char* name) { int i; for(i=0; i<reg_size; i++) if(!strcmp(regs[i].name, name)) return regs+i; return 0; } static reg_handle_t* find_handle(int handle) { reg_handle_t* t; for(t=head; t; t=t->prev) { if(t->handle==handle) { return t; } } return 0; } static int generate_handle() { static int zz=249; zz++; while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER)) zz++; return zz; } static reg_handle_t* insert_handle(long handle, const char* name) { reg_handle_t* t; t=(reg_handle_t*)malloc(sizeof(reg_handle_t)); if(head==0) { t->prev=0; } else { head->next=t; t->prev=head; } t->next=0; t->name=(char*)malloc(strlen(name)+1); strcpy(t->name, name); t->handle=handle; head=t; return t; } static char* build_keyname(long key, const char* subkey) { char* full_name; reg_handle_t* t; if((t=find_handle(key))==0) { TRACE("Invalid key\n"); return NULL; } if(subkey==NULL) subkey="<default>"; full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10); strcpy(full_name, t->name); strcat(full_name, "\\"); strcat(full_name, subkey); return full_name; } static struct reg_value* insert_reg_value(int handle, const char* name, int type, const void* value, int len) { reg_handle_t* t; struct reg_value* v; char* fullname; if((fullname=build_keyname(handle, name))==NULL) { TRACE("Invalid handle\n"); return NULL; } if((v=find_value_by_name(fullname))==0) //creating new value in registry { if(regs==0) create_registry(); regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1)); v=regs+reg_size; reg_size++; } else //replacing old one { free(v->value); free(v->name); } v->type=type; v->len=len; v->value=(char*)malloc(len); memcpy(v->value, value, len); v->name=(char*)malloc(strlen(fullname)+1); strcpy(v->name, fullname); save_registry(); return v; } static void init_registry(void) { #ifdef DETAILED_OUT printf("Initializing registry\n"); #endif open_registry(); insert_handle(HKEY_LOCAL_MACHINE, "HKLM"); insert_handle(HKEY_CURRENT_USER, "HKCU"); } static reg_handle_t* find_handle_2(long key, const char* subkey) { char* full_name; reg_handle_t* t; if((t=find_handle(key))==0) { TRACE("Invalid key\n"); return (reg_handle_t*)-1; } if(subkey==NULL) return t; full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10); strcpy(full_name, t->name); strcat(full_name, "\\"); strcat(full_name, subkey); t=find_handle_by_name(full_name); free(full_name); return t; } long RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey) { char* full_name; reg_handle_t* t; struct reg_value* v; TRACE("Opening key %s\n", subkey); if(!regs) init_registry() ; /* t=find_handle_2(key, subkey); if(t==0) return -1; if(t==(reg_handle_t*)-1) return -1; */ full_name=build_keyname(key, subkey); if(!full_name) return -1; v=find_value_by_name(full_name); t=insert_handle(generate_handle(), full_name); *newkey=t->handle; free(full_name); return 0; } long RegCloseKey(long key) { reg_handle_t *handle; if(key==HKEY_LOCAL_MACHINE) return 0; if(key==HKEY_CURRENT_USER) return 0; handle=find_handle(key); if(handle==0) return 0; if(handle->prev) handle->prev->next=handle->next; if(handle->next) handle->next->prev=handle->prev; if(handle->name) free(handle->name); if(handle==head) head=head->prev; free(handle); return 1; } long RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count) { struct reg_value* t; char* c; TRACE("Querying value %s\n", value); if(!regs) init_registry() ; c=build_keyname(key, value); if(c==NULL) return 1; if((t=find_value_by_name(c))==0) { free(c); return 2; } free(c); if(type) *type=t->type; if(data) { memcpy(data, t->value, (t->len<*count)?t->len:*count); TRACE("returning %d bytes: %d\n", t->len, *(int*)data); } if(*count<t->len) { *count=t->len; return ERROR_MORE_DATA; } else { *count=t->len; } return 0; } long RegCreateKeyExA(long key, const char* name, long reserved, void* classs, long options, long security, void* sec_attr, int* newkey, int* status) { reg_handle_t* t; char* fullname; struct reg_value* v; // TRACE("Creating/Opening key %s\n", name); TRACE("Creating/Opening key %s\n", name); if(!regs) init_registry() ; fullname=build_keyname(key, name); if(fullname==NULL) return 1; v=find_value_by_name(fullname); if(v==0) { int qw=45708; v=insert_reg_value(key, name, DIR, &qw, 4); if (status) *status=REG_CREATED_NEW_KEY; // return 0; } else { // this is a hack as I don't know how RegEnumValueA works if (strstr(fullname, "zlib") || strstr(fullname, "mszh")) return 1; if (status) *status=REG_OPENED_EXISTING_KEY; } t=insert_handle(generate_handle(), fullname); *newkey=t->handle; free(fullname); return 0; } long RegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count, LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count) { // have no idea how this should work //printf("Reg Enum 0x%x %d %p %d data: %p %d %d >%s<\n", hkey, index, value, *val_count, data, *count, reg_size, data); { reg_handle_t* t = find_handle(hkey); if (t) { struct reg_value* v=find_value_by_name(t->name); *count = v->len; memcpy(data, v->value, *count); *val_count = v->len; memcpy(value, v->value, *val_count); if (type) *type = v->type; //printf("Found handle %s\n", v->name); return 0; } } return -1; } long RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size) { struct reg_value* t; char* c; TRACE("Request to set value %s\n", name); if(!regs) init_registry() ; c=build_keyname(key, name); if(c==NULL) return 1; insert_reg_value(key, name, v2, data, size); free(c); return 0; }