3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/file/file.c
6 * PURPOSE: Directory functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
8 * GetTempFileName is modified from WINE [ Alexandre Juiliard ]
13 /* INCLUDES *****************************************************************/
18 #include "../include/debug.h"
21 /* GLOBALS ******************************************************************/
23 BOOL bIsFileApiAnsi
= TRUE
; // set the file api to ansi or oem
25 /* FUNCTIONS ****************************************************************/
30 FilenameA2W(LPCSTR NameA
, BOOL alloc
)
34 PUNICODE_STRING pstrW
;
37 ASSERT(NtCurrentTeb()->StaticUnicodeString
.Buffer
== NtCurrentTeb()->StaticUnicodeBuffer
);
38 ASSERT(NtCurrentTeb()->StaticUnicodeString
.MaximumLength
== sizeof(NtCurrentTeb()->StaticUnicodeBuffer
));
40 RtlInitAnsiString(&str
, NameA
);
41 pstrW
= alloc
? &strW
: &NtCurrentTeb()->StaticUnicodeString
;
44 Status
= RtlAnsiStringToUnicodeString( pstrW
, &str
, alloc
);
46 Status
= RtlOemStringToUnicodeString( pstrW
, &str
, alloc
);
48 if (NT_SUCCESS(Status
))
51 if (Status
== STATUS_BUFFER_OVERFLOW
)
52 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
54 SetLastErrorByStatus(Status
);
61 No copy/conversion is done if the dest. buffer is too small.
64 Success: number of TCHARS copied into dest. buffer NOT including nullterm
65 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
68 FilenameU2A_FitOrFail(
70 INT destLen
, /* buffer size in TCHARS incl. nullchar */
71 PUNICODE_STRING SourceU
76 ret
= bIsFileApiAnsi
? RtlUnicodeStringToAnsiSize(SourceU
) : RtlUnicodeStringToOemSize(SourceU
);
77 /* ret incl. nullchar */
79 if (DestA
&& (INT
)ret
<= destLen
)
84 str
.MaximumLength
= destLen
;
88 RtlUnicodeStringToAnsiString(&str
, SourceU
, FALSE
);
90 RtlUnicodeStringToOemString(&str
, SourceU
, FALSE
);
92 ret
= str
.Length
; /* SUCCESS: length without terminating 0 */
100 No copy/conversion is done if the dest. buffer is too small.
103 Success: number of TCHARS copied into dest. buffer NOT including nullterm
104 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
107 FilenameW2A_FitOrFail(
109 INT destLen
, /* buffer size in TCHARS incl. nullchar */
111 INT sourceLen
/* buffer size in TCHARS incl. nullchar */
116 if (sourceLen
< 0) sourceLen
= wcslen(SourceW
) + 1;
118 strW
.Buffer
= (PWCHAR
)SourceW
;
119 strW
.MaximumLength
= sourceLen
* sizeof(WCHAR
);
120 strW
.Length
= strW
.MaximumLength
- sizeof(WCHAR
);
122 return FilenameU2A_FitOrFail(DestA
, destLen
, &strW
);
127 Return: num. TCHARS copied into dest including nullterm
132 INT destlen
, /* buffer size in TCHARS incl. nullchar */
134 INT srclen
/* buffer size in TCHARS incl. nullchar */
139 if (srclen
< 0) srclen
= strlen( src
) + 1;
142 RtlMultiByteToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
144 RtlOemToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
146 if (ret
) dest
[(ret
/sizeof(WCHAR
))-1]=0;
148 return ret
/sizeof(WCHAR
);
152 Return: num. TCHARS copied into dest including nullterm
157 INT destlen
, /* buffer size in TCHARS incl. nullchar */
159 INT srclen
/* buffer size in TCHARS incl. nullchar */
164 if (srclen
< 0) srclen
= wcslen( src
) + 1;
167 RtlUnicodeToMultiByteN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
));
169 RtlUnicodeToOemN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
) );
171 if (ret
) dest
[ret
-1]=0;
182 SetFileApisToOEM(VOID
)
184 /* Set the correct Base Api */
185 Basep8BitStringToUnicodeString
= (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 ((LPWSTR
)PathNameW
,
304 return (HFILE
)INVALID_HANDLE_VALUE
;
308 // FILE_NO_INTERMEDIATE_BUFFERING
310 if ((uStyle
& OF_PARSE
) == OF_PARSE
)
312 RtlFreeUnicodeString(&FileNameString
);
316 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
317 ObjectAttributes
.RootDirectory
= NULL
;
318 ObjectAttributes
.ObjectName
= &FileNameString
;
319 ObjectAttributes
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
;
320 ObjectAttributes
.SecurityDescriptor
= NULL
;
321 ObjectAttributes
.SecurityQualityOfService
= NULL
;
323 errCode
= NtOpenFile (&FileHandle
,
324 GENERIC_READ
|SYNCHRONIZE
,
328 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
330 RtlFreeUnicodeString(&FileNameString
);
332 lpReOpenBuff
->nErrCode
= RtlNtStatusToDosError(errCode
);
334 if (!NT_SUCCESS(errCode
))
336 SetLastErrorByStatus (errCode
);
337 return (HFILE
)INVALID_HANDLE_VALUE
;
340 return (HFILE
)FileHandle
;
348 FlushFileBuffers(HANDLE hFile
)
351 IO_STATUS_BLOCK IoStatusBlock
;
353 if (IsConsoleHandle(hFile
))
358 errCode
= NtFlushBuffersFile(hFile
,
360 if (!NT_SUCCESS(errCode
))
362 SetLastErrorByStatus(errCode
);
373 SetFilePointer(HANDLE hFile
,
374 LONG lDistanceToMove
,
375 PLONG lpDistanceToMoveHigh
,
378 FILE_POSITION_INFORMATION FilePosition
;
379 FILE_STANDARD_INFORMATION FileStandard
;
381 IO_STATUS_BLOCK IoStatusBlock
;
382 LARGE_INTEGER Distance
;
384 DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
385 hFile
,lDistanceToMove
,dwMoveMethod
);
387 if(IsConsoleHandle(hFile
))
389 SetLastError(ERROR_INVALID_HANDLE
);
393 Distance
.u
.LowPart
= lDistanceToMove
;
394 if (lpDistanceToMoveHigh
)
396 Distance
.u
.HighPart
= *lpDistanceToMoveHigh
;
398 else if (lDistanceToMove
>= 0)
400 Distance
.u
.HighPart
= 0;
404 Distance
.u
.HighPart
= -1;
410 NtQueryInformationFile(hFile
,
413 sizeof(FILE_POSITION_INFORMATION
),
414 FilePositionInformation
);
415 FilePosition
.CurrentByteOffset
.QuadPart
+= Distance
.QuadPart
;
418 NtQueryInformationFile(hFile
,
421 sizeof(FILE_STANDARD_INFORMATION
),
422 FileStandardInformation
);
423 FilePosition
.CurrentByteOffset
.QuadPart
=
424 FileStandard
.EndOfFile
.QuadPart
+ Distance
.QuadPart
;
427 FilePosition
.CurrentByteOffset
.QuadPart
= Distance
.QuadPart
;
430 SetLastError(ERROR_INVALID_PARAMETER
);
434 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
436 SetLastError(ERROR_NEGATIVE_SEEK
);
440 errCode
= NtSetInformationFile(hFile
,
443 sizeof(FILE_POSITION_INFORMATION
),
444 FilePositionInformation
);
445 if (!NT_SUCCESS(errCode
))
447 SetLastErrorByStatus(errCode
);
451 if (lpDistanceToMoveHigh
!= NULL
)
453 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
455 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
464 SetFilePointerEx(HANDLE hFile
,
465 LARGE_INTEGER liDistanceToMove
,
466 PLARGE_INTEGER lpNewFilePointer
,
469 FILE_POSITION_INFORMATION FilePosition
;
470 FILE_STANDARD_INFORMATION FileStandard
;
472 IO_STATUS_BLOCK IoStatusBlock
;
474 if(IsConsoleHandle(hFile
))
476 SetLastError(ERROR_INVALID_HANDLE
);
483 NtQueryInformationFile(hFile
,
486 sizeof(FILE_POSITION_INFORMATION
),
487 FilePositionInformation
);
488 FilePosition
.CurrentByteOffset
.QuadPart
+= liDistanceToMove
.QuadPart
;
491 NtQueryInformationFile(hFile
,
494 sizeof(FILE_STANDARD_INFORMATION
),
495 FileStandardInformation
);
496 FilePosition
.CurrentByteOffset
.QuadPart
=
497 FileStandard
.EndOfFile
.QuadPart
+ liDistanceToMove
.QuadPart
;
500 FilePosition
.CurrentByteOffset
.QuadPart
= liDistanceToMove
.QuadPart
;
503 SetLastError(ERROR_INVALID_PARAMETER
);
507 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
509 SetLastError(ERROR_NEGATIVE_SEEK
);
513 errCode
= NtSetInformationFile(hFile
,
516 sizeof(FILE_POSITION_INFORMATION
),
517 FilePositionInformation
);
518 if (!NT_SUCCESS(errCode
))
520 SetLastErrorByStatus(errCode
);
524 if (lpNewFilePointer
)
526 *lpNewFilePointer
= FilePosition
.CurrentByteOffset
;
536 GetFileType(HANDLE hFile
)
538 FILE_FS_DEVICE_INFORMATION DeviceInfo
;
539 IO_STATUS_BLOCK StatusBlock
;
542 /* Get real handle */
543 switch ((ULONG
)hFile
)
545 case STD_INPUT_HANDLE
:
546 hFile
= NtCurrentPeb()->ProcessParameters
->StandardInput
;
549 case STD_OUTPUT_HANDLE
:
550 hFile
= NtCurrentPeb()->ProcessParameters
->StandardOutput
;
553 case STD_ERROR_HANDLE
:
554 hFile
= NtCurrentPeb()->ProcessParameters
->StandardError
;
558 /* Check for console handle */
559 if (IsConsoleHandle(hFile
))
561 if (VerifyConsoleIoHandle(hFile
))
562 return FILE_TYPE_CHAR
;
565 Status
= NtQueryVolumeInformationFile(hFile
,
568 sizeof(FILE_FS_DEVICE_INFORMATION
),
569 FileFsDeviceInformation
);
570 if (!NT_SUCCESS(Status
))
572 SetLastErrorByStatus(Status
);
573 return FILE_TYPE_UNKNOWN
;
576 switch (DeviceInfo
.DeviceType
)
578 case FILE_DEVICE_CD_ROM
:
579 case FILE_DEVICE_CD_ROM_FILE_SYSTEM
:
580 case FILE_DEVICE_CONTROLLER
:
581 case FILE_DEVICE_DATALINK
:
582 case FILE_DEVICE_DFS
:
583 case FILE_DEVICE_DISK
:
584 case FILE_DEVICE_DISK_FILE_SYSTEM
:
585 case FILE_DEVICE_VIRTUAL_DISK
:
586 return FILE_TYPE_DISK
;
588 case FILE_DEVICE_KEYBOARD
:
589 case FILE_DEVICE_MOUSE
:
590 case FILE_DEVICE_NULL
:
591 case FILE_DEVICE_PARALLEL_PORT
:
592 case FILE_DEVICE_PRINTER
:
593 case FILE_DEVICE_SERIAL_PORT
:
594 case FILE_DEVICE_SCREEN
:
595 case FILE_DEVICE_SOUND
:
596 case FILE_DEVICE_MODEM
:
597 return FILE_TYPE_CHAR
;
599 case FILE_DEVICE_NAMED_PIPE
:
600 return FILE_TYPE_PIPE
;
603 return FILE_TYPE_UNKNOWN
;
611 GetFileSize(HANDLE hFile
,
612 LPDWORD lpFileSizeHigh
)
615 FILE_STANDARD_INFORMATION FileStandard
;
616 IO_STATUS_BLOCK IoStatusBlock
;
618 errCode
= NtQueryInformationFile(hFile
,
621 sizeof(FILE_STANDARD_INFORMATION
),
622 FileStandardInformation
);
623 if (!NT_SUCCESS(errCode
))
625 SetLastErrorByStatus(errCode
);
626 if ( lpFileSizeHigh
== NULL
)
635 if ( lpFileSizeHigh
!= NULL
)
636 *lpFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
638 return FileStandard
.EndOfFile
.u
.LowPart
;
649 PLARGE_INTEGER lpFileSize
653 FILE_STANDARD_INFORMATION FileStandard
;
654 IO_STATUS_BLOCK IoStatusBlock
;
656 errCode
= NtQueryInformationFile(hFile
,
659 sizeof(FILE_STANDARD_INFORMATION
),
660 FileStandardInformation
);
661 if (!NT_SUCCESS(errCode
))
663 SetLastErrorByStatus(errCode
);
667 *lpFileSize
= FileStandard
.EndOfFile
;
677 GetCompressedFileSizeA(LPCSTR lpFileName
,
678 LPDWORD lpFileSizeHigh
)
682 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
683 return INVALID_FILE_SIZE
;
685 return GetCompressedFileSizeW(FileNameW
, lpFileSizeHigh
);
693 GetCompressedFileSizeW(LPCWSTR lpFileName
,
694 LPDWORD lpFileSizeHigh
)
696 FILE_COMPRESSION_INFORMATION FileCompression
;
698 IO_STATUS_BLOCK IoStatusBlock
;
701 hFile
= CreateFileW(lpFileName
,
706 FILE_ATTRIBUTE_NORMAL
,
709 if (hFile
== INVALID_HANDLE_VALUE
)
710 return INVALID_FILE_SIZE
;
712 errCode
= NtQueryInformationFile(hFile
,
715 sizeof(FILE_COMPRESSION_INFORMATION
),
716 FileCompressionInformation
);
720 if (!NT_SUCCESS(errCode
))
722 SetLastErrorByStatus(errCode
);
723 return INVALID_FILE_SIZE
;
727 *lpFileSizeHigh
= FileCompression
.CompressedFileSize
.u
.HighPart
;
729 SetLastError(NO_ERROR
);
730 return FileCompression
.CompressedFileSize
.u
.LowPart
;
738 GetFileInformationByHandle(HANDLE hFile
,
739 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
743 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
748 FILE_BASIC_INFORMATION FileBasic
;
749 FILE_INTERNAL_INFORMATION FileInternal
;
750 FILE_STANDARD_INFORMATION FileStandard
;
752 IO_STATUS_BLOCK IoStatusBlock
;
754 if(IsConsoleHandle(hFile
))
756 SetLastError(ERROR_INVALID_HANDLE
);
760 errCode
= NtQueryInformationFile(hFile
,
763 sizeof(FILE_BASIC_INFORMATION
),
764 FileBasicInformation
);
765 if (!NT_SUCCESS(errCode
))
767 SetLastErrorByStatus(errCode
);
771 lpFileInformation
->dwFileAttributes
= (DWORD
)FileBasic
.FileAttributes
;
773 lpFileInformation
->ftCreationTime
.dwHighDateTime
= FileBasic
.CreationTime
.u
.HighPart
;
774 lpFileInformation
->ftCreationTime
.dwLowDateTime
= FileBasic
.CreationTime
.u
.LowPart
;
776 lpFileInformation
->ftLastAccessTime
.dwHighDateTime
= FileBasic
.LastAccessTime
.u
.HighPart
;
777 lpFileInformation
->ftLastAccessTime
.dwLowDateTime
= FileBasic
.LastAccessTime
.u
.LowPart
;
779 lpFileInformation
->ftLastWriteTime
.dwHighDateTime
= FileBasic
.LastWriteTime
.u
.HighPart
;
780 lpFileInformation
->ftLastWriteTime
.dwLowDateTime
= FileBasic
.LastWriteTime
.u
.LowPart
;
782 errCode
= NtQueryInformationFile(hFile
,
785 sizeof(FILE_INTERNAL_INFORMATION
),
786 FileInternalInformation
);
787 if (!NT_SUCCESS(errCode
))
789 SetLastErrorByStatus(errCode
);
793 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
794 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
796 errCode
= NtQueryVolumeInformationFile(hFile
,
799 sizeof(FileFsVolume
),
800 FileFsVolumeInformation
);
801 if (!NT_SUCCESS(errCode
))
803 SetLastErrorByStatus(errCode
);
807 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.FileFsVolume
.VolumeSerialNumber
;
809 errCode
= NtQueryInformationFile(hFile
,
812 sizeof(FILE_STANDARD_INFORMATION
),
813 FileStandardInformation
);
814 if (!NT_SUCCESS(errCode
))
816 SetLastErrorByStatus(errCode
);
820 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
821 lpFileInformation
->nFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
822 lpFileInformation
->nFileSizeLow
= FileStandard
.EndOfFile
.u
.LowPart
;
832 GetFileAttributesExW(LPCWSTR lpFileName
,
833 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
834 LPVOID lpFileInformation
)
836 FILE_NETWORK_OPEN_INFORMATION FileInformation
;
837 OBJECT_ATTRIBUTES ObjectAttributes
;
838 UNICODE_STRING FileName
;
840 WIN32_FILE_ATTRIBUTE_DATA
* FileAttributeData
;
842 DPRINT("GetFileAttributesExW(%S) called\n", lpFileName
);
845 if (fInfoLevelId
!= GetFileExInfoStandard
|| lpFileInformation
== NULL
)
847 SetLastError(ERROR_INVALID_PARAMETER
);
851 /* Validate and translate the filename */
852 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
857 DPRINT1 ("Invalid path\n");
858 SetLastError (ERROR_BAD_PATHNAME
);
862 /* build the object attributes */
863 InitializeObjectAttributes (&ObjectAttributes
,
865 OBJ_CASE_INSENSITIVE
,
869 /* Get file attributes */
870 Status
= NtQueryFullAttributesFile(&ObjectAttributes
,
873 RtlFreeUnicodeString (&FileName
);
874 if (!NT_SUCCESS (Status
))
876 DPRINT ("NtQueryFullAttributesFile() failed (Status %lx)\n", Status
);
877 SetLastErrorByStatus (Status
);
881 FileAttributeData
= (WIN32_FILE_ATTRIBUTE_DATA
*)lpFileInformation
;
882 FileAttributeData
->dwFileAttributes
= FileInformation
.FileAttributes
;
883 FileAttributeData
->ftCreationTime
.dwLowDateTime
= FileInformation
.CreationTime
.u
.LowPart
;
884 FileAttributeData
->ftCreationTime
.dwHighDateTime
= FileInformation
.CreationTime
.u
.HighPart
;
885 FileAttributeData
->ftLastAccessTime
.dwLowDateTime
= FileInformation
.LastAccessTime
.u
.LowPart
;
886 FileAttributeData
->ftLastAccessTime
.dwHighDateTime
= FileInformation
.LastAccessTime
.u
.HighPart
;
887 FileAttributeData
->ftLastWriteTime
.dwLowDateTime
= FileInformation
.LastWriteTime
.u
.LowPart
;
888 FileAttributeData
->ftLastWriteTime
.dwHighDateTime
= FileInformation
.LastWriteTime
.u
.HighPart
;
889 FileAttributeData
->nFileSizeLow
= FileInformation
.EndOfFile
.u
.LowPart
;
890 FileAttributeData
->nFileSizeHigh
= FileInformation
.EndOfFile
.u
.HighPart
;
899 GetFileAttributesExA(LPCSTR lpFileName
,
900 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
901 LPVOID lpFileInformation
)
905 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
908 return GetFileAttributesExW(FileNameW
, fInfoLevelId
, lpFileInformation
);
916 GetFileAttributesA(LPCSTR lpFileName
)
918 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
922 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
923 return INVALID_FILE_ATTRIBUTES
;
925 ret
= GetFileAttributesExW(FileNameW
, GetFileExInfoStandard
, &FileAttributeData
);
927 return ret
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
935 GetFileAttributesW(LPCWSTR lpFileName
)
937 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
940 DPRINT ("GetFileAttributeW(%S) called\n", lpFileName
);
942 Result
= GetFileAttributesExW(lpFileName
, GetFileExInfoStandard
, &FileAttributeData
);
944 return Result
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
952 GetFileAttributesByHandle(IN HANDLE hFile
,
953 OUT LPDWORD dwFileAttributes
,
956 FILE_BASIC_INFORMATION FileBasic
;
957 IO_STATUS_BLOCK IoStatusBlock
;
960 UNREFERENCED_PARAMETER(dwFlags
);
962 if (IsConsoleHandle(hFile
))
964 SetLastError(ERROR_INVALID_HANDLE
);
968 Status
= NtQueryInformationFile(hFile
,
972 FileBasicInformation
);
973 if (NT_SUCCESS(Status
))
975 *dwFileAttributes
= FileBasic
.FileAttributes
;
979 SetLastErrorByStatus(Status
);
988 SetFileAttributesByHandle(IN HANDLE hFile
,
989 IN DWORD dwFileAttributes
,
992 FILE_BASIC_INFORMATION FileBasic
;
993 IO_STATUS_BLOCK IoStatusBlock
;
996 UNREFERENCED_PARAMETER(dwFlags
);
998 if (IsConsoleHandle(hFile
))
1000 SetLastError(ERROR_INVALID_HANDLE
);
1004 Status
= NtQueryInformationFile(hFile
,
1008 FileBasicInformation
);
1009 if (NT_SUCCESS(Status
))
1011 FileBasic
.FileAttributes
= dwFileAttributes
;
1013 Status
= NtSetInformationFile(hFile
,
1017 FileBasicInformation
);
1020 if (!NT_SUCCESS(Status
))
1022 SetLastErrorByStatus(Status
);
1036 DWORD dwFileAttributes
)
1040 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
1043 return SetFileAttributesW(FileNameW
, dwFileAttributes
);
1051 SetFileAttributesW(LPCWSTR lpFileName
,
1052 DWORD dwFileAttributes
)
1054 FILE_BASIC_INFORMATION FileInformation
;
1055 OBJECT_ATTRIBUTES ObjectAttributes
;
1056 IO_STATUS_BLOCK IoStatusBlock
;
1057 UNICODE_STRING FileName
;
1061 DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName
, dwFileAttributes
);
1063 /* Validate and translate the filename */
1064 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
1069 DPRINT ("Invalid path\n");
1070 SetLastError (ERROR_BAD_PATHNAME
);
1073 DPRINT ("FileName: \'%wZ\'\n", &FileName
);
1075 /* build the object attributes */
1076 InitializeObjectAttributes (&ObjectAttributes
,
1078 OBJ_CASE_INSENSITIVE
,
1083 Status
= NtOpenFile (&FileHandle
,
1084 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1087 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1088 FILE_SYNCHRONOUS_IO_NONALERT
);
1089 RtlFreeUnicodeString (&FileName
);
1090 if (!NT_SUCCESS (Status
))
1092 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
1093 SetLastErrorByStatus (Status
);
1097 Status
= NtQueryInformationFile(FileHandle
,
1100 sizeof(FILE_BASIC_INFORMATION
),
1101 FileBasicInformation
);
1102 if (!NT_SUCCESS(Status
))
1104 DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status
);
1105 NtClose (FileHandle
);
1106 SetLastErrorByStatus (Status
);
1110 FileInformation
.FileAttributes
= dwFileAttributes
;
1111 Status
= NtSetInformationFile(FileHandle
,
1114 sizeof(FILE_BASIC_INFORMATION
),
1115 FileBasicInformation
);
1116 NtClose (FileHandle
);
1117 if (!NT_SUCCESS(Status
))
1119 DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status
);
1120 SetLastErrorByStatus (Status
);
1130 /***********************************************************************
1131 * GetTempFileNameA (KERNEL32.@)
1133 UINT WINAPI
GetTempFileNameA( LPCSTR path
, LPCSTR prefix
, UINT unique
, LPSTR buffer
)
1135 WCHAR BufferW
[MAX_PATH
];
1140 if (!(PathW
= FilenameA2W(path
, FALSE
)))
1144 FilenameA2W_N(PrefixW
, 3+1, prefix
, -1);
1146 ret
= GetTempFileNameW(PathW
, prefix
? PrefixW
: NULL
, unique
, BufferW
);
1149 FilenameW2A_N(buffer
, MAX_PATH
, BufferW
, -1);
1154 /***********************************************************************
1155 * GetTempFileNameW (KERNEL32.@)
1157 UINT WINAPI
GetTempFileNameW( LPCWSTR path
, LPCWSTR prefix
, UINT unique
, LPWSTR buffer
)
1159 static const WCHAR formatW
[] = L
"%x.tmp";
1164 if ( !path
|| !prefix
|| !buffer
)
1166 SetLastError( ERROR_INVALID_PARAMETER
);
1170 wcscpy( buffer
, path
);
1171 p
= buffer
+ wcslen(buffer
);
1173 /* add a \, if there isn't one */
1174 if ((p
== buffer
) || (p
[-1] != '\\')) *p
++ = '\\';
1176 for (i
= 3; (i
> 0) && (*prefix
); i
--) *p
++ = *prefix
++;
1180 if (unique
) swprintf( p
, formatW
, unique
);
1183 /* get a "random" unique number and try to create the file */
1185 UINT num
= GetTickCount() & 0xffff;
1191 swprintf( p
, formatW
, unique
);
1192 handle
= CreateFileW( buffer
, GENERIC_WRITE
, 0, NULL
,
1193 CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, 0 );
1194 if (handle
!= INVALID_HANDLE_VALUE
)
1195 { /* We created it */
1196 DPRINT("created %S\n", buffer
);
1197 CloseHandle( handle
);
1200 if (GetLastError() != ERROR_FILE_EXISTS
&&
1201 GetLastError() != ERROR_SHARING_VIOLATION
)
1202 break; /* No need to go on */
1203 if (!(++unique
& 0xffff)) unique
= 1;
1204 } while (unique
!= num
);
1207 DPRINT("returning %S\n", buffer
);
1219 GetFileTime(HANDLE hFile
,
1220 LPFILETIME lpCreationTime
,
1221 LPFILETIME lpLastAccessTime
,
1222 LPFILETIME lpLastWriteTime
)
1224 IO_STATUS_BLOCK IoStatusBlock
;
1225 FILE_BASIC_INFORMATION FileBasic
;
1228 if(IsConsoleHandle(hFile
))
1230 SetLastError(ERROR_INVALID_HANDLE
);
1234 Status
= NtQueryInformationFile(hFile
,
1237 sizeof(FILE_BASIC_INFORMATION
),
1238 FileBasicInformation
);
1239 if (!NT_SUCCESS(Status
))
1241 SetLastErrorByStatus(Status
);
1246 memcpy(lpCreationTime
, &FileBasic
.CreationTime
, sizeof(FILETIME
));
1247 if (lpLastAccessTime
)
1248 memcpy(lpLastAccessTime
, &FileBasic
.LastAccessTime
, sizeof(FILETIME
));
1249 if (lpLastWriteTime
)
1250 memcpy(lpLastWriteTime
, &FileBasic
.LastWriteTime
, sizeof(FILETIME
));
1260 SetFileTime(HANDLE hFile
,
1261 CONST FILETIME
*lpCreationTime
,
1262 CONST FILETIME
*lpLastAccessTime
,
1263 CONST FILETIME
*lpLastWriteTime
)
1265 FILE_BASIC_INFORMATION FileBasic
;
1266 IO_STATUS_BLOCK IoStatusBlock
;
1269 if(IsConsoleHandle(hFile
))
1271 SetLastError(ERROR_INVALID_HANDLE
);
1275 Status
= NtQueryInformationFile(hFile
,
1278 sizeof(FILE_BASIC_INFORMATION
),
1279 FileBasicInformation
);
1280 if (!NT_SUCCESS(Status
))
1282 SetLastErrorByStatus(Status
);
1287 memcpy(&FileBasic
.CreationTime
, lpCreationTime
, sizeof(FILETIME
));
1288 if (lpLastAccessTime
)
1289 memcpy(&FileBasic
.LastAccessTime
, lpLastAccessTime
, sizeof(FILETIME
));
1290 if (lpLastWriteTime
)
1291 memcpy(&FileBasic
.LastWriteTime
, lpLastWriteTime
, sizeof(FILETIME
));
1293 // should i initialize changetime ???
1295 Status
= NtSetInformationFile(hFile
,
1298 sizeof(FILE_BASIC_INFORMATION
),
1299 FileBasicInformation
);
1300 if (!NT_SUCCESS(Status
))
1302 SetLastErrorByStatus(Status
);
1311 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
1316 SetEndOfFile(HANDLE hFile
)
1318 IO_STATUS_BLOCK IoStatusBlock
;
1319 FILE_END_OF_FILE_INFORMATION EndOfFileInfo
;
1320 FILE_ALLOCATION_INFORMATION FileAllocationInfo
;
1321 FILE_POSITION_INFORMATION FilePosInfo
;
1324 if(IsConsoleHandle(hFile
))
1326 SetLastError(ERROR_INVALID_HANDLE
);
1330 //get current position
1331 Status
= NtQueryInformationFile(
1335 sizeof(FILE_POSITION_INFORMATION
),
1336 FilePositionInformation
1339 if (!NT_SUCCESS(Status
)){
1340 SetLastErrorByStatus(Status
);
1344 EndOfFileInfo
.EndOfFile
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1348 This call is not supposed to free up any space after the eof marker
1349 if the file gets truncated. We have to deallocate the space explicitly afterwards.
1350 But...most file systems dispatch both FileEndOfFileInformation
1351 and FileAllocationInformation as they were the same command.
1354 Status
= NtSetInformationFile(
1356 &IoStatusBlock
, //out
1358 sizeof(FILE_END_OF_FILE_INFORMATION
),
1359 FileEndOfFileInformation
1362 if (!NT_SUCCESS(Status
)){
1363 SetLastErrorByStatus(Status
);
1367 FileAllocationInfo
.AllocationSize
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1370 Status
= NtSetInformationFile(
1372 &IoStatusBlock
, //out
1373 &FileAllocationInfo
,
1374 sizeof(FILE_ALLOCATION_INFORMATION
),
1375 FileAllocationInformation
1378 if (!NT_SUCCESS(Status
)){
1379 SetLastErrorByStatus(Status
);
1395 LONGLONG ValidDataLength
1398 IO_STATUS_BLOCK IoStatusBlock
;
1399 FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation
;
1402 ValidDataLengthInformation
.ValidDataLength
.QuadPart
= ValidDataLength
;
1404 Status
= NtSetInformationFile(
1406 &IoStatusBlock
, //out
1407 &ValidDataLengthInformation
,
1408 sizeof(FILE_VALID_DATA_LENGTH_INFORMATION
),
1409 FileValidDataLengthInformation
1412 if (!NT_SUCCESS(Status
)){
1413 SetLastErrorByStatus(Status
);
1429 LPCWSTR lpShortName
)
1433 UNICODE_STRING ShortName
;
1434 IO_STATUS_BLOCK IoStatusBlock
;
1435 PFILE_NAME_INFORMATION FileNameInformation
;
1437 if(IsConsoleHandle(hFile
))
1439 SetLastError(ERROR_INVALID_HANDLE
);
1445 SetLastError(ERROR_INVALID_PARAMETER
);
1449 RtlInitUnicodeString(&ShortName
, lpShortName
);
1451 NeededSize
= sizeof(FILE_NAME_INFORMATION
) + ShortName
.Length
+ sizeof(WCHAR
);
1452 if(!(FileNameInformation
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, NeededSize
)))
1454 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1458 FileNameInformation
->FileNameLength
= ShortName
.Length
;
1459 RtlCopyMemory(FileNameInformation
->FileName
, ShortName
.Buffer
, ShortName
.Length
);
1461 Status
= NtSetInformationFile(hFile
,
1462 &IoStatusBlock
, //out
1463 FileNameInformation
,
1465 FileShortNameInformation
);
1467 RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInformation
);
1468 if(!NT_SUCCESS(Status
))
1471 SetLastErrorByStatus(Status
);
1474 return NT_SUCCESS(Status
);
1490 if(IsConsoleHandle(hFile
))
1492 SetLastError(ERROR_INVALID_HANDLE
);
1498 SetLastError(ERROR_INVALID_PARAMETER
);
1502 if (!(ShortNameW
= FilenameA2W(lpShortName
, FALSE
)))
1505 return SetFileShortNameW(hFile
, ShortNameW
);
1514 CheckNameLegalDOS8Dot3W(
1516 LPSTR lpOemName OPTIONAL
,
1517 DWORD OemNameSize OPTIONAL
,
1518 PBOOL pbNameContainsSpaces OPTIONAL
,
1522 UNICODE_STRING Name
;
1523 ANSI_STRING AnsiName
;
1525 if(lpName
== NULL
||
1526 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1527 pbNameLegal
== NULL
)
1529 SetLastError(ERROR_INVALID_PARAMETER
);
1533 if(lpOemName
!= NULL
)
1535 AnsiName
.Buffer
= lpOemName
;
1536 AnsiName
.MaximumLength
= OemNameSize
* sizeof(CHAR
);
1537 AnsiName
.Length
= 0;
1540 RtlInitUnicodeString(&Name
, lpName
);
1542 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1543 (lpOemName
? &AnsiName
: NULL
),
1544 (BOOLEAN
*)pbNameContainsSpaces
);
1555 CheckNameLegalDOS8Dot3A(
1557 LPSTR lpOemName OPTIONAL
,
1558 DWORD OemNameSize OPTIONAL
,
1559 PBOOL pbNameContainsSpaces OPTIONAL
,
1563 UNICODE_STRING Name
;
1564 ANSI_STRING AnsiName
, AnsiInputName
;
1567 if(lpName
== NULL
||
1568 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1569 pbNameLegal
== NULL
)
1571 SetLastError(ERROR_INVALID_PARAMETER
);
1575 if(lpOemName
!= NULL
)
1577 AnsiName
.Buffer
= lpOemName
;
1578 AnsiName
.MaximumLength
= OemNameSize
* sizeof(CHAR
);
1579 AnsiName
.Length
= 0;
1582 RtlInitAnsiString(&AnsiInputName
, (LPSTR
)lpName
);
1584 Status
= RtlAnsiStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1586 Status
= RtlOemStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1588 if(!NT_SUCCESS(Status
))
1590 SetLastErrorByStatus(Status
);
1594 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1595 (lpOemName
? &AnsiName
: NULL
),
1596 (BOOLEAN
*)pbNameContainsSpaces
);
1598 RtlFreeUnicodeString(&Name
);