give GetFileAttributesExW more NtOpenFile right to prevent reactos crash if u using...
[reactos.git] / reactos / lib / kernel32 / file / file.c
index 10ccfdf..826ad71 100644 (file)
 
 BOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem
 
-
 /* FUNCTIONS ****************************************************************/
 
 
-PWCHAR 
-FilenameA2W(LPCSTR NameA, BOOL alloc)
-{
-   PUNICODE_STRING pstrW;
 
-   pstrW = FilenameA2U(NameA, alloc);
-   
-   return pstrW ? pstrW->Buffer : NULL;
-}
-
-
-PUNICODE_STRING
-FilenameA2U(LPCSTR NameA, BOOL alloc)
+PWCHAR
+FilenameA2W(LPCSTR NameA, BOOL alloc)
 {
    ANSI_STRING str;
    UNICODE_STRING strW;
@@ -57,13 +46,13 @@ FilenameA2U(LPCSTR NameA, BOOL alloc)
         Status= RtlOemStringToUnicodeString( pstrW, &str, alloc );
 
     if (NT_SUCCESS(Status))
-       return pstrW;
+       return pstrW->Buffer;
 
     if (Status== STATUS_BUFFER_OVERFLOW)
         SetLastError( ERROR_FILENAME_EXCED_RANGE );
     else
         SetLastErrorByStatus(Status);
-        
+
     return NULL;
 }
 
@@ -75,7 +64,7 @@ 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 
+DWORD
 FilenameU2A_FitOrFail(
    LPSTR  DestA,
    INT destLen, /* buffer size in TCHARS incl. nullchar */
@@ -86,23 +75,23 @@ FilenameU2A_FitOrFail(
 
    ret = bIsFileApiAnsi? RtlUnicodeStringToAnsiSize(SourceU) : RtlUnicodeStringToOemSize(SourceU);
    /* ret incl. nullchar */
-    
-   if (DestA && ret <= destLen)
+
+   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;
 }
 
@@ -114,7 +103,7 @@ 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 
+DWORD
 FilenameW2A_FitOrFail(
    LPSTR  DestA,
    INT destLen, /* buffer size in TCHARS incl. nullchar */
@@ -130,53 +119,57 @@ FilenameW2A_FitOrFail(
    strW.MaximumLength = sourceLen * sizeof(WCHAR);
    strW.Length = strW.MaximumLength - sizeof(WCHAR);
 
-   return FilenameU2A_FitOrFail(DestA, destLen, &strW);     
+   return FilenameU2A_FitOrFail(DestA, destLen, &strW);
 }
 
 
-
-DWORD 
-FilenameA2W_N( 
-   LPWSTR dest, 
+/*
+Return: num. TCHARS copied into dest including nullterm
+*/
+DWORD
+FilenameA2W_N(
+   LPWSTR dest,
    INT destlen, /* buffer size in TCHARS incl. nullchar */
-   LPCSTR src, 
+   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  );    
+        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;
-}
 
+    return ret/sizeof(WCHAR);
+}
 
-DWORD 
-FilenameW2A_N( 
-   LPSTR dest, 
+/*
+Return: num. TCHARS copied into dest including nullterm
+*/
+DWORD
+FilenameW2A_N(
+   LPSTR dest,
    INT destlen, /* buffer size in TCHARS incl. nullchar */
-   LPCWSTR src, 
+   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) );    
-        
+        RtlUnicodeToOemN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR) );
+
     if (ret) dest[ret-1]=0;
-    
+
     return ret;
 }
 
@@ -184,20 +177,30 @@ FilenameW2A_N(
 /*
  * @implemented
  */
-VOID STDCALL
+VOID
+STDCALL
 SetFileApisToOEM(VOID)
 {
-   bIsFileApiAnsi = FALSE;
+    /* Set the correct Base Api */
+    Basep8BitStringToUnicodeString = (PRTL_CONVERT_STRING)RtlOemStringToUnicodeString;
+
+    /* FIXME: Old, deprecated way */
+    bIsFileApiAnsi = FALSE;
 }
 
 
 /*
  * @implemented
  */
-VOID STDCALL
+VOID
+STDCALL
 SetFileApisToANSI(VOID)
 {
-   bIsFileApiAnsi = TRUE;
+    /* Set the correct Base Api */
+    Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString;
+
+    /* FIXME: Old, deprecated way */
+    bIsFileApiAnsi = TRUE;
 }
 
 
@@ -266,7 +269,7 @@ OpenFile(LPCSTR lpFileName,
                RtlAnsiStringToUnicodeString (&FileNameU, &FileName, TRUE);
        else
                RtlOemStringToUnicodeString (&FileNameU, &FileName, TRUE);
-                       
+
        Len = SearchPathW (NULL,
                           FileNameU.Buffer,
                           NULL,
@@ -377,7 +380,7 @@ SetFilePointer(HANDLE hFile,
    NTSTATUS errCode;
    IO_STATUS_BLOCK IoStatusBlock;
    LARGE_INTEGER Distance;
-   
+
    DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
          hFile,lDistanceToMove,dwMoveMethod);
 
@@ -400,7 +403,7 @@ SetFilePointer(HANDLE hFile,
    {
       Distance.u.HighPart = -1;
    }
-   
+
    switch(dwMoveMethod)
    {
      case FILE_CURRENT:
@@ -427,13 +430,13 @@ SetFilePointer(HANDLE hFile,
         SetLastError(ERROR_INVALID_PARAMETER);
        return -1;
    }
-   
+
    if(FilePosition.CurrentByteOffset.QuadPart < 0)
    {
      SetLastError(ERROR_NEGATIVE_SEEK);
      return -1;
    }
-   
+
    errCode = NtSetInformationFile(hFile,
                                  &IoStatusBlock,
                                  &FilePosition,
@@ -444,7 +447,7 @@ SetFilePointer(HANDLE hFile,
        SetLastErrorByStatus(errCode);
        return -1;
      }
-   
+
    if (lpDistanceToMoveHigh != NULL)
      {
         *lpDistanceToMoveHigh = FilePosition.CurrentByteOffset.u.HighPart;
@@ -500,13 +503,13 @@ SetFilePointerEx(HANDLE hFile,
         SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
-   
+
    if(FilePosition.CurrentByteOffset.QuadPart < 0)
    {
      SetLastError(ERROR_NEGATIVE_SEEK);
      return FALSE;
    }
-   
+
    errCode = NtSetInformationFile(hFile,
                                  &IoStatusBlock,
                                  &FilePosition,
@@ -517,7 +520,7 @@ SetFilePointerEx(HANDLE hFile,
        SetLastErrorByStatus(errCode);
        return FALSE;
      }
-   
+
    if (lpNewFilePointer)
      {
        *lpNewFilePointer = FilePosition.CurrentByteOffset;
@@ -540,15 +543,15 @@ GetFileType(HANDLE hFile)
   switch ((ULONG)hFile)
     {
       case STD_INPUT_HANDLE:
-       hFile = NtCurrentPeb()->ProcessParameters->hStdInput;
+       hFile = NtCurrentPeb()->ProcessParameters->StandardInput;
        break;
 
       case STD_OUTPUT_HANDLE:
-       hFile = NtCurrentPeb()->ProcessParameters->hStdOutput;
+       hFile = NtCurrentPeb()->ProcessParameters->StandardOutput;
        break;
 
       case STD_ERROR_HANDLE:
-       hFile = NtCurrentPeb()->ProcessParameters->hStdError;
+       hFile = NtCurrentPeb()->ProcessParameters->StandardError;
        break;
     }
 
@@ -694,7 +697,7 @@ GetCompressedFileSizeW(LPCWSTR lpFileName,
    NTSTATUS errCode;
    IO_STATUS_BLOCK IoStatusBlock;
    HANDLE hFile;
-   
+
    hFile = CreateFileW(lpFileName,
                       GENERIC_READ,
                       FILE_SHARE_READ,
@@ -702,7 +705,7 @@ GetCompressedFileSizeW(LPCWSTR lpFileName,
                       OPEN_EXISTING,
                       FILE_ATTRIBUTE_NORMAL,
                       NULL);
-             
+
    if (hFile == INVALID_HANDLE_VALUE)
       return INVALID_FILE_SIZE;
 
@@ -766,13 +769,13 @@ GetFileInformationByHandle(HANDLE hFile,
      }
 
    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;
 
@@ -826,8 +829,8 @@ GetFileInformationByHandle(HANDLE hFile,
  * @implemented
  */
 BOOL STDCALL
-GetFileAttributesExW(LPCWSTR lpFileName, 
-                    GET_FILEEX_INFO_LEVELS fInfoLevelId, 
+GetFileAttributesExW(LPCWSTR lpFileName,
+                    GET_FILEEX_INFO_LEVELS fInfoLevelId,
                     LPVOID lpFileInformation)
 {
   FILE_NETWORK_OPEN_INFORMATION FileInformation;
@@ -866,12 +869,18 @@ GetFileAttributesExW(LPCWSTR lpFileName,
                              NULL);
 
   /* Open the file */
+
+
   Status = NtOpenFile (&FileHandle,
-                      SYNCHRONIZE | FILE_READ_ATTRIBUTES,
+                      SYNCHRONIZE | GENERIC_ALL,
                       &ObjectAttributes,
                       &IoStatusBlock,
                       FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                       FILE_SYNCHRONOUS_IO_NONALERT);
+
+
+
+
   RtlFreeUnicodeString (&FileName);
   if (!NT_SUCCESS (Status))
     {
@@ -914,11 +923,11 @@ GetFileAttributesExW(LPCWSTR lpFileName,
  */
 BOOL STDCALL
 GetFileAttributesExA(LPCSTR lpFileName,
-                    GET_FILEEX_INFO_LEVELS fInfoLevelId, 
+                    GET_FILEEX_INFO_LEVELS fInfoLevelId,
                     LPVOID lpFileInformation)
 {
    PWCHAR FileNameW;
-   
+
    if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
       return FALSE;
 
@@ -938,7 +947,7 @@ GetFileAttributesA(LPCSTR lpFileName)
 
    if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
       return INVALID_FILE_ATTRIBUTES;
-   
+
    ret = GetFileAttributesExW(FileNameW, GetFileExInfoStandard, &FileAttributeData);
 
    return ret ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES;
@@ -961,6 +970,92 @@ GetFileAttributesW(LPCWSTR lpFileName)
   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;
+}
+
+
+/*
+ * @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,
@@ -1067,18 +1162,18 @@ UINT WINAPI GetTempFileNameA( LPCSTR path, LPCSTR prefix, UINT unique, LPSTR buf
    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;
 }
 
@@ -1233,7 +1328,7 @@ SetFileTime(HANDLE hFile,
        SetLastErrorByStatus(Status);
        return FALSE;
      }
-   
+
    return TRUE;
 }
 
@@ -1275,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.
 
        */
@@ -1310,7 +1405,7 @@ SetEndOfFile(HANDLE hFile)
                SetLastErrorByStatus(Status);
                return FALSE;
        }
-       
+
        return TRUE;
 
 }
@@ -1329,9 +1424,9 @@ SetFileValidData(
        IO_STATUS_BLOCK IoStatusBlock;
        FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation;
        NTSTATUS Status;
-       
+
        ValidDataLengthInformation.ValidDataLength.QuadPart = ValidDataLength;
-       
+
        Status = NtSetInformationFile(
                                                hFile,
                                                &IoStatusBlock,  //out
@@ -1339,12 +1434,12 @@ SetFileValidData(
                                                sizeof(FILE_VALID_DATA_LENGTH_INFORMATION),
                                                FileValidDataLengthInformation
                                                );
-  
+
        if (!NT_SUCCESS(Status)){
                SetLastErrorByStatus(Status);
                return FALSE;
        }
-       
+
        return TRUE;
 }
 
@@ -1364,44 +1459,44 @@ SetFileShortNameW(
   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);
 }
 
@@ -1417,19 +1512,19 @@ SetFileShortNameA(
     )
 {
   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;