1 /* $Id: fileinfo.c 54326 2011-11-07 00:18:13Z ion $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/file/file.c
6 * PURPOSE: Directory functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
8 * Pierre Schweitzer (pierre.schweitzer@reactos.org)
13 /* INCLUDES *****************************************************************/
18 DEBUG_CHANNEL(kernel32file
);
20 /* FUNCTIONS ****************************************************************/
23 FilenameA2W(LPCSTR NameA
, BOOL alloc
)
27 PUNICODE_STRING pstrW
;
30 //ASSERT(NtCurrentTeb()->StaticUnicodeString.Buffer == NtCurrentTeb()->StaticUnicodeBuffer);
31 ASSERT(NtCurrentTeb()->StaticUnicodeString
.MaximumLength
== sizeof(NtCurrentTeb()->StaticUnicodeBuffer
));
33 RtlInitAnsiString(&str
, NameA
);
34 pstrW
= alloc
? &strW
: &NtCurrentTeb()->StaticUnicodeString
;
37 Status
= RtlAnsiStringToUnicodeString( pstrW
, &str
, (BOOLEAN
)alloc
);
39 Status
= RtlOemStringToUnicodeString( pstrW
, &str
, (BOOLEAN
)alloc
);
41 if (NT_SUCCESS(Status
))
44 if (Status
== STATUS_BUFFER_OVERFLOW
)
45 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
47 BaseSetLastNTError(Status
);
54 No copy/conversion is done if the dest. buffer is too small.
57 Success: number of TCHARS copied into dest. buffer NOT including nullterm
58 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
61 FilenameU2A_FitOrFail(
63 INT destLen
, /* buffer size in TCHARS incl. nullchar */
64 PUNICODE_STRING SourceU
69 /* destLen should never exceed MAX_PATH */
70 if (destLen
> MAX_PATH
) destLen
= MAX_PATH
;
72 ret
= bIsFileApiAnsi
? RtlUnicodeStringToAnsiSize(SourceU
) : RtlUnicodeStringToOemSize(SourceU
);
73 /* ret incl. nullchar */
75 if (DestA
&& (INT
)ret
<= destLen
)
80 str
.MaximumLength
= (USHORT
)destLen
;
84 RtlUnicodeStringToAnsiString(&str
, SourceU
, FALSE
);
86 RtlUnicodeStringToOemString(&str
, SourceU
, FALSE
);
88 ret
= str
.Length
; /* SUCCESS: length without terminating 0 */
96 No copy/conversion is done if the dest. buffer is too small.
99 Success: number of TCHARS copied into dest. buffer NOT including nullterm
100 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
103 FilenameW2A_FitOrFail(
105 INT destLen
, /* buffer size in TCHARS incl. nullchar */
107 INT sourceLen
/* buffer size in TCHARS incl. nullchar */
112 if (sourceLen
< 0) sourceLen
= wcslen(SourceW
) + 1;
114 strW
.Buffer
= (PWCHAR
)SourceW
;
115 strW
.MaximumLength
= sourceLen
* sizeof(WCHAR
);
116 strW
.Length
= strW
.MaximumLength
- sizeof(WCHAR
);
118 return FilenameU2A_FitOrFail(DestA
, destLen
, &strW
);
123 Return: num. TCHARS copied into dest including nullterm
128 INT destlen
, /* buffer size in TCHARS incl. nullchar */
130 INT srclen
/* buffer size in TCHARS incl. nullchar */
135 if (srclen
< 0) srclen
= strlen( src
) + 1;
138 RtlMultiByteToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
140 RtlOemToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
142 if (ret
) dest
[(ret
/sizeof(WCHAR
))-1]=0;
144 return ret
/sizeof(WCHAR
);
148 Return: num. TCHARS copied into dest including nullterm
153 INT destlen
, /* buffer size in TCHARS incl. nullchar */
155 INT srclen
/* buffer size in TCHARS incl. nullchar */
160 if (srclen
< 0) srclen
= wcslen( src
) + 1;
163 RtlUnicodeToMultiByteN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
));
165 RtlUnicodeToOemN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
) );
167 if (ret
) dest
[ret
-1]=0;
176 FlushFileBuffers(IN HANDLE hFile
)
179 IO_STATUS_BLOCK IoStatusBlock
;
181 hFile
= TranslateStdHandle(hFile
);
183 if (IsConsoleHandle(hFile
))
185 return FlushConsoleInputBuffer(hFile
);
188 Status
= NtFlushBuffersFile(hFile
,
190 if (!NT_SUCCESS(Status
))
192 BaseSetLastNTError(Status
);
203 SetFilePointer(HANDLE hFile
,
204 LONG lDistanceToMove
,
205 PLONG lpDistanceToMoveHigh
,
208 FILE_POSITION_INFORMATION FilePosition
;
209 FILE_STANDARD_INFORMATION FileStandard
;
211 IO_STATUS_BLOCK IoStatusBlock
;
212 LARGE_INTEGER Distance
;
214 TRACE("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
215 hFile
,lDistanceToMove
,dwMoveMethod
);
217 if(IsConsoleHandle(hFile
))
219 SetLastError(ERROR_INVALID_HANDLE
);
220 return INVALID_SET_FILE_POINTER
;
223 if (lpDistanceToMoveHigh
)
225 Distance
.u
.HighPart
= *lpDistanceToMoveHigh
;
226 Distance
.u
.LowPart
= lDistanceToMove
;
230 Distance
.QuadPart
= lDistanceToMove
;
236 errCode
= NtQueryInformationFile(hFile
,
239 sizeof(FILE_POSITION_INFORMATION
),
240 FilePositionInformation
);
241 FilePosition
.CurrentByteOffset
.QuadPart
+= Distance
.QuadPart
;
242 if (!NT_SUCCESS(errCode
))
244 if (lpDistanceToMoveHigh
!= NULL
)
245 *lpDistanceToMoveHigh
= -1;
246 BaseSetLastNTError(errCode
);
247 return INVALID_SET_FILE_POINTER
;
251 errCode
= NtQueryInformationFile(hFile
,
254 sizeof(FILE_STANDARD_INFORMATION
),
255 FileStandardInformation
);
256 FilePosition
.CurrentByteOffset
.QuadPart
=
257 FileStandard
.EndOfFile
.QuadPart
+ Distance
.QuadPart
;
258 if (!NT_SUCCESS(errCode
))
260 if (lpDistanceToMoveHigh
!= NULL
)
261 *lpDistanceToMoveHigh
= -1;
262 BaseSetLastNTError(errCode
);
263 return INVALID_SET_FILE_POINTER
;
267 FilePosition
.CurrentByteOffset
.QuadPart
= Distance
.QuadPart
;
270 SetLastError(ERROR_INVALID_PARAMETER
);
271 return INVALID_SET_FILE_POINTER
;
274 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
276 SetLastError(ERROR_NEGATIVE_SEEK
);
277 return INVALID_SET_FILE_POINTER
;
280 if (lpDistanceToMoveHigh
== NULL
&& FilePosition
.CurrentByteOffset
.HighPart
!= 0)
282 /* If we're moving the pointer outside of the 32 bit boundaries but
283 the application only passed a 32 bit value we need to bail out! */
284 SetLastError(ERROR_INVALID_PARAMETER
);
285 return INVALID_SET_FILE_POINTER
;
288 errCode
= NtSetInformationFile(hFile
,
291 sizeof(FILE_POSITION_INFORMATION
),
292 FilePositionInformation
);
293 if (!NT_SUCCESS(errCode
))
295 if (lpDistanceToMoveHigh
!= NULL
)
296 *lpDistanceToMoveHigh
= -1;
298 BaseSetLastNTError(errCode
);
299 return INVALID_SET_FILE_POINTER
;
302 if (lpDistanceToMoveHigh
!= NULL
)
304 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
307 if (FilePosition
.CurrentByteOffset
.u
.LowPart
== MAXDWORD
)
309 /* The value of -1 is valid here, especially when the new
310 file position is greater than 4 GB. Since NtSetInformationFile
311 succeeded we never set an error code and we explicitly need
312 to clear a previously set error code in this case, which
313 an application will check if INVALID_SET_FILE_POINTER is returned! */
314 SetLastError(ERROR_SUCCESS
);
317 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
326 SetFilePointerEx(HANDLE hFile
,
327 LARGE_INTEGER liDistanceToMove
,
328 PLARGE_INTEGER lpNewFilePointer
,
331 FILE_POSITION_INFORMATION FilePosition
;
332 FILE_STANDARD_INFORMATION FileStandard
;
334 IO_STATUS_BLOCK IoStatusBlock
;
336 if(IsConsoleHandle(hFile
))
338 SetLastError(ERROR_INVALID_HANDLE
);
345 NtQueryInformationFile(hFile
,
348 sizeof(FILE_POSITION_INFORMATION
),
349 FilePositionInformation
);
350 FilePosition
.CurrentByteOffset
.QuadPart
+= liDistanceToMove
.QuadPart
;
353 NtQueryInformationFile(hFile
,
356 sizeof(FILE_STANDARD_INFORMATION
),
357 FileStandardInformation
);
358 FilePosition
.CurrentByteOffset
.QuadPart
=
359 FileStandard
.EndOfFile
.QuadPart
+ liDistanceToMove
.QuadPart
;
362 FilePosition
.CurrentByteOffset
.QuadPart
= liDistanceToMove
.QuadPart
;
365 SetLastError(ERROR_INVALID_PARAMETER
);
369 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
371 SetLastError(ERROR_NEGATIVE_SEEK
);
375 errCode
= NtSetInformationFile(hFile
,
378 sizeof(FILE_POSITION_INFORMATION
),
379 FilePositionInformation
);
380 if (!NT_SUCCESS(errCode
))
382 BaseSetLastNTError(errCode
);
386 if (lpNewFilePointer
)
388 *lpNewFilePointer
= FilePosition
.CurrentByteOffset
;
398 GetFileType(HANDLE hFile
)
400 FILE_FS_DEVICE_INFORMATION DeviceInfo
;
401 IO_STATUS_BLOCK StatusBlock
;
404 /* Get real handle */
405 hFile
= TranslateStdHandle(hFile
);
407 /* Check for console handle */
408 if (IsConsoleHandle(hFile
))
410 if (VerifyConsoleIoHandle(hFile
))
411 return FILE_TYPE_CHAR
;
414 Status
= NtQueryVolumeInformationFile(hFile
,
417 sizeof(FILE_FS_DEVICE_INFORMATION
),
418 FileFsDeviceInformation
);
419 if (!NT_SUCCESS(Status
))
421 BaseSetLastNTError(Status
);
422 return FILE_TYPE_UNKNOWN
;
425 switch (DeviceInfo
.DeviceType
)
427 case FILE_DEVICE_CD_ROM
:
428 case FILE_DEVICE_CD_ROM_FILE_SYSTEM
:
429 case FILE_DEVICE_CONTROLLER
:
430 case FILE_DEVICE_DATALINK
:
431 case FILE_DEVICE_DFS
:
432 case FILE_DEVICE_DISK
:
433 case FILE_DEVICE_DISK_FILE_SYSTEM
:
434 case FILE_DEVICE_VIRTUAL_DISK
:
435 return FILE_TYPE_DISK
;
437 case FILE_DEVICE_KEYBOARD
:
438 case FILE_DEVICE_MOUSE
:
439 case FILE_DEVICE_NULL
:
440 case FILE_DEVICE_PARALLEL_PORT
:
441 case FILE_DEVICE_PRINTER
:
442 case FILE_DEVICE_SERIAL_PORT
:
443 case FILE_DEVICE_SCREEN
:
444 case FILE_DEVICE_SOUND
:
445 case FILE_DEVICE_MODEM
:
446 return FILE_TYPE_CHAR
;
448 case FILE_DEVICE_NAMED_PIPE
:
449 return FILE_TYPE_PIPE
;
452 return FILE_TYPE_UNKNOWN
;
460 GetFileSize(HANDLE hFile
,
461 LPDWORD lpFileSizeHigh
)
464 FILE_STANDARD_INFORMATION FileStandard
;
465 IO_STATUS_BLOCK IoStatusBlock
;
467 errCode
= NtQueryInformationFile(hFile
,
470 sizeof(FILE_STANDARD_INFORMATION
),
471 FileStandardInformation
);
472 if (!NT_SUCCESS(errCode
))
474 BaseSetLastNTError(errCode
);
475 if ( lpFileSizeHigh
== NULL
)
484 if ( lpFileSizeHigh
!= NULL
)
485 *lpFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
487 return FileStandard
.EndOfFile
.u
.LowPart
;
498 PLARGE_INTEGER lpFileSize
502 FILE_STANDARD_INFORMATION FileStandard
;
503 IO_STATUS_BLOCK IoStatusBlock
;
505 errCode
= NtQueryInformationFile(hFile
,
508 sizeof(FILE_STANDARD_INFORMATION
),
509 FileStandardInformation
);
510 if (!NT_SUCCESS(errCode
))
512 BaseSetLastNTError(errCode
);
516 *lpFileSize
= FileStandard
.EndOfFile
;
526 GetCompressedFileSizeA(LPCSTR lpFileName
,
527 LPDWORD lpFileSizeHigh
)
531 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
532 return INVALID_FILE_SIZE
;
534 return GetCompressedFileSizeW(FileNameW
, lpFileSizeHigh
);
542 GetCompressedFileSizeW(LPCWSTR lpFileName
,
543 LPDWORD lpFileSizeHigh
)
545 FILE_COMPRESSION_INFORMATION FileCompression
;
547 IO_STATUS_BLOCK IoStatusBlock
;
550 hFile
= CreateFileW(lpFileName
,
555 FILE_ATTRIBUTE_NORMAL
,
558 if (hFile
== INVALID_HANDLE_VALUE
)
559 return INVALID_FILE_SIZE
;
561 errCode
= NtQueryInformationFile(hFile
,
564 sizeof(FILE_COMPRESSION_INFORMATION
),
565 FileCompressionInformation
);
569 if (!NT_SUCCESS(errCode
))
571 BaseSetLastNTError(errCode
);
572 return INVALID_FILE_SIZE
;
576 *lpFileSizeHigh
= FileCompression
.CompressedFileSize
.u
.HighPart
;
578 SetLastError(NO_ERROR
);
579 return FileCompression
.CompressedFileSize
.u
.LowPart
;
587 GetFileInformationByHandle(HANDLE hFile
,
588 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
592 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
597 FILE_BASIC_INFORMATION FileBasic
;
598 FILE_INTERNAL_INFORMATION FileInternal
;
599 FILE_STANDARD_INFORMATION FileStandard
;
601 IO_STATUS_BLOCK IoStatusBlock
;
603 if(IsConsoleHandle(hFile
))
605 SetLastError(ERROR_INVALID_HANDLE
);
609 errCode
= NtQueryInformationFile(hFile
,
612 sizeof(FILE_BASIC_INFORMATION
),
613 FileBasicInformation
);
614 if (!NT_SUCCESS(errCode
))
616 BaseSetLastNTError(errCode
);
620 lpFileInformation
->dwFileAttributes
= (DWORD
)FileBasic
.FileAttributes
;
622 lpFileInformation
->ftCreationTime
.dwHighDateTime
= FileBasic
.CreationTime
.u
.HighPart
;
623 lpFileInformation
->ftCreationTime
.dwLowDateTime
= FileBasic
.CreationTime
.u
.LowPart
;
625 lpFileInformation
->ftLastAccessTime
.dwHighDateTime
= FileBasic
.LastAccessTime
.u
.HighPart
;
626 lpFileInformation
->ftLastAccessTime
.dwLowDateTime
= FileBasic
.LastAccessTime
.u
.LowPart
;
628 lpFileInformation
->ftLastWriteTime
.dwHighDateTime
= FileBasic
.LastWriteTime
.u
.HighPart
;
629 lpFileInformation
->ftLastWriteTime
.dwLowDateTime
= FileBasic
.LastWriteTime
.u
.LowPart
;
631 errCode
= NtQueryInformationFile(hFile
,
634 sizeof(FILE_INTERNAL_INFORMATION
),
635 FileInternalInformation
);
636 if (!NT_SUCCESS(errCode
))
638 BaseSetLastNTError(errCode
);
642 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
643 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
645 errCode
= NtQueryVolumeInformationFile(hFile
,
648 sizeof(FileFsVolume
),
649 FileFsVolumeInformation
);
650 if (!NT_SUCCESS(errCode
))
652 BaseSetLastNTError(errCode
);
656 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.FileFsVolume
.VolumeSerialNumber
;
658 errCode
= NtQueryInformationFile(hFile
,
661 sizeof(FILE_STANDARD_INFORMATION
),
662 FileStandardInformation
);
663 if (!NT_SUCCESS(errCode
))
665 BaseSetLastNTError(errCode
);
669 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
670 lpFileInformation
->nFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
671 lpFileInformation
->nFileSizeLow
= FileStandard
.EndOfFile
.u
.LowPart
;
681 GetFileAttributesExW(LPCWSTR lpFileName
,
682 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
683 LPVOID lpFileInformation
)
685 FILE_NETWORK_OPEN_INFORMATION FileInformation
;
686 OBJECT_ATTRIBUTES ObjectAttributes
;
687 UNICODE_STRING FileName
;
689 WIN32_FILE_ATTRIBUTE_DATA
* FileAttributeData
;
691 TRACE("GetFileAttributesExW(%S) called\n", lpFileName
);
694 if (fInfoLevelId
!= GetFileExInfoStandard
|| lpFileInformation
== NULL
)
696 SetLastError(ERROR_INVALID_PARAMETER
);
700 /* Validate and translate the filename */
701 if (!RtlDosPathNameToNtPathName_U (lpFileName
,
706 WARN ("Invalid path '%S'\n", lpFileName
);
707 SetLastError (ERROR_BAD_PATHNAME
);
711 /* build the object attributes */
712 InitializeObjectAttributes (&ObjectAttributes
,
714 OBJ_CASE_INSENSITIVE
,
718 /* Get file attributes */
719 Status
= NtQueryFullAttributesFile(&ObjectAttributes
,
722 RtlFreeUnicodeString (&FileName
);
723 if (!NT_SUCCESS (Status
))
725 WARN ("NtQueryFullAttributesFile() failed (Status %lx)\n", Status
);
726 BaseSetLastNTError (Status
);
730 FileAttributeData
= (WIN32_FILE_ATTRIBUTE_DATA
*)lpFileInformation
;
731 FileAttributeData
->dwFileAttributes
= FileInformation
.FileAttributes
;
732 FileAttributeData
->ftCreationTime
.dwLowDateTime
= FileInformation
.CreationTime
.u
.LowPart
;
733 FileAttributeData
->ftCreationTime
.dwHighDateTime
= FileInformation
.CreationTime
.u
.HighPart
;
734 FileAttributeData
->ftLastAccessTime
.dwLowDateTime
= FileInformation
.LastAccessTime
.u
.LowPart
;
735 FileAttributeData
->ftLastAccessTime
.dwHighDateTime
= FileInformation
.LastAccessTime
.u
.HighPart
;
736 FileAttributeData
->ftLastWriteTime
.dwLowDateTime
= FileInformation
.LastWriteTime
.u
.LowPart
;
737 FileAttributeData
->ftLastWriteTime
.dwHighDateTime
= FileInformation
.LastWriteTime
.u
.HighPart
;
738 FileAttributeData
->nFileSizeLow
= FileInformation
.EndOfFile
.u
.LowPart
;
739 FileAttributeData
->nFileSizeHigh
= FileInformation
.EndOfFile
.u
.HighPart
;
748 GetFileAttributesExA(LPCSTR lpFileName
,
749 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
750 LPVOID lpFileInformation
)
754 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
757 return GetFileAttributesExW(FileNameW
, fInfoLevelId
, lpFileInformation
);
765 GetFileAttributesA(LPCSTR lpFileName
)
767 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
771 if (!lpFileName
|| !(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
772 return INVALID_FILE_ATTRIBUTES
;
774 ret
= GetFileAttributesExW(FileNameW
, GetFileExInfoStandard
, &FileAttributeData
);
776 return ret
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
784 GetFileAttributesW(LPCWSTR lpFileName
)
786 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
789 TRACE ("GetFileAttributeW(%S) called\n", lpFileName
);
791 Result
= GetFileAttributesExW(lpFileName
, GetFileExInfoStandard
, &FileAttributeData
);
793 return Result
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
801 GetFileAttributesByHandle(IN HANDLE hFile
,
802 OUT LPDWORD dwFileAttributes
,
805 FILE_BASIC_INFORMATION FileBasic
;
806 IO_STATUS_BLOCK IoStatusBlock
;
809 UNREFERENCED_PARAMETER(dwFlags
);
811 if (IsConsoleHandle(hFile
))
813 SetLastError(ERROR_INVALID_HANDLE
);
817 Status
= NtQueryInformationFile(hFile
,
821 FileBasicInformation
);
822 if (NT_SUCCESS(Status
))
824 *dwFileAttributes
= FileBasic
.FileAttributes
;
828 BaseSetLastNTError(Status
);
837 SetFileAttributesByHandle(IN HANDLE hFile
,
838 IN DWORD dwFileAttributes
,
841 FILE_BASIC_INFORMATION FileBasic
;
842 IO_STATUS_BLOCK IoStatusBlock
;
845 UNREFERENCED_PARAMETER(dwFlags
);
847 if (IsConsoleHandle(hFile
))
849 SetLastError(ERROR_INVALID_HANDLE
);
853 Status
= NtQueryInformationFile(hFile
,
857 FileBasicInformation
);
858 if (NT_SUCCESS(Status
))
860 FileBasic
.FileAttributes
= dwFileAttributes
;
862 Status
= NtSetInformationFile(hFile
,
866 FileBasicInformation
);
869 if (!NT_SUCCESS(Status
))
871 BaseSetLastNTError(Status
);
885 DWORD dwFileAttributes
)
889 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
892 return SetFileAttributesW(FileNameW
, dwFileAttributes
);
900 SetFileAttributesW(LPCWSTR lpFileName
,
901 DWORD dwFileAttributes
)
903 FILE_BASIC_INFORMATION FileInformation
;
904 OBJECT_ATTRIBUTES ObjectAttributes
;
905 IO_STATUS_BLOCK IoStatusBlock
;
906 UNICODE_STRING FileName
;
910 TRACE ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName
, dwFileAttributes
);
912 /* Validate and translate the filename */
913 if (!RtlDosPathNameToNtPathName_U (lpFileName
,
918 WARN ("Invalid path\n");
919 SetLastError (ERROR_BAD_PATHNAME
);
922 TRACE ("FileName: \'%wZ\'\n", &FileName
);
924 /* build the object attributes */
925 InitializeObjectAttributes (&ObjectAttributes
,
927 OBJ_CASE_INSENSITIVE
,
932 Status
= NtOpenFile (&FileHandle
,
933 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
936 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
937 FILE_SYNCHRONOUS_IO_NONALERT
);
938 RtlFreeUnicodeString (&FileName
);
939 if (!NT_SUCCESS (Status
))
941 WARN ("NtOpenFile() failed (Status %lx)\n", Status
);
942 BaseSetLastNTError (Status
);
946 Status
= NtQueryInformationFile(FileHandle
,
949 sizeof(FILE_BASIC_INFORMATION
),
950 FileBasicInformation
);
951 if (!NT_SUCCESS(Status
))
953 WARN ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status
);
954 NtClose (FileHandle
);
955 BaseSetLastNTError (Status
);
959 FileInformation
.FileAttributes
= dwFileAttributes
;
960 Status
= NtSetInformationFile(FileHandle
,
963 sizeof(FILE_BASIC_INFORMATION
),
964 FileBasicInformation
);
965 NtClose (FileHandle
);
966 if (!NT_SUCCESS(Status
))
968 WARN ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status
);
969 BaseSetLastNTError (Status
);
980 GetFileTime(IN HANDLE hFile
,
981 OUT LPFILETIME lpCreationTime OPTIONAL
,
982 OUT LPFILETIME lpLastAccessTime OPTIONAL
,
983 OUT LPFILETIME lpLastWriteTime OPTIONAL
)
986 IO_STATUS_BLOCK IoStatusBlock
;
987 FILE_BASIC_INFORMATION FileBasic
;
989 if(IsConsoleHandle(hFile
))
991 BaseSetLastNTError(STATUS_INVALID_HANDLE
);
995 Status
= NtQueryInformationFile(hFile
,
998 sizeof(FILE_BASIC_INFORMATION
),
999 FileBasicInformation
);
1000 if (!NT_SUCCESS(Status
))
1002 BaseSetLastNTError(Status
);
1008 lpCreationTime
->dwLowDateTime
= FileBasic
.CreationTime
.LowPart
;
1009 lpCreationTime
->dwHighDateTime
= FileBasic
.CreationTime
.HighPart
;
1012 if (lpLastAccessTime
)
1014 lpLastAccessTime
->dwLowDateTime
= FileBasic
.LastAccessTime
.LowPart
;
1015 lpLastAccessTime
->dwHighDateTime
= FileBasic
.LastAccessTime
.HighPart
;
1018 if (lpLastWriteTime
)
1020 lpLastWriteTime
->dwLowDateTime
= FileBasic
.LastWriteTime
.LowPart
;
1021 lpLastWriteTime
->dwHighDateTime
= FileBasic
.LastWriteTime
.HighPart
;
1032 SetFileTime(IN HANDLE hFile
,
1033 CONST FILETIME
*lpCreationTime OPTIONAL
,
1034 CONST FILETIME
*lpLastAccessTime OPTIONAL
,
1035 CONST FILETIME
*lpLastWriteTime OPTIONAL
)
1038 IO_STATUS_BLOCK IoStatusBlock
;
1039 FILE_BASIC_INFORMATION FileBasic
;
1041 if(IsConsoleHandle(hFile
))
1043 BaseSetLastNTError(STATUS_INVALID_HANDLE
);
1047 memset(&FileBasic
, 0, sizeof(FILE_BASIC_INFORMATION
));
1051 FileBasic
.CreationTime
.LowPart
= lpCreationTime
->dwLowDateTime
;
1052 FileBasic
.CreationTime
.HighPart
= lpCreationTime
->dwHighDateTime
;
1055 if (lpLastAccessTime
)
1057 FileBasic
.LastAccessTime
.LowPart
= lpLastAccessTime
->dwLowDateTime
;
1058 FileBasic
.LastAccessTime
.HighPart
= lpLastAccessTime
->dwHighDateTime
;
1061 if (lpLastWriteTime
)
1063 FileBasic
.LastWriteTime
.LowPart
= lpLastWriteTime
->dwLowDateTime
;
1064 FileBasic
.LastWriteTime
.HighPart
= lpLastWriteTime
->dwHighDateTime
;
1067 Status
= NtSetInformationFile(hFile
,
1070 sizeof(FILE_BASIC_INFORMATION
),
1071 FileBasicInformation
);
1072 if (!NT_SUCCESS(Status
))
1074 BaseSetLastNTError(Status
);
1083 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
1088 SetEndOfFile(HANDLE hFile
)
1090 IO_STATUS_BLOCK IoStatusBlock
;
1091 FILE_END_OF_FILE_INFORMATION EndOfFileInfo
;
1092 FILE_ALLOCATION_INFORMATION FileAllocationInfo
;
1093 FILE_POSITION_INFORMATION FilePosInfo
;
1096 if(IsConsoleHandle(hFile
))
1098 SetLastError(ERROR_INVALID_HANDLE
);
1102 //get current position
1103 Status
= NtQueryInformationFile(
1107 sizeof(FILE_POSITION_INFORMATION
),
1108 FilePositionInformation
1111 if (!NT_SUCCESS(Status
)){
1112 BaseSetLastNTError(Status
);
1116 EndOfFileInfo
.EndOfFile
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1120 This call is not supposed to free up any space after the eof marker
1121 if the file gets truncated. We have to deallocate the space explicitly afterwards.
1122 But...most file systems dispatch both FileEndOfFileInformation
1123 and FileAllocationInformation as they were the same command.
1126 Status
= NtSetInformationFile(
1128 &IoStatusBlock
, //out
1130 sizeof(FILE_END_OF_FILE_INFORMATION
),
1131 FileEndOfFileInformation
1134 if (!NT_SUCCESS(Status
)){
1135 BaseSetLastNTError(Status
);
1139 FileAllocationInfo
.AllocationSize
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1142 Status
= NtSetInformationFile(
1144 &IoStatusBlock
, //out
1145 &FileAllocationInfo
,
1146 sizeof(FILE_ALLOCATION_INFORMATION
),
1147 FileAllocationInformation
1150 if (!NT_SUCCESS(Status
)){
1151 BaseSetLastNTError(Status
);
1167 LONGLONG ValidDataLength
1170 IO_STATUS_BLOCK IoStatusBlock
;
1171 FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation
;
1174 ValidDataLengthInformation
.ValidDataLength
.QuadPart
= ValidDataLength
;
1176 Status
= NtSetInformationFile(
1178 &IoStatusBlock
, //out
1179 &ValidDataLengthInformation
,
1180 sizeof(FILE_VALID_DATA_LENGTH_INFORMATION
),
1181 FileValidDataLengthInformation
1184 if (!NT_SUCCESS(Status
)){
1185 BaseSetLastNTError(Status
);