ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

fileinfo.c
Go to the documentation of this file.
00001 /* $Id: fileinfo.c 54326 2011-11-07 00:18:13Z ion $
00002  *
00003  * COPYRIGHT:       See COPYING in the top level directory
00004  * PROJECT:         ReactOS system libraries
00005  * FILE:            lib/kernel32/file/file.c
00006  * PURPOSE:         Directory functions
00007  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
00008  *                  Pierre Schweitzer (pierre.schweitzer@reactos.org)
00009  * UPDATE HISTORY:
00010  *                  Created 01/11/98
00011  */
00012 
00013 /* INCLUDES *****************************************************************/
00014 
00015 #include <k32.h>
00016 #define NDEBUG
00017 #include <debug.h>
00018 DEBUG_CHANNEL(kernel32file);
00019 
00020 /* FUNCTIONS ****************************************************************/
00021 
00022 PWCHAR
00023 FilenameA2W(LPCSTR NameA, BOOL alloc)
00024 {
00025    ANSI_STRING str;
00026    UNICODE_STRING strW;
00027    PUNICODE_STRING pstrW;
00028    NTSTATUS Status;
00029 
00030    //ASSERT(NtCurrentTeb()->StaticUnicodeString.Buffer == NtCurrentTeb()->StaticUnicodeBuffer);
00031    ASSERT(NtCurrentTeb()->StaticUnicodeString.MaximumLength == sizeof(NtCurrentTeb()->StaticUnicodeBuffer));
00032 
00033    RtlInitAnsiString(&str, NameA);
00034    pstrW = alloc ? &strW : &NtCurrentTeb()->StaticUnicodeString;
00035 
00036    if (bIsFileApiAnsi)
00037         Status= RtlAnsiStringToUnicodeString( pstrW, &str, (BOOLEAN)alloc );
00038    else
00039         Status= RtlOemStringToUnicodeString( pstrW, &str, (BOOLEAN)alloc );
00040 
00041     if (NT_SUCCESS(Status))
00042        return pstrW->Buffer;
00043 
00044     if (Status== STATUS_BUFFER_OVERFLOW)
00045         SetLastError( ERROR_FILENAME_EXCED_RANGE );
00046     else
00047         BaseSetLastNTError(Status);
00048 
00049     return NULL;
00050 }
00051 
00052 
00053 /*
00054 No copy/conversion is done if the dest. buffer is too small.
00055 
00056 Returns:
00057    Success: number of TCHARS copied into dest. buffer NOT including nullterm
00058    Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
00059 */
00060 DWORD
00061 FilenameU2A_FitOrFail(
00062    LPSTR  DestA,
00063    INT destLen, /* buffer size in TCHARS incl. nullchar */
00064    PUNICODE_STRING SourceU
00065    )
00066 {
00067    DWORD ret;
00068 
00069    /* destLen should never exceed MAX_PATH */
00070    if (destLen > MAX_PATH) destLen = MAX_PATH;
00071 
00072    ret = bIsFileApiAnsi? RtlUnicodeStringToAnsiSize(SourceU) : RtlUnicodeStringToOemSize(SourceU);
00073    /* ret incl. nullchar */
00074 
00075    if (DestA && (INT)ret <= destLen)
00076    {
00077       ANSI_STRING str;
00078 
00079       str.Buffer = DestA;
00080       str.MaximumLength = (USHORT)destLen;
00081 
00082 
00083       if (bIsFileApiAnsi)
00084          RtlUnicodeStringToAnsiString(&str, SourceU, FALSE );
00085       else
00086          RtlUnicodeStringToOemString(&str, SourceU, FALSE );
00087 
00088       ret = str.Length;  /* SUCCESS: length without terminating 0 */
00089    }
00090 
00091    return ret;
00092 }
00093 
00094 
00095 /*
00096 No copy/conversion is done if the dest. buffer is too small.
00097 
00098 Returns:
00099    Success: number of TCHARS copied into dest. buffer NOT including nullterm
00100    Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
00101 */
00102 DWORD
00103 FilenameW2A_FitOrFail(
00104    LPSTR  DestA,
00105    INT destLen, /* buffer size in TCHARS incl. nullchar */
00106    LPCWSTR SourceW,
00107    INT sourceLen /* buffer size in TCHARS incl. nullchar */
00108    )
00109 {
00110    UNICODE_STRING strW;
00111 
00112    if (sourceLen < 0) sourceLen = wcslen(SourceW) + 1;
00113 
00114    strW.Buffer = (PWCHAR)SourceW;
00115    strW.MaximumLength = sourceLen * sizeof(WCHAR);
00116    strW.Length = strW.MaximumLength - sizeof(WCHAR);
00117 
00118    return FilenameU2A_FitOrFail(DestA, destLen, &strW);
00119 }
00120 
00121 
00122 /*
00123 Return: num. TCHARS copied into dest including nullterm
00124 */
00125 DWORD
00126 FilenameA2W_N(
00127    LPWSTR dest,
00128    INT destlen, /* buffer size in TCHARS incl. nullchar */
00129    LPCSTR src,
00130    INT srclen /* buffer size in TCHARS incl. nullchar */
00131    )
00132 {
00133     DWORD ret;
00134 
00135     if (srclen < 0) srclen = strlen( src ) + 1;
00136 
00137     if (bIsFileApiAnsi)
00138         RtlMultiByteToUnicodeN( dest, destlen* sizeof(WCHAR), &ret, (LPSTR)src, srclen  );
00139     else
00140         RtlOemToUnicodeN( dest, destlen* sizeof(WCHAR), &ret, (LPSTR)src, srclen );
00141 
00142     if (ret) dest[(ret/sizeof(WCHAR))-1]=0;
00143 
00144     return ret/sizeof(WCHAR);
00145 }
00146 
00147 /*
00148 Return: num. TCHARS copied into dest including nullterm
00149 */
00150 DWORD
00151 FilenameW2A_N(
00152    LPSTR dest,
00153    INT destlen, /* buffer size in TCHARS incl. nullchar */
00154    LPCWSTR src,
00155    INT srclen /* buffer size in TCHARS incl. nullchar */
00156    )
00157 {
00158     DWORD ret;
00159 
00160     if (srclen < 0) srclen = wcslen( src ) + 1;
00161 
00162     if (bIsFileApiAnsi)
00163         RtlUnicodeToMultiByteN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR));
00164     else
00165         RtlUnicodeToOemN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR) );
00166 
00167     if (ret) dest[ret-1]=0;
00168 
00169     return ret;
00170 }
00171 
00172 /*
00173  * @implemented
00174  */
00175 BOOL WINAPI
00176 FlushFileBuffers(IN HANDLE hFile)
00177 {
00178     NTSTATUS Status;
00179     IO_STATUS_BLOCK IoStatusBlock;
00180 
00181     hFile = TranslateStdHandle(hFile);
00182 
00183     if (IsConsoleHandle(hFile))
00184     {
00185         return FlushConsoleInputBuffer(hFile);
00186     }
00187 
00188     Status = NtFlushBuffersFile(hFile,
00189                                 &IoStatusBlock);
00190     if (!NT_SUCCESS(Status))
00191     {
00192         BaseSetLastNTError(Status);
00193         return FALSE;
00194     }
00195     return TRUE;
00196 }
00197 
00198 
00199 /*
00200  * @implemented
00201  */
00202 DWORD WINAPI
00203 SetFilePointer(HANDLE hFile,
00204            LONG lDistanceToMove,
00205            PLONG lpDistanceToMoveHigh,
00206            DWORD dwMoveMethod)
00207 {
00208    FILE_POSITION_INFORMATION FilePosition;
00209    FILE_STANDARD_INFORMATION FileStandard;
00210    NTSTATUS errCode;
00211    IO_STATUS_BLOCK IoStatusBlock;
00212    LARGE_INTEGER Distance;
00213 
00214    TRACE("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
00215       hFile,lDistanceToMove,dwMoveMethod);
00216 
00217    if(IsConsoleHandle(hFile))
00218    {
00219      SetLastError(ERROR_INVALID_HANDLE);
00220      return INVALID_SET_FILE_POINTER;
00221    }
00222 
00223    if (lpDistanceToMoveHigh)
00224    {
00225       Distance.u.HighPart = *lpDistanceToMoveHigh;
00226       Distance.u.LowPart = lDistanceToMove;
00227    }
00228    else
00229    {
00230       Distance.QuadPart = lDistanceToMove;
00231    }
00232 
00233    switch(dwMoveMethod)
00234    {
00235      case FILE_CURRENT:
00236     errCode = NtQueryInformationFile(hFile,
00237                    &IoStatusBlock,
00238                    &FilePosition,
00239                    sizeof(FILE_POSITION_INFORMATION),
00240                    FilePositionInformation);
00241     FilePosition.CurrentByteOffset.QuadPart += Distance.QuadPart;
00242     if (!NT_SUCCESS(errCode))
00243     {
00244       if (lpDistanceToMoveHigh != NULL)
00245           *lpDistanceToMoveHigh = -1;
00246       BaseSetLastNTError(errCode);
00247       return INVALID_SET_FILE_POINTER;
00248     }
00249     break;
00250      case FILE_END:
00251     errCode = NtQueryInformationFile(hFile,
00252                                &IoStatusBlock,
00253                                &FileStandard,
00254                                sizeof(FILE_STANDARD_INFORMATION),
00255                                FileStandardInformation);
00256     FilePosition.CurrentByteOffset.QuadPart =
00257                   FileStandard.EndOfFile.QuadPart + Distance.QuadPart;
00258     if (!NT_SUCCESS(errCode))
00259     {
00260       if (lpDistanceToMoveHigh != NULL)
00261           *lpDistanceToMoveHigh = -1;
00262       BaseSetLastNTError(errCode);
00263       return INVALID_SET_FILE_POINTER;
00264     }
00265     break;
00266      case FILE_BEGIN:
00267         FilePosition.CurrentByteOffset.QuadPart = Distance.QuadPart;
00268     break;
00269      default:
00270         SetLastError(ERROR_INVALID_PARAMETER);
00271     return INVALID_SET_FILE_POINTER;
00272    }
00273 
00274    if(FilePosition.CurrentByteOffset.QuadPart < 0)
00275    {
00276      SetLastError(ERROR_NEGATIVE_SEEK);
00277      return INVALID_SET_FILE_POINTER;
00278    }
00279 
00280    if (lpDistanceToMoveHigh == NULL && FilePosition.CurrentByteOffset.HighPart != 0)
00281    {
00282      /* If we're moving the pointer outside of the 32 bit boundaries but
00283         the application only passed a 32 bit value we need to bail out! */
00284      SetLastError(ERROR_INVALID_PARAMETER);
00285      return INVALID_SET_FILE_POINTER;
00286    }
00287 
00288    errCode = NtSetInformationFile(hFile,
00289                   &IoStatusBlock,
00290                   &FilePosition,
00291                   sizeof(FILE_POSITION_INFORMATION),
00292                   FilePositionInformation);
00293    if (!NT_SUCCESS(errCode))
00294      {
00295        if (lpDistanceToMoveHigh != NULL)
00296            *lpDistanceToMoveHigh = -1;
00297 
00298        BaseSetLastNTError(errCode);
00299        return INVALID_SET_FILE_POINTER;
00300      }
00301 
00302    if (lpDistanceToMoveHigh != NULL)
00303      {
00304         *lpDistanceToMoveHigh = FilePosition.CurrentByteOffset.u.HighPart;
00305      }
00306 
00307    if (FilePosition.CurrentByteOffset.u.LowPart == MAXDWORD)
00308      {
00309        /* The value of -1 is valid here, especially when the new
00310           file position is greater than 4 GB. Since NtSetInformationFile
00311           succeeded we never set an error code and we explicitly need
00312           to clear a previously set error code in this case, which
00313           an application will check if INVALID_SET_FILE_POINTER is returned! */
00314        SetLastError(ERROR_SUCCESS);
00315      }
00316 
00317    return FilePosition.CurrentByteOffset.u.LowPart;
00318 }
00319 
00320 
00321 /*
00322  * @implemented
00323  */
00324 BOOL
00325 WINAPI
00326 SetFilePointerEx(HANDLE hFile,
00327          LARGE_INTEGER liDistanceToMove,
00328          PLARGE_INTEGER lpNewFilePointer,
00329          DWORD dwMoveMethod)
00330 {
00331    FILE_POSITION_INFORMATION FilePosition;
00332    FILE_STANDARD_INFORMATION FileStandard;
00333    NTSTATUS errCode;
00334    IO_STATUS_BLOCK IoStatusBlock;
00335 
00336    if(IsConsoleHandle(hFile))
00337    {
00338      SetLastError(ERROR_INVALID_HANDLE);
00339      return FALSE;
00340    }
00341 
00342    switch(dwMoveMethod)
00343    {
00344      case FILE_CURRENT:
00345     NtQueryInformationFile(hFile,
00346                    &IoStatusBlock,
00347                    &FilePosition,
00348                    sizeof(FILE_POSITION_INFORMATION),
00349                    FilePositionInformation);
00350     FilePosition.CurrentByteOffset.QuadPart += liDistanceToMove.QuadPart;
00351     break;
00352      case FILE_END:
00353     NtQueryInformationFile(hFile,
00354                                &IoStatusBlock,
00355                                &FileStandard,
00356                                sizeof(FILE_STANDARD_INFORMATION),
00357                                FileStandardInformation);
00358         FilePosition.CurrentByteOffset.QuadPart =
00359                   FileStandard.EndOfFile.QuadPart + liDistanceToMove.QuadPart;
00360     break;
00361      case FILE_BEGIN:
00362         FilePosition.CurrentByteOffset.QuadPart = liDistanceToMove.QuadPart;
00363     break;
00364      default:
00365         SetLastError(ERROR_INVALID_PARAMETER);
00366     return FALSE;
00367    }
00368 
00369    if(FilePosition.CurrentByteOffset.QuadPart < 0)
00370    {
00371      SetLastError(ERROR_NEGATIVE_SEEK);
00372      return FALSE;
00373    }
00374 
00375    errCode = NtSetInformationFile(hFile,
00376                   &IoStatusBlock,
00377                   &FilePosition,
00378                   sizeof(FILE_POSITION_INFORMATION),
00379                   FilePositionInformation);
00380    if (!NT_SUCCESS(errCode))
00381      {
00382     BaseSetLastNTError(errCode);
00383     return FALSE;
00384      }
00385 
00386    if (lpNewFilePointer)
00387      {
00388        *lpNewFilePointer = FilePosition.CurrentByteOffset;
00389      }
00390    return TRUE;
00391 }
00392 
00393 
00394 /*
00395  * @implemented
00396  */
00397 DWORD WINAPI
00398 GetFileType(HANDLE hFile)
00399 {
00400   FILE_FS_DEVICE_INFORMATION DeviceInfo;
00401   IO_STATUS_BLOCK StatusBlock;
00402   NTSTATUS Status;
00403 
00404   /* Get real handle */
00405   hFile = TranslateStdHandle(hFile);
00406 
00407   /* Check for console handle */
00408   if (IsConsoleHandle(hFile))
00409     {
00410       if (VerifyConsoleIoHandle(hFile))
00411     return FILE_TYPE_CHAR;
00412     }
00413 
00414   Status = NtQueryVolumeInformationFile(hFile,
00415                     &StatusBlock,
00416                     &DeviceInfo,
00417                     sizeof(FILE_FS_DEVICE_INFORMATION),
00418                     FileFsDeviceInformation);
00419   if (!NT_SUCCESS(Status))
00420     {
00421       BaseSetLastNTError(Status);
00422       return FILE_TYPE_UNKNOWN;
00423     }
00424 
00425   switch (DeviceInfo.DeviceType)
00426     {
00427       case FILE_DEVICE_CD_ROM:
00428       case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
00429       case FILE_DEVICE_CONTROLLER:
00430       case FILE_DEVICE_DATALINK:
00431       case FILE_DEVICE_DFS:
00432       case FILE_DEVICE_DISK:
00433       case FILE_DEVICE_DISK_FILE_SYSTEM:
00434       case FILE_DEVICE_VIRTUAL_DISK:
00435     return FILE_TYPE_DISK;
00436 
00437       case FILE_DEVICE_KEYBOARD:
00438       case FILE_DEVICE_MOUSE:
00439       case FILE_DEVICE_NULL:
00440       case FILE_DEVICE_PARALLEL_PORT:
00441       case FILE_DEVICE_PRINTER:
00442       case FILE_DEVICE_SERIAL_PORT:
00443       case FILE_DEVICE_SCREEN:
00444       case FILE_DEVICE_SOUND:
00445       case FILE_DEVICE_MODEM:
00446     return FILE_TYPE_CHAR;
00447 
00448       case FILE_DEVICE_NAMED_PIPE:
00449     return FILE_TYPE_PIPE;
00450     }
00451 
00452   return FILE_TYPE_UNKNOWN;
00453 }
00454 
00455 
00456 /*
00457  * @implemented
00458  */
00459 DWORD WINAPI
00460 GetFileSize(HANDLE hFile,
00461         LPDWORD lpFileSizeHigh)
00462 {
00463    NTSTATUS errCode;
00464    FILE_STANDARD_INFORMATION FileStandard;
00465    IO_STATUS_BLOCK IoStatusBlock;
00466 
00467    errCode = NtQueryInformationFile(hFile,
00468                     &IoStatusBlock,
00469                     &FileStandard,
00470                     sizeof(FILE_STANDARD_INFORMATION),
00471                     FileStandardInformation);
00472    if (!NT_SUCCESS(errCode))
00473      {
00474     BaseSetLastNTError(errCode);
00475     if ( lpFileSizeHigh == NULL )
00476       {
00477          return -1;
00478       }
00479     else
00480       {
00481          return 0;
00482       }
00483      }
00484    if ( lpFileSizeHigh != NULL )
00485      *lpFileSizeHigh = FileStandard.EndOfFile.u.HighPart;
00486 
00487    return FileStandard.EndOfFile.u.LowPart;
00488 }
00489 
00490 
00491 /*
00492  * @implemented
00493  */
00494 BOOL
00495 WINAPI
00496 GetFileSizeEx(
00497     HANDLE hFile,
00498     PLARGE_INTEGER lpFileSize
00499     )
00500 {
00501    NTSTATUS errCode;
00502    FILE_STANDARD_INFORMATION FileStandard;
00503    IO_STATUS_BLOCK IoStatusBlock;
00504 
00505    errCode = NtQueryInformationFile(hFile,
00506                     &IoStatusBlock,
00507                     &FileStandard,
00508                     sizeof(FILE_STANDARD_INFORMATION),
00509                     FileStandardInformation);
00510    if (!NT_SUCCESS(errCode))
00511      {
00512     BaseSetLastNTError(errCode);
00513     return FALSE;
00514      }
00515    if (lpFileSize)
00516      *lpFileSize = FileStandard.EndOfFile;
00517 
00518    return TRUE;
00519 }
00520 
00521 
00522 /*
00523  * @implemented
00524  */
00525 DWORD WINAPI
00526 GetCompressedFileSizeA(LPCSTR lpFileName,
00527                LPDWORD lpFileSizeHigh)
00528 {
00529    PWCHAR FileNameW;
00530 
00531    if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
00532       return INVALID_FILE_SIZE;
00533 
00534    return GetCompressedFileSizeW(FileNameW, lpFileSizeHigh);
00535 }
00536 
00537 
00538 /*
00539  * @implemented
00540  */
00541 DWORD WINAPI
00542 GetCompressedFileSizeW(LPCWSTR lpFileName,
00543                LPDWORD lpFileSizeHigh)
00544 {
00545    FILE_COMPRESSION_INFORMATION FileCompression;
00546    NTSTATUS errCode;
00547    IO_STATUS_BLOCK IoStatusBlock;
00548    HANDLE hFile;
00549 
00550    hFile = CreateFileW(lpFileName,
00551                GENERIC_READ,
00552                FILE_SHARE_READ,
00553                NULL,
00554                OPEN_EXISTING,
00555                FILE_ATTRIBUTE_NORMAL,
00556                NULL);
00557 
00558    if (hFile == INVALID_HANDLE_VALUE)
00559       return INVALID_FILE_SIZE;
00560 
00561    errCode = NtQueryInformationFile(hFile,
00562                     &IoStatusBlock,
00563                     &FileCompression,
00564                     sizeof(FILE_COMPRESSION_INFORMATION),
00565                     FileCompressionInformation);
00566 
00567    CloseHandle(hFile);
00568 
00569    if (!NT_SUCCESS(errCode))
00570      {
00571     BaseSetLastNTError(errCode);
00572     return INVALID_FILE_SIZE;
00573      }
00574 
00575    if(lpFileSizeHigh)
00576     *lpFileSizeHigh = FileCompression.CompressedFileSize.u.HighPart;
00577 
00578    SetLastError(NO_ERROR);
00579    return FileCompression.CompressedFileSize.u.LowPart;
00580 }
00581 
00582 
00583 /*
00584  * @implemented
00585  */
00586 BOOL WINAPI
00587 GetFileInformationByHandle(HANDLE hFile,
00588                LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
00589 {
00590    struct
00591    {
00592         FILE_FS_VOLUME_INFORMATION FileFsVolume;
00593         WCHAR Name[255];
00594    }
00595    FileFsVolume;
00596 
00597    FILE_BASIC_INFORMATION FileBasic;
00598    FILE_INTERNAL_INFORMATION FileInternal;
00599    FILE_STANDARD_INFORMATION FileStandard;
00600    NTSTATUS errCode;
00601    IO_STATUS_BLOCK IoStatusBlock;
00602 
00603    if(IsConsoleHandle(hFile))
00604    {
00605      SetLastError(ERROR_INVALID_HANDLE);
00606      return FALSE;
00607    }
00608 
00609    errCode = NtQueryInformationFile(hFile,
00610                     &IoStatusBlock,
00611                     &FileBasic,
00612                     sizeof(FILE_BASIC_INFORMATION),
00613                     FileBasicInformation);
00614    if (!NT_SUCCESS(errCode))
00615      {
00616     BaseSetLastNTError(errCode);
00617     return FALSE;
00618      }
00619 
00620    lpFileInformation->dwFileAttributes = (DWORD)FileBasic.FileAttributes;
00621 
00622    lpFileInformation->ftCreationTime.dwHighDateTime = FileBasic.CreationTime.u.HighPart;
00623    lpFileInformation->ftCreationTime.dwLowDateTime = FileBasic.CreationTime.u.LowPart;
00624 
00625    lpFileInformation->ftLastAccessTime.dwHighDateTime = FileBasic.LastAccessTime.u.HighPart;
00626    lpFileInformation->ftLastAccessTime.dwLowDateTime = FileBasic.LastAccessTime.u.LowPart;
00627 
00628    lpFileInformation->ftLastWriteTime.dwHighDateTime = FileBasic.LastWriteTime.u.HighPart;
00629    lpFileInformation->ftLastWriteTime.dwLowDateTime = FileBasic.LastWriteTime.u.LowPart;
00630 
00631    errCode = NtQueryInformationFile(hFile,
00632                     &IoStatusBlock,
00633                     &FileInternal,
00634                     sizeof(FILE_INTERNAL_INFORMATION),
00635                     FileInternalInformation);
00636    if (!NT_SUCCESS(errCode))
00637      {
00638     BaseSetLastNTError(errCode);
00639     return FALSE;
00640      }
00641 
00642    lpFileInformation->nFileIndexHigh = FileInternal.IndexNumber.u.HighPart;
00643    lpFileInformation->nFileIndexLow = FileInternal.IndexNumber.u.LowPart;
00644 
00645    errCode = NtQueryVolumeInformationFile(hFile,
00646                       &IoStatusBlock,
00647                       &FileFsVolume,
00648                       sizeof(FileFsVolume),
00649                       FileFsVolumeInformation);
00650    if (!NT_SUCCESS(errCode))
00651      {
00652     BaseSetLastNTError(errCode);
00653     return FALSE;
00654      }
00655 
00656    lpFileInformation->dwVolumeSerialNumber = FileFsVolume.FileFsVolume.VolumeSerialNumber;
00657 
00658    errCode = NtQueryInformationFile(hFile,
00659                     &IoStatusBlock,
00660                     &FileStandard,
00661                     sizeof(FILE_STANDARD_INFORMATION),
00662                     FileStandardInformation);
00663    if (!NT_SUCCESS(errCode))
00664      {
00665     BaseSetLastNTError(errCode);
00666     return FALSE;
00667      }
00668 
00669    lpFileInformation->nNumberOfLinks = FileStandard.NumberOfLinks;
00670    lpFileInformation->nFileSizeHigh = FileStandard.EndOfFile.u.HighPart;
00671    lpFileInformation->nFileSizeLow = FileStandard.EndOfFile.u.LowPart;
00672 
00673    return TRUE;
00674 }
00675 
00676 
00677 /*
00678  * @implemented
00679  */
00680 BOOL WINAPI
00681 GetFileAttributesExW(LPCWSTR lpFileName,
00682              GET_FILEEX_INFO_LEVELS fInfoLevelId,
00683              LPVOID lpFileInformation)
00684 {
00685   FILE_NETWORK_OPEN_INFORMATION FileInformation;
00686   OBJECT_ATTRIBUTES ObjectAttributes;
00687   UNICODE_STRING FileName;
00688   NTSTATUS Status;
00689   WIN32_FILE_ATTRIBUTE_DATA* FileAttributeData;
00690 
00691   TRACE("GetFileAttributesExW(%S) called\n", lpFileName);
00692 
00693 
00694   if (fInfoLevelId != GetFileExInfoStandard || lpFileInformation == NULL)
00695   {
00696      SetLastError(ERROR_INVALID_PARAMETER);
00697      return FALSE;
00698   }
00699 
00700   /* Validate and translate the filename */
00701   if (!RtlDosPathNameToNtPathName_U (lpFileName,
00702                      &FileName,
00703                      NULL,
00704                      NULL))
00705     {
00706       WARN ("Invalid path '%S'\n", lpFileName);
00707       SetLastError (ERROR_BAD_PATHNAME);
00708       return FALSE;
00709     }
00710 
00711   /* build the object attributes */
00712   InitializeObjectAttributes (&ObjectAttributes,
00713                   &FileName,
00714                   OBJ_CASE_INSENSITIVE,
00715                   NULL,
00716                   NULL);
00717 
00718   /* Get file attributes */
00719   Status = NtQueryFullAttributesFile(&ObjectAttributes,
00720                                      &FileInformation);
00721 
00722   RtlFreeUnicodeString (&FileName);
00723   if (!NT_SUCCESS (Status))
00724     {
00725       WARN ("NtQueryFullAttributesFile() failed (Status %lx)\n", Status);
00726       BaseSetLastNTError (Status);
00727       return FALSE;
00728     }
00729 
00730   FileAttributeData = (WIN32_FILE_ATTRIBUTE_DATA*)lpFileInformation;
00731   FileAttributeData->dwFileAttributes = FileInformation.FileAttributes;
00732   FileAttributeData->ftCreationTime.dwLowDateTime = FileInformation.CreationTime.u.LowPart;
00733   FileAttributeData->ftCreationTime.dwHighDateTime = FileInformation.CreationTime.u.HighPart;
00734   FileAttributeData->ftLastAccessTime.dwLowDateTime = FileInformation.LastAccessTime.u.LowPart;
00735   FileAttributeData->ftLastAccessTime.dwHighDateTime = FileInformation.LastAccessTime.u.HighPart;
00736   FileAttributeData->ftLastWriteTime.dwLowDateTime = FileInformation.LastWriteTime.u.LowPart;
00737   FileAttributeData->ftLastWriteTime.dwHighDateTime = FileInformation.LastWriteTime.u.HighPart;
00738   FileAttributeData->nFileSizeLow = FileInformation.EndOfFile.u.LowPart;
00739   FileAttributeData->nFileSizeHigh = FileInformation.EndOfFile.u.HighPart;
00740 
00741   return TRUE;
00742 }
00743 
00744 /*
00745  * @implemented
00746  */
00747 BOOL WINAPI
00748 GetFileAttributesExA(LPCSTR lpFileName,
00749              GET_FILEEX_INFO_LEVELS fInfoLevelId,
00750              LPVOID lpFileInformation)
00751 {
00752    PWCHAR FileNameW;
00753 
00754    if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
00755       return FALSE;
00756 
00757    return GetFileAttributesExW(FileNameW, fInfoLevelId, lpFileInformation);
00758 }
00759 
00760 
00761 /*
00762  * @implemented
00763  */
00764 DWORD WINAPI
00765 GetFileAttributesA(LPCSTR lpFileName)
00766 {
00767    WIN32_FILE_ATTRIBUTE_DATA FileAttributeData;
00768    PWSTR FileNameW;
00769    BOOL ret;
00770 
00771    if (!lpFileName || !(FileNameW = FilenameA2W(lpFileName, FALSE)))
00772       return INVALID_FILE_ATTRIBUTES;
00773 
00774    ret = GetFileAttributesExW(FileNameW, GetFileExInfoStandard, &FileAttributeData);
00775 
00776    return ret ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES;
00777 }
00778 
00779 
00780 /*
00781  * @implemented
00782  */
00783 DWORD WINAPI
00784 GetFileAttributesW(LPCWSTR lpFileName)
00785 {
00786   WIN32_FILE_ATTRIBUTE_DATA FileAttributeData;
00787   BOOL Result;
00788 
00789   TRACE ("GetFileAttributeW(%S) called\n", lpFileName);
00790 
00791   Result = GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &FileAttributeData);
00792 
00793   return Result ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES;
00794 }
00795 
00796 
00797 /*
00798  * @implemented
00799  */
00800 BOOL WINAPI
00801 GetFileAttributesByHandle(IN HANDLE hFile,
00802                           OUT LPDWORD dwFileAttributes,
00803                           IN DWORD dwFlags)
00804 {
00805     FILE_BASIC_INFORMATION FileBasic;
00806     IO_STATUS_BLOCK IoStatusBlock;
00807     NTSTATUS Status;
00808 
00809     UNREFERENCED_PARAMETER(dwFlags);
00810 
00811     if (IsConsoleHandle(hFile))
00812     {
00813         SetLastError(ERROR_INVALID_HANDLE);
00814         return FALSE;
00815     }
00816 
00817     Status = NtQueryInformationFile(hFile,
00818                                     &IoStatusBlock,
00819                                     &FileBasic,
00820                                     sizeof(FileBasic),
00821                                     FileBasicInformation);
00822     if (NT_SUCCESS(Status))
00823     {
00824         *dwFileAttributes = FileBasic.FileAttributes;
00825         return TRUE;
00826     }
00827 
00828     BaseSetLastNTError(Status);
00829     return FALSE;
00830 }
00831 
00832 
00833 /*
00834  * @implemented
00835  */
00836 BOOL WINAPI
00837 SetFileAttributesByHandle(IN HANDLE hFile,
00838                           IN DWORD dwFileAttributes,
00839                           IN DWORD dwFlags)
00840 {
00841     FILE_BASIC_INFORMATION FileBasic;
00842     IO_STATUS_BLOCK IoStatusBlock;
00843     NTSTATUS Status;
00844 
00845     UNREFERENCED_PARAMETER(dwFlags);
00846 
00847     if (IsConsoleHandle(hFile))
00848     {
00849         SetLastError(ERROR_INVALID_HANDLE);
00850         return FALSE;
00851     }
00852 
00853     Status = NtQueryInformationFile(hFile,
00854                                     &IoStatusBlock,
00855                                     &FileBasic,
00856                                     sizeof(FileBasic),
00857                                     FileBasicInformation);
00858     if (NT_SUCCESS(Status))
00859     {
00860         FileBasic.FileAttributes = dwFileAttributes;
00861 
00862         Status = NtSetInformationFile(hFile,
00863                                       &IoStatusBlock,
00864                                       &FileBasic,
00865                                       sizeof(FileBasic),
00866                                       FileBasicInformation);
00867     }
00868 
00869     if (!NT_SUCCESS(Status))
00870     {
00871         BaseSetLastNTError(Status);
00872         return FALSE;
00873     }
00874 
00875     return TRUE;
00876 }
00877 
00878 
00879 /*
00880  * @implemented
00881  */
00882 BOOL WINAPI
00883 SetFileAttributesA(
00884    LPCSTR lpFileName,
00885     DWORD dwFileAttributes)
00886 {
00887    PWCHAR FileNameW;
00888 
00889    if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
00890       return FALSE;
00891 
00892    return SetFileAttributesW(FileNameW, dwFileAttributes);
00893 }
00894 
00895 
00896 /*
00897  * @implemented
00898  */
00899 BOOL WINAPI
00900 SetFileAttributesW(LPCWSTR lpFileName,
00901            DWORD dwFileAttributes)
00902 {
00903   FILE_BASIC_INFORMATION FileInformation;
00904   OBJECT_ATTRIBUTES ObjectAttributes;
00905   IO_STATUS_BLOCK IoStatusBlock;
00906   UNICODE_STRING FileName;
00907   HANDLE FileHandle;
00908   NTSTATUS Status;
00909 
00910   TRACE ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName, dwFileAttributes);
00911 
00912   /* Validate and translate the filename */
00913   if (!RtlDosPathNameToNtPathName_U (lpFileName,
00914                      &FileName,
00915                      NULL,
00916                      NULL))
00917     {
00918       WARN ("Invalid path\n");
00919       SetLastError (ERROR_BAD_PATHNAME);
00920       return FALSE;
00921     }
00922   TRACE ("FileName: \'%wZ\'\n", &FileName);
00923 
00924   /* build the object attributes */
00925   InitializeObjectAttributes (&ObjectAttributes,
00926                   &FileName,
00927                   OBJ_CASE_INSENSITIVE,
00928                   NULL,
00929                   NULL);
00930 
00931   /* Open the file */
00932   Status = NtOpenFile (&FileHandle,
00933                SYNCHRONIZE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
00934                &ObjectAttributes,
00935                &IoStatusBlock,
00936                FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
00937                FILE_SYNCHRONOUS_IO_NONALERT);
00938   RtlFreeUnicodeString (&FileName);
00939   if (!NT_SUCCESS (Status))
00940     {
00941       WARN ("NtOpenFile() failed (Status %lx)\n", Status);
00942       BaseSetLastNTError (Status);
00943       return FALSE;
00944     }
00945 
00946   Status = NtQueryInformationFile(FileHandle,
00947                   &IoStatusBlock,
00948                   &FileInformation,
00949                   sizeof(FILE_BASIC_INFORMATION),
00950                   FileBasicInformation);
00951   if (!NT_SUCCESS(Status))
00952     {
00953       WARN ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status);
00954       NtClose (FileHandle);
00955       BaseSetLastNTError (Status);
00956       return FALSE;
00957     }
00958 
00959   FileInformation.FileAttributes = dwFileAttributes;
00960   Status = NtSetInformationFile(FileHandle,
00961                 &IoStatusBlock,
00962                 &FileInformation,
00963                 sizeof(FILE_BASIC_INFORMATION),
00964                 FileBasicInformation);
00965   NtClose (FileHandle);
00966   if (!NT_SUCCESS(Status))
00967     {
00968       WARN ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status);
00969       BaseSetLastNTError (Status);
00970       return FALSE;
00971     }
00972 
00973   return TRUE;
00974 }
00975 
00976 /*
00977  * @implemented
00978  */
00979 BOOL WINAPI
00980 GetFileTime(IN HANDLE hFile,
00981             OUT LPFILETIME lpCreationTime OPTIONAL,
00982             OUT LPFILETIME lpLastAccessTime OPTIONAL,
00983             OUT LPFILETIME lpLastWriteTime OPTIONAL)
00984 {
00985     NTSTATUS Status;
00986     IO_STATUS_BLOCK IoStatusBlock;
00987     FILE_BASIC_INFORMATION FileBasic;
00988 
00989     if(IsConsoleHandle(hFile))
00990     {
00991         BaseSetLastNTError(STATUS_INVALID_HANDLE);
00992         return FALSE;
00993     }
00994 
00995     Status = NtQueryInformationFile(hFile,
00996                                     &IoStatusBlock,
00997                                     &FileBasic,
00998                                     sizeof(FILE_BASIC_INFORMATION),
00999                                     FileBasicInformation);
01000     if (!NT_SUCCESS(Status))
01001     {
01002         BaseSetLastNTError(Status);
01003         return FALSE;
01004     }
01005 
01006     if (lpCreationTime)
01007     {
01008         lpCreationTime->dwLowDateTime = FileBasic.CreationTime.LowPart;
01009         lpCreationTime->dwHighDateTime = FileBasic.CreationTime.HighPart;
01010     }
01011 
01012     if (lpLastAccessTime)
01013     {
01014         lpLastAccessTime->dwLowDateTime = FileBasic.LastAccessTime.LowPart;
01015         lpLastAccessTime->dwHighDateTime = FileBasic.LastAccessTime.HighPart;
01016     }
01017 
01018     if (lpLastWriteTime)
01019     {
01020         lpLastWriteTime->dwLowDateTime = FileBasic.LastWriteTime.LowPart;
01021         lpLastWriteTime->dwHighDateTime = FileBasic.LastWriteTime.HighPart;
01022     }
01023 
01024     return TRUE;
01025 }
01026 
01027 
01028 /*
01029  * @implemented
01030  */
01031 BOOL WINAPI
01032 SetFileTime(IN HANDLE hFile,
01033             CONST FILETIME *lpCreationTime OPTIONAL,
01034             CONST FILETIME *lpLastAccessTime OPTIONAL,
01035             CONST FILETIME *lpLastWriteTime OPTIONAL)
01036 {
01037     NTSTATUS Status;
01038     IO_STATUS_BLOCK IoStatusBlock;
01039     FILE_BASIC_INFORMATION FileBasic;
01040 
01041     if(IsConsoleHandle(hFile))
01042     {
01043         BaseSetLastNTError(STATUS_INVALID_HANDLE);
01044         return FALSE;
01045     }
01046 
01047     memset(&FileBasic, 0, sizeof(FILE_BASIC_INFORMATION));
01048 
01049     if (lpCreationTime)
01050     {
01051         FileBasic.CreationTime.LowPart = lpCreationTime->dwLowDateTime;
01052         FileBasic.CreationTime.HighPart = lpCreationTime->dwHighDateTime;
01053     }
01054 
01055     if (lpLastAccessTime)
01056     {
01057         FileBasic.LastAccessTime.LowPart = lpLastAccessTime->dwLowDateTime;
01058         FileBasic.LastAccessTime.HighPart = lpLastAccessTime->dwHighDateTime;
01059     }
01060 
01061     if (lpLastWriteTime)
01062     {
01063         FileBasic.LastWriteTime.LowPart = lpLastWriteTime->dwLowDateTime;
01064         FileBasic.LastWriteTime.HighPart = lpLastWriteTime->dwHighDateTime;
01065     }
01066 
01067     Status = NtSetInformationFile(hFile,
01068                                   &IoStatusBlock,
01069                                   &FileBasic,
01070                                   sizeof(FILE_BASIC_INFORMATION),
01071                                   FileBasicInformation);
01072     if (!NT_SUCCESS(Status))
01073     {
01074         BaseSetLastNTError(Status);
01075         return FALSE;
01076     }
01077 
01078     return TRUE;
01079 }
01080 
01081 
01082 /*
01083  * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
01084  *
01085  * @implemented
01086  */
01087 BOOL WINAPI
01088 SetEndOfFile(HANDLE hFile)
01089 {
01090     IO_STATUS_BLOCK  IoStatusBlock;
01091     FILE_END_OF_FILE_INFORMATION    EndOfFileInfo;
01092     FILE_ALLOCATION_INFORMATION     FileAllocationInfo;
01093     FILE_POSITION_INFORMATION        FilePosInfo;
01094     NTSTATUS Status;
01095 
01096     if(IsConsoleHandle(hFile))
01097     {
01098         SetLastError(ERROR_INVALID_HANDLE);
01099         return FALSE;
01100     }
01101 
01102     //get current position
01103     Status = NtQueryInformationFile(
01104                     hFile,
01105                     &IoStatusBlock,
01106                     &FilePosInfo,
01107                     sizeof(FILE_POSITION_INFORMATION),
01108                     FilePositionInformation
01109                     );
01110 
01111     if (!NT_SUCCESS(Status)){
01112         BaseSetLastNTError(Status);
01113         return FALSE;
01114     }
01115 
01116     EndOfFileInfo.EndOfFile.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
01117 
01118     /*
01119     NOTE:
01120     This call is not supposed to free up any space after the eof marker
01121     if the file gets truncated. We have to deallocate the space explicitly afterwards.
01122     But...most file systems dispatch both FileEndOfFileInformation
01123     and FileAllocationInformation as they were the same command.
01124 
01125     */
01126     Status = NtSetInformationFile(
01127                         hFile,
01128                         &IoStatusBlock,  //out
01129                         &EndOfFileInfo,
01130                         sizeof(FILE_END_OF_FILE_INFORMATION),
01131                         FileEndOfFileInformation
01132                         );
01133 
01134     if (!NT_SUCCESS(Status)){
01135         BaseSetLastNTError(Status);
01136         return FALSE;
01137     }
01138 
01139     FileAllocationInfo.AllocationSize.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
01140 
01141 
01142     Status = NtSetInformationFile(
01143                         hFile,
01144                         &IoStatusBlock,  //out
01145                         &FileAllocationInfo,
01146                         sizeof(FILE_ALLOCATION_INFORMATION),
01147                         FileAllocationInformation
01148                         );
01149 
01150     if (!NT_SUCCESS(Status)){
01151         BaseSetLastNTError(Status);
01152         return FALSE;
01153     }
01154 
01155     return TRUE;
01156 
01157 }
01158 
01159 
01160 /*
01161  * @implemented
01162  */
01163 BOOL
01164 WINAPI
01165 SetFileValidData(
01166     HANDLE hFile,
01167     LONGLONG ValidDataLength
01168     )
01169 {
01170     IO_STATUS_BLOCK IoStatusBlock;
01171     FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation;
01172     NTSTATUS Status;
01173 
01174     ValidDataLengthInformation.ValidDataLength.QuadPart = ValidDataLength;
01175 
01176     Status = NtSetInformationFile(
01177                         hFile,
01178                         &IoStatusBlock,  //out
01179                         &ValidDataLengthInformation,
01180                         sizeof(FILE_VALID_DATA_LENGTH_INFORMATION),
01181                         FileValidDataLengthInformation
01182                         );
01183 
01184     if (!NT_SUCCESS(Status)){
01185         BaseSetLastNTError(Status);
01186         return FALSE;
01187     }
01188 
01189     return TRUE;
01190 }
01191 
01192 /* EOF */

Generated on Sun May 27 2012 04:24:26 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.