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 *****************************************************************/
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
, (BOOLEAN
)alloc
);
46 Status
= RtlOemStringToUnicodeString( pstrW
, &str
, (BOOLEAN
)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
= (USHORT
)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
= (PRTL_CONVERT_STRING
)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 (PathNameW
,
304 return (HFILE
)INVALID_HANDLE_VALUE
;
308 // FILE_NO_INTERMEDIATE_BUFFERING
310 if ((uStyle
& OF_PARSE
) == OF_PARSE
)
312 RtlFreeHeap(RtlGetProcessHeap(),
314 FileNameString
.Buffer
);
318 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
319 ObjectAttributes
.RootDirectory
= NULL
;
320 ObjectAttributes
.ObjectName
= &FileNameString
;
321 ObjectAttributes
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
;
322 ObjectAttributes
.SecurityDescriptor
= NULL
;
323 ObjectAttributes
.SecurityQualityOfService
= NULL
;
325 errCode
= NtOpenFile (&FileHandle
,
326 GENERIC_READ
|SYNCHRONIZE
,
330 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
332 RtlFreeHeap(RtlGetProcessHeap(),
334 FileNameString
.Buffer
);
336 lpReOpenBuff
->nErrCode
= (WORD
)RtlNtStatusToDosError(errCode
);
338 if (!NT_SUCCESS(errCode
))
340 SetLastErrorByStatus (errCode
);
341 return (HFILE
)INVALID_HANDLE_VALUE
;
344 return (HFILE
)FileHandle
;
352 FlushFileBuffers(HANDLE hFile
)
355 IO_STATUS_BLOCK IoStatusBlock
;
357 if (IsConsoleHandle(hFile
))
362 errCode
= NtFlushBuffersFile(hFile
,
364 if (!NT_SUCCESS(errCode
))
366 SetLastErrorByStatus(errCode
);
377 SetFilePointer(HANDLE hFile
,
378 LONG lDistanceToMove
,
379 PLONG lpDistanceToMoveHigh
,
382 FILE_POSITION_INFORMATION FilePosition
;
383 FILE_STANDARD_INFORMATION FileStandard
;
385 IO_STATUS_BLOCK IoStatusBlock
;
386 LARGE_INTEGER Distance
;
388 DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
389 hFile
,lDistanceToMove
,dwMoveMethod
);
391 if(IsConsoleHandle(hFile
))
393 SetLastError(ERROR_INVALID_HANDLE
);
397 if (lpDistanceToMoveHigh
)
399 Distance
.u
.HighPart
= *lpDistanceToMoveHigh
;
400 Distance
.u
.LowPart
= lDistanceToMove
;
404 Distance
.QuadPart
= lDistanceToMove
;
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 if (lpDistanceToMoveHigh
== NULL
&& FilePosition
.CurrentByteOffset
.HighPart
!= 0)
442 /* If we're moving the pointer outside of the 32 bit boundaries but
443 the application only passed a 32 bit value we need to bail out! */
444 SetLastError(ERROR_INVALID_PARAMETER
);
448 errCode
= NtSetInformationFile(hFile
,
451 sizeof(FILE_POSITION_INFORMATION
),
452 FilePositionInformation
);
453 if (!NT_SUCCESS(errCode
))
455 if (lpDistanceToMoveHigh
!= NULL
)
456 *lpDistanceToMoveHigh
= -1;
458 SetLastErrorByStatus(errCode
);
462 if (lpDistanceToMoveHigh
!= NULL
)
464 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
467 if (FilePosition
.CurrentByteOffset
.u
.LowPart
== -1)
469 /* The value of -1 is valid here, especially when the new
470 file position is greater than 4 GB. Since NtSetInformationFile
471 succeeded we never set an error code and we explicitly need
472 to clear a previously set error code in this case, which
473 an application will check if INVALID_SET_FILE_POINTER is returned! */
474 SetLastError(ERROR_SUCCESS
);
477 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
486 SetFilePointerEx(HANDLE hFile
,
487 LARGE_INTEGER liDistanceToMove
,
488 PLARGE_INTEGER lpNewFilePointer
,
491 FILE_POSITION_INFORMATION FilePosition
;
492 FILE_STANDARD_INFORMATION FileStandard
;
494 IO_STATUS_BLOCK IoStatusBlock
;
496 if(IsConsoleHandle(hFile
))
498 SetLastError(ERROR_INVALID_HANDLE
);
505 NtQueryInformationFile(hFile
,
508 sizeof(FILE_POSITION_INFORMATION
),
509 FilePositionInformation
);
510 FilePosition
.CurrentByteOffset
.QuadPart
+= liDistanceToMove
.QuadPart
;
513 NtQueryInformationFile(hFile
,
516 sizeof(FILE_STANDARD_INFORMATION
),
517 FileStandardInformation
);
518 FilePosition
.CurrentByteOffset
.QuadPart
=
519 FileStandard
.EndOfFile
.QuadPart
+ liDistanceToMove
.QuadPart
;
522 FilePosition
.CurrentByteOffset
.QuadPart
= liDistanceToMove
.QuadPart
;
525 SetLastError(ERROR_INVALID_PARAMETER
);
529 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
531 SetLastError(ERROR_NEGATIVE_SEEK
);
535 errCode
= NtSetInformationFile(hFile
,
538 sizeof(FILE_POSITION_INFORMATION
),
539 FilePositionInformation
);
540 if (!NT_SUCCESS(errCode
))
542 SetLastErrorByStatus(errCode
);
546 if (lpNewFilePointer
)
548 *lpNewFilePointer
= FilePosition
.CurrentByteOffset
;
558 GetFileType(HANDLE hFile
)
560 FILE_FS_DEVICE_INFORMATION DeviceInfo
;
561 IO_STATUS_BLOCK StatusBlock
;
564 /* Get real handle */
565 switch ((ULONG
)hFile
)
567 case STD_INPUT_HANDLE
:
568 hFile
= NtCurrentPeb()->ProcessParameters
->StandardInput
;
571 case STD_OUTPUT_HANDLE
:
572 hFile
= NtCurrentPeb()->ProcessParameters
->StandardOutput
;
575 case STD_ERROR_HANDLE
:
576 hFile
= NtCurrentPeb()->ProcessParameters
->StandardError
;
580 /* Check for console handle */
581 if (IsConsoleHandle(hFile
))
583 if (VerifyConsoleIoHandle(hFile
))
584 return FILE_TYPE_CHAR
;
587 Status
= NtQueryVolumeInformationFile(hFile
,
590 sizeof(FILE_FS_DEVICE_INFORMATION
),
591 FileFsDeviceInformation
);
592 if (!NT_SUCCESS(Status
))
594 SetLastErrorByStatus(Status
);
595 return FILE_TYPE_UNKNOWN
;
598 switch (DeviceInfo
.DeviceType
)
600 case FILE_DEVICE_CD_ROM
:
601 case FILE_DEVICE_CD_ROM_FILE_SYSTEM
:
602 case FILE_DEVICE_CONTROLLER
:
603 case FILE_DEVICE_DATALINK
:
604 case FILE_DEVICE_DFS
:
605 case FILE_DEVICE_DISK
:
606 case FILE_DEVICE_DISK_FILE_SYSTEM
:
607 case FILE_DEVICE_VIRTUAL_DISK
:
608 return FILE_TYPE_DISK
;
610 case FILE_DEVICE_KEYBOARD
:
611 case FILE_DEVICE_MOUSE
:
612 case FILE_DEVICE_NULL
:
613 case FILE_DEVICE_PARALLEL_PORT
:
614 case FILE_DEVICE_PRINTER
:
615 case FILE_DEVICE_SERIAL_PORT
:
616 case FILE_DEVICE_SCREEN
:
617 case FILE_DEVICE_SOUND
:
618 case FILE_DEVICE_MODEM
:
619 return FILE_TYPE_CHAR
;
621 case FILE_DEVICE_NAMED_PIPE
:
622 return FILE_TYPE_PIPE
;
625 return FILE_TYPE_UNKNOWN
;
633 GetFileSize(HANDLE hFile
,
634 LPDWORD lpFileSizeHigh
)
637 FILE_STANDARD_INFORMATION FileStandard
;
638 IO_STATUS_BLOCK IoStatusBlock
;
640 errCode
= NtQueryInformationFile(hFile
,
643 sizeof(FILE_STANDARD_INFORMATION
),
644 FileStandardInformation
);
645 if (!NT_SUCCESS(errCode
))
647 SetLastErrorByStatus(errCode
);
648 if ( lpFileSizeHigh
== NULL
)
657 if ( lpFileSizeHigh
!= NULL
)
658 *lpFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
660 return FileStandard
.EndOfFile
.u
.LowPart
;
671 PLARGE_INTEGER lpFileSize
675 FILE_STANDARD_INFORMATION FileStandard
;
676 IO_STATUS_BLOCK IoStatusBlock
;
678 errCode
= NtQueryInformationFile(hFile
,
681 sizeof(FILE_STANDARD_INFORMATION
),
682 FileStandardInformation
);
683 if (!NT_SUCCESS(errCode
))
685 SetLastErrorByStatus(errCode
);
689 *lpFileSize
= FileStandard
.EndOfFile
;
699 GetCompressedFileSizeA(LPCSTR lpFileName
,
700 LPDWORD lpFileSizeHigh
)
704 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
705 return INVALID_FILE_SIZE
;
707 return GetCompressedFileSizeW(FileNameW
, lpFileSizeHigh
);
715 GetCompressedFileSizeW(LPCWSTR lpFileName
,
716 LPDWORD lpFileSizeHigh
)
718 FILE_COMPRESSION_INFORMATION FileCompression
;
720 IO_STATUS_BLOCK IoStatusBlock
;
723 hFile
= CreateFileW(lpFileName
,
728 FILE_ATTRIBUTE_NORMAL
,
731 if (hFile
== INVALID_HANDLE_VALUE
)
732 return INVALID_FILE_SIZE
;
734 errCode
= NtQueryInformationFile(hFile
,
737 sizeof(FILE_COMPRESSION_INFORMATION
),
738 FileCompressionInformation
);
742 if (!NT_SUCCESS(errCode
))
744 SetLastErrorByStatus(errCode
);
745 return INVALID_FILE_SIZE
;
749 *lpFileSizeHigh
= FileCompression
.CompressedFileSize
.u
.HighPart
;
751 SetLastError(NO_ERROR
);
752 return FileCompression
.CompressedFileSize
.u
.LowPart
;
760 GetFileInformationByHandle(HANDLE hFile
,
761 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
765 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
770 FILE_BASIC_INFORMATION FileBasic
;
771 FILE_INTERNAL_INFORMATION FileInternal
;
772 FILE_STANDARD_INFORMATION FileStandard
;
774 IO_STATUS_BLOCK IoStatusBlock
;
776 if(IsConsoleHandle(hFile
))
778 SetLastError(ERROR_INVALID_HANDLE
);
782 errCode
= NtQueryInformationFile(hFile
,
785 sizeof(FILE_BASIC_INFORMATION
),
786 FileBasicInformation
);
787 if (!NT_SUCCESS(errCode
))
789 SetLastErrorByStatus(errCode
);
793 lpFileInformation
->dwFileAttributes
= (DWORD
)FileBasic
.FileAttributes
;
795 lpFileInformation
->ftCreationTime
.dwHighDateTime
= FileBasic
.CreationTime
.u
.HighPart
;
796 lpFileInformation
->ftCreationTime
.dwLowDateTime
= FileBasic
.CreationTime
.u
.LowPart
;
798 lpFileInformation
->ftLastAccessTime
.dwHighDateTime
= FileBasic
.LastAccessTime
.u
.HighPart
;
799 lpFileInformation
->ftLastAccessTime
.dwLowDateTime
= FileBasic
.LastAccessTime
.u
.LowPart
;
801 lpFileInformation
->ftLastWriteTime
.dwHighDateTime
= FileBasic
.LastWriteTime
.u
.HighPart
;
802 lpFileInformation
->ftLastWriteTime
.dwLowDateTime
= FileBasic
.LastWriteTime
.u
.LowPart
;
804 errCode
= NtQueryInformationFile(hFile
,
807 sizeof(FILE_INTERNAL_INFORMATION
),
808 FileInternalInformation
);
809 if (!NT_SUCCESS(errCode
))
811 SetLastErrorByStatus(errCode
);
815 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
816 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
818 errCode
= NtQueryVolumeInformationFile(hFile
,
821 sizeof(FileFsVolume
),
822 FileFsVolumeInformation
);
823 if (!NT_SUCCESS(errCode
))
825 SetLastErrorByStatus(errCode
);
829 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.FileFsVolume
.VolumeSerialNumber
;
831 errCode
= NtQueryInformationFile(hFile
,
834 sizeof(FILE_STANDARD_INFORMATION
),
835 FileStandardInformation
);
836 if (!NT_SUCCESS(errCode
))
838 SetLastErrorByStatus(errCode
);
842 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
843 lpFileInformation
->nFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
844 lpFileInformation
->nFileSizeLow
= FileStandard
.EndOfFile
.u
.LowPart
;
854 GetFileAttributesExW(LPCWSTR lpFileName
,
855 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
856 LPVOID lpFileInformation
)
858 FILE_NETWORK_OPEN_INFORMATION FileInformation
;
859 OBJECT_ATTRIBUTES ObjectAttributes
;
860 UNICODE_STRING FileName
;
862 WIN32_FILE_ATTRIBUTE_DATA
* FileAttributeData
;
864 DPRINT("GetFileAttributesExW(%S) called\n", lpFileName
);
867 if (fInfoLevelId
!= GetFileExInfoStandard
|| lpFileInformation
== NULL
)
869 SetLastError(ERROR_INVALID_PARAMETER
);
873 /* Validate and translate the filename */
874 if (!RtlDosPathNameToNtPathName_U (lpFileName
,
879 DPRINT1 ("Invalid path\n");
880 SetLastError (ERROR_BAD_PATHNAME
);
884 /* build the object attributes */
885 InitializeObjectAttributes (&ObjectAttributes
,
887 OBJ_CASE_INSENSITIVE
,
891 /* Get file attributes */
892 Status
= NtQueryFullAttributesFile(&ObjectAttributes
,
895 RtlFreeUnicodeString (&FileName
);
896 if (!NT_SUCCESS (Status
))
898 DPRINT ("NtQueryFullAttributesFile() failed (Status %lx)\n", Status
);
899 SetLastErrorByStatus (Status
);
903 FileAttributeData
= (WIN32_FILE_ATTRIBUTE_DATA
*)lpFileInformation
;
904 FileAttributeData
->dwFileAttributes
= FileInformation
.FileAttributes
;
905 FileAttributeData
->ftCreationTime
.dwLowDateTime
= FileInformation
.CreationTime
.u
.LowPart
;
906 FileAttributeData
->ftCreationTime
.dwHighDateTime
= FileInformation
.CreationTime
.u
.HighPart
;
907 FileAttributeData
->ftLastAccessTime
.dwLowDateTime
= FileInformation
.LastAccessTime
.u
.LowPart
;
908 FileAttributeData
->ftLastAccessTime
.dwHighDateTime
= FileInformation
.LastAccessTime
.u
.HighPart
;
909 FileAttributeData
->ftLastWriteTime
.dwLowDateTime
= FileInformation
.LastWriteTime
.u
.LowPart
;
910 FileAttributeData
->ftLastWriteTime
.dwHighDateTime
= FileInformation
.LastWriteTime
.u
.HighPart
;
911 FileAttributeData
->nFileSizeLow
= FileInformation
.EndOfFile
.u
.LowPart
;
912 FileAttributeData
->nFileSizeHigh
= FileInformation
.EndOfFile
.u
.HighPart
;
921 GetFileAttributesExA(LPCSTR lpFileName
,
922 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
923 LPVOID lpFileInformation
)
927 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
930 return GetFileAttributesExW(FileNameW
, fInfoLevelId
, lpFileInformation
);
938 GetFileAttributesA(LPCSTR lpFileName
)
940 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
944 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
945 return INVALID_FILE_ATTRIBUTES
;
947 ret
= GetFileAttributesExW(FileNameW
, GetFileExInfoStandard
, &FileAttributeData
);
949 return ret
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
957 GetFileAttributesW(LPCWSTR lpFileName
)
959 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
962 DPRINT ("GetFileAttributeW(%S) called\n", lpFileName
);
964 Result
= GetFileAttributesExW(lpFileName
, GetFileExInfoStandard
, &FileAttributeData
);
966 return Result
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
974 GetFileAttributesByHandle(IN HANDLE hFile
,
975 OUT LPDWORD dwFileAttributes
,
978 FILE_BASIC_INFORMATION FileBasic
;
979 IO_STATUS_BLOCK IoStatusBlock
;
982 UNREFERENCED_PARAMETER(dwFlags
);
984 if (IsConsoleHandle(hFile
))
986 SetLastError(ERROR_INVALID_HANDLE
);
990 Status
= NtQueryInformationFile(hFile
,
994 FileBasicInformation
);
995 if (NT_SUCCESS(Status
))
997 *dwFileAttributes
= FileBasic
.FileAttributes
;
1001 SetLastErrorByStatus(Status
);
1010 SetFileAttributesByHandle(IN HANDLE hFile
,
1011 IN DWORD dwFileAttributes
,
1014 FILE_BASIC_INFORMATION FileBasic
;
1015 IO_STATUS_BLOCK IoStatusBlock
;
1018 UNREFERENCED_PARAMETER(dwFlags
);
1020 if (IsConsoleHandle(hFile
))
1022 SetLastError(ERROR_INVALID_HANDLE
);
1026 Status
= NtQueryInformationFile(hFile
,
1030 FileBasicInformation
);
1031 if (NT_SUCCESS(Status
))
1033 FileBasic
.FileAttributes
= dwFileAttributes
;
1035 Status
= NtSetInformationFile(hFile
,
1039 FileBasicInformation
);
1042 if (!NT_SUCCESS(Status
))
1044 SetLastErrorByStatus(Status
);
1058 DWORD dwFileAttributes
)
1062 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
1065 return SetFileAttributesW(FileNameW
, dwFileAttributes
);
1073 SetFileAttributesW(LPCWSTR lpFileName
,
1074 DWORD dwFileAttributes
)
1076 FILE_BASIC_INFORMATION FileInformation
;
1077 OBJECT_ATTRIBUTES ObjectAttributes
;
1078 IO_STATUS_BLOCK IoStatusBlock
;
1079 UNICODE_STRING FileName
;
1083 DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName
, dwFileAttributes
);
1085 /* Validate and translate the filename */
1086 if (!RtlDosPathNameToNtPathName_U (lpFileName
,
1091 DPRINT ("Invalid path\n");
1092 SetLastError (ERROR_BAD_PATHNAME
);
1095 DPRINT ("FileName: \'%wZ\'\n", &FileName
);
1097 /* build the object attributes */
1098 InitializeObjectAttributes (&ObjectAttributes
,
1100 OBJ_CASE_INSENSITIVE
,
1105 Status
= NtOpenFile (&FileHandle
,
1106 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1109 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1110 FILE_SYNCHRONOUS_IO_NONALERT
);
1111 RtlFreeUnicodeString (&FileName
);
1112 if (!NT_SUCCESS (Status
))
1114 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
1115 SetLastErrorByStatus (Status
);
1119 Status
= NtQueryInformationFile(FileHandle
,
1122 sizeof(FILE_BASIC_INFORMATION
),
1123 FileBasicInformation
);
1124 if (!NT_SUCCESS(Status
))
1126 DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status
);
1127 NtClose (FileHandle
);
1128 SetLastErrorByStatus (Status
);
1132 FileInformation
.FileAttributes
= dwFileAttributes
;
1133 Status
= NtSetInformationFile(FileHandle
,
1136 sizeof(FILE_BASIC_INFORMATION
),
1137 FileBasicInformation
);
1138 NtClose (FileHandle
);
1139 if (!NT_SUCCESS(Status
))
1141 DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status
);
1142 SetLastErrorByStatus (Status
);
1152 /***********************************************************************
1153 * GetTempFileNameA (KERNEL32.@)
1155 UINT WINAPI
GetTempFileNameA( LPCSTR path
, LPCSTR prefix
, UINT unique
, LPSTR buffer
)
1157 WCHAR BufferW
[MAX_PATH
];
1162 if (!(PathW
= FilenameA2W(path
, FALSE
)))
1166 FilenameA2W_N(PrefixW
, 3+1, prefix
, -1);
1168 ret
= GetTempFileNameW(PathW
, prefix
? PrefixW
: NULL
, unique
, BufferW
);
1171 FilenameW2A_N(buffer
, MAX_PATH
, BufferW
, -1);
1176 /***********************************************************************
1177 * GetTempFileNameW (KERNEL32.@)
1179 UINT WINAPI
GetTempFileNameW( LPCWSTR path
, LPCWSTR prefix
, UINT unique
, LPWSTR buffer
)
1181 static const WCHAR formatW
[] = L
"%x.tmp";
1186 if ( !path
|| !buffer
)
1188 SetLastError( ERROR_INVALID_PARAMETER
);
1192 wcscpy( buffer
, path
);
1193 p
= buffer
+ wcslen(buffer
);
1195 /* add a \, if there isn't one */
1196 if ((p
== buffer
) || (p
[-1] != '\\')) *p
++ = '\\';
1199 for (i
= 3; (i
> 0) && (*prefix
); i
--) *p
++ = *prefix
++;
1203 if (unique
) swprintf( p
, formatW
, unique
);
1206 /* get a "random" unique number and try to create the file */
1208 UINT num
= GetTickCount() & 0xffff;
1214 swprintf( p
, formatW
, unique
);
1215 handle
= CreateFileW( buffer
, GENERIC_WRITE
, 0, NULL
,
1216 CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, 0 );
1217 if (handle
!= INVALID_HANDLE_VALUE
)
1218 { /* We created it */
1219 DPRINT("created %S\n", buffer
);
1220 CloseHandle( handle
);
1223 if (GetLastError() != ERROR_FILE_EXISTS
&&
1224 GetLastError() != ERROR_SHARING_VIOLATION
)
1225 break; /* No need to go on */
1226 if (!(++unique
& 0xffff)) unique
= 1;
1227 } while (unique
!= num
);
1230 DPRINT("returning %S\n", buffer
);
1242 GetFileTime(HANDLE hFile
,
1243 LPFILETIME lpCreationTime
,
1244 LPFILETIME lpLastAccessTime
,
1245 LPFILETIME lpLastWriteTime
)
1247 IO_STATUS_BLOCK IoStatusBlock
;
1248 FILE_BASIC_INFORMATION FileBasic
;
1251 if(IsConsoleHandle(hFile
))
1253 SetLastError(ERROR_INVALID_HANDLE
);
1257 Status
= NtQueryInformationFile(hFile
,
1260 sizeof(FILE_BASIC_INFORMATION
),
1261 FileBasicInformation
);
1262 if (!NT_SUCCESS(Status
))
1264 SetLastErrorByStatus(Status
);
1269 memcpy(lpCreationTime
, &FileBasic
.CreationTime
, sizeof(FILETIME
));
1270 if (lpLastAccessTime
)
1271 memcpy(lpLastAccessTime
, &FileBasic
.LastAccessTime
, sizeof(FILETIME
));
1272 if (lpLastWriteTime
)
1273 memcpy(lpLastWriteTime
, &FileBasic
.LastWriteTime
, sizeof(FILETIME
));
1283 SetFileTime(HANDLE hFile
,
1284 CONST FILETIME
*lpCreationTime
,
1285 CONST FILETIME
*lpLastAccessTime
,
1286 CONST FILETIME
*lpLastWriteTime
)
1288 FILE_BASIC_INFORMATION FileBasic
;
1289 IO_STATUS_BLOCK IoStatusBlock
;
1292 if(IsConsoleHandle(hFile
))
1294 SetLastError(ERROR_INVALID_HANDLE
);
1298 Status
= NtQueryInformationFile(hFile
,
1301 sizeof(FILE_BASIC_INFORMATION
),
1302 FileBasicInformation
);
1303 if (!NT_SUCCESS(Status
))
1305 SetLastErrorByStatus(Status
);
1310 memcpy(&FileBasic
.CreationTime
, lpCreationTime
, sizeof(FILETIME
));
1311 if (lpLastAccessTime
)
1312 memcpy(&FileBasic
.LastAccessTime
, lpLastAccessTime
, sizeof(FILETIME
));
1313 if (lpLastWriteTime
)
1314 memcpy(&FileBasic
.LastWriteTime
, lpLastWriteTime
, sizeof(FILETIME
));
1316 // should i initialize changetime ???
1318 Status
= NtSetInformationFile(hFile
,
1321 sizeof(FILE_BASIC_INFORMATION
),
1322 FileBasicInformation
);
1323 if (!NT_SUCCESS(Status
))
1325 SetLastErrorByStatus(Status
);
1334 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
1339 SetEndOfFile(HANDLE hFile
)
1341 IO_STATUS_BLOCK IoStatusBlock
;
1342 FILE_END_OF_FILE_INFORMATION EndOfFileInfo
;
1343 FILE_ALLOCATION_INFORMATION FileAllocationInfo
;
1344 FILE_POSITION_INFORMATION FilePosInfo
;
1347 if(IsConsoleHandle(hFile
))
1349 SetLastError(ERROR_INVALID_HANDLE
);
1353 //get current position
1354 Status
= NtQueryInformationFile(
1358 sizeof(FILE_POSITION_INFORMATION
),
1359 FilePositionInformation
1362 if (!NT_SUCCESS(Status
)){
1363 SetLastErrorByStatus(Status
);
1367 EndOfFileInfo
.EndOfFile
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1371 This call is not supposed to free up any space after the eof marker
1372 if the file gets truncated. We have to deallocate the space explicitly afterwards.
1373 But...most file systems dispatch both FileEndOfFileInformation
1374 and FileAllocationInformation as they were the same command.
1377 Status
= NtSetInformationFile(
1379 &IoStatusBlock
, //out
1381 sizeof(FILE_END_OF_FILE_INFORMATION
),
1382 FileEndOfFileInformation
1385 if (!NT_SUCCESS(Status
)){
1386 SetLastErrorByStatus(Status
);
1390 FileAllocationInfo
.AllocationSize
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1393 Status
= NtSetInformationFile(
1395 &IoStatusBlock
, //out
1396 &FileAllocationInfo
,
1397 sizeof(FILE_ALLOCATION_INFORMATION
),
1398 FileAllocationInformation
1401 if (!NT_SUCCESS(Status
)){
1402 SetLastErrorByStatus(Status
);
1418 LONGLONG ValidDataLength
1421 IO_STATUS_BLOCK IoStatusBlock
;
1422 FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation
;
1425 ValidDataLengthInformation
.ValidDataLength
.QuadPart
= ValidDataLength
;
1427 Status
= NtSetInformationFile(
1429 &IoStatusBlock
, //out
1430 &ValidDataLengthInformation
,
1431 sizeof(FILE_VALID_DATA_LENGTH_INFORMATION
),
1432 FileValidDataLengthInformation
1435 if (!NT_SUCCESS(Status
)){
1436 SetLastErrorByStatus(Status
);
1452 LPCWSTR lpShortName
)
1456 UNICODE_STRING ShortName
;
1457 IO_STATUS_BLOCK IoStatusBlock
;
1458 PFILE_NAME_INFORMATION FileNameInfo
;
1460 if(IsConsoleHandle(hFile
))
1462 SetLastError(ERROR_INVALID_HANDLE
);
1468 SetLastError(ERROR_INVALID_PARAMETER
);
1472 RtlInitUnicodeString(&ShortName
, lpShortName
);
1474 NeededSize
= sizeof(FILE_NAME_INFORMATION
) + ShortName
.Length
+ sizeof(WCHAR
);
1475 if(!(FileNameInfo
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, NeededSize
)))
1477 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1481 FileNameInfo
->FileNameLength
= ShortName
.Length
;
1482 RtlCopyMemory(FileNameInfo
->FileName
, ShortName
.Buffer
, ShortName
.Length
);
1484 Status
= NtSetInformationFile(hFile
,
1485 &IoStatusBlock
, //out
1488 FileShortNameInformation
);
1490 RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInfo
);
1491 if(!NT_SUCCESS(Status
))
1493 SetLastErrorByStatus(Status
);
1513 if(IsConsoleHandle(hFile
))
1515 SetLastError(ERROR_INVALID_HANDLE
);
1521 SetLastError(ERROR_INVALID_PARAMETER
);
1525 if (!(ShortNameW
= FilenameA2W(lpShortName
, FALSE
)))
1528 return SetFileShortNameW(hFile
, ShortNameW
);
1537 CheckNameLegalDOS8Dot3W(
1539 LPSTR lpOemName OPTIONAL
,
1540 DWORD OemNameSize OPTIONAL
,
1541 PBOOL pbNameContainsSpaces OPTIONAL
,
1545 UNICODE_STRING Name
;
1546 ANSI_STRING AnsiName
;
1548 if(lpName
== NULL
||
1549 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1550 pbNameLegal
== NULL
)
1552 SetLastError(ERROR_INVALID_PARAMETER
);
1556 if(lpOemName
!= NULL
)
1558 AnsiName
.Buffer
= lpOemName
;
1559 AnsiName
.MaximumLength
= (USHORT
)OemNameSize
* sizeof(CHAR
);
1560 AnsiName
.Length
= 0;
1563 RtlInitUnicodeString(&Name
, lpName
);
1565 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1566 (lpOemName
? &AnsiName
: NULL
),
1567 (BOOLEAN
*)pbNameContainsSpaces
);
1578 CheckNameLegalDOS8Dot3A(
1580 LPSTR lpOemName OPTIONAL
,
1581 DWORD OemNameSize OPTIONAL
,
1582 PBOOL pbNameContainsSpaces OPTIONAL
,
1586 UNICODE_STRING Name
;
1587 ANSI_STRING AnsiName
, AnsiInputName
;
1590 if(lpName
== NULL
||
1591 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1592 pbNameLegal
== NULL
)
1594 SetLastError(ERROR_INVALID_PARAMETER
);
1598 if(lpOemName
!= NULL
)
1600 AnsiName
.Buffer
= lpOemName
;
1601 AnsiName
.MaximumLength
= (USHORT
)OemNameSize
* sizeof(CHAR
);
1602 AnsiName
.Length
= 0;
1605 RtlInitAnsiString(&AnsiInputName
, (LPSTR
)lpName
);
1607 Status
= RtlAnsiStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1609 Status
= RtlOemStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1611 if(!NT_SUCCESS(Status
))
1613 SetLastErrorByStatus(Status
);
1617 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1618 (lpOemName
? &AnsiName
: NULL
),
1619 (BOOLEAN
*)pbNameContainsSpaces
);
1621 RtlFreeUnicodeString(&Name
);
1632 GetFinalPathNameByHandleA(IN HANDLE hFile
,
1633 OUT LPSTR lpszFilePath
,
1634 IN DWORD cchFilePath
,
1637 WCHAR FilePathW
[MAX_PATH
];
1638 UNICODE_STRING FilePathU
;
1639 DWORD PrevLastError
;
1642 if (cchFilePath
!= 0 &&
1643 cchFilePath
> sizeof(FilePathW
) / sizeof(FilePathW
[0]))
1645 FilePathU
.Length
= 0;
1646 FilePathU
.MaximumLength
= (USHORT
)cchFilePath
* sizeof(WCHAR
);
1647 FilePathU
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
1649 FilePathU
.MaximumLength
);
1650 if (FilePathU
.Buffer
== NULL
)
1652 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1658 FilePathU
.Length
= 0;
1659 FilePathU
.MaximumLength
= sizeof(FilePathW
);
1660 FilePathU
.Buffer
= FilePathW
;
1663 /* save the last error code */
1664 PrevLastError
= GetLastError();
1665 SetLastError(ERROR_SUCCESS
);
1667 /* call the unicode version that does all the work */
1668 Ret
= GetFinalPathNameByHandleW(hFile
,
1673 if (GetLastError() == ERROR_SUCCESS
)
1675 /* no error, restore the last error code and convert the string */
1676 SetLastError(PrevLastError
);
1678 Ret
= FilenameU2A_FitOrFail(lpszFilePath
,
1683 /* free allocated memory if necessary */
1684 if (FilePathU
.Buffer
!= FilePathW
)
1686 RtlFreeHeap(RtlGetProcessHeap(),
1700 GetFinalPathNameByHandleW(IN HANDLE hFile
,
1701 OUT LPWSTR lpszFilePath
,
1702 IN DWORD cchFilePath
,
1705 if (dwFlags
& ~(VOLUME_NAME_DOS
| VOLUME_NAME_GUID
| VOLUME_NAME_NT
|
1706 VOLUME_NAME_NONE
| FILE_NAME_NORMALIZED
| FILE_NAME_OPENED
))
1708 SetLastError(ERROR_INVALID_PARAMETER
);
1722 SetFileBandwidthReservation(IN HANDLE hFile
,
1723 IN DWORD nPeriodMilliseconds
,
1724 IN DWORD nBytesPerPeriod
,
1725 IN BOOL bDiscardable
,
1726 OUT LPDWORD lpTransferSize
,
1727 OUT LPDWORD lpNumOutstandingRequests
)
1739 GetFileBandwidthReservation(IN HANDLE hFile
,
1740 OUT LPDWORD lpPeriodMilliseconds
,
1741 OUT LPDWORD lpBytesPerPeriod
,
1742 OUT LPBOOL pDiscardable
,
1743 OUT LPDWORD lpTransferSize
,
1744 OUT LPDWORD lpNumOutstandingRequests
)
1756 SetFileCompletionNotificationModes(IN HANDLE FileHandle
,
1759 if (Flags
& ~(FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
| FILE_SKIP_SET_EVENT_ON_HANDLE
))
1761 SetLastError(ERROR_INVALID_PARAMETER
);
1775 OpenFileById(IN HANDLE hFile
,
1776 IN LPFILE_ID_DESCRIPTOR lpFileID
,
1777 IN DWORD dwDesiredAccess
,
1778 IN DWORD dwShareMode
,
1779 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL
,
1783 return INVALID_HANDLE_VALUE
;