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 ****************************************************************/
32 SetFileApisToOEM(VOID
)
34 bIsFileApiAnsi
= FALSE
;
42 SetFileApisToANSI(VOID
)
44 bIsFileApiAnsi
= TRUE
;
54 return bIsFileApiAnsi
;
62 OpenFile(LPCSTR lpFileName
,
63 LPOFSTRUCT lpReOpenBuff
,
66 OBJECT_ATTRIBUTES ObjectAttributes
;
67 IO_STATUS_BLOCK IoStatusBlock
;
68 UNICODE_STRING FileNameString
;
69 UNICODE_STRING FileNameU
;
71 WCHAR PathNameW
[MAX_PATH
];
72 HANDLE FileHandle
= NULL
;
77 DPRINT("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName
, lpReOpenBuff
, uStyle
);
79 if (lpReOpenBuff
== NULL
)
84 if ((uStyle
& OF_CREATE
) == OF_CREATE
)
87 switch (uStyle
& 0x70)
89 case OF_SHARE_EXCLUSIVE
: Sharing
= 0; break;
90 case OF_SHARE_DENY_WRITE
: Sharing
= FILE_SHARE_READ
; break;
91 case OF_SHARE_DENY_READ
: Sharing
= FILE_SHARE_WRITE
; break;
92 case OF_SHARE_DENY_NONE
:
95 Sharing
= FILE_SHARE_READ
| FILE_SHARE_WRITE
;
97 return (HFILE
) CreateFileA (lpFileName
,
98 GENERIC_READ
| GENERIC_WRITE
,
102 FILE_ATTRIBUTE_NORMAL
,
106 RtlInitAnsiString (&FileName
, (LPSTR
)lpFileName
);
108 /* convert ansi (or oem) string to unicode */
110 RtlAnsiStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
112 RtlOemStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
114 Len
= SearchPathW (NULL
,
121 RtlFreeUnicodeString(&FileNameU
);
123 if (Len
== 0 || Len
> OFS_MAXPATHNAME
)
125 return (HFILE
)INVALID_HANDLE_VALUE
;
128 FileName
.Buffer
= lpReOpenBuff
->szPathName
;
130 FileName
.MaximumLength
= OFS_MAXPATHNAME
;
132 RtlInitUnicodeString(&FileNameU
, PathNameW
);
134 /* convert unicode string to ansi (or oem) */
136 RtlUnicodeStringToAnsiString (&FileName
, &FileNameU
, FALSE
);
138 RtlUnicodeStringToOemString (&FileName
, &FileNameU
, FALSE
);
140 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)PathNameW
,
145 return (HFILE
)INVALID_HANDLE_VALUE
;
149 // FILE_NO_INTERMEDIATE_BUFFERING
151 if ((uStyle
& OF_PARSE
) == OF_PARSE
)
153 RtlFreeUnicodeString(&FileNameString
);
157 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
158 ObjectAttributes
.RootDirectory
= NULL
;
159 ObjectAttributes
.ObjectName
= &FileNameString
;
160 ObjectAttributes
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
;
161 ObjectAttributes
.SecurityDescriptor
= NULL
;
162 ObjectAttributes
.SecurityQualityOfService
= NULL
;
164 errCode
= NtOpenFile (&FileHandle
,
165 GENERIC_READ
|SYNCHRONIZE
,
169 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
171 RtlFreeUnicodeString(&FileNameString
);
173 lpReOpenBuff
->nErrCode
= RtlNtStatusToDosError(errCode
);
175 if (!NT_SUCCESS(errCode
))
177 SetLastErrorByStatus (errCode
);
178 return (HFILE
)INVALID_HANDLE_VALUE
;
181 return (HFILE
)FileHandle
;
189 FlushFileBuffers(HANDLE hFile
)
192 IO_STATUS_BLOCK IoStatusBlock
;
194 if (IsConsoleHandle(hFile
))
199 errCode
= NtFlushBuffersFile(hFile
,
201 if (!NT_SUCCESS(errCode
))
203 SetLastErrorByStatus(errCode
);
214 SetFilePointer(HANDLE hFile
,
215 LONG lDistanceToMove
,
216 PLONG lpDistanceToMoveHigh
,
219 FILE_POSITION_INFORMATION FilePosition
;
220 FILE_STANDARD_INFORMATION FileStandard
;
222 IO_STATUS_BLOCK IoStatusBlock
;
223 LARGE_INTEGER Distance
;
225 DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
226 hFile
,lDistanceToMove
,dwMoveMethod
);
228 if(IsConsoleHandle(hFile
))
230 SetLastError(ERROR_INVALID_HANDLE
);
234 Distance
.u
.LowPart
= lDistanceToMove
;
235 if (lpDistanceToMoveHigh
)
237 Distance
.u
.HighPart
= *lpDistanceToMoveHigh
;
239 else if (lDistanceToMove
>= 0)
241 Distance
.u
.HighPart
= 0;
245 Distance
.u
.HighPart
= -1;
251 NtQueryInformationFile(hFile
,
254 sizeof(FILE_POSITION_INFORMATION
),
255 FilePositionInformation
);
256 FilePosition
.CurrentByteOffset
.QuadPart
+= Distance
.QuadPart
;
259 NtQueryInformationFile(hFile
,
262 sizeof(FILE_STANDARD_INFORMATION
),
263 FileStandardInformation
);
264 FilePosition
.CurrentByteOffset
.QuadPart
=
265 FileStandard
.EndOfFile
.QuadPart
+ Distance
.QuadPart
;
268 FilePosition
.CurrentByteOffset
.QuadPart
= Distance
.QuadPart
;
271 SetLastError(ERROR_INVALID_PARAMETER
);
275 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
277 SetLastError(ERROR_NEGATIVE_SEEK
);
281 errCode
= NtSetInformationFile(hFile
,
284 sizeof(FILE_POSITION_INFORMATION
),
285 FilePositionInformation
);
286 if (!NT_SUCCESS(errCode
))
288 SetLastErrorByStatus(errCode
);
292 if (lpDistanceToMoveHigh
!= NULL
)
294 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
296 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
305 SetFilePointerEx(HANDLE hFile
,
306 LARGE_INTEGER liDistanceToMove
,
307 PLARGE_INTEGER lpNewFilePointer
,
310 FILE_POSITION_INFORMATION FilePosition
;
311 FILE_STANDARD_INFORMATION FileStandard
;
313 IO_STATUS_BLOCK IoStatusBlock
;
315 if(IsConsoleHandle(hFile
))
317 SetLastError(ERROR_INVALID_HANDLE
);
324 NtQueryInformationFile(hFile
,
327 sizeof(FILE_POSITION_INFORMATION
),
328 FilePositionInformation
);
329 FilePosition
.CurrentByteOffset
.QuadPart
+= liDistanceToMove
.QuadPart
;
332 NtQueryInformationFile(hFile
,
335 sizeof(FILE_STANDARD_INFORMATION
),
336 FileStandardInformation
);
337 FilePosition
.CurrentByteOffset
.QuadPart
=
338 FileStandard
.EndOfFile
.QuadPart
+ liDistanceToMove
.QuadPart
;
341 FilePosition
.CurrentByteOffset
.QuadPart
= liDistanceToMove
.QuadPart
;
344 SetLastError(ERROR_INVALID_PARAMETER
);
348 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
350 SetLastError(ERROR_NEGATIVE_SEEK
);
354 errCode
= NtSetInformationFile(hFile
,
357 sizeof(FILE_POSITION_INFORMATION
),
358 FilePositionInformation
);
359 if (!NT_SUCCESS(errCode
))
361 SetLastErrorByStatus(errCode
);
365 if (lpNewFilePointer
)
367 *lpNewFilePointer
= FilePosition
.CurrentByteOffset
;
377 GetFileType(HANDLE hFile
)
379 FILE_FS_DEVICE_INFORMATION DeviceInfo
;
380 IO_STATUS_BLOCK StatusBlock
;
383 /* Get real handle */
384 switch ((ULONG
)hFile
)
386 case STD_INPUT_HANDLE
:
387 hFile
= NtCurrentPeb()->ProcessParameters
->hStdInput
;
390 case STD_OUTPUT_HANDLE
:
391 hFile
= NtCurrentPeb()->ProcessParameters
->hStdOutput
;
394 case STD_ERROR_HANDLE
:
395 hFile
= NtCurrentPeb()->ProcessParameters
->hStdError
;
399 /* Check for console handle */
400 if (IsConsoleHandle(hFile
))
402 if (VerifyConsoleIoHandle(hFile
))
403 return FILE_TYPE_CHAR
;
406 Status
= NtQueryVolumeInformationFile(hFile
,
409 sizeof(FILE_FS_DEVICE_INFORMATION
),
410 FileFsDeviceInformation
);
411 if (!NT_SUCCESS(Status
))
413 SetLastErrorByStatus(Status
);
414 return FILE_TYPE_UNKNOWN
;
417 switch (DeviceInfo
.DeviceType
)
419 case FILE_DEVICE_CD_ROM
:
420 case FILE_DEVICE_CD_ROM_FILE_SYSTEM
:
421 case FILE_DEVICE_CONTROLLER
:
422 case FILE_DEVICE_DATALINK
:
423 case FILE_DEVICE_DFS
:
424 case FILE_DEVICE_DISK
:
425 case FILE_DEVICE_DISK_FILE_SYSTEM
:
426 case FILE_DEVICE_VIRTUAL_DISK
:
427 return FILE_TYPE_DISK
;
429 case FILE_DEVICE_KEYBOARD
:
430 case FILE_DEVICE_MOUSE
:
431 case FILE_DEVICE_NULL
:
432 case FILE_DEVICE_PARALLEL_PORT
:
433 case FILE_DEVICE_PRINTER
:
434 case FILE_DEVICE_SERIAL_PORT
:
435 case FILE_DEVICE_SCREEN
:
436 case FILE_DEVICE_SOUND
:
437 case FILE_DEVICE_MODEM
:
438 return FILE_TYPE_CHAR
;
440 case FILE_DEVICE_NAMED_PIPE
:
441 return FILE_TYPE_PIPE
;
444 return FILE_TYPE_UNKNOWN
;
452 GetFileSize(HANDLE hFile
,
453 LPDWORD lpFileSizeHigh
)
456 FILE_STANDARD_INFORMATION FileStandard
;
457 IO_STATUS_BLOCK IoStatusBlock
;
459 errCode
= NtQueryInformationFile(hFile
,
462 sizeof(FILE_STANDARD_INFORMATION
),
463 FileStandardInformation
);
464 if (!NT_SUCCESS(errCode
))
466 SetLastErrorByStatus(errCode
);
467 if ( lpFileSizeHigh
== NULL
)
476 if ( lpFileSizeHigh
!= NULL
)
477 *lpFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
479 return FileStandard
.EndOfFile
.u
.LowPart
;
490 PLARGE_INTEGER lpFileSize
494 FILE_STANDARD_INFORMATION FileStandard
;
495 IO_STATUS_BLOCK IoStatusBlock
;
497 errCode
= NtQueryInformationFile(hFile
,
500 sizeof(FILE_STANDARD_INFORMATION
),
501 FileStandardInformation
);
502 if (!NT_SUCCESS(errCode
))
504 SetLastErrorByStatus(errCode
);
508 *lpFileSize
= FileStandard
.EndOfFile
;
518 GetCompressedFileSizeA(LPCSTR lpFileName
,
519 LPDWORD lpFileSizeHigh
)
521 UNICODE_STRING FileNameU
;
522 ANSI_STRING FileName
;
525 RtlInitAnsiString(&FileName
,
528 /* convert ansi (or oem) string to unicode */
530 RtlAnsiStringToUnicodeString(&FileNameU
,
534 RtlOemStringToUnicodeString(&FileNameU
,
538 Size
= GetCompressedFileSizeW(FileNameU
.Buffer
,
541 RtlFreeUnicodeString (&FileNameU
);
551 GetCompressedFileSizeW(LPCWSTR lpFileName
,
552 LPDWORD lpFileSizeHigh
)
554 FILE_COMPRESSION_INFORMATION FileCompression
;
556 IO_STATUS_BLOCK IoStatusBlock
;
559 hFile
= CreateFileW(lpFileName
,
564 FILE_ATTRIBUTE_NORMAL
,
567 errCode
= NtQueryInformationFile(hFile
,
570 sizeof(FILE_COMPRESSION_INFORMATION
),
571 FileCompressionInformation
);
572 if (!NT_SUCCESS(errCode
))
575 SetLastErrorByStatus(errCode
);
576 return INVALID_FILE_SIZE
;
581 *lpFileSizeHigh
= FileCompression
.CompressedFileSize
.u
.HighPart
;
583 return FileCompression
.CompressedFileSize
.u
.LowPart
;
591 GetFileInformationByHandle(HANDLE hFile
,
592 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
596 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
601 FILE_BASIC_INFORMATION FileBasic
;
602 FILE_INTERNAL_INFORMATION FileInternal
;
603 FILE_STANDARD_INFORMATION FileStandard
;
605 IO_STATUS_BLOCK IoStatusBlock
;
607 if(IsConsoleHandle(hFile
))
609 SetLastError(ERROR_INVALID_HANDLE
);
613 errCode
= NtQueryInformationFile(hFile
,
616 sizeof(FILE_BASIC_INFORMATION
),
617 FileBasicInformation
);
618 if (!NT_SUCCESS(errCode
))
620 SetLastErrorByStatus(errCode
);
624 lpFileInformation
->dwFileAttributes
= (DWORD
)FileBasic
.FileAttributes
;
626 lpFileInformation
->ftCreationTime
.dwHighDateTime
= FileBasic
.CreationTime
.u
.HighPart
;
627 lpFileInformation
->ftCreationTime
.dwLowDateTime
= FileBasic
.CreationTime
.u
.LowPart
;
629 lpFileInformation
->ftLastAccessTime
.dwHighDateTime
= FileBasic
.LastAccessTime
.u
.HighPart
;
630 lpFileInformation
->ftLastAccessTime
.dwLowDateTime
= FileBasic
.LastAccessTime
.u
.LowPart
;
632 lpFileInformation
->ftLastWriteTime
.dwHighDateTime
= FileBasic
.LastWriteTime
.u
.HighPart
;
633 lpFileInformation
->ftLastWriteTime
.dwLowDateTime
= FileBasic
.LastWriteTime
.u
.LowPart
;
635 errCode
= NtQueryInformationFile(hFile
,
638 sizeof(FILE_INTERNAL_INFORMATION
),
639 FileInternalInformation
);
640 if (!NT_SUCCESS(errCode
))
642 SetLastErrorByStatus(errCode
);
646 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
647 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
649 errCode
= NtQueryVolumeInformationFile(hFile
,
652 sizeof(FileFsVolume
),
653 FileFsVolumeInformation
);
654 if (!NT_SUCCESS(errCode
))
656 SetLastErrorByStatus(errCode
);
660 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.FileFsVolume
.VolumeSerialNumber
;
662 errCode
= NtQueryInformationFile(hFile
,
665 sizeof(FILE_STANDARD_INFORMATION
),
666 FileStandardInformation
);
667 if (!NT_SUCCESS(errCode
))
669 SetLastErrorByStatus(errCode
);
673 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
674 lpFileInformation
->nFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
675 lpFileInformation
->nFileSizeLow
= FileStandard
.EndOfFile
.u
.LowPart
;
685 GetFileAttributesExW(LPCWSTR lpFileName
,
686 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
687 LPVOID lpFileInformation
)
689 FILE_NETWORK_OPEN_INFORMATION FileInformation
;
690 OBJECT_ATTRIBUTES ObjectAttributes
;
691 IO_STATUS_BLOCK IoStatusBlock
;
692 UNICODE_STRING FileName
;
695 WIN32_FILE_ATTRIBUTE_DATA
* FileAttributeData
;
697 DPRINT ("GetFileAttributesExW(%S) called\n", lpFileName
);
700 if (fInfoLevelId
!= GetFileExInfoStandard
|| lpFileInformation
== NULL
)
702 SetLastError(ERROR_INVALID_PARAMETER
);
706 /* Validate and translate the filename */
707 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
712 DPRINT ("Invalid path\n");
713 SetLastError (ERROR_BAD_PATHNAME
);
717 /* build the object attributes */
718 InitializeObjectAttributes (&ObjectAttributes
,
720 OBJ_CASE_INSENSITIVE
,
725 Status
= NtOpenFile (&FileHandle
,
726 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
,
729 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
730 FILE_SYNCHRONOUS_IO_NONALERT
);
731 RtlFreeUnicodeString (&FileName
);
732 if (!NT_SUCCESS (Status
))
734 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
735 SetLastErrorByStatus (Status
);
739 /* Get file attributes */
740 Status
= NtQueryInformationFile (FileHandle
,
743 sizeof(FILE_NETWORK_OPEN_INFORMATION
),
744 FileNetworkOpenInformation
);
745 NtClose (FileHandle
);
747 if (!NT_SUCCESS (Status
))
749 DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status
);
750 SetLastErrorByStatus (Status
);
754 FileAttributeData
= (WIN32_FILE_ATTRIBUTE_DATA
*)lpFileInformation
;
755 FileAttributeData
->dwFileAttributes
= FileInformation
.FileAttributes
;
756 FileAttributeData
->ftCreationTime
.dwLowDateTime
= FileInformation
.CreationTime
.u
.LowPart
;
757 FileAttributeData
->ftCreationTime
.dwHighDateTime
= FileInformation
.CreationTime
.u
.HighPart
;
758 FileAttributeData
->ftLastAccessTime
.dwLowDateTime
= FileInformation
.LastAccessTime
.u
.LowPart
;
759 FileAttributeData
->ftLastAccessTime
.dwHighDateTime
= FileInformation
.LastAccessTime
.u
.HighPart
;
760 FileAttributeData
->ftLastWriteTime
.dwLowDateTime
= FileInformation
.LastWriteTime
.u
.LowPart
;
761 FileAttributeData
->ftLastWriteTime
.dwHighDateTime
= FileInformation
.LastWriteTime
.u
.HighPart
;
762 FileAttributeData
->nFileSizeLow
= FileInformation
.EndOfFile
.u
.LowPart
;
763 FileAttributeData
->nFileSizeHigh
= FileInformation
.EndOfFile
.u
.HighPart
;
772 GetFileAttributesExA(LPCSTR lpFileName
,
773 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
774 LPVOID lpFileInformation
)
776 UNICODE_STRING FileNameU
;
777 ANSI_STRING FileName
;
779 RtlInitAnsiString (&FileName
,
782 /* convert ansi (or oem) string to unicode */
784 RtlAnsiStringToUnicodeString (&FileNameU
,
788 RtlOemStringToUnicodeString (&FileNameU
,
792 Result
= GetFileAttributesExW(FileNameU
.Buffer
, fInfoLevelId
, lpFileInformation
);
794 RtlFreeUnicodeString (&FileNameU
);
804 GetFileAttributesA(LPCSTR lpFileName
)
806 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
807 UNICODE_STRING FileNameU
;
808 ANSI_STRING FileName
;
811 RtlInitAnsiString (&FileName
,
814 /* convert ansi (or oem) string to unicode */
816 RtlAnsiStringToUnicodeString (&FileNameU
,
820 RtlOemStringToUnicodeString (&FileNameU
,
824 Result
= GetFileAttributesExW(FileNameU
.Buffer
, GetFileExInfoStandard
, &FileAttributeData
);
826 RtlFreeUnicodeString (&FileNameU
);
828 return Result
? FileAttributeData
.dwFileAttributes
: 0xffffffff;
836 GetFileAttributesW(LPCWSTR lpFileName
)
838 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
841 DPRINT ("GetFileAttributeW(%S) called\n", lpFileName
);
843 Result
= GetFileAttributesExW(lpFileName
, GetFileExInfoStandard
, &FileAttributeData
);
845 return Result
? FileAttributeData
.dwFileAttributes
: 0xffffffff;
849 SetFileAttributesA(LPCSTR lpFileName
,
850 DWORD dwFileAttributes
)
852 UNICODE_STRING FileNameU
;
853 ANSI_STRING FileName
;
856 RtlInitAnsiString (&FileName
,
859 /* convert ansi (or oem) string to unicode */
861 RtlAnsiStringToUnicodeString (&FileNameU
,
865 RtlOemStringToUnicodeString (&FileNameU
,
869 Result
= SetFileAttributesW (FileNameU
.Buffer
,
872 RtlFreeUnicodeString (&FileNameU
);
882 SetFileAttributesW(LPCWSTR lpFileName
,
883 DWORD dwFileAttributes
)
885 FILE_BASIC_INFORMATION FileInformation
;
886 OBJECT_ATTRIBUTES ObjectAttributes
;
887 IO_STATUS_BLOCK IoStatusBlock
;
888 UNICODE_STRING FileName
;
892 DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName
, dwFileAttributes
);
894 /* Validate and translate the filename */
895 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
900 DPRINT ("Invalid path\n");
901 SetLastError (ERROR_BAD_PATHNAME
);
904 DPRINT ("FileName: \'%wZ\'\n", &FileName
);
906 /* build the object attributes */
907 InitializeObjectAttributes (&ObjectAttributes
,
909 OBJ_CASE_INSENSITIVE
,
914 Status
= NtOpenFile (&FileHandle
,
915 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
918 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
919 FILE_SYNCHRONOUS_IO_NONALERT
);
920 RtlFreeUnicodeString (&FileName
);
921 if (!NT_SUCCESS (Status
))
923 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
924 SetLastErrorByStatus (Status
);
928 Status
= NtQueryInformationFile(FileHandle
,
931 sizeof(FILE_BASIC_INFORMATION
),
932 FileBasicInformation
);
933 if (!NT_SUCCESS(Status
))
935 DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status
);
936 NtClose (FileHandle
);
937 SetLastErrorByStatus (Status
);
941 FileInformation
.FileAttributes
= dwFileAttributes
;
942 Status
= NtSetInformationFile(FileHandle
,
945 sizeof(FILE_BASIC_INFORMATION
),
946 FileBasicInformation
);
947 NtClose (FileHandle
);
948 if (!NT_SUCCESS(Status
))
950 DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status
);
951 SetLastErrorByStatus (Status
);
963 GetTempFileNameA(LPCSTR lpPathName
,
964 LPCSTR lpPrefixString
,
966 LPSTR lpTempFileName
)
969 UINT unique
= uUnique
;
971 const char *format
= "%.*s\\~%.3s%4.4x.TMP";
973 DPRINT("GetTempFileNameA(lpPathName %s, lpPrefixString %.*s, "
974 "uUnique %x, lpTempFileName %x)\n", lpPathName
, 4,
975 lpPrefixString
, uUnique
, lpTempFileName
);
977 if (lpPathName
== NULL
)
980 len
= strlen(lpPathName
);
981 if (len
> 0 && (lpPathName
[len
-1] == '\\' || lpPathName
[len
-1] == '/'))
985 uUnique
= GetCurrentTime();
987 sprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,uUnique
);
992 while ((hFile
= CreateFileA(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
993 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
994 0)) == INVALID_HANDLE_VALUE
)
996 if (GetLastError() != ERROR_FILE_EXISTS
)
1000 sprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,++uUnique
);
1011 GetTempFileNameW(LPCWSTR lpPathName
,
1012 LPCWSTR lpPrefixString
,
1014 LPWSTR lpTempFileName
)
1017 UINT unique
= uUnique
;
1019 const WCHAR
*format
= L
"%.*s\\~%.3s%4.4x.TMP";
1021 DPRINT("GetTempFileNameW(lpPathName %S, lpPrefixString %.*S, "
1022 "uUnique %x, lpTempFileName %x)\n", lpPathName
, 4,
1023 lpPrefixString
, uUnique
, lpTempFileName
);
1025 if (lpPathName
== NULL
)
1028 len
= wcslen(lpPathName
);
1029 if (len
> 0 && (lpPathName
[len
-1] == L
'\\' || lpPathName
[len
-1] == L
'/'))
1033 uUnique
= GetCurrentTime();
1035 swprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,uUnique
);
1040 while ((hFile
= CreateFileW(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
1041 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
1042 0)) == INVALID_HANDLE_VALUE
)
1044 if (GetLastError() != ERROR_FILE_EXISTS
)
1048 swprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,++uUnique
);
1059 GetFileTime(HANDLE hFile
,
1060 LPFILETIME lpCreationTime
,
1061 LPFILETIME lpLastAccessTime
,
1062 LPFILETIME lpLastWriteTime
)
1064 IO_STATUS_BLOCK IoStatusBlock
;
1065 FILE_BASIC_INFORMATION FileBasic
;
1068 if(IsConsoleHandle(hFile
))
1070 SetLastError(ERROR_INVALID_HANDLE
);
1074 Status
= NtQueryInformationFile(hFile
,
1077 sizeof(FILE_BASIC_INFORMATION
),
1078 FileBasicInformation
);
1079 if (!NT_SUCCESS(Status
))
1081 SetLastErrorByStatus(Status
);
1086 memcpy(lpCreationTime
, &FileBasic
.CreationTime
, sizeof(FILETIME
));
1087 if (lpLastAccessTime
)
1088 memcpy(lpLastAccessTime
, &FileBasic
.LastAccessTime
, sizeof(FILETIME
));
1089 if (lpLastWriteTime
)
1090 memcpy(lpLastWriteTime
, &FileBasic
.LastWriteTime
, sizeof(FILETIME
));
1100 SetFileTime(HANDLE hFile
,
1101 CONST FILETIME
*lpCreationTime
,
1102 CONST FILETIME
*lpLastAccessTime
,
1103 CONST FILETIME
*lpLastWriteTime
)
1105 FILE_BASIC_INFORMATION FileBasic
;
1106 IO_STATUS_BLOCK IoStatusBlock
;
1109 if(IsConsoleHandle(hFile
))
1111 SetLastError(ERROR_INVALID_HANDLE
);
1115 Status
= NtQueryInformationFile(hFile
,
1118 sizeof(FILE_BASIC_INFORMATION
),
1119 FileBasicInformation
);
1120 if (!NT_SUCCESS(Status
))
1122 SetLastErrorByStatus(Status
);
1127 memcpy(&FileBasic
.CreationTime
, lpCreationTime
, sizeof(FILETIME
));
1128 if (lpLastAccessTime
)
1129 memcpy(&FileBasic
.LastAccessTime
, lpLastAccessTime
, sizeof(FILETIME
));
1130 if (lpLastWriteTime
)
1131 memcpy(&FileBasic
.LastWriteTime
, lpLastWriteTime
, sizeof(FILETIME
));
1133 // should i initialize changetime ???
1135 Status
= NtSetInformationFile(hFile
,
1138 sizeof(FILE_BASIC_INFORMATION
),
1139 FileBasicInformation
);
1140 if (!NT_SUCCESS(Status
))
1142 SetLastErrorByStatus(Status
);
1151 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
1156 SetEndOfFile(HANDLE hFile
)
1158 IO_STATUS_BLOCK IoStatusBlock
;
1159 FILE_END_OF_FILE_INFORMATION EndOfFileInfo
;
1160 FILE_ALLOCATION_INFORMATION FileAllocationInfo
;
1161 FILE_POSITION_INFORMATION FilePosInfo
;
1164 if(IsConsoleHandle(hFile
))
1166 SetLastError(ERROR_INVALID_HANDLE
);
1170 //get current position
1171 Status
= NtQueryInformationFile(
1175 sizeof(FILE_POSITION_INFORMATION
),
1176 FilePositionInformation
1179 if (!NT_SUCCESS(Status
)){
1180 SetLastErrorByStatus(Status
);
1184 EndOfFileInfo
.EndOfFile
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1188 This call is not supposed to free up any space after the eof marker
1189 if the file gets truncated. We have to deallocate the space explicitly afterwards.
1190 But...most file systems dispatch both FileEndOfFileInformation
1191 and FileAllocationInformation as they were the same command.
1194 Status
= NtSetInformationFile(
1196 &IoStatusBlock
, //out
1198 sizeof(FILE_END_OF_FILE_INFORMATION
),
1199 FileEndOfFileInformation
1202 if (!NT_SUCCESS(Status
)){
1203 SetLastErrorByStatus(Status
);
1207 FileAllocationInfo
.AllocationSize
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1210 Status
= NtSetInformationFile(
1212 &IoStatusBlock
, //out
1213 &FileAllocationInfo
,
1214 sizeof(FILE_ALLOCATION_INFORMATION
),
1215 FileAllocationInformation
1218 if (!NT_SUCCESS(Status
)){
1219 SetLastErrorByStatus(Status
);
1235 LONGLONG ValidDataLength
1238 IO_STATUS_BLOCK IoStatusBlock
;
1239 FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation
;
1242 ValidDataLengthInformation
.ValidDataLength
.QuadPart
= ValidDataLength
;
1244 Status
= NtSetInformationFile(
1246 &IoStatusBlock
, //out
1247 &ValidDataLengthInformation
,
1248 sizeof(FILE_VALID_DATA_LENGTH_INFORMATION
),
1249 FileValidDataLengthInformation
1252 if (!NT_SUCCESS(Status
)){
1253 SetLastErrorByStatus(Status
);
1268 LPCWSTR lpShortName
)
1272 UNICODE_STRING ShortName
;
1273 IO_STATUS_BLOCK IoStatusBlock
;
1274 PFILE_NAME_INFORMATION FileNameInformation
;
1276 if(IsConsoleHandle(hFile
))
1278 SetLastError(ERROR_INVALID_HANDLE
);
1284 SetLastError(ERROR_INVALID_PARAMETER
);
1288 RtlInitUnicodeString(&ShortName
, lpShortName
);
1290 NeededSize
= sizeof(FILE_NAME_INFORMATION
) + ShortName
.Length
+ sizeof(WCHAR
);
1291 if(!(FileNameInformation
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, NeededSize
)))
1293 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1297 FileNameInformation
->FileNameLength
= ShortName
.Length
;
1298 RtlCopyMemory(FileNameInformation
->FileName
, ShortName
.Buffer
, ShortName
.Length
);
1300 Status
= NtSetInformationFile(hFile
,
1301 &IoStatusBlock
, //out
1302 FileNameInformation
,
1304 FileShortNameInformation
);
1306 RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInformation
);
1307 if(!NT_SUCCESS(Status
))
1310 SetLastErrorByStatus(Status
);
1313 return NT_SUCCESS(Status
);
1329 ANSI_STRING ShortNameA
;
1330 UNICODE_STRING ShortName
;
1332 if(IsConsoleHandle(hFile
))
1334 SetLastError(ERROR_INVALID_HANDLE
);
1340 SetLastError(ERROR_INVALID_PARAMETER
);
1344 RtlInitAnsiString(&ShortNameA
, (LPSTR
)lpShortName
);
1347 Status
= RtlAnsiStringToUnicodeString(&ShortName
, &ShortNameA
, TRUE
);
1349 Status
= RtlOemStringToUnicodeString(&ShortName
, &ShortNameA
, TRUE
);
1350 if(!NT_SUCCESS(Status
))
1352 SetLastErrorByStatus(Status
);
1356 Ret
= SetFileShortNameW(hFile
, ShortName
.Buffer
);
1358 RtlFreeUnicodeString(&ShortName
);
1368 CheckNameLegalDOS8Dot3W(
1370 LPSTR lpOemName OPTIONAL
,
1371 DWORD OemNameSize OPTIONAL
,
1372 PBOOL pbNameContainsSpaces OPTIONAL
,
1376 UNICODE_STRING Name
;
1377 ANSI_STRING AnsiName
;
1379 if(lpName
== NULL
||
1380 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1381 pbNameLegal
== NULL
)
1383 SetLastError(ERROR_INVALID_PARAMETER
);
1387 if(lpOemName
!= NULL
)
1389 AnsiName
.Buffer
= lpOemName
;
1390 AnsiName
.MaximumLength
= OemNameSize
* sizeof(CHAR
);
1391 AnsiName
.Length
= 0;
1394 RtlInitUnicodeString(&Name
, lpName
);
1396 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1397 (lpOemName
? &AnsiName
: NULL
),
1398 (BOOLEAN
*)pbNameContainsSpaces
);
1409 CheckNameLegalDOS8Dot3A(
1411 LPSTR lpOemName OPTIONAL
,
1412 DWORD OemNameSize OPTIONAL
,
1413 PBOOL pbNameContainsSpaces OPTIONAL
,
1417 UNICODE_STRING Name
;
1418 ANSI_STRING AnsiName
, AnsiInputName
;
1421 if(lpName
== NULL
||
1422 (lpOemName
== NULL
&& OemNameSize
!= 0) ||
1423 pbNameLegal
== NULL
)
1425 SetLastError(ERROR_INVALID_PARAMETER
);
1429 if(lpOemName
!= NULL
)
1431 AnsiName
.Buffer
= lpOemName
;
1432 AnsiName
.MaximumLength
= OemNameSize
* sizeof(CHAR
);
1433 AnsiName
.Length
= 0;
1436 RtlInitAnsiString(&AnsiInputName
, (LPSTR
)lpName
);
1438 Status
= RtlAnsiStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1440 Status
= RtlOemStringToUnicodeString(&Name
, &AnsiInputName
, TRUE
);
1442 if(!NT_SUCCESS(Status
))
1444 SetLastErrorByStatus(Status
);
1448 *pbNameLegal
= RtlIsNameLegalDOS8Dot3(&Name
,
1449 (lpOemName
? &AnsiName
: NULL
),
1450 (BOOLEAN
*)pbNameContainsSpaces
);
1452 RtlFreeUnicodeString(&Name
);