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 *****************************************************************/
15 /* File contains Vista Semantics */
17 #define _WIN32_WINNT 0x0600
22 #include "../include/debug.h"
25 /* GLOBALS ******************************************************************/
27 BOOL bIsFileApiAnsi
= TRUE
; // set the file api to ansi or oem
29 /* FUNCTIONS ****************************************************************/
34 FilenameA2W(LPCSTR NameA
, BOOL alloc
)
38 PUNICODE_STRING pstrW
;
41 ASSERT(NtCurrentTeb()->StaticUnicodeString
.Buffer
== NtCurrentTeb()->StaticUnicodeBuffer
);
42 ASSERT(NtCurrentTeb()->StaticUnicodeString
.MaximumLength
== sizeof(NtCurrentTeb()->StaticUnicodeBuffer
));
44 RtlInitAnsiString(&str
, NameA
);
45 pstrW
= alloc
? &strW
: &NtCurrentTeb()->StaticUnicodeString
;
48 Status
= RtlAnsiStringToUnicodeString( pstrW
, &str
, alloc
);
50 Status
= RtlOemStringToUnicodeString( pstrW
, &str
, alloc
);
52 if (NT_SUCCESS(Status
))
55 if (Status
== STATUS_BUFFER_OVERFLOW
)
56 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
58 SetLastErrorByStatus(Status
);
65 No copy/conversion is done if the dest. buffer is too small.
68 Success: number of TCHARS copied into dest. buffer NOT including nullterm
69 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
72 FilenameU2A_FitOrFail(
74 INT destLen
, /* buffer size in TCHARS incl. nullchar */
75 PUNICODE_STRING SourceU
80 ret
= bIsFileApiAnsi
? RtlUnicodeStringToAnsiSize(SourceU
) : RtlUnicodeStringToOemSize(SourceU
);
81 /* ret incl. nullchar */
83 if (DestA
&& (INT
)ret
<= destLen
)
88 str
.MaximumLength
= destLen
;
92 RtlUnicodeStringToAnsiString(&str
, SourceU
, FALSE
);
94 RtlUnicodeStringToOemString(&str
, SourceU
, FALSE
);
96 ret
= str
.Length
; /* SUCCESS: length without terminating 0 */
104 No copy/conversion is done if the dest. buffer is too small.
107 Success: number of TCHARS copied into dest. buffer NOT including nullterm
108 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
111 FilenameW2A_FitOrFail(
113 INT destLen
, /* buffer size in TCHARS incl. nullchar */
115 INT sourceLen
/* buffer size in TCHARS incl. nullchar */
120 if (sourceLen
< 0) sourceLen
= wcslen(SourceW
) + 1;
122 strW
.Buffer
= (PWCHAR
)SourceW
;
123 strW
.MaximumLength
= sourceLen
* sizeof(WCHAR
);
124 strW
.Length
= strW
.MaximumLength
- sizeof(WCHAR
);
126 return FilenameU2A_FitOrFail(DestA
, destLen
, &strW
);
131 Return: num. TCHARS copied into dest including nullterm
136 INT destlen
, /* buffer size in TCHARS incl. nullchar */
138 INT srclen
/* buffer size in TCHARS incl. nullchar */
143 if (srclen
< 0) srclen
= strlen( src
) + 1;
146 RtlMultiByteToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
148 RtlOemToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
150 if (ret
) dest
[(ret
/sizeof(WCHAR
))-1]=0;
152 return ret
/sizeof(WCHAR
);
156 Return: num. TCHARS copied into dest including nullterm
161 INT destlen
, /* buffer size in TCHARS incl. nullchar */
163 INT srclen
/* buffer size in TCHARS incl. nullchar */
168 if (srclen
< 0) srclen
= wcslen( src
) + 1;
171 RtlUnicodeToMultiByteN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
));
173 RtlUnicodeToOemN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
) );
175 if (ret
) dest
[ret
-1]=0;
186 SetFileApisToOEM(VOID
)
188 /* Set the correct Base Api */
189 Basep8BitStringToUnicodeString
= (PRTL_CONVERT_STRING
)RtlOemStringToUnicodeString
;
191 /* FIXME: Old, deprecated way */
192 bIsFileApiAnsi
= FALSE
;
201 SetFileApisToANSI(VOID
)
203 /* Set the correct Base Api */
204 Basep8BitStringToUnicodeString
= RtlAnsiStringToUnicodeString
;
206 /* FIXME: Old, deprecated way */
207 bIsFileApiAnsi
= TRUE
;
215 AreFileApisANSI(VOID
)
217 return bIsFileApiAnsi
;
225 OpenFile(LPCSTR lpFileName
,
226 LPOFSTRUCT lpReOpenBuff
,
229 OBJECT_ATTRIBUTES ObjectAttributes
;
230 IO_STATUS_BLOCK IoStatusBlock
;
231 UNICODE_STRING FileNameString
;
232 UNICODE_STRING FileNameU
;
233 ANSI_STRING FileName
;
234 WCHAR PathNameW
[MAX_PATH
];
235 HANDLE FileHandle
= NULL
;
240 DPRINT("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName
, lpReOpenBuff
, uStyle
);
242 if (lpReOpenBuff
== NULL
)
247 if ((uStyle
& OF_CREATE
) == OF_CREATE
)
250 switch (uStyle
& 0x70)
252 case OF_SHARE_EXCLUSIVE
: Sharing
= 0; break;
253 case OF_SHARE_DENY_WRITE
: Sharing
= FILE_SHARE_READ
; break;
254 case OF_SHARE_DENY_READ
: Sharing
= FILE_SHARE_WRITE
; break;
255 case OF_SHARE_DENY_NONE
:
256 case OF_SHARE_COMPAT
:
258 Sharing
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
260 return (HFILE
) CreateFileA (lpFileName
,
261 GENERIC_READ
| GENERIC_WRITE
,
265 FILE_ATTRIBUTE_NORMAL
,
269 RtlInitAnsiString (&FileName
, (LPSTR
)lpFileName
);
271 /* convert ansi (or oem) string to unicode */
273 RtlAnsiStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
275 RtlOemStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
277 Len
= SearchPathW (NULL
,
284 RtlFreeUnicodeString(&FileNameU
);
286 if (Len
== 0 || Len
> OFS_MAXPATHNAME
)
288 return (HFILE
)INVALID_HANDLE_VALUE
;
291 FileName
.Buffer
= lpReOpenBuff
->szPathName
;
293 FileName
.MaximumLength
= OFS_MAXPATHNAME
;
295 RtlInitUnicodeString(&FileNameU
, PathNameW
);
297 /* convert unicode string to ansi (or oem) */
299 RtlUnicodeStringToAnsiString (&FileName
, &FileNameU
, FALSE
);
301 RtlUnicodeStringToOemString (&FileName
, &FileNameU
, FALSE
);
303 if (!RtlDosPathNameToNtPathName_U (PathNameW
,
308 return (HFILE
)INVALID_HANDLE_VALUE
;
312 // FILE_NO_INTERMEDIATE_BUFFERING
314 if ((uStyle
& OF_PARSE
) == OF_PARSE
)
316 RtlFreeHeap(RtlGetProcessHeap(),
318 FileNameString
.Buffer
);
322 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
323 ObjectAttributes
.RootDirectory
= NULL
;
324 ObjectAttributes
.ObjectName
= &FileNameString
;
325 ObjectAttributes
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
;
326 ObjectAttributes
.SecurityDescriptor
= NULL
;
327 ObjectAttributes
.SecurityQualityOfService
= NULL
;
329 errCode
= NtOpenFile (&FileHandle
,
330 GENERIC_READ
|SYNCHRONIZE
,
334 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
336 RtlFreeHeap(RtlGetProcessHeap(),
338 FileNameString
.Buffer
);
340 lpReOpenBuff
->nErrCode
= RtlNtStatusToDosError(errCode
);
342 if (!NT_SUCCESS(errCode
))
344 SetLastErrorByStatus (errCode
);
345 return (HFILE
)INVALID_HANDLE_VALUE
;
348 return (HFILE
)FileHandle
;
356 FlushFileBuffers(HANDLE hFile
)
359 IO_STATUS_BLOCK IoStatusBlock
;
361 if (IsConsoleHandle(hFile
))
366 errCode
= NtFlushBuffersFile(hFile
,
368 if (!NT_SUCCESS(errCode
))
370 SetLastErrorByStatus(errCode
);
381 SetFilePointer(HANDLE hFile
,
382 LONG lDistanceToMove
,
383 PLONG lpDistanceToMoveHigh
,
386 FILE_POSITION_INFORMATION FilePosition
;
387 FILE_STANDARD_INFORMATION FileStandard
;
389 IO_STATUS_BLOCK IoStatusBlock
;
390 LARGE_INTEGER Distance
;
392 DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
393 hFile
,lDistanceToMove
,dwMoveMethod
);
395 if(IsConsoleHandle(hFile
))
397 SetLastError(ERROR_INVALID_HANDLE
);
401 Distance
.u
.LowPart
= lDistanceToMove
;
402 if (lpDistanceToMoveHigh
)
404 Distance
.u
.HighPart
= *lpDistanceToMoveHigh
;
406 else if (lDistanceToMove
>= 0)
408 Distance
.u
.HighPart
= 0;
412 Distance
.u
.HighPart
= -1;
418 NtQueryInformationFile(hFile
,
421 sizeof(FILE_POSITION_INFORMATION
),
422 FilePositionInformation
);
423 FilePosition
.CurrentByteOffset
.QuadPart
+= Distance
.QuadPart
;
426 NtQueryInformationFile(hFile
,
429 sizeof(FILE_STANDARD_INFORMATION
),
430 FileStandardInformation
);
431 FilePosition
.CurrentByteOffset
.QuadPart
=
432 FileStandard
.EndOfFile
.QuadPart
+ Distance
.QuadPart
;
435 FilePosition
.CurrentByteOffset
.QuadPart
= Distance
.QuadPart
;
438 SetLastError(ERROR_INVALID_PARAMETER
);
442 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
444 SetLastError(ERROR_NEGATIVE_SEEK
);
448 errCode
= NtSetInformationFile(hFile
,
451 sizeof(FILE_POSITION_INFORMATION
),
452 FilePositionInformation
);
453 if (!NT_SUCCESS(errCode
))
455 SetLastErrorByStatus(errCode
);
459 if (lpDistanceToMoveHigh
!= NULL
)
461 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
463 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
472 SetFilePointerEx(HANDLE hFile
,
473 LARGE_INTEGER liDistanceToMove
,
474 PLARGE_INTEGER lpNewFilePointer
,
477 FILE_POSITION_INFORMATION FilePosition
;
478 FILE_STANDARD_INFORMATION FileStandard
;
480 IO_STATUS_BLOCK IoStatusBlock
;
482 if(IsConsoleHandle(hFile
))
484 SetLastError(ERROR_INVALID_HANDLE
);
491 NtQueryInformationFile(hFile
,
494 sizeof(FILE_POSITION_INFORMATION
),
495 FilePositionInformation
);
496 FilePosition
.CurrentByteOffset
.QuadPart
+= liDistanceToMove
.QuadPart
;
499 NtQueryInformationFile(hFile
,
502 sizeof(FILE_STANDARD_INFORMATION
),
503 FileStandardInformation
);
504 FilePosition
.CurrentByteOffset
.QuadPart
=
505 FileStandard
.EndOfFile
.QuadPart
+ liDistanceToMove
.QuadPart
;
508 FilePosition
.CurrentByteOffset
.QuadPart
= liDistanceToMove
.QuadPart
;
511 SetLastError(ERROR_INVALID_PARAMETER
);
515 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
517 SetLastError(ERROR_NEGATIVE_SEEK
);
521 errCode
= NtSetInformationFile(hFile
,
524 sizeof(FILE_POSITION_INFORMATION
),
525 FilePositionInformation
);
526 if (!NT_SUCCESS(errCode
))
528 SetLastErrorByStatus(errCode
);
532 if (lpNewFilePointer
)
534 *lpNewFilePointer
= FilePosition
.CurrentByteOffset
;
544 GetFileType(HANDLE hFile
)
546 FILE_FS_DEVICE_INFORMATION DeviceInfo
;
547 IO_STATUS_BLOCK StatusBlock
;
550 /* Get real handle */
551 switch ((ULONG
)hFile
)
553 case STD_INPUT_HANDLE
:
554 hFile
= NtCurrentPeb()->ProcessParameters
->StandardInput
;
557 case STD_OUTPUT_HANDLE
:
558 hFile
= NtCurrentPeb()->ProcessParameters
->StandardOutput
;
561 case STD_ERROR_HANDLE
:
562 hFile
= NtCurrentPeb()->ProcessParameters
->StandardError
;
566 /* Check for console handle */
567 if (IsConsoleHandle(hFile
))
569 if (VerifyConsoleIoHandle(hFile
))
570 return FILE_TYPE_CHAR
;
573 Status
= NtQueryVolumeInformationFile(hFile
,
576 sizeof(FILE_FS_DEVICE_INFORMATION
),
577 FileFsDeviceInformation
);
578 if (!NT_SUCCESS(Status
))
580 SetLastErrorByStatus(Status
);
581 return FILE_TYPE_UNKNOWN
;
584 switch (DeviceInfo
.DeviceType
)
586 case FILE_DEVICE_CD_ROM
:
587 case FILE_DEVICE_CD_ROM_FILE_SYSTEM
:
588 case FILE_DEVICE_CONTROLLER
:
589 case FILE_DEVICE_DATALINK
:
590 case FILE_DEVICE_DFS
:
591 case FILE_DEVICE_DISK
:
592 case FILE_DEVICE_DISK_FILE_SYSTEM
:
593 case FILE_DEVICE_VIRTUAL_DISK
:
594 return FILE_TYPE_DISK
;
596 case FILE_DEVICE_KEYBOARD
:
597 case FILE_DEVICE_MOUSE
:
598 case FILE_DEVICE_NULL
:
599 case FILE_DEVICE_PARALLEL_PORT
:
600 case FILE_DEVICE_PRINTER
:
601 case FILE_DEVICE_SERIAL_PORT
:
602 case FILE_DEVICE_SCREEN
:
603 case FILE_DEVICE_SOUND
:
604 case FILE_DEVICE_MODEM
:
605 return FILE_TYPE_CHAR
;
607 case FILE_DEVICE_NAMED_PIPE
:
608 return FILE_TYPE_PIPE
;
611 return FILE_TYPE_UNKNOWN
;
619 GetFileSize(HANDLE hFile
,
620 LPDWORD lpFileSizeHigh
)
623 FILE_STANDARD_INFORMATION FileStandard
;
624 IO_STATUS_BLOCK IoStatusBlock
;
626 errCode
= NtQueryInformationFile(hFile
,
629 sizeof(FILE_STANDARD_INFORMATION
),
630 FileStandardInformation
);
631 if (!NT_SUCCESS(errCode
))
633 SetLastErrorByStatus(errCode
);
634 if ( lpFileSizeHigh
== NULL
)
643 if ( lpFileSizeHigh
!= NULL
)
644 *lpFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
646 return FileStandard
.EndOfFile
.u
.LowPart
;
657 PLARGE_INTEGER lpFileSize
661 FILE_STANDARD_INFORMATION FileStandard
;
662 IO_STATUS_BLOCK IoStatusBlock
;
664 errCode
= NtQueryInformationFile(hFile
,
667 sizeof(FILE_STANDARD_INFORMATION
),
668 FileStandardInformation
);
669 if (!NT_SUCCESS(errCode
))
671 SetLastErrorByStatus(errCode
);
675 *lpFileSize
= FileStandard
.EndOfFile
;
685 GetCompressedFileSizeA(LPCSTR lpFileName
,
686 LPDWORD lpFileSizeHigh
)
690 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
691 return INVALID_FILE_SIZE
;
693 return GetCompressedFileSizeW(FileNameW
, lpFileSizeHigh
);
701 GetCompressedFileSizeW(LPCWSTR lpFileName
,
702 LPDWORD lpFileSizeHigh
)
704 FILE_COMPRESSION_INFORMATION FileCompression
;
706 IO_STATUS_BLOCK IoStatusBlock
;
709 hFile
= CreateFileW(lpFileName
,
714 FILE_ATTRIBUTE_NORMAL
,
717 if (hFile
== INVALID_HANDLE_VALUE
)
718 return INVALID_FILE_SIZE
;
720 errCode
= NtQueryInformationFile(hFile
,
723 sizeof(FILE_COMPRESSION_INFORMATION
),
724 FileCompressionInformation
);
728 if (!NT_SUCCESS(errCode
))
730 SetLastErrorByStatus(errCode
);
731 return INVALID_FILE_SIZE
;
735 *lpFileSizeHigh
= FileCompression
.CompressedFileSize
.u
.HighPart
;
737 SetLastError(NO_ERROR
);
738 return FileCompression
.CompressedFileSize
.u
.LowPart
;
746 GetFileInformationByHandle(HANDLE hFile
,
747 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
751 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
756 FILE_BASIC_INFORMATION FileBasic
;
757 FILE_INTERNAL_INFORMATION FileInternal
;
758 FILE_STANDARD_INFORMATION FileStandard
;
760 IO_STATUS_BLOCK IoStatusBlock
;
762 if(IsConsoleHandle(hFile
))
764 SetLastError(ERROR_INVALID_HANDLE
);
768 errCode
= NtQueryInformationFile(hFile
,
771 sizeof(FILE_BASIC_INFORMATION
),
772 FileBasicInformation
);
773 if (!NT_SUCCESS(errCode
))
775 SetLastErrorByStatus(errCode
);
779 lpFileInformation
->dwFileAttributes
= (DWORD
)FileBasic
.FileAttributes
;
781 lpFileInformation
->ftCreationTime
.dwHighDateTime
= FileBasic
.CreationTime
.u
.HighPart
;
782 lpFileInformation
->ftCreationTime
.dwLowDateTime
= FileBasic
.CreationTime
.u
.LowPart
;
784 lpFileInformation
->ftLastAccessTime
.dwHighDateTime
= FileBasic
.LastAccessTime
.u
.HighPart
;
785 lpFileInformation
->ftLastAccessTime
.dwLowDateTime
= FileBasic
.LastAccessTime
.u
.LowPart
;
787 lpFileInformation
->ftLastWriteTime
.dwHighDateTime
= FileBasic
.LastWriteTime
.u
.HighPart
;
788 lpFileInformation
->ftLastWriteTime
.dwLowDateTime
= FileBasic
.LastWriteTime
.u
.LowPart
;
790 errCode
= NtQueryInformationFile(hFile
,
793 sizeof(FILE_INTERNAL_INFORMATION
),
794 FileInternalInformation
);
795 if (!NT_SUCCESS(errCode
))
797 SetLastErrorByStatus(errCode
);
801 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
802 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
804 errCode
= NtQueryVolumeInformationFile(hFile
,
807 sizeof(FileFsVolume
),
808 FileFsVolumeInformation
);
809 if (!NT_SUCCESS(errCode
))
811 SetLastErrorByStatus(errCode
);
815 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.FileFsVolume
.VolumeSerialNumber
;
817 errCode
= NtQueryInformationFile(hFile
,
820 sizeof(FILE_STANDARD_INFORMATION
),
821 FileStandardInformation
);
822 if (!NT_SUCCESS(errCode
))
824 SetLastErrorByStatus(errCode
);
828 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
829 lpFileInformation
->nFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
830 lpFileInformation
->nFileSizeLow
= FileStandard
.EndOfFile
.u
.LowPart
;
840 GetFileAttributesExW(LPCWSTR lpFileName
,
841 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
842 LPVOID lpFileInformation
)
844 FILE_NETWORK_OPEN_INFORMATION FileInformation
;
845 OBJECT_ATTRIBUTES ObjectAttributes
;
846 UNICODE_STRING FileName
;
848 WIN32_FILE_ATTRIBUTE_DATA
* FileAttributeData
;
850 DPRINT("GetFileAttributesExW(%S) called\n", lpFileName
);
853 if (fInfoLevelId
!= GetFileExInfoStandard
|| lpFileInformation
== NULL
)
855 SetLastError(ERROR_INVALID_PARAMETER
);
859 /* Validate and translate the filename */
860 if (!RtlDosPathNameToNtPathName_U (lpFileName
,
865 DPRINT1 ("Invalid path\n");
866 SetLastError (ERROR_BAD_PATHNAME
);
870 /* build the object attributes */
871 InitializeObjectAttributes (&ObjectAttributes
,
873 OBJ_CASE_INSENSITIVE
,
877 /* Get file attributes */
878 Status
= NtQueryFullAttributesFile(&ObjectAttributes
,
881 RtlFreeUnicodeString (&FileName
);
882 if (!NT_SUCCESS (Status
))
884 DPRINT ("NtQueryFullAttributesFile() failed (Status %lx)\n", Status
);
885 SetLastErrorByStatus (Status
);
889 FileAttributeData
= (WIN32_FILE_ATTRIBUTE_DATA
*)lpFileInformation
;
890 FileAttributeData
->dwFileAttributes
= FileInformation
.FileAttributes
;
891 FileAttributeData
->ftCreationTime
.dwLowDateTime
= FileInformation
.CreationTime
.u
.LowPart
;
892 FileAttributeData
->ftCreationTime
.dwHighDateTime
= FileInformation
.CreationTime
.u
.HighPart
;
893 FileAttributeData
->ftLastAccessTime
.dwLowDateTime
= FileInformation
.LastAccessTime
.u
.LowPart
;
894 FileAttributeData
->ftLastAccessTime
.dwHighDateTime
= FileInformation
.LastAccessTime
.u
.HighPart
;
895 FileAttributeData
->ftLastWriteTime
.dwLowDateTime
= FileInformation
.LastWriteTime
.u
.LowPart
;
896 FileAttributeData
->ftLastWriteTime
.dwHighDateTime
= FileInformation
.LastWriteTime
.u
.HighPart
;
897 FileAttributeData
->nFileSizeLow
= FileInformation
.EndOfFile
.u
.LowPart
;
898 FileAttributeData
->nFileSizeHigh
= FileInformation
.EndOfFile
.u
.HighPart
;
907 GetFileAttributesExA(LPCSTR lpFileName
,
908 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
909 LPVOID lpFileInformation
)
913 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
916 return GetFileAttributesExW(FileNameW
, fInfoLevelId
, lpFileInformation
);
924 GetFileAttributesA(LPCSTR lpFileName
)
926 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
930 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
931 return INVALID_FILE_ATTRIBUTES
;
933 ret
= GetFileAttributesExW(FileNameW
, GetFileExInfoStandard
, &FileAttributeData
);
935 return ret
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
943 GetFileAttributesW(LPCWSTR lpFileName
)
945 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
948 DPRINT ("GetFileAttributeW(%S) called\n", lpFileName
);
950 Result
= GetFileAttributesExW(lpFileName
, GetFileExInfoStandard
, &FileAttributeData
);
952 return Result
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
960 GetFileAttributesByHandle(IN HANDLE hFile
,
961 OUT LPDWORD dwFileAttributes
,
964 FILE_BASIC_INFORMATION FileBasic
;
965 IO_STATUS_BLOCK IoStatusBlock
;
968 UNREFERENCED_PARAMETER(dwFlags
);
970 if (IsConsoleHandle(hFile
))
972 SetLastError(ERROR_INVALID_HANDLE
);
976 Status
= NtQueryInformationFile(hFile
,
980 FileBasicInformation
);
981 if (NT_SUCCESS(Status
))
983 *dwFileAttributes
= FileBasic
.FileAttributes
;
987 SetLastErrorByStatus(Status
);
996 SetFileAttributesByHandle(IN HANDLE hFile
,
997 IN DWORD dwFileAttributes
,
1000 FILE_BASIC_INFORMATION FileBasic
;
1001 IO_STATUS_BLOCK IoStatusBlock
;
1004 UNREFERENCED_PARAMETER(dwFlags
);
1006 if (IsConsoleHandle(hFile
))
1008 SetLastError(ERROR_INVALID_HANDLE
);
1012 Status
= NtQueryInformationFile(hFile
,
1016 FileBasicInformation
);
1017 if (NT_SUCCESS(Status
))
1019 FileBasic
.FileAttributes
= dwFileAttributes
;
1021 Status
= NtSetInformationFile(hFile
,
1025 FileBasicInformation
);
1028 if (!NT_SUCCESS(Status
))
1030 SetLastErrorByStatus(Status
);
1044 DWORD dwFileAttributes
)
1048 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
1051 return SetFileAttributesW(FileNameW
, dwFileAttributes
);
1059 SetFileAttributesW(LPCWSTR lpFileName
,
1060 DWORD dwFileAttributes
)
1062 FILE_BASIC_INFORMATION FileInformation
;
1063 OBJECT_ATTRIBUTES ObjectAttributes
;
1064 IO_STATUS_BLOCK IoStatusBlock
;
1065 UNICODE_STRING FileName
;
1069 DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName
, dwFileAttributes
);
1071 /* Validate and translate the filename */
1072 if (!RtlDosPathNameToNtPathName_U (lpFileName
,
1077 DPRINT ("Invalid path\n");
1078 SetLastError (ERROR_BAD_PATHNAME
);
1081 DPRINT ("FileName: \'%wZ\'\n", &FileName
);
1083 /* build the object attributes */
1084 InitializeObjectAttributes (&ObjectAttributes
,
1086 OBJ_CASE_INSENSITIVE
,
1091 Status
= NtOpenFile (&FileHandle
,
1092 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1095 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1096 FILE_SYNCHRONOUS_IO_NONALERT
);
1097 RtlFreeUnicodeString (&FileName
);
1098 if (!NT_SUCCESS (Status
))
1100 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
1101 SetLastErrorByStatus (Status
);
1105 Status
= NtQueryInformationFile(FileHandle
,
1108 sizeof(FILE_BASIC_INFORMATION
),
1109 FileBasicInformation
);
1110 if (!NT_SUCCESS(Status
))
1112 DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status
);
1113 NtClose (FileHandle
);
1114 SetLastErrorByStatus (Status
);
1118 FileInformation
.FileAttributes
= dwFileAttributes
;
1119 Status
= NtSetInformationFile(FileHandle
,
1122 sizeof(FILE_BASIC_INFORMATION
),
1123 FileBasicInformation
);
1124 NtClose (FileHandle
);
1125 if (!NT_SUCCESS(Status
))
1127 DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status
);
1128 SetLastErrorByStatus (Status
);
1138 /***********************************************************************
1139 * GetTempFileNameA (KERNEL32.@)
1141 UINT WINAPI
GetTempFileNameA( LPCSTR path
, LPCSTR prefix
, UINT unique
, LPSTR buffer
)
1143 WCHAR BufferW
[MAX_PATH
];
1148 if (!(PathW
= FilenameA2W(path
, FALSE
)))
1152 FilenameA2W_N(PrefixW
, 3+1, prefix
, -1);
1154 ret
= GetTempFileNameW(PathW
, prefix
? PrefixW
: NULL
, unique
, BufferW
);
1157 FilenameW2A_N(buffer
, MAX_PATH
, BufferW
, -1);
1162 /***********************************************************************
1163 * GetTempFileNameW (KERNEL32.@)
1165 UINT WINAPI
GetTempFileNameW( LPCWSTR path
, LPCWSTR prefix
, UINT unique
, LPWSTR buffer
)
1167 static const WCHAR formatW
[] = L
"%x.tmp";
1172 if ( !path
|| !prefix
|| !buffer
)
1174 SetLastError( ERROR_INVALID_PARAMETER
);
1178 wcscpy( buffer
, path
);
1179 p
= buffer
+ wcslen(buffer
);
1181 /* add a \, if there isn't one */
1182 if ((p
== buffer
) || (p
[-1] != '\\')) *p
++ = '\\';
1184 for (i
= 3; (i
> 0) && (*prefix
); i
--) *p
++ = *prefix
++;
1188 if (unique
) swprintf( p
, formatW
, unique
);
1191 /* get a "random" unique number and try to create the file */
1193 UINT num
= GetTickCount() & 0xffff;
1199 swprintf( p
, formatW
, unique
);
1200 handle
= CreateFileW( buffer
, GENERIC_WRITE
, 0, NULL
,
1201 CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, 0 );
1202 if (handle
!= INVALID_HANDLE_VALUE
)
1203 { /* We created it */
1204 DPRINT("created %S\n", buffer
);
1205 CloseHandle( handle
);
1208 if (GetLastError() != ERROR_FILE_EXISTS
&&
1209 GetLastError() != ERROR_SHARING_VIOLATION
)
1210 break; /* No need to go on */
1211 if (!(++unique
& 0xffff)) unique
= 1;
1212 } while (unique
!= num
);
1215 DPRINT("returning %S\n", buffer
);
1227 GetFileTime(HANDLE hFile
,
1228 LPFILETIME lpCreationTime
,
1229 LPFILETIME lpLastAccessTime
,
1230 LPFILETIME lpLastWriteTime
)
1232 IO_STATUS_BLOCK IoStatusBlock
;
1233 FILE_BASIC_INFORMATION FileBasic
;
1236 if(IsConsoleHandle(hFile
))
1238 SetLastError(ERROR_INVALID_HANDLE
);
1242 Status
= NtQueryInformationFile(hFile
,
1245 sizeof(FILE_BASIC_INFORMATION
),
1246 FileBasicInformation
);
1247 if (!NT_SUCCESS(Status
))
1249 SetLastErrorByStatus(Status
);
1254 memcpy(lpCreationTime
, &FileBasic
.CreationTime
, sizeof(FILETIME
));
1255 if (lpLastAccessTime
)
1256 memcpy(lpLastAccessTime
, &FileBasic
.LastAccessTime
, sizeof(FILETIME
));
1257 if (lpLastWriteTime
)
1258 memcpy(lpLastWriteTime
, &FileBasic
.LastWriteTime
, sizeof(FILETIME
));
1268 SetFileTime(HANDLE hFile
,
1269 CONST FILETIME
*lpCreationTime
,
1270 CONST FILETIME
*lpLastAccessTime
,
1271 CONST FILETIME
*lpLastWriteTime
)
1273 FILE_BASIC_INFORMATION FileBasic
;
1274 IO_STATUS_BLOCK IoStatusBlock
;
1277 if(IsConsoleHandle(hFile
))
1279 SetLastError(ERROR_INVALID_HANDLE
);
1283 Status
= NtQueryInformationFile(hFile
,
1286 sizeof(FILE_BASIC_INFORMATION
),
1287 FileBasicInformation
);
1288 if (!NT_SUCCESS(Status
))
1290 SetLastErrorByStatus(Status
);
1295 memcpy(&FileBasic
.CreationTime
, lpCreationTime
, sizeof(FILETIME
));
1296 if (lpLastAccessTime
)
1297 memcpy(&FileBasic
.LastAccessTime
, lpLastAccessTime
, sizeof(FILETIME
));
1298 if (lpLastWriteTime
)
1299 memcpy(&FileBasic
.LastWriteTime
, lpLastWriteTime
, sizeof(FILETIME
));
1301 // should i initialize changetime ???
1303 Status
= NtSetInformationFile(hFile
,
1306 sizeof(FILE_BASIC_INFORMATION
),
1307 FileBasicInformation
);
1308 if (!NT_SUCCESS(Status
))
1310 SetLastErrorByStatus(Status
);
1319 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
1324 SetEndOfFile(HANDLE hFile
)
1326 IO_STATUS_BLOCK IoStatusBlock
;
1327 FILE_END_OF_FILE_INFORMATION EndOfFileInfo
;
1328 FILE_ALLOCATION_INFORMATION FileAllocationInfo
;
1329 FILE_POSITION_INFORMATION FilePosInfo
;
1332 if(IsConsoleHandle(hFile
))
1334 SetLastError(ERROR_INVALID_HANDLE
);
1338 //get current position
1339 Status
= NtQueryInformationFile(
1343 sizeof(FILE_POSITION_INFORMATION
),
1344 FilePositionInformation
1347 if (!NT_SUCCESS(Status
)){
1348 SetLastErrorByStatus(Status
);
1352 EndOfFileInfo
.EndOfFile
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1356 This call is not supposed to free up any space after the eof marker
1357 if the file gets truncated. We have to deallocate the space explicitly afterwards.
1358 But...most file systems dispatch both FileEndOfFileInformation
1359 and FileAllocationInformation as they were the same command.
1362 Status
= NtSetInformationFile(
1364 &IoStatusBlock
, //out
1366 sizeof(FILE_END_OF_FILE_INFORMATION
),
1367 FileEndOfFileInformation
1370 if (!NT_SUCCESS(Status
)){
1371 SetLastErrorByStatus(Status
);
1375 FileAllocationInfo
.AllocationSize
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1378 Status
= NtSetInformationFile(
1380 &IoStatusBlock
, //out
1381 &FileAllocationInfo
,
1382 sizeof(FILE_ALLOCATION_INFORMATION
),
1383 FileAllocationInformation
1386 if (!NT_SUCCESS(Status
)){
1387 SetLastErrorByStatus(Status
);
1403 LONGLONG ValidDataLength
1406 IO_STATUS_BLOCK IoStatusBlock
;
1407 FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation
;
1410 ValidDataLengthInformation
.ValidDataLength
.QuadPart
= ValidDataLength
;
1412 Status
= NtSetInformationFile(
1414 &IoStatusBlock
, //out
1415 &ValidDataLengthInformation
,
1416 sizeof(FILE_VALID_DATA_LENGTH_INFORMATION
),
1417 FileValidDataLengthInformation
1420 if (!NT_SUCCESS(Status
)){
1421 SetLastErrorByStatus(Status
);
1437 LPCWSTR lpShortName
)
1441 UNICODE_STRING ShortName
;
1442 IO_STATUS_BLOCK IoStatusBlock
;
1443 PFILE_NAME_INFORMATION FileNameInfo
;
1445 if(IsConsoleHandle(hFile
))
1447 SetLastError(ERROR_INVALID_HANDLE
);
1453 SetLastError(ERROR_INVALID_PARAMETER
);
1457 RtlInitUnicodeString(&ShortName
, lpShortName
);
1459 NeededSize
= sizeof(FILE_NAME_INFORMATION
) + ShortName
.Length
+ sizeof(WCHAR
);
1460 if(!(FileNameInfo
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, NeededSize
)))
1462 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1466 FileNameInfo
->FileNameLength
= ShortName
.Length
;
1467 RtlCopyMemory(FileNameInfo
->FileName
, ShortName
.Buffer
, ShortName
.Length
);
1469 Status
= NtSetInformationFile(hFile
,
1470 &IoStatusBlock
, //out
1473 FileShortNameInformation
);
1475 RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInfo
);
1476 if(!NT_SUCCESS(Status
))
1478 SetLastErrorByStatus(Status
);
1498 if(IsConsoleHandle(hFile
))
1500 SetLastError(ERROR_INVALID_HANDLE
);
1506 SetLastError(ERROR_INVALID_PARAMETER
);
1510 if (!(ShortNameW
= FilenameA2W(lpShortName
, FALSE
)))
1513 return SetFileShortNameW(hFile
, ShortNameW
);
1522 CheckNameLegalDOS8Dot3W(
1524 LPSTR lpOemName OPTIONAL
,
1525 DWORD OemNameSize OPTIONAL
,
1526 PBOOL pbNameContainsSpaces OPTIONAL
,
1530 UNICODE_STRING Name
;
1531 ANSI_STRING AnsiName
;
1533 if(lpName
== NULL
||
1534 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1535 pbNameLegal
== NULL
)
1537 SetLastError(ERROR_INVALID_PARAMETER
);
1541 if(lpOemName
!= NULL
)
1543 AnsiName
.Buffer
= lpOemName
;
1544 AnsiName
.MaximumLength
= OemNameSize
* sizeof(CHAR
);
1545 AnsiName
.Length
= 0;
1548 RtlInitUnicodeString(&Name
, lpName
);
1550 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1551 (lpOemName
? &AnsiName
: NULL
),
1552 (BOOLEAN
*)pbNameContainsSpaces
);
1563 CheckNameLegalDOS8Dot3A(
1565 LPSTR lpOemName OPTIONAL
,
1566 DWORD OemNameSize OPTIONAL
,
1567 PBOOL pbNameContainsSpaces OPTIONAL
,
1571 UNICODE_STRING Name
;
1572 ANSI_STRING AnsiName
, AnsiInputName
;
1575 if(lpName
== NULL
||
1576 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1577 pbNameLegal
== NULL
)
1579 SetLastError(ERROR_INVALID_PARAMETER
);
1583 if(lpOemName
!= NULL
)
1585 AnsiName
.Buffer
= lpOemName
;
1586 AnsiName
.MaximumLength
= OemNameSize
* sizeof(CHAR
);
1587 AnsiName
.Length
= 0;
1590 RtlInitAnsiString(&AnsiInputName
, (LPSTR
)lpName
);
1592 Status
= RtlAnsiStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1594 Status
= RtlOemStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1596 if(!NT_SUCCESS(Status
))
1598 SetLastErrorByStatus(Status
);
1602 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1603 (lpOemName
? &AnsiName
: NULL
),
1604 (BOOLEAN
*)pbNameContainsSpaces
);
1606 RtlFreeUnicodeString(&Name
);
1617 GetFinalPathNameByHandleA(IN HANDLE hFile
,
1618 OUT LPSTR lpszFilePath
,
1619 IN DWORD cchFilePath
,
1622 WCHAR FilePathW
[MAX_PATH
];
1623 UNICODE_STRING FilePathU
;
1624 DWORD PrevLastError
;
1627 if (cchFilePath
!= 0 &&
1628 cchFilePath
> sizeof(FilePathW
) / sizeof(FilePathW
[0]))
1630 FilePathU
.Length
= 0;
1631 FilePathU
.MaximumLength
= cchFilePath
* sizeof(WCHAR
);
1632 FilePathU
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
1634 FilePathU
.MaximumLength
);
1635 if (FilePathU
.Buffer
== NULL
)
1637 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1643 FilePathU
.Length
= 0;
1644 FilePathU
.MaximumLength
= sizeof(FilePathW
);
1645 FilePathU
.Buffer
= FilePathW
;
1648 /* save the last error code */
1649 PrevLastError
= GetLastError();
1650 SetLastError(ERROR_SUCCESS
);
1652 /* call the unicode version that does all the work */
1653 Ret
= GetFinalPathNameByHandleW(hFile
,
1658 if (GetLastError() == ERROR_SUCCESS
)
1660 /* no error, restore the last error code and convert the string */
1661 SetLastError(PrevLastError
);
1663 Ret
= FilenameU2A_FitOrFail(lpszFilePath
,
1668 /* free allocated memory if necessary */
1669 if (FilePathU
.Buffer
!= FilePathW
)
1671 RtlFreeHeap(RtlGetProcessHeap(),
1685 GetFinalPathNameByHandleW(IN HANDLE hFile
,
1686 OUT LPWSTR lpszFilePath
,
1687 IN DWORD cchFilePath
,
1690 if (dwFlags
& ~(VOLUME_NAME_DOS
| VOLUME_NAME_GUID
| VOLUME_NAME_NT
|
1691 VOLUME_NAME_NONE
| FILE_NAME_NORMALIZED
| FILE_NAME_OPENED
))
1693 SetLastError(ERROR_INVALID_PARAMETER
);
1707 SetFileBandwidthReservation(IN HANDLE hFile
,
1708 IN DWORD nPeriodMilliseconds
,
1709 IN DWORD nBytesPerPeriod
,
1710 IN BOOL bDiscardable
,
1711 OUT LPDWORD lpTransferSize
,
1712 OUT LPDWORD lpNumOutstandingRequests
)
1724 GetFileBandwidthReservation(IN HANDLE hFile
,
1725 OUT LPDWORD lpPeriodMilliseconds
,
1726 OUT LPDWORD lpBytesPerPeriod
,
1727 OUT LPBOOL pDiscardable
,
1728 OUT LPDWORD lpTransferSize
,
1729 OUT LPDWORD lpNumOutstandingRequests
)
1741 SetFileCompletionNotificationModes(IN HANDLE FileHandle
,
1744 if (Flags
& ~(FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
| FILE_SKIP_SET_EVENT_ON_HANDLE
))
1746 SetLastError(ERROR_INVALID_PARAMETER
);
1760 OpenFileById(IN HANDLE hFile
,
1761 IN LPFILE_ID_DESCRIPTOR lpFileID
,
1762 IN DWORD dwDesiredAccess
,
1763 IN DWORD dwShareMode
,
1764 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL
,
1768 return INVALID_HANDLE_VALUE
;