diff --git a/reactos/dll/win32/kernel32/file/move.c b/reactos/dll/win32/kernel32/file/move.c index 7a14b2d64fd..6fa44ed9d7d 100644 --- a/reactos/dll/win32/kernel32/file/move.c +++ b/reactos/dll/win32/kernel32/file/move.c @@ -6,8 +6,11 @@ * PURPOSE: Directory functions * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) * Gerhard W. Gruber (sparhawk_at_gmx.at) + * Dmitry Philippov (shedon@mail.ru) * UPDATE HISTORY: * Created 01/11/98 + * DP (29/07/2006) + * Fix some bugs in the add_boot_rename_entry function */ /* INCLUDES *****************************************************************/ @@ -83,12 +86,16 @@ static BOOL add_boot_rename_entry( LPCWSTR source, LPCWSTR dest, DWORD flags ) BOOL rc = FALSE; HANDLE Reboot = NULL; DWORD len1, len2; + DWORD DestLen = 0; DWORD DataSize = 0; BYTE *Buffer = NULL; WCHAR *p; NTSTATUS Status; - DPRINT("Add support to smss for keys created by MOVEFILE_DELAY_UNTIL_REBOOT\n"); + DPRINT("add_boot_rename_entry( %S, %S, %d ) \n", source, dest, flags); + + if(dest) + DestLen = wcslen(dest); if (!RtlDosPathNameToNtPathName_U( source, &source_name, NULL, NULL )) { @@ -96,7 +103,7 @@ static BOOL add_boot_rename_entry( LPCWSTR source, LPCWSTR dest, DWORD flags ) return FALSE; } dest_name.Buffer = NULL; - if (dest && !RtlDosPathNameToNtPathName_U( dest, &dest_name, NULL, NULL )) + if (DestLen && !RtlDosPathNameToNtPathName_U( dest, &dest_name, NULL, NULL )) { RtlFreeHeap( RtlGetProcessHeap(), 0, source_name.Buffer ); SetLastError( ERROR_PATH_NOT_FOUND ); @@ -105,7 +112,7 @@ static BOOL add_boot_rename_entry( LPCWSTR source, LPCWSTR dest, DWORD flags ) InitializeObjectAttributes(&ObjectAttributes, &KeyName, - OBJ_CASE_INSENSITIVE, + OBJ_OPENIF | OBJ_CASE_INSENSITIVE, NULL, NULL); @@ -114,36 +121,62 @@ static BOOL add_boot_rename_entry( LPCWSTR source, LPCWSTR dest, DWORD flags ) &ObjectAttributes, 0, NULL, - REG_OPTION_NON_VOLATILE, + 0, NULL); + if (Status == STATUS_ACCESS_DENIED) + { + Status = NtCreateKey( + &Reboot, + KEY_QUERY_VALUE | KEY_SET_VALUE, + &ObjectAttributes, + 0, + NULL, + REG_OPTION_BACKUP_RESTORE, + NULL); + } + if (!NT_SUCCESS(Status)) { - DPRINT1("NtCreateKey() failed (Status 0x%lx)\n", Status); - RtlFreeHeap( RtlGetProcessHeap(), 0, source_name.Buffer ); - RtlFreeHeap( RtlGetProcessHeap(), 0, dest_name.Buffer ); + DPRINT("NtCreateKey() failed (Status 0x%lx)\n", Status); + if (source_name.Buffer) + RtlFreeHeap(RtlGetProcessHeap(), 0, source_name.Buffer); + if (dest_name.Buffer) + RtlFreeHeap(RtlGetProcessHeap(), 0, dest_name.Buffer); return FALSE; } len1 = source_name.Length + sizeof(WCHAR); - if (dest) + if (DestLen) { len2 = dest_name.Length + sizeof(WCHAR); if (flags & MOVEFILE_REPLACE_EXISTING) len2 += sizeof(WCHAR); /* Plus 1 because of the leading '!' */ } - else len2 = sizeof(WCHAR); /* minimum is the 0 characters for the empty second string */ + else + { + len2 = sizeof(WCHAR); /* minimum is the 0 characters for the empty second string */ + } RtlInitUnicodeString( &nameW, ValueName ); /* First we check if the key exists and if so how many bytes it already contains. */ - if (NtQueryValueKey( Reboot, &nameW, KeyValuePartialInformation, - NULL, 0, &DataSize ) == STATUS_BUFFER_OVERFLOW) + Status = NtQueryValueKey( + Reboot, + &nameW, + KeyValuePartialInformation, + NULL, + 0, + &DataSize ); + if ((Status == STATUS_BUFFER_OVERFLOW) || + (Status == STATUS_BUFFER_TOO_SMALL)) { - if (!(Buffer = HeapAlloc( GetProcessHeap(), 0, DataSize + len1 + len2 + sizeof(WCHAR) ))) + if (!(Buffer = HeapAlloc(GetProcessHeap(), 0, DataSize + len1 + len2 + sizeof(WCHAR)))) + goto Quit; + Status = NtQueryValueKey(Reboot, &nameW, KeyValuePartialInformation, + Buffer, DataSize, &DataSize); + if(!NT_SUCCESS(Status)) goto Quit; - if (NtQueryValueKey( Reboot, &nameW, KeyValuePartialInformation, - Buffer, DataSize, &DataSize )) goto Quit; info = (KEY_VALUE_PARTIAL_INFORMATION *)Buffer; if (info->Type != REG_MULTI_SZ) goto Quit; if (DataSize > sizeof(info)) DataSize -= sizeof(WCHAR); /* remove terminating null (will be added back later) */ @@ -158,7 +191,7 @@ static BOOL add_boot_rename_entry( LPCWSTR source, LPCWSTR dest, DWORD flags ) memcpy( Buffer + DataSize, source_name.Buffer, len1 ); DataSize += len1; p = (WCHAR *)(Buffer + DataSize); - if (dest) + if (DestLen) { if (flags & MOVEFILE_REPLACE_EXISTING) *p++ = '!'; @@ -179,10 +212,12 @@ static BOOL add_boot_rename_entry( LPCWSTR source, LPCWSTR dest, DWORD flags ) rc = NT_SUCCESS(NtSetValueKey(Reboot, &nameW, 0, REG_MULTI_SZ, Buffer + info_size, DataSize - info_size)); Quit: - RtlFreeHeap( RtlGetProcessHeap(), 0, source_name.Buffer ); - RtlFreeHeap( RtlGetProcessHeap(), 0, dest_name.Buffer ); - if (Reboot) NtClose(Reboot); - HeapFree( GetProcessHeap(), 0, Buffer ); + RtlFreeHeap(RtlGetProcessHeap(), 0, source_name.Buffer); + if (dest_name.Buffer) + RtlFreeHeap(RtlGetProcessHeap(), 0, dest_name.Buffer); + NtClose(Reboot); + if(Buffer) + HeapFree(GetProcessHeap(), 0, Buffer); return(rc); } @@ -240,10 +275,13 @@ MoveFileWithProgressW ( } FileRename = alloca(sizeof(FILE_RENAME_INFORMATION) + DstPathU.Length); - if ((dwFlags & MOVEFILE_REPLACE_EXISTING) == MOVEFILE_REPLACE_EXISTING) + if( dwFlags & MOVEFILE_REPLACE_EXISTING ) { FileRename->ReplaceIfExists = TRUE; - else + } + else { FileRename->ReplaceIfExists = FALSE; + } + memcpy(FileRename->FileName, DstPathU.Buffer, DstPathU.Length); RtlFreeHeap (RtlGetProcessHeap (),