Implement registry key unloading.
This commit is contained in:
parent
449d10fd79
commit
5ac945c021
@ -1669,8 +1669,24 @@ LONG WINAPI RegRestoreKeyA( HKEY hkey, LPCSTR lpFile, DWORD dwFlags )
|
|||||||
*/
|
*/
|
||||||
LONG WINAPI RegUnLoadKeyW( HKEY hkey, LPCWSTR lpSubKey )
|
LONG WINAPI RegUnLoadKeyW( HKEY hkey, LPCWSTR lpSubKey )
|
||||||
{
|
{
|
||||||
FIXME("(%p,%s): stub\n",hkey, debugstr_w(lpSubKey));
|
DWORD ret;
|
||||||
return ERROR_SUCCESS;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1918,6 +1918,18 @@ struct load_registry_reply
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 save_registry_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
@ -3204,6 +3216,7 @@ enum request
|
|||||||
REQ_enum_key_value,
|
REQ_enum_key_value,
|
||||||
REQ_delete_key_value,
|
REQ_delete_key_value,
|
||||||
REQ_load_registry,
|
REQ_load_registry,
|
||||||
|
REQ_unload_registry,
|
||||||
REQ_save_registry,
|
REQ_save_registry,
|
||||||
REQ_save_registry_atexit,
|
REQ_save_registry_atexit,
|
||||||
REQ_set_registry_levels,
|
REQ_set_registry_levels,
|
||||||
@ -3388,6 +3401,7 @@ union generic_request
|
|||||||
struct enum_key_value_request enum_key_value_request;
|
struct enum_key_value_request enum_key_value_request;
|
||||||
struct delete_key_value_request delete_key_value_request;
|
struct delete_key_value_request delete_key_value_request;
|
||||||
struct load_registry_request load_registry_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_request save_registry_request;
|
||||||
struct save_registry_atexit_request save_registry_atexit_request;
|
struct save_registry_atexit_request save_registry_atexit_request;
|
||||||
struct set_registry_levels_request set_registry_levels_request;
|
struct set_registry_levels_request set_registry_levels_request;
|
||||||
@ -3570,6 +3584,7 @@ union generic_reply
|
|||||||
struct enum_key_value_reply enum_key_value_reply;
|
struct enum_key_value_reply enum_key_value_reply;
|
||||||
struct delete_key_value_reply delete_key_value_reply;
|
struct delete_key_value_reply delete_key_value_reply;
|
||||||
struct load_registry_reply load_registry_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_reply save_registry_reply;
|
||||||
struct save_registry_atexit_reply save_registry_atexit_reply;
|
struct save_registry_atexit_reply save_registry_atexit_reply;
|
||||||
struct set_registry_levels_reply set_registry_levels_reply;
|
struct set_registry_levels_reply set_registry_levels_reply;
|
||||||
@ -3646,6 +3661,6 @@ union generic_reply
|
|||||||
struct open_token_reply open_token_reply;
|
struct open_token_reply open_token_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 119
|
#define SERVER_PROTOCOL_VERSION 120
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
@ -1386,6 +1386,12 @@ enum char_info_mode
|
|||||||
@END
|
@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 */
|
/* Save a registry branch to a file */
|
||||||
@REQ(save_registry)
|
@REQ(save_registry)
|
||||||
obj_handle_t hkey; /* key to save */
|
obj_handle_t hkey; /* key to save */
|
||||||
|
@ -770,7 +770,7 @@ static void enum_key( const struct key *key, int index, int info_class,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* delete a key and its values */
|
/* delete a key and its values */
|
||||||
static void delete_key( struct key *key )
|
static int delete_key( struct key *key, int recurse )
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
struct key *parent;
|
struct key *parent;
|
||||||
@ -779,13 +779,18 @@ static void delete_key( struct key *key )
|
|||||||
if (key->flags & KEY_ROOT)
|
if (key->flags & KEY_ROOT)
|
||||||
{
|
{
|
||||||
set_error( STATUS_ACCESS_DENIED );
|
set_error( STATUS_ACCESS_DENIED );
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
if (!(parent = key->parent) || (key->flags & KEY_DELETED))
|
if (!(parent = key->parent) || (key->flags & KEY_DELETED))
|
||||||
{
|
{
|
||||||
set_error( STATUS_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++)
|
for (index = 0; index <= parent->last_subkey; index++)
|
||||||
if (parent->subkeys[index] == key) break;
|
if (parent->subkeys[index] == key) break;
|
||||||
assert( index <= parent->last_subkey );
|
assert( index <= parent->last_subkey );
|
||||||
@ -794,11 +799,13 @@ static void delete_key( struct key *key )
|
|||||||
if ((key->flags & KEY_ROOT) || (key->last_subkey >= 0))
|
if ((key->flags & KEY_ROOT) || (key->last_subkey >= 0))
|
||||||
{
|
{
|
||||||
set_error( STATUS_ACCESS_DENIED );
|
set_error( STATUS_ACCESS_DENIED );
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug_level > 1) dump_operation( key, NULL, "Delete" );
|
if (debug_level > 1) dump_operation( key, NULL, "Delete" );
|
||||||
free_subkey( parent, index );
|
free_subkey( parent, index );
|
||||||
touch_key( parent, REG_NOTIFY_CHANGE_NAME );
|
touch_key( parent, REG_NOTIFY_CHANGE_NAME );
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* try to grow the array of values; return 1 if OK, 0 on error */
|
/* try to grow the array of values; return 1 if OK, 0 on error */
|
||||||
@ -1764,7 +1771,7 @@ DECL_HANDLER(delete_key)
|
|||||||
|
|
||||||
if ((key = get_hkey_obj( req->hkey, 0 /*FIXME*/ )))
|
if ((key = get_hkey_obj( req->hkey, 0 /*FIXME*/ )))
|
||||||
{
|
{
|
||||||
delete_key( key );
|
delete_key( key, 0);
|
||||||
release_object( key );
|
release_object( key );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1856,6 +1863,17 @@ DECL_HANDLER(load_registry)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DECL_HANDLER(unload_registry)
|
||||||
|
{
|
||||||
|
struct key *key;
|
||||||
|
|
||||||
|
if ((key = get_hkey_obj( req->hkey, 0 )))
|
||||||
|
{
|
||||||
|
delete_key( key, 1 ); /* FIXME */
|
||||||
|
release_object( key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* save a registry branch to a file */
|
/* save a registry branch to a file */
|
||||||
DECL_HANDLER(save_registry)
|
DECL_HANDLER(save_registry)
|
||||||
{
|
{
|
||||||
|
@ -206,6 +206,7 @@ DECL_HANDLER(get_key_value);
|
|||||||
DECL_HANDLER(enum_key_value);
|
DECL_HANDLER(enum_key_value);
|
||||||
DECL_HANDLER(delete_key_value);
|
DECL_HANDLER(delete_key_value);
|
||||||
DECL_HANDLER(load_registry);
|
DECL_HANDLER(load_registry);
|
||||||
|
DECL_HANDLER(unload_registry);
|
||||||
DECL_HANDLER(save_registry);
|
DECL_HANDLER(save_registry);
|
||||||
DECL_HANDLER(save_registry_atexit);
|
DECL_HANDLER(save_registry_atexit);
|
||||||
DECL_HANDLER(set_registry_levels);
|
DECL_HANDLER(set_registry_levels);
|
||||||
@ -389,6 +390,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
|
|||||||
(req_handler)req_enum_key_value,
|
(req_handler)req_enum_key_value,
|
||||||
(req_handler)req_delete_key_value,
|
(req_handler)req_delete_key_value,
|
||||||
(req_handler)req_load_registry,
|
(req_handler)req_load_registry,
|
||||||
|
(req_handler)req_unload_registry,
|
||||||
(req_handler)req_save_registry,
|
(req_handler)req_save_registry,
|
||||||
(req_handler)req_save_registry_atexit,
|
(req_handler)req_save_registry_atexit,
|
||||||
(req_handler)req_set_registry_levels,
|
(req_handler)req_set_registry_levels,
|
||||||
|
@ -1624,6 +1624,11 @@ static void dump_load_registry_request( const struct load_registry_request *req
|
|||||||
dump_varargs_unicode_str( cur_size );
|
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 )
|
static void dump_save_registry_request( const struct save_registry_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " hkey=%p,", req->hkey );
|
fprintf( stderr, " hkey=%p,", req->hkey );
|
||||||
@ -2601,6 +2606,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||||||
(dump_func)dump_enum_key_value_request,
|
(dump_func)dump_enum_key_value_request,
|
||||||
(dump_func)dump_delete_key_value_request,
|
(dump_func)dump_delete_key_value_request,
|
||||||
(dump_func)dump_load_registry_request,
|
(dump_func)dump_load_registry_request,
|
||||||
|
(dump_func)dump_unload_registry_request,
|
||||||
(dump_func)dump_save_registry_request,
|
(dump_func)dump_save_registry_request,
|
||||||
(dump_func)dump_save_registry_atexit_request,
|
(dump_func)dump_save_registry_atexit_request,
|
||||||
(dump_func)dump_set_registry_levels_request,
|
(dump_func)dump_set_registry_levels_request,
|
||||||
@ -2785,6 +2791,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
(dump_func)0,
|
(dump_func)0,
|
||||||
|
(dump_func)0,
|
||||||
(dump_func)dump_create_timer_reply,
|
(dump_func)dump_create_timer_reply,
|
||||||
(dump_func)dump_open_timer_reply,
|
(dump_func)dump_open_timer_reply,
|
||||||
(dump_func)dump_set_timer_reply,
|
(dump_func)dump_set_timer_reply,
|
||||||
@ -2961,6 +2968,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||||||
"enum_key_value",
|
"enum_key_value",
|
||||||
"delete_key_value",
|
"delete_key_value",
|
||||||
"load_registry",
|
"load_registry",
|
||||||
|
"unload_registry",
|
||||||
"save_registry",
|
"save_registry",
|
||||||
"save_registry_atexit",
|
"save_registry_atexit",
|
||||||
"set_registry_levels",
|
"set_registry_levels",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user