ChangeLog: * Implement registry key unloading
Index: server/protocol.def =================================================================== RCS file: /home/wine/wine/server/protocol.def,v retrieving revision 1.78 diff -u -r1.78 protocol.def --- server/protocol.def 26 Jul 2003 20:36:43 -0000 1.78 +++ server/protocol.def 15 Aug 2003 08:07:55 -0000 @@ -1387,6 +1387,12 @@ @END +/* UnLoad a registry branch from a file */ +@REQ(unload_registry) + obj_handle_t hkey; /* root key to unload to */ +@END + + /* Save a registry branch to a file */ @REQ(save_registry) obj_handle_t hkey; /* key to save */ Index: server/registry.c =================================================================== RCS file: /home/wine/wine/server/registry.c,v retrieving revision 1.51 diff -u -r1.51 registry.c --- server/registry.c 18 Jun 2003 19:45:22 -0000 1.51 +++ server/registry.c 15 Aug 2003 08:07:56 -0000 @@ -770,7 +770,7 @@ } /* delete a key and its values */ -static void delete_key( struct key *key ) +static int delete_key( struct key *key, int recurse ) { int index; struct key *parent; @@ -779,13 +779,18 @@ if (key->flags & KEY_ROOT) { set_error( STATUS_ACCESS_DENIED ); - return; + return -1; } if (!(parent = key->parent) || (key->flags & KEY_DELETED)) { set_error( STATUS_KEY_DELETED ); - return; + return -1; } + + while (recurse && (key->last_subkey>=0)) + if(0>delete_key(key->subkeys[key->last_subkey], 1)) + return -1; + for (index = 0; index <= parent->last_subkey; index++) if (parent->subkeys[index] == key) break; assert( index <= parent->last_subkey ); @@ -794,11 +799,13 @@ if ((key->flags & KEY_ROOT) || (key->last_subkey >= 0)) { set_error( STATUS_ACCESS_DENIED ); - return; + return -1; } + if (debug_level > 1) dump_operation( key, NULL, "Delete" ); free_subkey( parent, index ); touch_key( parent, REG_NOTIFY_CHANGE_NAME ); + return 0; } /* try to grow the array of values; return 1 if OK, 0 on error */ @@ -1764,7 +1771,7 @@ if ((key = get_hkey_obj( req->hkey, 0 /*FIXME*/ ))) { - delete_key( key ); + delete_key( key, 0); release_object( key ); } } @@ -1852,6 +1859,17 @@ { /* FIXME: use subkey name */ load_registry( key, req->file ); + release_object( key ); + } +} + +DECL_HANDLER(unload_registry) +{ + struct key *key; + + if ((key = get_hkey_obj( req->hkey, 0 ))) + { + delete_key( key, 1 ); /* FIXME */ release_object( key ); } } Index: server/request.h =================================================================== RCS file: /home/wine/wine/server/request.h,v retrieving revision 1.87 diff -u -r1.87 request.h --- server/request.h 24 Jul 2003 00:07:00 -0000 1.87 +++ server/request.h 15 Aug 2003 08:07:57 -0000 @@ -206,6 +206,7 @@ DECL_HANDLER(enum_key_value); DECL_HANDLER(delete_key_value); DECL_HANDLER(load_registry); +DECL_HANDLER(unload_registry); DECL_HANDLER(save_registry); DECL_HANDLER(save_registry_atexit); DECL_HANDLER(set_registry_levels); @@ -389,6 +390,7 @@ (req_handler)req_enum_key_value, (req_handler)req_delete_key_value, (req_handler)req_load_registry, + (req_handler)req_unload_registry, (req_handler)req_save_registry, (req_handler)req_save_registry_atexit, (req_handler)req_set_registry_levels, Index: server/trace.c =================================================================== RCS file: /home/wine/wine/server/trace.c,v retrieving revision 1.175 diff -u -r1.175 trace.c --- server/trace.c 26 Jul 2003 20:36:43 -0000 1.175 +++ server/trace.c 15 Aug 2003 08:07:58 -0000 @@ -1625,6 +1625,11 @@ dump_varargs_unicode_str( cur_size ); } +static void dump_unload_registry_request( const struct unload_registry_request *req ) +{ + fprintf( stderr, " hkey=%p", req->hkey ); +} + static void dump_save_registry_request( const struct save_registry_request *req ) { fprintf( stderr, " hkey=%p,", req->hkey ); @@ -2602,6 +2607,7 @@ (dump_func)dump_enum_key_value_request, (dump_func)dump_delete_key_value_request, (dump_func)dump_load_registry_request, + (dump_func)dump_unload_registry_request, (dump_func)dump_save_registry_request, (dump_func)dump_save_registry_atexit_request, (dump_func)dump_set_registry_levels_request, @@ -2786,6 +2792,7 @@ (dump_func)0, (dump_func)0, (dump_func)0, + (dump_func)0, (dump_func)dump_create_timer_reply, (dump_func)dump_open_timer_reply, (dump_func)dump_set_timer_reply, @@ -2962,6 +2969,7 @@ "enum_key_value", "delete_key_value", "load_registry", + "unload_registry", "save_registry", "save_registry_atexit", "set_registry_levels", Index: include/wine/server_protocol.h =================================================================== RCS file: /home/wine/wine/include/wine/server_protocol.h,v retrieving revision 1.78 diff -u -r1.78 server_protocol.h --- include/wine/server_protocol.h 26 Jul 2003 20:36:43 -0000 1.78 +++ include/wine/server_protocol.h 15 Aug 2003 08:07:59 -0000 @@ -1919,6 +1919,18 @@ +struct unload_registry_request +{ + struct request_header __header; + obj_handle_t hkey; +}; +struct unload_registry_reply +{ + struct reply_header __header; +}; + + + struct save_registry_request { struct request_header __header; @@ -3205,6 +3217,7 @@ REQ_enum_key_value, REQ_delete_key_value, REQ_load_registry, + REQ_unload_registry, REQ_save_registry, REQ_save_registry_atexit, REQ_set_registry_levels, @@ -3389,6 +3402,7 @@ struct enum_key_value_request enum_key_value_request; struct delete_key_value_request delete_key_value_request; struct load_registry_request load_registry_request; + struct unload_registry_request unload_registry_request; struct save_registry_request save_registry_request; struct save_registry_atexit_request save_registry_atexit_request; struct set_registry_levels_request set_registry_levels_request; @@ -3571,6 +3585,7 @@ struct enum_key_value_reply enum_key_value_reply; struct delete_key_value_reply delete_key_value_reply; struct load_registry_reply load_registry_reply; + struct unload_registry_reply unload_registry_reply; struct save_registry_reply save_registry_reply; struct save_registry_atexit_reply save_registry_atexit_reply; struct set_registry_levels_reply set_registry_levels_reply; @@ -3647,6 +3662,6 @@ struct open_token_reply open_token_reply; }; -#define SERVER_PROTOCOL_VERSION 118 +#define SERVER_PROTOCOL_VERSION 119 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ Index: dlls/advapi32/registry.c =================================================================== RCS file: /home/wine/wine/dlls/advapi32/registry.c,v retrieving revision 1.53 diff -u -r1.53 registry.c --- dlls/advapi32/registry.c 18 Jun 2003 19:45:23 -0000 1.53 +++ dlls/advapi32/registry.c 15 Aug 2003 08:08:00 -0000 @@ -1669,8 +1669,24 @@ */ LONG WINAPI RegUnLoadKeyW( HKEY hkey, LPCWSTR lpSubKey ) { - FIXME("(%p,%s): stub\n",hkey, debugstr_w(lpSubKey)); - return ERROR_SUCCESS; + DWORD ret; + HKEY shkey; + + TRACE("(%p,%s)\n",hkey, debugstr_w(lpSubKey)); + + ret = RegOpenKeyW(hkey,lpSubKey,&shkey); + if( ret ) + return ERROR_INVALID_PARAMETER; + + SERVER_START_REQ( unload_registry ) + { + req->hkey = shkey; + ret = RtlNtStatusToDosError( wine_server_call(req) ); + } + SERVER_END_REQ; + RegCloseKey(shkey); + + return ret; }