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
, (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 Distance
.u
.LowPart
= lDistanceToMove
;
398 if (lpDistanceToMoveHigh
)
400 Distance
.u
.HighPart
= *lpDistanceToMoveHigh
;
402 else if (lDistanceToMove
>= 0)
404 Distance
.u
.HighPart
= 0;
408 Distance
.u
.HighPart
= -1;
414 NtQueryInformationFile(hFile
,
417 sizeof(FILE_POSITION_INFORMATION
),
418 FilePositionInformation
);
419 FilePosition
.CurrentByteOffset
.QuadPart
+= Distance
.QuadPart
;
422 NtQueryInformationFile(hFile
,
425 sizeof(FILE_STANDARD_INFORMATION
),
426 FileStandardInformation
);
427 FilePosition
.CurrentByteOffset
.QuadPart
=
428 FileStandard
.EndOfFile
.QuadPart
+ Distance
.QuadPart
;
431 FilePosition
.CurrentByteOffset
.QuadPart
= Distance
.QuadPart
;
434 SetLastError(ERROR_INVALID_PARAMETER
);
438 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
440 SetLastError(ERROR_NEGATIVE_SEEK
);
444 errCode
= NtSetInformationFile(hFile
,
447 sizeof(FILE_POSITION_INFORMATION
),
448 FilePositionInformation
);
449 if (!NT_SUCCESS(errCode
))
451 SetLastErrorByStatus(errCode
);
455 if (lpDistanceToMoveHigh
!= NULL
)
457 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
459 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
468 SetFilePointerEx(HANDLE hFile
,
469 LARGE_INTEGER liDistanceToMove
,
470 PLARGE_INTEGER lpNewFilePointer
,
473 FILE_POSITION_INFORMATION FilePosition
;
474 FILE_STANDARD_INFORMATION FileStandard
;
476 IO_STATUS_BLOCK IoStatusBlock
;
478 if(IsConsoleHandle(hFile
))
480 SetLastError(ERROR_INVALID_HANDLE
);
487 NtQueryInformationFile(hFile
,
490 sizeof(FILE_POSITION_INFORMATION
),
491 FilePositionInformation
);
492 FilePosition
.CurrentByteOffset
.QuadPart
+= liDistanceToMove
.QuadPart
;
495 NtQueryInformationFile(hFile
,
498 sizeof(FILE_STANDARD_INFORMATION
),
499 FileStandardInformation
);
500 FilePosition
.CurrentByteOffset
.QuadPart
=
501 FileStandard
.EndOfFile
.QuadPart
+ liDistanceToMove
.QuadPart
;
504 FilePosition
.CurrentByteOffset
.QuadPart
= liDistanceToMove
.QuadPart
;
507 SetLastError(ERROR_INVALID_PARAMETER
);
511 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
513 SetLastError(ERROR_NEGATIVE_SEEK
);
517 errCode
= NtSetInformationFile(hFile
,
520 sizeof(FILE_POSITION_INFORMATION
),
521 FilePositionInformation
);
522 if (!NT_SUCCESS(errCode
))
524 SetLastErrorByStatus(errCode
);
528 if (lpNewFilePointer
)
530 *lpNewFilePointer
= FilePosition
.CurrentByteOffset
;
540 GetFileType(HANDLE hFile
)
542 FILE_FS_DEVICE_INFORMATION DeviceInfo
;
543 IO_STATUS_BLOCK StatusBlock
;
546 /* Get real handle */
547 switch ((ULONG
)hFile
)
549 case STD_INPUT_HANDLE
:
550 hFile
= NtCurrentPeb()->ProcessParameters
->StandardInput
;
553 case STD_OUTPUT_HANDLE
:
554 hFile
= NtCurrentPeb()->ProcessParameters
->StandardOutput
;
557 case STD_ERROR_HANDLE
:
558 hFile
= NtCurrentPeb()->ProcessParameters
->StandardError
;
562 /* Check for console handle */
563 if (IsConsoleHandle(hFile
))
565 if (VerifyConsoleIoHandle(hFile
))
566 return FILE_TYPE_CHAR
;
569 Status
= NtQueryVolumeInformationFile(hFile
,
572 sizeof(FILE_FS_DEVICE_INFORMATION
),
573 FileFsDeviceInformation
);
574 if (!NT_SUCCESS(Status
))
576 SetLastErrorByStatus(Status
);
577 return FILE_TYPE_UNKNOWN
;
580 switch (DeviceInfo
.DeviceType
)
582 case FILE_DEVICE_CD_ROM
:
583 case FILE_DEVICE_CD_ROM_FILE_SYSTEM
:
584 case FILE_DEVICE_CONTROLLER
:
585 case FILE_DEVICE_DATALINK
:
586 case FILE_DEVICE_DFS
:
587 case FILE_DEVICE_DISK
:
588 case FILE_DEVICE_DISK_FILE_SYSTEM
:
589 case FILE_DEVICE_VIRTUAL_DISK
:
590 return FILE_TYPE_DISK
;
592 case FILE_DEVICE_KEYBOARD
:
593 case FILE_DEVICE_MOUSE
:
594 case FILE_DEVICE_NULL
:
595 case FILE_DEVICE_PARALLEL_PORT
:
596 case FILE_DEVICE_PRINTER
:
597 case FILE_DEVICE_SERIAL_PORT
:
598 case FILE_DEVICE_SCREEN
:
599 case FILE_DEVICE_SOUND
:
600 case FILE_DEVICE_MODEM
:
601 return FILE_TYPE_CHAR
;
603 case FILE_DEVICE_NAMED_PIPE
:
604 return FILE_TYPE_PIPE
;
607 return FILE_TYPE_UNKNOWN
;
615 GetFileSize(HANDLE hFile
,
616 LPDWORD lpFileSizeHigh
)
619 FILE_STANDARD_INFORMATION FileStandard
;
620 IO_STATUS_BLOCK IoStatusBlock
;
622 errCode
= NtQueryInformationFile(hFile
,
625 sizeof(FILE_STANDARD_INFORMATION
),
626 FileStandardInformation
);
627 if (!NT_SUCCESS(errCode
))
629 SetLastErrorByStatus(errCode
);
630 if ( lpFileSizeHigh
== NULL
)
639 if ( lpFileSizeHigh
!= NULL
)
640 *lpFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
642 return FileStandard
.EndOfFile
.u
.LowPart
;
653 PLARGE_INTEGER lpFileSize
657 FILE_STANDARD_INFORMATION FileStandard
;
658 IO_STATUS_BLOCK IoStatusBlock
;
660 errCode
= NtQueryInformationFile(hFile
,
663 sizeof(FILE_STANDARD_INFORMATION
),
664 FileStandardInformation
);
665 if (!NT_SUCCESS(errCode
))
667 SetLastErrorByStatus(errCode
);
671 *lpFileSize
= FileStandard
.EndOfFile
;
681 GetCompressedFileSizeA(LPCSTR lpFileName
,
682 LPDWORD lpFileSizeHigh
)
686 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
687 return INVALID_FILE_SIZE
;
689 return GetCompressedFileSizeW(FileNameW
, lpFileSizeHigh
);
697 GetCompressedFileSizeW(LPCWSTR lpFileName
,
698 LPDWORD lpFileSizeHigh
)
700 FILE_COMPRESSION_INFORMATION FileCompression
;
702 IO_STATUS_BLOCK IoStatusBlock
;
705 hFile
= CreateFileW(lpFileName
,
710 FILE_ATTRIBUTE_NORMAL
,
713 if (hFile
== INVALID_HANDLE_VALUE
)
714 return INVALID_FILE_SIZE
;
716 errCode
= NtQueryInformationFile(hFile
,
719 sizeof(FILE_COMPRESSION_INFORMATION
),
720 FileCompressionInformation
);
724 if (!NT_SUCCESS(errCode
))
726 SetLastErrorByStatus(errCode
);
727 return INVALID_FILE_SIZE
;
731 *lpFileSizeHigh
= FileCompression
.CompressedFileSize
.u
.HighPart
;
733 SetLastError(NO_ERROR
);
734 return FileCompression
.CompressedFileSize
.u
.LowPart
;
742 GetFileInformationByHandle(HANDLE hFile
,
743 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
747 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
752 FILE_BASIC_INFORMATION FileBasic
;
753 FILE_INTERNAL_INFORMATION FileInternal
;
754 FILE_STANDARD_INFORMATION FileStandard
;
756 IO_STATUS_BLOCK IoStatusBlock
;
758 if(IsConsoleHandle(hFile
))
760 SetLastError(ERROR_INVALID_HANDLE
);
764 errCode
= NtQueryInformationFile(hFile
,
767 sizeof(FILE_BASIC_INFORMATION
),
768 FileBasicInformation
);
769 if (!NT_SUCCESS(errCode
))
771 SetLastErrorByStatus(errCode
);
775 lpFileInformation
->dwFileAttributes
= (DWORD
)FileBasic
.FileAttributes
;
777 lpFileInformation
->ftCreationTime
.dwHighDateTime
= FileBasic
.CreationTime
.u
.HighPart
;
778 lpFileInformation
->ftCreationTime
.dwLowDateTime
= FileBasic
.CreationTime
.u
.LowPart
;
780 lpFileInformation
->ftLastAccessTime
.dwHighDateTime
= FileBasic
.LastAccessTime
.u
.HighPart
;
781 lpFileInformation
->ftLastAccessTime
.dwLowDateTime
= FileBasic
.LastAccessTime
.u
.LowPart
;
783 lpFileInformation
->ftLastWriteTime
.dwHighDateTime
= FileBasic
.LastWriteTime
.u
.HighPart
;
784 lpFileInformation
->ftLastWriteTime
.dwLowDateTime
= FileBasic
.LastWriteTime
.u
.LowPart
;
786 errCode
= NtQueryInformationFile(hFile
,
789 sizeof(FILE_INTERNAL_INFORMATION
),
790 FileInternalInformation
);
791 if (!NT_SUCCESS(errCode
))
793 SetLastErrorByStatus(errCode
);
797 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
798 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
800 errCode
= NtQueryVolumeInformationFile(hFile
,
803 sizeof(FileFsVolume
),
804 FileFsVolumeInformation
);
805 if (!NT_SUCCESS(errCode
))
807 SetLastErrorByStatus(errCode
);
811 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.FileFsVolume
.VolumeSerialNumber
;
813 errCode
= NtQueryInformationFile(hFile
,
816 sizeof(FILE_STANDARD_INFORMATION
),
817 FileStandardInformation
);
818 if (!NT_SUCCESS(errCode
))
820 SetLastErrorByStatus(errCode
);
824 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
825 lpFileInformation
->nFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
826 lpFileInformation
->nFileSizeLow
= FileStandard
.EndOfFile
.u
.LowPart
;
836 GetFileAttributesExW(LPCWSTR lpFileName
,
837 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
838 LPVOID lpFileInformation
)
840 FILE_NETWORK_OPEN_INFORMATION FileInformation
;
841 OBJECT_ATTRIBUTES ObjectAttributes
;
842 UNICODE_STRING FileName
;
844 WIN32_FILE_ATTRIBUTE_DATA
* FileAttributeData
;
846 DPRINT("GetFileAttributesExW(%S) called\n", lpFileName
);
849 if (fInfoLevelId
!= GetFileExInfoStandard
|| lpFileInformation
== NULL
)
851 SetLastError(ERROR_INVALID_PARAMETER
);
855 /* Validate and translate the filename */
856 if (!RtlDosPathNameToNtPathName_U (lpFileName
,
861 DPRINT1 ("Invalid path\n");
862 SetLastError (ERROR_BAD_PATHNAME
);
866 /* build the object attributes */
867 InitializeObjectAttributes (&ObjectAttributes
,
869 OBJ_CASE_INSENSITIVE
,
873 /* Get file attributes */
874 Status
= NtQueryFullAttributesFile(&ObjectAttributes
,
877 RtlFreeUnicodeString (&FileName
);
878 if (!NT_SUCCESS (Status
))
880 DPRINT ("NtQueryFullAttributesFile() failed (Status %lx)\n", Status
);
881 SetLastErrorByStatus (Status
);
885 FileAttributeData
= (WIN32_FILE_ATTRIBUTE_DATA
*)lpFileInformation
;
886 FileAttributeData
->dwFileAttributes
= FileInformation
.FileAttributes
;
887 FileAttributeData
->ftCreationTime
.dwLowDateTime
= FileInformation
.CreationTime
.u
.LowPart
;
888 FileAttributeData
->ftCreationTime
.dwHighDateTime
= FileInformation
.CreationTime
.u
.HighPart
;
889 FileAttributeData
->ftLastAccessTime
.dwLowDateTime
= FileInformation
.LastAccessTime
.u
.LowPart
;
890 FileAttributeData
->ftLastAccessTime
.dwHighDateTime
= FileInformation
.LastAccessTime
.u
.HighPart
;
891 FileAttributeData
->ftLastWriteTime
.dwLowDateTime
= FileInformation
.LastWriteTime
.u
.LowPart
;
892 FileAttributeData
->ftLastWriteTime
.dwHighDateTime
= FileInformation
.LastWriteTime
.u
.HighPart
;
893 FileAttributeData
->nFileSizeLow
= FileInformation
.EndOfFile
.u
.LowPart
;
894 FileAttributeData
->nFileSizeHigh
= FileInformation
.EndOfFile
.u
.HighPart
;
903 GetFileAttributesExA(LPCSTR lpFileName
,
904 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
905 LPVOID lpFileInformation
)
909 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
912 return GetFileAttributesExW(FileNameW
, fInfoLevelId
, lpFileInformation
);
920 GetFileAttributesA(LPCSTR lpFileName
)
922 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
926 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
927 return INVALID_FILE_ATTRIBUTES
;
929 ret
= GetFileAttributesExW(FileNameW
, GetFileExInfoStandard
, &FileAttributeData
);
931 return ret
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
939 GetFileAttributesW(LPCWSTR lpFileName
)
941 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
944 DPRINT ("GetFileAttributeW(%S) called\n", lpFileName
);
946 Result
= GetFileAttributesExW(lpFileName
, GetFileExInfoStandard
, &FileAttributeData
);
948 return Result
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
956 GetFileAttributesByHandle(IN HANDLE hFile
,
957 OUT LPDWORD dwFileAttributes
,
960 FILE_BASIC_INFORMATION FileBasic
;
961 IO_STATUS_BLOCK IoStatusBlock
;
964 UNREFERENCED_PARAMETER(dwFlags
);
966 if (IsConsoleHandle(hFile
))
968 SetLastError(ERROR_INVALID_HANDLE
);
972 Status
= NtQueryInformationFile(hFile
,
976 FileBasicInformation
);
977 if (NT_SUCCESS(Status
))
979 *dwFileAttributes
= FileBasic
.FileAttributes
;
983 SetLastErrorByStatus(Status
);
992 SetFileAttributesByHandle(IN HANDLE hFile
,
993 IN DWORD dwFileAttributes
,
996 FILE_BASIC_INFORMATION FileBasic
;
997 IO_STATUS_BLOCK IoStatusBlock
;
1000 UNREFERENCED_PARAMETER(dwFlags
);
1002 if (IsConsoleHandle(hFile
))
1004 SetLastError(ERROR_INVALID_HANDLE
);
1008 Status
= NtQueryInformationFile(hFile
,
1012 FileBasicInformation
);
1013 if (NT_SUCCESS(Status
))
1015 FileBasic
.FileAttributes
= dwFileAttributes
;
1017 Status
= NtSetInformationFile(hFile
,
1021 FileBasicInformation
);
1024 if (!NT_SUCCESS(Status
))
1026 SetLastErrorByStatus(Status
);
1040 DWORD dwFileAttributes
)
1044 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
1047 return SetFileAttributesW(FileNameW
, dwFileAttributes
);
1055 SetFileAttributesW(LPCWSTR lpFileName
,
1056 DWORD dwFileAttributes
)
1058 FILE_BASIC_INFORMATION FileInformation
;
1059 OBJECT_ATTRIBUTES ObjectAttributes
;
1060 IO_STATUS_BLOCK IoStatusBlock
;
1061 UNICODE_STRING FileName
;
1065 DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName
, dwFileAttributes
);
1067 /* Validate and translate the filename */
1068 if (!RtlDosPathNameToNtPathName_U (lpFileName
,
1073 DPRINT ("Invalid path\n");
1074 SetLastError (ERROR_BAD_PATHNAME
);
1077 DPRINT ("FileName: \'%wZ\'\n", &FileName
);
1079 /* build the object attributes */
1080 InitializeObjectAttributes (&ObjectAttributes
,
1082 OBJ_CASE_INSENSITIVE
,
1087 Status
= NtOpenFile (&FileHandle
,
1088 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1091 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1092 FILE_SYNCHRONOUS_IO_NONALERT
);
1093 RtlFreeUnicodeString (&FileName
);
1094 if (!NT_SUCCESS (Status
))
1096 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
1097 SetLastErrorByStatus (Status
);
1101 Status
= NtQueryInformationFile(FileHandle
,
1104 sizeof(FILE_BASIC_INFORMATION
),
1105 FileBasicInformation
);
1106 if (!NT_SUCCESS(Status
))
1108 DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status
);
1109 NtClose (FileHandle
);
1110 SetLastErrorByStatus (Status
);
1114 FileInformation
.FileAttributes
= dwFileAttributes
;
1115 Status
= NtSetInformationFile(FileHandle
,
1118 sizeof(FILE_BASIC_INFORMATION
),
1119 FileBasicInformation
);
1120 NtClose (FileHandle
);
1121 if (!NT_SUCCESS(Status
))
1123 DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status
);
1124 SetLastErrorByStatus (Status
);
1134 /***********************************************************************
1135 * GetTempFileNameA (KERNEL32.@)
1137 UINT WINAPI
GetTempFileNameA( LPCSTR path
, LPCSTR prefix
, UINT unique
, LPSTR buffer
)
1139 WCHAR BufferW
[MAX_PATH
];
1144 if (!(PathW
= FilenameA2W(path
, FALSE
)))
1148 FilenameA2W_N(PrefixW
, 3+1, prefix
, -1);
1150 ret
= GetTempFileNameW(PathW
, prefix
? PrefixW
: NULL
, unique
, BufferW
);
1153 FilenameW2A_N(buffer
, MAX_PATH
, BufferW
, -1);
1158 /***********************************************************************
1159 * GetTempFileNameW (KERNEL32.@)
1161 UINT WINAPI
GetTempFileNameW( LPCWSTR path
, LPCWSTR prefix
, UINT unique
, LPWSTR buffer
)
1163 static const WCHAR formatW
[] = L
"%x.tmp";
1168 if ( !path
|| !prefix
|| !buffer
)
1170 SetLastError( ERROR_INVALID_PARAMETER
);
1174 wcscpy( buffer
, path
);
1175 p
= buffer
+ wcslen(buffer
);
1177 /* add a \, if there isn't one */
1178 if ((p
== buffer
) || (p
[-1] != '\\')) *p
++ = '\\';
1180 for (i
= 3; (i
> 0) && (*prefix
); i
--) *p
++ = *prefix
++;
1184 if (unique
) swprintf( p
, formatW
, unique
);
1187 /* get a "random" unique number and try to create the file */
1189 UINT num
= GetTickCount() & 0xffff;
1195 swprintf( p
, formatW
, unique
);
1196 handle
= CreateFileW( buffer
, GENERIC_WRITE
, 0, NULL
,
1197 CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, 0 );
1198 if (handle
!= INVALID_HANDLE_VALUE
)
1199 { /* We created it */
1200 DPRINT("created %S\n", buffer
);
1201 CloseHandle( handle
);
1204 if (GetLastError() != ERROR_FILE_EXISTS
&&
1205 GetLastError() != ERROR_SHARING_VIOLATION
)
1206 break; /* No need to go on */
1207 if (!(++unique
& 0xffff)) unique
= 1;
1208 } while (unique
!= num
);
1211 DPRINT("returning %S\n", buffer
);
1223 GetFileTime(HANDLE hFile
,
1224 LPFILETIME lpCreationTime
,
1225 LPFILETIME lpLastAccessTime
,
1226 LPFILETIME lpLastWriteTime
)
1228 IO_STATUS_BLOCK IoStatusBlock
;
1229 FILE_BASIC_INFORMATION FileBasic
;
1232 if(IsConsoleHandle(hFile
))
1234 SetLastError(ERROR_INVALID_HANDLE
);
1238 Status
= NtQueryInformationFile(hFile
,
1241 sizeof(FILE_BASIC_INFORMATION
),
1242 FileBasicInformation
);
1243 if (!NT_SUCCESS(Status
))
1245 SetLastErrorByStatus(Status
);
1250 memcpy(lpCreationTime
, &FileBasic
.CreationTime
, sizeof(FILETIME
));
1251 if (lpLastAccessTime
)
1252 memcpy(lpLastAccessTime
, &FileBasic
.LastAccessTime
, sizeof(FILETIME
));
1253 if (lpLastWriteTime
)
1254 memcpy(lpLastWriteTime
, &FileBasic
.LastWriteTime
, sizeof(FILETIME
));
1264 SetFileTime(HANDLE hFile
,
1265 CONST FILETIME
*lpCreationTime
,
1266 CONST FILETIME
*lpLastAccessTime
,
1267 CONST FILETIME
*lpLastWriteTime
)
1269 FILE_BASIC_INFORMATION FileBasic
;
1270 IO_STATUS_BLOCK IoStatusBlock
;
1273 if(IsConsoleHandle(hFile
))
1275 SetLastError(ERROR_INVALID_HANDLE
);
1279 Status
= NtQueryInformationFile(hFile
,
1282 sizeof(FILE_BASIC_INFORMATION
),
1283 FileBasicInformation
);
1284 if (!NT_SUCCESS(Status
))
1286 SetLastErrorByStatus(Status
);
1291 memcpy(&FileBasic
.CreationTime
, lpCreationTime
, sizeof(FILETIME
));
1292 if (lpLastAccessTime
)
1293 memcpy(&FileBasic
.LastAccessTime
, lpLastAccessTime
, sizeof(FILETIME
));
1294 if (lpLastWriteTime
)
1295 memcpy(&FileBasic
.LastWriteTime
, lpLastWriteTime
, sizeof(FILETIME
));
1297 // should i initialize changetime ???
1299 Status
= NtSetInformationFile(hFile
,
1302 sizeof(FILE_BASIC_INFORMATION
),
1303 FileBasicInformation
);
1304 if (!NT_SUCCESS(Status
))
1306 SetLastErrorByStatus(Status
);
1315 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
1320 SetEndOfFile(HANDLE hFile
)
1322 IO_STATUS_BLOCK IoStatusBlock
;
1323 FILE_END_OF_FILE_INFORMATION EndOfFileInfo
;
1324 FILE_ALLOCATION_INFORMATION FileAllocationInfo
;
1325 FILE_POSITION_INFORMATION FilePosInfo
;
1328 if(IsConsoleHandle(hFile
))
1330 SetLastError(ERROR_INVALID_HANDLE
);
1334 //get current position
1335 Status
= NtQueryInformationFile(
1339 sizeof(FILE_POSITION_INFORMATION
),
1340 FilePositionInformation
1343 if (!NT_SUCCESS(Status
)){
1344 SetLastErrorByStatus(Status
);
1348 EndOfFileInfo
.EndOfFile
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1352 This call is not supposed to free up any space after the eof marker
1353 if the file gets truncated. We have to deallocate the space explicitly afterwards.
1354 But...most file systems dispatch both FileEndOfFileInformation
1355 and FileAllocationInformation as they were the same command.
1358 Status
= NtSetInformationFile(
1360 &IoStatusBlock
, //out
1362 sizeof(FILE_END_OF_FILE_INFORMATION
),
1363 FileEndOfFileInformation
1366 if (!NT_SUCCESS(Status
)){
1367 SetLastErrorByStatus(Status
);
1371 FileAllocationInfo
.AllocationSize
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1374 Status
= NtSetInformationFile(
1376 &IoStatusBlock
, //out
1377 &FileAllocationInfo
,
1378 sizeof(FILE_ALLOCATION_INFORMATION
),
1379 FileAllocationInformation
1382 if (!NT_SUCCESS(Status
)){
1383 SetLastErrorByStatus(Status
);
1399 LONGLONG ValidDataLength
1402 IO_STATUS_BLOCK IoStatusBlock
;
1403 FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation
;
1406 ValidDataLengthInformation
.ValidDataLength
.QuadPart
= ValidDataLength
;
1408 Status
= NtSetInformationFile(
1410 &IoStatusBlock
, //out
1411 &ValidDataLengthInformation
,
1412 sizeof(FILE_VALID_DATA_LENGTH_INFORMATION
),
1413 FileValidDataLengthInformation
1416 if (!NT_SUCCESS(Status
)){
1417 SetLastErrorByStatus(Status
);
1433 LPCWSTR lpShortName
)
1437 UNICODE_STRING ShortName
;
1438 IO_STATUS_BLOCK IoStatusBlock
;
1439 PFILE_NAME_INFORMATION FileNameInfo
;
1441 if(IsConsoleHandle(hFile
))
1443 SetLastError(ERROR_INVALID_HANDLE
);
1449 SetLastError(ERROR_INVALID_PARAMETER
);
1453 RtlInitUnicodeString(&ShortName
, lpShortName
);
1455 NeededSize
= sizeof(FILE_NAME_INFORMATION
) + ShortName
.Length
+ sizeof(WCHAR
);
1456 if(!(FileNameInfo
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, NeededSize
)))
1458 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1462 FileNameInfo
->FileNameLength
= ShortName
.Length
;
1463 RtlCopyMemory(FileNameInfo
->FileName
, ShortName
.Buffer
, ShortName
.Length
);
1465 Status
= NtSetInformationFile(hFile
,
1466 &IoStatusBlock
, //out
1469 FileShortNameInformation
);
1471 RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInfo
);
1472 if(!NT_SUCCESS(Status
))
1474 SetLastErrorByStatus(Status
);
1494 if(IsConsoleHandle(hFile
))
1496 SetLastError(ERROR_INVALID_HANDLE
);
1502 SetLastError(ERROR_INVALID_PARAMETER
);
1506 if (!(ShortNameW
= FilenameA2W(lpShortName
, FALSE
)))
1509 return SetFileShortNameW(hFile
, ShortNameW
);
1518 CheckNameLegalDOS8Dot3W(
1520 LPSTR lpOemName OPTIONAL
,
1521 DWORD OemNameSize OPTIONAL
,
1522 PBOOL pbNameContainsSpaces OPTIONAL
,
1526 UNICODE_STRING Name
;
1527 ANSI_STRING AnsiName
;
1529 if(lpName
== NULL
||
1530 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1531 pbNameLegal
== NULL
)
1533 SetLastError(ERROR_INVALID_PARAMETER
);
1537 if(lpOemName
!= NULL
)
1539 AnsiName
.Buffer
= lpOemName
;
1540 AnsiName
.MaximumLength
= (USHORT
)OemNameSize
* sizeof(CHAR
);
1541 AnsiName
.Length
= 0;
1544 RtlInitUnicodeString(&Name
, lpName
);
1546 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1547 (lpOemName
? &AnsiName
: NULL
),
1548 (BOOLEAN
*)pbNameContainsSpaces
);
1559 CheckNameLegalDOS8Dot3A(
1561 LPSTR lpOemName OPTIONAL
,
1562 DWORD OemNameSize OPTIONAL
,
1563 PBOOL pbNameContainsSpaces OPTIONAL
,
1567 UNICODE_STRING Name
;
1568 ANSI_STRING AnsiName
, AnsiInputName
;
1571 if(lpName
== NULL
||
1572 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1573 pbNameLegal
== NULL
)
1575 SetLastError(ERROR_INVALID_PARAMETER
);
1579 if(lpOemName
!= NULL
)
1581 AnsiName
.Buffer
= lpOemName
;
1582 AnsiName
.MaximumLength
= (USHORT
)OemNameSize
* sizeof(CHAR
);
1583 AnsiName
.Length
= 0;
1586 RtlInitAnsiString(&AnsiInputName
, (LPSTR
)lpName
);
1588 Status
= RtlAnsiStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1590 Status
= RtlOemStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1592 if(!NT_SUCCESS(Status
))
1594 SetLastErrorByStatus(Status
);
1598 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1599 (lpOemName
? &AnsiName
: NULL
),
1600 (BOOLEAN
*)pbNameContainsSpaces
);
1602 RtlFreeUnicodeString(&Name
);
1613 GetFinalPathNameByHandleA(IN HANDLE hFile
,
1614 OUT LPSTR lpszFilePath
,
1615 IN DWORD cchFilePath
,
1618 WCHAR FilePathW
[MAX_PATH
];
1619 UNICODE_STRING FilePathU
;
1620 DWORD PrevLastError
;
1623 if (cchFilePath
!= 0 &&
1624 cchFilePath
> sizeof(FilePathW
) / sizeof(FilePathW
[0]))
1626 FilePathU
.Length
= 0;
1627 FilePathU
.MaximumLength
= (USHORT
)cchFilePath
* sizeof(WCHAR
);
1628 FilePathU
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
1630 FilePathU
.MaximumLength
);
1631 if (FilePathU
.Buffer
== NULL
)
1633 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1639 FilePathU
.Length
= 0;
1640 FilePathU
.MaximumLength
= sizeof(FilePathW
);
1641 FilePathU
.Buffer
= FilePathW
;
1644 /* save the last error code */
1645 PrevLastError
= GetLastError();
1646 SetLastError(ERROR_SUCCESS
);
1648 /* call the unicode version that does all the work */
1649 Ret
= GetFinalPathNameByHandleW(hFile
,
1654 if (GetLastError() == ERROR_SUCCESS
)
1656 /* no error, restore the last error code and convert the string */
1657 SetLastError(PrevLastError
);
1659 Ret
= FilenameU2A_FitOrFail(lpszFilePath
,
1664 /* free allocated memory if necessary */
1665 if (FilePathU
.Buffer
!= FilePathW
)
1667 RtlFreeHeap(RtlGetProcessHeap(),
1681 GetFinalPathNameByHandleW(IN HANDLE hFile
,
1682 OUT LPWSTR lpszFilePath
,
1683 IN DWORD cchFilePath
,
1686 if (dwFlags
& ~(VOLUME_NAME_DOS
| VOLUME_NAME_GUID
| VOLUME_NAME_NT
|
1687 VOLUME_NAME_NONE
| FILE_NAME_NORMALIZED
| FILE_NAME_OPENED
))
1689 SetLastError(ERROR_INVALID_PARAMETER
);
1703 SetFileBandwidthReservation(IN HANDLE hFile
,
1704 IN DWORD nPeriodMilliseconds
,
1705 IN DWORD nBytesPerPeriod
,
1706 IN BOOL bDiscardable
,
1707 OUT LPDWORD lpTransferSize
,
1708 OUT LPDWORD lpNumOutstandingRequests
)
1720 GetFileBandwidthReservation(IN HANDLE hFile
,
1721 OUT LPDWORD lpPeriodMilliseconds
,
1722 OUT LPDWORD lpBytesPerPeriod
,
1723 OUT LPBOOL pDiscardable
,
1724 OUT LPDWORD lpTransferSize
,
1725 OUT LPDWORD lpNumOutstandingRequests
)
1737 SetFileCompletionNotificationModes(IN HANDLE FileHandle
,
1740 if (Flags
& ~(FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
| FILE_SKIP_SET_EVENT_ON_HANDLE
))
1742 SetLastError(ERROR_INVALID_PARAMETER
);
1756 OpenFileById(IN HANDLE hFile
,
1757 IN LPFILE_ID_DESCRIPTOR lpFileID
,
1758 IN DWORD dwDesiredAccess
,
1759 IN DWORD dwShareMode
,
1760 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL
,
1764 return INVALID_HANDLE_VALUE
;