give GetFileAttributesExW more NtOpenFile right to prevent reactos crash if u using...
[reactos.git] / reactos / lib / kernel32 / file / file.c
index 52941dc..826ad71 100644 (file)
-/*
+/* $Id$
+ *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
  * FILE:            lib/kernel32/file/file.c
  * PURPOSE:         Directory functions
  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
                  GetTempFileName is modified from WINE [ Alexandre Juiliard ]
*                 GetTempFileName is modified from WINE [ Alexandre Juiliard ]
  * UPDATE HISTORY:
  *                  Created 01/11/98
  */
 
-/* FIXME: the large integer manipulations in this file dont handle overflow  */
+/* INCLUDES *****************************************************************/
 
-#undef WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <ddk/ntddk.h>
-#include <wstring.h>
-#include <string.h>
-#include <kernel32/li.h>
-#include <ddk/rtl.h>
+#include <k32.h>
 
-#define LPPROGRESS_ROUTINE void*
+#define NDEBUG
+#include "../include/debug.h"
 
 
+/* GLOBALS ******************************************************************/
 
+BOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem
 
-WINBOOL 
-CopyFileExW( 
-    LPCWSTR lpExistingFileName, 
-    LPCWSTR lpNewFileName, 
-    LPPROGRESS_ROUTINE lpProgressRoutine, 
-    LPVOID lpData, 
-    WINBOOL * pbCancel, 
-    DWORD dwCopyFlags 
-    );
+/* FUNCTIONS ****************************************************************/
 
-WINBOOL 
-CopyFileExA( 
-    LPCSTR lpExistingFileName, 
-    LPCSTR lpNewFileName, 
-    LPPROGRESS_ROUTINE lpProgressRoutine, 
-    LPVOID lpData, 
-    WINBOOL * pbCancel, 
-    DWORD dwCopyFlags 
-    ); 
 
-DWORD
-GetCurrentTime(VOID);
 
-BOOLEAN  bIsFileApiAnsi; // set the file api to ansi or oem
+PWCHAR
+FilenameA2W(LPCSTR NameA, BOOL alloc)
+{
+   ANSI_STRING str;
+   UNICODE_STRING strW;
+   PUNICODE_STRING pstrW;
+   NTSTATUS Status;
 
+   ASSERT(NtCurrentTeb()->StaticUnicodeString.Buffer == NtCurrentTeb()->StaticUnicodeBuffer);
+   ASSERT(NtCurrentTeb()->StaticUnicodeString.MaximumLength == sizeof(NtCurrentTeb()->StaticUnicodeBuffer));
 
+   RtlInitAnsiString(&str, NameA);
+   pstrW = alloc ? &strW : &NtCurrentTeb()->StaticUnicodeString;
 
-VOID
-STDCALL
-SetFileApisToOEM(VOID)
-{
-       bIsFileApiAnsi = FALSE;
-       return; 
-}
+   if (bIsFileApiAnsi)
+        Status= RtlAnsiStringToUnicodeString( pstrW, &str, alloc );
+   else
+        Status= RtlOemStringToUnicodeString( pstrW, &str, alloc );
 
-WINBASEAPI
-VOID
-WINAPI
-SetFileApisToANSI(VOID)
-{
-       bIsFileApiAnsi = TRUE;
-       return; 
+    if (NT_SUCCESS(Status))
+       return pstrW->Buffer;
+
+    if (Status== STATUS_BUFFER_OVERFLOW)
+        SetLastError( ERROR_FILENAME_EXCED_RANGE );
+    else
+        SetLastErrorByStatus(Status);
+
+    return NULL;
 }
 
 
+/*
+No copy/conversion is done if the dest. buffer is too small.
 
-WINBOOL
-STDCALL
-AreFileApisANSI(VOID)
+Returns:
+   Success: number of TCHARS copied into dest. buffer NOT including nullterm
+   Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
+*/
+DWORD
+FilenameU2A_FitOrFail(
+   LPSTR  DestA,
+   INT destLen, /* buffer size in TCHARS incl. nullchar */
+   PUNICODE_STRING SourceU
+   )
 {
-       return  bIsFileApiAnsi;
-       
-}
+   DWORD ret;
 
+   ret = bIsFileApiAnsi? RtlUnicodeStringToAnsiSize(SourceU) : RtlUnicodeStringToOemSize(SourceU);
+   /* ret incl. nullchar */
 
+   if (DestA && (INT)ret <= destLen)
+   {
+      ANSI_STRING str;
 
+      str.Buffer = DestA;
+      str.MaximumLength = destLen;
 
-WINBOOL STDCALL WriteFile(HANDLE  hFile,       
-                      LPCVOID lpBuffer,        
-                      DWORD nNumberOfBytesToWrite,
-                      LPDWORD lpNumberOfBytesWritten,  
-                      LPOVERLAPPED lpOverLapped)
-{
-
-   PLARGE_INTEGER Offset;
-   LARGE_INTEGER ByteOffset;
-   HANDLE hEvent = NULL;
-   NTSTATUS errCode;
-   PIO_STATUS_BLOCK IoStatusBlock;
-   IO_STATUS_BLOCK IIosb;
-   if ( lpOverLapped != NULL )
-     {
-       SET_LARGE_INTEGER_LOW_PART(ByteOffset, lpOverLapped->Offset);
-       SET_LARGE_INTEGER_HIGH_PART(ByteOffset, lpOverLapped->OffsetHigh);
-       Offset = &ByteOffset;
-       lpOverLapped->Internal = STATUS_PENDING;
-       hEvent = lpOverLapped->hEvent;
-       IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
-     }
-   else
-     {
-       IoStatusBlock = &IIosb;
-       Offset = NULL;
-     }
-   errCode = NtWriteFile(hFile,hEvent,NULL,NULL,
-                        (PIO_STATUS_BLOCK)lpOverLapped,
-                        (PVOID)lpBuffer, 
-                        nNumberOfBytesToWrite,
-             Offset,
-                        NULL);
-   if (!NT_SUCCESS(errCode))
-     {
-       SetLastError(RtlNtStatusToDosError(errCode));
-       return FALSE;
-     }
-   
-   return(TRUE);
-}
 
-WINBOOL STDCALL ReadFile(HANDLE hFile,
-                        LPVOID lpBuffer,
-                        DWORD nNumberOfBytesToRead,
-                        LPDWORD lpNumberOfBytesRead,
-                        LPOVERLAPPED lpOverLapped)
-{
+      if (bIsFileApiAnsi)
+         RtlUnicodeStringToAnsiString(&str, SourceU, FALSE );
+      else
+         RtlUnicodeStringToOemString(&str, SourceU, FALSE );
 
-   HANDLE hEvent = NULL;
-   PLARGE_INTEGER Offset;
-   LARGE_INTEGER ByteOffset;
-   NTSTATUS errCode;
-   PIO_STATUS_BLOCK IoStatusBlock;
-   IO_STATUS_BLOCK IIosb;
+      ret = str.Length;  /* SUCCESS: length without terminating 0 */
+   }
 
-   
-   if ( lpOverLapped != NULL )
-     {
-       SET_LARGE_INTEGER_LOW_PART(ByteOffset, lpOverLapped->Offset);
-       SET_LARGE_INTEGER_HIGH_PART(ByteOffset, lpOverLapped->OffsetHigh);
-       Offset = &ByteOffset;
-       lpOverLapped->Internal = STATUS_PENDING;
-       hEvent = lpOverLapped->hEvent;
-       IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
-     }
-   else
-     {
-       IoStatusBlock = &IIosb;
-       Offset = NULL;
-     }
-                                            
-   errCode = NtReadFile(hFile,
-                       hEvent,
-                       NULL,
-                       NULL,
-                       IoStatusBlock,
-                       lpBuffer,
-                       nNumberOfBytesToRead,
-                       Offset,                 
-                       NULL);   
-   if ( !NT_SUCCESS(errCode) )  
-     {      
-       SetLastError(RtlNtStatusToDosError(errCode));
-       return FALSE;
-     }
-   return TRUE;  
+   return ret;
 }
 
-WINBOOL
-STDCALL
-ReadFileEx(
-          HANDLE hFile,
-          LPVOID lpBuffer,
-          DWORD nNumberOfBytesToRead,
-          LPOVERLAPPED lpOverLapped,
-          LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
-          )
+
+/*
+No copy/conversion is done if the dest. buffer is too small.
+
+Returns:
+   Success: number of TCHARS copied into dest. buffer NOT including nullterm
+   Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
+*/
+DWORD
+FilenameW2A_FitOrFail(
+   LPSTR  DestA,
+   INT destLen, /* buffer size in TCHARS incl. nullchar */
+   LPCWSTR SourceW,
+   INT sourceLen /* buffer size in TCHARS incl. nullchar */
+   )
 {
-       HANDLE hEvent = NULL;
-       LARGE_INTEGER Offset;
-       NTSTATUS errCode;
-       IO_STATUS_BLOCK IIosb;
-       PIO_STATUS_BLOCK IoStatusBlock;
-       
-               
-       if ( lpOverLapped != NULL ) {
-               SET_LARGE_INTEGER_LOW_PART(Offset, lpOverLapped->Offset);
-               SET_LARGE_INTEGER_HIGH_PART(Offset, lpOverLapped->OffsetHigh);
-               lpOverLapped->Internal = STATUS_PENDING;
-               hEvent = lpOverLapped->hEvent;
-               IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
-       }
-       else {
-               SET_LARGE_INTEGER_LOW_PART(Offset, 0);
-               SET_LARGE_INTEGER_HIGH_PART(Offset, 0);
-               IoStatusBlock = &IIosb;
-       }
-       
-                                
-               
-
-       errCode = NtReadFile(hFile,
-                            hEvent,
-                            (PIO_APC_ROUTINE)lpCompletionRoutine,
-                            NULL,
-                            IoStatusBlock,
-                            lpBuffer,
-                            nNumberOfBytesToRead,
-                            &Offset,
-                            NULL);
-       if ( !NT_SUCCESS(errCode) )  {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
-       return TRUE;  
-}
+   UNICODE_STRING strW;
 
+   if (sourceLen < 0) sourceLen = wcslen(SourceW) + 1;
 
-WINBOOL
-STDCALL
-LockFile(
-        HANDLE hFile,
-        DWORD dwFileOffsetLow,
-        DWORD dwFileOffsetHigh,
-        DWORD nNumberOfBytesToLockLow,
-        DWORD nNumberOfBytesToLockHigh
-        )
-{      
-       DWORD dwReserved;
-       OVERLAPPED Overlapped;
-   
-       Overlapped.Offset = dwFileOffsetLow;
-       Overlapped.OffsetHigh = dwFileOffsetHigh;
-       dwReserved = 0;
-
-       return LockFileEx(hFile, LOCKFILE_FAIL_IMMEDIATELY|LOCKFILE_EXCLUSIVE_LOCK,dwReserved,nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh, &Overlapped ) ;
-}
+   strW.Buffer = (PWCHAR)SourceW;
+   strW.MaximumLength = sourceLen * sizeof(WCHAR);
+   strW.Length = strW.MaximumLength - sizeof(WCHAR);
 
-WINBOOL
-STDCALL
-LockFileEx(
-          HANDLE hFile,
-          DWORD dwFlags,
-          DWORD dwReserved,
-          DWORD nNumberOfBytesToLockLow,
-          DWORD nNumberOfBytesToLockHigh,
-          LPOVERLAPPED lpOverlapped
-          )
-{
-   LARGE_INTEGER BytesToLock;  
-   BOOL LockImmediate;
-   BOOL LockExclusive;
-   NTSTATUS errCode;
-   LARGE_INTEGER Offset;
-   
-   if(dwReserved != 0) 
-     {      
-       SetLastError(ERROR_INVALID_PARAMETER);
-       return FALSE;
-     }
-   
-   lpOverlapped->Internal = STATUS_PENDING;  
-   
-   SET_LARGE_INTEGER_LOW_PART(Offset, lpOverlapped->Offset);
-   SET_LARGE_INTEGER_HIGH_PART(Offset, lpOverlapped->OffsetHigh);
-   
-   if ( (dwFlags & LOCKFILE_FAIL_IMMEDIATELY) == LOCKFILE_FAIL_IMMEDIATELY )
-     LockImmediate = TRUE;
-   else
-     LockImmediate = FALSE;
-   
-   if ( (dwFlags & LOCKFILE_EXCLUSIVE_LOCK) == LOCKFILE_EXCLUSIVE_LOCK )
-     LockExclusive = TRUE;
-   else
-     LockExclusive = FALSE;
-   
-   SET_LARGE_INTEGER_LOW_PART(BytesToLock, nNumberOfBytesToLockLow);
-   SET_LARGE_INTEGER_HIGH_PART(BytesToLock, nNumberOfBytesToLockHigh);
-   
-   errCode = NtLockFile(hFile,
-                       NULL,
-                       NULL,
-                       NULL,
-                       (PIO_STATUS_BLOCK)lpOverlapped,
-                       &Offset,
-                       &BytesToLock,
-                       NULL,
-                       LockImmediate,
-                       LockExclusive);
-   if ( !NT_SUCCESS(errCode) ) 
-     {
-      SetLastError(RtlNtStatusToDosError(errCode));
-      return FALSE;
-     }
-   
-   return TRUE;
-                
+   return FilenameU2A_FitOrFail(DestA, destLen, &strW);
 }
 
-WINBOOL
-STDCALL
-UnlockFile(
-          HANDLE hFile,
-          DWORD dwFileOffsetLow,
-          DWORD dwFileOffsetHigh,
-          DWORD nNumberOfBytesToUnlockLow,
-          DWORD nNumberOfBytesToUnlockHigh
-          )
+
+/*
+Return: num. TCHARS copied into dest including nullterm
+*/
+DWORD
+FilenameA2W_N(
+   LPWSTR dest,
+   INT destlen, /* buffer size in TCHARS incl. nullchar */
+   LPCSTR src,
+   INT srclen /* buffer size in TCHARS incl. nullchar */
+   )
 {
-       DWORD dwReserved;
-       OVERLAPPED Overlapped;
-       Overlapped.Offset = dwFileOffsetLow;
-       Overlapped.OffsetHigh = dwFileOffsetHigh;
-       dwReserved = 0;
-       return UnlockFileEx(hFile, dwReserved, nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh, &Overlapped);
+    DWORD ret;
 
-}
+    if (srclen < 0) srclen = strlen( src ) + 1;
 
+    if (bIsFileApiAnsi)
+        RtlMultiByteToUnicodeN( dest, destlen* sizeof(WCHAR), &ret, (LPSTR)src, srclen  );
+    else
+        RtlOemToUnicodeN( dest, destlen* sizeof(WCHAR), &ret, (LPSTR)src, srclen );
 
+    if (ret) dest[(ret/sizeof(WCHAR))-1]=0;
 
-WINBOOL 
-STDCALL 
-UnlockFileEx(
-       HANDLE hFile,
-       DWORD dwReserved,
-       DWORD nNumberOfBytesToUnLockLow,
-       DWORD nNumberOfBytesToUnLockHigh,
-       LPOVERLAPPED lpOverlapped
-       )
-{
-   LARGE_INTEGER BytesToUnLock;
-   LARGE_INTEGER StartAddress;
-   NTSTATUS errCode;
-   
-   if(dwReserved != 0) 
-     {
-       SetLastError(ERROR_INVALID_PARAMETER);
-       return FALSE;
-     }
-   if ( lpOverlapped == NULL ) 
-     {
-       SetLastError(ERROR_INVALID_PARAMETER);
-       return FALSE;
-     }
-   
-   SET_LARGE_INTEGER_LOW_PART(BytesToUnLock, nNumberOfBytesToUnLockLow);
-   SET_LARGE_INTEGER_HIGH_PART(BytesToUnLock, nNumberOfBytesToUnLockHigh);
-   
-   SET_LARGE_INTEGER_LOW_PART(StartAddress, lpOverlapped->Offset);
-   SET_LARGE_INTEGER_HIGH_PART(StartAddress, lpOverlapped->OffsetHigh);
-   
-   errCode = NtUnlockFile(hFile,
-                         (PIO_STATUS_BLOCK)lpOverlapped,
-                         &StartAddress,
-                         &BytesToUnLock,
-                         NULL);
-   if ( !NT_SUCCESS(errCode) ) {
-      SetLastError(RtlNtStatusToDosError(errCode));
-      return FALSE;
-   }
-   
-   return TRUE;
+    return ret/sizeof(WCHAR);
 }
 
+/*
+Return: num. TCHARS copied into dest including nullterm
+*/
+DWORD
+FilenameW2A_N(
+   LPSTR dest,
+   INT destlen, /* buffer size in TCHARS incl. nullchar */
+   LPCWSTR src,
+   INT srclen /* buffer size in TCHARS incl. nullchar */
+   )
+{
+    DWORD ret;
 
+    if (srclen < 0) srclen = wcslen( src ) + 1;
 
+    if (bIsFileApiAnsi)
+        RtlUnicodeToMultiByteN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR));
+    else
+        RtlUnicodeToOemN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR) );
 
+    if (ret) dest[ret-1]=0;
 
+    return ret;
+}
 
 
-WINBOOL
+/*
+ * @implemented
+ */
+VOID
 STDCALL
-CopyFileA(
-    LPCSTR lpExistingFileName,
-    LPCSTR lpNewFileName,
-    WINBOOL bFailIfExists
-    )
+SetFileApisToOEM(VOID)
 {
-       return CopyFileExA(lpExistingFileName,lpNewFileName,NULL,NULL,FALSE,bFailIfExists);
-}
+    /* Set the correct Base Api */
+    Basep8BitStringToUnicodeString = (PRTL_CONVERT_STRING)RtlOemStringToUnicodeString;
 
-WINBOOL 
-STDCALL 
-CopyFileExA( 
-    LPCSTR lpExistingFileName, 
-    LPCSTR lpNewFileName, 
-    LPPROGRESS_ROUTINE lpProgressRoutine, 
-    LPVOID lpData, 
-    WINBOOL * pbCancel, 
-    DWORD dwCopyFlags 
-    )
-{
-       ULONG i;
-       WCHAR ExistingFileNameW[MAX_PATH];
-       WCHAR NewFileNameW[MAX_PATH];
-
-       
-
-       i = 0;
-       while ((*lpExistingFileName)!=0 && i < MAX_PATH)
-       {
-               ExistingFileNameW[i] = *lpExistingFileName;
-               lpExistingFileName++;
-               i++;
-       }
-       ExistingFileNameW[i] = 0;
-
-       i = 0;
-       while ((*lpNewFileName)!=0 && i < MAX_PATH)
-       {
-               NewFileNameW[i] = *lpNewFileName;
-               lpNewFileName++;
-               i++;
-       }
-       NewFileNameW[i] = 0;
-
-       return CopyFileExW(ExistingFileNameW,NewFileNameW,lpProgressRoutine,lpData,pbCancel,dwCopyFlags);
+    /* FIXME: Old, deprecated way */
+    bIsFileApiAnsi = FALSE;
 }
 
 
-WINBOOL
+/*
+ * @implemented
+ */
+VOID
 STDCALL
-CopyFileW(
-    LPCWSTR lpExistingFileName,
-    LPCWSTR lpNewFileName,
-    WINBOOL bFailIfExists
-    )
+SetFileApisToANSI(VOID)
 {
-       return CopyFileExW(lpExistingFileName,lpNewFileName,NULL,NULL,NULL,bFailIfExists);
-}
+    /* Set the correct Base Api */
+    Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString;
 
+    /* FIXME: Old, deprecated way */
+    bIsFileApiAnsi = TRUE;
+}
 
 
+/*
+ * @implemented
+ */
+BOOL STDCALL
+AreFileApisANSI(VOID)
+{
+   return bIsFileApiAnsi;
+}
 
 
-WINBOOL 
-STDCALL 
-CopyFileExW( 
-    LPCWSTR lpExistingFileName, 
-    LPCWSTR lpNewFileName, 
-    LPPROGRESS_ROUTINE lpProgressRoutine, 
-    LPVOID lpData, 
-    WINBOOL * pbCancel, 
-    DWORD dwCopyFlags 
-    )
+/*
+ * @implemented
+ */
+HFILE STDCALL
+OpenFile(LPCSTR lpFileName,
+        LPOFSTRUCT lpReOpenBuff,
+        UINT uStyle)
 {
-       
-       NTSTATUS errCode = 0;
-       HANDLE FileHandleSource, FileHandleDest;
+       OBJECT_ATTRIBUTES ObjectAttributes;
        IO_STATUS_BLOCK IoStatusBlock;
+       UNICODE_STRING FileNameString;
+       UNICODE_STRING FileNameU;
+       ANSI_STRING FileName;
+       WCHAR PathNameW[MAX_PATH];
+       HANDLE FileHandle = NULL;
+       NTSTATUS errCode;
+       PWCHAR FilePart;
+       ULONG Len;
 
-       FILE_STANDARD_INFORMATION FileStandard;
-       FILE_BASIC_INFORMATION FileBasic;
-       FILE_POSITION_INFORMATION FilePosition;
-       
-       UCHAR *lpBuffer = NULL;
-
-
-
-       ULONG RegionSize = 0x1000000;
-
-       BOOL bCancel = FALSE;
-
-       
-
-       FileHandleSource = CreateFileW(
-               lpExistingFileName,     
-               GENERIC_READ,   
-               FILE_SHARE_READ,        
-               NULL,   
-               OPEN_EXISTING,  
-               FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING,   
-               NULL 
-       );
-
-
-
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
-  
-
-       errCode = NtQueryInformationFile(FileHandleSource,
-               &IoStatusBlock,&FileStandard, sizeof(FILE_STANDARD_INFORMATION),
-               FileStandardInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               NtClose(FileHandleSource);
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
+       DPRINT("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName, lpReOpenBuff, uStyle);
 
-       errCode = NtQueryInformationFile(FileHandleSource,
-               &IoStatusBlock,&FileBasic, sizeof(FILE_BASIC_INFORMATION),
-               FileBasicInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               NtClose(FileHandleSource);
-               SetLastError(RtlNtStatusToDosError(errCode));
+       if (lpReOpenBuff == NULL)
+       {
                return FALSE;
        }
-               
-
-       
-
-   
-  
-               FileHandleDest = CreateFileW(
-                       lpNewFileName,  
-               GENERIC_WRITE,  
-               FILE_SHARE_WRITE,       
-               NULL,   
-               dwCopyFlags  ?  CREATE_NEW : CREATE_ALWAYS ,    
-               FileBasic.FileAttributes|FILE_FLAG_NO_BUFFERING,        
-               NULL 
-               );
-       if ( !NT_SUCCESS(errCode) ) {
-               NtClose(FileHandleSource);
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       } 
-
-
-
-
-       SET_LARGE_INTEGER_LOW_PART(FilePosition.CurrentByteOffset, 0);
-       SET_LARGE_INTEGER_HIGH_PART(FilePosition.CurrentByteOffset, 0);
-
-       errCode = NtSetInformationFile(FileHandleSource,
-               &IoStatusBlock,&FilePosition, sizeof(FILE_POSITION_INFORMATION),
-               FilePositionInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               NtClose(FileHandleSource);
-               NtClose(FileHandleDest);
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       } 
-
-       errCode = NtSetInformationFile(FileHandleDest,
-               &IoStatusBlock,&FilePosition, sizeof(FILE_POSITION_INFORMATION),
-               FilePositionInformation);
-  
-       if ( !NT_SUCCESS(errCode) ) {
-               NtClose(FileHandleSource);
-               NtClose(FileHandleDest);
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       } 
-
-
-
-       errCode = NtAllocateVirtualMemory( 
-               NtCurrentProcess(),
-               (PVOID *)&lpBuffer,
-               2,
-               &RegionSize,
-               MEM_COMMIT, 
-               PAGE_READWRITE
-       );
-  
-       if ( !NT_SUCCESS(errCode) ) {
-               NtClose(FileHandleSource);
-               NtClose(FileHandleDest);
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       } 
-
-       
-
-       
-
-       
-       do {
-
-               errCode = NtReadFile(
-                            FileHandleSource,
-                            NULL,
-                            NULL,
-                            NULL,
-                            (PIO_STATUS_BLOCK)&IoStatusBlock,
-                            lpBuffer,
-                            RegionSize,
-                            NULL,
-                            NULL);
-               if ( pbCancel != NULL )
-                       bCancel = *pbCancel;
-
-       
-               if ( !NT_SUCCESS(errCode) || bCancel )  {
-                       NtFreeVirtualMemory(NtCurrentProcess(),(PVOID *)&lpBuffer, &RegionSize,MEM_RELEASE);
-                       NtClose(FileHandleSource);
-                       NtClose(FileHandleDest);
-                       if ( errCode == STATUS_END_OF_FILE )
-                               break;
-                       else
-                               return FALSE;
-                       
-               }
 
-               errCode = NtWriteFile(FileHandleDest,
-                            NULL,
-                            lpProgressRoutine,
-                            lpData,
-                            (PIO_STATUS_BLOCK)&IoStatusBlock,
-                            lpBuffer,
-                            RegionSize,
-                            NULL,
-                            NULL);
-
-               
-
-               if ( !NT_SUCCESS(errCode) ) {
-                       NtFreeVirtualMemory(NtCurrentProcess(),(PVOID *)&lpBuffer, &RegionSize,MEM_RELEASE);
-                       NtClose(FileHandleSource);
-                       NtClose(FileHandleDest);
-                       return FALSE;
+       if ((uStyle & OF_CREATE) == OF_CREATE)
+       {
+               DWORD Sharing;
+               switch (uStyle & 0x70)
+               {
+                       case OF_SHARE_EXCLUSIVE: Sharing = 0; break;
+                       case OF_SHARE_DENY_WRITE: Sharing = FILE_SHARE_READ; break;
+                       case OF_SHARE_DENY_READ: Sharing = FILE_SHARE_WRITE; break;
+                       case OF_SHARE_DENY_NONE:
+                       case OF_SHARE_COMPAT:
+                       default:
+                               Sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
                }
+               return (HFILE) CreateFileA (lpFileName,
+                                           GENERIC_READ | GENERIC_WRITE,
+                                           Sharing,
+                                           NULL,
+                                           CREATE_ALWAYS,
+                                           FILE_ATTRIBUTE_NORMAL,
+                                           0);
+       }
 
-       } while ( TRUE );
-
-       return TRUE;
-
+       RtlInitAnsiString (&FileName, (LPSTR)lpFileName);
 
-}
+       /* convert ansi (or oem) string to unicode */
+       if (bIsFileApiAnsi)
+               RtlAnsiStringToUnicodeString (&FileNameU, &FileName, TRUE);
+       else
+               RtlOemStringToUnicodeString (&FileNameU, &FileName, TRUE);
 
+       Len = SearchPathW (NULL,
+                          FileNameU.Buffer,
+                          NULL,
+                          OFS_MAXPATHNAME,
+                          PathNameW,
+                          &FilePart);
 
-HFILE
-STDCALL
-OpenFile(
-        LPCSTR lpFileName,
-        LPOFSTRUCT lpReOpenBuff,
-        UINT uStyle
-        )
-{
-       NTSTATUS errCode;
-       HANDLE FileHandle = NULL;
-       UNICODE_STRING FileNameString;
-       WCHAR FileNameW[MAX_PATH];
-       WCHAR PathNameW[MAX_PATH];
-       ULONG i;
-       OBJECT_ATTRIBUTES ObjectAttributes;
-       IO_STATUS_BLOCK IoStatusBlock;
-       WCHAR *FilePart;        
-       ULONG Len;
+       RtlFreeUnicodeString(&FileNameU);
 
-       if ( lpReOpenBuff == NULL ) {
-               return FALSE;
+       if (Len == 0 || Len > OFS_MAXPATHNAME)
+       {
+               return (HFILE)INVALID_HANDLE_VALUE;
        }
 
-       
+       FileName.Buffer = lpReOpenBuff->szPathName;
+       FileName.Length = 0;
+       FileName.MaximumLength = OFS_MAXPATHNAME;
 
-       
-       i = 0;
-       while ((*lpFileName)!=0 && i < MAX_PATH)
-       {
-               FileNameW[i] = *lpFileName;
-               lpFileName++;
-               i++;
-       }
-       FileNameW[i] = 0;
+       RtlInitUnicodeString(&FileNameU, PathNameW);
 
+       /* convert unicode string to ansi (or oem) */
+       if (bIsFileApiAnsi)
+               RtlUnicodeStringToAnsiString (&FileName, &FileNameU, FALSE);
+       else
+               RtlUnicodeStringToOemString (&FileName, &FileNameU, FALSE);
 
-       Len = SearchPathW(NULL,FileNameW,NULL,MAX_PATH,PathNameW,&FilePart);
-       if ( Len == 0 )
-               return (HFILE)NULL;
+       if (!RtlDosPathNameToNtPathName_U ((LPWSTR)PathNameW,
+                                          &FileNameString,
+                                          NULL,
+                                          NULL))
+       {
+               return (HFILE)INVALID_HANDLE_VALUE;
+       }
 
+       // FILE_SHARE_READ
+       // FILE_NO_INTERMEDIATE_BUFFERING
 
-       if ( Len > MAX_PATH )
+       if ((uStyle & OF_PARSE) == OF_PARSE)
+       {
+               RtlFreeUnicodeString(&FileNameString);
                return (HFILE)NULL;
-   
-       FileNameString.Length = lstrlenW(PathNameW)*sizeof(WCHAR);
-       FileNameString.Buffer = PathNameW;
-       FileNameString.MaximumLength = FileNameString.Length;
-   
-
-       
+       }
 
-       ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
+       ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
        ObjectAttributes.RootDirectory = NULL;
-       ObjectAttributes.ObjectName = &FileNameString;
+       ObjectAttributes.ObjectName = &FileNameString;
        ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
        ObjectAttributes.SecurityDescriptor = NULL;
        ObjectAttributes.SecurityQualityOfService = NULL;
 
-       // FILE_SHARE_READ
-       // FILE_NO_INTERMEDIATE_BUFFERING
-
-
-
-       if ((uStyle & OF_PARSE) == OF_PARSE ) 
-               return (HFILE)NULL;
-
+       errCode = NtOpenFile (&FileHandle,
+                             GENERIC_READ|SYNCHRONIZE,
+                             &ObjectAttributes,
+                             &IoStatusBlock,
+                             FILE_SHARE_READ,
+                             FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT);
 
-       errCode = NtOpenFile(
-               &FileHandle,
-               GENERIC_READ|SYNCHRONIZE,
-               &ObjectAttributes,
-               &IoStatusBlock,   
-               FILE_SHARE_READ,         
-               FILE_NON_DIRECTORY_FILE                                                                 
-       );
+       RtlFreeUnicodeString(&FileNameString);
 
        lpReOpenBuff->nErrCode = RtlNtStatusToDosError(errCode);
 
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
+       if (!NT_SUCCESS(errCode))
+       {
+               SetLastErrorByStatus (errCode);
                return (HFILE)INVALID_HANDLE_VALUE;
        }
 
        return (HFILE)FileHandle;
-
 }
 
 
-WINBOOL
-STDCALL
-MoveFileA(
-    LPCSTR lpExistingFileName,
-    LPCSTR lpNewFileName
-    )
-{
-       return MoveFileExA(lpExistingFileName,lpNewFileName,MOVEFILE_COPY_ALLOWED);
-}
-
-WINBOOL
-STDCALL
-MoveFileExA(
-    LPCSTR lpExistingFileName,
-    LPCSTR lpNewFileName,
-    DWORD dwFlags
-    )
+/*
+ * @implemented
+ */
+BOOL STDCALL
+FlushFileBuffers(HANDLE hFile)
 {
-       ULONG i;
-       WCHAR ExistingFileNameW[MAX_PATH];
-       WCHAR NewFileNameW[MAX_PATH];
-
-       
-
-       i = 0;
-       while ((*lpExistingFileName)!=0 && i < MAX_PATH)
-       {
-               ExistingFileNameW[i] = *lpExistingFileName;
-               lpExistingFileName++;
-               i++;
-       }
-       ExistingFileNameW[i] = 0;
-
-       i = 0;
-       while ((*lpNewFileName)!=0 && i < MAX_PATH)
-       {
-               NewFileNameW[i] = *lpNewFileName;
-               lpNewFileName++;
-               i++;
-       }
-       NewFileNameW[i] = 0;
-
-       return MoveFileExW(ExistingFileNameW,NewFileNameW,dwFlags);
-       
-}
-
+   NTSTATUS errCode;
+   IO_STATUS_BLOCK IoStatusBlock;
 
+   if (IsConsoleHandle(hFile))
+   {
+      return FALSE;
+   }
 
-WINBOOL
-STDCALL
-MoveFileW(
-    LPCWSTR lpExistingFileName,
-    LPCWSTR lpNewFileName
-    )
-{
-       return MoveFileExW(lpExistingFileName,lpNewFileName,MOVEFILE_COPY_ALLOWED);
+   errCode = NtFlushBuffersFile(hFile,
+                               &IoStatusBlock);
+   if (!NT_SUCCESS(errCode))
+     {
+       SetLastErrorByStatus(errCode);
+       return(FALSE);
+     }
+   return(TRUE);
 }
 
-#define FILE_RENAME_SIZE  MAX_PATH +sizeof(FILE_RENAME_INFORMATION)
 
-WINBOOL
-STDCALL
-MoveFileExW(
-    LPCWSTR lpExistingFileName,
-    LPCWSTR lpNewFileName,
-    DWORD dwFlags
-    )
+/*
+ * @implemented
+ */
+DWORD STDCALL
+SetFilePointer(HANDLE hFile,
+              LONG lDistanceToMove,
+              PLONG lpDistanceToMoveHigh,
+              DWORD dwMoveMethod)
 {
-       HANDLE hFile = NULL;
-       IO_STATUS_BLOCK IoStatusBlock;
-       FILE_RENAME_INFORMATION *FileRename;
-       USHORT Buffer[FILE_RENAME_SIZE];
-       NTSTATUS errCode;       
+   FILE_POSITION_INFORMATION FilePosition;
+   FILE_STANDARD_INFORMATION FileStandard;
+   NTSTATUS errCode;
+   IO_STATUS_BLOCK IoStatusBlock;
+   LARGE_INTEGER Distance;
 
-       hFile = CreateFileW(
-               lpExistingFileName,     
-               GENERIC_ALL,    
-               FILE_SHARE_WRITE|FILE_SHARE_READ,       
-               NULL,   
-               OPEN_EXISTING,  
-               FILE_ATTRIBUTE_NORMAL,  
-               NULL 
-       );
+   DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
+         hFile,lDistanceToMove,dwMoveMethod);
 
+   if(IsConsoleHandle(hFile))
+   {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return -1;
+   }
 
+   Distance.u.LowPart = lDistanceToMove;
+   if (lpDistanceToMoveHigh)
+   {
+      Distance.u.HighPart = *lpDistanceToMoveHigh;
+   }
+   else if (lDistanceToMove >= 0)
+   {
+      Distance.u.HighPart = 0;
+   }
+   else
+   {
+      Distance.u.HighPart = -1;
+   }
 
-       FileRename = (FILE_RENAME_INFORMATION *)Buffer;
-       if ( ( dwFlags & MOVEFILE_REPLACE_EXISTING ) == MOVEFILE_REPLACE_EXISTING )
-               FileRename->Replace = TRUE;
-       else
-               FileRename->Replace = FALSE;
-
-       FileRename->FileNameLength = lstrlenW(lpNewFileName);
-       memcpy(FileRename->FileName,lpNewFileName,min(FileRename->FileNameLength,MAX_PATH));
-       
-       errCode = NtSetInformationFile(hFile,&IoStatusBlock,FileRename, FILE_RENAME_SIZE, FileRenameInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               if ( CopyFileW(lpExistingFileName,lpNewFileName,FileRename->Replace) )
-                       DeleteFileW(lpExistingFileName);
-       }
+   switch(dwMoveMethod)
+   {
+     case FILE_CURRENT:
+       NtQueryInformationFile(hFile,
+                              &IoStatusBlock,
+                              &FilePosition,
+                              sizeof(FILE_POSITION_INFORMATION),
+                              FilePositionInformation);
+       FilePosition.CurrentByteOffset.QuadPart += Distance.QuadPart;
+       break;
+     case FILE_END:
+       NtQueryInformationFile(hFile,
+                               &IoStatusBlock,
+                               &FileStandard,
+                               sizeof(FILE_STANDARD_INFORMATION),
+                               FileStandardInformation);
+        FilePosition.CurrentByteOffset.QuadPart =
+                  FileStandard.EndOfFile.QuadPart + Distance.QuadPart;
+       break;
+     case FILE_BEGIN:
+        FilePosition.CurrentByteOffset.QuadPart = Distance.QuadPart;
+       break;
+     default:
+        SetLastError(ERROR_INVALID_PARAMETER);
+       return -1;
+   }
 
-       CloseHandle(hFile);
-       return TRUE;
-}
+   if(FilePosition.CurrentByteOffset.QuadPart < 0)
+   {
+     SetLastError(ERROR_NEGATIVE_SEEK);
+     return -1;
+   }
 
-WINBOOL
-STDCALL
-DeleteFileA(
-    LPCSTR lpFileName
-    )
-{
-       ULONG i;
-       
-       WCHAR FileNameW[MAX_PATH];
-
-       
-
-       i = 0;
-       while ((*lpFileName)!=0 && i < MAX_PATH)
-       {
-               FileNameW[i] = *lpFileName;
-               lpFileName++;
-               i++;
-       }
-       FileNameW[i] = 0;
-       return DeleteFileW(FileNameW);
+   errCode = NtSetInformationFile(hFile,
+                                 &IoStatusBlock,
+                                 &FilePosition,
+                                 sizeof(FILE_POSITION_INFORMATION),
+                                 FilePositionInformation);
+   if (!NT_SUCCESS(errCode))
+     {
+       SetLastErrorByStatus(errCode);
+       return -1;
+     }
 
+   if (lpDistanceToMoveHigh != NULL)
+     {
+        *lpDistanceToMoveHigh = FilePosition.CurrentByteOffset.u.HighPart;
+     }
+   return FilePosition.CurrentByteOffset.u.LowPart;
 }
 
-WINBOOL
+
+/*
+ * @implemented
+ */
+BOOL
 STDCALL
-DeleteFileW(
-    LPCWSTR lpFileName
-    )
+SetFilePointerEx(HANDLE hFile,
+                LARGE_INTEGER liDistanceToMove,
+                PLARGE_INTEGER lpNewFilePointer,
+                DWORD dwMoveMethod)
 {
-       OBJECT_ATTRIBUTES ObjectAttributes;
-       UNICODE_STRING FileNameString;
-       NTSTATUS errCode;
-       WCHAR PathNameW[MAX_PATH];
-       UINT Len;
-
-       Len =  GetCurrentDirectoryW(MAX_PATH,PathNameW);
-       if ( Len == 0 )
-               return FALSE;
-       if ( PathNameW[Len-1] != L'\\' ) {
-               PathNameW[Len] = L'\\';
-               PathNameW[Len+1] = 0;
-       }
-       lstrcatW(PathNameW,lpFileName); 
-        FileNameString.Length = lstrlenW( PathNameW)*sizeof(WCHAR);
-       if ( FileNameString.Length == 0 )
-               return FALSE;
+   FILE_POSITION_INFORMATION FilePosition;
+   FILE_STANDARD_INFORMATION FileStandard;
+   NTSTATUS errCode;
+   IO_STATUS_BLOCK IoStatusBlock;
 
-       if ( FileNameString.Length > MAX_PATH )
-               return FALSE;
-   
+   if(IsConsoleHandle(hFile))
+   {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
+   }
 
-       
-   
-       FileNameString.Buffer = (WCHAR *)PathNameW;
-       FileNameString.MaximumLength = FileNameString.Length;
-   
+   switch(dwMoveMethod)
+   {
+     case FILE_CURRENT:
+       NtQueryInformationFile(hFile,
+                              &IoStatusBlock,
+                              &FilePosition,
+                              sizeof(FILE_POSITION_INFORMATION),
+                              FilePositionInformation);
+       FilePosition.CurrentByteOffset.QuadPart += liDistanceToMove.QuadPart;
+       break;
+     case FILE_END:
+       NtQueryInformationFile(hFile,
+                               &IoStatusBlock,
+                               &FileStandard,
+                               sizeof(FILE_STANDARD_INFORMATION),
+                               FileStandardInformation);
+        FilePosition.CurrentByteOffset.QuadPart =
+                  FileStandard.EndOfFile.QuadPart + liDistanceToMove.QuadPart;
+       break;
+     case FILE_BEGIN:
+        FilePosition.CurrentByteOffset.QuadPart = liDistanceToMove.QuadPart;
+       break;
+     default:
+        SetLastError(ERROR_INVALID_PARAMETER);
+       return FALSE;
+   }
 
-       
+   if(FilePosition.CurrentByteOffset.QuadPart < 0)
+   {
+     SetLastError(ERROR_NEGATIVE_SEEK);
+     return FALSE;
+   }
 
-       ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
-       ObjectAttributes.RootDirectory = NULL;
-       ObjectAttributes.ObjectName = &FileNameString;
-       ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
-       ObjectAttributes.SecurityDescriptor = NULL;
-       ObjectAttributes.SecurityQualityOfService = NULL;
+   errCode = NtSetInformationFile(hFile,
+                                 &IoStatusBlock,
+                                 &FilePosition,
+                                 sizeof(FILE_POSITION_INFORMATION),
+                                 FilePositionInformation);
+   if (!NT_SUCCESS(errCode))
+     {
+       SetLastErrorByStatus(errCode);
+       return FALSE;
+     }
 
+   if (lpNewFilePointer)
+     {
+       *lpNewFilePointer = FilePosition.CurrentByteOffset;
+     }
+   return TRUE;
+}
 
 
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetFileType(HANDLE hFile)
+{
+  FILE_FS_DEVICE_INFORMATION DeviceInfo;
+  IO_STATUS_BLOCK StatusBlock;
+  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;
+    }
+
+  /* Check for console handle */
+  if (IsConsoleHandle(hFile))
+    {
+      if (VerifyConsoleIoHandle(hFile))
+       return FILE_TYPE_CHAR;
+    }
+
+  Status = NtQueryVolumeInformationFile(hFile,
+                                       &StatusBlock,
+                                       &DeviceInfo,
+                                       sizeof(FILE_FS_DEVICE_INFORMATION),
+                                       FileFsDeviceInformation);
+  if (!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return FILE_TYPE_UNKNOWN;
+    }
+
+  switch (DeviceInfo.DeviceType)
+    {
+      case FILE_DEVICE_CD_ROM:
+      case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
+      case FILE_DEVICE_CONTROLLER:
+      case FILE_DEVICE_DATALINK:
+      case FILE_DEVICE_DFS:
+      case FILE_DEVICE_DISK:
+      case FILE_DEVICE_DISK_FILE_SYSTEM:
+      case FILE_DEVICE_VIRTUAL_DISK:
+       return FILE_TYPE_DISK;
+
+      case FILE_DEVICE_KEYBOARD:
+      case FILE_DEVICE_MOUSE:
+      case FILE_DEVICE_NULL:
+      case FILE_DEVICE_PARALLEL_PORT:
+      case FILE_DEVICE_PRINTER:
+      case FILE_DEVICE_SERIAL_PORT:
+      case FILE_DEVICE_SCREEN:
+      case FILE_DEVICE_SOUND:
+      case FILE_DEVICE_MODEM:
+       return FILE_TYPE_CHAR;
+
+      case FILE_DEVICE_NAMED_PIPE:
+       return FILE_TYPE_PIPE;
+    }
+
+  return FILE_TYPE_UNKNOWN;
+}
 
-       errCode = NtDeleteFile(&ObjectAttributes);
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
-       return TRUE;
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetFileSize(HANDLE hFile,
+           LPDWORD lpFileSizeHigh)
+{
+   NTSTATUS errCode;
+   FILE_STANDARD_INFORMATION FileStandard;
+   IO_STATUS_BLOCK IoStatusBlock;
+
+   errCode = NtQueryInformationFile(hFile,
+                                   &IoStatusBlock,
+                                   &FileStandard,
+                                   sizeof(FILE_STANDARD_INFORMATION),
+                                   FileStandardInformation);
+   if (!NT_SUCCESS(errCode))
+     {
+       SetLastErrorByStatus(errCode);
+       if ( lpFileSizeHigh == NULL )
+         {
+            return -1;
+         }
+       else
+         {
+            return 0;
+         }
+     }
+   if ( lpFileSizeHigh != NULL )
+     *lpFileSizeHigh = FileStandard.EndOfFile.u.HighPart;
+
+   return FileStandard.EndOfFile.u.LowPart;
 }
 
-WINBOOL 
+
+/*
+ * @implemented
+ */
+BOOL
 STDCALL
-FlushFileBuffers(
-       HANDLE hFile    
-       )
+GetFileSizeEx(
+    HANDLE hFile,
+    PLARGE_INTEGER lpFileSize
+    )
 {
-       NTSTATUS errCode;
-       IO_STATUS_BLOCK IoStatusBlock;
+   NTSTATUS errCode;
+   FILE_STANDARD_INFORMATION FileStandard;
+   IO_STATUS_BLOCK IoStatusBlock;
+
+   errCode = NtQueryInformationFile(hFile,
+                                   &IoStatusBlock,
+                                   &FileStandard,
+                                   sizeof(FILE_STANDARD_INFORMATION),
+                                   FileStandardInformation);
+   if (!NT_SUCCESS(errCode))
+     {
+       SetLastErrorByStatus(errCode);
+       return FALSE;
+     }
+   if (lpFileSize)
+     *lpFileSize = FileStandard.EndOfFile;
 
-       errCode = NtFlushBuffersFile(
-               hFile,
-               &IoStatusBlock
-       );
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
-       return TRUE;
+   return TRUE;
 }
 
 
-DWORD
-STDCALL
-SetFilePointer(
-              HANDLE hFile,
-              LONG lDistanceToMove,
-              PLONG lpDistanceToMoveHigh,
-              DWORD dwMoveMethod
-              )
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetCompressedFileSizeA(LPCSTR lpFileName,
+                      LPDWORD lpFileSizeHigh)
 {
-       FILE_POSITION_INFORMATION FilePosition;
-       FILE_END_OF_FILE_INFORMATION FileEndOfFile;
-       NTSTATUS errCode;
-       IO_STATUS_BLOCK IoStatusBlock;
-       if ( dwMoveMethod == FILE_CURRENT ) {
-               NtQueryInformationFile(hFile,&IoStatusBlock,&FilePosition, sizeof(FILE_POSITION_INFORMATION),FilePositionInformation);
-               SET_LARGE_INTEGER_LOW_PART(FilePosition.CurrentByteOffset,
-                  GET_LARGE_INTEGER_LOW_PART(FilePosition.CurrentByteOffset) + 
-                  lDistanceToMove);
-               if ( lpDistanceToMoveHigh != NULL ) {
-                       SET_LARGE_INTEGER_HIGH_PART(FilePosition.CurrentByteOffset,
-                          GET_LARGE_INTEGER_HIGH_PART(FilePosition.CurrentByteOffset) +
-                          *lpDistanceToMoveHigh);
-                }
-       }
-       else if ( dwMoveMethod == FILE_END ) {
-               NtQueryInformationFile(hFile,&IoStatusBlock,&FileEndOfFile, sizeof(FILE_END_OF_FILE_INFORMATION),FileEndOfFileInformation);
-               SET_LARGE_INTEGER_LOW_PART(FilePosition.CurrentByteOffset,
-                  GET_LARGE_INTEGER_LOW_PART(FileEndOfFile.EndOfFile) - 
-                  lDistanceToMove);
-               if ( lpDistanceToMoveHigh != NULL ) {
-                       SET_LARGE_INTEGER_HIGH_PART(FilePosition.CurrentByteOffset,
-                          GET_LARGE_INTEGER_HIGH_PART(FileEndOfFile.EndOfFile) - 
-                          *lpDistanceToMoveHigh);
-               } else {
-                       SET_LARGE_INTEGER_HIGH_PART(FilePosition.CurrentByteOffset,
-                          GET_LARGE_INTEGER_HIGH_PART(FileEndOfFile.EndOfFile));
-                }
-       }
-       else if ( dwMoveMethod == FILE_CURRENT ) {
-               SET_LARGE_INTEGER_LOW_PART(FilePosition.CurrentByteOffset,
-                  lDistanceToMove);
-               if ( lpDistanceToMoveHigh != NULL ) {
-                       SET_LARGE_INTEGER_HIGH_PART(FilePosition.CurrentByteOffset,
-                          *lpDistanceToMoveHigh);
-               } else {
-                       SET_LARGE_INTEGER_HIGH_PART(FilePosition.CurrentByteOffset,
-                          0);
-                }
-       }
+   PWCHAR FileNameW;
 
-       errCode = NtSetInformationFile(hFile,&IoStatusBlock,&FilePosition, sizeof(FILE_POSITION_INFORMATION),FilePositionInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return -1;
-       }
-       
-       if ( lpDistanceToMoveHigh != NULL ) {
-               *lpDistanceToMoveHigh = GET_LARGE_INTEGER_HIGH_PART(FilePosition.CurrentByteOffset);
-        }
-       return GET_LARGE_INTEGER_LOW_PART(FilePosition.CurrentByteOffset);
+   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+      return INVALID_FILE_SIZE;
+
+   return GetCompressedFileSizeW(FileNameW, lpFileSizeHigh);
 }
 
-DWORD 
-STDCALL
-GetFileType(
-           HANDLE hFile        
-   )
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetCompressedFileSizeW(LPCWSTR lpFileName,
+                      LPDWORD lpFileSizeHigh)
 {
-       return FILE_TYPE_UNKNOWN;
+   FILE_COMPRESSION_INFORMATION FileCompression;
+   NTSTATUS errCode;
+   IO_STATUS_BLOCK IoStatusBlock;
+   HANDLE hFile;
+
+   hFile = CreateFileW(lpFileName,
+                      GENERIC_READ,
+                      FILE_SHARE_READ,
+                      NULL,
+                      OPEN_EXISTING,
+                      FILE_ATTRIBUTE_NORMAL,
+                      NULL);
+
+   if (hFile == INVALID_HANDLE_VALUE)
+      return INVALID_FILE_SIZE;
+
+   errCode = NtQueryInformationFile(hFile,
+                                   &IoStatusBlock,
+                                   &FileCompression,
+                                   sizeof(FILE_COMPRESSION_INFORMATION),
+                                   FileCompressionInformation);
+
+   CloseHandle(hFile);
+
+   if (!NT_SUCCESS(errCode))
+     {
+       SetLastErrorByStatus(errCode);
+       return INVALID_FILE_SIZE;
+     }
+
+   if(lpFileSizeHigh)
+    *lpFileSizeHigh = FileCompression.CompressedFileSize.u.HighPart;
+
+   SetLastError(NO_ERROR);
+   return FileCompression.CompressedFileSize.u.LowPart;
 }
 
 
-DWORD 
-STDCALL
-GetFileSize(
-       HANDLE hFile,   
-       LPDWORD lpFileSizeHigh  
-   )
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetFileInformationByHandle(HANDLE hFile,
+                          LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
 {
-       NTSTATUS errCode;
-       FILE_STANDARD_INFORMATION FileStandard;
-       IO_STATUS_BLOCK IoStatusBlock;
+   struct
+   {
+        FILE_FS_VOLUME_INFORMATION FileFsVolume;
+        WCHAR Name[255];
+   }
+   FileFsVolume;
 
+   FILE_BASIC_INFORMATION FileBasic;
+   FILE_INTERNAL_INFORMATION FileInternal;
+   FILE_STANDARD_INFORMATION FileStandard;
+   NTSTATUS errCode;
+   IO_STATUS_BLOCK IoStatusBlock;
 
-       errCode = NtQueryInformationFile(hFile,
-               &IoStatusBlock,&FileStandard, sizeof(FILE_STANDARD_INFORMATION),
-               FileStandardInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               CloseHandle(hFile);
-               SetLastError(RtlNtStatusToDosError(errCode));
-               if ( lpFileSizeHigh == NULL ) {
-                       return -1;
-               }
-               else
-                       return 0;
-       }
-       if ( lpFileSizeHigh != NULL )
-               *lpFileSizeHigh = GET_LARGE_INTEGER_HIGH_PART(FileStandard.AllocationSize);
+   if(IsConsoleHandle(hFile))
+   {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
+   }
+
+   errCode = NtQueryInformationFile(hFile,
+                                   &IoStatusBlock,
+                                   &FileBasic,
+                                   sizeof(FILE_BASIC_INFORMATION),
+                                   FileBasicInformation);
+   if (!NT_SUCCESS(errCode))
+     {
+       SetLastErrorByStatus(errCode);
+       return FALSE;
+     }
 
-       CloseHandle(hFile);
-       return GET_LARGE_INTEGER_LOW_PART(FileStandard.AllocationSize); 
+   lpFileInformation->dwFileAttributes = (DWORD)FileBasic.FileAttributes;
+
+   lpFileInformation->ftCreationTime.dwHighDateTime = FileBasic.CreationTime.u.HighPart;
+   lpFileInformation->ftCreationTime.dwLowDateTime = FileBasic.CreationTime.u.LowPart;
+
+   lpFileInformation->ftLastAccessTime.dwHighDateTime = FileBasic.LastAccessTime.u.HighPart;
+   lpFileInformation->ftLastAccessTime.dwLowDateTime = FileBasic.LastAccessTime.u.LowPart;
+
+   lpFileInformation->ftLastWriteTime.dwHighDateTime = FileBasic.LastWriteTime.u.HighPart;
+   lpFileInformation->ftLastWriteTime.dwLowDateTime = FileBasic.LastWriteTime.u.LowPart;
+
+   errCode = NtQueryInformationFile(hFile,
+                                   &IoStatusBlock,
+                                   &FileInternal,
+                                   sizeof(FILE_INTERNAL_INFORMATION),
+                                   FileInternalInformation);
+   if (!NT_SUCCESS(errCode))
+     {
+       SetLastErrorByStatus(errCode);
+       return FALSE;
+     }
+
+   lpFileInformation->nFileIndexHigh = FileInternal.IndexNumber.u.HighPart;
+   lpFileInformation->nFileIndexLow = FileInternal.IndexNumber.u.LowPart;
+
+   errCode = NtQueryVolumeInformationFile(hFile,
+                                         &IoStatusBlock,
+                                         &FileFsVolume,
+                                         sizeof(FileFsVolume),
+                                         FileFsVolumeInformation);
+   if (!NT_SUCCESS(errCode))
+     {
+       SetLastErrorByStatus(errCode);
+       return FALSE;
+     }
+
+   lpFileInformation->dwVolumeSerialNumber = FileFsVolume.FileFsVolume.VolumeSerialNumber;
+
+   errCode = NtQueryInformationFile(hFile,
+                                   &IoStatusBlock,
+                                   &FileStandard,
+                                   sizeof(FILE_STANDARD_INFORMATION),
+                                   FileStandardInformation);
+   if (!NT_SUCCESS(errCode))
+     {
+       SetLastErrorByStatus(errCode);
+       return FALSE;
+     }
+
+   lpFileInformation->nNumberOfLinks = FileStandard.NumberOfLinks;
+   lpFileInformation->nFileSizeHigh = FileStandard.EndOfFile.u.HighPart;
+   lpFileInformation->nFileSizeLow = FileStandard.EndOfFile.u.LowPart;
+
+   return TRUE;
 }
 
-DWORD
-STDCALL
-GetCompressedFileSizeA(
-    LPCSTR lpFileName,
-    LPDWORD lpFileSizeHigh
-    )
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetFileAttributesExW(LPCWSTR lpFileName,
+                    GET_FILEEX_INFO_LEVELS fInfoLevelId,
+                    LPVOID lpFileInformation)
 {
-       WCHAR FileNameW[MAX_PATH];
-       ULONG i;
-       i = 0;
-       while ((*lpFileName)!=0 && i < MAX_PATH)
-       {
-               FileNameW[i] = *lpFileName;
-               lpFileName++;
-               i++;
-       }
-       FileNameW[i] = 0;
-
-
-       return GetCompressedFileSizeW(FileNameW,lpFileSizeHigh);
-       
+  FILE_NETWORK_OPEN_INFORMATION FileInformation;
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  IO_STATUS_BLOCK IoStatusBlock;
+  UNICODE_STRING FileName;
+  HANDLE FileHandle;
+  NTSTATUS Status;
+  WIN32_FILE_ATTRIBUTE_DATA* FileAttributeData;
+
+  DPRINT("GetFileAttributesExW(%S) called\n", lpFileName);
+
+
+  if (fInfoLevelId != GetFileExInfoStandard || lpFileInformation == NULL)
+  {
+     SetLastError(ERROR_INVALID_PARAMETER);
+     return FALSE;
+  }
+
+  /* Validate and translate the filename */
+  if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName,
+                                    &FileName,
+                                    NULL,
+                                    NULL))
+    {
+      DPRINT1 ("Invalid path\n");
+      SetLastError (ERROR_BAD_PATHNAME);
+      return FALSE;
+    }
+
+  /* build the object attributes */
+  InitializeObjectAttributes (&ObjectAttributes,
+                             &FileName,
+                             OBJ_CASE_INSENSITIVE,
+                             NULL,
+                             NULL);
+
+  /* Open the file */
+
+
+  Status = NtOpenFile (&FileHandle,
+                      SYNCHRONIZE | GENERIC_ALL,
+                      &ObjectAttributes,
+                      &IoStatusBlock,
+                      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                      FILE_SYNCHRONOUS_IO_NONALERT);
+
+
+
+
+  RtlFreeUnicodeString (&FileName);
+  if (!NT_SUCCESS (Status))
+    {
+      DPRINT ("NtOpenFile() failed  %x (Status %lx)\n", &ObjectAttributes, Status);
+      SetLastErrorByStatus (Status);
+      return FALSE;
+    }
+
+  /* Get file attributes */
+  Status = NtQueryInformationFile (FileHandle,
+                                  &IoStatusBlock,
+                                  &FileInformation,
+                                  sizeof(FILE_NETWORK_OPEN_INFORMATION),
+                                  FileNetworkOpenInformation);
+  NtClose (FileHandle);
+
+  if (!NT_SUCCESS (Status))
+    {
+      DPRINT1 ("NtQueryInformationFile() failed (Status %lx)\n", Status);
+      SetLastErrorByStatus (Status);
+      return FALSE;
+    }
+
+  FileAttributeData = (WIN32_FILE_ATTRIBUTE_DATA*)lpFileInformation;
+  FileAttributeData->dwFileAttributes = FileInformation.FileAttributes;
+  FileAttributeData->ftCreationTime.dwLowDateTime = FileInformation.CreationTime.u.LowPart;
+  FileAttributeData->ftCreationTime.dwHighDateTime = FileInformation.CreationTime.u.HighPart;
+  FileAttributeData->ftLastAccessTime.dwLowDateTime = FileInformation.LastAccessTime.u.LowPart;
+  FileAttributeData->ftLastAccessTime.dwHighDateTime = FileInformation.LastAccessTime.u.HighPart;
+  FileAttributeData->ftLastWriteTime.dwLowDateTime = FileInformation.LastWriteTime.u.LowPart;
+  FileAttributeData->ftLastWriteTime.dwHighDateTime = FileInformation.LastWriteTime.u.HighPart;
+  FileAttributeData->nFileSizeLow = FileInformation.EndOfFile.u.LowPart;
+  FileAttributeData->nFileSizeHigh = FileInformation.EndOfFile.u.HighPart;
+
+  return TRUE;
 }
 
-DWORD
-STDCALL
-GetCompressedFileSizeW(
-    LPCWSTR lpFileName,
-    LPDWORD lpFileSizeHigh
-    )
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetFileAttributesExA(LPCSTR lpFileName,
+                    GET_FILEEX_INFO_LEVELS fInfoLevelId,
+                    LPVOID lpFileInformation)
 {
-       FILE_COMPRESSION_INFORMATION FileCompression;
-       NTSTATUS errCode;
-       IO_STATUS_BLOCK IoStatusBlock;
-       HANDLE hFile;
-
-       hFile = CreateFileW(
-               lpFileName,     
-               GENERIC_READ,   
-               FILE_SHARE_READ,        
-               NULL,   
-               OPEN_EXISTING,  
-               FILE_ATTRIBUTE_NORMAL,  
-               NULL 
-       );
-
-       errCode = NtQueryInformationFile(hFile,
-               &IoStatusBlock,&FileCompression, sizeof(FILE_COMPRESSION_INFORMATION),
-               FileCompressionInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               CloseHandle(hFile);
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return 0;
-       }
-       CloseHandle(hFile);
-       return 0;
+   PWCHAR FileNameW;
 
+   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+      return FALSE;
+
+   return GetFileAttributesExW(FileNameW, fInfoLevelId, lpFileInformation);
 }
 
 
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetFileAttributesA(LPCSTR lpFileName)
+{
+   WIN32_FILE_ATTRIBUTE_DATA FileAttributeData;
+   PWSTR FileNameW;
+       BOOL ret;
 
-WINBOOL
-STDCALL
-GetFileInformationByHandle(
-                          HANDLE hFile,
-                          LPBY_HANDLE_FILE_INFORMATION lpFileInformation
-                          )
+   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+      return INVALID_FILE_ATTRIBUTES;
+
+   ret = GetFileAttributesExW(FileNameW, GetFileExInfoStandard, &FileAttributeData);
+
+   return ret ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES;
+}
+
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetFileAttributesW(LPCWSTR lpFileName)
 {
-       FILE_DIRECTORY_INFORMATION FileDirectory;
-       FILE_INTERNAL_INFORMATION FileInternal;
-       FILE_FS_VOLUME_INFORMATION FileFsVolume;
-       FILE_STANDARD_INFORMATION FileStandard;
+  WIN32_FILE_ATTRIBUTE_DATA FileAttributeData;
+  BOOL Result;
 
-       NTSTATUS errCode;
-       IO_STATUS_BLOCK IoStatusBlock;
-       errCode = NtQueryInformationFile(hFile,&IoStatusBlock,&FileDirectory, sizeof(FILE_DIRECTORY_INFORMATION),FileDirectoryInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
-       lpFileInformation->dwFileAttributes = (DWORD)FileDirectory.FileAttributes;
-       memcpy(&lpFileInformation->ftCreationTime,&FileDirectory.CreationTime,sizeof(LARGE_INTEGER));
-       memcpy(&lpFileInformation->ftLastAccessTime,&FileDirectory.LastAccessTime,sizeof(LARGE_INTEGER));
-       memcpy(&lpFileInformation->ftLastWriteTime, &FileDirectory.LastWriteTime,sizeof(LARGE_INTEGER)); 
-       lpFileInformation->nFileSizeHigh = GET_LARGE_INTEGER_HIGH_PART(FileDirectory.AllocationSize); 
-       lpFileInformation->nFileSizeLow = GET_LARGE_INTEGER_LOW_PART(FileDirectory.AllocationSize); 
-        
+  DPRINT ("GetFileAttributeW(%S) called\n", lpFileName);
+
+  Result = GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &FileAttributeData);
+
+  return Result ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetFileAttributesByHandle(IN HANDLE hFile,
+                          OUT LPDWORD dwFileAttributes,
+                          IN DWORD dwFlags)
+{
+    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,
+                                    sizeof(FileBasic),
+                                    FileBasicInformation);
+    if (NT_SUCCESS(Status))
+    {
+        *dwFileAttributes = FileBasic.FileAttributes;
+        return TRUE;
+    }
+    
+    SetLastErrorByStatus(Status);
+    return FALSE;
+}
 
-       errCode = NtQueryInformationFile(hFile,&IoStatusBlock,&FileInternal, sizeof(FILE_INTERNAL_INFORMATION),FileInternalInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
-       lpFileInformation->nFileIndexHigh = GET_LARGE_INTEGER_HIGH_PART(FileInternal.IndexNumber);
-       lpFileInformation->nFileIndexLow = GET_LARGE_INTEGER_LOW_PART(FileInternal.IndexNumber);
 
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetFileAttributesByHandle(IN HANDLE hFile,
+                          IN DWORD dwFileAttributes,
+                          IN DWORD dwFlags)
+{
+    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,
+                                    sizeof(FileBasic),
+                                    FileBasicInformation);
+    if (NT_SUCCESS(Status))
+    {
+        FileBasic.FileAttributes = dwFileAttributes;
+        
+        Status = NtSetInformationFile(hFile,
+                                      &IoStatusBlock,
+                                      &FileBasic,
+                                      sizeof(FileBasic),
+                                      FileBasicInformation);
+    }
+
+    if (!NT_SUCCESS(Status))
+    {
+        SetLastErrorByStatus(Status);
+        return FALSE;
+    }
+    
+    return TRUE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetFileAttributesA(
+   LPCSTR lpFileName,
+       DWORD dwFileAttributes)
+{
+   PWCHAR FileNameW;
+
+   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+      return FALSE;
+
+   return SetFileAttributesW(FileNameW, dwFileAttributes);
+}
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetFileAttributesW(LPCWSTR lpFileName,
+                  DWORD dwFileAttributes)
+{
+  FILE_BASIC_INFORMATION FileInformation;
+  OBJECT_ATTRIBUTES ObjectAttributes;
+  IO_STATUS_BLOCK IoStatusBlock;
+  UNICODE_STRING FileName;
+  HANDLE FileHandle;
+  NTSTATUS Status;
+
+  DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName, dwFileAttributes);
+
+  /* Validate and translate the filename */
+  if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName,
+                                    &FileName,
+                                    NULL,
+                                    NULL))
+    {
+      DPRINT ("Invalid path\n");
+      SetLastError (ERROR_BAD_PATHNAME);
+      return FALSE;
+    }
+  DPRINT ("FileName: \'%wZ\'\n", &FileName);
+
+  /* build the object attributes */
+  InitializeObjectAttributes (&ObjectAttributes,
+                             &FileName,
+                             OBJ_CASE_INSENSITIVE,
+                             NULL,
+                             NULL);
+
+  /* Open the file */
+  Status = NtOpenFile (&FileHandle,
+                      SYNCHRONIZE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
+                      &ObjectAttributes,
+                      &IoStatusBlock,
+                      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                      FILE_SYNCHRONOUS_IO_NONALERT);
+  RtlFreeUnicodeString (&FileName);
+  if (!NT_SUCCESS (Status))
+    {
+      DPRINT ("NtOpenFile() failed (Status %lx)\n", Status);
+      SetLastErrorByStatus (Status);
+      return FALSE;
+    }
+
+  Status = NtQueryInformationFile(FileHandle,
+                                 &IoStatusBlock,
+                                 &FileInformation,
+                                 sizeof(FILE_BASIC_INFORMATION),
+                                 FileBasicInformation);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status);
+      NtClose (FileHandle);
+      SetLastErrorByStatus (Status);
+      return FALSE;
+    }
+
+  FileInformation.FileAttributes = dwFileAttributes;
+  Status = NtSetInformationFile(FileHandle,
+                               &IoStatusBlock,
+                               &FileInformation,
+                               sizeof(FILE_BASIC_INFORMATION),
+                               FileBasicInformation);
+  NtClose (FileHandle);
+  if (!NT_SUCCESS(Status))
+    {
+      DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status);
+      SetLastErrorByStatus (Status);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+
+
+
+/***********************************************************************
+ *           GetTempFileNameA   (KERNEL32.@)
+ */
+UINT WINAPI GetTempFileNameA( LPCSTR path, LPCSTR prefix, UINT unique, LPSTR buffer)
+{
+   WCHAR BufferW[MAX_PATH];
+   PWCHAR PathW;
+   WCHAR PrefixW[3+1];
+   UINT ret;
+
+   if (!(PathW = FilenameA2W(path, FALSE)))
+      return 0;
+
+   if (prefix)
+      FilenameA2W_N(PrefixW, 3+1, prefix, -1);
+
+   ret = GetTempFileNameW(PathW, prefix ? PrefixW : NULL, unique, BufferW);
+
+   if (ret)
+      FilenameW2A_N(buffer, MAX_PATH, BufferW, -1);
+
+   return ret;
+}
+
+/***********************************************************************
+ *           GetTempFileNameW   (KERNEL32.@)
+ */
+UINT WINAPI GetTempFileNameW( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR buffer )
+{
+    static const WCHAR formatW[] = L"%x.tmp";
+
+    int i;
+    LPWSTR p;
+
+    if ( !path || !prefix || !buffer )
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return 0;
+    }
+
+    wcscpy( buffer, path );
+    p = buffer + wcslen(buffer);
+
+    /* add a \, if there isn't one  */
+    if ((p == buffer) || (p[-1] != '\\')) *p++ = '\\';
+
+    for (i = 3; (i > 0) && (*prefix); i--) *p++ = *prefix++;
+
+    unique &= 0xffff;
+
+    if (unique) swprintf( p, formatW, unique );
+    else
+    {
+        /* get a "random" unique number and try to create the file */
+        HANDLE handle;
+        UINT num = GetTickCount() & 0xffff;
+
+        if (!num) num = 1;
+        unique = num;
+        do
+        {
+            swprintf( p, formatW, unique );
+            handle = CreateFileW( buffer, GENERIC_WRITE, 0, NULL,
+                                  CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
+            if (handle != INVALID_HANDLE_VALUE)
+            {  /* We created it */
+                DPRINT("created %S\n", buffer);
+                CloseHandle( handle );
+                break;
+            }
+            if (GetLastError() != ERROR_FILE_EXISTS &&
+                GetLastError() != ERROR_SHARING_VIOLATION)
+                break;  /* No need to go on */
+            if (!(++unique & 0xffff)) unique = 1;
+        } while (unique != num);
+    }
+
+    DPRINT("returning %S\n", buffer);
+    return unique;
+}
+
+
+
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetFileTime(HANDLE hFile,
+           LPFILETIME lpCreationTime,
+           LPFILETIME lpLastAccessTime,
+           LPFILETIME lpLastWriteTime)
+{
+   IO_STATUS_BLOCK IoStatusBlock;
+   FILE_BASIC_INFORMATION FileBasic;
+   NTSTATUS Status;
+
+   if(IsConsoleHandle(hFile))
+   {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
+   }
+
+   Status = NtQueryInformationFile(hFile,
+                                  &IoStatusBlock,
+                                  &FileBasic,
+                                  sizeof(FILE_BASIC_INFORMATION),
+                                  FileBasicInformation);
+   if (!NT_SUCCESS(Status))
+     {
+       SetLastErrorByStatus(Status);
+       return FALSE;
+     }
+
+   if (lpCreationTime)
+     memcpy(lpCreationTime, &FileBasic.CreationTime, sizeof(FILETIME));
+   if (lpLastAccessTime)
+     memcpy(lpLastAccessTime, &FileBasic.LastAccessTime, sizeof(FILETIME));
+   if (lpLastWriteTime)
+     memcpy(lpLastWriteTime, &FileBasic.LastWriteTime, sizeof(FILETIME));
+
+   return TRUE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetFileTime(HANDLE hFile,
+           CONST FILETIME *lpCreationTime,
+           CONST FILETIME *lpLastAccessTime,
+           CONST FILETIME *lpLastWriteTime)
+{
+   FILE_BASIC_INFORMATION FileBasic;
+   IO_STATUS_BLOCK IoStatusBlock;
+   NTSTATUS Status;
+
+   if(IsConsoleHandle(hFile))
+   {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
+   }
+
+   Status = NtQueryInformationFile(hFile,
+                                  &IoStatusBlock,
+                                  &FileBasic,
+                                  sizeof(FILE_BASIC_INFORMATION),
+                                  FileBasicInformation);
+   if (!NT_SUCCESS(Status))
+     {
+       SetLastErrorByStatus(Status);
+       return FALSE;
+     }
+
+   if (lpCreationTime)
+     memcpy(&FileBasic.CreationTime, lpCreationTime, sizeof(FILETIME));
+   if (lpLastAccessTime)
+     memcpy(&FileBasic.LastAccessTime, lpLastAccessTime, sizeof(FILETIME));
+   if (lpLastWriteTime)
+     memcpy(&FileBasic.LastWriteTime, lpLastWriteTime, sizeof(FILETIME));
+
+   // should i initialize changetime ???
+
+   Status = NtSetInformationFile(hFile,
+                                &IoStatusBlock,
+                                &FileBasic,
+                                sizeof(FILE_BASIC_INFORMATION),
+                                FileBasicInformation);
+   if (!NT_SUCCESS(Status))
+     {
+       SetLastErrorByStatus(Status);
+       return FALSE;
+     }
+
+   return TRUE;
+}
 
-       errCode = NtQueryVolumeInformationFile(hFile,&IoStatusBlock,&FileFsVolume, sizeof(FILE_FS_VOLUME_INFORMATION),FileFsVolumeInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
+
+/*
+ * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
+ *
+ * @implemented
+ */
+BOOL STDCALL
+SetEndOfFile(HANDLE hFile)
+{
+       IO_STATUS_BLOCK  IoStatusBlock;
+       FILE_END_OF_FILE_INFORMATION    EndOfFileInfo;
+       FILE_ALLOCATION_INFORMATION             FileAllocationInfo;
+       FILE_POSITION_INFORMATION                FilePosInfo;
+       NTSTATUS Status;
+
+       if(IsConsoleHandle(hFile))
+       {
+               SetLastError(ERROR_INVALID_HANDLE);
                return FALSE;
        }
-       lpFileInformation->dwVolumeSerialNumber = FileFsVolume.VolumeSerialNumber;
 
+       //get current position
+       Status = NtQueryInformationFile(
+                                       hFile,
+                                       &IoStatusBlock,
+                                       &FilePosInfo,
+                                       sizeof(FILE_POSITION_INFORMATION),
+                                       FilePositionInformation
+                                       );
+
+       if (!NT_SUCCESS(Status)){
+               SetLastErrorByStatus(Status);
+               return FALSE;
+       }
 
-       errCode = NtQueryInformationFile(hFile,&IoStatusBlock,&FileStandard, sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               CloseHandle(hFile);
-               SetLastError(RtlNtStatusToDosError(errCode));
+       EndOfFileInfo.EndOfFile.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
+
+       /*
+       NOTE:
+       This call is not supposed to free up any space after the eof marker
+       if the file gets truncated. We have to deallocate the space explicitly afterwards.
+       But...most file systems dispatch both FileEndOfFileInformation
+       and FileAllocationInformation as they were the same     command.
+
+       */
+       Status = NtSetInformationFile(
+                                               hFile,
+                                               &IoStatusBlock,  //out
+                                               &EndOfFileInfo,
+                                               sizeof(FILE_END_OF_FILE_INFORMATION),
+                                               FileEndOfFileInformation
+                                               );
+
+       if (!NT_SUCCESS(Status)){
+               SetLastErrorByStatus(Status);
                return FALSE;
        }
-       lpFileInformation->nNumberOfLinks = FileStandard.NumberOfLinks;
-       CloseHandle(hFile);
-       return TRUE;
-       
-}
 
+       FileAllocationInfo.AllocationSize.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
 
 
+       Status = NtSetInformationFile(
+                                               hFile,
+                                               &IoStatusBlock,  //out
+                                               &FileAllocationInfo,
+                                               sizeof(FILE_ALLOCATION_INFORMATION),
+                                               FileAllocationInformation
+                                               );
 
+       if (!NT_SUCCESS(Status)){
+               SetLastErrorByStatus(Status);
+               return FALSE;
+       }
 
+       return TRUE;
 
-DWORD
-STDCALL
-GetFileAttributesA(
-    LPCSTR lpFileName
-    )
-{
-       ULONG i;
-       WCHAR FileNameW[MAX_PATH];
-       i = 0;
-       while ((*lpFileName)!=0 && i < MAX_PATH)
-       {
-               FileNameW[i] = *lpFileName;
-               lpFileName++;
-               i++;
-       }
-       FileNameW[i] = 0;
-       return GetFileAttributesW(FileNameW);
 }
 
 
-DWORD
+/*
+ * @implemented
+ */
+BOOL
 STDCALL
-GetFileAttributesW(
-    LPCWSTR lpFileName
+SetFileValidData(
+    HANDLE hFile,
+    LONGLONG ValidDataLength
     )
 {
        IO_STATUS_BLOCK IoStatusBlock;
-       FILE_BASIC_INFORMATION FileBasic;
-       HANDLE hFile;
-       NTSTATUS errCode;
+       FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation;
+       NTSTATUS Status;
 
+       ValidDataLengthInformation.ValidDataLength.QuadPart = ValidDataLength;
 
-       hFile = CreateFileW(
-               lpFileName,     
-               GENERIC_READ,   
-               FILE_SHARE_READ,        
-               NULL,   
-               OPEN_EXISTING,  
-               FILE_ATTRIBUTE_NORMAL,  
-               NULL 
-       );
-
-       
-       errCode = NtQueryInformationFile(hFile,&IoStatusBlock,&FileBasic, sizeof(FILE_BASIC_INFORMATION),FileBasicInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               CloseHandle(hFile);
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return 0;
+       Status = NtSetInformationFile(
+                                               hFile,
+                                               &IoStatusBlock,  //out
+                                               &ValidDataLengthInformation,
+                                               sizeof(FILE_VALID_DATA_LENGTH_INFORMATION),
+                                               FileValidDataLengthInformation
+                                               );
+
+       if (!NT_SUCCESS(Status)){
+               SetLastErrorByStatus(Status);
+               return FALSE;
        }
-       CloseHandle(hFile);
-       return (DWORD)FileBasic.FileAttributes;
-               
+
+       return TRUE;
 }
 
 
 
-DWORD
-GetCurrentTime(VOID)
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+SetFileShortNameW(
+  HANDLE hFile,
+  LPCWSTR lpShortName)
 {
-       NTSTATUS errCode;
-       FILETIME CurrentTime;
-       errCode = NtQuerySystemTime (
-               (TIME *)&CurrentTime
-       );
-       return CurrentTime.dwLowDateTime;
+  NTSTATUS Status;
+  ULONG NeededSize;
+  UNICODE_STRING ShortName;
+  IO_STATUS_BLOCK IoStatusBlock;
+  PFILE_NAME_INFORMATION FileNameInformation;
+
+  if(IsConsoleHandle(hFile))
+  {
+    SetLastError(ERROR_INVALID_HANDLE);
+    return FALSE;
+  }
+
+  if(!lpShortName)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return FALSE;
+  }
+
+  RtlInitUnicodeString(&ShortName, lpShortName);
+
+  NeededSize = sizeof(FILE_NAME_INFORMATION) + ShortName.Length + sizeof(WCHAR);
+  if(!(FileNameInformation = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, NeededSize)))
+  {
+    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+    return FALSE;
+  }
+
+  FileNameInformation->FileNameLength = ShortName.Length;
+  RtlCopyMemory(FileNameInformation->FileName, ShortName.Buffer, ShortName.Length);
+
+  Status = NtSetInformationFile(hFile,
+                                &IoStatusBlock,         //out
+                                FileNameInformation,
+                                NeededSize,
+                                FileShortNameInformation);
+
+  RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInformation);
+  if(!NT_SUCCESS(Status))
+  {
+
+    SetLastErrorByStatus(Status);
+  }
+
+  return NT_SUCCESS(Status);
 }
 
-UINT
+
+/*
+ * @implemented
+ */
+BOOL
 STDCALL
-GetTempFileNameA(
-    LPCSTR lpPathName,
-    LPCSTR lpPrefixString,
-    UINT uUnique,
-    LPSTR lpTempFileName
+SetFileShortNameA(
+    HANDLE hFile,
+    LPCSTR lpShortName
     )
 {
-       HANDLE hFile;
-       UINT unique = uUnique;
-  
-       if (lpPathName == NULL)
-               return 0;
-
-       if (uUnique == 0)
-               uUnique = GetCurrentTime();
-  
-       wsprintfA(lpTempFileName,"%s\\%c%.3s%4.4x%s",
-         lpPathName,'~',lpPrefixString,uUnique,".tmp");
-  
-       if (unique)
-               return uUnique;
-  
-       while ((hFile = CreateFileA(lpTempFileName, GENERIC_WRITE, 0, NULL,
-                            CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
-                            0)) == INVALID_HANDLE_VALUE)
-       {
-               wsprintfA(lpTempFileName,"%s\\%c%.3s%4.4x%s",
-               lpPathName,'~',lpPrefixString,++uUnique,".tmp");
-       }
-
-       CloseHandle((HANDLE)hFile);
-       return uUnique;
+  PWCHAR ShortNameW;
+
+  if(IsConsoleHandle(hFile))
+  {
+    SetLastError(ERROR_INVALID_HANDLE);
+    return FALSE;
+  }
+
+  if(!lpShortName)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return FALSE;
+  }
+
+  if (!(ShortNameW = FilenameA2W(lpShortName, FALSE)))
+     return FALSE;
+
+  return SetFileShortNameW(hFile, ShortNameW);
 }
 
 
-UINT
+/*
+ * @implemented
+ */
+BOOL
 STDCALL
-GetTempFileNameW(
-    LPCWSTR lpPathName,
-    LPCWSTR lpPrefixString,
-    UINT uUnique,
-    LPWSTR lpTempFileName
+CheckNameLegalDOS8Dot3W(
+    LPCWSTR lpName,
+    LPSTR lpOemName OPTIONAL,
+    DWORD OemNameSize OPTIONAL,
+    PBOOL pbNameContainsSpaces OPTIONAL,
+    PBOOL pbNameLegal
     )
 {
-       HANDLE hFile;
-       UINT unique = uUnique;
-  
-       if (lpPathName == NULL)
-               return 0;
-
-       if (uUnique == 0)
-               uUnique = GetCurrentTime();
-  
-       wsprintfW(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
-         lpPathName,'~',lpPrefixString,uUnique,L".tmp");
-  
-       if (unique)
-               return uUnique;
-  
-       while ((hFile = CreateFileW(lpTempFileName, GENERIC_WRITE, 0, NULL,
-                            CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
-                            0)) == INVALID_HANDLE_VALUE)
-       {
-               wsprintfW(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
-               lpPathName,'~',lpPrefixString,++uUnique,L".tmp");
-       }
-
-       CloseHandle((HANDLE)hFile);
-       return uUnique;
-}
+    UNICODE_STRING Name;
+    ANSI_STRING AnsiName;
+
+    if(lpName == NULL ||
+       (lpOemName == NULL && OemNameSize != 0) ||
+       pbNameLegal == NULL)
+    {
+      SetLastError(ERROR_INVALID_PARAMETER);
+      return FALSE;
+    }
 
-WINBOOL
-STDCALL
-GetFileTime(
-           HANDLE hFile,
-           LPFILETIME lpCreationTime,
-           LPFILETIME lpLastAccessTime,
-           LPFILETIME lpLastWriteTime
-           )
-{
-       IO_STATUS_BLOCK IoStatusBlock;
-       FILE_BASIC_INFORMATION FileBasic;
-       NTSTATUS errCode;
-       
+    if(lpOemName != NULL)
+    {
+      AnsiName.Buffer = lpOemName;
+      AnsiName.MaximumLength = OemNameSize * sizeof(CHAR);
+      AnsiName.Length = 0;
+    }
 
-       
-       errCode = NtQueryInformationFile(hFile,&IoStatusBlock,&FileBasic, sizeof(FILE_BASIC_INFORMATION),FileBasicInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
-       memcpy(lpCreationTime,&FileBasic.CreationTime,sizeof(FILETIME));
-       memcpy(lpLastAccessTime,&FileBasic.LastAccessTime,sizeof(FILETIME));
-       memcpy(lpLastWriteTime,&FileBasic.LastWriteTime,sizeof(FILETIME));
-       return TRUE;
+    RtlInitUnicodeString(&Name, lpName);
+
+    *pbNameLegal = RtlIsNameLegalDOS8Dot3(&Name,
+                                          (lpOemName ? &AnsiName : NULL),
+                                          (BOOLEAN*)pbNameContainsSpaces);
+
+    return TRUE;
 }
 
-WINBOOL
+
+/*
+ * @implemented
+ */
+BOOL
 STDCALL
-SetFileTime(
-           HANDLE hFile,
-           CONST FILETIME *lpCreationTime,
-           CONST FILETIME *lpLastAccessTime,
-           CONST FILETIME *lpLastWriteTime
-           )
+CheckNameLegalDOS8Dot3A(
+    LPCSTR lpName,
+    LPSTR lpOemName OPTIONAL,
+    DWORD OemNameSize OPTIONAL,
+    PBOOL pbNameContainsSpaces OPTIONAL,
+    PBOOL pbNameLegal
+    )
 {
-       FILE_BASIC_INFORMATION FileBasic;
-       IO_STATUS_BLOCK IoStatusBlock;
-       NTSTATUS errCode;
-
+    UNICODE_STRING Name;
+    ANSI_STRING AnsiName, AnsiInputName;
+    NTSTATUS Status;
+
+    if(lpName == NULL ||
+       (lpOemName == NULL && OemNameSize != 0) ||
+       pbNameLegal == NULL)
+    {
+      SetLastError(ERROR_INVALID_PARAMETER);
+      return FALSE;
+    }
+
+    if(lpOemName != NULL)
+    {
+      AnsiName.Buffer = lpOemName;
+      AnsiName.MaximumLength = OemNameSize * sizeof(CHAR);
+      AnsiName.Length = 0;
+    }
+
+    RtlInitAnsiString(&AnsiInputName, (LPSTR)lpName);
+    if(bIsFileApiAnsi)
+      Status = RtlAnsiStringToUnicodeString(&Name, &AnsiInputName, TRUE);
+    else
+      Status = RtlOemStringToUnicodeString(&Name, &AnsiInputName, TRUE);
+
+    if(!NT_SUCCESS(Status))
+    {
+      SetLastErrorByStatus(Status);
+      return FALSE;
+    }
 
+    *pbNameLegal = RtlIsNameLegalDOS8Dot3(&Name,
+                                          (lpOemName ? &AnsiName : NULL),
+                                          (BOOLEAN*)pbNameContainsSpaces);
 
-       memcpy(&FileBasic.CreationTime,lpCreationTime,sizeof(FILETIME));
-       memcpy(&FileBasic.LastAccessTime,lpLastAccessTime,sizeof(FILETIME));
-       memcpy(&FileBasic.LastWriteTime,lpLastWriteTime,sizeof(FILETIME));
+    RtlFreeUnicodeString(&Name);
 
-       // shoud i initialize changetime ???
-       
-       errCode = NtSetInformationFile(hFile,&IoStatusBlock,&FileBasic, sizeof(FILE_BASIC_INFORMATION),FileBasicInformation);
-       if ( !NT_SUCCESS(errCode) ) {
-               SetLastError(RtlNtStatusToDosError(errCode));
-               return FALSE;
-       }
-       
-       return TRUE;
+    return TRUE;
 }
+
+/* EOF */