Module: wine Branch: master Commit: 2d0e8ff672058336ce0ef48eeb99accbd51015ad URL: https://source.winehq.org/git/wine.git/?a=commit;h=2d0e8ff672058336ce0ef48ee...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Dec 12 11:16:59 2019 +0100
kernelbase: Save registry keys directly to the destination file.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/kernelbase/registry.c | 51 ++++++++++++++-------------------------------- 1 file changed, 15 insertions(+), 36 deletions(-)
diff --git a/dlls/kernelbase/registry.c b/dlls/kernelbase/registry.c index ad9a2a3366..0961cb0850 100644 --- a/dlls/kernelbase/registry.c +++ b/dlls/kernelbase/registry.c @@ -2263,12 +2263,10 @@ LSTATUS WINAPI RegLoadKeyA( HKEY hkey, LPCSTR subkey, LPCSTR filename ) */ LSTATUS WINAPI RegSaveKeyExW( HKEY hkey, LPCWSTR file, SECURITY_ATTRIBUTES *sa, DWORD flags ) { - static const WCHAR format[] = - {'r','e','g','%','0','4','x','.','t','m','p',0}; - WCHAR buffer[MAX_PATH]; - int count = 0; - LPWSTR nameW; - DWORD ret, err; + UNICODE_STRING nameW; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK io; + NTSTATUS status; HANDLE handle;
TRACE( "(%p,%s,%p)\n", hkey, debugstr_w(file), sa ); @@ -2276,39 +2274,20 @@ LSTATUS WINAPI RegSaveKeyExW( HKEY hkey, LPCWSTR file, SECURITY_ATTRIBUTES *sa, if (!file || !*file) return ERROR_INVALID_PARAMETER; if (!(hkey = get_special_root_hkey( hkey, 0 ))) return ERROR_INVALID_HANDLE;
- err = GetLastError(); - GetFullPathNameW( file, ARRAY_SIZE( buffer ), buffer, &nameW ); - - for (;;) - { - swprintf( nameW, 16, format, count++ ); - handle = CreateFileW( buffer, GENERIC_WRITE, 0, NULL, - CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 ); - if (handle != INVALID_HANDLE_VALUE) break; - if ((ret = GetLastError()) != ERROR_FILE_EXISTS) goto done; - - /* Something gone haywire ? Please report if this happens abnormally */ - if (count >= 100) - MESSAGE("Wow, we are already fiddling with a temp file %s with an ordinal as high as %d !\nYou might want to delete all corresponding temp files in that directory.\n", debugstr_w(buffer), count); - } - - ret = RtlNtStatusToDosError(NtSaveKey(hkey, handle)); + if ((status = RtlDosPathNameToNtPathName_U_WithStatus( file, &nameW, NULL, NULL ))) + return RtlNtStatusToDosError( status );
- CloseHandle( handle ); - if (!ret) + InitializeObjectAttributes( &attr, &nameW, OBJ_CASE_INSENSITIVE, 0, sa ); + status = NtCreateFile( &handle, GENERIC_WRITE | SYNCHRONIZE, &attr, &io, NULL, FILE_NON_DIRECTORY_FILE, + FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, + FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0 ); + RtlFreeUnicodeString( &nameW ); + if (!status) { - if (!MoveFileExW( buffer, file, MOVEFILE_REPLACE_EXISTING )) - { - ERR( "Failed to move %s to %s\n", debugstr_w(buffer), - debugstr_w(file) ); - ret = GetLastError(); - } + status = NtSaveKey( hkey, handle ); + CloseHandle( handle ); } - if (ret) DeleteFileW( buffer ); - -done: - SetLastError( err ); /* restore last error code */ - return ret; + return RtlNtStatusToDosError( status ); }