server: Convert the registry key modification time to a win32-style time.
This commit is contained in:
parent
7832378658
commit
3343c408cb
|
@ -68,7 +68,6 @@ NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_AT
|
||||||
req->access = access;
|
req->access = access;
|
||||||
req->attributes = attr->Attributes;
|
req->attributes = attr->Attributes;
|
||||||
req->options = options;
|
req->options = options;
|
||||||
req->modif = 0;
|
|
||||||
req->namelen = attr->ObjectName->Length;
|
req->namelen = attr->ObjectName->Length;
|
||||||
wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length );
|
wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length );
|
||||||
if (class) wine_server_add_data( req, class->Buffer, class->Length );
|
if (class) wine_server_add_data( req, class->Buffer, class->Length );
|
||||||
|
@ -232,17 +231,13 @@ static NTSTATUS enumerate_key( HANDLE handle, int index, KEY_INFORMATION_CLASS i
|
||||||
if (length > fixed_size) wine_server_set_reply( req, data_ptr, length - fixed_size );
|
if (length > fixed_size) wine_server_set_reply( req, data_ptr, length - fixed_size );
|
||||||
if (!(ret = wine_server_call( req )))
|
if (!(ret = wine_server_call( req )))
|
||||||
{
|
{
|
||||||
LARGE_INTEGER modif;
|
|
||||||
|
|
||||||
RtlSecondsSince1970ToTime( reply->modif, &modif );
|
|
||||||
|
|
||||||
switch(info_class)
|
switch(info_class)
|
||||||
{
|
{
|
||||||
case KeyBasicInformation:
|
case KeyBasicInformation:
|
||||||
{
|
{
|
||||||
KEY_BASIC_INFORMATION keyinfo;
|
KEY_BASIC_INFORMATION keyinfo;
|
||||||
fixed_size = (char *)keyinfo.Name - (char *)&keyinfo;
|
fixed_size = (char *)keyinfo.Name - (char *)&keyinfo;
|
||||||
keyinfo.LastWriteTime = modif;
|
keyinfo.LastWriteTime.QuadPart = reply->modif;
|
||||||
keyinfo.TitleIndex = 0;
|
keyinfo.TitleIndex = 0;
|
||||||
keyinfo.NameLength = reply->namelen;
|
keyinfo.NameLength = reply->namelen;
|
||||||
memcpy( info, &keyinfo, min( length, fixed_size ) );
|
memcpy( info, &keyinfo, min( length, fixed_size ) );
|
||||||
|
@ -252,7 +247,7 @@ static NTSTATUS enumerate_key( HANDLE handle, int index, KEY_INFORMATION_CLASS i
|
||||||
{
|
{
|
||||||
KEY_FULL_INFORMATION keyinfo;
|
KEY_FULL_INFORMATION keyinfo;
|
||||||
fixed_size = (char *)keyinfo.Class - (char *)&keyinfo;
|
fixed_size = (char *)keyinfo.Class - (char *)&keyinfo;
|
||||||
keyinfo.LastWriteTime = modif;
|
keyinfo.LastWriteTime.QuadPart = reply->modif;
|
||||||
keyinfo.TitleIndex = 0;
|
keyinfo.TitleIndex = 0;
|
||||||
keyinfo.ClassLength = wine_server_reply_size(reply);
|
keyinfo.ClassLength = wine_server_reply_size(reply);
|
||||||
keyinfo.ClassOffset = keyinfo.ClassLength ? fixed_size : -1;
|
keyinfo.ClassOffset = keyinfo.ClassLength ? fixed_size : -1;
|
||||||
|
@ -269,7 +264,7 @@ static NTSTATUS enumerate_key( HANDLE handle, int index, KEY_INFORMATION_CLASS i
|
||||||
{
|
{
|
||||||
KEY_NODE_INFORMATION keyinfo;
|
KEY_NODE_INFORMATION keyinfo;
|
||||||
fixed_size = (char *)keyinfo.Name - (char *)&keyinfo;
|
fixed_size = (char *)keyinfo.Name - (char *)&keyinfo;
|
||||||
keyinfo.LastWriteTime = modif;
|
keyinfo.LastWriteTime.QuadPart = reply->modif;
|
||||||
keyinfo.TitleIndex = 0;
|
keyinfo.TitleIndex = 0;
|
||||||
if (reply->namelen < wine_server_reply_size(reply))
|
if (reply->namelen < wine_server_reply_size(reply))
|
||||||
{
|
{
|
||||||
|
|
|
@ -1981,7 +1981,6 @@ struct create_key_request
|
||||||
unsigned int access;
|
unsigned int access;
|
||||||
unsigned int attributes;
|
unsigned int attributes;
|
||||||
unsigned int options;
|
unsigned int options;
|
||||||
time_t modif;
|
|
||||||
data_size_t namelen;
|
data_size_t namelen;
|
||||||
/* VARARG(name,unicode_str,namelen); */
|
/* VARARG(name,unicode_str,namelen); */
|
||||||
/* VARARG(class,unicode_str); */
|
/* VARARG(class,unicode_str); */
|
||||||
|
@ -2050,7 +2049,7 @@ struct enum_key_reply
|
||||||
int values;
|
int values;
|
||||||
int max_value;
|
int max_value;
|
||||||
int max_data;
|
int max_data;
|
||||||
time_t modif;
|
timeout_t modif;
|
||||||
data_size_t total;
|
data_size_t total;
|
||||||
data_size_t namelen;
|
data_size_t namelen;
|
||||||
/* VARARG(name,unicode_str,namelen); */
|
/* VARARG(name,unicode_str,namelen); */
|
||||||
|
@ -5072,6 +5071,6 @@ union generic_reply
|
||||||
struct set_window_layered_info_reply set_window_layered_info_reply;
|
struct set_window_layered_info_reply set_window_layered_info_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 346
|
#define SERVER_PROTOCOL_VERSION 347
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -1525,7 +1525,6 @@ enum char_info_mode
|
||||||
unsigned int access; /* desired access rights */
|
unsigned int access; /* desired access rights */
|
||||||
unsigned int attributes; /* object attributes */
|
unsigned int attributes; /* object attributes */
|
||||||
unsigned int options; /* creation options */
|
unsigned int options; /* creation options */
|
||||||
time_t modif; /* last modification time */
|
|
||||||
data_size_t namelen; /* length of key name in bytes */
|
data_size_t namelen; /* length of key name in bytes */
|
||||||
VARARG(name,unicode_str,namelen); /* key name */
|
VARARG(name,unicode_str,namelen); /* key name */
|
||||||
VARARG(class,unicode_str); /* class name */
|
VARARG(class,unicode_str); /* class name */
|
||||||
|
@ -1569,7 +1568,7 @@ enum char_info_mode
|
||||||
int values; /* number of values */
|
int values; /* number of values */
|
||||||
int max_value; /* longest value name */
|
int max_value; /* longest value name */
|
||||||
int max_data; /* longest value data */
|
int max_data; /* longest value data */
|
||||||
time_t modif; /* last modification time */
|
timeout_t modif; /* last modification time */
|
||||||
data_size_t total; /* total length needed for full name and class */
|
data_size_t total; /* total length needed for full name and class */
|
||||||
data_size_t namelen; /* length of key name in bytes */
|
data_size_t namelen; /* length of key name in bytes */
|
||||||
VARARG(name,unicode_str,namelen); /* key name */
|
VARARG(name,unicode_str,namelen); /* key name */
|
||||||
|
|
|
@ -75,7 +75,7 @@ struct key
|
||||||
int nb_values; /* count of allocated values in array */
|
int nb_values; /* count of allocated values in array */
|
||||||
struct key_value *values; /* values array */
|
struct key_value *values; /* values array */
|
||||||
unsigned int flags; /* flags */
|
unsigned int flags; /* flags */
|
||||||
time_t modif; /* last modification time */
|
timeout_t modif; /* last modification time */
|
||||||
struct list notify_list; /* list of notifications */
|
struct list notify_list; /* list of notifications */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -103,6 +103,7 @@ struct key_value
|
||||||
/* the root of the registry tree */
|
/* the root of the registry tree */
|
||||||
static struct key *root_key;
|
static struct key *root_key;
|
||||||
|
|
||||||
|
static const timeout_t ticks_1601_to_1970 = (timeout_t)86400 * (369 * 365 + 89) * TICKS_PER_SEC;
|
||||||
static const timeout_t save_period = 30 * -TICKS_PER_SEC; /* delay between periodic saves */
|
static const timeout_t save_period = 30 * -TICKS_PER_SEC; /* delay between periodic saves */
|
||||||
static struct timeout_user *save_timeout_user; /* saving timer */
|
static struct timeout_user *save_timeout_user; /* saving timer */
|
||||||
|
|
||||||
|
@ -245,7 +246,7 @@ static void save_subkeys( const struct key *key, const struct key *base, FILE *f
|
||||||
{
|
{
|
||||||
fprintf( f, "\n[" );
|
fprintf( f, "\n[" );
|
||||||
if (key != base) dump_path( key, base, f );
|
if (key != base) dump_path( key, base, f );
|
||||||
fprintf( f, "] %ld\n", (long)key->modif );
|
fprintf( f, "] %u\n", (unsigned int)((key->modif - ticks_1601_to_1970) / TICKS_PER_SEC) );
|
||||||
for (i = 0; i <= key->last_value; i++) dump_value( &key->values[i], f );
|
for (i = 0; i <= key->last_value; i++) dump_value( &key->values[i], f );
|
||||||
}
|
}
|
||||||
for (i = 0; i <= key->last_subkey; i++) save_subkeys( key->subkeys[i], base, f );
|
for (i = 0; i <= key->last_subkey; i++) save_subkeys( key->subkeys[i], base, f );
|
||||||
|
@ -391,7 +392,7 @@ static struct unicode_str *get_path_token( const struct unicode_str *path, struc
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate a key object */
|
/* allocate a key object */
|
||||||
static struct key *alloc_key( const struct unicode_str *name, time_t modif )
|
static struct key *alloc_key( const struct unicode_str *name, timeout_t modif )
|
||||||
{
|
{
|
||||||
struct key *key;
|
struct key *key;
|
||||||
if ((key = alloc_object( &key_ops )))
|
if ((key = alloc_object( &key_ops )))
|
||||||
|
@ -459,7 +460,7 @@ static void touch_key( struct key *key, unsigned int change )
|
||||||
{
|
{
|
||||||
struct key *k;
|
struct key *k;
|
||||||
|
|
||||||
key->modif = time(NULL);
|
key->modif = current_time;
|
||||||
make_dirty( key );
|
make_dirty( key );
|
||||||
|
|
||||||
/* do notifications */
|
/* do notifications */
|
||||||
|
@ -495,7 +496,7 @@ static int grow_subkeys( struct key *key )
|
||||||
|
|
||||||
/* allocate a subkey for a given key, and return its index */
|
/* allocate a subkey for a given key, and return its index */
|
||||||
static struct key *alloc_subkey( struct key *parent, const struct unicode_str *name,
|
static struct key *alloc_subkey( struct key *parent, const struct unicode_str *name,
|
||||||
int index, time_t modif )
|
int index, timeout_t modif )
|
||||||
{
|
{
|
||||||
struct key *key;
|
struct key *key;
|
||||||
int i;
|
int i;
|
||||||
|
@ -600,7 +601,7 @@ static struct key *open_key( struct key *key, const struct unicode_str *name )
|
||||||
|
|
||||||
/* create a subkey */
|
/* create a subkey */
|
||||||
static struct key *create_key( struct key *key, const struct unicode_str *name,
|
static struct key *create_key( struct key *key, const struct unicode_str *name,
|
||||||
const struct unicode_str *class, int flags, time_t modif, int *created )
|
const struct unicode_str *class, int flags, timeout_t modif, int *created )
|
||||||
{
|
{
|
||||||
struct key *base;
|
struct key *base;
|
||||||
int index;
|
int index;
|
||||||
|
@ -616,7 +617,6 @@ static struct key *create_key( struct key *key, const struct unicode_str *name,
|
||||||
set_error( STATUS_CHILD_MUST_BE_VOLATILE );
|
set_error( STATUS_CHILD_MUST_BE_VOLATILE );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!modif) modif = time(NULL);
|
|
||||||
|
|
||||||
token.str = NULL;
|
token.str = NULL;
|
||||||
if (!get_path_token( name, &token )) return NULL;
|
if (!get_path_token( name, &token )) return NULL;
|
||||||
|
@ -1105,12 +1105,13 @@ static int get_data_type( const char *buffer, int *type, int *parse_type )
|
||||||
|
|
||||||
/* load and create a key from the input file */
|
/* load and create a key from the input file */
|
||||||
static struct key *load_key( struct key *base, const char *buffer, int flags,
|
static struct key *load_key( struct key *base, const char *buffer, int flags,
|
||||||
int prefix_len, struct file_load_info *info,
|
int prefix_len, struct file_load_info *info )
|
||||||
int default_modif )
|
|
||||||
{
|
{
|
||||||
WCHAR *p;
|
WCHAR *p;
|
||||||
struct unicode_str name;
|
struct unicode_str name;
|
||||||
int res, modif;
|
int res;
|
||||||
|
unsigned int mod;
|
||||||
|
timeout_t modif = current_time;
|
||||||
data_size_t len;
|
data_size_t len;
|
||||||
|
|
||||||
if (!get_file_tmp_space( info, strlen(buffer) * sizeof(WCHAR) )) return NULL;
|
if (!get_file_tmp_space( info, strlen(buffer) * sizeof(WCHAR) )) return NULL;
|
||||||
|
@ -1121,7 +1122,8 @@ static struct key *load_key( struct key *base, const char *buffer, int flags,
|
||||||
file_read_error( "Malformed key", info );
|
file_read_error( "Malformed key", info );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (sscanf( buffer + res, " %d", &modif ) != 1) modif = default_modif;
|
if (sscanf( buffer + res, " %u", &mod ) == 1)
|
||||||
|
modif = (timeout_t)mod * TICKS_PER_SEC + ticks_1601_to_1970;
|
||||||
|
|
||||||
p = info->tmp;
|
p = info->tmp;
|
||||||
while (prefix_len && *p) { if (*p++ == '\\') prefix_len--; }
|
while (prefix_len && *p) { if (*p++ == '\\') prefix_len--; }
|
||||||
|
@ -1302,7 +1304,6 @@ static void load_keys( struct key *key, const char *filename, FILE *f, int prefi
|
||||||
struct key *subkey = NULL;
|
struct key *subkey = NULL;
|
||||||
struct file_load_info info;
|
struct file_load_info info;
|
||||||
char *p;
|
char *p;
|
||||||
int default_modif = time(NULL);
|
|
||||||
int flags = (key->flags & KEY_VOLATILE) ? KEY_VOLATILE : KEY_DIRTY;
|
int flags = (key->flags & KEY_VOLATILE) ? KEY_VOLATILE : KEY_DIRTY;
|
||||||
|
|
||||||
info.filename = filename;
|
info.filename = filename;
|
||||||
|
@ -1333,7 +1334,7 @@ static void load_keys( struct key *key, const char *filename, FILE *f, int prefi
|
||||||
case '[': /* new key */
|
case '[': /* new key */
|
||||||
if (subkey) release_object( subkey );
|
if (subkey) release_object( subkey );
|
||||||
if (prefix_len == -1) prefix_len = get_prefix_len( key, p + 1, &info );
|
if (prefix_len == -1) prefix_len = get_prefix_len( key, p + 1, &info );
|
||||||
if (!(subkey = load_key( key, p + 1, flags, prefix_len, &info, default_modif )))
|
if (!(subkey = load_key( key, p + 1, flags, prefix_len, &info )))
|
||||||
file_read_error( "Error creating key", &info );
|
file_read_error( "Error creating key", &info );
|
||||||
break;
|
break;
|
||||||
case '@': /* default value */
|
case '@': /* default value */
|
||||||
|
@ -1444,13 +1445,13 @@ void init_registry(void)
|
||||||
if (fchdir( config_dir_fd ) == -1) fatal_perror( "chdir to config dir" );
|
if (fchdir( config_dir_fd ) == -1) fatal_perror( "chdir to config dir" );
|
||||||
|
|
||||||
/* create the root key */
|
/* create the root key */
|
||||||
root_key = alloc_key( &root_name, time(NULL) );
|
root_key = alloc_key( &root_name, current_time );
|
||||||
assert( root_key );
|
assert( root_key );
|
||||||
make_object_static( &root_key->obj );
|
make_object_static( &root_key->obj );
|
||||||
|
|
||||||
/* load system.reg into Registry\Machine */
|
/* load system.reg into Registry\Machine */
|
||||||
|
|
||||||
if (!(key = create_key( root_key, &HKLM_name, NULL, 0, time(NULL), &dummy )))
|
if (!(key = create_key( root_key, &HKLM_name, NULL, 0, current_time, &dummy )))
|
||||||
fatal_error( "could not create Machine registry key\n" );
|
fatal_error( "could not create Machine registry key\n" );
|
||||||
|
|
||||||
load_init_registry_from_file( "system.reg", key );
|
load_init_registry_from_file( "system.reg", key );
|
||||||
|
@ -1458,7 +1459,7 @@ void init_registry(void)
|
||||||
|
|
||||||
/* load userdef.reg into Registry\User\.Default */
|
/* load userdef.reg into Registry\User\.Default */
|
||||||
|
|
||||||
if (!(key = create_key( root_key, &HKU_name, NULL, 0, time(NULL), &dummy )))
|
if (!(key = create_key( root_key, &HKU_name, NULL, 0, current_time, &dummy )))
|
||||||
fatal_error( "could not create User\\.Default registry key\n" );
|
fatal_error( "could not create User\\.Default registry key\n" );
|
||||||
|
|
||||||
load_init_registry_from_file( "userdef.reg", key );
|
load_init_registry_from_file( "userdef.reg", key );
|
||||||
|
@ -1469,7 +1470,7 @@ void init_registry(void)
|
||||||
/* FIXME: match default user in token.c. should get from process token instead */
|
/* FIXME: match default user in token.c. should get from process token instead */
|
||||||
current_user_path = format_user_registry_path( security_interactive_sid, ¤t_user_str );
|
current_user_path = format_user_registry_path( security_interactive_sid, ¤t_user_str );
|
||||||
if (!current_user_path ||
|
if (!current_user_path ||
|
||||||
!(key = create_key( root_key, ¤t_user_str, NULL, 0, time(NULL), &dummy )))
|
!(key = create_key( root_key, ¤t_user_str, NULL, 0, current_time, &dummy )))
|
||||||
fatal_error( "could not create HKEY_CURRENT_USER registry key\n" );
|
fatal_error( "could not create HKEY_CURRENT_USER registry key\n" );
|
||||||
free( current_user_path );
|
free( current_user_path );
|
||||||
load_init_registry_from_file( "user.reg", key );
|
load_init_registry_from_file( "user.reg", key );
|
||||||
|
@ -1664,7 +1665,7 @@ DECL_HANDLER(create_key)
|
||||||
{
|
{
|
||||||
int flags = (req->options & REG_OPTION_VOLATILE) ? KEY_VOLATILE : KEY_DIRTY;
|
int flags = (req->options & REG_OPTION_VOLATILE) ? KEY_VOLATILE : KEY_DIRTY;
|
||||||
|
|
||||||
if ((key = create_key( parent, &name, &class, flags, req->modif, &reply->created )))
|
if ((key = create_key( parent, &name, &class, flags, current_time, &reply->created )))
|
||||||
{
|
{
|
||||||
reply->hkey = alloc_handle( current->process, key, access, req->attributes );
|
reply->hkey = alloc_handle( current->process, key, access, req->attributes );
|
||||||
release_object( key );
|
release_object( key );
|
||||||
|
@ -1819,7 +1820,7 @@ DECL_HANDLER(load_registry)
|
||||||
{
|
{
|
||||||
int dummy;
|
int dummy;
|
||||||
get_req_path( &name, !req->hkey );
|
get_req_path( &name, !req->hkey );
|
||||||
if ((key = create_key( parent, &name, NULL, KEY_DIRTY, time(NULL), &dummy )))
|
if ((key = create_key( parent, &name, NULL, KEY_DIRTY, current_time, &dummy )))
|
||||||
{
|
{
|
||||||
load_registry( key, req->file );
|
load_registry( key, req->file );
|
||||||
release_object( key );
|
release_object( key );
|
||||||
|
|
|
@ -1970,7 +1970,6 @@ static void dump_create_key_request( const struct create_key_request *req )
|
||||||
fprintf( stderr, " access=%08x,", req->access );
|
fprintf( stderr, " access=%08x,", req->access );
|
||||||
fprintf( stderr, " attributes=%08x,", req->attributes );
|
fprintf( stderr, " attributes=%08x,", req->attributes );
|
||||||
fprintf( stderr, " options=%08x,", req->options );
|
fprintf( stderr, " options=%08x,", req->options );
|
||||||
fprintf( stderr, " modif=%ld,", (long)req->modif );
|
|
||||||
fprintf( stderr, " namelen=%u,", req->namelen );
|
fprintf( stderr, " namelen=%u,", req->namelen );
|
||||||
fprintf( stderr, " name=" );
|
fprintf( stderr, " name=" );
|
||||||
dump_varargs_unicode_str( min(cur_size,req->namelen) );
|
dump_varargs_unicode_str( min(cur_size,req->namelen) );
|
||||||
|
@ -2024,7 +2023,9 @@ static void dump_enum_key_reply( const struct enum_key_reply *req )
|
||||||
fprintf( stderr, " values=%d,", req->values );
|
fprintf( stderr, " values=%d,", req->values );
|
||||||
fprintf( stderr, " max_value=%d,", req->max_value );
|
fprintf( stderr, " max_value=%d,", req->max_value );
|
||||||
fprintf( stderr, " max_data=%d,", req->max_data );
|
fprintf( stderr, " max_data=%d,", req->max_data );
|
||||||
fprintf( stderr, " modif=%ld,", (long)req->modif );
|
fprintf( stderr, " modif=" );
|
||||||
|
dump_timeout( &req->modif );
|
||||||
|
fprintf( stderr, "," );
|
||||||
fprintf( stderr, " total=%u,", req->total );
|
fprintf( stderr, " total=%u,", req->total );
|
||||||
fprintf( stderr, " namelen=%u,", req->namelen );
|
fprintf( stderr, " namelen=%u,", req->namelen );
|
||||||
fprintf( stderr, " name=" );
|
fprintf( stderr, " name=" );
|
||||||
|
|
|
@ -31,7 +31,6 @@ my %formats =
|
||||||
"unsigned int" => "%08x",
|
"unsigned int" => "%08x",
|
||||||
"unsigned long" => "%lx",
|
"unsigned long" => "%lx",
|
||||||
"void*" => "%p",
|
"void*" => "%p",
|
||||||
"time_t" => "%ld (long)",
|
|
||||||
"size_t" => "%lu (unsigned long)",
|
"size_t" => "%lu (unsigned long)",
|
||||||
"data_size_t" => "%u",
|
"data_size_t" => "%u",
|
||||||
"obj_handle_t" => "%p",
|
"obj_handle_t" => "%p",
|
||||||
|
|
Loading…
Reference in New Issue