give GetFileAttributesExW more NtOpenFile right to prevent reactos crash if u using...
[reactos.git] / reactos / lib / kernel32 / file / file.c
index ec70fca..826ad71 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: file.c,v 1.38 2002/11/07 02:52:37 robd Exp $
+/* $Id$
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS system libraries
 
 /* INCLUDES *****************************************************************/
 
-#include <ddk/ntddk.h>
-#include <windows.h>
-#include <wchar.h>
-#include <string.h>
+#include <k32.h>
 
 #define NDEBUG
-#include <kernel32/kernel32.h>
-#include <kernel32/error.h>
-
-#define LPPROGRESS_ROUTINE void*
+#include "../include/debug.h"
 
 
 /* GLOBALS ******************************************************************/
 
-WINBOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem
-
+BOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem
 
 /* FUNCTIONS ****************************************************************/
 
-VOID STDCALL
+
+
+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;
+
+   if (bIsFileApiAnsi)
+        Status= RtlAnsiStringToUnicodeString( pstrW, &str, alloc );
+   else
+        Status= RtlOemStringToUnicodeString( pstrW, &str, alloc );
+
+    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.
+
+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
+   )
+{
+   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;
+
+
+      if (bIsFileApiAnsi)
+         RtlUnicodeStringToAnsiString(&str, SourceU, FALSE );
+      else
+         RtlUnicodeStringToOemString(&str, SourceU, FALSE );
+
+      ret = str.Length;  /* SUCCESS: length without terminating 0 */
+   }
+
+   return ret;
+}
+
+
+/*
+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 */
+   )
+{
+   UNICODE_STRING strW;
+
+   if (sourceLen < 0) sourceLen = wcslen(SourceW) + 1;
+
+   strW.Buffer = (PWCHAR)SourceW;
+   strW.MaximumLength = sourceLen * sizeof(WCHAR);
+   strW.Length = strW.MaximumLength - sizeof(WCHAR);
+
+   return FilenameU2A_FitOrFail(DestA, destLen, &strW);
+}
+
+
+/*
+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 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;
+
+    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;
+}
+
+
+/*
+ * @implemented
+ */
+VOID
+STDCALL
 SetFileApisToOEM(VOID)
 {
-   bIsFileApiAnsi = FALSE;
+    /* Set the correct Base Api */
+    Basep8BitStringToUnicodeString = (PRTL_CONVERT_STRING)RtlOemStringToUnicodeString;
+
+    /* FIXME: Old, deprecated way */
+    bIsFileApiAnsi = FALSE;
 }
 
 
-VOID STDCALL
+/*
+ * @implemented
+ */
+VOID
+STDCALL
 SetFileApisToANSI(VOID)
 {
-   bIsFileApiAnsi = TRUE;
+    /* Set the correct Base Api */
+    Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString;
+
+    /* FIXME: Old, deprecated way */
+    bIsFileApiAnsi = TRUE;
 }
 
 
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
 AreFileApisANSI(VOID)
 {
    return bIsFileApiAnsi;
 }
 
 
+/*
+ * @implemented
+ */
 HFILE STDCALL
 OpenFile(LPCSTR lpFileName,
         LPOFSTRUCT lpReOpenBuff,
@@ -75,6 +240,28 @@ OpenFile(LPCSTR lpFileName,
                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);
+       }
+
        RtlInitAnsiString (&FileName, (LPSTR)lpFileName);
 
        /* convert ansi (or oem) string to unicode */
@@ -85,10 +272,10 @@ OpenFile(LPCSTR lpFileName,
 
        Len = SearchPathW (NULL,
                           FileNameU.Buffer,
-                          NULL,
+                          NULL,
                           OFS_MAXPATHNAME,
                           PathNameW,
-                          &FilePart);
+                          &FilePart);
 
        RtlFreeUnicodeString(&FileNameU);
 
@@ -117,13 +304,6 @@ OpenFile(LPCSTR lpFileName,
                return (HFILE)INVALID_HANDLE_VALUE;
        }
 
-       ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
-       ObjectAttributes.RootDirectory = NULL;
-       ObjectAttributes.ObjectName = &FileNameString;
-       ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
-       ObjectAttributes.SecurityDescriptor = NULL;
-       ObjectAttributes.SecurityQualityOfService = NULL;
-
        // FILE_SHARE_READ
        // FILE_NO_INTERMEDIATE_BUFFERING
 
@@ -133,12 +313,19 @@ OpenFile(LPCSTR lpFileName,
                return (HFILE)NULL;
        }
 
+       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 = NtOpenFile (&FileHandle,
                              GENERIC_READ|SYNCHRONIZE,
                              &ObjectAttributes,
                              &IoStatusBlock,
                              FILE_SHARE_READ,
-                             FILE_NON_DIRECTORY_FILE);
+                             FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT);
 
        RtlFreeUnicodeString(&FileNameString);
 
@@ -154,7 +341,10 @@ OpenFile(LPCSTR lpFileName,
 }
 
 
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
 FlushFileBuffers(HANDLE hFile)
 {
    NTSTATUS errCode;
@@ -176,6 +366,9 @@ FlushFileBuffers(HANDLE hFile)
 }
 
 
+/*
+ * @implemented
+ */
 DWORD STDCALL
 SetFilePointer(HANDLE hFile,
               LONG lDistanceToMove,
@@ -183,14 +376,20 @@ SetFilePointer(HANDLE hFile,
               DWORD dwMoveMethod)
 {
    FILE_POSITION_INFORMATION FilePosition;
-   FILE_STANDARD_INFORMATION FileStandart;
+   FILE_STANDARD_INFORMATION FileStandard;
    NTSTATUS errCode;
    IO_STATUS_BLOCK IoStatusBlock;
    LARGE_INTEGER Distance;
-   
+
    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)
    {
@@ -205,30 +404,39 @@ SetFilePointer(HANDLE hFile,
       Distance.u.HighPart = -1;
    }
 
-   if (dwMoveMethod == FILE_CURRENT)
-     {
+   switch(dwMoveMethod)
+   {
+     case FILE_CURRENT:
        NtQueryInformationFile(hFile,
                               &IoStatusBlock,
                               &FilePosition,
                               sizeof(FILE_POSITION_INFORMATION),
                               FilePositionInformation);
        FilePosition.CurrentByteOffset.QuadPart += Distance.QuadPart;
-     }
-   else if (dwMoveMethod == FILE_END)
-     {
+       break;
+     case FILE_END:
        NtQueryInformationFile(hFile,
                                &IoStatusBlock,
-                               &FileStandart,
+                               &FileStandard,
                                sizeof(FILE_STANDARD_INFORMATION),
                                FileStandardInformation);
         FilePosition.CurrentByteOffset.QuadPart =
-                  FileStandart.EndOfFile.QuadPart + Distance.QuadPart;
-     }
-   else if ( dwMoveMethod == FILE_BEGIN )
-     {
+                  FileStandard.EndOfFile.QuadPart + Distance.QuadPart;
+       break;
+     case FILE_BEGIN:
         FilePosition.CurrentByteOffset.QuadPart = Distance.QuadPart;
-     }
-   
+       break;
+     default:
+        SetLastError(ERROR_INVALID_PARAMETER);
+       return -1;
+   }
+
+   if(FilePosition.CurrentByteOffset.QuadPart < 0)
+   {
+     SetLastError(ERROR_NEGATIVE_SEEK);
+     return -1;
+   }
+
    errCode = NtSetInformationFile(hFile,
                                  &IoStatusBlock,
                                  &FilePosition,
@@ -239,7 +447,7 @@ SetFilePointer(HANDLE hFile,
        SetLastErrorByStatus(errCode);
        return -1;
      }
-   
+
    if (lpDistanceToMoveHigh != NULL)
      {
         *lpDistanceToMoveHigh = FilePosition.CurrentByteOffset.u.HighPart;
@@ -248,81 +456,157 @@ SetFilePointer(HANDLE hFile,
 }
 
 
-DWORD STDCALL
-GetFileType(HANDLE hFile)
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+SetFilePointerEx(HANDLE hFile,
+                LARGE_INTEGER liDistanceToMove,
+                PLARGE_INTEGER lpNewFilePointer,
+                DWORD dwMoveMethod)
 {
-   FILE_FS_DEVICE_INFORMATION DeviceInfo;
-   IO_STATUS_BLOCK StatusBlock;
-   NTSTATUS Status;
-
-   /* get real handle */
-   switch ((ULONG)hFile)
-     {
-       case STD_INPUT_HANDLE:
-         hFile = NtCurrentPeb()->ProcessParameters->hStdInput;
-
-         break;
-
-       case STD_OUTPUT_HANDLE:
-         hFile = NtCurrentPeb()->ProcessParameters->hStdOutput;
+   FILE_POSITION_INFORMATION FilePosition;
+   FILE_STANDARD_INFORMATION FileStandard;
+   NTSTATUS errCode;
+   IO_STATUS_BLOCK IoStatusBlock;
 
-         break;
+   if(IsConsoleHandle(hFile))
+   {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
+   }
 
-       case STD_ERROR_HANDLE:
-         hFile = NtCurrentPeb()->ProcessParameters->hStdError;
+   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;
+   }
 
-         break;
-     }
+   if(FilePosition.CurrentByteOffset.QuadPart < 0)
+   {
+     SetLastError(ERROR_NEGATIVE_SEEK);
+     return FALSE;
+   }
 
-   /* check console handles */
-   if (IsConsoleHandle(hFile))
+   errCode = NtSetInformationFile(hFile,
+                                 &IoStatusBlock,
+                                 &FilePosition,
+                                 sizeof(FILE_POSITION_INFORMATION),
+                                 FilePositionInformation);
+   if (!NT_SUCCESS(errCode))
      {
-//     if (VerifyConsoleHandle(hFile))
-         return FILE_TYPE_CHAR;
+       SetLastErrorByStatus(errCode);
+       return FALSE;
      }
 
-   Status = NtQueryVolumeInformationFile(hFile,
-                                        &StatusBlock,
-                                        &DeviceInfo,
-                                        sizeof(FILE_FS_DEVICE_INFORMATION),
-                                        FileFsDeviceInformation);
-   if (!NT_SUCCESS(Status))
+   if (lpNewFilePointer)
      {
-       SetLastErrorByStatus(Status);
-       return FILE_TYPE_UNKNOWN;
+       *lpNewFilePointer = FilePosition.CurrentByteOffset;
      }
+   return TRUE;
+}
 
-   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;
+/*
+ * @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;
 }
 
 
+/*
+ * @implemented
+ */
 DWORD STDCALL
 GetFileSize(HANDLE hFile,
            LPDWORD lpFileSizeHigh)
@@ -355,36 +639,56 @@ GetFileSize(HANDLE hFile,
 }
 
 
-DWORD STDCALL
-GetCompressedFileSizeA(LPCSTR lpFileName,
-                      LPDWORD lpFileSizeHigh)
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+GetFileSizeEx(
+    HANDLE hFile,
+    PLARGE_INTEGER lpFileSize
+    )
 {
-   UNICODE_STRING FileNameU;
-   ANSI_STRING FileName;
-   DWORD Size;
+   NTSTATUS errCode;
+   FILE_STANDARD_INFORMATION FileStandard;
+   IO_STATUS_BLOCK IoStatusBlock;
 
-   RtlInitAnsiString(&FileName,
-                    (LPSTR)lpFileName);
+   errCode = NtQueryInformationFile(hFile,
+                                   &IoStatusBlock,
+                                   &FileStandard,
+                                   sizeof(FILE_STANDARD_INFORMATION),
+                                   FileStandardInformation);
+   if (!NT_SUCCESS(errCode))
+     {
+       SetLastErrorByStatus(errCode);
+       return FALSE;
+     }
+   if (lpFileSize)
+     *lpFileSize = FileStandard.EndOfFile;
 
-   /* convert ansi (or oem) string to unicode */
-   if (bIsFileApiAnsi)
-     RtlAnsiStringToUnicodeString(&FileNameU,
-                                 &FileName,
-                                 TRUE);
-   else
-     RtlOemStringToUnicodeString(&FileNameU,
-                                &FileName,
-                                TRUE);
+   return TRUE;
+}
 
-   Size = GetCompressedFileSizeW(FileNameU.Buffer,
-                                lpFileSizeHigh);
 
-   RtlFreeUnicodeString (&FileNameU);
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetCompressedFileSizeA(LPCSTR lpFileName,
+                      LPDWORD lpFileSizeHigh)
+{
+   PWCHAR FileNameW;
+
+   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+      return INVALID_FILE_SIZE;
 
-   return Size;
+   return GetCompressedFileSizeW(FileNameW, lpFileSizeHigh);
 }
 
 
+/*
+ * @implemented
+ */
 DWORD STDCALL
 GetCompressedFileSizeW(LPCWSTR lpFileName,
                       LPDWORD lpFileSizeHigh)
@@ -393,7 +697,7 @@ GetCompressedFileSizeW(LPCWSTR lpFileName,
    NTSTATUS errCode;
    IO_STATUS_BLOCK IoStatusBlock;
    HANDLE hFile;
-   
+
    hFile = CreateFileW(lpFileName,
                       GENERIC_READ,
                       FILE_SHARE_READ,
@@ -402,23 +706,35 @@ GetCompressedFileSizeW(LPCWSTR lpFileName,
                       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))
      {
-       CloseHandle(hFile);
        SetLastErrorByStatus(errCode);
-       return 0;
+       return INVALID_FILE_SIZE;
      }
-   CloseHandle(hFile);
-   return 0;
+
+   if(lpFileSizeHigh)
+    *lpFileSizeHigh = FileCompression.CompressedFileSize.u.HighPart;
+
+   SetLastError(NO_ERROR);
+   return FileCompression.CompressedFileSize.u.LowPart;
 }
 
 
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
 GetFileInformationByHandle(HANDLE hFile,
                           LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
 {
@@ -435,6 +751,12 @@ GetFileInformationByHandle(HANDLE hFile,
    NTSTATUS errCode;
    IO_STATUS_BLOCK IoStatusBlock;
 
+   if(IsConsoleHandle(hFile))
+   {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
+   }
+
    errCode = NtQueryInformationFile(hFile,
                                    &IoStatusBlock,
                                    &FileBasic,
@@ -447,9 +769,15 @@ GetFileInformationByHandle(HANDLE hFile,
      }
 
    lpFileInformation->dwFileAttributes = (DWORD)FileBasic.FileAttributes;
-   memcpy(&lpFileInformation->ftCreationTime,&FileBasic.CreationTime,sizeof(LARGE_INTEGER));
-   memcpy(&lpFileInformation->ftLastAccessTime,&FileBasic.LastAccessTime,sizeof(LARGE_INTEGER));
-   memcpy(&lpFileInformation->ftLastWriteTime, &FileBasic.LastWriteTime,sizeof(LARGE_INTEGER));
+
+   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,
@@ -497,236 +825,423 @@ GetFileInformationByHandle(HANDLE hFile,
 }
 
 
-DWORD STDCALL
-GetFileAttributesA(LPCSTR lpFileName)
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetFileAttributesExW(LPCWSTR lpFileName,
+                    GET_FILEEX_INFO_LEVELS fInfoLevelId,
+                    LPVOID lpFileInformation)
 {
-       UNICODE_STRING FileNameU;
-       ANSI_STRING FileName;
-       WINBOOL Result;
+  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;
+    }
 
-       RtlInitAnsiString (&FileName,
-                          (LPSTR)lpFileName);
+  /* build the object attributes */
+  InitializeObjectAttributes (&ObjectAttributes,
+                             &FileName,
+                             OBJ_CASE_INSENSITIVE,
+                             NULL,
+                             NULL);
+
+  /* Open the file */
 
-       /* convert ansi (or oem) string to unicode */
-       if (bIsFileApiAnsi)
-               RtlAnsiStringToUnicodeString (&FileNameU,
-                                             &FileName,
-                                             TRUE);
-       else
-               RtlOemStringToUnicodeString (&FileNameU,
-                                            &FileName,
-                                            TRUE);
 
-       Result = GetFileAttributesW (FileNameU.Buffer);
+  Status = NtOpenFile (&FileHandle,
+                      SYNCHRONIZE | GENERIC_ALL,
+                      &ObjectAttributes,
+                      &IoStatusBlock,
+                      FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+                      FILE_SYNCHRONOUS_IO_NONALERT);
 
-       RtlFreeUnicodeString (&FileNameU);
 
-       return Result;
+
+
+  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;
 }
 
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetFileAttributesExA(LPCSTR lpFileName,
+                    GET_FILEEX_INFO_LEVELS fInfoLevelId,
+                    LPVOID lpFileInformation)
+{
+   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;
+
+   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)
 {
-   IO_STATUS_BLOCK IoStatusBlock;
-   FILE_BASIC_INFORMATION FileBasic;
-   HANDLE hFile;
-   NTSTATUS errCode;
+  WIN32_FILE_ATTRIBUTE_DATA FileAttributeData;
+  BOOL Result;
 
-   hFile = CreateFileW(lpFileName,
-                      FILE_READ_ATTRIBUTES,
-                      FILE_SHARE_READ,
-                      NULL,
-                      OPEN_EXISTING,
-                      FILE_ATTRIBUTE_NORMAL,
-                      NULL);
-   if (hFile == INVALID_HANDLE_VALUE)
-     {
-       return 0xFFFFFFFF;
-     }
+  DPRINT ("GetFileAttributeW(%S) called\n", lpFileName);
 
-   errCode = NtQueryInformationFile(hFile,
-                                   &IoStatusBlock,
-                                   &FileBasic,
-                                   sizeof(FILE_BASIC_INFORMATION),
-                                   FileBasicInformation);
-   if (!NT_SUCCESS(errCode))
-     {
-       CloseHandle(hFile);
-       SetLastErrorByStatus(errCode);
-       return 0xFFFFFFFF;
-     }
-   CloseHandle(hFile);
-   return (DWORD)FileBasic.FileAttributes;
+  Result = GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &FileAttributeData);
+
+  return Result ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES;
 }
 
 
-WINBOOL STDCALL
-SetFileAttributesA(LPCSTR lpFileName,
-                  DWORD dwFileAttributes)
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetFileAttributesByHandle(IN HANDLE hFile,
+                          OUT LPDWORD dwFileAttributes,
+                          IN DWORD dwFlags)
 {
-   UNICODE_STRING FileNameU;
-   ANSI_STRING FileName;
-   WINBOOL Result;
+    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;
+}
 
-   RtlInitAnsiString(&FileName,
-                    (LPSTR)lpFileName);
 
-   /* convert ansi (or oem) string to unicode */
-   if (bIsFileApiAnsi)
-     RtlAnsiStringToUnicodeString(&FileNameU,
-                                 &FileName,
-                                 TRUE);
-   else
-     RtlOemStringToUnicodeString(&FileNameU,
-                                &FileName,
-                                TRUE);
+/*
+ * @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;
+}
 
-   Result = SetFileAttributesW(FileNameU.Buffer,
-                              dwFileAttributes);
 
-   RtlFreeUnicodeString(&FileNameU);
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetFileAttributesA(
+   LPCSTR lpFileName,
+       DWORD dwFileAttributes)
+{
+   PWCHAR FileNameW;
+
+   if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+      return FALSE;
 
-   return Result;
+   return SetFileAttributesW(FileNameW, dwFileAttributes);
 }
 
 
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
 SetFileAttributesW(LPCWSTR lpFileName,
                   DWORD dwFileAttributes)
 {
-   IO_STATUS_BLOCK IoStatusBlock;
-   FILE_BASIC_INFORMATION FileBasic;
-   HANDLE hFile;
-   NTSTATUS errCode;
-   
-   hFile = CreateFileW(lpFileName,
-                      FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
-                      FILE_SHARE_READ,
-                      NULL,
-                      OPEN_EXISTING,
-                      FILE_ATTRIBUTE_NORMAL,
-                      NULL);
+  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;
+    }
 
-   errCode = NtQueryInformationFile(hFile,
-                                   &IoStatusBlock,
-                                   &FileBasic,
-                                   sizeof(FILE_BASIC_INFORMATION),
-                                   FileBasicInformation);
-   if (!NT_SUCCESS(errCode))
-     {
-       CloseHandle(hFile);
-       SetLastErrorByStatus(errCode);
-       return FALSE;
-     }
-   FileBasic.FileAttributes = dwFileAttributes;
-   errCode = NtSetInformationFile(hFile,
+  Status = NtQueryInformationFile(FileHandle,
                                  &IoStatusBlock,
-                                 &FileBasic,
+                                 &FileInformation,
                                  sizeof(FILE_BASIC_INFORMATION),
                                  FileBasicInformation);
-   if (!NT_SUCCESS(errCode))
-     {
-       CloseHandle(hFile);
-       SetLastErrorByStatus(errCode);
-       return FALSE;
-     }
-   CloseHandle(hFile);
-   return TRUE;
+  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;
 }
 
 
-UINT STDCALL
-GetTempFileNameA(LPCSTR lpPathName,
-                LPCSTR lpPrefixString,
-                UINT uUnique,
-                LPSTR lpTempFileName)
+
+
+/***********************************************************************
+ *           GetTempFileNameA   (KERNEL32.@)
+ */
+UINT WINAPI GetTempFileNameA( LPCSTR path, LPCSTR prefix, UINT unique, LPSTR buffer)
 {
-   HANDLE hFile;
-   UINT unique = uUnique;
-   UINT len;
-   const char *format = "%.*s\\~%.3s%4.4x.TMP";
-
-   DPRINT("GetTempFileNameA(lpPathName %s, lpPrefixString %.*s, "
-         "uUnique %x, lpTempFileName %x)\n", lpPathName, 4, 
-         lpPrefixString, uUnique, lpTempFileName);
-  
-   if (lpPathName == NULL)
-     return 0;
-
-   len = strlen(lpPathName);
-   if (len > 0 && (lpPathName[len-1] == '\\' || lpPathName[len-1] == '/'))
-     len--;
-
-   if (uUnique == 0)
-     uUnique = GetCurrentTime();
-   
-   sprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,uUnique);
-   
-   if (unique)
-     return uUnique;
-   
-   while ((hFile = CreateFileA(lpTempFileName, GENERIC_WRITE, 0, NULL,
-                              CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
-                              0)) == INVALID_HANDLE_VALUE)
-   {
-      if (GetLastError() != ERROR_ALREADY_EXISTS)
-      {
-         return 0;
-      }
-      sprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,++uUnique);
-   }
-   CloseHandle(hFile);
-   return uUnique;
-}
+   WCHAR BufferW[MAX_PATH];
+   PWCHAR PathW;
+   WCHAR PrefixW[3+1];
+   UINT ret;
 
+   if (!(PathW = FilenameA2W(path, FALSE)))
+      return 0;
 
-UINT STDCALL
-GetTempFileNameW(LPCWSTR lpPathName,
-                LPCWSTR lpPrefixString,
-                UINT uUnique,
-                LPWSTR lpTempFileName)
+   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 )
 {
-   HANDLE hFile;
-   UINT unique = uUnique;
-   UINT len;
-   const WCHAR *format = L"%.*S\\~%.3S%4.4x.TMP";
-   
-   DPRINT("GetTempFileNameW(lpPathName %S, lpPrefixString %.*S, "
-         "uUnique %x, lpTempFileName %x)\n", lpPathName, 4, 
-         lpPrefixString, uUnique, lpTempFileName);
-
-   if (lpPathName == NULL)
-     return 0;
-
-   len = wcslen(lpPathName);
-   if (len > 0 && (lpPathName[len-1] == L'\\' || lpPathName[len-1] == L'/'))
-     len--;
-   
-   if (uUnique == 0)
-     uUnique = GetCurrentTime();
-   
-   swprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,uUnique);
-   
-   if (unique)
-     return uUnique;
-  
-   while ((hFile = CreateFileW(lpTempFileName, GENERIC_WRITE, 0, NULL,
-                              CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
-                              0)) == INVALID_HANDLE_VALUE)
-   {
-      if (GetLastError() != ERROR_ALREADY_EXISTS)
-      {
-         return 0;
-      }
-      swprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,++uUnique);
-   }
-   CloseHandle(hFile);
-   return uUnique;
+    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;
 }
 
 
-WINBOOL STDCALL
+
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
 GetFileTime(HANDLE hFile,
            LPFILETIME lpCreationTime,
            LPFILETIME lpLastAccessTime,
@@ -736,6 +1251,12 @@ GetFileTime(HANDLE hFile,
    FILE_BASIC_INFORMATION FileBasic;
    NTSTATUS Status;
 
+   if(IsConsoleHandle(hFile))
+   {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
+   }
+
    Status = NtQueryInformationFile(hFile,
                                   &IoStatusBlock,
                                   &FileBasic,
@@ -758,7 +1279,10 @@ GetFileTime(HANDLE hFile,
 }
 
 
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
 SetFileTime(HANDLE hFile,
            CONST FILETIME *lpCreationTime,
            CONST FILETIME *lpLastAccessTime,
@@ -768,6 +1292,12 @@ SetFileTime(HANDLE hFile,
    IO_STATUS_BLOCK IoStatusBlock;
    NTSTATUS Status;
 
+   if(IsConsoleHandle(hFile))
+   {
+     SetLastError(ERROR_INVALID_HANDLE);
+     return FALSE;
+   }
+
    Status = NtQueryInformationFile(hFile,
                                   &IoStatusBlock,
                                   &FileBasic,
@@ -798,15 +1328,17 @@ SetFileTime(HANDLE hFile,
        SetLastErrorByStatus(Status);
        return FALSE;
      }
-   
+
    return TRUE;
 }
 
 
 /*
-The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
-*/
-WINBOOL STDCALL
+ * 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;
@@ -815,6 +1347,12 @@ SetEndOfFile(HANDLE hFile)
        FILE_POSITION_INFORMATION                FilePosInfo;
        NTSTATUS Status;
 
+       if(IsConsoleHandle(hFile))
+       {
+               SetLastError(ERROR_INVALID_HANDLE);
+               return FALSE;
+       }
+
        //get current position
        Status = NtQueryInformationFile(
                                        hFile,
@@ -832,10 +1370,10 @@ SetEndOfFile(HANDLE hFile)
        EndOfFileInfo.EndOfFile.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
 
        /*
-       NOTE: 
+       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 
+       But...most file systems dispatch both FileEndOfFileInformation
        and FileAllocationInformation as they were the same     command.
 
        */
@@ -867,9 +1405,225 @@ SetEndOfFile(HANDLE hFile)
                SetLastErrorByStatus(Status);
                return FALSE;
        }
-       
+
+       return TRUE;
+
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+SetFileValidData(
+    HANDLE hFile,
+    LONGLONG ValidDataLength
+    )
+{
+       IO_STATUS_BLOCK IoStatusBlock;
+       FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation;
+       NTSTATUS Status;
+
+       ValidDataLengthInformation.ValidDataLength.QuadPart = ValidDataLength;
+
+       Status = NtSetInformationFile(
+                                               hFile,
+                                               &IoStatusBlock,  //out
+                                               &ValidDataLengthInformation,
+                                               sizeof(FILE_VALID_DATA_LENGTH_INFORMATION),
+                                               FileValidDataLengthInformation
+                                               );
+
+       if (!NT_SUCCESS(Status)){
+               SetLastErrorByStatus(Status);
+               return FALSE;
+       }
+
        return TRUE;
+}
+
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+SetFileShortNameW(
+  HANDLE hFile,
+  LPCWSTR lpShortName)
+{
+  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);
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+SetFileShortNameA(
+    HANDLE hFile,
+    LPCSTR lpShortName
+    )
+{
+  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);
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+CheckNameLegalDOS8Dot3W(
+    LPCWSTR lpName,
+    LPSTR lpOemName OPTIONAL,
+    DWORD OemNameSize OPTIONAL,
+    PBOOL pbNameContainsSpaces OPTIONAL,
+    PBOOL pbNameLegal
+    )
+{
+    UNICODE_STRING Name;
+    ANSI_STRING AnsiName;
+
+    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;
+    }
+
+    RtlInitUnicodeString(&Name, lpName);
+
+    *pbNameLegal = RtlIsNameLegalDOS8Dot3(&Name,
+                                          (lpOemName ? &AnsiName : NULL),
+                                          (BOOLEAN*)pbNameContainsSpaces);
+
+    return TRUE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+CheckNameLegalDOS8Dot3A(
+    LPCSTR lpName,
+    LPSTR lpOemName OPTIONAL,
+    DWORD OemNameSize OPTIONAL,
+    PBOOL pbNameContainsSpaces OPTIONAL,
+    PBOOL pbNameLegal
+    )
+{
+    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);
+
+    RtlFreeUnicodeString(&Name);
 
+    return TRUE;
 }
 
 /* EOF */