2 Samba Unix/Linux SMB client utility libeditreg.c
3 Copyright (C) 2004 Jelmer Vernooij, jelmer@samba.org
5 Backend for Windows '95 registry files. Explanation of file format
6 comes from http://www.cs.mun.ca/~michael/regutils/.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23 #include "lib/registry/common/registry.h"
26 * The registry starts with a header that contains pointers to
29 * After the main header follows the RGKN header (key index table) */
31 typedef unsigned int DWORD;
32 typedef unsigned short WORD;
34 typedef struct creg_block {
35 DWORD CREG_ID; /* CREG */
46 typedef struct rgkn_block {
47 DWORD RGKN_ID; /* RGKN */
57 typedef struct rgkn_key {
68 typedef struct rgdb_block {
69 DWORD RGDB_ID; /* RGDB */
74 DWORD free_offset; /* -1 if there is no free space */
81 typedef struct rgdb_key {
92 typedef struct rgdb_value {
99 typedef struct creg_struct_s {
109 static DWORD str_to_dword(const char *a) {
111 unsigned long ret = 0;
112 for(i = strlen(a)-1; i >= 0; i--) {
113 ret = ret * 0x100 + a[i];
118 #define LOCN(creg, o) (((creg)->base + sizeof(CREG_HDR) + o))
120 static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *credentials)
122 CREG *creg = talloc_p(h->mem_ctx, CREG);
123 DWORD creg_id, rgkn_id;
124 memset(creg, 0, sizeof(CREG));
125 h->backend_data = creg;
129 if((creg->fd = open(location, O_RDONLY, 0000)) < 0) {
133 if (fstat(creg->fd, &creg->sbuf) < 0) {
137 creg->base = mmap(0, creg->sbuf.st_size, PROT_READ, MAP_SHARED, creg->fd, 0);
139 if ((int)creg->base == 1) {
140 DEBUG(0,("Could not mmap file: %s, %s\n", location, strerror(errno)));
144 creg->creg_hdr = (CREG_HDR *)creg->base;
146 if ((creg_id = IVAL(&creg->creg_hdr->CREG_ID,0)) != str_to_dword("CREG")) {
147 DEBUG(0, ("Unrecognized Windows 95 registry header id: 0x%0X, %s\n",
152 creg->rgkn_hdr = (RGKN_HDR *)LOCN(creg, 0);
154 if ((rgkn_id = IVAL(&creg->rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) {
155 DEBUG(0, ("Unrecognized Windows 95 registry key index id: 0x%0X, %s\n",
161 for(i = 0; i < creg->rgkn_hdr->size; i+=sizeof(RGKN_KEY)) {
162 RGKN_KEY *key = (RGKN_KEY *)LOCN(creg, sizeof(RGKN_HDR) + i);
165 } else if(key->type == 0) {
166 DEBUG(0,("Not used\n"));
168 } else if(key->type == 0x80000000) {
169 DEBUG(0,("Regular key\n"));
172 DEBUG(0,("Invalid key type in RGKN: %0X\n", key->type));
176 curpos += creg->rgkn_hdr->size + sizeof(RGKN_HDR);
178 offset = creg->rgkn_hdr->size;
180 DEBUG(0, ("Reading %d rgdb entries\n", creg->creg_hdr->num_rgdb));
181 for(i = 0; i < creg->creg_hdr->num_rgdb; i++) {
182 RGDB_HDR *rgdb_hdr = (RGDB_HDR *)LOCN(creg, offset);
184 if(strncmp((char *)&(rgdb_hdr->RGDB_ID), "RGDB", 4)) {
185 DEBUG(0, ("unrecognized rgdb entry: %4s, %s\n",
186 &rgdb_hdr->RGDB_ID, location));
189 DEBUG(0, ("Valid rgdb entry\n"));
192 offset+=rgdb_hdr->size;
199 static WERROR w95_close_reg(REG_HANDLE *h)
201 CREG *creg = h->backend_data;
202 if (creg->base) munmap(creg->base, creg->sbuf.st_size);
208 static struct registry_ops reg_backend_w95 = {
210 .open_registry = w95_open_reg,
211 .close_registry = w95_close_reg,
214 NTSTATUS reg_w95_init(void)
216 return register_backend("registry", ®_backend_w95);