X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=dll%2Fwin32%2Fkernel32%2Ffile%2Ffile.c;h=66046621821eedaa787f39c2db2fcc3a782084b2;hp=86ef5ad7730cf220ca76ae37ed87c8d19b1bb28d;hb=e4a060ead45b9dc87a64408b6d791ea4a5fef55e;hpb=2597cfe258b768473a744df30227f4067252d9b7 diff --git a/dll/win32/kernel32/file/file.c b/dll/win32/kernel32/file/file.c index 86ef5ad7730..66046621821 100644 --- a/dll/win32/kernel32/file/file.c +++ b/dll/win32/kernel32/file/file.c @@ -239,7 +239,6 @@ OpenFile(LPCSTR lpFileName, return HFILE_ERROR; } - lpReOpenBuff->cBytes = sizeof(OFSTRUCT); lpReOpenBuff->nErrCode = 0; if (uStyle & OF_REOPEN) lpFileName = lpReOpenBuff->szPathName; @@ -282,10 +281,11 @@ OpenFile(LPCSTR lpFileName, return -1; default: + lpReOpenBuff->cBytes = sizeof(OFSTRUCT); return 1; } } - + lpReOpenBuff->cBytes = sizeof(OFSTRUCT); if ((uStyle & OF_CREATE) == OF_CREATE) { DWORD Sharing; @@ -1905,13 +1905,14 @@ ReplaceFileW( LPVOID lpReserved ) { - HANDLE hReplaced = NULL, hReplacement = NULL, hBackup = NULL; + HANDLE hReplaced = NULL, hReplacement = NULL; UNICODE_STRING NtReplacedName, NtReplacementName; DWORD Error = ERROR_SUCCESS; NTSTATUS Status; BOOL Ret = FALSE; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; + PVOID Buffer = NULL ; if (dwReplaceFlags) FIXME("Ignoring flags %x\n", dwReplaceFlags); @@ -1923,6 +1924,16 @@ ReplaceFileW( return FALSE; } + /* Back it up */ + if(lpBackupFileName) + { + if(!CopyFileW(lpReplacedFileName, lpBackupFileName, FALSE)) + { + Error = GetLastError(); + goto Cleanup ; + } + } + /* Open the "replaced" file for reading and writing */ if (!(RtlDosPathNameToNtPathName_U(lpReplacedFileName, &NtReplacedName, NULL, NULL))) { @@ -1937,7 +1948,7 @@ ReplaceFileW( NULL); Status = NtOpenFile(&hReplaced, - GENERIC_READ | GENERIC_WRITE | DELETE | SYNCHRONIZE, + GENERIC_READ | GENERIC_WRITE | DELETE | SYNCHRONIZE | WRITE_DAC, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, @@ -1952,9 +1963,12 @@ ReplaceFileW( goto Cleanup; } + /* Blank it */ + SetEndOfFile(hReplaced) ; + /* * Open the replacement file for reading, writing, and deleting - * (writing and deleting are needed when finished) + * (deleting is needed when finished) */ if (!(RtlDosPathNameToNtPathName_U(lpReplacementFileName, &NtReplacementName, NULL, NULL))) { @@ -1969,11 +1983,11 @@ ReplaceFileW( NULL); Status = NtOpenFile(&hReplacement, - GENERIC_READ | GENERIC_WRITE | DELETE | WRITE_DAC | SYNCHRONIZE, + GENERIC_READ | DELETE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, 0, - FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE); + FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE); if (!NT_SUCCESS(Status)) { @@ -1981,15 +1995,39 @@ ReplaceFileW( goto Cleanup; } - /* Not success :( */ - FIXME("ReplaceFileW not implemented, but it is returned TRUE!\n"); + Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 0x10000) ; + if (!Buffer) + { + Error = ERROR_NOT_ENOUGH_MEMORY; + goto Cleanup ; + } + while (Status != STATUS_END_OF_FILE) + { + Status = NtReadFile(hReplacement, NULL, NULL, NULL, &IoStatusBlock, Buffer, 0x10000, NULL, NULL) ; + if (NT_SUCCESS(Status)) + { + Status = NtWriteFile(hReplaced, NULL, NULL, NULL, &IoStatusBlock, Buffer, + IoStatusBlock.Information, NULL, NULL) ; + if (!NT_SUCCESS(Status)) + { + Error = RtlNtStatusToDosError(Status); + goto Cleanup; + } + } + else if (Status != STATUS_END_OF_FILE) + { + Error = RtlNtStatusToDosError(Status); + goto Cleanup; + } + } + Ret = TRUE; /* Perform resource cleanup */ Cleanup: - if (hBackup) NtClose(hBackup); if (hReplaced) NtClose(hReplaced); if (hReplacement) NtClose(hReplacement); + if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer); RtlFreeUnicodeString(&NtReplacementName); RtlFreeUnicodeString(&NtReplacedName);