mirror of
https://github.com/reactos/reactos.git
synced 2025-07-06 18:51:22 +00:00
[kernel32]
- Jerome Gardou <jerome DOT gardou AT laposte DOT net>: Implement missing ReplaceFileW functionality - Fixes six kernel32 file winetests, bug #4827 svn path=/trunk/; revision=44383
This commit is contained in:
parent
9b49e5e810
commit
76e69bee97
1 changed files with 46 additions and 8 deletions
|
@ -1905,13 +1905,14 @@ ReplaceFileW(
|
||||||
LPVOID lpReserved
|
LPVOID lpReserved
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
HANDLE hReplaced = NULL, hReplacement = NULL, hBackup = NULL;
|
HANDLE hReplaced = NULL, hReplacement = NULL;
|
||||||
UNICODE_STRING NtReplacedName, NtReplacementName;
|
UNICODE_STRING NtReplacedName, NtReplacementName;
|
||||||
DWORD Error = ERROR_SUCCESS;
|
DWORD Error = ERROR_SUCCESS;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
BOOL Ret = FALSE;
|
BOOL Ret = FALSE;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
PVOID Buffer = NULL ;
|
||||||
|
|
||||||
if (dwReplaceFlags)
|
if (dwReplaceFlags)
|
||||||
FIXME("Ignoring flags %x\n", dwReplaceFlags);
|
FIXME("Ignoring flags %x\n", dwReplaceFlags);
|
||||||
|
@ -1923,6 +1924,16 @@ ReplaceFileW(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Back it up */
|
||||||
|
if(lpBackupFileName)
|
||||||
|
{
|
||||||
|
if(!CopyFileW(lpReplacedFileName, lpBackupFileName, FALSE))
|
||||||
|
{
|
||||||
|
Error = GetLastError();
|
||||||
|
goto Cleanup ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Open the "replaced" file for reading and writing */
|
/* Open the "replaced" file for reading and writing */
|
||||||
if (!(RtlDosPathNameToNtPathName_U(lpReplacedFileName, &NtReplacedName, NULL, NULL)))
|
if (!(RtlDosPathNameToNtPathName_U(lpReplacedFileName, &NtReplacedName, NULL, NULL)))
|
||||||
{
|
{
|
||||||
|
@ -1937,7 +1948,7 @@ ReplaceFileW(
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
Status = NtOpenFile(&hReplaced,
|
Status = NtOpenFile(&hReplaced,
|
||||||
GENERIC_READ | GENERIC_WRITE | DELETE | SYNCHRONIZE,
|
GENERIC_READ | GENERIC_WRITE | DELETE | SYNCHRONIZE | WRITE_DAC,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
@ -1952,9 +1963,12 @@ ReplaceFileW(
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Blank it */
|
||||||
|
SetEndOfFile(hReplaced) ;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open the replacement file for reading, writing, and deleting
|
* 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)))
|
if (!(RtlDosPathNameToNtPathName_U(lpReplacementFileName, &NtReplacementName, NULL, NULL)))
|
||||||
{
|
{
|
||||||
|
@ -1969,11 +1983,11 @@ ReplaceFileW(
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
Status = NtOpenFile(&hReplacement,
|
Status = NtOpenFile(&hReplacement,
|
||||||
GENERIC_READ | GENERIC_WRITE | DELETE | WRITE_DAC | SYNCHRONIZE,
|
GENERIC_READ | DELETE | SYNCHRONIZE,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
0,
|
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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
@ -1981,15 +1995,39 @@ ReplaceFileW(
|
||||||
goto Cleanup;
|
goto Cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not success :( */
|
Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 0x10000) ;
|
||||||
FIXME("ReplaceFileW not implemented, but it is returned TRUE!\n");
|
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;
|
Ret = TRUE;
|
||||||
|
|
||||||
/* Perform resource cleanup */
|
/* Perform resource cleanup */
|
||||||
Cleanup:
|
Cleanup:
|
||||||
if (hBackup) NtClose(hBackup);
|
|
||||||
if (hReplaced) NtClose(hReplaced);
|
if (hReplaced) NtClose(hReplaced);
|
||||||
if (hReplacement) NtClose(hReplacement);
|
if (hReplacement) NtClose(hReplacement);
|
||||||
|
if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
|
||||||
|
|
||||||
RtlFreeUnicodeString(&NtReplacementName);
|
RtlFreeUnicodeString(&NtReplacementName);
|
||||||
RtlFreeUnicodeString(&NtReplacedName);
|
RtlFreeUnicodeString(&NtReplacedName);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue