[KERNEL32] ReplaceFileW:
[reactos.git] / reactos / dll / win32 / kernel32 / file / file.c
index 4292973..cdbafd0 100644 (file)
 /* INCLUDES *****************************************************************/
 
 #include <k32.h>
+#include <wine/debug.h>
 
-#define NDEBUG
-#include "../include/debug.h"
-
+WINE_DEFAULT_DEBUG_CHANNEL(kernel32file);
 
 /* GLOBALS ******************************************************************/
 
@@ -34,16 +33,16 @@ FilenameA2W(LPCSTR NameA, BOOL alloc)
    PUNICODE_STRING pstrW;
    NTSTATUS Status;
 
-   ASSERT(NtCurrentTeb()->StaticUnicodeString.Buffer == NtCurrentTeb()->StaticUnicodeBuffer);
+   //ASSERT(NtCurrentTeb()->StaticUnicodeString.Buffer == NtCurrentTeb()->StaticUnicodeBuffer);
    ASSERT(NtCurrentTeb()->StaticUnicodeString.MaximumLength == sizeof(NtCurrentTeb()->StaticUnicodeBuffer));
 
    RtlInitAnsiString(&str, NameA);
    pstrW = alloc ? &strW : &NtCurrentTeb()->StaticUnicodeString;
 
    if (bIsFileApiAnsi)
-        Status= RtlAnsiStringToUnicodeString( pstrW, &str, alloc );
+        Status= RtlAnsiStringToUnicodeString( pstrW, &str, (BOOLEAN)alloc );
    else
-        Status= RtlOemStringToUnicodeString( pstrW, &str, alloc );
+        Status= RtlOemStringToUnicodeString( pstrW, &str, (BOOLEAN)alloc );
 
     if (NT_SUCCESS(Status))
        return pstrW->Buffer;
@@ -81,7 +80,7 @@ FilenameU2A_FitOrFail(
       ANSI_STRING str;
 
       str.Buffer = DestA;
-      str.MaximumLength = destLen;
+      str.MaximumLength = (USHORT)destLen;
 
 
       if (bIsFileApiAnsi)
@@ -178,7 +177,7 @@ FilenameW2A_N(
  * @implemented
  */
 VOID
-STDCALL
+WINAPI
 SetFileApisToOEM(VOID)
 {
     /* Set the correct Base Api */
@@ -193,7 +192,7 @@ SetFileApisToOEM(VOID)
  * @implemented
  */
 VOID
-STDCALL
+WINAPI
 SetFileApisToANSI(VOID)
 {
     /* Set the correct Base Api */
@@ -207,7 +206,7 @@ SetFileApisToANSI(VOID)
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 AreFileApisANSI(VOID)
 {
    return bIsFileApiAnsi;
@@ -217,7 +216,7 @@ AreFileApisANSI(VOID)
 /*
  * @implemented
  */
-HFILE STDCALL
+HFILE WINAPI
 OpenFile(LPCSTR lpFileName,
         LPOFSTRUCT lpReOpenBuff,
         UINT uStyle)
@@ -233,13 +232,60 @@ OpenFile(LPCSTR lpFileName,
        PWCHAR FilePart;
        ULONG Len;
 
-       DPRINT("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName, lpReOpenBuff, uStyle);
+       TRACE("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName, lpReOpenBuff, uStyle);
 
        if (lpReOpenBuff == NULL)
        {
-               return FALSE;
+               return HFILE_ERROR;
+       }
+
+    lpReOpenBuff->nErrCode = 0;
+
+       if (uStyle & OF_REOPEN) lpFileName = lpReOpenBuff->szPathName;
+
+       if (!lpFileName)
+       {
+               return HFILE_ERROR;
+       }
+
+       if (!GetFullPathNameA(lpFileName,
+                                                 sizeof(lpReOpenBuff->szPathName),
+                                                 lpReOpenBuff->szPathName,
+                                                 NULL))
+       {
+           lpReOpenBuff->nErrCode = GetLastError();
+               return HFILE_ERROR;
        }
 
+    if (uStyle & OF_PARSE)
+    {
+        lpReOpenBuff->fFixedDisk = (GetDriveTypeA(lpReOpenBuff->szPathName) != DRIVE_REMOVABLE);
+        TRACE("(%s): OF_PARSE, res = '%s'\n", 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;
@@ -281,9 +327,21 @@ OpenFile(LPCSTR lpFileName,
 
        if (Len == 0 || Len > OFS_MAXPATHNAME)
        {
+               lpReOpenBuff->nErrCode = GetLastError();
                return (HFILE)INVALID_HANDLE_VALUE;
        }
 
+    if (uStyle & OF_DELETE)
+    {
+        if (!DeleteFileW(PathNameW))
+               {
+                       lpReOpenBuff->nErrCode = GetLastError();
+                       return HFILE_ERROR;
+               }
+        TRACE("(%s): OF_DELETE return = OK\n", lpFileName);
+        return TRUE;
+    }
+
        FileName.Buffer = lpReOpenBuff->szPathName;
        FileName.Length = 0;
        FileName.MaximumLength = OFS_MAXPATHNAME;
@@ -307,14 +365,6 @@ OpenFile(LPCSTR lpFileName,
        // FILE_SHARE_READ
        // FILE_NO_INTERMEDIATE_BUFFERING
 
-       if ((uStyle & OF_PARSE) == OF_PARSE)
-       {
-               RtlFreeHeap(RtlGetProcessHeap(),
-                            0,
-                            FileNameString.Buffer);
-               return (HFILE)NULL;
-       }
-
        ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
        ObjectAttributes.RootDirectory = NULL;
        ObjectAttributes.ObjectName = &FileNameString;
@@ -329,9 +379,7 @@ OpenFile(LPCSTR lpFileName,
                              FILE_SHARE_READ,
                              FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT);
 
-       RtlFreeHeap(RtlGetProcessHeap(),
-                    0,
-                    FileNameString.Buffer);
+       RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameString.Buffer);
 
        lpReOpenBuff->nErrCode = RtlNtStatusToDosError(errCode);
 
@@ -341,6 +389,12 @@ OpenFile(LPCSTR lpFileName,
                return (HFILE)INVALID_HANDLE_VALUE;
        }
 
+       if (uStyle & OF_EXIST)
+       {
+               NtClose(FileHandle);
+               return (HFILE)1;
+       }
+
        return (HFILE)FileHandle;
 }
 
@@ -348,12 +402,14 @@ OpenFile(LPCSTR lpFileName,
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 FlushFileBuffers(HANDLE hFile)
 {
    NTSTATUS errCode;
    IO_STATUS_BLOCK IoStatusBlock;
 
+   hFile = TranslateStdHandle(hFile);
+
    if (IsConsoleHandle(hFile))
    {
       return FALSE;
@@ -373,11 +429,11 @@ FlushFileBuffers(HANDLE hFile)
 /*
  * @implemented
  */
-DWORD STDCALL
+DWORD WINAPI
 SetFilePointer(HANDLE hFile,
-              LONG lDistanceToMove,
-              PLONG lpDistanceToMoveHigh,
-              DWORD dwMoveMethod)
+           LONG lDistanceToMove,
+           PLONG lpDistanceToMoveHigh,
+           DWORD dwMoveMethod)
 {
    FILE_POSITION_INFORMATION FilePosition;
    FILE_STANDARD_INFORMATION FileStandard;
@@ -385,77 +441,109 @@ SetFilePointer(HANDLE hFile,
    IO_STATUS_BLOCK IoStatusBlock;
    LARGE_INTEGER Distance;
 
-   DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
-         hFile,lDistanceToMove,dwMoveMethod);
+   TRACE("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
+      hFile,lDistanceToMove,dwMoveMethod);
 
    if(IsConsoleHandle(hFile))
    {
      SetLastError(ERROR_INVALID_HANDLE);
-     return -1;
+     return INVALID_SET_FILE_POINTER;
    }
 
-   Distance.u.LowPart = lDistanceToMove;
    if (lpDistanceToMoveHigh)
    {
       Distance.u.HighPart = *lpDistanceToMoveHigh;
-   }
-   else if (lDistanceToMove >= 0)
-   {
-      Distance.u.HighPart = 0;
+      Distance.u.LowPart = lDistanceToMove;
    }
    else
    {
-      Distance.u.HighPart = -1;
+      Distance.QuadPart = lDistanceToMove;
    }
 
    switch(dwMoveMethod)
    {
      case FILE_CURRENT:
-       NtQueryInformationFile(hFile,
-                              &IoStatusBlock,
-                              &FilePosition,
-                              sizeof(FILE_POSITION_INFORMATION),
-                              FilePositionInformation);
-       FilePosition.CurrentByteOffset.QuadPart += Distance.QuadPart;
-       break;
+    errCode = NtQueryInformationFile(hFile,
+                   &IoStatusBlock,
+                   &FilePosition,
+                   sizeof(FILE_POSITION_INFORMATION),
+                   FilePositionInformation);
+    FilePosition.CurrentByteOffset.QuadPart += Distance.QuadPart;
+    if (!NT_SUCCESS(errCode))
+    {
+      if (lpDistanceToMoveHigh != NULL)
+          *lpDistanceToMoveHigh = -1;
+      SetLastErrorByStatus(errCode);
+      return INVALID_SET_FILE_POINTER;
+    }
+    break;
      case FILE_END:
-       NtQueryInformationFile(hFile,
+    errCode = NtQueryInformationFile(hFile,
                                &IoStatusBlock,
                                &FileStandard,
                                sizeof(FILE_STANDARD_INFORMATION),
                                FileStandardInformation);
-        FilePosition.CurrentByteOffset.QuadPart =
+    FilePosition.CurrentByteOffset.QuadPart =
                   FileStandard.EndOfFile.QuadPart + Distance.QuadPart;
-       break;
+    if (!NT_SUCCESS(errCode))
+    {
+      if (lpDistanceToMoveHigh != NULL)
+          *lpDistanceToMoveHigh = -1;
+      SetLastErrorByStatus(errCode);
+      return INVALID_SET_FILE_POINTER;
+    }
+    break;
      case FILE_BEGIN:
         FilePosition.CurrentByteOffset.QuadPart = Distance.QuadPart;
-       break;
+    break;
      default:
         SetLastError(ERROR_INVALID_PARAMETER);
-       return -1;
+    return INVALID_SET_FILE_POINTER;
    }
 
    if(FilePosition.CurrentByteOffset.QuadPart < 0)
    {
      SetLastError(ERROR_NEGATIVE_SEEK);
-     return -1;
+     return INVALID_SET_FILE_POINTER;
+   }
+
+   if (lpDistanceToMoveHigh == NULL && FilePosition.CurrentByteOffset.HighPart != 0)
+   {
+     /* If we're moving the pointer outside of the 32 bit boundaries but
+        the application only passed a 32 bit value we need to bail out! */
+     SetLastError(ERROR_INVALID_PARAMETER);
+     return INVALID_SET_FILE_POINTER;
    }
 
    errCode = NtSetInformationFile(hFile,
-                                 &IoStatusBlock,
-                                 &FilePosition,
-                                 sizeof(FILE_POSITION_INFORMATION),
-                                 FilePositionInformation);
+                  &IoStatusBlock,
+                  &FilePosition,
+                  sizeof(FILE_POSITION_INFORMATION),
+                  FilePositionInformation);
    if (!NT_SUCCESS(errCode))
      {
-       SetLastErrorByStatus(errCode);
-       return -1;
+       if (lpDistanceToMoveHigh != NULL)
+           *lpDistanceToMoveHigh = -1;
+
+       SetLastErrorByStatus(errCode);
+       return INVALID_SET_FILE_POINTER;
      }
 
    if (lpDistanceToMoveHigh != NULL)
      {
         *lpDistanceToMoveHigh = FilePosition.CurrentByteOffset.u.HighPart;
      }
+
+   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
+          succeeded we never set an error code and we explicitly need
+          to clear a previously set error code in this case, which
+          an application will check if INVALID_SET_FILE_POINTER is returned! */
+       SetLastError(ERROR_SUCCESS);
+     }
+
    return FilePosition.CurrentByteOffset.u.LowPart;
 }
 
@@ -464,7 +552,7 @@ SetFilePointer(HANDLE hFile,
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 SetFilePointerEx(HANDLE hFile,
                 LARGE_INTEGER liDistanceToMove,
                 PLARGE_INTEGER lpNewFilePointer,
@@ -536,7 +624,7 @@ SetFilePointerEx(HANDLE hFile,
 /*
  * @implemented
  */
-DWORD STDCALL
+DWORD WINAPI
 GetFileType(HANDLE hFile)
 {
   FILE_FS_DEVICE_INFORMATION DeviceInfo;
@@ -544,20 +632,7 @@ GetFileType(HANDLE hFile)
   NTSTATUS Status;
 
   /* Get real handle */
-  switch ((ULONG)hFile)
-    {
-      case STD_INPUT_HANDLE:
-       hFile = NtCurrentPeb()->ProcessParameters->StandardInput;
-       break;
-
-      case STD_OUTPUT_HANDLE:
-       hFile = NtCurrentPeb()->ProcessParameters->StandardOutput;
-       break;
-
-      case STD_ERROR_HANDLE:
-       hFile = NtCurrentPeb()->ProcessParameters->StandardError;
-       break;
-    }
+  hFile = TranslateStdHandle(hFile);
 
   /* Check for console handle */
   if (IsConsoleHandle(hFile))
@@ -611,7 +686,7 @@ GetFileType(HANDLE hFile)
 /*
  * @implemented
  */
-DWORD STDCALL
+DWORD WINAPI
 GetFileSize(HANDLE hFile,
            LPDWORD lpFileSizeHigh)
 {
@@ -647,7 +722,7 @@ GetFileSize(HANDLE hFile,
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 GetFileSizeEx(
     HANDLE hFile,
     PLARGE_INTEGER lpFileSize
@@ -677,7 +752,7 @@ GetFileSizeEx(
 /*
  * @implemented
  */
-DWORD STDCALL
+DWORD WINAPI
 GetCompressedFileSizeA(LPCSTR lpFileName,
                       LPDWORD lpFileSizeHigh)
 {
@@ -693,7 +768,7 @@ GetCompressedFileSizeA(LPCSTR lpFileName,
 /*
  * @implemented
  */
-DWORD STDCALL
+DWORD WINAPI
 GetCompressedFileSizeW(LPCWSTR lpFileName,
                       LPDWORD lpFileSizeHigh)
 {
@@ -738,7 +813,7 @@ GetCompressedFileSizeW(LPCWSTR lpFileName,
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 GetFileInformationByHandle(HANDLE hFile,
                           LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
 {
@@ -832,7 +907,7 @@ GetFileInformationByHandle(HANDLE hFile,
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 GetFileAttributesExW(LPCWSTR lpFileName,
                     GET_FILEEX_INFO_LEVELS fInfoLevelId,
                     LPVOID lpFileInformation)
@@ -843,7 +918,7 @@ GetFileAttributesExW(LPCWSTR lpFileName,
   NTSTATUS Status;
   WIN32_FILE_ATTRIBUTE_DATA* FileAttributeData;
 
-  DPRINT("GetFileAttributesExW(%S) called\n", lpFileName);
+  TRACE("GetFileAttributesExW(%S) called\n", lpFileName);
 
 
   if (fInfoLevelId != GetFileExInfoStandard || lpFileInformation == NULL)
@@ -858,7 +933,7 @@ GetFileAttributesExW(LPCWSTR lpFileName,
                                     NULL,
                                     NULL))
     {
-      DPRINT1 ("Invalid path\n");
+      WARN ("Invalid path '%S'\n", lpFileName);
       SetLastError (ERROR_BAD_PATHNAME);
       return FALSE;
     }
@@ -873,11 +948,11 @@ GetFileAttributesExW(LPCWSTR lpFileName,
   /* Get file attributes */
   Status = NtQueryFullAttributesFile(&ObjectAttributes,
                                      &FileInformation);
-                                     
+
   RtlFreeUnicodeString (&FileName);
   if (!NT_SUCCESS (Status))
     {
-      DPRINT ("NtQueryFullAttributesFile() failed (Status %lx)\n", Status);
+      WARN ("NtQueryFullAttributesFile() failed (Status %lx)\n", Status);
       SetLastErrorByStatus (Status);
       return FALSE;
     }
@@ -899,7 +974,7 @@ GetFileAttributesExW(LPCWSTR lpFileName,
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 GetFileAttributesExA(LPCSTR lpFileName,
                     GET_FILEEX_INFO_LEVELS fInfoLevelId,
                     LPVOID lpFileInformation)
@@ -916,14 +991,14 @@ GetFileAttributesExA(LPCSTR lpFileName,
 /*
  * @implemented
  */
-DWORD STDCALL
+DWORD WINAPI
 GetFileAttributesA(LPCSTR lpFileName)
 {
    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);
@@ -935,13 +1010,13 @@ GetFileAttributesA(LPCSTR lpFileName)
 /*
  * @implemented
  */
-DWORD STDCALL
+DWORD WINAPI
 GetFileAttributesW(LPCWSTR lpFileName)
 {
   WIN32_FILE_ATTRIBUTE_DATA FileAttributeData;
   BOOL Result;
 
-  DPRINT ("GetFileAttributeW(%S) called\n", lpFileName);
+  TRACE ("GetFileAttributeW(%S) called\n", lpFileName);
 
   Result = GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &FileAttributeData);
 
@@ -952,7 +1027,7 @@ GetFileAttributesW(LPCWSTR lpFileName)
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 GetFileAttributesByHandle(IN HANDLE hFile,
                           OUT LPDWORD dwFileAttributes,
                           IN DWORD dwFlags)
@@ -960,15 +1035,15 @@ GetFileAttributesByHandle(IN HANDLE hFile,
     FILE_BASIC_INFORMATION FileBasic;
     IO_STATUS_BLOCK IoStatusBlock;
     NTSTATUS Status;
-    
+
     UNREFERENCED_PARAMETER(dwFlags);
-    
+
     if (IsConsoleHandle(hFile))
     {
         SetLastError(ERROR_INVALID_HANDLE);
         return FALSE;
     }
-    
+
     Status = NtQueryInformationFile(hFile,
                                     &IoStatusBlock,
                                     &FileBasic,
@@ -979,7 +1054,7 @@ GetFileAttributesByHandle(IN HANDLE hFile,
         *dwFileAttributes = FileBasic.FileAttributes;
         return TRUE;
     }
-    
+
     SetLastErrorByStatus(Status);
     return FALSE;
 }
@@ -988,7 +1063,7 @@ GetFileAttributesByHandle(IN HANDLE hFile,
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 SetFileAttributesByHandle(IN HANDLE hFile,
                           IN DWORD dwFileAttributes,
                           IN DWORD dwFlags)
@@ -998,7 +1073,7 @@ SetFileAttributesByHandle(IN HANDLE hFile,
     NTSTATUS Status;
 
     UNREFERENCED_PARAMETER(dwFlags);
-    
+
     if (IsConsoleHandle(hFile))
     {
         SetLastError(ERROR_INVALID_HANDLE);
@@ -1013,7 +1088,7 @@ SetFileAttributesByHandle(IN HANDLE hFile,
     if (NT_SUCCESS(Status))
     {
         FileBasic.FileAttributes = dwFileAttributes;
-        
+
         Status = NtSetInformationFile(hFile,
                                       &IoStatusBlock,
                                       &FileBasic,
@@ -1026,7 +1101,7 @@ SetFileAttributesByHandle(IN HANDLE hFile,
         SetLastErrorByStatus(Status);
         return FALSE;
     }
-    
+
     return TRUE;
 }
 
@@ -1034,7 +1109,7 @@ SetFileAttributesByHandle(IN HANDLE hFile,
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 SetFileAttributesA(
    LPCSTR lpFileName,
        DWORD dwFileAttributes)
@@ -1051,7 +1126,7 @@ SetFileAttributesA(
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 SetFileAttributesW(LPCWSTR lpFileName,
                   DWORD dwFileAttributes)
 {
@@ -1062,7 +1137,7 @@ SetFileAttributesW(LPCWSTR lpFileName,
   HANDLE FileHandle;
   NTSTATUS Status;
 
-  DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName, dwFileAttributes);
+  TRACE ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName, dwFileAttributes);
 
   /* Validate and translate the filename */
   if (!RtlDosPathNameToNtPathName_U (lpFileName,
@@ -1070,11 +1145,11 @@ SetFileAttributesW(LPCWSTR lpFileName,
                                     NULL,
                                     NULL))
     {
-      DPRINT ("Invalid path\n");
+      WARN ("Invalid path\n");
       SetLastError (ERROR_BAD_PATHNAME);
       return FALSE;
     }
-  DPRINT ("FileName: \'%wZ\'\n", &FileName);
+  TRACE ("FileName: \'%wZ\'\n", &FileName);
 
   /* build the object attributes */
   InitializeObjectAttributes (&ObjectAttributes,
@@ -1093,7 +1168,7 @@ SetFileAttributesW(LPCWSTR lpFileName,
   RtlFreeUnicodeString (&FileName);
   if (!NT_SUCCESS (Status))
     {
-      DPRINT ("NtOpenFile() failed (Status %lx)\n", Status);
+      WARN ("NtOpenFile() failed (Status %lx)\n", Status);
       SetLastErrorByStatus (Status);
       return FALSE;
     }
@@ -1105,7 +1180,7 @@ SetFileAttributesW(LPCWSTR lpFileName,
                                  FileBasicInformation);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status);
+      WARN ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status);
       NtClose (FileHandle);
       SetLastErrorByStatus (Status);
       return FALSE;
@@ -1120,7 +1195,7 @@ SetFileAttributesW(LPCWSTR lpFileName,
   NtClose (FileHandle);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status);
+      WARN ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status);
       SetLastErrorByStatus (Status);
       return FALSE;
     }
@@ -1165,7 +1240,7 @@ UINT WINAPI GetTempFileNameW( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR
     int i;
     LPWSTR p;
 
-    if ( !path || !prefix || !buffer )
+    if ( !path || !buffer )
     {
         SetLastError( ERROR_INVALID_PARAMETER );
         return 0;
@@ -1177,7 +1252,8 @@ UINT WINAPI GetTempFileNameW( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR
     /* add a \, if there isn't one  */
     if ((p == buffer) || (p[-1] != '\\')) *p++ = '\\';
 
-    for (i = 3; (i > 0) && (*prefix); i--) *p++ = *prefix++;
+    if ( prefix )
+        for (i = 3; (i > 0) && (*prefix); i--) *p++ = *prefix++;
 
     unique &= 0xffff;
 
@@ -1197,7 +1273,7 @@ UINT WINAPI GetTempFileNameW( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR
                                   CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
             if (handle != INVALID_HANDLE_VALUE)
             {  /* We created it */
-                DPRINT("created %S\n", buffer);
+                TRACE("created %S\n", buffer);
                 CloseHandle( handle );
                 break;
             }
@@ -1208,7 +1284,7 @@ UINT WINAPI GetTempFileNameW( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR
         } while (unique != num);
     }
 
-    DPRINT("returning %S\n", buffer);
+    TRACE("returning %S\n", buffer);
     return unique;
 }
 
@@ -1219,7 +1295,7 @@ UINT WINAPI GetTempFileNameW( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 GetFileTime(HANDLE hFile,
            LPFILETIME lpCreationTime,
            LPFILETIME lpLastAccessTime,
@@ -1260,7 +1336,7 @@ GetFileTime(HANDLE hFile,
 /*
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 SetFileTime(HANDLE hFile,
            CONST FILETIME *lpCreationTime,
            CONST FILETIME *lpLastAccessTime,
@@ -1316,7 +1392,7 @@ SetFileTime(HANDLE hFile,
  *
  * @implemented
  */
-BOOL STDCALL
+BOOL WINAPI
 SetEndOfFile(HANDLE hFile)
 {
        IO_STATUS_BLOCK  IoStatusBlock;
@@ -1393,7 +1469,7 @@ SetEndOfFile(HANDLE hFile)
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 SetFileValidData(
     HANDLE hFile,
     LONGLONG ValidDataLength
@@ -1427,7 +1503,7 @@ SetFileValidData(
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 SetFileShortNameW(
   HANDLE hFile,
   LPCWSTR lpShortName)
@@ -1483,7 +1559,7 @@ SetFileShortNameW(
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 SetFileShortNameA(
     HANDLE hFile,
     LPCSTR lpShortName
@@ -1514,7 +1590,7 @@ SetFileShortNameA(
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 CheckNameLegalDOS8Dot3W(
     LPCWSTR lpName,
     LPSTR lpOemName OPTIONAL,
@@ -1537,7 +1613,7 @@ CheckNameLegalDOS8Dot3W(
     if(lpOemName != NULL)
     {
       AnsiName.Buffer = lpOemName;
-      AnsiName.MaximumLength = OemNameSize * sizeof(CHAR);
+      AnsiName.MaximumLength = (USHORT)OemNameSize * sizeof(CHAR);
       AnsiName.Length = 0;
     }
 
@@ -1555,7 +1631,7 @@ CheckNameLegalDOS8Dot3W(
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 CheckNameLegalDOS8Dot3A(
     LPCSTR lpName,
     LPSTR lpOemName OPTIONAL,
@@ -1579,7 +1655,7 @@ CheckNameLegalDOS8Dot3A(
     if(lpOemName != NULL)
     {
       AnsiName.Buffer = lpOemName;
-      AnsiName.MaximumLength = OemNameSize * sizeof(CHAR);
+      AnsiName.MaximumLength = (USHORT)OemNameSize * sizeof(CHAR);
       AnsiName.Length = 0;
     }
 
@@ -1624,7 +1700,7 @@ GetFinalPathNameByHandleA(IN HANDLE hFile,
         cchFilePath > sizeof(FilePathW) / sizeof(FilePathW[0]))
     {
         FilePathU.Length = 0;
-        FilePathU.MaximumLength = cchFilePath * sizeof(WCHAR);
+        FilePathU.MaximumLength = (USHORT)cchFilePath * sizeof(WCHAR);
         FilePathU.Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
                                            0,
                                            FilePathU.MaximumLength);
@@ -1764,4 +1840,208 @@ OpenFileById(IN HANDLE hFile,
     return INVALID_HANDLE_VALUE;
 }
 
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+ReplaceFileA(
+    LPCSTR  lpReplacedFileName,
+    LPCSTR  lpReplacementFileName,
+    LPCSTR  lpBackupFileName,
+    DWORD   dwReplaceFlags,
+    LPVOID  lpExclude,
+    LPVOID  lpReserved
+    )
+{
+    WCHAR *replacedW, *replacementW, *backupW = NULL;
+    BOOL ret;
+
+    /* This function only makes sense when the first two parameters are defined */
+    if (!lpReplacedFileName || !(replacedW = FilenameA2W(lpReplacedFileName, TRUE)))
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    if (!lpReplacementFileName || !(replacementW = FilenameA2W(lpReplacementFileName, TRUE)))
+    {
+        HeapFree(GetProcessHeap(), 0, replacedW);
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return FALSE;
+    }
+
+    /* The backup parameter, however, is optional */
+    if (lpBackupFileName)
+    {
+        if (!(backupW = FilenameA2W(lpBackupFileName, TRUE)))
+        {
+            HeapFree(GetProcessHeap(), 0, replacedW);
+            HeapFree(GetProcessHeap(), 0, replacementW);
+            SetLastError(ERROR_INVALID_PARAMETER);
+            return FALSE;
+        }
+    }
+
+    ret = ReplaceFileW(replacedW, replacementW, backupW, dwReplaceFlags, lpExclude, lpReserved);
+    HeapFree(GetProcessHeap(), 0, replacedW);
+    HeapFree(GetProcessHeap(), 0, replacementW);
+    HeapFree(GetProcessHeap(), 0, backupW);
+
+    return ret;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL
+WINAPI
+ReplaceFileW(
+    LPCWSTR lpReplacedFileName,
+    LPCWSTR lpReplacementFileName,
+    LPCWSTR lpBackupFileName,
+    DWORD   dwReplaceFlags,
+    LPVOID  lpExclude,
+    LPVOID  lpReserved
+    )
+{
+    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);
+
+    /* First two arguments are mandatory */
+    if (!lpReplacedFileName || !lpReplacementFileName)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        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)))
+    {
+        Error = ERROR_PATH_NOT_FOUND;
+        goto Cleanup;
+    }
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &NtReplacedName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+
+    Status = NtOpenFile(&hReplaced,
+                        GENERIC_READ | GENERIC_WRITE | DELETE | SYNCHRONIZE | WRITE_DAC,
+                        &ObjectAttributes,
+                        &IoStatusBlock,
+                        FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                        FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
+
+    if (!NT_SUCCESS(Status))
+    {
+        if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
+            Error = ERROR_FILE_NOT_FOUND;
+        else
+            Error = ERROR_UNABLE_TO_REMOVE_REPLACED;
+        goto Cleanup;
+    }
+
+    /* Blank it */
+    SetEndOfFile(hReplaced) ;
+
+    /*
+     * Open the replacement file for reading, writing, and deleting
+     * (deleting is needed when finished)
+     */
+    if (!(RtlDosPathNameToNtPathName_U(lpReplacementFileName, &NtReplacementName, NULL, NULL)))
+    {
+        Error = ERROR_PATH_NOT_FOUND;
+        goto Cleanup;
+    }
+
+    InitializeObjectAttributes(&ObjectAttributes,
+                               &NtReplacementName,
+                               OBJ_CASE_INSENSITIVE,
+                               NULL,
+                               NULL);
+
+    Status = NtOpenFile(&hReplacement,
+                        GENERIC_READ | DELETE | SYNCHRONIZE,
+                        &ObjectAttributes,
+                        &IoStatusBlock,
+                        0,
+                        FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE);
+
+    if (!NT_SUCCESS(Status))
+    {
+        Error = RtlNtStatusToDosError(Status);
+        goto Cleanup;
+    }
+
+    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 (hReplaced) NtClose(hReplaced);
+    if (hReplacement) NtClose(hReplacement);
+    if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
+
+    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)
+    {
+        TRACE("ReplaceFileW failed (error=%d)\n", Error);
+        SetLastError(Error);
+    }
+    return Ret;
+}
+
 /* EOF */