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
26 /* FUNCTIONS ****************************************************************/
31 FilenameA2W(LPCSTR NameA
, BOOL alloc
)
35 PUNICODE_STRING pstrW
;
38 ASSERT(NtCurrentTeb()->StaticUnicodeString
.Buffer
== NtCurrentTeb()->StaticUnicodeBuffer
);
39 ASSERT(NtCurrentTeb()->StaticUnicodeString
.MaximumLength
== sizeof(NtCurrentTeb()->StaticUnicodeBuffer
));
41 RtlInitAnsiString(&str
, NameA
);
42 pstrW
= alloc
? &strW
: &NtCurrentTeb()->StaticUnicodeString
;
45 Status
= RtlAnsiStringToUnicodeString( pstrW
, &str
, alloc
);
47 Status
= RtlOemStringToUnicodeString( pstrW
, &str
, alloc
);
49 if (NT_SUCCESS(Status
))
52 if (Status
== STATUS_BUFFER_OVERFLOW
)
53 SetLastError( ERROR_FILENAME_EXCED_RANGE
);
55 SetLastErrorByStatus(Status
);
62 No copy/conversion is done if the dest. buffer is too small.
65 Success: number of TCHARS copied into dest. buffer NOT including nullterm
66 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
69 FilenameU2A_FitOrFail(
71 INT destLen
, /* buffer size in TCHARS incl. nullchar */
72 PUNICODE_STRING SourceU
77 ret
= bIsFileApiAnsi
? RtlUnicodeStringToAnsiSize(SourceU
) : RtlUnicodeStringToOemSize(SourceU
);
78 /* ret incl. nullchar */
80 if (DestA
&& ret
<= destLen
)
85 str
.MaximumLength
= destLen
;
89 RtlUnicodeStringToAnsiString(&str
, SourceU
, FALSE
);
91 RtlUnicodeStringToOemString(&str
, SourceU
, FALSE
);
93 ret
= str
.Length
; /* SUCCESS: length without terminating 0 */
101 No copy/conversion is done if the dest. buffer is too small.
104 Success: number of TCHARS copied into dest. buffer NOT including nullterm
105 Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
108 FilenameW2A_FitOrFail(
110 INT destLen
, /* buffer size in TCHARS incl. nullchar */
112 INT sourceLen
/* buffer size in TCHARS incl. nullchar */
117 if (sourceLen
< 0) sourceLen
= wcslen(SourceW
) + 1;
119 strW
.Buffer
= (PWCHAR
)SourceW
;
120 strW
.MaximumLength
= sourceLen
* sizeof(WCHAR
);
121 strW
.Length
= strW
.MaximumLength
- sizeof(WCHAR
);
123 return FilenameU2A_FitOrFail(DestA
, destLen
, &strW
);
128 Return: num. TCHARS copied into dest including nullterm
133 INT destlen
, /* buffer size in TCHARS incl. nullchar */
135 INT srclen
/* buffer size in TCHARS incl. nullchar */
140 if (srclen
< 0) srclen
= strlen( src
) + 1;
143 RtlMultiByteToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
145 RtlOemToUnicodeN( dest
, destlen
* sizeof(WCHAR
), &ret
, (LPSTR
)src
, srclen
);
147 if (ret
) dest
[(ret
/sizeof(WCHAR
))-1]=0;
149 return ret
/sizeof(WCHAR
);
153 Return: num. TCHARS copied into dest including nullterm
158 INT destlen
, /* buffer size in TCHARS incl. nullchar */
160 INT srclen
/* buffer size in TCHARS incl. nullchar */
165 if (srclen
< 0) srclen
= wcslen( src
) + 1;
168 RtlUnicodeToMultiByteN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
));
170 RtlUnicodeToOemN( dest
, destlen
, &ret
, (LPWSTR
) src
, srclen
* sizeof(WCHAR
) );
172 if (ret
) dest
[ret
-1]=0;
182 SetFileApisToOEM(VOID
)
184 bIsFileApiAnsi
= FALSE
;
192 SetFileApisToANSI(VOID
)
194 bIsFileApiAnsi
= TRUE
;
202 AreFileApisANSI(VOID
)
204 return bIsFileApiAnsi
;
212 OpenFile(LPCSTR lpFileName
,
213 LPOFSTRUCT lpReOpenBuff
,
216 OBJECT_ATTRIBUTES ObjectAttributes
;
217 IO_STATUS_BLOCK IoStatusBlock
;
218 UNICODE_STRING FileNameString
;
219 UNICODE_STRING FileNameU
;
220 ANSI_STRING FileName
;
221 WCHAR PathNameW
[MAX_PATH
];
222 HANDLE FileHandle
= NULL
;
227 DPRINT("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName
, lpReOpenBuff
, uStyle
);
229 if (lpReOpenBuff
== NULL
)
234 if ((uStyle
& OF_CREATE
) == OF_CREATE
)
237 switch (uStyle
& 0x70)
239 case OF_SHARE_EXCLUSIVE
: Sharing
= 0; break;
240 case OF_SHARE_DENY_WRITE
: Sharing
= FILE_SHARE_READ
; break;
241 case OF_SHARE_DENY_READ
: Sharing
= FILE_SHARE_WRITE
; break;
242 case OF_SHARE_DENY_NONE
:
243 case OF_SHARE_COMPAT
:
245 Sharing
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
247 return (HFILE
) CreateFileA (lpFileName
,
248 GENERIC_READ
| GENERIC_WRITE
,
252 FILE_ATTRIBUTE_NORMAL
,
256 RtlInitAnsiString (&FileName
, (LPSTR
)lpFileName
);
258 /* convert ansi (or oem) string to unicode */
260 RtlAnsiStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
262 RtlOemStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
264 Len
= SearchPathW (NULL
,
271 RtlFreeUnicodeString(&FileNameU
);
273 if (Len
== 0 || Len
> OFS_MAXPATHNAME
)
275 return (HFILE
)INVALID_HANDLE_VALUE
;
278 FileName
.Buffer
= lpReOpenBuff
->szPathName
;
280 FileName
.MaximumLength
= OFS_MAXPATHNAME
;
282 RtlInitUnicodeString(&FileNameU
, PathNameW
);
284 /* convert unicode string to ansi (or oem) */
286 RtlUnicodeStringToAnsiString (&FileName
, &FileNameU
, FALSE
);
288 RtlUnicodeStringToOemString (&FileName
, &FileNameU
, FALSE
);
290 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)PathNameW
,
295 return (HFILE
)INVALID_HANDLE_VALUE
;
299 // FILE_NO_INTERMEDIATE_BUFFERING
301 if ((uStyle
& OF_PARSE
) == OF_PARSE
)
303 RtlFreeUnicodeString(&FileNameString
);
307 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
308 ObjectAttributes
.RootDirectory
= NULL
;
309 ObjectAttributes
.ObjectName
= &FileNameString
;
310 ObjectAttributes
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
;
311 ObjectAttributes
.SecurityDescriptor
= NULL
;
312 ObjectAttributes
.SecurityQualityOfService
= NULL
;
314 errCode
= NtOpenFile (&FileHandle
,
315 GENERIC_READ
|SYNCHRONIZE
,
319 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
321 RtlFreeUnicodeString(&FileNameString
);
323 lpReOpenBuff
->nErrCode
= RtlNtStatusToDosError(errCode
);
325 if (!NT_SUCCESS(errCode
))
327 SetLastErrorByStatus (errCode
);
328 return (HFILE
)INVALID_HANDLE_VALUE
;
331 return (HFILE
)FileHandle
;
339 FlushFileBuffers(HANDLE hFile
)
342 IO_STATUS_BLOCK IoStatusBlock
;
344 if (IsConsoleHandle(hFile
))
349 errCode
= NtFlushBuffersFile(hFile
,
351 if (!NT_SUCCESS(errCode
))
353 SetLastErrorByStatus(errCode
);
364 SetFilePointer(HANDLE hFile
,
365 LONG lDistanceToMove
,
366 PLONG lpDistanceToMoveHigh
,
369 FILE_POSITION_INFORMATION FilePosition
;
370 FILE_STANDARD_INFORMATION FileStandard
;
372 IO_STATUS_BLOCK IoStatusBlock
;
373 LARGE_INTEGER Distance
;
375 DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
376 hFile
,lDistanceToMove
,dwMoveMethod
);
378 if(IsConsoleHandle(hFile
))
380 SetLastError(ERROR_INVALID_HANDLE
);
384 Distance
.u
.LowPart
= lDistanceToMove
;
385 if (lpDistanceToMoveHigh
)
387 Distance
.u
.HighPart
= *lpDistanceToMoveHigh
;
389 else if (lDistanceToMove
>= 0)
391 Distance
.u
.HighPart
= 0;
395 Distance
.u
.HighPart
= -1;
401 NtQueryInformationFile(hFile
,
404 sizeof(FILE_POSITION_INFORMATION
),
405 FilePositionInformation
);
406 FilePosition
.CurrentByteOffset
.QuadPart
+= Distance
.QuadPart
;
409 NtQueryInformationFile(hFile
,
412 sizeof(FILE_STANDARD_INFORMATION
),
413 FileStandardInformation
);
414 FilePosition
.CurrentByteOffset
.QuadPart
=
415 FileStandard
.EndOfFile
.QuadPart
+ Distance
.QuadPart
;
418 FilePosition
.CurrentByteOffset
.QuadPart
= Distance
.QuadPart
;
421 SetLastError(ERROR_INVALID_PARAMETER
);
425 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
427 SetLastError(ERROR_NEGATIVE_SEEK
);
431 errCode
= NtSetInformationFile(hFile
,
434 sizeof(FILE_POSITION_INFORMATION
),
435 FilePositionInformation
);
436 if (!NT_SUCCESS(errCode
))
438 SetLastErrorByStatus(errCode
);
442 if (lpDistanceToMoveHigh
!= NULL
)
444 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
446 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
455 SetFilePointerEx(HANDLE hFile
,
456 LARGE_INTEGER liDistanceToMove
,
457 PLARGE_INTEGER lpNewFilePointer
,
460 FILE_POSITION_INFORMATION FilePosition
;
461 FILE_STANDARD_INFORMATION FileStandard
;
463 IO_STATUS_BLOCK IoStatusBlock
;
465 if(IsConsoleHandle(hFile
))
467 SetLastError(ERROR_INVALID_HANDLE
);
474 NtQueryInformationFile(hFile
,
477 sizeof(FILE_POSITION_INFORMATION
),
478 FilePositionInformation
);
479 FilePosition
.CurrentByteOffset
.QuadPart
+= liDistanceToMove
.QuadPart
;
482 NtQueryInformationFile(hFile
,
485 sizeof(FILE_STANDARD_INFORMATION
),
486 FileStandardInformation
);
487 FilePosition
.CurrentByteOffset
.QuadPart
=
488 FileStandard
.EndOfFile
.QuadPart
+ liDistanceToMove
.QuadPart
;
491 FilePosition
.CurrentByteOffset
.QuadPart
= liDistanceToMove
.QuadPart
;
494 SetLastError(ERROR_INVALID_PARAMETER
);
498 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
500 SetLastError(ERROR_NEGATIVE_SEEK
);
504 errCode
= NtSetInformationFile(hFile
,
507 sizeof(FILE_POSITION_INFORMATION
),
508 FilePositionInformation
);
509 if (!NT_SUCCESS(errCode
))
511 SetLastErrorByStatus(errCode
);
515 if (lpNewFilePointer
)
517 *lpNewFilePointer
= FilePosition
.CurrentByteOffset
;
527 GetFileType(HANDLE hFile
)
529 FILE_FS_DEVICE_INFORMATION DeviceInfo
;
530 IO_STATUS_BLOCK StatusBlock
;
533 /* Get real handle */
534 switch ((ULONG
)hFile
)
536 case STD_INPUT_HANDLE
:
537 hFile
= NtCurrentPeb()->ProcessParameters
->hStdInput
;
540 case STD_OUTPUT_HANDLE
:
541 hFile
= NtCurrentPeb()->ProcessParameters
->hStdOutput
;
544 case STD_ERROR_HANDLE
:
545 hFile
= NtCurrentPeb()->ProcessParameters
->hStdError
;
549 /* Check for console handle */
550 if (IsConsoleHandle(hFile
))
552 if (VerifyConsoleIoHandle(hFile
))
553 return FILE_TYPE_CHAR
;
556 Status
= NtQueryVolumeInformationFile(hFile
,
559 sizeof(FILE_FS_DEVICE_INFORMATION
),
560 FileFsDeviceInformation
);
561 if (!NT_SUCCESS(Status
))
563 SetLastErrorByStatus(Status
);
564 return FILE_TYPE_UNKNOWN
;
567 switch (DeviceInfo
.DeviceType
)
569 case FILE_DEVICE_CD_ROM
:
570 case FILE_DEVICE_CD_ROM_FILE_SYSTEM
:
571 case FILE_DEVICE_CONTROLLER
:
572 case FILE_DEVICE_DATALINK
:
573 case FILE_DEVICE_DFS
:
574 case FILE_DEVICE_DISK
:
575 case FILE_DEVICE_DISK_FILE_SYSTEM
:
576 case FILE_DEVICE_VIRTUAL_DISK
:
577 return FILE_TYPE_DISK
;
579 case FILE_DEVICE_KEYBOARD
:
580 case FILE_DEVICE_MOUSE
:
581 case FILE_DEVICE_NULL
:
582 case FILE_DEVICE_PARALLEL_PORT
:
583 case FILE_DEVICE_PRINTER
:
584 case FILE_DEVICE_SERIAL_PORT
:
585 case FILE_DEVICE_SCREEN
:
586 case FILE_DEVICE_SOUND
:
587 case FILE_DEVICE_MODEM
:
588 return FILE_TYPE_CHAR
;
590 case FILE_DEVICE_NAMED_PIPE
:
591 return FILE_TYPE_PIPE
;
594 return FILE_TYPE_UNKNOWN
;
602 GetFileSize(HANDLE hFile
,
603 LPDWORD lpFileSizeHigh
)
606 FILE_STANDARD_INFORMATION FileStandard
;
607 IO_STATUS_BLOCK IoStatusBlock
;
609 errCode
= NtQueryInformationFile(hFile
,
612 sizeof(FILE_STANDARD_INFORMATION
),
613 FileStandardInformation
);
614 if (!NT_SUCCESS(errCode
))
616 SetLastErrorByStatus(errCode
);
617 if ( lpFileSizeHigh
== NULL
)
626 if ( lpFileSizeHigh
!= NULL
)
627 *lpFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
629 return FileStandard
.EndOfFile
.u
.LowPart
;
640 PLARGE_INTEGER lpFileSize
644 FILE_STANDARD_INFORMATION FileStandard
;
645 IO_STATUS_BLOCK IoStatusBlock
;
647 errCode
= NtQueryInformationFile(hFile
,
650 sizeof(FILE_STANDARD_INFORMATION
),
651 FileStandardInformation
);
652 if (!NT_SUCCESS(errCode
))
654 SetLastErrorByStatus(errCode
);
658 *lpFileSize
= FileStandard
.EndOfFile
;
668 GetCompressedFileSizeA(LPCSTR lpFileName
,
669 LPDWORD lpFileSizeHigh
)
673 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
674 return INVALID_FILE_SIZE
;
676 return GetCompressedFileSizeW(FileNameW
, lpFileSizeHigh
);
684 GetCompressedFileSizeW(LPCWSTR lpFileName
,
685 LPDWORD lpFileSizeHigh
)
687 FILE_COMPRESSION_INFORMATION FileCompression
;
689 IO_STATUS_BLOCK IoStatusBlock
;
692 hFile
= CreateFileW(lpFileName
,
697 FILE_ATTRIBUTE_NORMAL
,
700 if (hFile
== INVALID_HANDLE_VALUE
)
701 return INVALID_FILE_SIZE
;
703 errCode
= NtQueryInformationFile(hFile
,
706 sizeof(FILE_COMPRESSION_INFORMATION
),
707 FileCompressionInformation
);
711 if (!NT_SUCCESS(errCode
))
713 SetLastErrorByStatus(errCode
);
714 return INVALID_FILE_SIZE
;
718 *lpFileSizeHigh
= FileCompression
.CompressedFileSize
.u
.HighPart
;
720 SetLastError(NO_ERROR
);
721 return FileCompression
.CompressedFileSize
.u
.LowPart
;
729 GetFileInformationByHandle(HANDLE hFile
,
730 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
734 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
739 FILE_BASIC_INFORMATION FileBasic
;
740 FILE_INTERNAL_INFORMATION FileInternal
;
741 FILE_STANDARD_INFORMATION FileStandard
;
743 IO_STATUS_BLOCK IoStatusBlock
;
745 if(IsConsoleHandle(hFile
))
747 SetLastError(ERROR_INVALID_HANDLE
);
751 errCode
= NtQueryInformationFile(hFile
,
754 sizeof(FILE_BASIC_INFORMATION
),
755 FileBasicInformation
);
756 if (!NT_SUCCESS(errCode
))
758 SetLastErrorByStatus(errCode
);
762 lpFileInformation
->dwFileAttributes
= (DWORD
)FileBasic
.FileAttributes
;
764 lpFileInformation
->ftCreationTime
.dwHighDateTime
= FileBasic
.CreationTime
.u
.HighPart
;
765 lpFileInformation
->ftCreationTime
.dwLowDateTime
= FileBasic
.CreationTime
.u
.LowPart
;
767 lpFileInformation
->ftLastAccessTime
.dwHighDateTime
= FileBasic
.LastAccessTime
.u
.HighPart
;
768 lpFileInformation
->ftLastAccessTime
.dwLowDateTime
= FileBasic
.LastAccessTime
.u
.LowPart
;
770 lpFileInformation
->ftLastWriteTime
.dwHighDateTime
= FileBasic
.LastWriteTime
.u
.HighPart
;
771 lpFileInformation
->ftLastWriteTime
.dwLowDateTime
= FileBasic
.LastWriteTime
.u
.LowPart
;
773 errCode
= NtQueryInformationFile(hFile
,
776 sizeof(FILE_INTERNAL_INFORMATION
),
777 FileInternalInformation
);
778 if (!NT_SUCCESS(errCode
))
780 SetLastErrorByStatus(errCode
);
784 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
785 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
787 errCode
= NtQueryVolumeInformationFile(hFile
,
790 sizeof(FileFsVolume
),
791 FileFsVolumeInformation
);
792 if (!NT_SUCCESS(errCode
))
794 SetLastErrorByStatus(errCode
);
798 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.FileFsVolume
.VolumeSerialNumber
;
800 errCode
= NtQueryInformationFile(hFile
,
803 sizeof(FILE_STANDARD_INFORMATION
),
804 FileStandardInformation
);
805 if (!NT_SUCCESS(errCode
))
807 SetLastErrorByStatus(errCode
);
811 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
812 lpFileInformation
->nFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
813 lpFileInformation
->nFileSizeLow
= FileStandard
.EndOfFile
.u
.LowPart
;
823 GetFileAttributesExW(LPCWSTR lpFileName
,
824 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
825 LPVOID lpFileInformation
)
827 FILE_NETWORK_OPEN_INFORMATION FileInformation
;
828 OBJECT_ATTRIBUTES ObjectAttributes
;
829 IO_STATUS_BLOCK IoStatusBlock
;
830 UNICODE_STRING FileName
;
833 WIN32_FILE_ATTRIBUTE_DATA
* FileAttributeData
;
835 DPRINT("GetFileAttributesExW(%S) called\n", lpFileName
);
838 if (fInfoLevelId
!= GetFileExInfoStandard
|| lpFileInformation
== NULL
)
840 SetLastError(ERROR_INVALID_PARAMETER
);
844 /* Validate and translate the filename */
845 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
850 DPRINT1 ("Invalid path\n");
851 SetLastError (ERROR_BAD_PATHNAME
);
855 /* build the object attributes */
856 InitializeObjectAttributes (&ObjectAttributes
,
858 OBJ_CASE_INSENSITIVE
,
863 Status
= NtOpenFile (&FileHandle
,
864 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
,
867 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
868 FILE_SYNCHRONOUS_IO_NONALERT
);
869 RtlFreeUnicodeString (&FileName
);
870 if (!NT_SUCCESS (Status
))
872 DPRINT ("NtOpenFile() failed %x (Status %lx)\n", &ObjectAttributes
, Status
);
873 SetLastErrorByStatus (Status
);
877 /* Get file attributes */
878 Status
= NtQueryInformationFile (FileHandle
,
881 sizeof(FILE_NETWORK_OPEN_INFORMATION
),
882 FileNetworkOpenInformation
);
883 NtClose (FileHandle
);
885 if (!NT_SUCCESS (Status
))
887 DPRINT1 ("NtQueryInformationFile() failed (Status %lx)\n", Status
);
888 SetLastErrorByStatus (Status
);
892 FileAttributeData
= (WIN32_FILE_ATTRIBUTE_DATA
*)lpFileInformation
;
893 FileAttributeData
->dwFileAttributes
= FileInformation
.FileAttributes
;
894 FileAttributeData
->ftCreationTime
.dwLowDateTime
= FileInformation
.CreationTime
.u
.LowPart
;
895 FileAttributeData
->ftCreationTime
.dwHighDateTime
= FileInformation
.CreationTime
.u
.HighPart
;
896 FileAttributeData
->ftLastAccessTime
.dwLowDateTime
= FileInformation
.LastAccessTime
.u
.LowPart
;
897 FileAttributeData
->ftLastAccessTime
.dwHighDateTime
= FileInformation
.LastAccessTime
.u
.HighPart
;
898 FileAttributeData
->ftLastWriteTime
.dwLowDateTime
= FileInformation
.LastWriteTime
.u
.LowPart
;
899 FileAttributeData
->ftLastWriteTime
.dwHighDateTime
= FileInformation
.LastWriteTime
.u
.HighPart
;
900 FileAttributeData
->nFileSizeLow
= FileInformation
.EndOfFile
.u
.LowPart
;
901 FileAttributeData
->nFileSizeHigh
= FileInformation
.EndOfFile
.u
.HighPart
;
910 GetFileAttributesExA(LPCSTR lpFileName
,
911 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
912 LPVOID lpFileInformation
)
916 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
919 return GetFileAttributesExW(FileNameW
, fInfoLevelId
, lpFileInformation
);
927 GetFileAttributesA(LPCSTR lpFileName
)
929 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
933 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
934 return INVALID_FILE_ATTRIBUTES
;
936 ret
= GetFileAttributesExW(FileNameW
, GetFileExInfoStandard
, &FileAttributeData
);
938 return ret
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
946 GetFileAttributesW(LPCWSTR lpFileName
)
948 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
951 DPRINT ("GetFileAttributeW(%S) called\n", lpFileName
);
953 Result
= GetFileAttributesExW(lpFileName
, GetFileExInfoStandard
, &FileAttributeData
);
955 return Result
? FileAttributeData
.dwFileAttributes
: INVALID_FILE_ATTRIBUTES
;
961 DWORD dwFileAttributes
)
965 if (!(FileNameW
= FilenameA2W(lpFileName
, FALSE
)))
968 return SetFileAttributesW(FileNameW
, dwFileAttributes
);
976 SetFileAttributesW(LPCWSTR lpFileName
,
977 DWORD dwFileAttributes
)
979 FILE_BASIC_INFORMATION FileInformation
;
980 OBJECT_ATTRIBUTES ObjectAttributes
;
981 IO_STATUS_BLOCK IoStatusBlock
;
982 UNICODE_STRING FileName
;
986 DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName
, dwFileAttributes
);
988 /* Validate and translate the filename */
989 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
994 DPRINT ("Invalid path\n");
995 SetLastError (ERROR_BAD_PATHNAME
);
998 DPRINT ("FileName: \'%wZ\'\n", &FileName
);
1000 /* build the object attributes */
1001 InitializeObjectAttributes (&ObjectAttributes
,
1003 OBJ_CASE_INSENSITIVE
,
1008 Status
= NtOpenFile (&FileHandle
,
1009 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
1012 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
1013 FILE_SYNCHRONOUS_IO_NONALERT
);
1014 RtlFreeUnicodeString (&FileName
);
1015 if (!NT_SUCCESS (Status
))
1017 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
1018 SetLastErrorByStatus (Status
);
1022 Status
= NtQueryInformationFile(FileHandle
,
1025 sizeof(FILE_BASIC_INFORMATION
),
1026 FileBasicInformation
);
1027 if (!NT_SUCCESS(Status
))
1029 DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status
);
1030 NtClose (FileHandle
);
1031 SetLastErrorByStatus (Status
);
1035 FileInformation
.FileAttributes
= dwFileAttributes
;
1036 Status
= NtSetInformationFile(FileHandle
,
1039 sizeof(FILE_BASIC_INFORMATION
),
1040 FileBasicInformation
);
1041 NtClose (FileHandle
);
1042 if (!NT_SUCCESS(Status
))
1044 DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status
);
1045 SetLastErrorByStatus (Status
);
1055 /***********************************************************************
1056 * GetTempFileNameA (KERNEL32.@)
1058 UINT WINAPI
GetTempFileNameA( LPCSTR path
, LPCSTR prefix
, UINT unique
, LPSTR buffer
)
1060 WCHAR BufferW
[MAX_PATH
];
1065 if (!(PathW
= FilenameA2W(path
, FALSE
)))
1069 FilenameA2W_N(PrefixW
, 3+1, prefix
, -1);
1071 ret
= GetTempFileNameW(PathW
, prefix
? PrefixW
: NULL
, unique
, BufferW
);
1074 FilenameW2A_N(buffer
, MAX_PATH
, BufferW
, -1);
1079 /***********************************************************************
1080 * GetTempFileNameW (KERNEL32.@)
1082 UINT WINAPI
GetTempFileNameW( LPCWSTR path
, LPCWSTR prefix
, UINT unique
, LPWSTR buffer
)
1084 static const WCHAR formatW
[] = L
"%x.tmp";
1089 if ( !path
|| !prefix
|| !buffer
)
1091 SetLastError( ERROR_INVALID_PARAMETER
);
1095 wcscpy( buffer
, path
);
1096 p
= buffer
+ wcslen(buffer
);
1098 /* add a \, if there isn't one */
1099 if ((p
== buffer
) || (p
[-1] != '\\')) *p
++ = '\\';
1101 for (i
= 3; (i
> 0) && (*prefix
); i
--) *p
++ = *prefix
++;
1105 if (unique
) swprintf( p
, formatW
, unique
);
1108 /* get a "random" unique number and try to create the file */
1110 UINT num
= GetTickCount() & 0xffff;
1116 swprintf( p
, formatW
, unique
);
1117 handle
= CreateFileW( buffer
, GENERIC_WRITE
, 0, NULL
,
1118 CREATE_NEW
, FILE_ATTRIBUTE_NORMAL
, 0 );
1119 if (handle
!= INVALID_HANDLE_VALUE
)
1120 { /* We created it */
1121 DPRINT("created %S\n", buffer
);
1122 CloseHandle( handle
);
1125 if (GetLastError() != ERROR_FILE_EXISTS
&&
1126 GetLastError() != ERROR_SHARING_VIOLATION
)
1127 break; /* No need to go on */
1128 if (!(++unique
& 0xffff)) unique
= 1;
1129 } while (unique
!= num
);
1132 DPRINT("returning %S\n", buffer
);
1144 GetFileTime(HANDLE hFile
,
1145 LPFILETIME lpCreationTime
,
1146 LPFILETIME lpLastAccessTime
,
1147 LPFILETIME lpLastWriteTime
)
1149 IO_STATUS_BLOCK IoStatusBlock
;
1150 FILE_BASIC_INFORMATION FileBasic
;
1153 if(IsConsoleHandle(hFile
))
1155 SetLastError(ERROR_INVALID_HANDLE
);
1159 Status
= NtQueryInformationFile(hFile
,
1162 sizeof(FILE_BASIC_INFORMATION
),
1163 FileBasicInformation
);
1164 if (!NT_SUCCESS(Status
))
1166 SetLastErrorByStatus(Status
);
1171 memcpy(lpCreationTime
, &FileBasic
.CreationTime
, sizeof(FILETIME
));
1172 if (lpLastAccessTime
)
1173 memcpy(lpLastAccessTime
, &FileBasic
.LastAccessTime
, sizeof(FILETIME
));
1174 if (lpLastWriteTime
)
1175 memcpy(lpLastWriteTime
, &FileBasic
.LastWriteTime
, sizeof(FILETIME
));
1185 SetFileTime(HANDLE hFile
,
1186 CONST FILETIME
*lpCreationTime
,
1187 CONST FILETIME
*lpLastAccessTime
,
1188 CONST FILETIME
*lpLastWriteTime
)
1190 FILE_BASIC_INFORMATION FileBasic
;
1191 IO_STATUS_BLOCK IoStatusBlock
;
1194 if(IsConsoleHandle(hFile
))
1196 SetLastError(ERROR_INVALID_HANDLE
);
1200 Status
= NtQueryInformationFile(hFile
,
1203 sizeof(FILE_BASIC_INFORMATION
),
1204 FileBasicInformation
);
1205 if (!NT_SUCCESS(Status
))
1207 SetLastErrorByStatus(Status
);
1212 memcpy(&FileBasic
.CreationTime
, lpCreationTime
, sizeof(FILETIME
));
1213 if (lpLastAccessTime
)
1214 memcpy(&FileBasic
.LastAccessTime
, lpLastAccessTime
, sizeof(FILETIME
));
1215 if (lpLastWriteTime
)
1216 memcpy(&FileBasic
.LastWriteTime
, lpLastWriteTime
, sizeof(FILETIME
));
1218 // should i initialize changetime ???
1220 Status
= NtSetInformationFile(hFile
,
1223 sizeof(FILE_BASIC_INFORMATION
),
1224 FileBasicInformation
);
1225 if (!NT_SUCCESS(Status
))
1227 SetLastErrorByStatus(Status
);
1236 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
1241 SetEndOfFile(HANDLE hFile
)
1243 IO_STATUS_BLOCK IoStatusBlock
;
1244 FILE_END_OF_FILE_INFORMATION EndOfFileInfo
;
1245 FILE_ALLOCATION_INFORMATION FileAllocationInfo
;
1246 FILE_POSITION_INFORMATION FilePosInfo
;
1249 if(IsConsoleHandle(hFile
))
1251 SetLastError(ERROR_INVALID_HANDLE
);
1255 //get current position
1256 Status
= NtQueryInformationFile(
1260 sizeof(FILE_POSITION_INFORMATION
),
1261 FilePositionInformation
1264 if (!NT_SUCCESS(Status
)){
1265 SetLastErrorByStatus(Status
);
1269 EndOfFileInfo
.EndOfFile
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1273 This call is not supposed to free up any space after the eof marker
1274 if the file gets truncated. We have to deallocate the space explicitly afterwards.
1275 But...most file systems dispatch both FileEndOfFileInformation
1276 and FileAllocationInformation as they were the same command.
1279 Status
= NtSetInformationFile(
1281 &IoStatusBlock
, //out
1283 sizeof(FILE_END_OF_FILE_INFORMATION
),
1284 FileEndOfFileInformation
1287 if (!NT_SUCCESS(Status
)){
1288 SetLastErrorByStatus(Status
);
1292 FileAllocationInfo
.AllocationSize
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1295 Status
= NtSetInformationFile(
1297 &IoStatusBlock
, //out
1298 &FileAllocationInfo
,
1299 sizeof(FILE_ALLOCATION_INFORMATION
),
1300 FileAllocationInformation
1303 if (!NT_SUCCESS(Status
)){
1304 SetLastErrorByStatus(Status
);
1320 LONGLONG ValidDataLength
1323 IO_STATUS_BLOCK IoStatusBlock
;
1324 FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation
;
1327 ValidDataLengthInformation
.ValidDataLength
.QuadPart
= ValidDataLength
;
1329 Status
= NtSetInformationFile(
1331 &IoStatusBlock
, //out
1332 &ValidDataLengthInformation
,
1333 sizeof(FILE_VALID_DATA_LENGTH_INFORMATION
),
1334 FileValidDataLengthInformation
1337 if (!NT_SUCCESS(Status
)){
1338 SetLastErrorByStatus(Status
);
1354 LPCWSTR lpShortName
)
1358 UNICODE_STRING ShortName
;
1359 IO_STATUS_BLOCK IoStatusBlock
;
1360 PFILE_NAME_INFORMATION FileNameInformation
;
1362 if(IsConsoleHandle(hFile
))
1364 SetLastError(ERROR_INVALID_HANDLE
);
1370 SetLastError(ERROR_INVALID_PARAMETER
);
1374 RtlInitUnicodeString(&ShortName
, lpShortName
);
1376 NeededSize
= sizeof(FILE_NAME_INFORMATION
) + ShortName
.Length
+ sizeof(WCHAR
);
1377 if(!(FileNameInformation
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, NeededSize
)))
1379 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1383 FileNameInformation
->FileNameLength
= ShortName
.Length
;
1384 RtlCopyMemory(FileNameInformation
->FileName
, ShortName
.Buffer
, ShortName
.Length
);
1386 Status
= NtSetInformationFile(hFile
,
1387 &IoStatusBlock
, //out
1388 FileNameInformation
,
1390 FileShortNameInformation
);
1392 RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInformation
);
1393 if(!NT_SUCCESS(Status
))
1396 SetLastErrorByStatus(Status
);
1399 return NT_SUCCESS(Status
);
1415 if(IsConsoleHandle(hFile
))
1417 SetLastError(ERROR_INVALID_HANDLE
);
1423 SetLastError(ERROR_INVALID_PARAMETER
);
1427 if (!(ShortNameW
= FilenameA2W(lpShortName
, FALSE
)))
1430 return SetFileShortNameW(hFile
, ShortNameW
);
1439 CheckNameLegalDOS8Dot3W(
1441 LPSTR lpOemName OPTIONAL
,
1442 DWORD OemNameSize OPTIONAL
,
1443 PBOOL pbNameContainsSpaces OPTIONAL
,
1447 UNICODE_STRING Name
;
1448 ANSI_STRING AnsiName
;
1450 if(lpName
== NULL
||
1451 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1452 pbNameLegal
== NULL
)
1454 SetLastError(ERROR_INVALID_PARAMETER
);
1458 if(lpOemName
!= NULL
)
1460 AnsiName
.Buffer
= lpOemName
;
1461 AnsiName
.MaximumLength
= OemNameSize
* sizeof(CHAR
);
1462 AnsiName
.Length
= 0;
1465 RtlInitUnicodeString(&Name
, lpName
);
1467 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1468 (lpOemName
? &AnsiName
: NULL
),
1469 (BOOLEAN
*)pbNameContainsSpaces
);
1480 CheckNameLegalDOS8Dot3A(
1482 LPSTR lpOemName OPTIONAL
,
1483 DWORD OemNameSize OPTIONAL
,
1484 PBOOL pbNameContainsSpaces OPTIONAL
,
1488 UNICODE_STRING Name
;
1489 ANSI_STRING AnsiName
, AnsiInputName
;
1492 if(lpName
== NULL
||
1493 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1494 pbNameLegal
== NULL
)
1496 SetLastError(ERROR_INVALID_PARAMETER
);
1500 if(lpOemName
!= NULL
)
1502 AnsiName
.Buffer
= lpOemName
;
1503 AnsiName
.MaximumLength
= OemNameSize
* sizeof(CHAR
);
1504 AnsiName
.Length
= 0;
1507 RtlInitAnsiString(&AnsiInputName
, (LPSTR
)lpName
);
1509 Status
= RtlAnsiStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1511 Status
= RtlOemStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1513 if(!NT_SUCCESS(Status
))
1515 SetLastErrorByStatus(Status
);
1519 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1520 (lpOemName
? &AnsiName
: NULL
),
1521 (BOOLEAN
*)pbNameContainsSpaces
);
1523 RtlFreeUnicodeString(&Name
);