mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
Fix PReg write support.
Add tests for patch files (.REG and PReg).
This commit is contained in:
parent
6e9b1e35a2
commit
497977c36c
@ -320,12 +320,33 @@ static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name)
|
||||
{
|
||||
struct registry_context *ctx = (struct registry_context *)_ctx;
|
||||
struct registry_key *tmp;
|
||||
char *buf, *buf_ptr;
|
||||
WERROR error;
|
||||
|
||||
/* Recursively create the path */
|
||||
buf = talloc_strdup(ctx, key_name);
|
||||
buf_ptr = buf;
|
||||
|
||||
while (*buf_ptr++ != '\0' ) {
|
||||
if (*buf_ptr == '\\') {
|
||||
*buf_ptr = '\0';
|
||||
error = reg_key_add_abs(ctx, ctx, buf, 0, NULL, &tmp);
|
||||
|
||||
if (!W_ERROR_EQUAL(error, WERR_ALREADY_EXISTS) &&
|
||||
!W_ERROR_IS_OK(error)) {
|
||||
DEBUG(0, ("Error adding new key '%s': %s\n",
|
||||
key_name, win_errstr(error)));
|
||||
return error;
|
||||
}
|
||||
*buf_ptr++ = '\\';
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the key */
|
||||
error = reg_key_add_abs(ctx, ctx, key_name, 0, NULL, &tmp);
|
||||
|
||||
if (!W_ERROR_EQUAL(error, WERR_ALREADY_EXISTS) &&
|
||||
!W_ERROR_IS_OK(error)) {
|
||||
!W_ERROR_IS_OK(error)) {
|
||||
DEBUG(0, ("Error adding new key '%s': %s\n",
|
||||
key_name, win_errstr(error)));
|
||||
return error;
|
||||
|
@ -23,9 +23,12 @@
|
||||
#include "lib/registry/registry.h"
|
||||
#include "system/filesys.h"
|
||||
#include "param/param.h"
|
||||
#include "librpc/gen_ndr/winreg.h"
|
||||
|
||||
struct preg_data {
|
||||
int fd;
|
||||
TALLOC_CTX *ctx;
|
||||
struct smb_iconv_convenience *ic;
|
||||
};
|
||||
|
||||
static WERROR preg_read_utf16(struct smb_iconv_convenience *ic, int fd, char *c)
|
||||
@ -38,25 +41,69 @@ static WERROR preg_read_utf16(struct smb_iconv_convenience *ic, int fd, char *c)
|
||||
push_codepoint(ic, c, v);
|
||||
return WERR_OK;
|
||||
}
|
||||
static WERROR preg_write_utf16(struct smb_iconv_convenience *ic, int fd, const char *string)
|
||||
{
|
||||
codepoint_t v;
|
||||
uint16_t i;
|
||||
size_t size;
|
||||
|
||||
/* FIXME These functions need to be implemented */
|
||||
for (i = 0; i < strlen(string); i+=size) {
|
||||
v = next_codepoint(ic, &string[i], &size);
|
||||
if (write(fd, &v, 2) < 2) {
|
||||
return WERR_GENERAL_FAILURE;
|
||||
}
|
||||
}
|
||||
return WERR_OK;
|
||||
}
|
||||
/* PReg does not support adding keys. */
|
||||
static WERROR reg_preg_diff_add_key(void *_data, const char *key_name)
|
||||
{
|
||||
return WERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
static WERROR reg_preg_diff_del_key(void *_data, const char *key_name)
|
||||
{
|
||||
return WERR_NOT_SUPPORTED;
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR reg_preg_diff_set_value(void *_data, const char *key_name,
|
||||
const char *value_name,
|
||||
uint32_t value_type, DATA_BLOB value_data)
|
||||
{
|
||||
return WERR_NOT_SUPPORTED;
|
||||
struct preg_data *data = _data;
|
||||
uint32_t buf;
|
||||
|
||||
preg_write_utf16(data->ic, data->fd, "[");
|
||||
preg_write_utf16(data->ic, data->fd, key_name);
|
||||
preg_write_utf16(data->ic, data->fd, ";");
|
||||
preg_write_utf16(data->ic, data->fd, value_name);
|
||||
preg_write_utf16(data->ic, data->fd, ";");
|
||||
SIVAL(&buf, 0, value_type);
|
||||
write(data->fd, &buf, sizeof(uint32_t));
|
||||
preg_write_utf16(data->ic, data->fd, ";");
|
||||
SIVAL(&buf, 0, value_data.length);
|
||||
write(data->fd, &buf, sizeof(uint32_t));
|
||||
preg_write_utf16(data->ic, data->fd, ";");
|
||||
write(data->fd, value_data.data, value_data.length);
|
||||
preg_write_utf16(data->ic, data->fd, "]");
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
static WERROR reg_preg_diff_del_key(void *_data, const char *key_name)
|
||||
{
|
||||
struct preg_data *data = _data;
|
||||
char *parent_name;
|
||||
DATA_BLOB blob;
|
||||
|
||||
parent_name = talloc_strndup(data->ctx, key_name, strrchr(key_name, '\\')-key_name);
|
||||
blob.data = (void *)talloc_strndup(data->ctx, key_name,
|
||||
strlen(key_name)-(strrchr(key_name, '\\')-key_name));
|
||||
blob.length = strlen((char *)blob.data)+1;
|
||||
|
||||
|
||||
/* FIXME: These values should be accumulated to be written at done(). */
|
||||
reg_preg_diff_set_value(_data, parent_name, "**DeleteKeys", REG_SZ, blob);
|
||||
|
||||
return WERR_OK;
|
||||
}
|
||||
|
||||
/* FIXME These functions need to be implemented */
|
||||
static WERROR reg_preg_diff_del_value(void *_data, const char *key_name,
|
||||
const char *value_name)
|
||||
{
|
||||
@ -81,6 +128,7 @@ static WERROR reg_preg_diff_done(void *_data)
|
||||
* Save registry diff
|
||||
*/
|
||||
_PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename,
|
||||
struct smb_iconv_convenience *ic,
|
||||
struct reg_diff_callbacks **callbacks,
|
||||
void **callback_data)
|
||||
{
|
||||
@ -103,10 +151,14 @@ _PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename,
|
||||
} else {
|
||||
data->fd = STDOUT_FILENO;
|
||||
}
|
||||
|
||||
memcpy(preg_header.hdr, "PReg", 4);
|
||||
SIVAL(&preg_header, 4, 1);
|
||||
write(data->fd, (uint8_t *)&preg_header,8);
|
||||
|
||||
data->ctx = ctx;
|
||||
data->ic = ic;
|
||||
|
||||
*callbacks = talloc(ctx, struct reg_diff_callbacks);
|
||||
|
||||
(*callbacks)->add_key = reg_preg_diff_add_key;
|
||||
@ -179,7 +231,8 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd,
|
||||
*buf_ptr != ';' && buf_ptr-buf < buf_size) {
|
||||
buf_ptr++;
|
||||
}
|
||||
key = talloc_asprintf(mem_ctx, "\\%s", buf);
|
||||
buf[buf_ptr-buf] = '\0';
|
||||
key = talloc_strdup(mem_ctx, buf);
|
||||
|
||||
/* Get the name */
|
||||
buf_ptr = buf;
|
||||
@ -187,6 +240,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd,
|
||||
*buf_ptr != ';' && buf_ptr-buf < buf_size) {
|
||||
buf_ptr++;
|
||||
}
|
||||
buf[buf_ptr-buf] = '\0';
|
||||
value_name = talloc_strdup(mem_ctx, buf);
|
||||
|
||||
/* Get the type */
|
||||
|
@ -493,6 +493,7 @@ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename,
|
||||
struct reg_diff_callbacks **callbacks,
|
||||
void **callback_data);
|
||||
WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename,
|
||||
struct smb_iconv_convenience *ic,
|
||||
struct reg_diff_callbacks **callbacks,
|
||||
void **callback_data);
|
||||
WERROR reg_generate_diff_key(struct registry_key *oldkey,
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "lib/registry/registry.h"
|
||||
#include "torture/torture.h"
|
||||
#include "librpc/gen_ndr/winreg.h"
|
||||
#include "param/param.h"
|
||||
|
||||
struct diff_tcase_data {
|
||||
struct registry_context *r1_ctx;
|
||||
@ -56,13 +57,12 @@ static bool test_generate_diff(struct torture_context *tctx, void *tcase_data)
|
||||
static bool test_diff_load(struct torture_context *tctx, void *tcase_data)
|
||||
{
|
||||
struct diff_tcase_data *td = tcase_data;
|
||||
struct smb_iconv_convenience *iconv_convenience;
|
||||
struct smb_iconv_convenience *ic;
|
||||
struct reg_diff_callbacks *callbacks;
|
||||
void *data;
|
||||
WERROR error;
|
||||
|
||||
iconv_convenience = smb_iconv_convenience_init(tctx, "CP850", "UTF-8", 1);
|
||||
|
||||
ic = lp_iconv_convenience(tctx->lp_ctx);
|
||||
|
||||
error = reg_diff_load(td->filename, iconv_convenience, callbacks, data);
|
||||
torture_assert_werr_ok(tctx, error, "reg_diff_load");
|
||||
@ -244,13 +244,16 @@ static bool diff_setup_tcase(struct torture_context *tctx, void **data)
|
||||
static bool diff_setup_preg_tcase (struct torture_context *tctx, void **data)
|
||||
{
|
||||
struct diff_tcase_data *td;
|
||||
struct smb_iconv_convenience *ic;
|
||||
WERROR error;
|
||||
|
||||
diff_setup_tcase(tctx, data);
|
||||
td = *data;
|
||||
|
||||
|
||||
ic = lp_iconv_convenience(tctx->lp_ctx);
|
||||
|
||||
td->filename = talloc_asprintf(tctx, "%s/test.pol", td->tempdir);
|
||||
error = reg_preg_diff_save(tctx, td->filename, &td->callbacks, &td->callback_data);
|
||||
error = reg_preg_diff_save(tctx, td->filename, ic, &td->callbacks, &td->callback_data);
|
||||
torture_assert_werr_ok(tctx, error, "reg_preg_diff_save");
|
||||
|
||||
return true;
|
||||
@ -259,16 +262,16 @@ static bool diff_setup_preg_tcase (struct torture_context *tctx, void **data)
|
||||
static bool diff_setup_dotreg_tcase (struct torture_context *tctx, void **data)
|
||||
{
|
||||
struct diff_tcase_data *td;
|
||||
struct smb_iconv_convenience *iconv_convenience;
|
||||
struct smb_iconv_convenience *ic;
|
||||
WERROR error;
|
||||
|
||||
diff_setup_tcase(tctx, data);
|
||||
td = *data;
|
||||
|
||||
iconv_convenience = smb_iconv_convenience_init(tctx, "CP850", "UTF-8", 1);
|
||||
ic = lp_iconv_convenience(tctx->lp_ctx);
|
||||
|
||||
td->filename = talloc_asprintf(tctx, "%s/test.reg", td->tempdir);
|
||||
error = reg_dotreg_diff_save(tctx, td->filename, iconv_convenience, &td->callbacks, &td->callback_data);
|
||||
error = reg_dotreg_diff_save(tctx, td->filename, ic, &td->callbacks, &td->callback_data);
|
||||
torture_assert_werr_ok(tctx, error, "reg_dotreg_diff_save");
|
||||
|
||||
return true;
|
||||
|
Loading…
Reference in New Issue
Block a user