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 * GetTempFileName is modified from WINE [ Alexandre Juiliard ]
13 /* INCLUDES *****************************************************************/
18 #include "../include/debug.h"
21 /* GLOBALS ******************************************************************/
23 BOOL bIsFileApiAnsi
= TRUE
; // set the file api to ansi or oem
25 /* FUNCTIONS ****************************************************************/
30 FilenameA2W(LPCSTR NameA
, BOOL alloc
)
34 PUNICODE_STRING pstrW
;
37 ASSERT(NtCurrentTeb()->StaticUnicodeString
.Buffer
== NtCurrentTeb()->StaticUnicodeBuffer
);
38 ASSERT(NtCurrentTeb()->StaticUnicodeString
.MaximumLength
== sizeof(NtCurrentTeb()->StaticUnicodeBuffer
));
40 RtlInitAnsiString(&str
, NameA
);
41 pstrW
= alloc
? &strW
: &NtCurrentTeb()->StaticUnicodeString
;
44 Status
= RtlAnsiStringToUnicodeString( pstrW
, &str
, alloc
);
46 Status
= RtlOemStringToUnicodeString( pstrW
, &str
, alloc
);
48 if (NT_SUCCESS(Status
))
51 if (Status
== STATUS_BUFFER_OVERFLOW
)
52 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
54 SetLastErrorByStatus(Status
);
61 No copy/conversion is done if the dest. buffer is too small.
64 Success: number of TCHARS copied into dest. buffer NOT including nullterm
65 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
68 FilenameU2A_FitOrFail(
70 INT destLen
, /* buffer size in TCHARS incl. nullchar */
71 PUNICODE_STRING SourceU
76 ret
= bIsFileApiAnsi
? RtlUnicodeStringToAnsiSize(SourceU
) : RtlUnicodeStringToOemSize(SourceU
);
77 /* ret incl. nullchar */
79 if (DestA
&& (INT
)ret
<= destLen
)
84 str
.MaximumLength
= destLen
;
88 RtlUnicodeStringToAnsiString(&str
, SourceU
, FALSE
);
90 RtlUnicodeStringToOemString(&str
, SourceU
, FALSE
);
92 ret
= str
.Length
; /* SUCCESS: length without terminating 0 */
100 No copy/conversion is done if the dest. buffer is too small.
103 Success: number of TCHARS copied into dest. buffer NOT including nullterm
104 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
107 FilenameW2A_FitOrFail(
109 INT destLen
, /* buffer size in TCHARS incl. nullchar */
111 INT sourceLen
/* buffer size in TCHARS incl. nullchar */
116 if (sourceLen
< 0) sourceLen
= wcslen(SourceW
) + 1;
118 strW
.Buffer
= (PWCHAR
)SourceW
;
119 strW
.MaximumLength
= sourceLen
* sizeof(WCHAR
);
120 strW
.Length
= strW
.MaximumLength
- sizeof(WCHAR
);
122 return FilenameU2A_FitOrFail(DestA
, destLen
, &strW
);
127 Return: num. TCHARS copied into dest including nullterm
132 INT destlen
, /* buffer size in TCHARS incl. nullchar */
134 INT srclen
/* buffer size in TCHARS incl. nullchar */
139 if (srclen
< 0) srclen
= strlen( src
) + 1;
142 RtlMultiByteToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
144 RtlOemToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
146 if (ret
) dest
[(ret
/sizeof(WCHAR
))-1]=0;
148 return ret
/sizeof(WCHAR
);
152 Return: num. TCHARS copied into dest including nullterm
157 INT destlen
, /* buffer size in TCHARS incl. nullchar */
159 INT srclen
/* buffer size in TCHARS incl. nullchar */
164 if (srclen
< 0) srclen
= wcslen( src
) + 1;
167 RtlUnicodeToMultiByteN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
));
169 RtlUnicodeToOemN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
) );
171 if (ret
) dest
[ret
-1]=0;
182 SetFileApisToOEM(VOID
)
184 /* Set the correct Base Api */
185 Basep8BitStringToUnicodeString
= RtlOemStringToUnicodeString
;
187 /* FIXME: Old, deprecated way */
188 bIsFileApiAnsi
= FALSE
;
197 SetFileApisToANSI(VOID
)
199 /* Set the correct Base Api */
200 Basep8BitStringToUnicodeString
= RtlAnsiStringToUnicodeString
;
202 /* FIXME: Old, deprecated way */
203 bIsFileApiAnsi
= TRUE
;
211 AreFileApisANSI(VOID
)
213 return bIsFileApiAnsi
;
221 OpenFile(LPCSTR lpFileName
,
222 LPOFSTRUCT lpReOpenBuff
,
225 OBJECT_ATTRIBUTES ObjectAttributes
;
226 IO_STATUS_BLOCK IoStatusBlock
;
227 UNICODE_STRING FileNameString
;
228 UNICODE_STRING FileNameU
;
229 ANSI_STRING FileName
;
230 WCHAR PathNameW
[MAX_PATH
];
231 HANDLE FileHandle
= NULL
;
236 DPRINT("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName
, lpReOpenBuff
, uStyle
);
238 if (lpReOpenBuff
== NULL
)
243 if ((uStyle
& OF_CREATE
) == OF_CREATE
)
246 switch (uStyle
& 0x70)
248 case OF_SHARE_EXCLUSIVE
: Sharing
= 0; break;
249 case OF_SHARE_DENY_WRITE
: Sharing
= FILE_SHARE_READ
; break;
250 case OF_SHARE_DENY_READ
: Sharing
= FILE_SHARE_WRITE
; break;
251 case OF_SHARE_DENY_NONE
:
252 case OF_SHARE_COMPAT
:
254 Sharing
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
256 return (HFILE
) CreateFileA (lpFileName
,
257 GENERIC_READ
| GENERIC_WRITE
,
261 FILE_ATTRIBUTE_NORMAL
,
265 RtlInitAnsiString (&FileName
, (LPSTR
)lpFileName
);
267 /* convert ansi (or oem) string to unicode */
269 RtlAnsiStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
271 RtlOemStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
273 Len
= SearchPathW (NULL
,
280 RtlFreeUnicodeString(&FileNameU
);
282 if (Len
== 0 || Len
> OFS_MAXPATHNAME
)
284 return (HFILE
)INVALID_HANDLE_VALUE
;
287 FileName
.Buffer
= lpReOpenBuff
->szPathName
;
289 FileName
.MaximumLength
= OFS_MAXPATHNAME
;
291 RtlInitUnicodeString(&FileNameU
, PathNameW
);
293 /* convert unicode string to ansi (or oem) */
295 RtlUnicodeStringToAnsiString (&FileName
, &FileNameU
, FALSE
);
297 RtlUnicodeStringToOemString (&FileName
, &FileNameU
, FALSE
);
299 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)PathNameW
,
304 return (HFILE
)INVALID_HANDLE_VALUE
;
308 // FILE_NO_INTERMEDIATE_BUFFERING
310 if ((uStyle
& OF_PARSE
) == OF_PARSE
)
312 RtlFreeUnicodeString(&FileNameString
);
316 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
317 ObjectAttributes
.RootDirectory
= NULL
;
318 ObjectAttributes
.ObjectName
= &FileNameString
;
319 ObjectAttributes
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
;
320 ObjectAttributes
.SecurityDescriptor
= NULL
;
321 ObjectAttributes
.SecurityQualityOfService
= NULL
;
323 errCode
= NtOpenFile (&FileHandle
,
324 GENERIC_READ
|SYNCHRONIZE
,
328 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
330 RtlFreeUnicodeString(&FileNameString
);
332 lpReOpenBuff
->nErrCode
= RtlNtStatusToDosError(errCode
);
334 if (!NT_SUCCESS(errCode
))
336 SetLastErrorByStatus (errCode
);
337 return (HFILE
)INVALID_HANDLE_VALUE
;
340 return (HFILE
)FileHandle
;
348 FlushFileBuffers(HANDLE hFile
)
351 IO_STATUS_BLOCK IoStatusBlock
;
353 if (IsConsoleHandle(hFile
))
358 errCode
= NtFlushBuffersFile(hFile
,
360 if (!NT_SUCCESS(errCode
))
362 SetLastErrorByStatus(errCode
);
373 SetFilePointer(HANDLE hFile
,
374 LONG lDistanceToMove
,
375 PLONG lpDistanceToMoveHigh
,
378 FILE_POSITION_INFORMATION FilePosition
;
379 FILE_STANDARD_INFORMATION FileStandard
;
381 IO_STATUS_BLOCK IoStatusBlock
;
382 LARGE_INTEGER Distance
;
384 DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
385 hFile
,lDistanceToMove
,dwMoveMethod
);
387 if(IsConsoleHandle(hFile
))
389 SetLastError(ERROR_INVALID_HANDLE
);
393 Distance
.u
.LowPart
= lDistanceToMove
;
394 if (lpDistanceToMoveHigh
)
396 Distance
.u
.HighPart
= *lpDistanceToMoveHigh
;
398 else if (lDistanceToMove
>= 0)
400 Distance
.u
.HighPart
= 0;
404 Distance
.u
.HighPart
= -1;
410 NtQueryInformationFile(hFile
,
413 sizeof(FILE_POSITION_INFORMATION
),
414 FilePositionInformation
);
415 FilePosition
.CurrentByteOffset
.QuadPart
+= Distance
.QuadPart
;
418 NtQueryInformationFile(hFile
,
421 sizeof(FILE_STANDARD_INFORMATION
),
422 FileStandardInformation
);
423 FilePosition
.CurrentByteOffset
.QuadPart
=
424 FileStandard
.EndOfFile
.QuadPart
+ Distance
.QuadPart
;
427 FilePosition
.CurrentByteOffset
.QuadPart
= Distance
.QuadPart
;
430 SetLastError(ERROR_INVALID_PARAMETER
);
434 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
436 SetLastError(ERROR_NEGATIVE_SEEK
);
440 errCode
= NtSetInformationFile(hFile
,
443 sizeof(FILE_POSITION_INFORMATION
),
444 FilePositionInformation
);
445 if (!NT_SUCCESS(errCode
))
447 SetLastErrorByStatus(errCode
);
451 if (lpDistanceToMoveHigh
!= NULL
)
453 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
455 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
464 SetFilePointerEx(HANDLE hFile
,
465 LARGE_INTEGER liDistanceToMove
,
466 PLARGE_INTEGER lpNewFilePointer
,
469 FILE_POSITION_INFORMATION FilePosition
;
470 FILE_STANDARD_INFORMATION FileStandard
;
472 IO_STATUS_BLOCK IoStatusBlock
;
474 if(IsConsoleHandle(hFile
))
476 SetLastError(ERROR_INVALID_HANDLE
);
483 NtQueryInformationFile(hFile
,
486 sizeof(FILE_POSITION_INFORMATION
),
487 FilePositionInformation
);
488 FilePosition
.CurrentByteOffset
.QuadPart
+= liDistanceToMove
.QuadPart
;
491 NtQueryInformationFile(hFile
,
494 sizeof(FILE_STANDARD_INFORMATION
),
495 FileStandardInformation
);
496 FilePosition
.CurrentByteOffset
.QuadPart
=
497 FileStandard
.EndOfFile
.QuadPart
+ liDistanceToMove
.QuadPart
;
500 FilePosition
.CurrentByteOffset
.QuadPart
= liDistanceToMove
.QuadPart
;
503 SetLastError(ERROR_INVALID_PARAMETER
);
507 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
509 SetLastError(ERROR_NEGATIVE_SEEK
);
513 errCode
= NtSetInformationFile(hFile
,
516 sizeof(FILE_POSITION_INFORMATION
),
517 FilePositionInformation
);
518 if (!NT_SUCCESS(errCode
))
520 SetLastErrorByStatus(errCode
);
524 if (lpNewFilePointer
)
526 *lpNewFilePointer
= FilePosition
.CurrentByteOffset
;
536 GetFileType(HANDLE hFile
)
538 FILE_FS_DEVICE_INFORMATION DeviceInfo
;
539 IO_STATUS_BLOCK StatusBlock
;
542 /* Get real handle */
543 switch ((ULONG
)hFile
)
545 case STD_INPUT_HANDLE
:
546 hFile
= NtCurrentPeb()->ProcessParameters
->StandardInput
;
549 case STD_OUTPUT_HANDLE
:
550 hFile
= NtCurrentPeb()->ProcessParameters
->StandardOutput
;
553 case STD_ERROR_HANDLE
:
554 hFile
= NtCurrentPeb()->ProcessParameters
->StandardError
;
558 /* Check for console handle */
559 if (IsConsoleHandle(hFile
))
561 if (VerifyConsoleIoHandle(hFile
))
562 return FILE_TYPE_CHAR
;
565 Status
= NtQueryVolumeInformationFile(hFile
,
568 sizeof(FILE_FS_DEVICE_INFORMATION
),
569 FileFsDeviceInformation
);
570 if (!NT_SUCCESS(Status
))
572 SetLastErrorByStatus(Status
);
573 return FILE_TYPE_UNKNOWN
;
576 switch (DeviceInfo
.DeviceType
)
578 case FILE_DEVICE_CD_ROM
:
579 case FILE_DEVICE_CD_ROM_FILE_SYSTEM
:
580 case FILE_DEVICE_CONTROLLER
:
581 case FILE_DEVICE_DATALINK
:
582 case FILE_DEVICE_DFS
:
583 case FILE_DEVICE_DISK
:
584 case FILE_DEVICE_DISK_FILE_SYSTEM
:
585 case FILE_DEVICE_VIRTUAL_DISK
:
586 return FILE_TYPE_DISK
;
588 case FILE_DEVICE_KEYBOARD
:
589 case FILE_DEVICE_MOUSE
:
590 case FILE_DEVICE_NULL
:
591 case FILE_DEVICE_PARALLEL_PORT
:
592 case FILE_DEVICE_PRINTER
:
593 case FILE_DEVICE_SERIAL_PORT
:
594 case FILE_DEVICE_SCREEN
:
595 case FILE_DEVICE_SOUND
:
596 case FILE_DEVICE_MODEM
:
597 return FILE_TYPE_CHAR
;
599 case FILE_DEVICE_NAMED_PIPE
:
600 return FILE_TYPE_PIPE
;
603 return FILE_TYPE_UNKNOWN
;
611 GetFileSize(HANDLE hFile
,
612 LPDWORD lpFileSizeHigh
)
615 FILE_STANDARD_INFORMATION FileStandard
;
616 IO_STATUS_BLOCK IoStatusBlock
;
618 errCode
= NtQueryInformationFile(hFile
,
621 sizeof(FILE_STANDARD_INFORMATION
),
622 FileStandardInformation
);
623 if (!NT_SUCCESS(errCode
))
625 SetLastErrorByStatus(errCode
);
626 if ( lpFileSizeHigh
== NULL
)
635 if ( lpFileSizeHigh
!= NULL
)
636 *lpFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
638 return FileStandard
.EndOfFile
.u
.LowPart
;
649 PLARGE_INTEGER lpFileSize
653 FILE_STANDARD_INFORMATION FileStandard
;
654 IO_STATUS_BLOCK IoStatusBlock
;
656 errCode
= NtQueryInformationFile(hFile
,
659 sizeof(FILE_STANDARD_INFORMATION
),
660 FileStandardInformation
);
661 if (!NT_SUCCESS(errCode
))
663 SetLastErrorByStatus(errCode
);
667 *lpFileSize
= FileStandard
.EndOfFile
;
677 GetCompressedFileSizeA(LPCSTR lpFileName
,
678 LPDWORD lpFileSizeHigh
)
682 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
683 return INVALID_FILE_SIZE
;
685 return GetCompressedFileSizeW(FileNameW
, lpFileSizeHigh
);
693 GetCompressedFileSizeW(LPCWSTR lpFileName
,
694 LPDWORD lpFileSizeHigh
)
696 FILE_COMPRESSION_INFORMATION FileCompression
;
698 IO_STATUS_BLOCK IoStatusBlock
;
701 hFile
= CreateFileW(lpFileName
,
706 FILE_ATTRIBUTE_NORMAL
,
709 if (hFile
== INVALID_HANDLE_VALUE
)
710 return INVALID_FILE_SIZE
;
712 errCode
= NtQueryInformationFile(hFile
,
715 sizeof(FILE_COMPRESSION_INFORMATION
),
716 FileCompressionInformation
);
720 if (!NT_SUCCESS(errCode
))
722 SetLastErrorByStatus(errCode
);
723 return INVALID_FILE_SIZE
;
727 *lpFileSizeHigh
= FileCompression
.CompressedFileSize
.u
.HighPart
;
729 SetLastError(NO_ERROR
);
730 return FileCompression
.CompressedFileSize
.u
.LowPart
;
738 GetFileInformationByHandle(HANDLE hFile
,
739 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
743 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
748 FILE_BASIC_INFORMATION FileBasic
;
749 FILE_INTERNAL_INFORMATION FileInternal
;
750 FILE_STANDARD_INFORMATION FileStandard
;
752 IO_STATUS_BLOCK IoStatusBlock
;
754 if(IsConsoleHandle(hFile
))
756 SetLastError(ERROR_INVALID_HANDLE
);
760 errCode
= NtQueryInformationFile(hFile
,
763 sizeof(FILE_BASIC_INFORMATION
),
764 FileBasicInformation
);
765 if (!NT_SUCCESS(errCode
))
767 SetLastErrorByStatus(errCode
);
771 lpFileInformation
->dwFileAttributes
= (DWORD
)FileBasic
.FileAttributes
;
773 lpFileInformation
->ftCreationTime
.dwHighDateTime
= FileBasic
.CreationTime
.u
.HighPart
;
774 lpFileInformation
->ftCreationTime
.dwLowDateTime
= FileBasic
.CreationTime
.u
.LowPart
;
776 lpFileInformation
->ftLastAccessTime
.dwHighDateTime
= FileBasic
.LastAccessTime
.u
.HighPart
;
777 lpFileInformation
->ftLastAccessTime
.dwLowDateTime
= FileBasic
.LastAccessTime
.u
.LowPart
;
779 lpFileInformation
->ftLastWriteTime
.dwHighDateTime
= FileBasic
.LastWriteTime
.u
.HighPart
;
780 lpFileInformation
->ftLastWriteTime
.dwLowDateTime
= FileBasic
.LastWriteTime
.u
.LowPart
;
782 errCode
= NtQueryInformationFile(hFile
,
785 sizeof(FILE_INTERNAL_INFORMATION
),
786 FileInternalInformation
);
787 if (!NT_SUCCESS(errCode
))
789 SetLastErrorByStatus(errCode
);
793 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
794 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
796 errCode
= NtQueryVolumeInformationFile(hFile
,
799 sizeof(FileFsVolume
),
800 FileFsVolumeInformation
);
801 if (!NT_SUCCESS(errCode
))
803 SetLastErrorByStatus(errCode
);
807 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.FileFsVolume
.VolumeSerialNumber
;
809 errCode
= NtQueryInformationFile(hFile
,
812 sizeof(FILE_STANDARD_INFORMATION
),
813 FileStandardInformation
);
814 if (!NT_SUCCESS(errCode
))
816 SetLastErrorByStatus(errCode
);
820 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
821 lpFileInformation
->nFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
822 lpFileInformation
->nFileSizeLow
= FileStandard
.EndOfFile
.u
.LowPart
;
832 GetFileAttributesExW(LPCWSTR lpFileName
,
833 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
834 LPVOID lpFileInformation
)
836 FILE_NETWORK_OPEN_INFORMATION FileInformation
;
837 OBJECT_ATTRIBUTES ObjectAttributes
;
838 IO_STATUS_BLOCK IoStatusBlock
;
839 UNICODE_STRING FileName
;
842 WIN32_FILE_ATTRIBUTE_DATA
* FileAttributeData
;
844 DPRINT("GetFileAttributesExW(%S) called\n", lpFileName
);
847 if (fInfoLevelId
!= GetFileExInfoStandard
|| lpFileInformation
== NULL
)
849 SetLastError(ERROR_INVALID_PARAMETER
);
853 /* Validate and translate the filename */
854 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
859 DPRINT1 ("Invalid path\n");
860 SetLastError (ERROR_BAD_PATHNAME
);
864 /* build the object attributes */
865 InitializeObjectAttributes (&ObjectAttributes
,
867 OBJ_CASE_INSENSITIVE
,
872 Status
= NtOpenFile (&FileHandle
,
873 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
,
876 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
877 FILE_SYNCHRONOUS_IO_NONALERT
);
878 RtlFreeUnicodeString (&FileName
);
879 if (!NT_SUCCESS (Status
))
881 DPRINT ("NtOpenFile() failed %x (Status %lx)\n", &ObjectAttributes
, Status
);
882 SetLastErrorByStatus (Status
);
886 /* Get file attributes */
887 Status
= NtQueryInformationFile (FileHandle
,
890 sizeof(FILE_NETWORK_OPEN_INFORMATION
),
891 FileNetworkOpenInformation
);
892 NtClose (FileHandle
);
894 if (!NT_SUCCESS (Status
))
896 DPRINT1 ("NtQueryInformationFile() failed (Status %lx)\n", Status
);
897 SetLastErrorByStatus (Status
);
901 FileAttributeData
= (WIN32_FILE_ATTRIBUTE_DATA
*)lpFileInformation
;
902 FileAttributeData
->dwFileAttributes
= FileInformation
.FileAttributes
;
903 FileAttributeData
->ftCreationTime
.dwLowDateTime
= FileInformation
.CreationTime
.u
.LowPart
;
904 FileAttributeData
->ftCreationTime
.dwHighDateTime
= FileInformation
.CreationTime
.u
.HighPart
;
905 FileAttributeData
->ftLastAccessTime
.dwLowDateTime
= FileInformation
.LastAccessTime
.u
.LowPart
;
906 FileAttributeData
->ftLastAccessTime
.dwHighDateTime
= FileInformation
.LastAccessTime
.u
.HighPart
;
907 FileAttributeData
->ftLastWriteTime
.dwLowDateTime
= FileInformation
.LastWriteTime
.u
.LowPart
;
908 FileAttributeData
->ftLastWriteTime
.dwHighDateTime
= FileInformation
.LastWriteTime
.u
.HighPart
;
909 FileAttributeData
->nFileSizeLow
= FileInformation
.EndOfFile
.u
.LowPart
;
910 FileAttributeData
->nFileSizeHigh
= FileInformation
.EndOfFile
.u
.HighPart
;
919 GetFileAttributesExA(LPCSTR lpFileName
,
920 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
921 LPVOID lpFileInformation
)
925 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
928 return GetFileAttributesExW(FileNameW
, fInfoLevelId
, lpFileInformation
);
936 GetFileAttributesA(LPCSTR lpFileName
)
938 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
942 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
943 return INVALID_FILE_ATTRIBUTES
;
945 ret
= GetFileAttributesExW(FileNameW
, GetFileExInfoStandard
, &FileAttributeData
);
947 return ret
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
955 GetFileAttributesW(LPCWSTR lpFileName
)
957 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
960 DPRINT ("GetFileAttributeW(%S) called\n", lpFileName
);
962 Result
= GetFileAttributesExW(lpFileName
, GetFileExInfoStandard
, &FileAttributeData
);
964 return Result
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
972 GetFileAttributesByHandle(IN HANDLE hFile
,
973 OUT LPDWORD dwFileAttributes
,
976 FILE_BASIC_INFORMATION FileBasic
;
977 IO_STATUS_BLOCK IoStatusBlock
;
980 UNREFERENCED_PARAMETER(dwFlags
);
982 if (IsConsoleHandle(hFile
))
984 SetLastError(ERROR_INVALID_HANDLE
);
988 Status
= NtQueryInformationFile(hFile
,
992 FileBasicInformation
);
993 if (NT_SUCCESS(Status
))
995 *dwFileAttributes
= FileBasic
.FileAttributes
;
999 SetLastErrorByStatus(Status
);
1008 SetFileAttributesByHandle(IN HANDLE hFile
,
1009 IN DWORD dwFileAttributes
,
1012 FILE_BASIC_INFORMATION FileBasic
;
1013 IO_STATUS_BLOCK IoStatusBlock
;
1016 UNREFERENCED_PARAMETER(dwFlags
);
1018 if (IsConsoleHandle(hFile
))
1020 SetLastError(ERROR_INVALID_HANDLE
);
1024 Status
= NtQueryInformationFile(hFile
,
1028 FileBasicInformation
);
1029 if (NT_SUCCESS(Status
))
1031 FileBasic
.FileAttributes
= dwFileAttributes
;
1033 Status
= NtSetInformationFile(hFile
,
1037 FileBasicInformation
);
1040 if (!NT_SUCCESS(Status
))
1042 SetLastErrorByStatus(Status
);
1056 DWORD dwFileAttributes
)
1060 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
1063 return SetFileAttributesW(FileNameW
, dwFileAttributes
);
1071 SetFileAttributesW(LPCWSTR lpFileName
,
1072 DWORD dwFileAttributes
)
1074 FILE_BASIC_INFORMATION FileInformation
;
1075 OBJECT_ATTRIBUTES ObjectAttributes
;
1076 IO_STATUS_BLOCK IoStatusBlock
;
1077 UNICODE_STRING FileName
;
1081 DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName
, dwFileAttributes
);
1083 /* Validate and translate the filename */
1084 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
1089 DPRINT ("Invalid path\n");
1090 SetLastError (ERROR_BAD_PATHNAME
);
1093 DPRINT ("FileName: \'%wZ\'\n", &FileName
);
1095 /* build the object attributes */
1096 InitializeObjectAttributes (&ObjectAttributes
,
1098 OBJ_CASE_INSENSITIVE
,
1103 Status
= NtOpenFile (&FileHandle
,
1104 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1107 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1108 FILE_SYNCHRONOUS_IO_NONALERT
);
1109 RtlFreeUnicodeString (&FileName
);
1110 if (!NT_SUCCESS (Status
))
1112 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
1113 SetLastErrorByStatus (Status
);
1117 Status
= NtQueryInformationFile(FileHandle
,
1120 sizeof(FILE_BASIC_INFORMATION
),
1121 FileBasicInformation
);
1122 if (!NT_SUCCESS(Status
))
1124 DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status
);
1125 NtClose (FileHandle
);
1126 SetLastErrorByStatus (Status
);
1130 FileInformation
.FileAttributes
= dwFileAttributes
;
1131 Status
= NtSetInformationFile(FileHandle
,
1134 sizeof(FILE_BASIC_INFORMATION
),
1135 FileBasicInformation
);
1136 NtClose (FileHandle
);
1137 if (!NT_SUCCESS(Status
))
1139 DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status
);
1140 SetLastErrorByStatus (Status
);
1150 /***********************************************************************
1151 * GetTempFileNameA (KERNEL32.@)
1153 UINT WINAPI
GetTempFileNameA( LPCSTR path
, LPCSTR prefix
, UINT unique
, LPSTR buffer
)
1155 WCHAR BufferW
[MAX_PATH
];
1160 if (!(PathW
= FilenameA2W(path
, FALSE
)))
1164 FilenameA2W_N(PrefixW
, 3+1, prefix
, -1);
1166 ret
= GetTempFileNameW(PathW
, prefix
? PrefixW
: NULL
, unique
, BufferW
);
1169 FilenameW2A_N(buffer
, MAX_PATH
, BufferW
, -1);
1174 /***********************************************************************
1175 * GetTempFileNameW (KERNEL32.@)
1177 UINT WINAPI
GetTempFileNameW( LPCWSTR path
, LPCWSTR prefix
, UINT unique
, LPWSTR buffer
)
1179 static const WCHAR formatW
[] = L
"%x.tmp";
1184 if ( !path
|| !prefix
|| !buffer
)
1186 SetLastError( ERROR_INVALID_PARAMETER
);
1190 wcscpy( buffer
, path
);
1191 p
= buffer
+ wcslen(buffer
);
1193 /* add a \, if there isn't one */
1194 if ((p
== buffer
) || (p
[-1] != '\\')) *p
++ = '\\';
1196 for (i
= 3; (i
> 0) && (*prefix
); i
--) *p
++ = *prefix
++;
1200 if (unique
) swprintf( p
, formatW
, unique
);
1203 /* get a "random" unique number and try to create the file */
1205 UINT num
= GetTickCount() & 0xffff;
1211 swprintf( p
, formatW
, unique
);
1212 handle
= CreateFileW( buffer
, GENERIC_WRITE
, 0, NULL
,
1213 CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, 0 );
1214 if (handle
!= INVALID_HANDLE_VALUE
)
1215 { /* We created it */
1216 DPRINT("created %S\n", buffer
);
1217 CloseHandle( handle
);
1220 if (GetLastError() != ERROR_FILE_EXISTS
&&
1221 GetLastError() != ERROR_SHARING_VIOLATION
)
1222 break; /* No need to go on */
1223 if (!(++unique
& 0xffff)) unique
= 1;
1224 } while (unique
!= num
);
1227 DPRINT("returning %S\n", buffer
);
1239 GetFileTime(HANDLE hFile
,
1240 LPFILETIME lpCreationTime
,
1241 LPFILETIME lpLastAccessTime
,
1242 LPFILETIME lpLastWriteTime
)
1244 IO_STATUS_BLOCK IoStatusBlock
;
1245 FILE_BASIC_INFORMATION FileBasic
;
1248 if(IsConsoleHandle(hFile
))
1250 SetLastError(ERROR_INVALID_HANDLE
);
1254 Status
= NtQueryInformationFile(hFile
,
1257 sizeof(FILE_BASIC_INFORMATION
),
1258 FileBasicInformation
);
1259 if (!NT_SUCCESS(Status
))
1261 SetLastErrorByStatus(Status
);
1266 memcpy(lpCreationTime
, &FileBasic
.CreationTime
, sizeof(FILETIME
));
1267 if (lpLastAccessTime
)
1268 memcpy(lpLastAccessTime
, &FileBasic
.LastAccessTime
, sizeof(FILETIME
));
1269 if (lpLastWriteTime
)
1270 memcpy(lpLastWriteTime
, &FileBasic
.LastWriteTime
, sizeof(FILETIME
));
1280 SetFileTime(HANDLE hFile
,
1281 CONST FILETIME
*lpCreationTime
,
1282 CONST FILETIME
*lpLastAccessTime
,
1283 CONST FILETIME
*lpLastWriteTime
)
1285 FILE_BASIC_INFORMATION FileBasic
;
1286 IO_STATUS_BLOCK IoStatusBlock
;
1289 if(IsConsoleHandle(hFile
))
1291 SetLastError(ERROR_INVALID_HANDLE
);
1295 Status
= NtQueryInformationFile(hFile
,
1298 sizeof(FILE_BASIC_INFORMATION
),
1299 FileBasicInformation
);
1300 if (!NT_SUCCESS(Status
))
1302 SetLastErrorByStatus(Status
);
1307 memcpy(&FileBasic
.CreationTime
, lpCreationTime
, sizeof(FILETIME
));
1308 if (lpLastAccessTime
)
1309 memcpy(&FileBasic
.LastAccessTime
, lpLastAccessTime
, sizeof(FILETIME
));
1310 if (lpLastWriteTime
)
1311 memcpy(&FileBasic
.LastWriteTime
, lpLastWriteTime
, sizeof(FILETIME
));
1313 // should i initialize changetime ???
1315 Status
= NtSetInformationFile(hFile
,
1318 sizeof(FILE_BASIC_INFORMATION
),
1319 FileBasicInformation
);
1320 if (!NT_SUCCESS(Status
))
1322 SetLastErrorByStatus(Status
);
1331 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
1336 SetEndOfFile(HANDLE hFile
)
1338 IO_STATUS_BLOCK IoStatusBlock
;
1339 FILE_END_OF_FILE_INFORMATION EndOfFileInfo
;
1340 FILE_ALLOCATION_INFORMATION FileAllocationInfo
;
1341 FILE_POSITION_INFORMATION FilePosInfo
;
1344 if(IsConsoleHandle(hFile
))
1346 SetLastError(ERROR_INVALID_HANDLE
);
1350 //get current position
1351 Status
= NtQueryInformationFile(
1355 sizeof(FILE_POSITION_INFORMATION
),
1356 FilePositionInformation
1359 if (!NT_SUCCESS(Status
)){
1360 SetLastErrorByStatus(Status
);
1364 EndOfFileInfo
.EndOfFile
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1368 This call is not supposed to free up any space after the eof marker
1369 if the file gets truncated. We have to deallocate the space explicitly afterwards.
1370 But...most file systems dispatch both FileEndOfFileInformation
1371 and FileAllocationInformation as they were the same command.
1374 Status
= NtSetInformationFile(
1376 &IoStatusBlock
, //out
1378 sizeof(FILE_END_OF_FILE_INFORMATION
),
1379 FileEndOfFileInformation
1382 if (!NT_SUCCESS(Status
)){
1383 SetLastErrorByStatus(Status
);
1387 FileAllocationInfo
.AllocationSize
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1390 Status
= NtSetInformationFile(
1392 &IoStatusBlock
, //out
1393 &FileAllocationInfo
,
1394 sizeof(FILE_ALLOCATION_INFORMATION
),
1395 FileAllocationInformation
1398 if (!NT_SUCCESS(Status
)){
1399 SetLastErrorByStatus(Status
);
1415 LONGLONG ValidDataLength
1418 IO_STATUS_BLOCK IoStatusBlock
;
1419 FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation
;
1422 ValidDataLengthInformation
.ValidDataLength
.QuadPart
= ValidDataLength
;
1424 Status
= NtSetInformationFile(
1426 &IoStatusBlock
, //out
1427 &ValidDataLengthInformation
,
1428 sizeof(FILE_VALID_DATA_LENGTH_INFORMATION
),
1429 FileValidDataLengthInformation
1432 if (!NT_SUCCESS(Status
)){
1433 SetLastErrorByStatus(Status
);
1449 LPCWSTR lpShortName
)
1453 UNICODE_STRING ShortName
;
1454 IO_STATUS_BLOCK IoStatusBlock
;
1455 PFILE_NAME_INFORMATION FileNameInformation
;
1457 if(IsConsoleHandle(hFile
))
1459 SetLastError(ERROR_INVALID_HANDLE
);
1465 SetLastError(ERROR_INVALID_PARAMETER
);
1469 RtlInitUnicodeString(&ShortName
, lpShortName
);
1471 NeededSize
= sizeof(FILE_NAME_INFORMATION
) + ShortName
.Length
+ sizeof(WCHAR
);
1472 if(!(FileNameInformation
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, NeededSize
)))
1474 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1478 FileNameInformation
->FileNameLength
= ShortName
.Length
;
1479 RtlCopyMemory(FileNameInformation
->FileName
, ShortName
.Buffer
, ShortName
.Length
);
1481 Status
= NtSetInformationFile(hFile
,
1482 &IoStatusBlock
, //out
1483 FileNameInformation
,
1485 FileShortNameInformation
);
1487 RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInformation
);
1488 if(!NT_SUCCESS(Status
))
1491 SetLastErrorByStatus(Status
);
1494 return NT_SUCCESS(Status
);
1510 if(IsConsoleHandle(hFile
))
1512 SetLastError(ERROR_INVALID_HANDLE
);
1518 SetLastError(ERROR_INVALID_PARAMETER
);
1522 if (!(ShortNameW
= FilenameA2W(lpShortName
, FALSE
)))
1525 return SetFileShortNameW(hFile
, ShortNameW
);
1534 CheckNameLegalDOS8Dot3W(
1536 LPSTR lpOemName OPTIONAL
,
1537 DWORD OemNameSize OPTIONAL
,
1538 PBOOL pbNameContainsSpaces OPTIONAL
,
1542 UNICODE_STRING Name
;
1543 ANSI_STRING AnsiName
;
1545 if(lpName
== NULL
||
1546 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1547 pbNameLegal
== NULL
)
1549 SetLastError(ERROR_INVALID_PARAMETER
);
1553 if(lpOemName
!= NULL
)
1555 AnsiName
.Buffer
= lpOemName
;
1556 AnsiName
.MaximumLength
= OemNameSize
* sizeof(CHAR
);
1557 AnsiName
.Length
= 0;
1560 RtlInitUnicodeString(&Name
, lpName
);
1562 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1563 (lpOemName
? &AnsiName
: NULL
),
1564 (BOOLEAN
*)pbNameContainsSpaces
);
1575 CheckNameLegalDOS8Dot3A(
1577 LPSTR lpOemName OPTIONAL
,
1578 DWORD OemNameSize OPTIONAL
,
1579 PBOOL pbNameContainsSpaces OPTIONAL
,
1583 UNICODE_STRING Name
;
1584 ANSI_STRING AnsiName
, AnsiInputName
;
1587 if(lpName
== NULL
||
1588 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1589 pbNameLegal
== NULL
)
1591 SetLastError(ERROR_INVALID_PARAMETER
);
1595 if(lpOemName
!= NULL
)
1597 AnsiName
.Buffer
= lpOemName
;
1598 AnsiName
.MaximumLength
= OemNameSize
* sizeof(CHAR
);
1599 AnsiName
.Length
= 0;
1602 RtlInitAnsiString(&AnsiInputName
, (LPSTR
)lpName
);
1604 Status
= RtlAnsiStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1606 Status
= RtlOemStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1608 if(!NT_SUCCESS(Status
))
1610 SetLastErrorByStatus(Status
);
1614 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1615 (lpOemName
? &AnsiName
: NULL
),
1616 (BOOLEAN
*)pbNameContainsSpaces
);
1618 RtlFreeUnicodeString(&Name
);