1 /* $Id: file.c,v 1.53 2004/03/18 18:29:18 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 RtlInitAnsiString (&FileName
, (LPSTR
)lpFileName
);
87 /* convert ansi (or oem) string to unicode */
89 RtlAnsiStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
91 RtlOemStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
93 Len
= SearchPathW (NULL
,
100 RtlFreeUnicodeString(&FileNameU
);
102 if (Len
== 0 || Len
> OFS_MAXPATHNAME
)
104 return (HFILE
)INVALID_HANDLE_VALUE
;
107 FileName
.Buffer
= lpReOpenBuff
->szPathName
;
109 FileName
.MaximumLength
= OFS_MAXPATHNAME
;
111 RtlInitUnicodeString(&FileNameU
, PathNameW
);
113 /* convert unicode string to ansi (or oem) */
115 RtlUnicodeStringToAnsiString (&FileName
, &FileNameU
, FALSE
);
117 RtlUnicodeStringToOemString (&FileName
, &FileNameU
, FALSE
);
119 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)PathNameW
,
124 return (HFILE
)INVALID_HANDLE_VALUE
;
127 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
128 ObjectAttributes
.RootDirectory
= NULL
;
129 ObjectAttributes
.ObjectName
= &FileNameString
;
130 ObjectAttributes
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
;
131 ObjectAttributes
.SecurityDescriptor
= NULL
;
132 ObjectAttributes
.SecurityQualityOfService
= NULL
;
135 // FILE_NO_INTERMEDIATE_BUFFERING
137 if ((uStyle
& OF_PARSE
) == OF_PARSE
)
139 RtlFreeUnicodeString(&FileNameString
);
143 errCode
= NtOpenFile (&FileHandle
,
144 GENERIC_READ
|SYNCHRONIZE
,
148 FILE_NON_DIRECTORY_FILE
|FILE_SYNCHRONOUS_IO_NONALERT
);
150 RtlFreeUnicodeString(&FileNameString
);
152 lpReOpenBuff
->nErrCode
= RtlNtStatusToDosError(errCode
);
154 if (!NT_SUCCESS(errCode
))
156 SetLastErrorByStatus (errCode
);
157 return (HFILE
)INVALID_HANDLE_VALUE
;
160 return (HFILE
)FileHandle
;
168 FlushFileBuffers(HANDLE hFile
)
171 IO_STATUS_BLOCK IoStatusBlock
;
173 if (IsConsoleHandle(hFile
))
178 errCode
= NtFlushBuffersFile(hFile
,
180 if (!NT_SUCCESS(errCode
))
182 SetLastErrorByStatus(errCode
);
193 SetFilePointer(HANDLE hFile
,
194 LONG lDistanceToMove
,
195 PLONG lpDistanceToMoveHigh
,
198 FILE_POSITION_INFORMATION FilePosition
;
199 FILE_STANDARD_INFORMATION FileStandart
;
201 IO_STATUS_BLOCK IoStatusBlock
;
202 LARGE_INTEGER Distance
;
204 DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
205 hFile
,lDistanceToMove
,dwMoveMethod
);
207 /* FIXME - should fail if hFile is a console handle */
209 Distance
.u
.LowPart
= lDistanceToMove
;
210 if (lpDistanceToMoveHigh
)
212 Distance
.u
.HighPart
= *lpDistanceToMoveHigh
;
214 else if (lDistanceToMove
>= 0)
216 Distance
.u
.HighPart
= 0;
220 Distance
.u
.HighPart
= -1;
226 NtQueryInformationFile(hFile
,
229 sizeof(FILE_POSITION_INFORMATION
),
230 FilePositionInformation
);
231 FilePosition
.CurrentByteOffset
.QuadPart
+= Distance
.QuadPart
;
234 NtQueryInformationFile(hFile
,
237 sizeof(FILE_STANDARD_INFORMATION
),
238 FileStandardInformation
);
239 FilePosition
.CurrentByteOffset
.QuadPart
=
240 FileStandart
.EndOfFile
.QuadPart
+ Distance
.QuadPart
;
243 FilePosition
.CurrentByteOffset
.QuadPart
= Distance
.QuadPart
;
247 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
249 SetLastError(ERROR_NEGATIVE_SEEK
);
253 errCode
= NtSetInformationFile(hFile
,
256 sizeof(FILE_POSITION_INFORMATION
),
257 FilePositionInformation
);
258 if (!NT_SUCCESS(errCode
))
260 SetLastErrorByStatus(errCode
);
264 if (lpDistanceToMoveHigh
!= NULL
)
266 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
268 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
277 SetFilePointerEx(HANDLE hFile
,
278 LARGE_INTEGER liDistanceToMove
,
279 PLARGE_INTEGER lpNewFilePointer
,
282 FILE_POSITION_INFORMATION FilePosition
;
283 FILE_STANDARD_INFORMATION FileStandart
;
285 IO_STATUS_BLOCK IoStatusBlock
;
287 /* FIXME - should fail if hFile is a console handle */
292 NtQueryInformationFile(hFile
,
295 sizeof(FILE_POSITION_INFORMATION
),
296 FilePositionInformation
);
297 FilePosition
.CurrentByteOffset
.QuadPart
+= liDistanceToMove
.QuadPart
;
300 NtQueryInformationFile(hFile
,
303 sizeof(FILE_STANDARD_INFORMATION
),
304 FileStandardInformation
);
305 FilePosition
.CurrentByteOffset
.QuadPart
=
306 FileStandart
.EndOfFile
.QuadPart
+ liDistanceToMove
.QuadPart
;
309 FilePosition
.CurrentByteOffset
.QuadPart
= liDistanceToMove
.QuadPart
;
313 if(FilePosition
.CurrentByteOffset
.QuadPart
< 0)
315 SetLastError(ERROR_NEGATIVE_SEEK
);
319 errCode
= NtSetInformationFile(hFile
,
322 sizeof(FILE_POSITION_INFORMATION
),
323 FilePositionInformation
);
324 if (!NT_SUCCESS(errCode
))
326 SetLastErrorByStatus(errCode
);
330 if (lpNewFilePointer
)
332 *lpNewFilePointer
= FilePosition
.CurrentByteOffset
;
342 GetFileType(HANDLE hFile
)
344 FILE_FS_DEVICE_INFORMATION DeviceInfo
;
345 IO_STATUS_BLOCK StatusBlock
;
348 /* Get real handle */
349 switch ((ULONG
)hFile
)
351 case STD_INPUT_HANDLE
:
352 hFile
= NtCurrentPeb()->ProcessParameters
->hStdInput
;
355 case STD_OUTPUT_HANDLE
:
356 hFile
= NtCurrentPeb()->ProcessParameters
->hStdOutput
;
359 case STD_ERROR_HANDLE
:
360 hFile
= NtCurrentPeb()->ProcessParameters
->hStdError
;
364 /* Check for console handle */
365 if (IsConsoleHandle(hFile
))
367 if (VerifyConsoleIoHandle(hFile
))
368 return FILE_TYPE_CHAR
;
371 Status
= NtQueryVolumeInformationFile(hFile
,
374 sizeof(FILE_FS_DEVICE_INFORMATION
),
375 FileFsDeviceInformation
);
376 if (!NT_SUCCESS(Status
))
378 SetLastErrorByStatus(Status
);
379 return FILE_TYPE_UNKNOWN
;
382 switch (DeviceInfo
.DeviceType
)
384 case FILE_DEVICE_CD_ROM
:
385 case FILE_DEVICE_CD_ROM_FILE_SYSTEM
:
386 case FILE_DEVICE_CONTROLLER
:
387 case FILE_DEVICE_DATALINK
:
388 case FILE_DEVICE_DFS
:
389 case FILE_DEVICE_DISK
:
390 case FILE_DEVICE_DISK_FILE_SYSTEM
:
391 case FILE_DEVICE_VIRTUAL_DISK
:
392 return FILE_TYPE_DISK
;
394 case FILE_DEVICE_KEYBOARD
:
395 case FILE_DEVICE_MOUSE
:
396 case FILE_DEVICE_NULL
:
397 case FILE_DEVICE_PARALLEL_PORT
:
398 case FILE_DEVICE_PRINTER
:
399 case FILE_DEVICE_SERIAL_PORT
:
400 case FILE_DEVICE_SCREEN
:
401 case FILE_DEVICE_SOUND
:
402 case FILE_DEVICE_MODEM
:
403 return FILE_TYPE_CHAR
;
405 case FILE_DEVICE_NAMED_PIPE
:
406 return FILE_TYPE_PIPE
;
409 return FILE_TYPE_UNKNOWN
;
417 GetFileSize(HANDLE hFile
,
418 LPDWORD lpFileSizeHigh
)
421 FILE_STANDARD_INFORMATION FileStandard
;
422 IO_STATUS_BLOCK IoStatusBlock
;
424 errCode
= NtQueryInformationFile(hFile
,
427 sizeof(FILE_STANDARD_INFORMATION
),
428 FileStandardInformation
);
429 if (!NT_SUCCESS(errCode
))
431 SetLastErrorByStatus(errCode
);
432 if ( lpFileSizeHigh
== NULL
)
441 if ( lpFileSizeHigh
!= NULL
)
442 *lpFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
444 return FileStandard
.EndOfFile
.u
.LowPart
;
455 PLARGE_INTEGER lpFileSize
459 FILE_STANDARD_INFORMATION FileStandard
;
460 IO_STATUS_BLOCK IoStatusBlock
;
462 errCode
= NtQueryInformationFile(hFile
,
465 sizeof(FILE_STANDARD_INFORMATION
),
466 FileStandardInformation
);
467 if (!NT_SUCCESS(errCode
))
469 SetLastErrorByStatus(errCode
);
473 *lpFileSize
= FileStandard
.EndOfFile
;
483 GetCompressedFileSizeA(LPCSTR lpFileName
,
484 LPDWORD lpFileSizeHigh
)
486 UNICODE_STRING FileNameU
;
487 ANSI_STRING FileName
;
490 RtlInitAnsiString(&FileName
,
493 /* convert ansi (or oem) string to unicode */
495 RtlAnsiStringToUnicodeString(&FileNameU
,
499 RtlOemStringToUnicodeString(&FileNameU
,
503 Size
= GetCompressedFileSizeW(FileNameU
.Buffer
,
506 RtlFreeUnicodeString (&FileNameU
);
516 GetCompressedFileSizeW(LPCWSTR lpFileName
,
517 LPDWORD lpFileSizeHigh
)
519 FILE_COMPRESSION_INFORMATION FileCompression
;
521 IO_STATUS_BLOCK IoStatusBlock
;
524 hFile
= CreateFileW(lpFileName
,
529 FILE_ATTRIBUTE_NORMAL
,
532 errCode
= NtQueryInformationFile(hFile
,
535 sizeof(FILE_COMPRESSION_INFORMATION
),
536 FileCompressionInformation
);
537 if (!NT_SUCCESS(errCode
))
540 SetLastErrorByStatus(errCode
);
541 return INVALID_FILE_SIZE
;
546 *lpFileSizeHigh
= FileCompression
.CompressedFileSize
.u
.HighPart
;
548 return FileCompression
.CompressedFileSize
.u
.LowPart
;
556 GetFileInformationByHandle(HANDLE hFile
,
557 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
561 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
566 FILE_BASIC_INFORMATION FileBasic
;
567 FILE_INTERNAL_INFORMATION FileInternal
;
568 FILE_STANDARD_INFORMATION FileStandard
;
570 IO_STATUS_BLOCK IoStatusBlock
;
572 errCode
= NtQueryInformationFile(hFile
,
575 sizeof(FILE_BASIC_INFORMATION
),
576 FileBasicInformation
);
577 if (!NT_SUCCESS(errCode
))
579 SetLastErrorByStatus(errCode
);
583 lpFileInformation
->dwFileAttributes
= (DWORD
)FileBasic
.FileAttributes
;
584 memcpy(&lpFileInformation
->ftCreationTime
,&FileBasic
.CreationTime
,sizeof(LARGE_INTEGER
));
585 memcpy(&lpFileInformation
->ftLastAccessTime
,&FileBasic
.LastAccessTime
,sizeof(LARGE_INTEGER
));
586 memcpy(&lpFileInformation
->ftLastWriteTime
, &FileBasic
.LastWriteTime
,sizeof(LARGE_INTEGER
));
588 errCode
= NtQueryInformationFile(hFile
,
591 sizeof(FILE_INTERNAL_INFORMATION
),
592 FileInternalInformation
);
593 if (!NT_SUCCESS(errCode
))
595 SetLastErrorByStatus(errCode
);
599 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
600 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
602 errCode
= NtQueryVolumeInformationFile(hFile
,
605 sizeof(FileFsVolume
),
606 FileFsVolumeInformation
);
607 if (!NT_SUCCESS(errCode
))
609 SetLastErrorByStatus(errCode
);
613 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.FileFsVolume
.VolumeSerialNumber
;
615 errCode
= NtQueryInformationFile(hFile
,
618 sizeof(FILE_STANDARD_INFORMATION
),
619 FileStandardInformation
);
620 if (!NT_SUCCESS(errCode
))
622 SetLastErrorByStatus(errCode
);
626 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
627 lpFileInformation
->nFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
628 lpFileInformation
->nFileSizeLow
= FileStandard
.EndOfFile
.u
.LowPart
;
638 GetFileAttributesExW(LPCWSTR lpFileName
,
639 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
640 LPVOID lpFileInformation
)
642 FILE_NETWORK_OPEN_INFORMATION FileInformation
;
643 OBJECT_ATTRIBUTES ObjectAttributes
;
644 IO_STATUS_BLOCK IoStatusBlock
;
645 UNICODE_STRING FileName
;
648 WIN32_FILE_ATTRIBUTE_DATA
* FileAttributeData
;
650 DPRINT ("GetFileAttributesExW(%S) called\n", lpFileName
);
653 if (fInfoLevelId
!= GetFileExInfoStandard
|| lpFileInformation
== NULL
)
655 SetLastError(ERROR_INVALID_PARAMETER
);
659 /* Validate and translate the filename */
660 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
665 DPRINT ("Invalid path\n");
666 SetLastError (ERROR_BAD_PATHNAME
);
670 /* build the object attributes */
671 InitializeObjectAttributes (&ObjectAttributes
,
673 OBJ_CASE_INSENSITIVE
,
678 Status
= NtOpenFile (&FileHandle
,
679 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
,
682 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
683 FILE_SYNCHRONOUS_IO_NONALERT
);
684 RtlFreeUnicodeString (&FileName
);
685 if (!NT_SUCCESS (Status
))
687 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
688 SetLastErrorByStatus (Status
);
692 /* Get file attributes */
693 Status
= NtQueryInformationFile (FileHandle
,
696 sizeof(FILE_NETWORK_OPEN_INFORMATION
),
697 FileNetworkOpenInformation
);
698 NtClose (FileHandle
);
700 if (!NT_SUCCESS (Status
))
702 DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status
);
703 SetLastErrorByStatus (Status
);
707 FileAttributeData
= (WIN32_FILE_ATTRIBUTE_DATA
*)lpFileInformation
;
708 FileAttributeData
->dwFileAttributes
= FileInformation
.FileAttributes
;
709 FileAttributeData
->ftCreationTime
.dwLowDateTime
= FileInformation
.CreationTime
.u
.LowPart
;
710 FileAttributeData
->ftCreationTime
.dwHighDateTime
= FileInformation
.CreationTime
.u
.HighPart
;
711 FileAttributeData
->ftLastAccessTime
.dwLowDateTime
= FileInformation
.LastAccessTime
.u
.LowPart
;
712 FileAttributeData
->ftLastAccessTime
.dwHighDateTime
= FileInformation
.LastAccessTime
.u
.HighPart
;
713 FileAttributeData
->ftLastWriteTime
.dwLowDateTime
= FileInformation
.LastWriteTime
.u
.LowPart
;
714 FileAttributeData
->ftLastWriteTime
.dwHighDateTime
= FileInformation
.LastWriteTime
.u
.HighPart
;
715 FileAttributeData
->nFileSizeLow
= FileInformation
.EndOfFile
.u
.LowPart
;
716 FileAttributeData
->nFileSizeHigh
= FileInformation
.EndOfFile
.u
.HighPart
;
725 GetFileAttributesExA(LPCSTR lpFileName
,
726 GET_FILEEX_INFO_LEVELS fInfoLevelId
,
727 LPVOID lpFileInformation
)
729 UNICODE_STRING FileNameU
;
730 ANSI_STRING FileName
;
732 RtlInitAnsiString (&FileName
,
735 /* convert ansi (or oem) string to unicode */
737 RtlAnsiStringToUnicodeString (&FileNameU
,
741 RtlOemStringToUnicodeString (&FileNameU
,
745 Result
= GetFileAttributesExW(FileNameU
.Buffer
, fInfoLevelId
, lpFileInformation
);
747 RtlFreeUnicodeString (&FileNameU
);
757 GetFileAttributesA(LPCSTR lpFileName
)
759 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
760 UNICODE_STRING FileNameU
;
761 ANSI_STRING FileName
;
764 RtlInitAnsiString (&FileName
,
767 /* convert ansi (or oem) string to unicode */
769 RtlAnsiStringToUnicodeString (&FileNameU
,
773 RtlOemStringToUnicodeString (&FileNameU
,
777 Result
= GetFileAttributesExW(FileNameU
.Buffer
, GetFileExInfoStandard
, &FileAttributeData
);
779 RtlFreeUnicodeString (&FileNameU
);
781 return Result
? FileAttributeData
.dwFileAttributes
: 0xffffffff;
789 GetFileAttributesW(LPCWSTR lpFileName
)
791 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData
;
794 DPRINT ("GetFileAttributeW(%S) called\n", lpFileName
);
796 Result
= GetFileAttributesExW(lpFileName
, GetFileExInfoStandard
, &FileAttributeData
);
798 return Result
? FileAttributeData
.dwFileAttributes
: 0xffffffff;
802 SetFileAttributesA(LPCSTR lpFileName
,
803 DWORD dwFileAttributes
)
805 UNICODE_STRING FileNameU
;
806 ANSI_STRING FileName
;
809 RtlInitAnsiString (&FileName
,
812 /* convert ansi (or oem) string to unicode */
814 RtlAnsiStringToUnicodeString (&FileNameU
,
818 RtlOemStringToUnicodeString (&FileNameU
,
822 Result
= SetFileAttributesW (FileNameU
.Buffer
,
825 RtlFreeUnicodeString (&FileNameU
);
835 SetFileAttributesW(LPCWSTR lpFileName
,
836 DWORD dwFileAttributes
)
838 FILE_BASIC_INFORMATION FileInformation
;
839 OBJECT_ATTRIBUTES ObjectAttributes
;
840 IO_STATUS_BLOCK IoStatusBlock
;
841 UNICODE_STRING FileName
;
845 DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName
, dwFileAttributes
);
847 /* Validate and translate the filename */
848 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
853 DPRINT ("Invalid path\n");
854 SetLastError (ERROR_BAD_PATHNAME
);
857 DPRINT ("FileName: \'%wZ\'\n", &FileName
);
859 /* build the object attributes */
860 InitializeObjectAttributes (&ObjectAttributes
,
862 OBJ_CASE_INSENSITIVE
,
867 Status
= NtOpenFile (&FileHandle
,
868 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
871 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
872 FILE_SYNCHRONOUS_IO_NONALERT
);
873 RtlFreeUnicodeString (&FileName
);
874 if (!NT_SUCCESS (Status
))
876 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
877 SetLastErrorByStatus (Status
);
881 Status
= NtQueryInformationFile(FileHandle
,
884 sizeof(FILE_BASIC_INFORMATION
),
885 FileBasicInformation
);
886 if (!NT_SUCCESS(Status
))
888 DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status
);
889 NtClose (FileHandle
);
890 SetLastErrorByStatus (Status
);
894 FileInformation
.FileAttributes
= dwFileAttributes
;
895 Status
= NtSetInformationFile(FileHandle
,
898 sizeof(FILE_BASIC_INFORMATION
),
899 FileBasicInformation
);
900 NtClose (FileHandle
);
901 if (!NT_SUCCESS(Status
))
903 DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status
);
904 SetLastErrorByStatus (Status
);
916 GetTempFileNameA(LPCSTR lpPathName
,
917 LPCSTR lpPrefixString
,
919 LPSTR lpTempFileName
)
922 UINT unique
= uUnique
;
924 const char *format
= "%.*s\\~%.3s%4.4x.TMP";
926 DPRINT("GetTempFileNameA(lpPathName %s, lpPrefixString %.*s, "
927 "uUnique %x, lpTempFileName %x)\n", lpPathName
, 4,
928 lpPrefixString
, uUnique
, lpTempFileName
);
930 if (lpPathName
== NULL
)
933 len
= strlen(lpPathName
);
934 if (len
> 0 && (lpPathName
[len
-1] == '\\' || lpPathName
[len
-1] == '/'))
938 uUnique
= GetCurrentTime();
940 sprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,uUnique
);
945 while ((hFile
= CreateFileA(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
946 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
947 0)) == INVALID_HANDLE_VALUE
)
949 if (GetLastError() != ERROR_ALREADY_EXISTS
)
953 sprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,++uUnique
);
964 GetTempFileNameW(LPCWSTR lpPathName
,
965 LPCWSTR lpPrefixString
,
967 LPWSTR lpTempFileName
)
970 UINT unique
= uUnique
;
972 const WCHAR
*format
= L
"%.*s\\~%.3s%4.4x.TMP";
974 DPRINT("GetTempFileNameW(lpPathName %S, lpPrefixString %.*S, "
975 "uUnique %x, lpTempFileName %x)\n", lpPathName
, 4,
976 lpPrefixString
, uUnique
, lpTempFileName
);
978 if (lpPathName
== NULL
)
981 len
= wcslen(lpPathName
);
982 if (len
> 0 && (lpPathName
[len
-1] == L
'\\' || lpPathName
[len
-1] == L
'/'))
986 uUnique
= GetCurrentTime();
988 swprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,uUnique
);
993 while ((hFile
= CreateFileW(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
994 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
995 0)) == INVALID_HANDLE_VALUE
)
997 if (GetLastError() != ERROR_ALREADY_EXISTS
)
1001 swprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,++uUnique
);
1012 GetFileTime(HANDLE hFile
,
1013 LPFILETIME lpCreationTime
,
1014 LPFILETIME lpLastAccessTime
,
1015 LPFILETIME lpLastWriteTime
)
1017 IO_STATUS_BLOCK IoStatusBlock
;
1018 FILE_BASIC_INFORMATION FileBasic
;
1021 Status
= NtQueryInformationFile(hFile
,
1024 sizeof(FILE_BASIC_INFORMATION
),
1025 FileBasicInformation
);
1026 if (!NT_SUCCESS(Status
))
1028 SetLastErrorByStatus(Status
);
1033 memcpy(lpCreationTime
, &FileBasic
.CreationTime
, sizeof(FILETIME
));
1034 if (lpLastAccessTime
)
1035 memcpy(lpLastAccessTime
, &FileBasic
.LastAccessTime
, sizeof(FILETIME
));
1036 if (lpLastWriteTime
)
1037 memcpy(lpLastWriteTime
, &FileBasic
.LastWriteTime
, sizeof(FILETIME
));
1047 SetFileTime(HANDLE hFile
,
1048 CONST FILETIME
*lpCreationTime
,
1049 CONST FILETIME
*lpLastAccessTime
,
1050 CONST FILETIME
*lpLastWriteTime
)
1052 FILE_BASIC_INFORMATION FileBasic
;
1053 IO_STATUS_BLOCK IoStatusBlock
;
1056 Status
= NtQueryInformationFile(hFile
,
1059 sizeof(FILE_BASIC_INFORMATION
),
1060 FileBasicInformation
);
1061 if (!NT_SUCCESS(Status
))
1063 SetLastErrorByStatus(Status
);
1068 memcpy(&FileBasic
.CreationTime
, lpCreationTime
, sizeof(FILETIME
));
1069 if (lpLastAccessTime
)
1070 memcpy(&FileBasic
.LastAccessTime
, lpLastAccessTime
, sizeof(FILETIME
));
1071 if (lpLastWriteTime
)
1072 memcpy(&FileBasic
.LastWriteTime
, lpLastWriteTime
, sizeof(FILETIME
));
1074 // should i initialize changetime ???
1076 Status
= NtSetInformationFile(hFile
,
1079 sizeof(FILE_BASIC_INFORMATION
),
1080 FileBasicInformation
);
1081 if (!NT_SUCCESS(Status
))
1083 SetLastErrorByStatus(Status
);
1092 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
1097 SetEndOfFile(HANDLE hFile
)
1099 IO_STATUS_BLOCK IoStatusBlock
;
1100 FILE_END_OF_FILE_INFORMATION EndOfFileInfo
;
1101 FILE_ALLOCATION_INFORMATION FileAllocationInfo
;
1102 FILE_POSITION_INFORMATION FilePosInfo
;
1105 //get current position
1106 Status
= NtQueryInformationFile(
1110 sizeof(FILE_POSITION_INFORMATION
),
1111 FilePositionInformation
1114 if (!NT_SUCCESS(Status
)){
1115 SetLastErrorByStatus(Status
);
1119 EndOfFileInfo
.EndOfFile
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1123 This call is not supposed to free up any space after the eof marker
1124 if the file gets truncated. We have to deallocate the space explicitly afterwards.
1125 But...most file systems dispatch both FileEndOfFileInformation
1126 and FileAllocationInformation as they were the same command.
1129 Status
= NtSetInformationFile(
1131 &IoStatusBlock
, //out
1133 sizeof(FILE_END_OF_FILE_INFORMATION
),
1134 FileEndOfFileInformation
1137 if (!NT_SUCCESS(Status
)){
1138 SetLastErrorByStatus(Status
);
1142 FileAllocationInfo
.AllocationSize
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
1145 Status
= NtSetInformationFile(
1147 &IoStatusBlock
, //out
1148 &FileAllocationInfo
,
1149 sizeof(FILE_ALLOCATION_INFORMATION
),
1150 FileAllocationInformation
1153 if (!NT_SUCCESS(Status
)){
1154 SetLastErrorByStatus(Status
);
1170 LONGLONG ValidDataLength
1173 IO_STATUS_BLOCK IoStatusBlock
;
1174 FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation
;
1177 ValidDataLengthInformation
.ValidDataLength
.QuadPart
= ValidDataLength
;
1179 Status
= NtSetInformationFile(
1181 &IoStatusBlock
, //out
1182 &ValidDataLengthInformation
,
1183 sizeof(FILE_VALID_DATA_LENGTH_INFORMATION
),
1184 FileValidDataLengthInformation
1187 if (!NT_SUCCESS(Status
)){
1188 SetLastErrorByStatus(Status
);
1203 LPCWSTR lpShortName
)
1207 UNICODE_STRING ShortName
;
1208 IO_STATUS_BLOCK IoStatusBlock
;
1209 PFILE_NAME_INFORMATION FileNameInformation
;
1213 SetLastError(ERROR_INVALID_PARAMETER
);
1217 RtlInitUnicodeString(&ShortName
, lpShortName
);
1219 NeededSize
= sizeof(FILE_NAME_INFORMATION
) + ShortName
.Length
+ sizeof(WCHAR
);
1220 if(!(FileNameInformation
= RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY
, NeededSize
)))
1222 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1226 FileNameInformation
->FileNameLength
= ShortName
.Length
;
1227 RtlCopyMemory(FileNameInformation
->FileName
, ShortName
.Buffer
, ShortName
.Length
);
1229 Status
= NtSetInformationFile(hFile
,
1230 &IoStatusBlock
, //out
1231 FileNameInformation
,
1233 FileShortNameInformation
);
1235 RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInformation
);
1236 if(!NT_SUCCESS(Status
))
1239 SetLastErrorByStatus(Status
);
1242 return NT_SUCCESS(Status
);
1258 ANSI_STRING ShortNameA
;
1259 UNICODE_STRING ShortName
;
1263 SetLastError(ERROR_INVALID_PARAMETER
);
1267 RtlInitAnsiString(&ShortNameA
, (LPSTR
)lpShortName
);
1270 Status
= RtlAnsiStringToUnicodeString(&ShortName
, &ShortNameA
, TRUE
);
1272 Status
= RtlOemStringToUnicodeString(&ShortName
, &ShortNameA
, TRUE
);
1273 if(!NT_SUCCESS(Status
))
1275 SetLastErrorByStatus(Status
);
1279 Ret
= SetFileShortNameW(hFile
, ShortName
.Buffer
);
1281 RtlFreeUnicodeString(&ShortName
);