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 *****************************************************************/
16 #include <wine/debug.h>
18 WINE_DEFAULT_DEBUG_CHANNEL(kernel32file
);
20 /* GLOBALS ******************************************************************/
22 BOOL bIsFileApiAnsi
= TRUE
; // set the file api to ansi or oem
24 /* FUNCTIONS ****************************************************************/
29 FilenameA2W(LPCSTR NameA
, BOOL alloc
)
33 PUNICODE_STRING pstrW
;
36 //ASSERT(NtCurrentTeb()->StaticUnicodeString.Buffer == NtCurrentTeb()->StaticUnicodeBuffer);
37 ASSERT(NtCurrentTeb()->StaticUnicodeString
.MaximumLength
== sizeof(NtCurrentTeb()->StaticUnicodeBuffer
));
39 RtlInitAnsiString(&str
, NameA
);
40 pstrW
= alloc
? &strW
: &NtCurrentTeb()->StaticUnicodeString
;
43 Status
= RtlAnsiStringToUnicodeString( pstrW
, &str
, (BOOLEAN
)alloc
);
45 Status
= RtlOemStringToUnicodeString( pstrW
, &str
, (BOOLEAN
)alloc
);
47 if (NT_SUCCESS(Status
))
50 if (Status
== STATUS_BUFFER_OVERFLOW
)
51 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
53 SetLastErrorByStatus(Status
);
60 No copy/conversion is done if the dest. buffer is too small.
63 Success: number of TCHARS copied into dest. buffer NOT including nullterm
64 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
67 FilenameU2A_FitOrFail(
69 INT destLen
, /* buffer size in TCHARS incl. nullchar */
70 PUNICODE_STRING SourceU
75 ret
= bIsFileApiAnsi
? RtlUnicodeStringToAnsiSize(SourceU
) : RtlUnicodeStringToOemSize(SourceU
);
76 /* ret incl. nullchar */
78 if (DestA
&& (INT
)ret
<= destLen
)
83 str
.MaximumLength
= (USHORT
)destLen
;
87 RtlUnicodeStringToAnsiString(&str
, SourceU
, FALSE
);
89 RtlUnicodeStringToOemString(&str
, SourceU
, FALSE
);
91 ret
= str
.Length
; /* SUCCESS: length without terminating 0 */
99 No copy/conversion is done if the dest. buffer is too small.
102 Success: number of TCHARS copied into dest. buffer NOT including nullterm
103 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
106 FilenameW2A_FitOrFail(
108 INT destLen
, /* buffer size in TCHARS incl. nullchar */
110 INT sourceLen
/* buffer size in TCHARS incl. nullchar */
115 if (sourceLen
< 0) sourceLen
= wcslen(SourceW
) + 1;
117 strW
.Buffer
= (PWCHAR
)SourceW
;
118 strW
.MaximumLength
= sourceLen
* sizeof(WCHAR
);
119 strW
.Length
= strW
.MaximumLength
- sizeof(WCHAR
);
121 return FilenameU2A_FitOrFail(DestA
, destLen
, &strW
);
126 Return: num. TCHARS copied into dest including nullterm
131 INT destlen
, /* buffer size in TCHARS incl. nullchar */
133 INT srclen
/* buffer size in TCHARS incl. nullchar */
138 if (srclen
< 0) srclen
= strlen( src
) + 1;
141 RtlMultiByteToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
143 RtlOemToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
145 if (ret
) dest
[(ret
/sizeof(WCHAR
))-1]=0;
147 return ret
/sizeof(WCHAR
);
151 Return: num. TCHARS copied into dest including nullterm
156 INT destlen
, /* buffer size in TCHARS incl. nullchar */
158 INT srclen
/* buffer size in TCHARS incl. nullchar */
163 if (srclen
< 0) srclen
= wcslen( src
) + 1;
166 RtlUnicodeToMultiByteN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
));
168 RtlUnicodeToOemN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
) );
170 if (ret
) dest
[ret
-1]=0;
181 SetFileApisToOEM(VOID
)
183 /* Set the correct Base Api */
184 Basep8BitStringToUnicodeString
= (PRTL_CONVERT_STRING
)RtlOemStringToUnicodeString
;
186 /* FIXME: Old, deprecated way */
187 bIsFileApiAnsi
= FALSE
;
196 SetFileApisToANSI(VOID
)
198 /* Set the correct Base Api */
199 Basep8BitStringToUnicodeString
= RtlAnsiStringToUnicodeString
;
201 /* FIXME: Old, deprecated way */
202 bIsFileApiAnsi
= TRUE
;
210 AreFileApisANSI(VOID
)
212 return bIsFileApiAnsi
;
220 OpenFile(LPCSTR lpFileName
,
221 LPOFSTRUCT lpReOpenBuff
,
224 OBJECT_ATTRIBUTES ObjectAttributes
;
225 IO_STATUS_BLOCK IoStatusBlock
;
226 UNICODE_STRING FileNameString
;
227 UNICODE_STRING FileNameU
;
228 ANSI_STRING FileName
;
229 WCHAR PathNameW
[MAX_PATH
];
230 HANDLE FileHandle
= NULL
;
235 TRACE("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName
, lpReOpenBuff
, uStyle
);
237 if (lpReOpenBuff
== NULL
)
242 if ((uStyle
& OF_CREATE
) == OF_CREATE
)
245 switch (uStyle
& 0x70)
247 case OF_SHARE_EXCLUSIVE
: Sharing
= 0; break;
248 case OF_SHARE_DENY_WRITE
: Sharing
= FILE_SHARE_READ
; break;
249 case OF_SHARE_DENY_READ
: Sharing
= FILE_SHARE_WRITE
; break;
250 case OF_SHARE_DENY_NONE
:
251 case OF_SHARE_COMPAT
:
253 Sharing
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
255 return (HFILE
) CreateFileA (lpFileName
,
256 GENERIC_READ
| GENERIC_WRITE
,
260 FILE_ATTRIBUTE_NORMAL
,
264 RtlInitAnsiString (&FileName
, (LPSTR
)lpFileName
);
266 /* convert ansi (or oem) string to unicode */
268 RtlAnsiStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
270 RtlOemStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
272 Len
= SearchPathW (NULL
,
279 RtlFreeUnicodeString(&FileNameU
);
281 if (Len
== 0 || Len
> OFS_MAXPATHNAME
)
283 return (HFILE
)INVALID_HANDLE_VALUE
;
286 FileName
.Buffer
= lpReOpenBuff
->szPathName
;
288 FileName
.MaximumLength
= OFS_MAXPATHNAME
;
290 RtlInitUnicodeString(&FileNameU
, PathNameW
);
292 /* convert unicode string to ansi (or oem) */
294 RtlUnicodeStringToAnsiString (&FileName
, &FileNameU
, FALSE
);
296 RtlUnicodeStringToOemString (&FileName
, &FileNameU
, FALSE
);
298 if (!RtlDosPathNameToNtPathName_U (PathNameW
,
303 return (HFILE
)INVALID_HANDLE_VALUE
;
307 // FILE_NO_INTERMEDIATE_BUFFERING
309 if ((uStyle
& OF_PARSE
) == OF_PARSE
)
311 RtlFreeHeap(RtlGetProcessHeap(),
313 FileNameString
.Buffer
);
317 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
318 ObjectAttributes
.RootDirectory
= NULL
;
319 ObjectAttributes
.ObjectName
= &FileNameString
;
320 ObjectAttributes
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
;
321 ObjectAttributes
.SecurityDescriptor
= NULL
;
322 ObjectAttributes
.SecurityQualityOfService
= NULL
;
324 errCode
= NtOpenFile (&FileHandle
,
325 GENERIC_READ
|SYNCHRONIZE
,
329 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
331 RtlFreeHeap(RtlGetProcessHeap(),
333 FileNameString
.Buffer
);
335 lpReOpenBuff
->nErrCode
= (WORD
)RtlNtStatusToDosError(errCode
);
337 if (!NT_SUCCESS(errCode
))
339 SetLastErrorByStatus (errCode
);
340 return (HFILE
)INVALID_HANDLE_VALUE
;
343 return (HFILE
)FileHandle
;
351 FlushFileBuffers(HANDLE hFile
)
354 IO_STATUS_BLOCK IoStatusBlock
;
356 hFile
= TranslateStdHandle(hFile
);
358 if (IsConsoleHandle(hFile
))
363 errCode
= NtFlushBuffersFile(hFile
,
365 if (!NT_SUCCESS(errCode
))
367 SetLastErrorByStatus(errCode
);
378 SetFilePointer(HANDLE hFile
,
379 LONG lDistanceToMove
,
380 PLONG lpDistanceToMoveHigh
,
383 FILE_POSITION_INFORMATION FilePosition
;
384 FILE_STANDARD_INFORMATION FileStandard
;
386 IO_STATUS_BLOCK IoStatusBlock
;
387 LARGE_INTEGER Distance
;
389 TRACE("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
390 hFile
,lDistanceToMove
,dwMoveMethod
);
392 if(IsConsoleHandle(hFile
))
394 SetLastError(ERROR_INVALID_HANDLE
);
395 return INVALID_SET_FILE_POINTER
;
398 if (lpDistanceToMoveHigh
)
400 Distance
.u
.HighPart
= *lpDistanceToMoveHigh
;
401 Distance
.u
.LowPart
= lDistanceToMove
;
405 Distance
.QuadPart
= lDistanceToMove
;
411 errCode
= NtQueryInformationFile(hFile
,
414 sizeof(FILE_POSITION_INFORMATION
),
415 FilePositionInformation
);
416 FilePosition
.CurrentByteOffset
.QuadPart
+= Distance
.QuadPart
;
417 if (!NT_SUCCESS(errCode
))
419 if (lpDistanceToMoveHigh
!= NULL
)
420 *lpDistanceToMoveHigh
= -1;
421 SetLastErrorByStatus(errCode
);
422 return INVALID_SET_FILE_POINTER
;
426 errCode
= NtQueryInformationFile(hFile
,
429 sizeof(FILE_STANDARD_INFORMATION
),
430 FileStandardInformation
);
431 FilePosition
.CurrentByteOffset
.QuadPart
=
432 FileStandard
.EndOfFile
.QuadPart
+ Distance
.QuadPart
;
433 if (!NT_SUCCESS(errCode
))
435 if (lpDistanceToMoveHigh
!= NULL
)
436 *lpDistanceToMoveHigh
= -1;
437 SetLastErrorByStatus(errCode
);
438 return INVALID_SET_FILE_POINTER
;
442 FilePosition
.CurrentByteOffset
.QuadPart
= Distance
.QuadPart
;
445 SetLastError(ERROR_INVALID_PARAMETER
);
446 return INVALID_SET_FILE_POINTER
;
449 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
451 SetLastError(ERROR_NEGATIVE_SEEK
);
452 return INVALID_SET_FILE_POINTER
;
455 if (lpDistanceToMoveHigh
== NULL
&& FilePosition
.CurrentByteOffset
.HighPart
!= 0)
457 /* If we're moving the pointer outside of the 32 bit boundaries but
458 the application only passed a 32 bit value we need to bail out! */
459 SetLastError(ERROR_INVALID_PARAMETER
);
460 return INVALID_SET_FILE_POINTER
;
463 errCode
= NtSetInformationFile(hFile
,
466 sizeof(FILE_POSITION_INFORMATION
),
467 FilePositionInformation
);
468 if (!NT_SUCCESS(errCode
))
470 if (lpDistanceToMoveHigh
!= NULL
)
471 *lpDistanceToMoveHigh
= -1;
473 SetLastErrorByStatus(errCode
);
474 return INVALID_SET_FILE_POINTER
;
477 if (lpDistanceToMoveHigh
!= NULL
)
479 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
482 if (FilePosition
.CurrentByteOffset
.u
.LowPart
== -1)
484 /* The value of -1 is valid here, especially when the new
485 file position is greater than 4 GB. Since NtSetInformationFile
486 succeeded we never set an error code and we explicitly need
487 to clear a previously set error code in this case, which
488 an application will check if INVALID_SET_FILE_POINTER is returned! */
489 SetLastError(ERROR_SUCCESS
);
492 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
501 SetFilePointerEx(HANDLE hFile
,
502 LARGE_INTEGER liDistanceToMove
,
503 PLARGE_INTEGER lpNewFilePointer
,
506 FILE_POSITION_INFORMATION FilePosition
;
507 FILE_STANDARD_INFORMATION FileStandard
;
509 IO_STATUS_BLOCK IoStatusBlock
;
511 if(IsConsoleHandle(hFile
))
513 SetLastError(ERROR_INVALID_HANDLE
);
520 NtQueryInformationFile(hFile
,
523 sizeof(FILE_POSITION_INFORMATION
),
524 FilePositionInformation
);
525 FilePosition
.CurrentByteOffset
.QuadPart
+= liDistanceToMove
.QuadPart
;
528 NtQueryInformationFile(hFile
,
531 sizeof(FILE_STANDARD_INFORMATION
),
532 FileStandardInformation
);
533 FilePosition
.CurrentByteOffset
.QuadPart
=
534 FileStandard
.EndOfFile
.QuadPart
+ liDistanceToMove
.QuadPart
;
537 FilePosition
.CurrentByteOffset
.QuadPart
= liDistanceToMove
.QuadPart
;
540 SetLastError(ERROR_INVALID_PARAMETER
);
544 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
546 SetLastError(ERROR_NEGATIVE_SEEK
);
550 errCode
= NtSetInformationFile(hFile
,
553 sizeof(FILE_POSITION_INFORMATION
),
554 FilePositionInformation
);
555 if (!NT_SUCCESS(errCode
))
557 SetLastErrorByStatus(errCode
);
561 if (lpNewFilePointer
)
563 *lpNewFilePointer
= FilePosition
.CurrentByteOffset
;
573 GetFileType(HANDLE hFile
)
575 FILE_FS_DEVICE_INFORMATION DeviceInfo
;
576 IO_STATUS_BLOCK StatusBlock
;
579 /* Get real handle */
580 hFile
= TranslateStdHandle(hFile
);
582 /* Check for console handle */
583 if (IsConsoleHandle(hFile
))
585 if (VerifyConsoleIoHandle(hFile
))
586 return FILE_TYPE_CHAR
;
589 Status
= NtQueryVolumeInformationFile(hFile
,
592 sizeof(FILE_FS_DEVICE_INFORMATION
),
593 FileFsDeviceInformation
);
594 if (!NT_SUCCESS(Status
))
596 SetLastErrorByStatus(Status
);
597 return FILE_TYPE_UNKNOWN
;
600 switch (DeviceInfo
.DeviceType
)
602 case FILE_DEVICE_CD_ROM
:
603 case FILE_DEVICE_CD_ROM_FILE_SYSTEM
:
604 case FILE_DEVICE_CONTROLLER
:
605 case FILE_DEVICE_DATALINK
:
606 case FILE_DEVICE_DFS
:
607 case FILE_DEVICE_DISK
:
608 case FILE_DEVICE_DISK_FILE_SYSTEM
:
609 case FILE_DEVICE_VIRTUAL_DISK
:
610 return FILE_TYPE_DISK
;
612 case FILE_DEVICE_KEYBOARD
:
613 case FILE_DEVICE_MOUSE
:
614 case FILE_DEVICE_NULL
:
615 case FILE_DEVICE_PARALLEL_PORT
:
616 case FILE_DEVICE_PRINTER
:
617 case FILE_DEVICE_SERIAL_PORT
:
618 case FILE_DEVICE_SCREEN
:
619 case FILE_DEVICE_SOUND
:
620 case FILE_DEVICE_MODEM
:
621 return FILE_TYPE_CHAR
;
623 case FILE_DEVICE_NAMED_PIPE
:
624 return FILE_TYPE_PIPE
;
627 return FILE_TYPE_UNKNOWN
;
635 GetFileSize(HANDLE hFile
,
636 LPDWORD lpFileSizeHigh
)
639 FILE_STANDARD_INFORMATION FileStandard
;
640 IO_STATUS_BLOCK IoStatusBlock
;
642 errCode
= NtQueryInformationFile(hFile
,
645 sizeof(FILE_STANDARD_INFORMATION
),
646 FileStandardInformation
);
647 if (!NT_SUCCESS(errCode
))
649 SetLastErrorByStatus(errCode
);
650 if ( lpFileSizeHigh
== NULL
)
659 if ( lpFileSizeHigh
!= NULL
)
660 *lpFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
662 return FileStandard
.EndOfFile
.u
.LowPart
;
673 PLARGE_INTEGER lpFileSize
677 FILE_STANDARD_INFORMATION FileStandard
;
678 IO_STATUS_BLOCK IoStatusBlock
;
680 errCode
= NtQueryInformationFile(hFile
,
683 sizeof(FILE_STANDARD_INFORMATION
),
684 FileStandardInformation
);
685 if (!NT_SUCCESS(errCode
))
687 SetLastErrorByStatus(errCode
);
691 *lpFileSize
= FileStandard
.EndOfFile
;
701 GetCompressedFileSizeA(LPCSTR lpFileName
,
702 LPDWORD lpFileSizeHigh
)
706 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
707 return INVALID_FILE_SIZE
;
709 return GetCompressedFileSizeW(FileNameW
, lpFileSizeHigh
);
717 GetCompressedFileSizeW(LPCWSTR lpFileName
,
718 LPDWORD lpFileSizeHigh
)
720 FILE_COMPRESSION_INFORMATION FileCompression
;
722 IO_STATUS_BLOCK IoStatusBlock
;
725 hFile
= CreateFileW(lpFileName
,
730 FILE_ATTRIBUTE_NORMAL
,
733 if (hFile
== INVALID_HANDLE_VALUE
)
734 return INVALID_FILE_SIZE
;
736 errCode
= NtQueryInformationFile(hFile
,
739 sizeof(FILE_COMPRESSION_INFORMATION
),
740 FileCompressionInformation
);
744 if (!NT_SUCCESS(errCode
))
746 SetLastErrorByStatus(errCode
);
747 return INVALID_FILE_SIZE
;
751 *lpFileSizeHigh
= FileCompression
.CompressedFileSize
.u
.HighPart
;
753 SetLastError(NO_ERROR
);
754 return FileCompression
.CompressedFileSize
.u
.LowPart
;
762 GetFileInformationByHandle(HANDLE hFile
,
763 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
767 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
772 FILE_BASIC_INFORMATION FileBasic
;
773 FILE_INTERNAL_INFORMATION FileInternal
;
774 FILE_STANDARD_INFORMATION FileStandard
;
776 IO_STATUS_BLOCK IoStatusBlock
;
778 if(IsConsoleHandle(hFile
))
780 SetLastError(ERROR_INVALID_HANDLE
);
784 errCode
= NtQueryInformationFile(hFile
,
787 sizeof(FILE_BASIC_INFORMATION
),
788 FileBasicInformation
);
789 if (!NT_SUCCESS(errCode
))
791 SetLastErrorByStatus(errCode
);
795 lpFileInformation
->dwFileAttributes
= (DWORD
)FileBasic
.FileAttributes
;
797 lpFileInformation
->ftCreationTime
.dwHighDateTime
= FileBasic
.CreationTime
.u
.HighPart
;
798 lpFileInformation
->ftCreationTime
.dwLowDateTime
= FileBasic
.CreationTime
.u
.LowPart
;
800 lpFileInformation
->ftLastAccessTime
.dwHighDateTime
= FileBasic
.LastAccessTime
.u
.HighPart
;
801 lpFileInformation
->ftLastAccessTime
.dwLowDateTime
= FileBasic
.LastAccessTime
.u
.LowPart
;
803 lpFileInformation
->ftLastWriteTime
.dwHighDateTime
= FileBasic
.LastWriteTime
.u
.HighPart
;
804 lpFileInformation
->ftLastWriteTime
.dwLowDateTime
= FileBasic
.LastWriteTime
.u
.LowPart
;
806 errCode
= NtQueryInformationFile(hFile
,
809 sizeof(FILE_INTERNAL_INFORMATION
),
810 FileInternalInformation
);
811 if (!NT_SUCCESS(errCode
))
813 SetLastErrorByStatus(errCode
);
817 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
818 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
820 errCode
= NtQueryVolumeInformationFile(hFile
,
823 sizeof(FileFsVolume
),
824 FileFsVolumeInformation
);
825 if (!NT_SUCCESS(errCode
))
827 SetLastErrorByStatus(errCode
);
831 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.FileFsVolume
.VolumeSerialNumber
;
833 errCode
= NtQueryInformationFile(hFile
,
836 sizeof(FILE_STANDARD_INFORMATION
),
837 FileStandardInformation
);
838 if (!NT_SUCCESS(errCode
))
840 SetLastErrorByStatus(errCode
);
844 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
845 lpFileInformation
->nFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
846 lpFileInformation
->nFileSizeLow
= FileStandard
.EndOfFile
.u
.LowPart
;
856 GetFileAttributesExW(LPCWSTR lpFileName
,
857 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
858 LPVOID lpFileInformation
)
860 FILE_NETWORK_OPEN_INFORMATION FileInformation
;
861 OBJECT_ATTRIBUTES ObjectAttributes
;
862 UNICODE_STRING FileName
;
864 WIN32_FILE_ATTRIBUTE_DATA
* FileAttributeData
;
866 TRACE("GetFileAttributesExW(%S) called\n", lpFileName
);
869 if (fInfoLevelId
!= GetFileExInfoStandard
|| lpFileInformation
== NULL
)
871 SetLastError(ERROR_INVALID_PARAMETER
);
875 /* Validate and translate the filename */
876 if (!RtlDosPathNameToNtPathName_U (lpFileName
,
881 WARN ("Invalid path '%S'\n", lpFileName
);
882 SetLastError (ERROR_BAD_PATHNAME
);
886 /* build the object attributes */
887 InitializeObjectAttributes (&ObjectAttributes
,
889 OBJ_CASE_INSENSITIVE
,
893 /* Get file attributes */
894 Status
= NtQueryFullAttributesFile(&ObjectAttributes
,
897 RtlFreeUnicodeString (&FileName
);
898 if (!NT_SUCCESS (Status
))
900 WARN ("NtQueryFullAttributesFile() failed (Status %lx)\n", Status
);
901 SetLastErrorByStatus (Status
);
905 FileAttributeData
= (WIN32_FILE_ATTRIBUTE_DATA
*)lpFileInformation
;
906 FileAttributeData
->dwFileAttributes
= FileInformation
.FileAttributes
;
907 FileAttributeData
->ftCreationTime
.dwLowDateTime
= FileInformation
.CreationTime
.u
.LowPart
;
908 FileAttributeData
->ftCreationTime
.dwHighDateTime
= FileInformation
.CreationTime
.u
.HighPart
;
909 FileAttributeData
->ftLastAccessTime
.dwLowDateTime
= FileInformation
.LastAccessTime
.u
.LowPart
;
910 FileAttributeData
->ftLastAccessTime
.dwHighDateTime
= FileInformation
.LastAccessTime
.u
.HighPart
;
911 FileAttributeData
->ftLastWriteTime
.dwLowDateTime
= FileInformation
.LastWriteTime
.u
.LowPart
;
912 FileAttributeData
->ftLastWriteTime
.dwHighDateTime
= FileInformation
.LastWriteTime
.u
.HighPart
;
913 FileAttributeData
->nFileSizeLow
= FileInformation
.EndOfFile
.u
.LowPart
;
914 FileAttributeData
->nFileSizeHigh
= FileInformation
.EndOfFile
.u
.HighPart
;
923 GetFileAttributesExA(LPCSTR lpFileName
,
924 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
925 LPVOID lpFileInformation
)
929 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
932 return GetFileAttributesExW(FileNameW
, fInfoLevelId
, lpFileInformation
);
940 GetFileAttributesA(LPCSTR lpFileName
)
942 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
946 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
947 return INVALID_FILE_ATTRIBUTES
;
949 ret
= GetFileAttributesExW(FileNameW
, GetFileExInfoStandard
, &FileAttributeData
);
951 return ret
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
959 GetFileAttributesW(LPCWSTR lpFileName
)
961 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
964 TRACE ("GetFileAttributeW(%S) called\n", lpFileName
);
966 Result
= GetFileAttributesExW(lpFileName
, GetFileExInfoStandard
, &FileAttributeData
);
968 return Result
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
976 GetFileAttributesByHandle(IN HANDLE hFile
,
977 OUT LPDWORD dwFileAttributes
,
980 FILE_BASIC_INFORMATION FileBasic
;
981 IO_STATUS_BLOCK IoStatusBlock
;
984 UNREFERENCED_PARAMETER(dwFlags
);
986 if (IsConsoleHandle(hFile
))
988 SetLastError(ERROR_INVALID_HANDLE
);
992 Status
= NtQueryInformationFile(hFile
,
996 FileBasicInformation
);
997 if (NT_SUCCESS(Status
))
999 *dwFileAttributes
= FileBasic
.FileAttributes
;
1003 SetLastErrorByStatus(Status
);
1012 SetFileAttributesByHandle(IN HANDLE hFile
,
1013 IN DWORD dwFileAttributes
,
1016 FILE_BASIC_INFORMATION FileBasic
;
1017 IO_STATUS_BLOCK IoStatusBlock
;
1020 UNREFERENCED_PARAMETER(dwFlags
);
1022 if (IsConsoleHandle(hFile
))
1024 SetLastError(ERROR_INVALID_HANDLE
);
1028 Status
= NtQueryInformationFile(hFile
,
1032 FileBasicInformation
);
1033 if (NT_SUCCESS(Status
))
1035 FileBasic
.FileAttributes
= dwFileAttributes
;
1037 Status
= NtSetInformationFile(hFile
,
1041 FileBasicInformation
);
1044 if (!NT_SUCCESS(Status
))
1046 SetLastErrorByStatus(Status
);
1060 DWORD dwFileAttributes
)
1064 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
1067 return SetFileAttributesW(FileNameW
, dwFileAttributes
);
1075 SetFileAttributesW(LPCWSTR lpFileName
,
1076 DWORD dwFileAttributes
)
1078 FILE_BASIC_INFORMATION FileInformation
;
1079 OBJECT_ATTRIBUTES ObjectAttributes
;
1080 IO_STATUS_BLOCK IoStatusBlock
;
1081 UNICODE_STRING FileName
;
1085 TRACE ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName
, dwFileAttributes
);
1087 /* Validate and translate the filename */
1088 if (!RtlDosPathNameToNtPathName_U (lpFileName
,
1093 WARN ("Invalid path\n");
1094 SetLastError (ERROR_BAD_PATHNAME
);
1097 TRACE ("FileName: \'%wZ\'\n", &FileName
);
1099 /* build the object attributes */
1100 InitializeObjectAttributes (&ObjectAttributes
,
1102 OBJ_CASE_INSENSITIVE
,
1107 Status
= NtOpenFile (&FileHandle
,
1108 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1111 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1112 FILE_SYNCHRONOUS_IO_NONALERT
);
1113 RtlFreeUnicodeString (&FileName
);
1114 if (!NT_SUCCESS (Status
))
1116 WARN ("NtOpenFile() failed (Status %lx)\n", Status
);
1117 SetLastErrorByStatus (Status
);
1121 Status
= NtQueryInformationFile(FileHandle
,
1124 sizeof(FILE_BASIC_INFORMATION
),
1125 FileBasicInformation
);
1126 if (!NT_SUCCESS(Status
))
1128 WARN ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status
);
1129 NtClose (FileHandle
);
1130 SetLastErrorByStatus (Status
);
1134 FileInformation
.FileAttributes
= dwFileAttributes
;
1135 Status
= NtSetInformationFile(FileHandle
,
1138 sizeof(FILE_BASIC_INFORMATION
),
1139 FileBasicInformation
);
1140 NtClose (FileHandle
);
1141 if (!NT_SUCCESS(Status
))
1143 WARN ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status
);
1144 SetLastErrorByStatus (Status
);
1154 /***********************************************************************
1155 * GetTempFileNameA (KERNEL32.@)
1157 UINT WINAPI
GetTempFileNameA( LPCSTR path
, LPCSTR prefix
, UINT unique
, LPSTR buffer
)
1159 WCHAR BufferW
[MAX_PATH
];
1164 if (!(PathW
= FilenameA2W(path
, FALSE
)))
1168 FilenameA2W_N(PrefixW
, 3+1, prefix
, -1);
1170 ret
= GetTempFileNameW(PathW
, prefix
? PrefixW
: NULL
, unique
, BufferW
);
1173 FilenameW2A_N(buffer
, MAX_PATH
, BufferW
, -1);
1178 /***********************************************************************
1179 * GetTempFileNameW (KERNEL32.@)
1181 UINT WINAPI
GetTempFileNameW( LPCWSTR path
, LPCWSTR prefix
, UINT unique
, LPWSTR buffer
)
1183 static const WCHAR formatW
[] = L
"%x.tmp";
1188 if ( !path
|| !buffer
)
1190 SetLastError( ERROR_INVALID_PARAMETER
);
1194 wcscpy( buffer
, path
);
1195 p
= buffer
+ wcslen(buffer
);
1197 /* add a \, if there isn't one */
1198 if ((p
== buffer
) || (p
[-1] != '\\')) *p
++ = '\\';
1201 for (i
= 3; (i
> 0) && (*prefix
); i
--) *p
++ = *prefix
++;
1205 if (unique
) swprintf( p
, formatW
, unique
);
1208 /* get a "random" unique number and try to create the file */
1210 UINT num
= GetTickCount() & 0xffff;
1216 swprintf( p
, formatW
, unique
);
1217 handle
= CreateFileW( buffer
, GENERIC_WRITE
, 0, NULL
,
1218 CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, 0 );
1219 if (handle
!= INVALID_HANDLE_VALUE
)
1220 { /* We created it */
1221 TRACE("created %S\n", buffer
);
1222 CloseHandle( handle
);
1225 if (GetLastError() != ERROR_FILE_EXISTS
&&
1226 GetLastError() != ERROR_SHARING_VIOLATION
)
1227 break; /* No need to go on */
1228 if (!(++unique
& 0xffff)) unique
= 1;
1229 } while (unique
!= num
);
1232 TRACE("returning %S\n", buffer
);
1244 GetFileTime(HANDLE hFile
,
1245 LPFILETIME lpCreationTime
,
1246 LPFILETIME lpLastAccessTime
,
1247 LPFILETIME lpLastWriteTime
)
1249 IO_STATUS_BLOCK IoStatusBlock
;
1250 FILE_BASIC_INFORMATION FileBasic
;
1253 if(IsConsoleHandle(hFile
))
1255 SetLastError(ERROR_INVALID_HANDLE
);
1259 Status
= NtQueryInformationFile(hFile
,
1262 sizeof(FILE_BASIC_INFORMATION
),
1263 FileBasicInformation
);
1264 if (!NT_SUCCESS(Status
))
1266 SetLastErrorByStatus(Status
);
1271 memcpy(lpCreationTime
, &FileBasic
.CreationTime
, sizeof(FILETIME
));
1272 if (lpLastAccessTime
)
1273 memcpy(lpLastAccessTime
, &FileBasic
.LastAccessTime
, sizeof(FILETIME
));
1274 if (lpLastWriteTime
)
1275 memcpy(lpLastWriteTime
, &FileBasic
.LastWriteTime
, sizeof(FILETIME
));
1285 SetFileTime(HANDLE hFile
,
1286 CONST FILETIME
*lpCreationTime
,
1287 CONST FILETIME
*lpLastAccessTime
,
1288 CONST FILETIME
*lpLastWriteTime
)
1290 FILE_BASIC_INFORMATION FileBasic
;
1291 IO_STATUS_BLOCK IoStatusBlock
;
1294 if(IsConsoleHandle(hFile
))
1296 SetLastError(ERROR_INVALID_HANDLE
);
1300 Status
= NtQueryInformationFile(hFile
,
1303 sizeof(FILE_BASIC_INFORMATION
),
1304 FileBasicInformation
);
1305 if (!NT_SUCCESS(Status
))
1307 SetLastErrorByStatus(Status
);
1312 memcpy(&FileBasic
.CreationTime
, lpCreationTime
, sizeof(FILETIME
));
1313 if (lpLastAccessTime
)
1314 memcpy(&FileBasic
.LastAccessTime
, lpLastAccessTime
, sizeof(FILETIME
));
1315 if (lpLastWriteTime
)
1316 memcpy(&FileBasic
.LastWriteTime
, lpLastWriteTime
, sizeof(FILETIME
));
1318 // should i initialize changetime ???
1320 Status
= NtSetInformationFile(hFile
,
1323 sizeof(FILE_BASIC_INFORMATION
),
1324 FileBasicInformation
);
1325 if (!NT_SUCCESS(Status
))
1327 SetLastErrorByStatus(Status
);
1336 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
1341 SetEndOfFile(HANDLE hFile
)
1343 IO_STATUS_BLOCK IoStatusBlock
;
1344 FILE_END_OF_FILE_INFORMATION EndOfFileInfo
;
1345 FILE_ALLOCATION_INFORMATION FileAllocationInfo
;
1346 FILE_POSITION_INFORMATION FilePosInfo
;
1349 if(IsConsoleHandle(hFile
))
1351 SetLastError(ERROR_INVALID_HANDLE
);
1355 //get current position
1356 Status
= NtQueryInformationFile(
1360 sizeof(FILE_POSITION_INFORMATION
),
1361 FilePositionInformation
1364 if (!NT_SUCCESS(Status
)){
1365 SetLastErrorByStatus(Status
);
1369 EndOfFileInfo
.EndOfFile
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1373 This call is not supposed to free up any space after the eof marker
1374 if the file gets truncated. We have to deallocate the space explicitly afterwards.
1375 But...most file systems dispatch both FileEndOfFileInformation
1376 and FileAllocationInformation as they were the same command.
1379 Status
= NtSetInformationFile(
1381 &IoStatusBlock
, //out
1383 sizeof(FILE_END_OF_FILE_INFORMATION
),
1384 FileEndOfFileInformation
1387 if (!NT_SUCCESS(Status
)){
1388 SetLastErrorByStatus(Status
);
1392 FileAllocationInfo
.AllocationSize
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1395 Status
= NtSetInformationFile(
1397 &IoStatusBlock
, //out
1398 &FileAllocationInfo
,
1399 sizeof(FILE_ALLOCATION_INFORMATION
),
1400 FileAllocationInformation
1403 if (!NT_SUCCESS(Status
)){
1404 SetLastErrorByStatus(Status
);
1420 LONGLONG ValidDataLength
1423 IO_STATUS_BLOCK IoStatusBlock
;
1424 FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation
;
1427 ValidDataLengthInformation
.ValidDataLength
.QuadPart
= ValidDataLength
;
1429 Status
= NtSetInformationFile(
1431 &IoStatusBlock
, //out
1432 &ValidDataLengthInformation
,
1433 sizeof(FILE_VALID_DATA_LENGTH_INFORMATION
),
1434 FileValidDataLengthInformation
1437 if (!NT_SUCCESS(Status
)){
1438 SetLastErrorByStatus(Status
);
1454 LPCWSTR lpShortName
)
1458 UNICODE_STRING ShortName
;
1459 IO_STATUS_BLOCK IoStatusBlock
;
1460 PFILE_NAME_INFORMATION FileNameInfo
;
1462 if(IsConsoleHandle(hFile
))
1464 SetLastError(ERROR_INVALID_HANDLE
);
1470 SetLastError(ERROR_INVALID_PARAMETER
);
1474 RtlInitUnicodeString(&ShortName
, lpShortName
);
1476 NeededSize
= sizeof(FILE_NAME_INFORMATION
) + ShortName
.Length
+ sizeof(WCHAR
);
1477 if(!(FileNameInfo
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, NeededSize
)))
1479 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1483 FileNameInfo
->FileNameLength
= ShortName
.Length
;
1484 RtlCopyMemory(FileNameInfo
->FileName
, ShortName
.Buffer
, ShortName
.Length
);
1486 Status
= NtSetInformationFile(hFile
,
1487 &IoStatusBlock
, //out
1490 FileShortNameInformation
);
1492 RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInfo
);
1493 if(!NT_SUCCESS(Status
))
1495 SetLastErrorByStatus(Status
);
1515 if(IsConsoleHandle(hFile
))
1517 SetLastError(ERROR_INVALID_HANDLE
);
1523 SetLastError(ERROR_INVALID_PARAMETER
);
1527 if (!(ShortNameW
= FilenameA2W(lpShortName
, FALSE
)))
1530 return SetFileShortNameW(hFile
, ShortNameW
);
1539 CheckNameLegalDOS8Dot3W(
1541 LPSTR lpOemName OPTIONAL
,
1542 DWORD OemNameSize OPTIONAL
,
1543 PBOOL pbNameContainsSpaces OPTIONAL
,
1547 UNICODE_STRING Name
;
1548 ANSI_STRING AnsiName
;
1550 if(lpName
== NULL
||
1551 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1552 pbNameLegal
== NULL
)
1554 SetLastError(ERROR_INVALID_PARAMETER
);
1558 if(lpOemName
!= NULL
)
1560 AnsiName
.Buffer
= lpOemName
;
1561 AnsiName
.MaximumLength
= (USHORT
)OemNameSize
* sizeof(CHAR
);
1562 AnsiName
.Length
= 0;
1565 RtlInitUnicodeString(&Name
, lpName
);
1567 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1568 (lpOemName
? &AnsiName
: NULL
),
1569 (BOOLEAN
*)pbNameContainsSpaces
);
1580 CheckNameLegalDOS8Dot3A(
1582 LPSTR lpOemName OPTIONAL
,
1583 DWORD OemNameSize OPTIONAL
,
1584 PBOOL pbNameContainsSpaces OPTIONAL
,
1588 UNICODE_STRING Name
;
1589 ANSI_STRING AnsiName
, AnsiInputName
;
1592 if(lpName
== NULL
||
1593 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1594 pbNameLegal
== NULL
)
1596 SetLastError(ERROR_INVALID_PARAMETER
);
1600 if(lpOemName
!= NULL
)
1602 AnsiName
.Buffer
= lpOemName
;
1603 AnsiName
.MaximumLength
= (USHORT
)OemNameSize
* sizeof(CHAR
);
1604 AnsiName
.Length
= 0;
1607 RtlInitAnsiString(&AnsiInputName
, (LPSTR
)lpName
);
1609 Status
= RtlAnsiStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1611 Status
= RtlOemStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1613 if(!NT_SUCCESS(Status
))
1615 SetLastErrorByStatus(Status
);
1619 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1620 (lpOemName
? &AnsiName
: NULL
),
1621 (BOOLEAN
*)pbNameContainsSpaces
);
1623 RtlFreeUnicodeString(&Name
);
1634 GetFinalPathNameByHandleA(IN HANDLE hFile
,
1635 OUT LPSTR lpszFilePath
,
1636 IN DWORD cchFilePath
,
1639 WCHAR FilePathW
[MAX_PATH
];
1640 UNICODE_STRING FilePathU
;
1641 DWORD PrevLastError
;
1644 if (cchFilePath
!= 0 &&
1645 cchFilePath
> sizeof(FilePathW
) / sizeof(FilePathW
[0]))
1647 FilePathU
.Length
= 0;
1648 FilePathU
.MaximumLength
= (USHORT
)cchFilePath
* sizeof(WCHAR
);
1649 FilePathU
.Buffer
= RtlAllocateHeap(RtlGetProcessHeap(),
1651 FilePathU
.MaximumLength
);
1652 if (FilePathU
.Buffer
== NULL
)
1654 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1660 FilePathU
.Length
= 0;
1661 FilePathU
.MaximumLength
= sizeof(FilePathW
);
1662 FilePathU
.Buffer
= FilePathW
;
1665 /* save the last error code */
1666 PrevLastError
= GetLastError();
1667 SetLastError(ERROR_SUCCESS
);
1669 /* call the unicode version that does all the work */
1670 Ret
= GetFinalPathNameByHandleW(hFile
,
1675 if (GetLastError() == ERROR_SUCCESS
)
1677 /* no error, restore the last error code and convert the string */
1678 SetLastError(PrevLastError
);
1680 Ret
= FilenameU2A_FitOrFail(lpszFilePath
,
1685 /* free allocated memory if necessary */
1686 if (FilePathU
.Buffer
!= FilePathW
)
1688 RtlFreeHeap(RtlGetProcessHeap(),
1702 GetFinalPathNameByHandleW(IN HANDLE hFile
,
1703 OUT LPWSTR lpszFilePath
,
1704 IN DWORD cchFilePath
,
1707 if (dwFlags
& ~(VOLUME_NAME_DOS
| VOLUME_NAME_GUID
| VOLUME_NAME_NT
|
1708 VOLUME_NAME_NONE
| FILE_NAME_NORMALIZED
| FILE_NAME_OPENED
))
1710 SetLastError(ERROR_INVALID_PARAMETER
);
1724 SetFileBandwidthReservation(IN HANDLE hFile
,
1725 IN DWORD nPeriodMilliseconds
,
1726 IN DWORD nBytesPerPeriod
,
1727 IN BOOL bDiscardable
,
1728 OUT LPDWORD lpTransferSize
,
1729 OUT LPDWORD lpNumOutstandingRequests
)
1741 GetFileBandwidthReservation(IN HANDLE hFile
,
1742 OUT LPDWORD lpPeriodMilliseconds
,
1743 OUT LPDWORD lpBytesPerPeriod
,
1744 OUT LPBOOL pDiscardable
,
1745 OUT LPDWORD lpTransferSize
,
1746 OUT LPDWORD lpNumOutstandingRequests
)
1758 SetFileCompletionNotificationModes(IN HANDLE FileHandle
,
1761 if (Flags
& ~(FILE_SKIP_COMPLETION_PORT_ON_SUCCESS
| FILE_SKIP_SET_EVENT_ON_HANDLE
))
1763 SetLastError(ERROR_INVALID_PARAMETER
);
1777 OpenFileById(IN HANDLE hFile
,
1778 IN LPFILE_ID_DESCRIPTOR lpFileID
,
1779 IN DWORD dwDesiredAccess
,
1780 IN DWORD dwShareMode
,
1781 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL
,
1785 return INVALID_HANDLE_VALUE
;