1 /* $Id: file.c,v 1.57 2004/09/06 15:56:25 weiden Exp $
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 <ddk/ntifs.h>
19 #include "../include/debug.h"
22 /* GLOBALS ******************************************************************/
24 BOOL bIsFileApiAnsi
= TRUE
; // set the file api to ansi or oem
27 /* FUNCTIONS ****************************************************************/
33 SetFileApisToOEM(VOID
)
35 bIsFileApiAnsi
= FALSE
;
43 SetFileApisToANSI(VOID
)
45 bIsFileApiAnsi
= TRUE
;
55 return bIsFileApiAnsi
;
63 OpenFile(LPCSTR lpFileName
,
64 LPOFSTRUCT lpReOpenBuff
,
67 OBJECT_ATTRIBUTES ObjectAttributes
;
68 IO_STATUS_BLOCK IoStatusBlock
;
69 UNICODE_STRING FileNameString
;
70 UNICODE_STRING FileNameU
;
72 WCHAR PathNameW
[MAX_PATH
];
73 HANDLE FileHandle
= NULL
;
78 DPRINT("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName
, lpReOpenBuff
, uStyle
);
80 if (lpReOpenBuff
== NULL
)
85 if ((uStyle
& OF_CREATE
) == OF_CREATE
)
88 switch (uStyle
& 0x70)
90 case OF_SHARE_EXCLUSIVE
: Sharing
= 0; break;
91 case OF_SHARE_DENY_WRITE
: Sharing
= FILE_SHARE_READ
; break;
92 case OF_SHARE_DENY_READ
: Sharing
= FILE_SHARE_WRITE
; break;
93 case OF_SHARE_DENY_NONE
:
96 Sharing
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
98 return (HFILE
) CreateFileA (lpFileName
,
99 GENERIC_READ
| GENERIC_WRITE
,
103 FILE_ATTRIBUTE_NORMAL
,
107 RtlInitAnsiString (&FileName
, (LPSTR
)lpFileName
);
109 /* convert ansi (or oem) string to unicode */
111 RtlAnsiStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
113 RtlOemStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
115 Len
= SearchPathW (NULL
,
122 RtlFreeUnicodeString(&FileNameU
);
124 if (Len
== 0 || Len
> OFS_MAXPATHNAME
)
126 return (HFILE
)INVALID_HANDLE_VALUE
;
129 FileName
.Buffer
= lpReOpenBuff
->szPathName
;
131 FileName
.MaximumLength
= OFS_MAXPATHNAME
;
133 RtlInitUnicodeString(&FileNameU
, PathNameW
);
135 /* convert unicode string to ansi (or oem) */
137 RtlUnicodeStringToAnsiString (&FileName
, &FileNameU
, FALSE
);
139 RtlUnicodeStringToOemString (&FileName
, &FileNameU
, FALSE
);
141 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)PathNameW
,
146 return (HFILE
)INVALID_HANDLE_VALUE
;
150 // FILE_NO_INTERMEDIATE_BUFFERING
152 if ((uStyle
& OF_PARSE
) == OF_PARSE
)
154 RtlFreeUnicodeString(&FileNameString
);
158 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
159 ObjectAttributes
.RootDirectory
= NULL
;
160 ObjectAttributes
.ObjectName
= &FileNameString
;
161 ObjectAttributes
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
;
162 ObjectAttributes
.SecurityDescriptor
= NULL
;
163 ObjectAttributes
.SecurityQualityOfService
= NULL
;
165 errCode
= NtOpenFile (&FileHandle
,
166 GENERIC_READ
|SYNCHRONIZE
,
170 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
172 RtlFreeUnicodeString(&FileNameString
);
174 lpReOpenBuff
->nErrCode
= RtlNtStatusToDosError(errCode
);
176 if (!NT_SUCCESS(errCode
))
178 SetLastErrorByStatus (errCode
);
179 return (HFILE
)INVALID_HANDLE_VALUE
;
182 return (HFILE
)FileHandle
;
190 FlushFileBuffers(HANDLE hFile
)
193 IO_STATUS_BLOCK IoStatusBlock
;
195 if (IsConsoleHandle(hFile
))
200 errCode
= NtFlushBuffersFile(hFile
,
202 if (!NT_SUCCESS(errCode
))
204 SetLastErrorByStatus(errCode
);
215 SetFilePointer(HANDLE hFile
,
216 LONG lDistanceToMove
,
217 PLONG lpDistanceToMoveHigh
,
220 FILE_POSITION_INFORMATION FilePosition
;
221 FILE_STANDARD_INFORMATION FileStandard
;
223 IO_STATUS_BLOCK IoStatusBlock
;
224 LARGE_INTEGER Distance
;
226 DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
227 hFile
,lDistanceToMove
,dwMoveMethod
);
229 if(IsConsoleHandle(hFile
))
231 SetLastError(ERROR_INVALID_HANDLE
);
235 Distance
.u
.LowPart
= lDistanceToMove
;
236 if (lpDistanceToMoveHigh
)
238 Distance
.u
.HighPart
= *lpDistanceToMoveHigh
;
240 else if (lDistanceToMove
>= 0)
242 Distance
.u
.HighPart
= 0;
246 Distance
.u
.HighPart
= -1;
252 NtQueryInformationFile(hFile
,
255 sizeof(FILE_POSITION_INFORMATION
),
256 FilePositionInformation
);
257 FilePosition
.CurrentByteOffset
.QuadPart
+= Distance
.QuadPart
;
260 NtQueryInformationFile(hFile
,
263 sizeof(FILE_STANDARD_INFORMATION
),
264 FileStandardInformation
);
265 FilePosition
.CurrentByteOffset
.QuadPart
=
266 FileStandard
.EndOfFile
.QuadPart
+ Distance
.QuadPart
;
269 FilePosition
.CurrentByteOffset
.QuadPart
= Distance
.QuadPart
;
272 SetLastError(ERROR_INVALID_PARAMETER
);
276 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
278 SetLastError(ERROR_NEGATIVE_SEEK
);
282 errCode
= NtSetInformationFile(hFile
,
285 sizeof(FILE_POSITION_INFORMATION
),
286 FilePositionInformation
);
287 if (!NT_SUCCESS(errCode
))
289 SetLastErrorByStatus(errCode
);
293 if (lpDistanceToMoveHigh
!= NULL
)
295 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
297 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
306 SetFilePointerEx(HANDLE hFile
,
307 LARGE_INTEGER liDistanceToMove
,
308 PLARGE_INTEGER lpNewFilePointer
,
311 FILE_POSITION_INFORMATION FilePosition
;
312 FILE_STANDARD_INFORMATION FileStandard
;
314 IO_STATUS_BLOCK IoStatusBlock
;
316 if(IsConsoleHandle(hFile
))
318 SetLastError(ERROR_INVALID_HANDLE
);
325 NtQueryInformationFile(hFile
,
328 sizeof(FILE_POSITION_INFORMATION
),
329 FilePositionInformation
);
330 FilePosition
.CurrentByteOffset
.QuadPart
+= liDistanceToMove
.QuadPart
;
333 NtQueryInformationFile(hFile
,
336 sizeof(FILE_STANDARD_INFORMATION
),
337 FileStandardInformation
);
338 FilePosition
.CurrentByteOffset
.QuadPart
=
339 FileStandard
.EndOfFile
.QuadPart
+ liDistanceToMove
.QuadPart
;
342 FilePosition
.CurrentByteOffset
.QuadPart
= liDistanceToMove
.QuadPart
;
345 SetLastError(ERROR_INVALID_PARAMETER
);
349 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
351 SetLastError(ERROR_NEGATIVE_SEEK
);
355 errCode
= NtSetInformationFile(hFile
,
358 sizeof(FILE_POSITION_INFORMATION
),
359 FilePositionInformation
);
360 if (!NT_SUCCESS(errCode
))
362 SetLastErrorByStatus(errCode
);
366 if (lpNewFilePointer
)
368 *lpNewFilePointer
= FilePosition
.CurrentByteOffset
;
378 GetFileType(HANDLE hFile
)
380 FILE_FS_DEVICE_INFORMATION DeviceInfo
;
381 IO_STATUS_BLOCK StatusBlock
;
384 /* Get real handle */
385 switch ((ULONG
)hFile
)
387 case STD_INPUT_HANDLE
:
388 hFile
= NtCurrentPeb()->ProcessParameters
->hStdInput
;
391 case STD_OUTPUT_HANDLE
:
392 hFile
= NtCurrentPeb()->ProcessParameters
->hStdOutput
;
395 case STD_ERROR_HANDLE
:
396 hFile
= NtCurrentPeb()->ProcessParameters
->hStdError
;
400 /* Check for console handle */
401 if (IsConsoleHandle(hFile
))
403 if (VerifyConsoleIoHandle(hFile
))
404 return FILE_TYPE_CHAR
;
407 Status
= NtQueryVolumeInformationFile(hFile
,
410 sizeof(FILE_FS_DEVICE_INFORMATION
),
411 FileFsDeviceInformation
);
412 if (!NT_SUCCESS(Status
))
414 SetLastErrorByStatus(Status
);
415 return FILE_TYPE_UNKNOWN
;
418 switch (DeviceInfo
.DeviceType
)
420 case FILE_DEVICE_CD_ROM
:
421 case FILE_DEVICE_CD_ROM_FILE_SYSTEM
:
422 case FILE_DEVICE_CONTROLLER
:
423 case FILE_DEVICE_DATALINK
:
424 case FILE_DEVICE_DFS
:
425 case FILE_DEVICE_DISK
:
426 case FILE_DEVICE_DISK_FILE_SYSTEM
:
427 case FILE_DEVICE_VIRTUAL_DISK
:
428 return FILE_TYPE_DISK
;
430 case FILE_DEVICE_KEYBOARD
:
431 case FILE_DEVICE_MOUSE
:
432 case FILE_DEVICE_NULL
:
433 case FILE_DEVICE_PARALLEL_PORT
:
434 case FILE_DEVICE_PRINTER
:
435 case FILE_DEVICE_SERIAL_PORT
:
436 case FILE_DEVICE_SCREEN
:
437 case FILE_DEVICE_SOUND
:
438 case FILE_DEVICE_MODEM
:
439 return FILE_TYPE_CHAR
;
441 case FILE_DEVICE_NAMED_PIPE
:
442 return FILE_TYPE_PIPE
;
445 return FILE_TYPE_UNKNOWN
;
453 GetFileSize(HANDLE hFile
,
454 LPDWORD lpFileSizeHigh
)
457 FILE_STANDARD_INFORMATION FileStandard
;
458 IO_STATUS_BLOCK IoStatusBlock
;
460 errCode
= NtQueryInformationFile(hFile
,
463 sizeof(FILE_STANDARD_INFORMATION
),
464 FileStandardInformation
);
465 if (!NT_SUCCESS(errCode
))
467 SetLastErrorByStatus(errCode
);
468 if ( lpFileSizeHigh
== NULL
)
477 if ( lpFileSizeHigh
!= NULL
)
478 *lpFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
480 return FileStandard
.EndOfFile
.u
.LowPart
;
491 PLARGE_INTEGER lpFileSize
495 FILE_STANDARD_INFORMATION FileStandard
;
496 IO_STATUS_BLOCK IoStatusBlock
;
498 errCode
= NtQueryInformationFile(hFile
,
501 sizeof(FILE_STANDARD_INFORMATION
),
502 FileStandardInformation
);
503 if (!NT_SUCCESS(errCode
))
505 SetLastErrorByStatus(errCode
);
509 *lpFileSize
= FileStandard
.EndOfFile
;
519 GetCompressedFileSizeA(LPCSTR lpFileName
,
520 LPDWORD lpFileSizeHigh
)
522 UNICODE_STRING FileNameU
;
523 ANSI_STRING FileName
;
526 RtlInitAnsiString(&FileName
,
529 /* convert ansi (or oem) string to unicode */
531 RtlAnsiStringToUnicodeString(&FileNameU
,
535 RtlOemStringToUnicodeString(&FileNameU
,
539 Size
= GetCompressedFileSizeW(FileNameU
.Buffer
,
542 RtlFreeUnicodeString (&FileNameU
);
552 GetCompressedFileSizeW(LPCWSTR lpFileName
,
553 LPDWORD lpFileSizeHigh
)
555 FILE_COMPRESSION_INFORMATION FileCompression
;
557 IO_STATUS_BLOCK IoStatusBlock
;
560 hFile
= CreateFileW(lpFileName
,
565 FILE_ATTRIBUTE_NORMAL
,
568 errCode
= NtQueryInformationFile(hFile
,
571 sizeof(FILE_COMPRESSION_INFORMATION
),
572 FileCompressionInformation
);
573 if (!NT_SUCCESS(errCode
))
576 SetLastErrorByStatus(errCode
);
577 return INVALID_FILE_SIZE
;
582 *lpFileSizeHigh
= FileCompression
.CompressedFileSize
.u
.HighPart
;
584 return FileCompression
.CompressedFileSize
.u
.LowPart
;
592 GetFileInformationByHandle(HANDLE hFile
,
593 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
597 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
602 FILE_BASIC_INFORMATION FileBasic
;
603 FILE_INTERNAL_INFORMATION FileInternal
;
604 FILE_STANDARD_INFORMATION FileStandard
;
606 IO_STATUS_BLOCK IoStatusBlock
;
608 if(IsConsoleHandle(hFile
))
610 SetLastError(ERROR_INVALID_HANDLE
);
614 errCode
= NtQueryInformationFile(hFile
,
617 sizeof(FILE_BASIC_INFORMATION
),
618 FileBasicInformation
);
619 if (!NT_SUCCESS(errCode
))
621 SetLastErrorByStatus(errCode
);
625 lpFileInformation
->dwFileAttributes
= (DWORD
)FileBasic
.FileAttributes
;
627 lpFileInformation
->ftCreationTime
.dwHighDateTime
= FileBasic
.CreationTime
.u
.HighPart
;
628 lpFileInformation
->ftCreationTime
.dwLowDateTime
= FileBasic
.CreationTime
.u
.LowPart
;
630 lpFileInformation
->ftLastAccessTime
.dwHighDateTime
= FileBasic
.LastAccessTime
.u
.HighPart
;
631 lpFileInformation
->ftLastAccessTime
.dwLowDateTime
= FileBasic
.LastAccessTime
.u
.LowPart
;
633 lpFileInformation
->ftLastWriteTime
.dwHighDateTime
= FileBasic
.LastWriteTime
.u
.HighPart
;
634 lpFileInformation
->ftLastWriteTime
.dwLowDateTime
= FileBasic
.LastWriteTime
.u
.LowPart
;
636 errCode
= NtQueryInformationFile(hFile
,
639 sizeof(FILE_INTERNAL_INFORMATION
),
640 FileInternalInformation
);
641 if (!NT_SUCCESS(errCode
))
643 SetLastErrorByStatus(errCode
);
647 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
648 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
650 errCode
= NtQueryVolumeInformationFile(hFile
,
653 sizeof(FileFsVolume
),
654 FileFsVolumeInformation
);
655 if (!NT_SUCCESS(errCode
))
657 SetLastErrorByStatus(errCode
);
661 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.FileFsVolume
.VolumeSerialNumber
;
663 errCode
= NtQueryInformationFile(hFile
,
666 sizeof(FILE_STANDARD_INFORMATION
),
667 FileStandardInformation
);
668 if (!NT_SUCCESS(errCode
))
670 SetLastErrorByStatus(errCode
);
674 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
675 lpFileInformation
->nFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
676 lpFileInformation
->nFileSizeLow
= FileStandard
.EndOfFile
.u
.LowPart
;
686 GetFileAttributesExW(LPCWSTR lpFileName
,
687 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
688 LPVOID lpFileInformation
)
690 FILE_NETWORK_OPEN_INFORMATION FileInformation
;
691 OBJECT_ATTRIBUTES ObjectAttributes
;
692 IO_STATUS_BLOCK IoStatusBlock
;
693 UNICODE_STRING FileName
;
696 WIN32_FILE_ATTRIBUTE_DATA
* FileAttributeData
;
698 DPRINT ("GetFileAttributesExW(%S) called\n", lpFileName
);
701 if (fInfoLevelId
!= GetFileExInfoStandard
|| lpFileInformation
== NULL
)
703 SetLastError(ERROR_INVALID_PARAMETER
);
707 /* Validate and translate the filename */
708 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
713 DPRINT ("Invalid path\n");
714 SetLastError (ERROR_BAD_PATHNAME
);
718 /* build the object attributes */
719 InitializeObjectAttributes (&ObjectAttributes
,
721 OBJ_CASE_INSENSITIVE
,
726 Status
= NtOpenFile (&FileHandle
,
727 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
,
730 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
731 FILE_SYNCHRONOUS_IO_NONALERT
);
732 RtlFreeUnicodeString (&FileName
);
733 if (!NT_SUCCESS (Status
))
735 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
736 SetLastErrorByStatus (Status
);
740 /* Get file attributes */
741 Status
= NtQueryInformationFile (FileHandle
,
744 sizeof(FILE_NETWORK_OPEN_INFORMATION
),
745 FileNetworkOpenInformation
);
746 NtClose (FileHandle
);
748 if (!NT_SUCCESS (Status
))
750 DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status
);
751 SetLastErrorByStatus (Status
);
755 FileAttributeData
= (WIN32_FILE_ATTRIBUTE_DATA
*)lpFileInformation
;
756 FileAttributeData
->dwFileAttributes
= FileInformation
.FileAttributes
;
757 FileAttributeData
->ftCreationTime
.dwLowDateTime
= FileInformation
.CreationTime
.u
.LowPart
;
758 FileAttributeData
->ftCreationTime
.dwHighDateTime
= FileInformation
.CreationTime
.u
.HighPart
;
759 FileAttributeData
->ftLastAccessTime
.dwLowDateTime
= FileInformation
.LastAccessTime
.u
.LowPart
;
760 FileAttributeData
->ftLastAccessTime
.dwHighDateTime
= FileInformation
.LastAccessTime
.u
.HighPart
;
761 FileAttributeData
->ftLastWriteTime
.dwLowDateTime
= FileInformation
.LastWriteTime
.u
.LowPart
;
762 FileAttributeData
->ftLastWriteTime
.dwHighDateTime
= FileInformation
.LastWriteTime
.u
.HighPart
;
763 FileAttributeData
->nFileSizeLow
= FileInformation
.EndOfFile
.u
.LowPart
;
764 FileAttributeData
->nFileSizeHigh
= FileInformation
.EndOfFile
.u
.HighPart
;
773 GetFileAttributesExA(LPCSTR lpFileName
,
774 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
775 LPVOID lpFileInformation
)
777 UNICODE_STRING FileNameU
;
778 ANSI_STRING FileName
;
780 RtlInitAnsiString (&FileName
,
783 /* convert ansi (or oem) string to unicode */
785 RtlAnsiStringToUnicodeString (&FileNameU
,
789 RtlOemStringToUnicodeString (&FileNameU
,
793 Result
= GetFileAttributesExW(FileNameU
.Buffer
, fInfoLevelId
, lpFileInformation
);
795 RtlFreeUnicodeString (&FileNameU
);
805 GetFileAttributesA(LPCSTR lpFileName
)
807 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
808 UNICODE_STRING FileNameU
;
809 ANSI_STRING FileName
;
812 RtlInitAnsiString (&FileName
,
815 /* convert ansi (or oem) string to unicode */
817 RtlAnsiStringToUnicodeString (&FileNameU
,
821 RtlOemStringToUnicodeString (&FileNameU
,
825 Result
= GetFileAttributesExW(FileNameU
.Buffer
, GetFileExInfoStandard
, &FileAttributeData
);
827 RtlFreeUnicodeString (&FileNameU
);
829 return Result
? FileAttributeData
.dwFileAttributes
: 0xffffffff;
837 GetFileAttributesW(LPCWSTR lpFileName
)
839 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
842 DPRINT ("GetFileAttributeW(%S) called\n", lpFileName
);
844 Result
= GetFileAttributesExW(lpFileName
, GetFileExInfoStandard
, &FileAttributeData
);
846 return Result
? FileAttributeData
.dwFileAttributes
: 0xffffffff;
850 SetFileAttributesA(LPCSTR lpFileName
,
851 DWORD dwFileAttributes
)
853 UNICODE_STRING FileNameU
;
854 ANSI_STRING FileName
;
857 RtlInitAnsiString (&FileName
,
860 /* convert ansi (or oem) string to unicode */
862 RtlAnsiStringToUnicodeString (&FileNameU
,
866 RtlOemStringToUnicodeString (&FileNameU
,
870 Result
= SetFileAttributesW (FileNameU
.Buffer
,
873 RtlFreeUnicodeString (&FileNameU
);
883 SetFileAttributesW(LPCWSTR lpFileName
,
884 DWORD dwFileAttributes
)
886 FILE_BASIC_INFORMATION FileInformation
;
887 OBJECT_ATTRIBUTES ObjectAttributes
;
888 IO_STATUS_BLOCK IoStatusBlock
;
889 UNICODE_STRING FileName
;
893 DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName
, dwFileAttributes
);
895 /* Validate and translate the filename */
896 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
901 DPRINT ("Invalid path\n");
902 SetLastError (ERROR_BAD_PATHNAME
);
905 DPRINT ("FileName: \'%wZ\'\n", &FileName
);
907 /* build the object attributes */
908 InitializeObjectAttributes (&ObjectAttributes
,
910 OBJ_CASE_INSENSITIVE
,
915 Status
= NtOpenFile (&FileHandle
,
916 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
919 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
920 FILE_SYNCHRONOUS_IO_NONALERT
);
921 RtlFreeUnicodeString (&FileName
);
922 if (!NT_SUCCESS (Status
))
924 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
925 SetLastErrorByStatus (Status
);
929 Status
= NtQueryInformationFile(FileHandle
,
932 sizeof(FILE_BASIC_INFORMATION
),
933 FileBasicInformation
);
934 if (!NT_SUCCESS(Status
))
936 DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status
);
937 NtClose (FileHandle
);
938 SetLastErrorByStatus (Status
);
942 FileInformation
.FileAttributes
= dwFileAttributes
;
943 Status
= NtSetInformationFile(FileHandle
,
946 sizeof(FILE_BASIC_INFORMATION
),
947 FileBasicInformation
);
948 NtClose (FileHandle
);
949 if (!NT_SUCCESS(Status
))
951 DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status
);
952 SetLastErrorByStatus (Status
);
964 GetTempFileNameA(LPCSTR lpPathName
,
965 LPCSTR lpPrefixString
,
967 LPSTR lpTempFileName
)
970 UINT unique
= uUnique
;
972 const char *format
= "%.*s\\~%.3s%4.4x.TMP";
974 DPRINT("GetTempFileNameA(lpPathName %s, lpPrefixString %.*s, "
975 "uUnique %x, lpTempFileName %x)\n", lpPathName
, 4,
976 lpPrefixString
, uUnique
, lpTempFileName
);
978 if (lpPathName
== NULL
)
981 len
= strlen(lpPathName
);
982 if (len
> 0 && (lpPathName
[len
-1] == '\\' || lpPathName
[len
-1] == '/'))
986 uUnique
= GetCurrentTime();
988 sprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,uUnique
);
993 while ((hFile
= CreateFileA(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
994 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
995 0)) == INVALID_HANDLE_VALUE
)
997 if (GetLastError() != ERROR_ALREADY_EXISTS
)
1001 sprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,++uUnique
);
1012 GetTempFileNameW(LPCWSTR lpPathName
,
1013 LPCWSTR lpPrefixString
,
1015 LPWSTR lpTempFileName
)
1018 UINT unique
= uUnique
;
1020 const WCHAR
*format
= L
"%.*s\\~%.3s%4.4x.TMP";
1022 DPRINT("GetTempFileNameW(lpPathName %S, lpPrefixString %.*S, "
1023 "uUnique %x, lpTempFileName %x)\n", lpPathName
, 4,
1024 lpPrefixString
, uUnique
, lpTempFileName
);
1026 if (lpPathName
== NULL
)
1029 len
= wcslen(lpPathName
);
1030 if (len
> 0 && (lpPathName
[len
-1] == L
'\\' || lpPathName
[len
-1] == L
'/'))
1034 uUnique
= GetCurrentTime();
1036 swprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,uUnique
);
1041 while ((hFile
= CreateFileW(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
1042 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
1043 0)) == INVALID_HANDLE_VALUE
)
1045 if (GetLastError() != ERROR_ALREADY_EXISTS
)
1049 swprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,++uUnique
);
1060 GetFileTime(HANDLE hFile
,
1061 LPFILETIME lpCreationTime
,
1062 LPFILETIME lpLastAccessTime
,
1063 LPFILETIME lpLastWriteTime
)
1065 IO_STATUS_BLOCK IoStatusBlock
;
1066 FILE_BASIC_INFORMATION FileBasic
;
1069 if(IsConsoleHandle(hFile
))
1071 SetLastError(ERROR_INVALID_HANDLE
);
1075 Status
= NtQueryInformationFile(hFile
,
1078 sizeof(FILE_BASIC_INFORMATION
),
1079 FileBasicInformation
);
1080 if (!NT_SUCCESS(Status
))
1082 SetLastErrorByStatus(Status
);
1087 memcpy(lpCreationTime
, &FileBasic
.CreationTime
, sizeof(FILETIME
));
1088 if (lpLastAccessTime
)
1089 memcpy(lpLastAccessTime
, &FileBasic
.LastAccessTime
, sizeof(FILETIME
));
1090 if (lpLastWriteTime
)
1091 memcpy(lpLastWriteTime
, &FileBasic
.LastWriteTime
, sizeof(FILETIME
));
1101 SetFileTime(HANDLE hFile
,
1102 CONST FILETIME
*lpCreationTime
,
1103 CONST FILETIME
*lpLastAccessTime
,
1104 CONST FILETIME
*lpLastWriteTime
)
1106 FILE_BASIC_INFORMATION FileBasic
;
1107 IO_STATUS_BLOCK IoStatusBlock
;
1110 if(IsConsoleHandle(hFile
))
1112 SetLastError(ERROR_INVALID_HANDLE
);
1116 Status
= NtQueryInformationFile(hFile
,
1119 sizeof(FILE_BASIC_INFORMATION
),
1120 FileBasicInformation
);
1121 if (!NT_SUCCESS(Status
))
1123 SetLastErrorByStatus(Status
);
1128 memcpy(&FileBasic
.CreationTime
, lpCreationTime
, sizeof(FILETIME
));
1129 if (lpLastAccessTime
)
1130 memcpy(&FileBasic
.LastAccessTime
, lpLastAccessTime
, sizeof(FILETIME
));
1131 if (lpLastWriteTime
)
1132 memcpy(&FileBasic
.LastWriteTime
, lpLastWriteTime
, sizeof(FILETIME
));
1134 // should i initialize changetime ???
1136 Status
= NtSetInformationFile(hFile
,
1139 sizeof(FILE_BASIC_INFORMATION
),
1140 FileBasicInformation
);
1141 if (!NT_SUCCESS(Status
))
1143 SetLastErrorByStatus(Status
);
1152 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
1157 SetEndOfFile(HANDLE hFile
)
1159 IO_STATUS_BLOCK IoStatusBlock
;
1160 FILE_END_OF_FILE_INFORMATION EndOfFileInfo
;
1161 FILE_ALLOCATION_INFORMATION FileAllocationInfo
;
1162 FILE_POSITION_INFORMATION FilePosInfo
;
1165 if(IsConsoleHandle(hFile
))
1167 SetLastError(ERROR_INVALID_HANDLE
);
1171 //get current position
1172 Status
= NtQueryInformationFile(
1176 sizeof(FILE_POSITION_INFORMATION
),
1177 FilePositionInformation
1180 if (!NT_SUCCESS(Status
)){
1181 SetLastErrorByStatus(Status
);
1185 EndOfFileInfo
.EndOfFile
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1189 This call is not supposed to free up any space after the eof marker
1190 if the file gets truncated. We have to deallocate the space explicitly afterwards.
1191 But...most file systems dispatch both FileEndOfFileInformation
1192 and FileAllocationInformation as they were the same command.
1195 Status
= NtSetInformationFile(
1197 &IoStatusBlock
, //out
1199 sizeof(FILE_END_OF_FILE_INFORMATION
),
1200 FileEndOfFileInformation
1203 if (!NT_SUCCESS(Status
)){
1204 SetLastErrorByStatus(Status
);
1208 FileAllocationInfo
.AllocationSize
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1211 Status
= NtSetInformationFile(
1213 &IoStatusBlock
, //out
1214 &FileAllocationInfo
,
1215 sizeof(FILE_ALLOCATION_INFORMATION
),
1216 FileAllocationInformation
1219 if (!NT_SUCCESS(Status
)){
1220 SetLastErrorByStatus(Status
);
1236 LONGLONG ValidDataLength
1239 IO_STATUS_BLOCK IoStatusBlock
;
1240 FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation
;
1243 ValidDataLengthInformation
.ValidDataLength
.QuadPart
= ValidDataLength
;
1245 Status
= NtSetInformationFile(
1247 &IoStatusBlock
, //out
1248 &ValidDataLengthInformation
,
1249 sizeof(FILE_VALID_DATA_LENGTH_INFORMATION
),
1250 FileValidDataLengthInformation
1253 if (!NT_SUCCESS(Status
)){
1254 SetLastErrorByStatus(Status
);
1269 LPCWSTR lpShortName
)
1273 UNICODE_STRING ShortName
;
1274 IO_STATUS_BLOCK IoStatusBlock
;
1275 PFILE_NAME_INFORMATION FileNameInformation
;
1277 if(IsConsoleHandle(hFile
))
1279 SetLastError(ERROR_INVALID_HANDLE
);
1285 SetLastError(ERROR_INVALID_PARAMETER
);
1289 RtlInitUnicodeString(&ShortName
, lpShortName
);
1291 NeededSize
= sizeof(FILE_NAME_INFORMATION
) + ShortName
.Length
+ sizeof(WCHAR
);
1292 if(!(FileNameInformation
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, NeededSize
)))
1294 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1298 FileNameInformation
->FileNameLength
= ShortName
.Length
;
1299 RtlCopyMemory(FileNameInformation
->FileName
, ShortName
.Buffer
, ShortName
.Length
);
1301 Status
= NtSetInformationFile(hFile
,
1302 &IoStatusBlock
, //out
1303 FileNameInformation
,
1305 FileShortNameInformation
);
1307 RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInformation
);
1308 if(!NT_SUCCESS(Status
))
1311 SetLastErrorByStatus(Status
);
1314 return NT_SUCCESS(Status
);
1330 ANSI_STRING ShortNameA
;
1331 UNICODE_STRING ShortName
;
1333 if(IsConsoleHandle(hFile
))
1335 SetLastError(ERROR_INVALID_HANDLE
);
1341 SetLastError(ERROR_INVALID_PARAMETER
);
1345 RtlInitAnsiString(&ShortNameA
, (LPSTR
)lpShortName
);
1348 Status
= RtlAnsiStringToUnicodeString(&ShortName
, &ShortNameA
, TRUE
);
1350 Status
= RtlOemStringToUnicodeString(&ShortName
, &ShortNameA
, TRUE
);
1351 if(!NT_SUCCESS(Status
))
1353 SetLastErrorByStatus(Status
);
1357 Ret
= SetFileShortNameW(hFile
, ShortName
.Buffer
);
1359 RtlFreeUnicodeString(&ShortName
);