2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/file/file.c
5 * PURPOSE: Directory functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 * Pierre Schweitzer (pierre.schweitzer@reactos.org)
12 /* INCLUDES *****************************************************************/
17 DEBUG_CHANNEL(kernel32file
);
19 /* FUNCTIONS ****************************************************************/
22 FilenameA2W(LPCSTR NameA
, BOOL alloc
)
26 PUNICODE_STRING pstrW
;
29 //ASSERT(NtCurrentTeb()->StaticUnicodeString.Buffer == NtCurrentTeb()->StaticUnicodeBuffer);
30 ASSERT(NtCurrentTeb()->StaticUnicodeString
.MaximumLength
== sizeof(NtCurrentTeb()->StaticUnicodeBuffer
));
32 RtlInitAnsiString(&str
, NameA
);
33 pstrW
= alloc
? &strW
: &NtCurrentTeb()->StaticUnicodeString
;
36 Status
= RtlAnsiStringToUnicodeString( pstrW
, &str
, (BOOLEAN
)alloc
);
38 Status
= RtlOemStringToUnicodeString( pstrW
, &str
, (BOOLEAN
)alloc
);
40 if (NT_SUCCESS(Status
))
43 if (Status
== STATUS_BUFFER_OVERFLOW
)
44 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
46 BaseSetLastNTError(Status
);
53 No copy/conversion is done if the dest. buffer is too small.
56 Success: number of TCHARS copied into dest. buffer NOT including nullterm
57 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
60 FilenameU2A_FitOrFail(
62 INT destLen
, /* buffer size in TCHARS incl. nullchar */
63 PUNICODE_STRING SourceU
68 /* destLen should never exceed MAX_PATH */
69 if (destLen
> MAX_PATH
) destLen
= MAX_PATH
;
71 ret
= bIsFileApiAnsi
? RtlUnicodeStringToAnsiSize(SourceU
) : RtlUnicodeStringToOemSize(SourceU
);
72 /* ret incl. nullchar */
74 if (DestA
&& (INT
)ret
<= destLen
)
79 str
.MaximumLength
= (USHORT
)destLen
;
83 RtlUnicodeStringToAnsiString(&str
, SourceU
, FALSE
);
85 RtlUnicodeStringToOemString(&str
, SourceU
, FALSE
);
87 ret
= str
.Length
; /* SUCCESS: length without terminating 0 */
95 No copy/conversion is done if the dest. buffer is too small.
98 Success: number of TCHARS copied into dest. buffer NOT including nullterm
99 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
102 FilenameW2A_FitOrFail(
104 INT destLen
, /* buffer size in TCHARS incl. nullchar */
106 INT sourceLen
/* buffer size in TCHARS incl. nullchar */
111 if (sourceLen
< 0) sourceLen
= wcslen(SourceW
) + 1;
113 strW
.Buffer
= (PWCHAR
)SourceW
;
114 strW
.MaximumLength
= sourceLen
* sizeof(WCHAR
);
115 strW
.Length
= strW
.MaximumLength
- sizeof(WCHAR
);
117 return FilenameU2A_FitOrFail(DestA
, destLen
, &strW
);
122 Return: num. TCHARS copied into dest including nullterm
127 INT destlen
, /* buffer size in TCHARS incl. nullchar */
129 INT srclen
/* buffer size in TCHARS incl. nullchar */
134 if (srclen
< 0) srclen
= strlen( src
) + 1;
137 RtlMultiByteToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
139 RtlOemToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
141 if (ret
) dest
[(ret
/sizeof(WCHAR
))-1]=0;
143 return ret
/sizeof(WCHAR
);
147 Return: num. TCHARS copied into dest including nullterm
152 INT destlen
, /* buffer size in TCHARS incl. nullchar */
154 INT srclen
/* buffer size in TCHARS incl. nullchar */
159 if (srclen
< 0) srclen
= wcslen( src
) + 1;
162 RtlUnicodeToMultiByteN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
));
164 RtlUnicodeToOemN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
) );
166 if (ret
) dest
[ret
-1]=0;
175 FlushFileBuffers(IN HANDLE hFile
)
178 IO_STATUS_BLOCK IoStatusBlock
;
180 hFile
= TranslateStdHandle(hFile
);
182 if (IsConsoleHandle(hFile
))
184 return FlushConsoleInputBuffer(hFile
);
187 Status
= NtFlushBuffersFile(hFile
,
189 if (!NT_SUCCESS(Status
))
191 BaseSetLastNTError(Status
);
204 SetFilePointer(HANDLE hFile
,
205 LONG lDistanceToMove
,
206 PLONG lpDistanceToMoveHigh
,
209 FILE_POSITION_INFORMATION FilePosition
;
210 FILE_STANDARD_INFORMATION FileStandard
;
212 IO_STATUS_BLOCK IoStatusBlock
;
213 LARGE_INTEGER Distance
;
215 TRACE("SetFilePointer(hFile %p, lDistanceToMove %d, dwMoveMethod %lu)\n",
216 hFile
,lDistanceToMove
,dwMoveMethod
);
218 if(IsConsoleHandle(hFile
))
220 SetLastError(ERROR_INVALID_HANDLE
);
221 return INVALID_SET_FILE_POINTER
;
224 if (lpDistanceToMoveHigh
)
226 Distance
.u
.HighPart
= *lpDistanceToMoveHigh
;
227 Distance
.u
.LowPart
= lDistanceToMove
;
231 Distance
.QuadPart
= lDistanceToMove
;
237 errCode
= NtQueryInformationFile(hFile
,
240 sizeof(FILE_POSITION_INFORMATION
),
241 FilePositionInformation
);
242 FilePosition
.CurrentByteOffset
.QuadPart
+= Distance
.QuadPart
;
243 if (!NT_SUCCESS(errCode
))
245 if (lpDistanceToMoveHigh
!= NULL
)
246 *lpDistanceToMoveHigh
= -1;
247 BaseSetLastNTError(errCode
);
248 return INVALID_SET_FILE_POINTER
;
252 errCode
= NtQueryInformationFile(hFile
,
255 sizeof(FILE_STANDARD_INFORMATION
),
256 FileStandardInformation
);
257 FilePosition
.CurrentByteOffset
.QuadPart
=
258 FileStandard
.EndOfFile
.QuadPart
+ Distance
.QuadPart
;
259 if (!NT_SUCCESS(errCode
))
261 if (lpDistanceToMoveHigh
!= NULL
)
262 *lpDistanceToMoveHigh
= -1;
263 BaseSetLastNTError(errCode
);
264 return INVALID_SET_FILE_POINTER
;
268 FilePosition
.CurrentByteOffset
.QuadPart
= Distance
.QuadPart
;
271 SetLastError(ERROR_INVALID_PARAMETER
);
272 return INVALID_SET_FILE_POINTER
;
275 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
277 SetLastError(ERROR_NEGATIVE_SEEK
);
278 return INVALID_SET_FILE_POINTER
;
281 if (lpDistanceToMoveHigh
== NULL
&& FilePosition
.CurrentByteOffset
.HighPart
!= 0)
283 /* If we're moving the pointer outside of the 32 bit boundaries but
284 the application only passed a 32 bit value we need to bail out! */
285 SetLastError(ERROR_INVALID_PARAMETER
);
286 return INVALID_SET_FILE_POINTER
;
289 errCode
= NtSetInformationFile(hFile
,
292 sizeof(FILE_POSITION_INFORMATION
),
293 FilePositionInformation
);
294 if (!NT_SUCCESS(errCode
))
296 if (lpDistanceToMoveHigh
!= NULL
)
297 *lpDistanceToMoveHigh
= -1;
299 BaseSetLastNTError(errCode
);
300 return INVALID_SET_FILE_POINTER
;
303 if (lpDistanceToMoveHigh
!= NULL
)
305 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
308 if (FilePosition
.CurrentByteOffset
.u
.LowPart
== MAXDWORD
)
310 /* The value of -1 is valid here, especially when the new
311 file position is greater than 4 GB. Since NtSetInformationFile
312 succeeded we never set an error code and we explicitly need
313 to clear a previously set error code in this case, which
314 an application will check if INVALID_SET_FILE_POINTER is returned! */
315 SetLastError(ERROR_SUCCESS
);
318 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
327 SetFilePointerEx(HANDLE hFile
,
328 LARGE_INTEGER liDistanceToMove
,
329 PLARGE_INTEGER lpNewFilePointer
,
332 FILE_POSITION_INFORMATION FilePosition
;
333 FILE_STANDARD_INFORMATION FileStandard
;
335 IO_STATUS_BLOCK IoStatusBlock
;
337 if(IsConsoleHandle(hFile
))
339 SetLastError(ERROR_INVALID_HANDLE
);
346 NtQueryInformationFile(hFile
,
349 sizeof(FILE_POSITION_INFORMATION
),
350 FilePositionInformation
);
351 FilePosition
.CurrentByteOffset
.QuadPart
+= liDistanceToMove
.QuadPart
;
354 NtQueryInformationFile(hFile
,
357 sizeof(FILE_STANDARD_INFORMATION
),
358 FileStandardInformation
);
359 FilePosition
.CurrentByteOffset
.QuadPart
=
360 FileStandard
.EndOfFile
.QuadPart
+ liDistanceToMove
.QuadPart
;
363 FilePosition
.CurrentByteOffset
.QuadPart
= liDistanceToMove
.QuadPart
;
366 SetLastError(ERROR_INVALID_PARAMETER
);
370 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
372 SetLastError(ERROR_NEGATIVE_SEEK
);
376 errCode
= NtSetInformationFile(hFile
,
379 sizeof(FILE_POSITION_INFORMATION
),
380 FilePositionInformation
);
381 if (!NT_SUCCESS(errCode
))
383 BaseSetLastNTError(errCode
);
387 if (lpNewFilePointer
)
389 *lpNewFilePointer
= FilePosition
.CurrentByteOffset
;
399 GetFileType(HANDLE hFile
)
401 FILE_FS_DEVICE_INFORMATION DeviceInfo
;
402 IO_STATUS_BLOCK StatusBlock
;
405 /* Get real handle */
406 hFile
= TranslateStdHandle(hFile
);
408 /* Check for console handle */
409 if (IsConsoleHandle(hFile
))
411 if (VerifyConsoleIoHandle(hFile
))
412 return FILE_TYPE_CHAR
;
415 Status
= NtQueryVolumeInformationFile(hFile
,
418 sizeof(FILE_FS_DEVICE_INFORMATION
),
419 FileFsDeviceInformation
);
420 if (!NT_SUCCESS(Status
))
422 BaseSetLastNTError(Status
);
423 return FILE_TYPE_UNKNOWN
;
426 switch (DeviceInfo
.DeviceType
)
428 case FILE_DEVICE_CD_ROM
:
429 case FILE_DEVICE_CD_ROM_FILE_SYSTEM
:
430 case FILE_DEVICE_CONTROLLER
:
431 case FILE_DEVICE_DATALINK
:
432 case FILE_DEVICE_DFS
:
433 case FILE_DEVICE_DISK
:
434 case FILE_DEVICE_DISK_FILE_SYSTEM
:
435 case FILE_DEVICE_VIRTUAL_DISK
:
436 return FILE_TYPE_DISK
;
438 case FILE_DEVICE_KEYBOARD
:
439 case FILE_DEVICE_MOUSE
:
440 case FILE_DEVICE_NULL
:
441 case FILE_DEVICE_PARALLEL_PORT
:
442 case FILE_DEVICE_PRINTER
:
443 case FILE_DEVICE_SERIAL_PORT
:
444 case FILE_DEVICE_SCREEN
:
445 case FILE_DEVICE_SOUND
:
446 case FILE_DEVICE_MODEM
:
447 return FILE_TYPE_CHAR
;
449 case FILE_DEVICE_NAMED_PIPE
:
450 return FILE_TYPE_PIPE
;
453 return FILE_TYPE_UNKNOWN
;
461 GetFileSize(HANDLE hFile
,
462 LPDWORD lpFileSizeHigh
)
465 FILE_STANDARD_INFORMATION FileStandard
;
466 IO_STATUS_BLOCK IoStatusBlock
;
468 errCode
= NtQueryInformationFile(hFile
,
471 sizeof(FILE_STANDARD_INFORMATION
),
472 FileStandardInformation
);
473 if (!NT_SUCCESS(errCode
))
475 BaseSetLastNTError(errCode
);
476 if ( lpFileSizeHigh
== NULL
)
485 if ( lpFileSizeHigh
!= NULL
)
486 *lpFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
488 return FileStandard
.EndOfFile
.u
.LowPart
;
499 PLARGE_INTEGER lpFileSize
503 FILE_STANDARD_INFORMATION FileStandard
;
504 IO_STATUS_BLOCK IoStatusBlock
;
506 errCode
= NtQueryInformationFile(hFile
,
509 sizeof(FILE_STANDARD_INFORMATION
),
510 FileStandardInformation
);
511 if (!NT_SUCCESS(errCode
))
513 BaseSetLastNTError(errCode
);
517 *lpFileSize
= FileStandard
.EndOfFile
;
527 GetCompressedFileSizeA(LPCSTR lpFileName
,
528 LPDWORD lpFileSizeHigh
)
532 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
533 return INVALID_FILE_SIZE
;
535 return GetCompressedFileSizeW(FileNameW
, lpFileSizeHigh
);
543 GetCompressedFileSizeW(LPCWSTR lpFileName
,
544 LPDWORD lpFileSizeHigh
)
546 FILE_COMPRESSION_INFORMATION FileCompression
;
548 IO_STATUS_BLOCK IoStatusBlock
;
551 hFile
= CreateFileW(lpFileName
,
556 FILE_ATTRIBUTE_NORMAL
,
559 if (hFile
== INVALID_HANDLE_VALUE
)
560 return INVALID_FILE_SIZE
;
562 errCode
= NtQueryInformationFile(hFile
,
565 sizeof(FILE_COMPRESSION_INFORMATION
),
566 FileCompressionInformation
);
570 if (!NT_SUCCESS(errCode
))
572 BaseSetLastNTError(errCode
);
573 return INVALID_FILE_SIZE
;
577 *lpFileSizeHigh
= FileCompression
.CompressedFileSize
.u
.HighPart
;
579 SetLastError(NO_ERROR
);
580 return FileCompression
.CompressedFileSize
.u
.LowPart
;
588 GetFileInformationByHandle(HANDLE hFile
,
589 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
593 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
598 FILE_BASIC_INFORMATION FileBasic
;
599 FILE_INTERNAL_INFORMATION FileInternal
;
600 FILE_STANDARD_INFORMATION FileStandard
;
602 IO_STATUS_BLOCK IoStatusBlock
;
604 if(IsConsoleHandle(hFile
))
606 SetLastError(ERROR_INVALID_HANDLE
);
610 errCode
= NtQueryInformationFile(hFile
,
613 sizeof(FILE_BASIC_INFORMATION
),
614 FileBasicInformation
);
615 if (!NT_SUCCESS(errCode
))
617 BaseSetLastNTError(errCode
);
621 lpFileInformation
->dwFileAttributes
= (DWORD
)FileBasic
.FileAttributes
;
623 lpFileInformation
->ftCreationTime
.dwHighDateTime
= FileBasic
.CreationTime
.u
.HighPart
;
624 lpFileInformation
->ftCreationTime
.dwLowDateTime
= FileBasic
.CreationTime
.u
.LowPart
;
626 lpFileInformation
->ftLastAccessTime
.dwHighDateTime
= FileBasic
.LastAccessTime
.u
.HighPart
;
627 lpFileInformation
->ftLastAccessTime
.dwLowDateTime
= FileBasic
.LastAccessTime
.u
.LowPart
;
629 lpFileInformation
->ftLastWriteTime
.dwHighDateTime
= FileBasic
.LastWriteTime
.u
.HighPart
;
630 lpFileInformation
->ftLastWriteTime
.dwLowDateTime
= FileBasic
.LastWriteTime
.u
.LowPart
;
632 errCode
= NtQueryInformationFile(hFile
,
635 sizeof(FILE_INTERNAL_INFORMATION
),
636 FileInternalInformation
);
637 if (!NT_SUCCESS(errCode
))
639 BaseSetLastNTError(errCode
);
643 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
644 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
646 errCode
= NtQueryVolumeInformationFile(hFile
,
649 sizeof(FileFsVolume
),
650 FileFsVolumeInformation
);
651 if (!NT_SUCCESS(errCode
))
653 BaseSetLastNTError(errCode
);
657 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.FileFsVolume
.VolumeSerialNumber
;
659 errCode
= NtQueryInformationFile(hFile
,
662 sizeof(FILE_STANDARD_INFORMATION
),
663 FileStandardInformation
);
664 if (!NT_SUCCESS(errCode
))
666 BaseSetLastNTError(errCode
);
670 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
671 lpFileInformation
->nFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
672 lpFileInformation
->nFileSizeLow
= FileStandard
.EndOfFile
.u
.LowPart
;
682 GetFileAttributesExW(LPCWSTR lpFileName
,
683 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
684 LPVOID lpFileInformation
)
686 FILE_NETWORK_OPEN_INFORMATION FileInformation
;
687 OBJECT_ATTRIBUTES ObjectAttributes
;
688 UNICODE_STRING FileName
;
690 WIN32_FILE_ATTRIBUTE_DATA
* FileAttributeData
;
692 TRACE("GetFileAttributesExW(%S) called\n", lpFileName
);
695 if (fInfoLevelId
!= GetFileExInfoStandard
|| lpFileInformation
== NULL
)
697 SetLastError(ERROR_INVALID_PARAMETER
);
701 /* Validate and translate the filename */
702 if (!RtlDosPathNameToNtPathName_U (lpFileName
,
707 WARN ("Invalid path '%S'\n", lpFileName
);
708 SetLastError (ERROR_BAD_PATHNAME
);
712 /* build the object attributes */
713 InitializeObjectAttributes (&ObjectAttributes
,
715 OBJ_CASE_INSENSITIVE
,
719 /* Get file attributes */
720 Status
= NtQueryFullAttributesFile(&ObjectAttributes
,
723 RtlFreeUnicodeString (&FileName
);
724 if (!NT_SUCCESS (Status
))
726 WARN ("NtQueryFullAttributesFile() failed (Status %lx)\n", Status
);
727 BaseSetLastNTError (Status
);
731 FileAttributeData
= (WIN32_FILE_ATTRIBUTE_DATA
*)lpFileInformation
;
732 FileAttributeData
->dwFileAttributes
= FileInformation
.FileAttributes
;
733 FileAttributeData
->ftCreationTime
.dwLowDateTime
= FileInformation
.CreationTime
.u
.LowPart
;
734 FileAttributeData
->ftCreationTime
.dwHighDateTime
= FileInformation
.CreationTime
.u
.HighPart
;
735 FileAttributeData
->ftLastAccessTime
.dwLowDateTime
= FileInformation
.LastAccessTime
.u
.LowPart
;
736 FileAttributeData
->ftLastAccessTime
.dwHighDateTime
= FileInformation
.LastAccessTime
.u
.HighPart
;
737 FileAttributeData
->ftLastWriteTime
.dwLowDateTime
= FileInformation
.LastWriteTime
.u
.LowPart
;
738 FileAttributeData
->ftLastWriteTime
.dwHighDateTime
= FileInformation
.LastWriteTime
.u
.HighPart
;
739 FileAttributeData
->nFileSizeLow
= FileInformation
.EndOfFile
.u
.LowPart
;
740 FileAttributeData
->nFileSizeHigh
= FileInformation
.EndOfFile
.u
.HighPart
;
749 GetFileAttributesExA(LPCSTR lpFileName
,
750 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
751 LPVOID lpFileInformation
)
755 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
758 return GetFileAttributesExW(FileNameW
, fInfoLevelId
, lpFileInformation
);
766 GetFileAttributesA(LPCSTR lpFileName
)
768 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
772 if (!lpFileName
|| !(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
773 return INVALID_FILE_ATTRIBUTES
;
775 ret
= GetFileAttributesExW(FileNameW
, GetFileExInfoStandard
, &FileAttributeData
);
777 return ret
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
785 GetFileAttributesW(LPCWSTR lpFileName
)
787 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
790 TRACE ("GetFileAttributeW(%S) called\n", lpFileName
);
792 Result
= GetFileAttributesExW(lpFileName
, GetFileExInfoStandard
, &FileAttributeData
);
794 return Result
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
802 GetFileAttributesByHandle(IN HANDLE hFile
,
803 OUT LPDWORD dwFileAttributes
,
806 FILE_BASIC_INFORMATION FileBasic
;
807 IO_STATUS_BLOCK IoStatusBlock
;
810 UNREFERENCED_PARAMETER(dwFlags
);
812 if (IsConsoleHandle(hFile
))
814 SetLastError(ERROR_INVALID_HANDLE
);
818 Status
= NtQueryInformationFile(hFile
,
822 FileBasicInformation
);
823 if (NT_SUCCESS(Status
))
825 *dwFileAttributes
= FileBasic
.FileAttributes
;
829 BaseSetLastNTError(Status
);
838 SetFileAttributesByHandle(IN HANDLE hFile
,
839 IN DWORD dwFileAttributes
,
842 FILE_BASIC_INFORMATION FileBasic
;
843 IO_STATUS_BLOCK IoStatusBlock
;
846 UNREFERENCED_PARAMETER(dwFlags
);
848 if (IsConsoleHandle(hFile
))
850 SetLastError(ERROR_INVALID_HANDLE
);
854 Status
= NtQueryInformationFile(hFile
,
858 FileBasicInformation
);
859 if (NT_SUCCESS(Status
))
861 FileBasic
.FileAttributes
= dwFileAttributes
;
863 Status
= NtSetInformationFile(hFile
,
867 FileBasicInformation
);
870 if (!NT_SUCCESS(Status
))
872 BaseSetLastNTError(Status
);
886 DWORD dwFileAttributes
)
890 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
893 return SetFileAttributesW(FileNameW
, dwFileAttributes
);
901 SetFileAttributesW(LPCWSTR lpFileName
,
902 DWORD dwFileAttributes
)
904 FILE_BASIC_INFORMATION FileInformation
;
905 OBJECT_ATTRIBUTES ObjectAttributes
;
906 IO_STATUS_BLOCK IoStatusBlock
;
907 UNICODE_STRING FileName
;
911 TRACE ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName
, dwFileAttributes
);
913 /* Validate and translate the filename */
914 if (!RtlDosPathNameToNtPathName_U (lpFileName
,
919 WARN ("Invalid path\n");
920 SetLastError (ERROR_BAD_PATHNAME
);
923 TRACE ("FileName: \'%wZ\'\n", &FileName
);
925 /* build the object attributes */
926 InitializeObjectAttributes (&ObjectAttributes
,
928 OBJ_CASE_INSENSITIVE
,
933 Status
= NtOpenFile (&FileHandle
,
934 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
937 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
938 FILE_SYNCHRONOUS_IO_NONALERT
);
939 RtlFreeUnicodeString (&FileName
);
940 if (!NT_SUCCESS (Status
))
942 WARN ("NtOpenFile() failed (Status %lx)\n", Status
);
943 BaseSetLastNTError (Status
);
947 Status
= NtQueryInformationFile(FileHandle
,
950 sizeof(FILE_BASIC_INFORMATION
),
951 FileBasicInformation
);
952 if (!NT_SUCCESS(Status
))
954 WARN ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status
);
955 NtClose (FileHandle
);
956 BaseSetLastNTError (Status
);
960 FileInformation
.FileAttributes
= dwFileAttributes
;
961 Status
= NtSetInformationFile(FileHandle
,
964 sizeof(FILE_BASIC_INFORMATION
),
965 FileBasicInformation
);
966 NtClose (FileHandle
);
967 if (!NT_SUCCESS(Status
))
969 WARN ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status
);
970 BaseSetLastNTError (Status
);
981 GetFileTime(IN HANDLE hFile
,
982 OUT LPFILETIME lpCreationTime OPTIONAL
,
983 OUT LPFILETIME lpLastAccessTime OPTIONAL
,
984 OUT LPFILETIME lpLastWriteTime OPTIONAL
)
987 IO_STATUS_BLOCK IoStatusBlock
;
988 FILE_BASIC_INFORMATION FileBasic
;
990 if(IsConsoleHandle(hFile
))
992 BaseSetLastNTError(STATUS_INVALID_HANDLE
);
996 Status
= NtQueryInformationFile(hFile
,
999 sizeof(FILE_BASIC_INFORMATION
),
1000 FileBasicInformation
);
1001 if (!NT_SUCCESS(Status
))
1003 BaseSetLastNTError(Status
);
1009 lpCreationTime
->dwLowDateTime
= FileBasic
.CreationTime
.LowPart
;
1010 lpCreationTime
->dwHighDateTime
= FileBasic
.CreationTime
.HighPart
;
1013 if (lpLastAccessTime
)
1015 lpLastAccessTime
->dwLowDateTime
= FileBasic
.LastAccessTime
.LowPart
;
1016 lpLastAccessTime
->dwHighDateTime
= FileBasic
.LastAccessTime
.HighPart
;
1019 if (lpLastWriteTime
)
1021 lpLastWriteTime
->dwLowDateTime
= FileBasic
.LastWriteTime
.LowPart
;
1022 lpLastWriteTime
->dwHighDateTime
= FileBasic
.LastWriteTime
.HighPart
;
1033 SetFileTime(IN HANDLE hFile
,
1034 CONST FILETIME
*lpCreationTime OPTIONAL
,
1035 CONST FILETIME
*lpLastAccessTime OPTIONAL
,
1036 CONST FILETIME
*lpLastWriteTime OPTIONAL
)
1039 IO_STATUS_BLOCK IoStatusBlock
;
1040 FILE_BASIC_INFORMATION FileBasic
;
1042 if(IsConsoleHandle(hFile
))
1044 BaseSetLastNTError(STATUS_INVALID_HANDLE
);
1048 memset(&FileBasic
, 0, sizeof(FILE_BASIC_INFORMATION
));
1052 FileBasic
.CreationTime
.LowPart
= lpCreationTime
->dwLowDateTime
;
1053 FileBasic
.CreationTime
.HighPart
= lpCreationTime
->dwHighDateTime
;
1056 if (lpLastAccessTime
)
1058 FileBasic
.LastAccessTime
.LowPart
= lpLastAccessTime
->dwLowDateTime
;
1059 FileBasic
.LastAccessTime
.HighPart
= lpLastAccessTime
->dwHighDateTime
;
1062 if (lpLastWriteTime
)
1064 FileBasic
.LastWriteTime
.LowPart
= lpLastWriteTime
->dwLowDateTime
;
1065 FileBasic
.LastWriteTime
.HighPart
= lpLastWriteTime
->dwHighDateTime
;
1068 Status
= NtSetInformationFile(hFile
,
1071 sizeof(FILE_BASIC_INFORMATION
),
1072 FileBasicInformation
);
1073 if (!NT_SUCCESS(Status
))
1075 BaseSetLastNTError(Status
);
1084 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
1089 SetEndOfFile(HANDLE hFile
)
1091 IO_STATUS_BLOCK IoStatusBlock
;
1092 FILE_END_OF_FILE_INFORMATION EndOfFileInfo
;
1093 FILE_ALLOCATION_INFORMATION FileAllocationInfo
;
1094 FILE_POSITION_INFORMATION FilePosInfo
;
1097 if(IsConsoleHandle(hFile
))
1099 SetLastError(ERROR_INVALID_HANDLE
);
1103 //get current position
1104 Status
= NtQueryInformationFile(
1108 sizeof(FILE_POSITION_INFORMATION
),
1109 FilePositionInformation
1112 if (!NT_SUCCESS(Status
)){
1113 BaseSetLastNTError(Status
);
1117 EndOfFileInfo
.EndOfFile
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1121 This call is not supposed to free up any space after the eof marker
1122 if the file gets truncated. We have to deallocate the space explicitly afterwards.
1123 But...most file systems dispatch both FileEndOfFileInformation
1124 and FileAllocationInformation as they were the same command.
1127 Status
= NtSetInformationFile(
1129 &IoStatusBlock
, //out
1131 sizeof(FILE_END_OF_FILE_INFORMATION
),
1132 FileEndOfFileInformation
1135 if (!NT_SUCCESS(Status
)){
1136 BaseSetLastNTError(Status
);
1140 FileAllocationInfo
.AllocationSize
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1143 Status
= NtSetInformationFile(
1145 &IoStatusBlock
, //out
1146 &FileAllocationInfo
,
1147 sizeof(FILE_ALLOCATION_INFORMATION
),
1148 FileAllocationInformation
1151 if (!NT_SUCCESS(Status
)){
1152 BaseSetLastNTError(Status
);
1168 LONGLONG ValidDataLength
1171 IO_STATUS_BLOCK IoStatusBlock
;
1172 FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation
;
1175 ValidDataLengthInformation
.ValidDataLength
.QuadPart
= ValidDataLength
;
1177 Status
= NtSetInformationFile(
1179 &IoStatusBlock
, //out
1180 &ValidDataLengthInformation
,
1181 sizeof(FILE_VALID_DATA_LENGTH_INFORMATION
),
1182 FileValidDataLengthInformation
1185 if (!NT_SUCCESS(Status
)){
1186 BaseSetLastNTError(Status
);