r169: Fix gregedit
[kai/samba.git] / source / lib / registry / reg_backend_w95 / reg_backend_w95.c
1 /*
2    Samba Unix/Linux SMB client utility libeditreg.c 
3    Copyright (C) 2004 Jelmer Vernooij, jelmer@samba.org
4
5    Backend for Windows '95 registry files. Explanation of file format 
6    comes from http://www.cs.mun.ca/~michael/regutils/.
7
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.
12    
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.
17    
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.  */
21
22 #include "includes.h"
23 #include "lib/registry/common/registry.h"
24
25 /**
26  * The registry starts with a header that contains pointers to 
27  * the rgdb.
28  *
29  * After the main header follows the RGKN header (key index table) */
30
31 typedef unsigned int DWORD;
32 typedef unsigned short WORD;
33
34 typedef struct regc_block {
35         DWORD REGC_ID;          /* REGC */
36         DWORD uk1;
37         DWORD rgdb_offset;
38         DWORD chksum;
39         WORD  num_rgdb;
40         WORD  flags;
41         DWORD  uk2;
42         DWORD  uk3;
43         DWORD  uk4;
44         DWORD  uk5;
45 } REGC_HDR;
46
47 typedef struct rgkn_block {
48         DWORD RGKN_ID;          /* RGKN */
49         DWORD size;
50         DWORD root_offset;
51         DWORD free_offset;
52         DWORD flags;
53         DWORD chksum;
54         DWORD uk1;
55         DWORD uk2;
56 } RGKN_HDR;
57
58 typedef struct rgkn_key {
59         DWORD inuse;
60         DWORD hash;
61         DWORD next_free;
62         DWORD parent;
63         DWORD child;
64         DWORD next;
65         WORD id;
66         WORD rgdb;
67 } RGKN_KEY;
68
69 typedef struct rgdb_block {
70         DWORD RGDB_ID;          /* RGDB */
71         DWORD size;
72         DWORD unused_size;
73         WORD flags;
74         WORD section;
75         DWORD free_offset;      /* -1 if there is no free space */
76         WORD max_id;
77         WORD first_free_id;
78         DWORD uk1;
79         DWORD chksum;
80 } RGDB_HDR;
81
82 typedef struct rgdb_key {
83         DWORD inuse;
84         DWORD hash;
85         DWORD next_free;
86         DWORD parent;
87         DWORD child;
88         DWORD next;
89         WORD id;
90         WORD rgdb;
91 } RGDB_KEY;
92
93 typedef struct rgdb_value {
94         DWORD type;
95         DWORD uk1;
96         DWORD name_len;
97         DWORD data_len;
98 } RGDB_VALUE;
99
100 typedef struct regc_struct_s {
101         int fd;
102         struct stat sbuf;
103         BOOL modified;
104         char *base;
105 } REGC;
106
107 static WERROR w95_open_reg (REG_HANDLE *h, const char *location, const char *credentials)
108 {
109         REGC *regc = talloc_p(h->mem_ctx, REGC);
110         REGC_HDR *regc_hdr;
111         RGKN_HDR *rgkn_hdr;
112         DWORD regc_id, rgkn_id;
113         memset(regc, 0, sizeof(REGC));
114         h->backend_data = regc;
115
116         if((regc->fd = open(location, O_RDONLY, 0000)) < 0) {
117                 return WERR_FOOBAR;
118         }
119
120         if(fstat(regc->fd, &regc->sbuf) < 0) {
121                 return WERR_FOOBAR;
122         }
123
124         regc->base = mmap(0, regc->sbuf.st_size, PROT_READ, MAP_SHARED, regc->fd, 0);
125         regc_hdr = (REGC_HDR *)regc->base;
126
127         if ((int)regc->base == 1) {
128                 return WERR_FOOBAR;
129         }
130         
131         if ((regc_id = IVAL(&regc_hdr->REGC_ID,0)) != str_to_dword("REGC")) {
132                 DEBUG(0, ("Unrecognized Windows 95 registry header id: %0X, %s\n", 
133                                   regc_id, location));
134                 return WERR_FOOBAR;
135         }
136
137         rgkn_hdr = (RGKN_HDR *)regc->base + sizeof(REGC_HDR);
138
139         if ((rgkn_id = IVAL(&rgkn_hdr->RGKN_ID,0)) != str_to_dword("RGKN")) {
140                 DEBUG(0, ("Unrecognized Windows 95 registry key index id: %0X, %s\n", 
141                                   rgkn_id, location));
142                 return WERR_FOOBAR;
143         }
144
145         //rgkn = (RGKN_KEY *)regc->base + sizeof(REGC_HDR) + sizeof(RGKN_HDR);
146
147         /* FIXME */
148
149         return WERR_OK;
150 }
151
152 static WERROR w95_close_reg(REG_HANDLE *h)
153 {
154         REGC *regc = h->backend_data;
155     if (regc->base) munmap(regc->base, regc->sbuf.st_size);
156     regc->base = NULL;
157     close(regc->fd);
158         return WERR_OK;
159 }
160
161 static struct registry_ops reg_backend_w95 = {
162         .name = "w95",
163         .open_registry = w95_open_reg,
164         .close_registry = w95_close_reg,
165 };
166
167 NTSTATUS reg_w95_init(void)
168 {
169         return register_backend("registry", &reg_backend_w95);
170 }