return HFILE_ERROR;
}
- lpReOpenBuff->cBytes = sizeof(OFSTRUCT);
lpReOpenBuff->nErrCode = 0;
if (uStyle & OF_REOPEN) lpFileName = lpReOpenBuff->szPathName;
return 0;
}
+ if ((uStyle & OF_EXIST) && !(uStyle & OF_CREATE))
+ {
+ DWORD dwAttributes = GetFileAttributesA(lpReOpenBuff->szPathName);
+
+ switch (dwAttributes)
+ {
+ case 0xFFFFFFFF: /* File does not exist */
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ lpReOpenBuff->nErrCode = (WORD) ERROR_FILE_NOT_FOUND;
+ return -1;
+
+ case FILE_ATTRIBUTE_DIRECTORY:
+ SetLastError(ERROR_ACCESS_DENIED);
+ lpReOpenBuff->nErrCode = (WORD) ERROR_ACCESS_DENIED;
+ return -1;
+
+ default:
+ lpReOpenBuff->cBytes = sizeof(OFSTRUCT);
+ return 1;
+ }
+ }
+ lpReOpenBuff->cBytes = sizeof(OFSTRUCT);
if ((uStyle & OF_CREATE) == OF_CREATE)
{
DWORD Sharing;
if (uStyle & OF_EXIST)
{
NtClose(FileHandle);
- return TRUE;
+ return (HFILE)1;
}
return (HFILE)FileHandle;
*lpDistanceToMoveHigh = FilePosition.CurrentByteOffset.u.HighPart;
}
- if (FilePosition.CurrentByteOffset.u.LowPart == -1U)
+ if (FilePosition.CurrentByteOffset.u.LowPart == MAXDWORD)
{
/* The value of -1 is valid here, especially when the new
file position is greater than 4 GB. Since NtSetInformationFile
{
WIN32_FILE_ATTRIBUTE_DATA FileAttributeData;
PWSTR FileNameW;
- BOOL ret;
+ BOOL ret;
- if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+ if (!lpFileName || !(FileNameW = FilenameA2W(lpFileName, FALSE)))
return INVALID_FILE_ATTRIBUTES;
ret = GetFileAttributesExW(FileNameW, GetFileExInfoStandard, &FileAttributeData);
LPVOID lpReserved
)
{
- HANDLE hReplaced = NULL, hReplacement = NULL, hBackup = NULL;
- UNICODE_STRING NtReplacedName, NtReplacementName;
+ HANDLE hReplaced = NULL, hReplacement = NULL;
+ UNICODE_STRING NtReplacedName = { 0, 0, NULL };
+ UNICODE_STRING NtReplacementName = { 0, 0, NULL };
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);
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)))
{
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,
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)))
{
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))
{
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);
+ if (NtReplacementName.Buffer)
+ RtlFreeHeap(GetProcessHeap(), 0, NtReplacementName.Buffer);
+ if (NtReplacedName.Buffer)
+ RtlFreeHeap(GetProcessHeap(), 0, NtReplacedName.Buffer);
/* If there was an error, set the error code */
if(!Ret)