2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
5 * Copyright (C) Gerald Carter 2002-2006.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
21 /* Implementation of registry functions. */
24 #include "../librpc/gen_ndr/srv_winreg.h"
25 #include "registry/reg_parse_prs.h"
27 #include "registry/reg_perfcount.h"
30 #define DBGC_CLASS DBGC_RPC_SRV
32 /******************************************************************
33 Find a registry key handle and return a struct registry_key *
34 *****************************************************************/
36 static struct registry_key *find_regkey_by_hnd(struct pipes_struct *p,
37 struct policy_handle *hnd)
39 struct registry_key *regkey = NULL;
41 if(!find_policy_by_hnd(p,hnd,(void **)(void *)®key)) {
42 DEBUG(2,("find_regkey_index_by_hnd: Registry Key not found: "));
49 /*******************************************************************
50 Function for open a new registry handle and creating a handle
51 Note that P should be valid & hnd should already have space
53 When we open a key, we store the full path to the key as
54 HK[LM|U]\<key>\<key>\...
55 *******************************************************************/
57 static WERROR open_registry_key(struct pipes_struct *p,
58 struct policy_handle *hnd,
59 struct registry_key *parent,
60 const char *subkeyname,
61 uint32_t access_desired)
63 WERROR result = WERR_OK;
64 struct registry_key *key;
67 result = reg_openhive(p->mem_ctx, subkeyname, access_desired,
68 p->server_info->ptok, &key);
71 result = reg_openkey(p->mem_ctx, parent, subkeyname,
72 access_desired, &key);
75 if ( !W_ERROR_IS_OK(result) ) {
79 if ( !create_policy_hnd( p, hnd, key ) ) {
86 /*******************************************************************
87 Function for open a new registry handle and creating a handle
88 Note that P should be valid & hnd should already have space
89 *******************************************************************/
91 static bool close_registry_key(struct pipes_struct *p,
92 struct policy_handle *hnd)
94 struct registry_key *regkey = find_regkey_by_hnd(p, hnd);
97 DEBUG(2,("close_registry_key: Invalid handle (%s:%u:%u)\n",
102 close_policy_hnd(p, hnd);
107 /********************************************************************
109 ********************************************************************/
111 WERROR _winreg_CloseKey(struct pipes_struct *p,
112 struct winreg_CloseKey *r)
114 /* close the policy handle */
116 if (!close_registry_key(p, r->in.handle))
119 ZERO_STRUCTP(r->out.handle);
124 /*******************************************************************
126 ********************************************************************/
128 WERROR _winreg_OpenHKLM(struct pipes_struct *p,
129 struct winreg_OpenHKLM *r)
131 return open_registry_key(p, r->out.handle, NULL, KEY_HKLM, r->in.access_mask);
134 /*******************************************************************
136 ********************************************************************/
138 WERROR _winreg_OpenHKPD(struct pipes_struct *p,
139 struct winreg_OpenHKPD *r)
141 return open_registry_key(p, r->out.handle, NULL, KEY_HKPD, r->in.access_mask);
144 /*******************************************************************
146 ********************************************************************/
148 WERROR _winreg_OpenHKPT(struct pipes_struct *p,
149 struct winreg_OpenHKPT *r)
151 return open_registry_key(p, r->out.handle, NULL, KEY_HKPT, r->in.access_mask);
154 /*******************************************************************
156 ********************************************************************/
158 WERROR _winreg_OpenHKCR(struct pipes_struct *p,
159 struct winreg_OpenHKCR *r)
161 return open_registry_key(p, r->out.handle, NULL, KEY_HKCR, r->in.access_mask);
164 /*******************************************************************
166 ********************************************************************/
168 WERROR _winreg_OpenHKU(struct pipes_struct *p,
169 struct winreg_OpenHKU *r)
171 return open_registry_key(p, r->out.handle, NULL, KEY_HKU, r->in.access_mask);
174 /*******************************************************************
176 ********************************************************************/
178 WERROR _winreg_OpenHKCU(struct pipes_struct *p,
179 struct winreg_OpenHKCU *r)
181 return open_registry_key(p, r->out.handle, NULL, KEY_HKCU, r->in.access_mask);
184 /*******************************************************************
186 ********************************************************************/
188 WERROR _winreg_OpenHKCC(struct pipes_struct *p,
189 struct winreg_OpenHKCC *r)
191 return open_registry_key(p, r->out.handle, NULL, KEY_HKCC, r->in.access_mask);
194 /*******************************************************************
196 ********************************************************************/
198 WERROR _winreg_OpenHKDD(struct pipes_struct *p,
199 struct winreg_OpenHKDD *r)
201 return open_registry_key(p, r->out.handle, NULL, KEY_HKDD, r->in.access_mask);
204 /*******************************************************************
206 ********************************************************************/
208 WERROR _winreg_OpenHKPN(struct pipes_struct *p,
209 struct winreg_OpenHKPN *r)
211 return open_registry_key(p, r->out.handle, NULL, KEY_HKPN, r->in.access_mask);
214 /*******************************************************************
216 ********************************************************************/
218 WERROR _winreg_OpenKey(struct pipes_struct *p,
219 struct winreg_OpenKey *r)
221 struct registry_key *parent = find_regkey_by_hnd(p, r->in.parent_handle );
226 return open_registry_key(p, r->out.handle, parent, r->in.keyname.name, r->in.access_mask);
229 /*******************************************************************
231 ********************************************************************/
233 WERROR _winreg_QueryValue(struct pipes_struct *p,
234 struct winreg_QueryValue *r)
236 WERROR status = WERR_BADFILE;
237 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
240 uint8_t *outbuf = NULL;
241 uint32_t outbuf_size = 0;
243 bool free_buf = False;
244 bool free_prs = False;
249 if (r->in.value_name->name == NULL) {
250 return WERR_INVALID_PARAM;
253 if ((r->out.data_length == NULL) || (r->out.type == NULL) || (r->out.data_size == NULL)) {
254 return WERR_INVALID_PARAM;
257 DEBUG(7,("_winreg_QueryValue: policy key name = [%s]\n", regkey->key->name));
258 DEBUG(7,("_winreg_QueryValue: policy key type = [%08x]\n", regkey->key->type));
260 /* Handle QueryValue calls on HKEY_PERFORMANCE_DATA */
261 if(regkey->key->type == REG_KEY_HKPD)
263 if (strequal(r->in.value_name->name, "Global")) {
264 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
266 status = reg_perfcount_get_hkpd(
267 &prs_hkpd, *r->in.data_size, &outbuf_size, NULL);
268 outbuf = (uint8_t *)prs_hkpd.data_p;
271 else if (strequal(r->in.value_name->name, "Counter 009")) {
272 outbuf_size = reg_perfcount_get_counter_names(
273 reg_perfcount_get_base_index(),
274 (char **)(void *)&outbuf);
277 else if (strequal(r->in.value_name->name, "Explain 009")) {
278 outbuf_size = reg_perfcount_get_counter_help(
279 reg_perfcount_get_base_index(),
280 (char **)(void *)&outbuf);
283 else if (isdigit(r->in.value_name->name[0])) {
284 /* we probably have a request for a specific object
286 if (!prs_init(&prs_hkpd, *r->in.data_size, p->mem_ctx, MARSHALL))
288 status = reg_perfcount_get_hkpd(
289 &prs_hkpd, *r->in.data_size, &outbuf_size,
290 r->in.value_name->name);
291 outbuf = (uint8_t *)prs_hkpd.data_p;
295 DEBUG(3,("Unsupported key name [%s] for HKPD.\n",
296 r->in.value_name->name));
300 *r->out.type = REG_BINARY;
303 struct registry_value *val;
305 status = reg_queryvalue(p->mem_ctx, regkey, r->in.value_name->name,
307 if (!W_ERROR_IS_OK(status)) {
309 DEBUG(10,("_winreg_QueryValue: reg_queryvalue failed with: %s\n",
310 win_errstr(status)));
312 if (r->out.data_size) {
313 *r->out.data_size = 0;
315 if (r->out.data_length) {
316 *r->out.data_length = 0;
321 outbuf = val->data.data;
322 outbuf_size = val->data.length;
323 *r->out.type = val->type;
326 status = WERR_BADFILE;
328 if (*r->in.data_size < outbuf_size) {
329 *r->out.data_size = outbuf_size;
330 status = r->in.data ? WERR_MORE_DATA : WERR_OK;
332 *r->out.data_length = outbuf_size;
333 *r->out.data_size = outbuf_size;
335 memcpy(r->out.data, outbuf, outbuf_size);
340 if (free_prs) prs_mem_free(&prs_hkpd);
341 if (free_buf) SAFE_FREE(outbuf);
346 /*****************************************************************************
348 ****************************************************************************/
350 WERROR _winreg_QueryInfoKey(struct pipes_struct *p,
351 struct winreg_QueryInfoKey *r)
353 WERROR status = WERR_OK;
354 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
359 r->out.classname->name = NULL;
361 status = reg_queryinfokey(regkey, r->out.num_subkeys, r->out.max_subkeylen,
362 r->out.max_classlen, r->out.num_values, r->out.max_valnamelen,
363 r->out.max_valbufsize, r->out.secdescsize,
364 r->out.last_changed_time);
365 if (!W_ERROR_IS_OK(status)) {
370 * These calculations account for the registry buffers being
371 * UTF-16. They are inexact at best, but so far they worked.
374 *r->out.max_subkeylen *= 2;
376 *r->out.max_valnamelen += 1;
377 *r->out.max_valnamelen *= 2;
383 /*****************************************************************************
385 ****************************************************************************/
387 WERROR _winreg_GetVersion(struct pipes_struct *p,
388 struct winreg_GetVersion *r)
390 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
395 return reg_getversion(r->out.version);
399 /*****************************************************************************
401 ****************************************************************************/
403 WERROR _winreg_EnumKey(struct pipes_struct *p,
404 struct winreg_EnumKey *r)
406 WERROR err = WERR_OK;
407 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
412 if ( !r->in.name || !r->in.keyclass )
413 return WERR_INVALID_PARAM;
415 DEBUG(8,("_winreg_EnumKey: enumerating key [%s]\n", key->key->name));
417 err = reg_enumkey(p->mem_ctx, key, r->in.enum_index, (char **)&r->out.name->name,
418 r->out.last_changed_time);
419 if (!W_ERROR_IS_OK(err)) {
422 r->out.keyclass->name = "";
426 /*****************************************************************************
428 ****************************************************************************/
430 WERROR _winreg_EnumValue(struct pipes_struct *p,
431 struct winreg_EnumValue *r)
433 WERROR err = WERR_OK;
434 struct registry_key *key = find_regkey_by_hnd( p, r->in.handle );
435 char *valname = NULL;
436 struct registry_value *val = NULL;
442 return WERR_INVALID_PARAM;
444 DEBUG(8,("_winreg_EnumValue: enumerating values for key [%s]\n",
447 err = reg_enumvalue(p->mem_ctx, key, r->in.enum_index, &valname, &val);
448 if (!W_ERROR_IS_OK(err)) {
452 if (r->out.name != NULL) {
453 r->out.name->name = valname;
456 if (r->out.type != NULL) {
457 *r->out.type = val->type;
460 if (r->out.value != NULL) {
461 if ((r->out.size == NULL) || (r->out.length == NULL)) {
462 return WERR_INVALID_PARAM;
465 if (val->data.length > *r->out.size) {
466 return WERR_MORE_DATA;
469 memcpy( r->out.value, val->data.data, val->data.length );
472 if (r->out.length != NULL) {
473 *r->out.length = val->data.length;
475 if (r->out.size != NULL) {
476 *r->out.size = val->data.length;
482 /*******************************************************************
483 _winreg_InitiateSystemShutdown
484 ********************************************************************/
486 WERROR _winreg_InitiateSystemShutdown(struct pipes_struct *p,
487 struct winreg_InitiateSystemShutdown *r)
489 struct winreg_InitiateSystemShutdownEx s;
491 s.in.hostname = r->in.hostname;
492 s.in.message = r->in.message;
493 s.in.timeout = r->in.timeout;
494 s.in.force_apps = r->in.force_apps;
495 s.in.do_reboot = r->in.do_reboot;
498 /* thunk down to _winreg_InitiateSystemShutdownEx()
499 (just returns a status) */
501 return _winreg_InitiateSystemShutdownEx( p, &s );
504 /*******************************************************************
505 _winreg_InitiateSystemShutdownEx
506 ********************************************************************/
508 #define SHUTDOWN_R_STRING "-r"
509 #define SHUTDOWN_F_STRING "-f"
512 WERROR _winreg_InitiateSystemShutdownEx(struct pipes_struct *p,
513 struct winreg_InitiateSystemShutdownEx *r)
515 char *shutdown_script = NULL;
523 bool can_shutdown = false;
525 shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
526 if (!shutdown_script) {
529 if (!*shutdown_script) {
530 return WERR_ACCESS_DENIED;
533 /* pull the message string and perform necessary sanity checks on it */
535 if ( r->in.message && r->in.message->string ) {
536 if ( (msg = talloc_strdup(p->mem_ctx, r->in.message->string )) == NULL ) {
539 chkmsg = TALLOC_ARRAY(p->mem_ctx, char, strlen(msg)+1);
543 alpha_strcpy(chkmsg, msg, NULL, strlen(msg)+1);
546 fstr_sprintf(str_timeout, "%d", r->in.timeout);
547 fstr_sprintf(do_reboot, r->in.do_reboot ? SHUTDOWN_R_STRING : "");
548 fstr_sprintf(f, r->in.force_apps ? SHUTDOWN_F_STRING : "");
549 fstr_sprintf(str_reason, "%d", r->in.reason );
551 shutdown_script = talloc_all_string_sub(p->mem_ctx,
552 shutdown_script, "%z", chkmsg ? chkmsg : "");
553 if (!shutdown_script) {
556 shutdown_script = talloc_all_string_sub(p->mem_ctx,
557 shutdown_script, "%t", str_timeout);
558 if (!shutdown_script) {
561 shutdown_script = talloc_all_string_sub(p->mem_ctx,
562 shutdown_script, "%r", do_reboot);
563 if (!shutdown_script) {
566 shutdown_script = talloc_all_string_sub(p->mem_ctx,
567 shutdown_script, "%f", f);
568 if (!shutdown_script) {
571 shutdown_script = talloc_all_string_sub(p->mem_ctx,
572 shutdown_script, "%x", str_reason);
573 if (!shutdown_script) {
577 can_shutdown = user_has_privileges( p->server_info->ptok,
578 &se_remote_shutdown );
580 /* IF someone has privs, run the shutdown script as root. OTHERWISE run it as not root
581 Take the error return from the script and provide it as the Windows return code. */
583 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
588 ret = smbrun( shutdown_script, NULL );
593 /********** END SeRemoteShutdownPrivilege BLOCK **********/
595 DEBUG(3,("_reg_shutdown_ex: Running the command `%s' gave %d\n",
596 shutdown_script, ret));
598 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
601 /*******************************************************************
602 _winreg_AbortSystemShutdown
603 ********************************************************************/
605 WERROR _winreg_AbortSystemShutdown(struct pipes_struct *p,
606 struct winreg_AbortSystemShutdown *r)
608 const char *abort_shutdown_script = lp_abort_shutdown_script();
610 bool can_shutdown = false;
612 if (!*abort_shutdown_script)
613 return WERR_ACCESS_DENIED;
615 can_shutdown = user_has_privileges( p->server_info->ptok,
616 &se_remote_shutdown );
618 /********** BEGIN SeRemoteShutdownPrivilege BLOCK **********/
623 ret = smbrun( abort_shutdown_script, NULL );
628 /********** END SeRemoteShutdownPrivilege BLOCK **********/
630 DEBUG(3,("_winreg_AbortSystemShutdown: Running the command `%s' gave %d\n",
631 abort_shutdown_script, ret));
633 return (ret == 0) ? WERR_OK : WERR_ACCESS_DENIED;
636 /*******************************************************************
637 ********************************************************************/
639 static int validate_reg_filename(TALLOC_CTX *ctx, char **pp_fname )
642 int num_services = lp_numservices();
644 const char *share_path = NULL;
645 char *fname = *pp_fname;
647 /* convert to a unix path, stripping the C:\ along the way */
649 if (!(p = valid_share_pathname(ctx, fname))) {
653 /* has to exist within a valid file share */
655 for (snum=0; snum<num_services; snum++) {
656 if (!lp_snum_ok(snum) || lp_print_ok(snum)) {
660 share_path = lp_pathname(snum);
662 /* make sure we have a path (e.g. [homes] ) */
663 if (strlen(share_path) == 0) {
667 if (strncmp(share_path, p, strlen(share_path)) == 0) {
673 return (snum < num_services) ? snum : -1;
676 /*******************************************************************
678 ********************************************************************/
680 WERROR _winreg_RestoreKey(struct pipes_struct *p,
681 struct winreg_RestoreKey *r)
683 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
690 if ( !r->in.filename || !r->in.filename->name )
691 return WERR_INVALID_PARAM;
693 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
698 DEBUG(8,("_winreg_RestoreKey: verifying restore of key [%s] from "
699 "\"%s\"\n", regkey->key->name, fname));
701 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1)
702 return WERR_OBJECT_PATH_INVALID;
704 /* user must posses SeRestorePrivilege for this this proceed */
706 if ( !user_has_privileges( p->server_info->ptok, &se_restore ) )
707 return WERR_ACCESS_DENIED;
709 DEBUG(2,("_winreg_RestoreKey: Restoring [%s] from %s in share %s\n",
710 regkey->key->name, fname, lp_servicename(snum) ));
712 return reg_restorekey(regkey, fname);
715 /*******************************************************************
717 ********************************************************************/
719 WERROR _winreg_SaveKey(struct pipes_struct *p,
720 struct winreg_SaveKey *r)
722 struct registry_key *regkey = find_regkey_by_hnd( p, r->in.handle );
729 if ( !r->in.filename || !r->in.filename->name )
730 return WERR_INVALID_PARAM;
732 fname = talloc_strdup(p->mem_ctx, r->in.filename->name);
737 DEBUG(8,("_winreg_SaveKey: verifying backup of key [%s] to \"%s\"\n",
738 regkey->key->name, fname));
740 if ((snum = validate_reg_filename(p->mem_ctx, &fname)) == -1 )
741 return WERR_OBJECT_PATH_INVALID;
743 DEBUG(2,("_winreg_SaveKey: Saving [%s] to %s in share %s\n",
744 regkey->key->name, fname, lp_servicename(snum) ));
746 return reg_savekey(regkey, fname);
749 /*******************************************************************
751 ********************************************************************/
753 WERROR _winreg_SaveKeyEx(struct pipes_struct *p,
754 struct winreg_SaveKeyEx *r)
756 /* fill in your code here if you think this call should
759 p->rng_fault_state = True;
760 return WERR_NOT_SUPPORTED;
763 /*******************************************************************
765 ********************************************************************/
767 WERROR _winreg_CreateKey(struct pipes_struct *p,
768 struct winreg_CreateKey *r)
770 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
771 struct registry_key *new_key = NULL;
772 WERROR result = WERR_OK;
777 DEBUG(10, ("_winreg_CreateKey called with parent key '%s' and "
778 "subkey name '%s'\n", parent->key->name, r->in.name.name));
780 result = reg_createkey(NULL, parent, r->in.name.name, r->in.access_mask,
781 &new_key, r->out.action_taken);
782 if (!W_ERROR_IS_OK(result)) {
786 if (!create_policy_hnd(p, r->out.new_handle, new_key)) {
787 TALLOC_FREE(new_key);
794 /*******************************************************************
796 ********************************************************************/
798 WERROR _winreg_SetValue(struct pipes_struct *p,
799 struct winreg_SetValue *r)
801 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
802 struct registry_value *val = NULL;
807 DEBUG(8,("_winreg_SetValue: Setting value for [%s:%s]\n",
808 key->key->name, r->in.name.name));
810 val = talloc_zero(p->mem_ctx, struct registry_value);
815 val->type = r->in.type;
816 val->data = data_blob_talloc(p->mem_ctx, r->in.data, r->in.size);
818 return reg_setvalue(key, r->in.name.name, val);
821 /*******************************************************************
823 ********************************************************************/
825 WERROR _winreg_DeleteKey(struct pipes_struct *p,
826 struct winreg_DeleteKey *r)
828 struct registry_key *parent = find_regkey_by_hnd(p, r->in.handle);
833 return reg_deletekey(parent, r->in.key.name);
837 /*******************************************************************
839 ********************************************************************/
841 WERROR _winreg_DeleteValue(struct pipes_struct *p,
842 struct winreg_DeleteValue *r)
844 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
849 return reg_deletevalue(key, r->in.value.name);
852 /*******************************************************************
853 _winreg_GetKeySecurity
854 ********************************************************************/
856 WERROR _winreg_GetKeySecurity(struct pipes_struct *p,
857 struct winreg_GetKeySecurity *r)
859 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
860 WERROR err = WERR_OK;
861 struct security_descriptor *secdesc = NULL;
868 /* access checks first */
870 if ( !(key->key->access_granted & SEC_STD_READ_CONTROL) )
871 return WERR_ACCESS_DENIED;
873 err = reg_getkeysecurity(p->mem_ctx, key, &secdesc);
874 if (!W_ERROR_IS_OK(err)) {
878 err = ntstatus_to_werror(marshall_sec_desc(p->mem_ctx, secdesc,
880 if (!W_ERROR_IS_OK(err)) {
884 if (len > r->out.sd->size) {
885 r->out.sd->size = len;
886 return WERR_INSUFFICIENT_BUFFER;
889 r->out.sd->size = len;
890 r->out.sd->len = len;
891 r->out.sd->data = data;
896 /*******************************************************************
897 _winreg_SetKeySecurity
898 ********************************************************************/
900 WERROR _winreg_SetKeySecurity(struct pipes_struct *p,
901 struct winreg_SetKeySecurity *r)
903 struct registry_key *key = find_regkey_by_hnd(p, r->in.handle);
904 struct security_descriptor *secdesc = NULL;
905 WERROR err = WERR_OK;
910 /* access checks first */
912 if ( !(key->key->access_granted & SEC_STD_WRITE_DAC) )
913 return WERR_ACCESS_DENIED;
915 err = ntstatus_to_werror(unmarshall_sec_desc(p->mem_ctx, r->in.sd->data,
916 r->in.sd->len, &secdesc));
917 if (!W_ERROR_IS_OK(err)) {
921 return reg_setkeysecurity(key, secdesc);
924 /*******************************************************************
926 ********************************************************************/
928 WERROR _winreg_FlushKey(struct pipes_struct *p,
929 struct winreg_FlushKey *r)
931 /* I'm just replying OK because there's not a lot
932 here I see to do i --jerry */
937 /*******************************************************************
939 ********************************************************************/
941 WERROR _winreg_UnLoadKey(struct pipes_struct *p,
942 struct winreg_UnLoadKey *r)
944 /* fill in your code here if you think this call should
947 p->rng_fault_state = True;
948 return WERR_NOT_SUPPORTED;
951 /*******************************************************************
953 ********************************************************************/
955 WERROR _winreg_ReplaceKey(struct pipes_struct *p,
956 struct winreg_ReplaceKey *r)
958 /* fill in your code here if you think this call should
961 p->rng_fault_state = True;
962 return WERR_NOT_SUPPORTED;
965 /*******************************************************************
967 ********************************************************************/
969 WERROR _winreg_LoadKey(struct pipes_struct *p,
970 struct winreg_LoadKey *r)
972 /* fill in your code here if you think this call should
975 p->rng_fault_state = True;
976 return WERR_NOT_SUPPORTED;
979 /*******************************************************************
980 _winreg_NotifyChangeKeyValue
981 ********************************************************************/
983 WERROR _winreg_NotifyChangeKeyValue(struct pipes_struct *p,
984 struct winreg_NotifyChangeKeyValue *r)
986 return WERR_NOT_SUPPORTED;
989 /*******************************************************************
990 _winreg_QueryMultipleValues
991 ********************************************************************/
993 WERROR _winreg_QueryMultipleValues(struct pipes_struct *p,
994 struct winreg_QueryMultipleValues *r)
996 struct winreg_QueryMultipleValues2 r2;
999 r2.in.key_handle = r->in.key_handle;
1000 r2.in.values_in = r->in.values_in;
1001 r2.in.num_values = r->in.num_values;
1002 r2.in.offered = r->in.buffer_size;
1003 r2.in.buffer = r->in.buffer;
1004 r2.out.values_out = r->out.values_out;
1005 r2.out.needed = &needed;
1006 r2.out.buffer = r->out.buffer;
1008 return _winreg_QueryMultipleValues2(p, &r2);
1011 /*******************************************************************
1012 ********************************************************************/
1014 static WERROR construct_multiple_entry(TALLOC_CTX *mem_ctx,
1015 const char *valuename,
1016 uint32_t value_length,
1018 enum winreg_Type type,
1019 struct QueryMultipleValue *r)
1021 r->ve_valuename = talloc_zero(mem_ctx, struct winreg_ValNameBuf);
1022 if (r->ve_valuename == NULL) {
1026 r->ve_valuename->name = talloc_strdup(r->ve_valuename, valuename ? valuename : "");
1027 if (r->ve_valuename->name == NULL) {
1031 r->ve_valuename->size = strlen_m_term(r->ve_valuename->name)*2;
1032 r->ve_valuelen = value_length;
1033 r->ve_valueptr = offset;
1039 /*******************************************************************
1040 _winreg_QueryMultipleValues2
1041 ********************************************************************/
1043 WERROR _winreg_QueryMultipleValues2(struct pipes_struct *p,
1044 struct winreg_QueryMultipleValues2 *r)
1046 struct registry_key *regkey = find_regkey_by_hnd(p, r->in.key_handle);
1047 struct registry_value *vals = NULL;
1048 const char **names = NULL;
1049 uint32_t offset = 0, num_vals = 0;
1050 DATA_BLOB result = data_blob_null;
1052 WERROR err = WERR_OK;
1058 names = talloc_zero_array(p->mem_ctx, const char *, r->in.num_values);
1059 if (names == NULL) {
1063 for (i=0; i < r->in.num_values; i++) {
1064 if (r->in.values_in[i].ve_valuename &&
1065 r->in.values_in[i].ve_valuename->name) {
1066 names[i] = talloc_strdup(names,
1067 r->in.values_in[i].ve_valuename->name);
1068 if (names[i] == NULL) {
1074 err = reg_querymultiplevalues(p->mem_ctx, regkey,
1075 r->in.num_values, names,
1077 if (!W_ERROR_IS_OK(err)) {
1081 result = data_blob_talloc(p->mem_ctx, NULL, 0);
1083 for (i=0; i < r->in.num_values; i++) {
1084 const char *valuename = NULL;
1086 if (vals[i].data.length > 0) {
1087 if (!data_blob_append(p->mem_ctx, &result,
1089 vals[i].data.length)) {
1094 if (r->in.values_in[i].ve_valuename &&
1095 r->in.values_in[i].ve_valuename->name) {
1096 valuename = r->in.values_in[i].ve_valuename->name;
1099 err = construct_multiple_entry(r->out.values_out,
1101 vals[i].data.length,
1104 &r->out.values_out[i]);
1105 if (!W_ERROR_IS_OK(err)) {
1109 offset += vals[i].data.length;
1112 *r->out.needed = result.length;
1114 if (r->in.num_values != num_vals) {
1115 return WERR_BADFILE;
1118 if (*r->in.offered >= *r->out.needed) {
1119 if (r->out.buffer) {
1120 memcpy(r->out.buffer, result.data, MIN(result.length, *r->in.offered));
1124 return WERR_MORE_DATA;
1128 /*******************************************************************
1130 ********************************************************************/
1132 WERROR _winreg_DeleteKeyEx(struct pipes_struct *p,
1133 struct winreg_DeleteKeyEx *r)
1135 /* fill in your code here if you think this call should
1138 p->rng_fault_state = True;
1139 return WERR_NOT_SUPPORTED;