kernelbase: Save registry keys directly to the destination file.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
d5449a8905
commit
2d0e8ff672
|
@ -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 )
|
LSTATUS WINAPI RegSaveKeyExW( HKEY hkey, LPCWSTR file, SECURITY_ATTRIBUTES *sa, DWORD flags )
|
||||||
{
|
{
|
||||||
static const WCHAR format[] =
|
UNICODE_STRING nameW;
|
||||||
{'r','e','g','%','0','4','x','.','t','m','p',0};
|
OBJECT_ATTRIBUTES attr;
|
||||||
WCHAR buffer[MAX_PATH];
|
IO_STATUS_BLOCK io;
|
||||||
int count = 0;
|
NTSTATUS status;
|
||||||
LPWSTR nameW;
|
|
||||||
DWORD ret, err;
|
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
|
|
||||||
TRACE( "(%p,%s,%p)\n", hkey, debugstr_w(file), sa );
|
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 (!file || !*file) return ERROR_INVALID_PARAMETER;
|
||||||
if (!(hkey = get_special_root_hkey( hkey, 0 ))) return ERROR_INVALID_HANDLE;
|
if (!(hkey = get_special_root_hkey( hkey, 0 ))) return ERROR_INVALID_HANDLE;
|
||||||
|
|
||||||
err = GetLastError();
|
if ((status = RtlDosPathNameToNtPathName_U_WithStatus( file, &nameW, NULL, NULL )))
|
||||||
GetFullPathNameW( file, ARRAY_SIZE( buffer ), buffer, &nameW );
|
return RtlNtStatusToDosError( status );
|
||||||
|
|
||||||
for (;;)
|
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)
|
||||||
{
|
{
|
||||||
swprintf( nameW, 16, format, count++ );
|
status = NtSaveKey( hkey, handle );
|
||||||
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));
|
|
||||||
|
|
||||||
CloseHandle( handle );
|
CloseHandle( handle );
|
||||||
if (!ret)
|
|
||||||
{
|
|
||||||
if (!MoveFileExW( buffer, file, MOVEFILE_REPLACE_EXISTING ))
|
|
||||||
{
|
|
||||||
ERR( "Failed to move %s to %s\n", debugstr_w(buffer),
|
|
||||||
debugstr_w(file) );
|
|
||||||
ret = GetLastError();
|
|
||||||
}
|
}
|
||||||
}
|
return RtlNtStatusToDosError( status );
|
||||||
if (ret) DeleteFileW( buffer );
|
|
||||||
|
|
||||||
done:
|
|
||||||
SetLastError( err ); /* restore last error code */
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue