#include #include #include #include #include #include #include #include #include #include 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 static void create_registry(); static void open_registry(); static void save_registry(); static void create_registry(){ 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() { 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, "/.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; ipw_dir)+20); strcpy(pathname, pwent->pw_dir); strcat(pathname, "/.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; iprev) { if(!strcmp(t->name, name)) { return t; } } return 0; } static struct reg_value* find_value_by_name(const char* name) { int i; // printf("REGISTRY: find_value_by_name(%s)\n",name); for(i=0; iprev) { 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=""; 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; } 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() { // printf("Initializing registry\n"); 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(*countlen) { *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); *status=REG_CREATED_NEW_KEY; // return 0; } else *status=REG_OPENED_EXISTING_KEY; t=insert_handle(generate_handle(), fullname); *newkey=t->handle; free(fullname); return 0; } 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; }