00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <errno.h>
00022 #include <stdlib.h>
00023 #include <string.h>
00024
00025 #include "defreg.h"
00026 #include "htatom.h"
00027 #include "htctrl.h"
00028 #include "htdialog.h"
00029 #include "htio.h"
00030 #include "htiobox.h"
00031 #include "htreg.h"
00032 #include "log.h"
00033 #include "snprintf.h"
00034 #include "store.h"
00035 #include "tools.h"
00036
00037 ht_registry *registry;
00038
00039 #define ATOM_HT_REGISTRY MAGICD("REG\x00")
00040 #define ATOM_HT_REGISTRY_NODE MAGICD("REG\x01")
00041 #define ATOM_HT_REGISTRY_DATA_STREE MAGICD("REG\x02")
00042 #define ATOM_HT_REGISTRY_DATA_DWORD MAGICD("REG\x03")
00043 #define ATOM_HT_REGISTRY_DATA_RAW MAGICD("REG\x04")
00044 #define ATOM_HT_REGISTRY_DATA_STRING MAGICD("REG\x05")
00045 #define ATOM_HT_REGISTRY_NODE_TYPE_DESC MAGICD("REG\x10")
00046 #define ATOM_HT_CREATE_EMPTY_SUBDIR MAGICD("REG\x20")
00047 #define ATOM_HT_CREATE_EMPTY_SYMLINK MAGICD("REG\x21")
00048 #define ATOM_HT_CREATE_EMPTY_DWORD MAGICD("REG\x22")
00049 #define ATOM_HT_CREATE_EMPTY_STRING MAGICD("REG\x23")
00050 #define ATOM_HT_CREATE_EMPTY_RAW MAGICD("REG\x24")
00051
00052
00053
00054
00055
00056 bool ht_registry_data::editdialog(const char *keyname)
00057 {
00058 return false;
00059 }
00060
00061 void ht_registry_data::strvalue(char *buf32bytes)
00062 {
00063 strcpy(buf32bytes, "<unknown>");
00064 }
00065
00066
00067
00068
00069
00070 ht_registry_data_stree::ht_registry_data_stree(ht_stree *t)
00071 {
00072 tree = t;
00073 }
00074
00075 ht_registry_data_stree::~ht_registry_data_stree()
00076 {
00077 if (tree) {
00078 tree->destroy();
00079 delete tree;
00080 }
00081 }
00082
00083 int ht_registry_data_stree::load(ht_object_stream *f)
00084 {
00085 if (!(tree = (ht_stree*)f->getObject("tree"))) return 1;
00086 return f->get_error();
00087 }
00088
00089 OBJECT_ID ht_registry_data_stree::object_id() const
00090 {
00091 return ATOM_HT_REGISTRY_DATA_STREE;
00092 }
00093
00094 void ht_registry_data_stree::store(ht_object_stream *f)
00095 {
00096 f->putObject(tree, "tree");
00097 }
00098
00099 void ht_registry_data_stree::strvalue(char *buf32bytes)
00100 {
00101 *buf32bytes = 0;
00102 }
00103
00104
00105
00106
00107
00108 ht_registry_data_dword::ht_registry_data_dword(dword v)
00109 {
00110 value = v;
00111 }
00112
00113 bool ht_registry_data_dword::editdialog(const char *keyname)
00114 {
00115
00116 char result[32];
00117 ht_snprintf(result, sizeof result, "%d", value);
00118 if (inputbox("edit dword", "number", result, sizeof result, 0)==button_ok) {
00119 char *r;
00120 int i = (int)strtol(result, &r, 10);
00121 if (*r == 0) {
00122 value = i;
00123 return true;
00124 }
00125 }
00126 return false;
00127 }
00128
00129 int ht_registry_data_dword::load(ht_object_stream *f)
00130 {
00131 value = f->getIntHex(4, "dword");
00132 return f->get_error();
00133 }
00134
00135 OBJECT_ID ht_registry_data_dword::object_id() const
00136 {
00137 return ATOM_HT_REGISTRY_DATA_DWORD;
00138 }
00139
00140 void ht_registry_data_dword::store(ht_object_stream *f)
00141 {
00142 f->putIntHex(value, 4, "dword");
00143 }
00144
00145 void ht_registry_data_dword::strvalue(char *buf32bytes)
00146 {
00147 ht_snprintf(buf32bytes, 32, "%d", value);
00148 }
00149
00150
00151
00152
00153
00154 ht_registry_data_raw::ht_registry_data_raw(const void *v, UINT s)
00155 {
00156 size = s;
00157 if (size) {
00158 value = malloc(s);
00159 memmove(value, v, s);
00160 } else {
00161 value = 0;
00162 }
00163 }
00164
00165 ht_registry_data_raw::~ht_registry_data_raw()
00166 {
00167 if (value) free(value);
00168 }
00169
00170 bool ht_registry_data_raw::editdialog(const char *keyname)
00171 {
00172 bool r = false;
00173 bounds b;
00174 b.w = 50;
00175 b.h = 15;
00176 b.x = (screen->size.w-b.w)/2;
00177 b.y = (screen->size.h-b.h)/2;
00178
00179 ht_dialog *d = new ht_dialog();
00180 d->init(&b, "edit data_raw", FS_TITLE | FS_KILLER);
00181
00182 if (d->run(false)) {
00183 r = true;
00184 }
00185
00186 d->done();
00187 delete d;
00188 return r;
00189 }
00190
00191 int ht_registry_data_raw::load(ht_object_stream *f)
00192 {
00193 size = f->getIntDec(4, "size");
00194 value = f->getBinary(size, NULL);
00195 return f->get_error();
00196 }
00197
00198 OBJECT_ID ht_registry_data_raw::object_id() const
00199 {
00200 return ATOM_HT_REGISTRY_DATA_RAW;
00201 }
00202
00203 void ht_registry_data_raw::store(ht_object_stream *f)
00204 {
00205 f->putIntDec(size, 4, "size");
00206 f->putBinary(value, size, NULL);
00207 }
00208
00209 void ht_registry_data_raw::strvalue(char *buf32bytes)
00210 {
00211 strcpy(buf32bytes, "raw");
00212 }
00213
00214
00215
00216
00217
00218 ht_registry_data_string::ht_registry_data_string(const char *s)
00219 {
00220 value = ht_strdup(s);
00221 }
00222
00223 ht_registry_data_string::~ht_registry_data_string()
00224 {
00225 if (value) free(value);
00226 }
00227
00228 bool ht_registry_data_string::editdialog(const char *keyname)
00229 {
00230 char res[256];
00231 strncpy(res, value, 255);
00232 res[255] = 0;
00233 if (inputbox("edit string", "string", res, 256, 0)) {
00234 if (value) delete value;
00235 value = strdup(res);
00236 return true;
00237 }
00238 return false;
00239 }
00240
00241 int ht_registry_data_string::load(ht_object_stream *f)
00242 {
00243 value = f->getString("string");
00244 return f->get_error();
00245 }
00246
00247 OBJECT_ID ht_registry_data_string::object_id() const
00248 {
00249 return ATOM_HT_REGISTRY_DATA_STRING;
00250 }
00251
00252 void ht_registry_data_string::store(ht_object_stream *f)
00253 {
00254 f->putString(value, "string");
00255 }
00256
00257 void ht_registry_data_string::strvalue(char *buf32bytes)
00258 {
00259 strncpy(buf32bytes, value, 31);
00260 buf32bytes[31] = 0;
00261 }
00262
00263
00264
00265
00266
00267 void ht_registry_node::init(ht_registry_node_type Type)
00268 {
00269 type = Type;
00270 data = NULL;
00271 }
00272
00273 void ht_registry_node::done()
00274 {
00275 if (data) {
00276 data->done();
00277 delete data;
00278 }
00279 }
00280
00281 int ht_registry_node::load(ht_object_stream *f)
00282 {
00283 type = f->getIntHex(4, "type");
00284 if (!(data = (ht_registry_data*)f->getObject(NULL))) return 1;
00285 return f->get_error();
00286 }
00287
00288 void ht_registry_node::store(ht_object_stream *f)
00289 {
00290 f->putIntHex(type, 4, "type");
00291 f->putObject(data, NULL);
00292 }
00293
00294 OBJECT_ID ht_registry_node::object_id() const
00295 {
00296 return ATOM_HT_REGISTRY_NODE;
00297 }
00298
00299
00300
00301
00302
00303 ht_registry_data *create_empty_symlink()
00304 {
00305 return new ht_registry_data_string("");
00306 }
00307
00308 ht_registry_data *create_empty_dword()
00309 {
00310 return new ht_registry_data_dword();
00311 }
00312
00313 ht_registry_data *create_empty_string()
00314 {
00315 return new ht_registry_data_string("");
00316 }
00317
00318 ht_registry_data *create_empty_raw()
00319 {
00320 return new ht_registry_data_raw();
00321 }
00322
00323
00324
00325
00326
00327 int ht_registry_node_type_desc::load(ht_object_stream *f)
00328 {
00329 type = f->getIntDec(4, "type");
00330 HT_ATOM a = f->getIntHex(4, NULL);
00331 void *p = find_atom(a);
00332 create_empty_registry_data=(create_empty_registry_data_func)p;
00333 return f->get_error();
00334 }
00335
00336 OBJECT_ID ht_registry_node_type_desc::object_id() const
00337 {
00338 return ATOM_HT_REGISTRY_NODE_TYPE_DESC;
00339 }
00340
00341 void ht_registry_node_type_desc::store(ht_object_stream *f)
00342 {
00343 f->putIntDec(type, 4, "type");
00344 HT_ATOM a = find_atom_rev((void*)create_empty_registry_data);
00345 f->putIntHex(a, 4, NULL);
00346 }
00347
00348
00349 void ht_registry::init()
00350 {
00351
00352 root=new ht_registry_node();
00353
00354 root->init(RNT_SUBDIR);
00355
00356 ht_stree *s=new ht_stree();
00357 s->init(compare_keys_string);
00358
00359 root->data=new ht_registry_data_stree(s);
00360
00361
00362 node_types=new ht_stree();
00363 node_types->init(compare_keys_string);
00364
00365 struct bla {
00366 char *identifier;
00367 ht_registry_node_type type;
00368 create_empty_registry_data_func create_empty_registry_data;
00369 };
00370 bla b[]=
00371 {
00372 {"subdir", RNT_SUBDIR, NULL},
00373 {"symlink", RNT_SYMLINK, create_empty_symlink},
00374 {"dword", RNT_DWORD, create_empty_dword},
00375 {"string", RNT_STRING, create_empty_string},
00376 {"raw", RNT_RAW, create_empty_raw}
00377 };
00378
00379 for (UINT i=0; i<sizeof (b) / sizeof b[0]; i++) {
00380 ht_registry_node_type_desc *d=new ht_registry_node_type_desc();
00381 d->type = b[i].type;
00382 d->create_empty_registry_data = b[i].create_empty_registry_data;
00383 node_types->insert(new ht_data_string(b[i].identifier), d);
00384 }
00385 }
00386
00387 void ht_registry::done()
00388 {
00389 node_types->destroy();
00390 delete node_types;
00391
00392 root->done();
00393 delete root;
00394 }
00395
00396 int ht_registry::create_node(const char *key, ht_registry_node_type type)
00397 {
00398 const char *name;
00399 ht_registry_node *m;
00400 if (!splitfind(key, &name, &m)) return EINVAL;
00401
00402 if (!valid_nodename(name)) return EINVAL;
00403
00404 ht_registry_node_type_desc *d = get_node_type_desc(type, NULL);
00405 if (d && d->create_empty_registry_data) {
00406 ht_registry_data *data = d->create_empty_registry_data();
00407
00408 ht_registry_node *n=new ht_registry_node();
00409 n->init(type);
00410 n->data=data;
00411
00412 return ((ht_registry_data_stree*)m->data)->tree->insert(new ht_data_string(name), n) ? 0 : EEXIST;
00413 }
00414
00415 return ENOSYS;
00416 }
00417
00418 int ht_registry::create_subdir(const char *key)
00419 {
00420 const char *name;
00421 ht_registry_node *m;
00422 if (!splitfind(key, &name, &m)) return EINVAL;
00423
00424 if (!valid_nodename(name)) return EINVAL;
00425
00426 ht_stree *s=new ht_stree();
00427 s->init(compare_keys_string);
00428
00429 ht_registry_node *n=new ht_registry_node();
00430 n->init(RNT_SUBDIR);
00431 n->data=new ht_registry_data_stree(s);
00432
00433 return ((ht_registry_data_stree*)m->data)->tree->insert(new ht_data_string(name), n) ? 0 : EEXIST;
00434 }
00435
00436 int ht_registry::delete_node(const char *key)
00437 {
00438 ht_tree *dir;
00439 ht_registry_node *n=find_entry_i(&dir, key, 0);
00440 if (!n) return ENOENT;
00441 const char *s=strrchr(key, '/');
00442 if (s) s++; else s=key;
00443 ht_data_string ss(s);
00444 return dir->del(&ss) ? 0 : ENOENT;
00445 }
00446
00447 void ht_registry::debug_dump()
00448 {
00449 #if 0
00450
00451 debug_dump_i(stderr, ((ht_registry_data_stree*)root->data)->tree, 0);
00452
00453 #endif
00454 }
00455
00456 void ht_registry::debug_dump_i(FILE *f, ht_tree *t, int ident)
00457 {
00458 #if 0
00459 ht_data_string *key=NULL;
00460 ht_registry_node *n;
00461 while ((key=(ht_data_string*)t->enum_next((Object**)&n, key))) {
00462 for (int i=0; i<ident; i++) fprintf(f, " ");
00463 fprintf(f, "%s ", key->value);
00464 switch (n->type) {
00465 case RNT_DWORD:
00466 fprintf(f, "= (dword) %08d (%08x)\n", ((ht_data_dword*)n->data)->value, ((ht_data_dword*)n->data)->value);
00467 break;
00468 case RNT_STRING:
00469 fprintf(f, "= (string) \"%s\"\n", ((ht_data_string*)n->data)->value);
00470 break;
00471 case RNT_SYMLINK:
00472 fprintf(f, "=> \"%s\"\n", ((ht_data_string*)n->data)->value);
00473 break;
00474 case RNT_SUBDIR:
00475 fprintf(f, "{\n");
00476 debug_dump_i(f, ((ht_registry_data_stree*)n->data)->tree, ident+1);
00477 for (int i=0; i<ident; i++) fprintf(f, " ");
00478 fprintf(f, "}\n");
00479 break;
00480 case RNT_RAW:
00481 fprintf(f, "= (raw) nyi!\n");
00482 break;
00483 default: {
00484 char *name=lookup_node_type_name(n->type);
00485 if (!name) name="?";
00486 fprintf(f, "= ('%s'=%d)\n", name, n->type);
00487 break;
00488 }
00489 }
00490 }
00491 #endif
00492 }
00493
00494 const char *ht_registry::enum_next(ht_registry_data **data, ht_registry_node_type *type, const char *dir, const char *prevkey)
00495 {
00496 ht_tree *t;
00497 rec_depth = 0;
00498 ht_registry_node *n = find_entry_i(0, dir, 1);
00499 if (n) {
00500 if (n->type != RNT_SUBDIR) return NULL;
00501 t = ((ht_registry_data_stree*)n->data)->tree;
00502
00503 ht_data_string ok(prevkey);
00504 ht_data_string *k;
00505 ht_registry_node *d;
00506 if ((k = (ht_data_string*)t->enum_next((Object**)&d, prevkey ? &ok : NULL))) {
00507 *data = d->data;
00508 *type = d->type;
00509 return k->value;
00510 }
00511 }
00512 return NULL;
00513 }
00514
00515 const char *ht_registry::enum_prev(ht_registry_data **data, ht_registry_node_type *type, const char *dir, const char *nextkey)
00516 {
00517 ht_tree *t;
00518 rec_depth = 0;
00519 ht_registry_node *n = find_entry_i(0, dir, 1);
00520 if (n) {
00521 if (n->type != RNT_SUBDIR) return NULL;
00522 t = ((ht_registry_data_stree*)n->data)->tree;
00523
00524 ht_data_string ok(nextkey);
00525 ht_data_string *k;
00526 ht_registry_node *d;
00527 if ((k = (ht_data_string*)t->enum_prev((Object**)&d, nextkey ? &ok : NULL))) {
00528 *data = d->data;
00529 *type = d->type;
00530 return k->value;
00531 }
00532 }
00533 return NULL;
00534 }
00535
00536 bool ht_registry::find_any_entry(const char *key, ht_registry_data **data, ht_registry_node_type *type)
00537 {
00538 rec_depth=0;
00539 ht_registry_node *n=find_entry_i(0, key, 1);
00540 if (n) {
00541 *data=n->data;
00542 *type=n->type;
00543 return true;
00544 }
00545 return false;
00546 }
00547
00548 bool ht_registry::find_data_entry(const char *key, ht_registry_data **data, ht_registry_node_type *type, bool follow_symlinks)
00549 {
00550 rec_depth=0;
00551 ht_registry_node *n=find_entry_i(0, key, follow_symlinks);
00552 if (n) {
00553 if (n->type==RNT_SUBDIR) return false;
00554 *data=n->data;
00555 *type=n->type;
00556 return true;
00557 }
00558 return false;
00559 }
00560
00561 ht_registry_node *ht_registry::find_entry_i(ht_tree **rdir, const char *key, bool follow_symlinks)
00562 {
00563 ht_registry_node *dir=root;
00564 char *s;
00565 char t[256];
00566 if (key[0]=='/') key++;
00567 while (1) {
00568 s=strchr(key, '/');
00569 if (s) {
00570 strncpy(t, key, s-key);
00571 t[s-key]=0;
00572 dir=find_entry_get_subdir(((ht_registry_data_stree*)dir->data)->tree, t);
00573 if (!dir) break;
00574 key=s+1;
00575 } else {
00576 ht_registry_node *n;
00577 if (*key==0) {
00578 n=dir;
00579 } else {
00580 n=find_entry_get_data(((ht_registry_data_stree*)dir->data)->tree, key, follow_symlinks);
00581 }
00582 if (rdir) *rdir=((ht_registry_data_stree*)dir->data)->tree;
00583 return n;
00584 }
00585 }
00586 return 0;
00587 }
00588
00589 ht_registry_node *ht_registry::find_entry_get_node(ht_tree *dir, const char *nodename)
00590 {
00591 if (nodename) {
00592 ht_data_string keystr(nodename);
00593 ht_registry_node *n=(ht_registry_node*)dir->get(&keystr);
00594 return n;
00595 }
00596 return NULL;
00597 }
00598
00599 ht_registry_node *ht_registry::find_entry_get_subdir(ht_tree *dir, const char *nodename)
00600 {
00601 ht_registry_node *n=find_entry_get_node(dir, nodename);
00602 start:
00603 if (!n) return 0;
00604 switch (n->type) {
00605 case RNT_SYMLINK: {
00606 rec_depth++;
00607 if (rec_depth>MAX_SYMLINK_REC_DEPTH) return 0;
00608 char *sl=((ht_registry_data_string*)n->data)->value;
00609 if (sl[0]=='/') {
00610 n=find_entry_i(0, sl, 1);
00611 goto start;
00612 } else {
00613 return find_entry_get_subdir(dir, sl);
00614 }
00615 }
00616 case RNT_SUBDIR:
00617 return n;
00618 }
00619 return 0;
00620 }
00621
00622 ht_registry_node *ht_registry::find_entry_get_data(ht_tree *dir, const char *nodename, bool follow_symlinks)
00623 {
00624 ht_registry_node *n=find_entry_get_node(dir, nodename);
00625 start:
00626 if (!n) return 0;
00627 if ((follow_symlinks) && (n->type==RNT_SYMLINK)) {
00628 rec_depth++;
00629 if (rec_depth>MAX_SYMLINK_REC_DEPTH) return 0;
00630 char *sl=((ht_registry_data_string*)n->data)->value;
00631 if (sl[0]=='/') {
00632 n=find_entry_i(0, sl, 1);
00633 goto start;
00634 } else {
00635 return find_entry_get_data(dir, sl, follow_symlinks);
00636 }
00637 }
00638 return n;
00639 }
00640
00641 ht_registry_node_type ht_registry::have_node_type(const char *identifier, create_empty_registry_data_func create_empty_registry_data)
00642 {
00643 ht_registry_node_type t=lookup_node_type(identifier);
00644 if (!t) t=register_node_type(identifier, create_empty_registry_data);
00645 return t;
00646 }
00647
00648 int ht_registry::load(ht_object_stream *f)
00649 {
00650 if (!(node_types=(ht_stree*)f->getObject("types"))) return 1;
00651 if (!(root=(ht_registry_node*)f->getObject("root"))) return 1;
00652 return f->get_error();
00653 }
00654
00655 ht_registry_node_type_desc *ht_registry::get_node_type_desc(ht_registry_node_type t, char **identifier)
00656 {
00657 ht_data_string *key=NULL;
00658 ht_registry_node_type_desc *data;
00659 while ((key=(ht_data_string*)node_types->enum_next((Object**)&data, key))) {
00660 if (t==data->type) {
00661 if (identifier) *identifier = key->value;
00662 return data;
00663 }
00664 }
00665 return NULL;
00666 }
00667
00668 ht_registry_node_type ht_registry::lookup_node_type(const char *identifier)
00669 {
00670 ht_data_string s(identifier);
00671 ht_registry_node_type_desc *d=(ht_registry_node_type_desc*)node_types->get(&s);
00672 return d ? d->type : 0;
00673 }
00674
00675 OBJECT_ID ht_registry::object_id() const
00676 {
00677 return ATOM_HT_REGISTRY;
00678 }
00679
00680 ht_registry_node_type ht_registry::register_node_type(const char *identifier, create_empty_registry_data_func create_empty_registry_data)
00681 {
00682
00683 ht_registry_node_type t = 0;
00684 ht_data_string *key;
00685 ht_registry_node_type_desc *data;
00686 bool found = false;
00687 while (!found) {
00688 t++;
00689 found = true;
00690 key = NULL;
00691 while ((key=(ht_data_string*)node_types->enum_next((Object**)&data, key))) {
00692 if (t == data->type) {
00693 found = false;
00694 break;
00695 }
00696 }
00697 }
00698
00699 ht_registry_node_type_desc *v = new ht_registry_node_type_desc();
00700 v->type = t;
00701 v->create_empty_registry_data = create_empty_registry_data;
00702 bool b = node_types->insert(new ht_data_string(identifier), v);
00703 if (b) return t;
00704 return RNT_INVALID;
00705 }
00706
00707 int ht_registry::set_dword(const char *key, dword d)
00708 {
00709 return set_node(key, RNT_DWORD, new ht_registry_data_dword(d));
00710 }
00711
00712 int ht_registry::set_raw(const char *key, const void *data, UINT size)
00713 {
00714 return set_node(key, RNT_RAW, new ht_registry_data_raw(data, size));
00715 }
00716
00717 int ht_registry::set_node(const char *key, ht_registry_node_type type, ht_registry_data *data)
00718 {
00719 ht_registry_node *n = find_entry_i(0, key, 0);
00720 if (!n) return ENOENT;
00721
00722 if (n->type == type) {
00723 if (n->data) {
00724 n->data->done();
00725 delete n->data;
00726 }
00727 n->data = data;
00728 return 0;
00729 }
00730 return EPERM;
00731 }
00732
00733 int ht_registry::set_string(const char *key, const char *string)
00734 {
00735 return set_node(key, RNT_STRING, new ht_registry_data_string(string));
00736 }
00737
00738 int ht_registry::set_symlink(const char *key, const char *dest)
00739 {
00740 return set_node(key, RNT_SYMLINK, new ht_registry_data_string(dest));
00741 }
00742
00743 bool ht_registry::splitfind(const char *key, const char **name, ht_registry_node **node)
00744 {
00745 char dir[256];
00746 const char *n=strrchr(key, '/');
00747 if (n) {
00748 strncpy(dir, key, n-key);
00749 dir[n-key]=0;
00750 n++;
00751 } else {
00752 dir[0]=0;
00753 n=key;
00754 }
00755
00756 ht_registry_node *m=find_entry_i(0, dir, 1);
00757 if (!m) return 0;
00758 if (m->type!=RNT_SUBDIR) return 0;
00759 *node=m;
00760 *name=n;
00761 return 1;
00762 }
00763
00764 void ht_registry::store(ht_object_stream *f)
00765 {
00766 f->putObject(node_types, "types");
00767 f->putObject(root, "root");
00768 }
00769
00770 unsigned char valid_nodename_chars[256/8]=
00771 {
00772
00773 0, 0, 0, 0,
00774
00775
00776 BITMAP(1, 0, 0, 0, 0, 0, 1, 0), BITMAP(0, 0, 0, 0, 0, 1, 1, 0),
00777 BITMAP(1, 1, 1, 1, 1, 1, 1, 1), BITMAP(1, 1, 1, 0, 0, 0, 0, 0),
00778
00779
00780 BITMAP(0, 1, 1, 1, 1, 1, 1, 1), BITMAP(1, 1, 1, 1, 1, 1, 1, 1),
00781 BITMAP(1, 1, 1, 1, 1, 1, 1, 1), BITMAP(1, 1, 1, 0, 0, 0, 0, 1),
00782
00783
00784 BITMAP(0, 1, 1, 1, 1, 1, 1, 1), BITMAP(1, 1, 1, 1, 1, 1, 1, 1),
00785 BITMAP(1, 1, 1, 1, 1, 1, 1, 1), BITMAP(1, 1, 1, 0, 0, 0, 0, 0),
00786
00787 0, 0, 0, 0,
00788
00789 0, 0, 0, 0,
00790
00791 0, 0, 0, 0,
00792
00793 0, 0, 0, 0
00794 };
00795
00796 unsigned char valid_nodename_chars_first[256/8]=
00797 {
00798
00799 0, 0, 0, 0,
00800
00801
00802 BITMAP(0, 0, 0, 0, 0, 0, 1, 0), BITMAP(0, 0, 0, 0, 0, 1, 1, 0),
00803 BITMAP(1, 1, 1, 1, 1, 1, 1, 1), BITMAP(1, 1, 0, 0, 0, 0, 0, 0),
00804
00805
00806 BITMAP(0, 1, 1, 1, 1, 1, 1, 1), BITMAP(1, 1, 1, 1, 1, 1, 1, 1),
00807 BITMAP(1, 1, 1, 1, 1, 1, 1, 1), BITMAP(1, 1, 1, 0, 0, 0, 0, 1),
00808
00809
00810 BITMAP(0, 1, 1, 1, 1, 1, 1, 1), BITMAP(1, 1, 1, 1, 1, 1, 1, 1),
00811 BITMAP(1, 1, 1, 1, 1, 1, 1, 1), BITMAP(1, 1, 1, 0, 0, 0, 0, 0),
00812
00813 0, 0, 0, 0,
00814
00815 0, 0, 0, 0,
00816
00817 0, 0, 0, 0,
00818
00819 0, 0, 0, 0
00820 };
00821
00822 bool valid_char(unsigned char *bitmap, char c)
00823 {
00824 int o=c/8;
00825 int p=c%8;
00826 return BITBIT(bitmap[o], p);
00827 }
00828
00829 bool ht_registry::valid_nodename(const char *nodename)
00830 {
00831 if ((strcmp(nodename, "..")==0) || (strcmp(nodename, ".")==0)) {
00832 return false;
00833 }
00834 if (!valid_char(valid_nodename_chars_first, *nodename)) return false;
00835 nodename++;
00836 while (*nodename) {
00837 if (!valid_char(valid_nodename_chars, *nodename)) return false;
00838 nodename++;
00839 }
00840 return true;
00841 }
00842
00843 dword get_config_dword(char *ident)
00844 {
00845 char e[HT_NAME_MAX], *ee = e;
00846 strcpy(ee, "/config/"); ee += strlen(ee);
00847 strncpy(ee, ident, sizeof (e) - (ee-e));
00848 ht_registry_data *d;
00849 ht_registry_node_type t;
00850 if (registry->find_data_entry(e, &d, &t, true)) {
00851 if (t == RNT_DWORD) {
00852 ht_registry_data_dword *s = (ht_registry_data_dword *)d;
00853 return s->value;
00854 } else {
00855 char *q = "?";
00856 registry->get_node_type_desc(t, &q);
00857 LOG_EX(LOG_ERROR, "registry key '%s' not of type %s, but: %s", e, "dword", q);
00858 }
00859 } else LOG_EX(LOG_ERROR, "registry key '%s' not found", e);
00860 return 0;
00861 }
00862
00863 char *get_config_string(char *ident)
00864 {
00865 char e[HT_NAME_MAX], *ee = e;
00866 strcpy(ee, "/config/"); ee += strlen(ee);
00867 strncpy(ee, ident, sizeof (e) - (ee-e));
00868 ht_registry_data *d;
00869 ht_registry_node_type t;
00870 if (registry->find_data_entry(e, &d, &t, true)) {
00871 if (t == RNT_STRING) {
00872 ht_registry_data_string *s = (ht_registry_data_string *)d;
00873 return ht_strdup(s->value);
00874 } else {
00875 char *q = "?";
00876 registry->get_node_type_desc(t, &q);
00877 LOG_EX(LOG_ERROR, "registry key '%s' not of type %s, but: %s", e, "string", q);
00878 }
00879 } else LOG_EX(LOG_ERROR, "registry key '%s' not found", e);
00880 return NULL;
00881 }
00882
00883 BUILDER(ATOM_HT_REGISTRY, ht_registry);
00884 BUILDER(ATOM_HT_REGISTRY_NODE, ht_registry_node);
00885 BUILDER(ATOM_HT_REGISTRY_DATA_STREE, ht_registry_data_stree);
00886 BUILDER(ATOM_HT_REGISTRY_DATA_DWORD, ht_registry_data_dword);
00887 BUILDER(ATOM_HT_REGISTRY_DATA_RAW, ht_registry_data_raw);
00888 BUILDER(ATOM_HT_REGISTRY_DATA_STRING, ht_registry_data_string);
00889 BUILDER(ATOM_HT_REGISTRY_NODE_TYPE_DESC, ht_registry_node_type_desc);
00890
00891
00892
00893
00894
00895 bool init_registry()
00896 {
00897 REGISTER(ATOM_HT_REGISTRY, ht_registry);
00898 REGISTER(ATOM_HT_REGISTRY_NODE, ht_registry_node);
00899 REGISTER(ATOM_HT_REGISTRY_DATA_STREE, ht_registry_data_stree);
00900 REGISTER(ATOM_HT_REGISTRY_DATA_DWORD, ht_registry_data_dword);
00901 REGISTER(ATOM_HT_REGISTRY_DATA_RAW, ht_registry_data_raw);
00902 REGISTER(ATOM_HT_REGISTRY_DATA_STRING, ht_registry_data_string);
00903 REGISTER(ATOM_HT_REGISTRY_NODE_TYPE_DESC, ht_registry_node_type_desc);
00904
00905 register_atom(ATOM_HT_CREATE_EMPTY_SYMLINK, (void*)create_empty_symlink);
00906 register_atom(ATOM_HT_CREATE_EMPTY_DWORD, (void*)create_empty_dword);
00907 register_atom(ATOM_HT_CREATE_EMPTY_STRING, (void*)create_empty_string);
00908 register_atom(ATOM_HT_CREATE_EMPTY_RAW, (void*)create_empty_raw);
00909
00910
00911
00912
00913 ht_memmap_file *f = new ht_memmap_file();
00914 f->init((unsigned char*)default_reg, sizeof default_reg);
00915
00916 ht_object_stream_bin *o = new ht_object_stream_bin();
00917 o->init(f);
00918
00919 registry = (ht_registry*)o->getObject(NULL);
00920
00921 o->done();
00922 delete o;
00923
00924 f->done();
00925 delete f;
00926
00927 return true;
00928 }
00929
00930
00931
00932
00933
00934 void done_registry()
00935 {
00936 UNREGISTER(ATOM_HT_REGISTRY, ht_registry);
00937 UNREGISTER(ATOM_HT_REGISTRY_NODE, ht_registry_node);
00938 UNREGISTER(ATOM_HT_REGISTRY_DATA_STREE, ht_registry_data_stree);
00939 UNREGISTER(ATOM_HT_REGISTRY_DATA_DWORD, ht_registry_data_dword);
00940 UNREGISTER(ATOM_HT_REGISTRY_DATA_RAW, ht_registry_data_raw);
00941 UNREGISTER(ATOM_HT_REGISTRY_DATA_STRING, ht_registry_data_string);
00942 UNREGISTER(ATOM_HT_REGISTRY_NODE_TYPE_DESC, ht_registry_node_type_desc);
00943
00944 unregister_atom(ATOM_HT_CREATE_EMPTY_SYMLINK);
00945 unregister_atom(ATOM_HT_CREATE_EMPTY_DWORD);
00946 unregister_atom(ATOM_HT_CREATE_EMPTY_STRING);
00947 unregister_atom(ATOM_HT_CREATE_EMPTY_RAW);
00948
00949 registry->done();
00950 delete registry;
00951 }
00952