Dmitriy Philippov (shedon@mail.ru):

- The MOVEFILE_DELAY_UNTIL_REBOOT flag is incorrect processed in the MoveFileWithProgressW function.
- The add_boot_rename_entry function contains too many bugs, it crashes when
deleting operation is performed, it does not save old entry in registry, etc...

Fixes are based on the testing application located in reactos/base/application/testsets/smss/movefile


svn path=/trunk/; revision=23537
This commit is contained in:
Aleksey Bragin 2006-08-09 19:46:07 +00:00
parent 46d49263c2
commit ccf643d45b

View file

@ -6,8 +6,11 @@
* PURPOSE: Directory functions * PURPOSE: Directory functions
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl) * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
* Gerhard W. Gruber (sparhawk_at_gmx.at) * Gerhard W. Gruber (sparhawk_at_gmx.at)
* Dmitry Philippov (shedon@mail.ru)
* UPDATE HISTORY: * UPDATE HISTORY:
* Created 01/11/98 * Created 01/11/98
* DP (29/07/2006)
* Fix some bugs in the add_boot_rename_entry function
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
@ -83,12 +86,16 @@ static BOOL add_boot_rename_entry( LPCWSTR source, LPCWSTR dest, DWORD flags )
BOOL rc = FALSE; BOOL rc = FALSE;
HANDLE Reboot = NULL; HANDLE Reboot = NULL;
DWORD len1, len2; DWORD len1, len2;
DWORD DestLen = 0;
DWORD DataSize = 0; DWORD DataSize = 0;
BYTE *Buffer = NULL; BYTE *Buffer = NULL;
WCHAR *p; WCHAR *p;
NTSTATUS Status; 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 )) 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; return FALSE;
} }
dest_name.Buffer = NULL; 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 ); RtlFreeHeap( RtlGetProcessHeap(), 0, source_name.Buffer );
SetLastError( ERROR_PATH_NOT_FOUND ); SetLastError( ERROR_PATH_NOT_FOUND );
@ -105,7 +112,7 @@ static BOOL add_boot_rename_entry( LPCWSTR source, LPCWSTR dest, DWORD flags )
InitializeObjectAttributes(&ObjectAttributes, InitializeObjectAttributes(&ObjectAttributes,
&KeyName, &KeyName,
OBJ_CASE_INSENSITIVE, OBJ_OPENIF | OBJ_CASE_INSENSITIVE,
NULL, NULL,
NULL); NULL);
@ -114,36 +121,62 @@ static BOOL add_boot_rename_entry( LPCWSTR source, LPCWSTR dest, DWORD flags )
&ObjectAttributes, &ObjectAttributes,
0, 0,
NULL, NULL,
REG_OPTION_NON_VOLATILE, 0,
NULL); 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)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("NtCreateKey() failed (Status 0x%lx)\n", Status); DPRINT("NtCreateKey() failed (Status 0x%lx)\n", Status);
RtlFreeHeap( RtlGetProcessHeap(), 0, source_name.Buffer ); if (source_name.Buffer)
RtlFreeHeap( RtlGetProcessHeap(), 0, dest_name.Buffer ); RtlFreeHeap(RtlGetProcessHeap(), 0, source_name.Buffer);
if (dest_name.Buffer)
RtlFreeHeap(RtlGetProcessHeap(), 0, dest_name.Buffer);
return FALSE; return FALSE;
} }
len1 = source_name.Length + sizeof(WCHAR); len1 = source_name.Length + sizeof(WCHAR);
if (dest) if (DestLen)
{ {
len2 = dest_name.Length + sizeof(WCHAR); len2 = dest_name.Length + sizeof(WCHAR);
if (flags & MOVEFILE_REPLACE_EXISTING) if (flags & MOVEFILE_REPLACE_EXISTING)
len2 += sizeof(WCHAR); /* Plus 1 because of the leading '!' */ 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 ); RtlInitUnicodeString( &nameW, ValueName );
/* First we check if the key exists and if so how many bytes it already contains. */ /* First we check if the key exists and if so how many bytes it already contains. */
if (NtQueryValueKey( Reboot, &nameW, KeyValuePartialInformation, Status = NtQueryValueKey(
NULL, 0, &DataSize ) == STATUS_BUFFER_OVERFLOW) 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; goto Quit;
if (NtQueryValueKey( Reboot, &nameW, KeyValuePartialInformation,
Buffer, DataSize, &DataSize )) goto Quit;
info = (KEY_VALUE_PARTIAL_INFORMATION *)Buffer; info = (KEY_VALUE_PARTIAL_INFORMATION *)Buffer;
if (info->Type != REG_MULTI_SZ) goto Quit; if (info->Type != REG_MULTI_SZ) goto Quit;
if (DataSize > sizeof(info)) DataSize -= sizeof(WCHAR); /* remove terminating null (will be added back later) */ 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 ); memcpy( Buffer + DataSize, source_name.Buffer, len1 );
DataSize += len1; DataSize += len1;
p = (WCHAR *)(Buffer + DataSize); p = (WCHAR *)(Buffer + DataSize);
if (dest) if (DestLen)
{ {
if (flags & MOVEFILE_REPLACE_EXISTING) if (flags & MOVEFILE_REPLACE_EXISTING)
*p++ = '!'; *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)); rc = NT_SUCCESS(NtSetValueKey(Reboot, &nameW, 0, REG_MULTI_SZ, Buffer + info_size, DataSize - info_size));
Quit: Quit:
RtlFreeHeap( RtlGetProcessHeap(), 0, source_name.Buffer ); RtlFreeHeap(RtlGetProcessHeap(), 0, source_name.Buffer);
RtlFreeHeap( RtlGetProcessHeap(), 0, dest_name.Buffer ); if (dest_name.Buffer)
if (Reboot) NtClose(Reboot); RtlFreeHeap(RtlGetProcessHeap(), 0, dest_name.Buffer);
HeapFree( GetProcessHeap(), 0, Buffer ); NtClose(Reboot);
if(Buffer)
HeapFree(GetProcessHeap(), 0, Buffer);
return(rc); return(rc);
} }
@ -240,10 +275,13 @@ MoveFileWithProgressW (
} }
FileRename = alloca(sizeof(FILE_RENAME_INFORMATION) + DstPathU.Length); FileRename = alloca(sizeof(FILE_RENAME_INFORMATION) + DstPathU.Length);
if ((dwFlags & MOVEFILE_REPLACE_EXISTING) == MOVEFILE_REPLACE_EXISTING) if( dwFlags & MOVEFILE_REPLACE_EXISTING ) {
FileRename->ReplaceIfExists = TRUE; FileRename->ReplaceIfExists = TRUE;
else }
else {
FileRename->ReplaceIfExists = FALSE; FileRename->ReplaceIfExists = FALSE;
}
memcpy(FileRename->FileName, DstPathU.Buffer, DstPathU.Length); memcpy(FileRename->FileName, DstPathU.Buffer, DstPathU.Length);
RtlFreeHeap (RtlGetProcessHeap (), RtlFreeHeap (RtlGetProcessHeap (),