33
37
static TALLOC_CTX *ctx = NULL;
35
struct gp_registry_file_header {
40
struct gp_registry_file_entry {
43
enum winreg_Type type;
48
struct gp_registry_file {
49
struct gp_registry_file_header header;
51
struct gp_registry_entry *entries;
54
/****************************************************************
55
****************************************************************/
57
static bool reg_parse_header(const char *desc,
58
struct gp_registry_file_header *header,
65
prs_debug(ps, depth, desc, "reg_parse_header");
68
if (!prs_uint32("signature", ps, depth, &header->signature))
71
if (!prs_uint32("version", ps, depth, &header->version))
77
/****************************************************************
78
****************************************************************/
80
static bool reg_parse_and_verify_ucs2_char(const char *desc,
87
if (!prs_uint16(desc, ps, depth, &tmp))
90
if (tmp != UCS2_CHAR(character))
96
/****************************************************************
97
****************************************************************/
99
static bool reg_parse_init(prs_struct *ps, int depth)
101
return reg_parse_and_verify_ucs2_char("initiator '['", '[',
105
/****************************************************************
106
****************************************************************/
108
static bool reg_parse_sep(prs_struct *ps, int depth)
110
return reg_parse_and_verify_ucs2_char("separator ';'", ';',
114
/****************************************************************
115
****************************************************************/
117
static bool reg_parse_term(prs_struct *ps, int depth)
119
return reg_parse_and_verify_ucs2_char("terminator ']'", ']',
124
/****************************************************************
125
* [key;value;type;size;data]
126
****************************************************************/
128
static bool reg_parse_entry(TALLOC_CTX *mem_ctx,
130
struct gp_registry_file_entry *entry,
139
prs_debug(ps, depth, desc, "reg_parse_entry");
144
if (!reg_parse_init(ps, depth))
147
if (!prs_unistr("key", ps, depth, &entry->key))
150
if (!reg_parse_sep(ps, depth))
153
if (!prs_unistr("value", ps, depth, &entry->value))
156
if (!reg_parse_sep(ps, depth))
159
if (!prs_uint32("type", ps, depth, &entry->type))
162
if (!reg_parse_sep(ps, depth))
165
if (!prs_uint32("size", ps, depth, &size))
170
if (!reg_parse_sep(ps, depth))
174
entry->data = TALLOC_ZERO_ARRAY(mem_ctx, uint8, entry->size);
179
if (!prs_uint8s(false, "data", ps, depth, entry->data, entry->size))
182
if (!reg_parse_term(ps, depth))
188
39
/****************************************************************
189
40
****************************************************************/
191
42
static bool reg_parse_value(TALLOC_CTX *mem_ctx,
193
44
enum gp_reg_action *action)
270
if (strlen_w((const smb_ucs2_t *)file_entry->key.buffer) <= 0)
273
if (!pull_ucs2_talloc(mem_ctx, &key, file_entry->key.buffer,
279
if (strlen_w((const smb_ucs2_t *)file_entry->value.buffer) > 0 &&
280
!pull_ucs2_talloc(mem_ctx, &value, file_entry->value.buffer,
286
if (!reg_parse_value(mem_ctx, &value, &action))
289
data->type = file_entry->type;
291
switch (data->type) {
293
data->v.dword = atoi((char *)file_entry->data);
296
data->v.binary = data_blob_talloc(mem_ctx,
303
if (!pull_ucs2_talloc(mem_ctx, &data->v.sz.str,
311
case REG_DWORD_BIG_ENDIAN:
316
/* case REG_DWORD_LITTLE_ENDIAN: */
317
/* case REG_QWORD_LITTLE_ENDIAN: */
318
printf("not yet implemented: %d\n", data->type);
321
printf("invalid reg type defined: %d\n", data->type);
118
data->type = r->type;
119
data->data = data_blob_talloc(data, r->data, r->size);
326
121
entry = TALLOC_ZERO_P(mem_ctx, struct gp_registry_entry);
331
entry->value = value;
125
if (!reg_parse_value(mem_ctx, &r->valuename, &action))
128
entry->key = talloc_strdup(entry, r->keyname);
129
entry->value = talloc_strdup(entry, r->valuename);
332
130
entry->data = data;
333
131
entry->action = action;
340
138
/****************************************************************
341
* [key;value;type;size;data][key;value;type;size;data]...
342
****************************************************************/
344
static bool reg_parse_entries(TALLOC_CTX *mem_ctx,
346
struct gp_registry_entry **entries,
352
if (!entries || !num_entries)
355
prs_debug(ps, depth, desc, "reg_parse_entries");
361
while (ps->buffer_size > ps->data_offset) {
363
struct gp_registry_file_entry f_entry;
364
struct gp_registry_entry *r_entry = NULL;
366
if (!reg_parse_entry(mem_ctx, desc, &f_entry,
370
if (!gp_reg_entry_from_file_entry(mem_ctx,
375
if (!add_gp_registry_entry_to_array(mem_ctx,
385
/****************************************************************
386
139
****************************************************************/
388
141
static NTSTATUS reg_parse_registry(TALLOC_CTX *mem_ctx,
390
143
const char *filename,
391
struct gp_registry_entry **entries,
144
struct gp_registry_entry **entries_p,
145
size_t *num_entries_p)
394
uint16_t *buf = NULL;
398
struct gp_registry_file *reg_file;
149
enum ndr_err_code ndr_err;
399
150
const char *real_filename = NULL;
401
reg_file = TALLOC_ZERO_P(mem_ctx, struct gp_registry_file);
402
NT_STATUS_HAVE_NO_MEMORY(reg_file);
152
struct gp_registry_entry *entries = NULL;
153
size_t num_entries = 0;
404
156
status = gp_find_file(mem_ctx,
409
161
if (!NT_STATUS_IS_OK(status)) {
410
TALLOC_FREE(reg_file);
414
buf = (uint16 *)file_load(real_filename, &n, 0, NULL);
416
TALLOC_FREE(reg_file);
165
blob.data = (uint8_t *)file_load(real_filename, &blob.length, 0, NULL);
417
167
return NT_STATUS_CANNOT_LOAD_REGISTRY_FILE;
420
if (!prs_init(&ps, n, mem_ctx, UNMARSHALL)) {
421
status = NT_STATUS_NO_MEMORY;
425
if (!prs_copy_data_in(&ps, (char *)buf, n)) {
426
status = NT_STATUS_NO_MEMORY;
430
prs_set_offset(&ps, 0);
432
if (!reg_parse_header("header", ®_file->header, &ps, 0)) {
433
status = NT_STATUS_REGISTRY_IO_FAILED;
437
if (reg_file->header.signature != GP_REGPOL_FILE_SIGNATURE) {
438
status = NT_STATUS_INVALID_PARAMETER;
442
if (reg_file->header.version != GP_REGPOL_FILE_VERSION) {
443
status = NT_STATUS_INVALID_PARAMETER;
447
if (!reg_parse_entries(mem_ctx, "entries", ®_file->entries,
448
®_file->num_entries, &ps, 0)) {
449
status = NT_STATUS_REGISTRY_IO_FAILED;
453
*entries = reg_file->entries;
454
*num_entries = reg_file->num_entries;
170
ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r,
171
(ndr_pull_flags_fn_t)ndr_pull_preg_file);
172
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
173
status = ndr_map_error2ntstatus(ndr_err);
177
if (!strequal(r.header.signature, "PReg")) {
178
status = NT_STATUS_INVALID_PARAMETER;
182
if (r.header.version != GP_REGPOL_FILE_VERSION) {
183
status = NT_STATUS_INVALID_PARAMETER;
187
for (i=0; i < r.num_entries; i++) {
189
struct gp_registry_entry *r_entry = NULL;
191
if (!gp_reg_entry_from_file_entry(mem_ctx,
194
status = NT_STATUS_NO_MEMORY;
198
if (!add_gp_registry_entry_to_array(mem_ctx,
202
status = NT_STATUS_NO_MEMORY;
207
*entries_p = entries;
208
*num_entries_p = num_entries;
456
210
status = NT_STATUS_OK;
213
data_blob_free(&blob);