1 /* $Id: file.c,v 1.43 2003/03/23 04:01:16 ekohl 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 *****************************************************************/
18 #include <kernel32/kernel32.h>
21 /* GLOBALS ******************************************************************/
23 WINBOOL bIsFileApiAnsi
= TRUE
; // set the file api to ansi or oem
26 /* FUNCTIONS ****************************************************************/
29 SetFileApisToOEM(VOID
)
31 bIsFileApiAnsi
= FALSE
;
36 SetFileApisToANSI(VOID
)
38 bIsFileApiAnsi
= TRUE
;
45 return bIsFileApiAnsi
;
50 OpenFile(LPCSTR lpFileName
,
51 LPOFSTRUCT lpReOpenBuff
,
54 OBJECT_ATTRIBUTES ObjectAttributes
;
55 IO_STATUS_BLOCK IoStatusBlock
;
56 UNICODE_STRING FileNameString
;
57 UNICODE_STRING FileNameU
;
59 WCHAR PathNameW
[MAX_PATH
];
60 HANDLE FileHandle
= NULL
;
65 DPRINT("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName
, lpReOpenBuff
, uStyle
);
67 if (lpReOpenBuff
== NULL
)
72 RtlInitAnsiString (&FileName
, (LPSTR
)lpFileName
);
74 /* convert ansi (or oem) string to unicode */
76 RtlAnsiStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
78 RtlOemStringToUnicodeString (&FileNameU
, &FileName
, TRUE
);
80 Len
= SearchPathW (NULL
,
87 RtlFreeUnicodeString(&FileNameU
);
89 if (Len
== 0 || Len
> OFS_MAXPATHNAME
)
91 return (HFILE
)INVALID_HANDLE_VALUE
;
94 FileName
.Buffer
= lpReOpenBuff
->szPathName
;
96 FileName
.MaximumLength
= OFS_MAXPATHNAME
;
98 RtlInitUnicodeString(&FileNameU
, PathNameW
);
100 /* convert unicode string to ansi (or oem) */
102 RtlUnicodeStringToAnsiString (&FileName
, &FileNameU
, FALSE
);
104 RtlUnicodeStringToOemString (&FileName
, &FileNameU
, FALSE
);
106 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)PathNameW
,
111 return (HFILE
)INVALID_HANDLE_VALUE
;
114 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
115 ObjectAttributes
.RootDirectory
= NULL
;
116 ObjectAttributes
.ObjectName
= &FileNameString
;
117 ObjectAttributes
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
;
118 ObjectAttributes
.SecurityDescriptor
= NULL
;
119 ObjectAttributes
.SecurityQualityOfService
= NULL
;
122 // FILE_NO_INTERMEDIATE_BUFFERING
124 if ((uStyle
& OF_PARSE
) == OF_PARSE
)
126 RtlFreeUnicodeString(&FileNameString
);
130 errCode
= NtOpenFile (&FileHandle
,
131 GENERIC_READ
|SYNCHRONIZE
,
135 FILE_NON_DIRECTORY_FILE
);
137 RtlFreeUnicodeString(&FileNameString
);
139 lpReOpenBuff
->nErrCode
= RtlNtStatusToDosError(errCode
);
141 if (!NT_SUCCESS(errCode
))
143 SetLastErrorByStatus (errCode
);
144 return (HFILE
)INVALID_HANDLE_VALUE
;
147 return (HFILE
)FileHandle
;
152 FlushFileBuffers(HANDLE hFile
)
155 IO_STATUS_BLOCK IoStatusBlock
;
157 if (IsConsoleHandle(hFile
))
162 errCode
= NtFlushBuffersFile(hFile
,
164 if (!NT_SUCCESS(errCode
))
166 SetLastErrorByStatus(errCode
);
174 SetFilePointer(HANDLE hFile
,
175 LONG lDistanceToMove
,
176 PLONG lpDistanceToMoveHigh
,
179 FILE_POSITION_INFORMATION FilePosition
;
180 FILE_STANDARD_INFORMATION FileStandart
;
182 IO_STATUS_BLOCK IoStatusBlock
;
183 LARGE_INTEGER Distance
;
185 DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
186 hFile
,lDistanceToMove
,dwMoveMethod
);
188 Distance
.u
.LowPart
= lDistanceToMove
;
189 if (lpDistanceToMoveHigh
)
191 Distance
.u
.HighPart
= *lpDistanceToMoveHigh
;
193 else if (lDistanceToMove
>= 0)
195 Distance
.u
.HighPart
= 0;
199 Distance
.u
.HighPart
= -1;
202 if (dwMoveMethod
== FILE_CURRENT
)
204 NtQueryInformationFile(hFile
,
207 sizeof(FILE_POSITION_INFORMATION
),
208 FilePositionInformation
);
209 FilePosition
.CurrentByteOffset
.QuadPart
+= Distance
.QuadPart
;
211 else if (dwMoveMethod
== FILE_END
)
213 NtQueryInformationFile(hFile
,
216 sizeof(FILE_STANDARD_INFORMATION
),
217 FileStandardInformation
);
218 FilePosition
.CurrentByteOffset
.QuadPart
=
219 FileStandart
.EndOfFile
.QuadPart
+ Distance
.QuadPart
;
221 else if ( dwMoveMethod
== FILE_BEGIN
)
223 FilePosition
.CurrentByteOffset
.QuadPart
= Distance
.QuadPart
;
226 errCode
= NtSetInformationFile(hFile
,
229 sizeof(FILE_POSITION_INFORMATION
),
230 FilePositionInformation
);
231 if (!NT_SUCCESS(errCode
))
233 SetLastErrorByStatus(errCode
);
237 if (lpDistanceToMoveHigh
!= NULL
)
239 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
241 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
246 GetFileType(HANDLE hFile
)
248 FILE_FS_DEVICE_INFORMATION DeviceInfo
;
249 IO_STATUS_BLOCK StatusBlock
;
252 /* Get real handle */
253 switch ((ULONG
)hFile
)
255 case STD_INPUT_HANDLE
:
256 hFile
= NtCurrentPeb()->ProcessParameters
->hStdInput
;
259 case STD_OUTPUT_HANDLE
:
260 hFile
= NtCurrentPeb()->ProcessParameters
->hStdOutput
;
263 case STD_ERROR_HANDLE
:
264 hFile
= NtCurrentPeb()->ProcessParameters
->hStdError
;
268 /* Check for console handle */
269 if (IsConsoleHandle(hFile
))
271 if (VerifyConsoleIoHandle(hFile
))
272 return FILE_TYPE_CHAR
;
275 Status
= NtQueryVolumeInformationFile(hFile
,
278 sizeof(FILE_FS_DEVICE_INFORMATION
),
279 FileFsDeviceInformation
);
280 if (!NT_SUCCESS(Status
))
282 SetLastErrorByStatus(Status
);
283 return FILE_TYPE_UNKNOWN
;
286 switch (DeviceInfo
.DeviceType
)
288 case FILE_DEVICE_CD_ROM
:
289 case FILE_DEVICE_CD_ROM_FILE_SYSTEM
:
290 case FILE_DEVICE_CONTROLLER
:
291 case FILE_DEVICE_DATALINK
:
292 case FILE_DEVICE_DFS
:
293 case FILE_DEVICE_DISK
:
294 case FILE_DEVICE_DISK_FILE_SYSTEM
:
295 case FILE_DEVICE_VIRTUAL_DISK
:
296 return FILE_TYPE_DISK
;
298 case FILE_DEVICE_KEYBOARD
:
299 case FILE_DEVICE_MOUSE
:
300 case FILE_DEVICE_NULL
:
301 case FILE_DEVICE_PARALLEL_PORT
:
302 case FILE_DEVICE_PRINTER
:
303 case FILE_DEVICE_SERIAL_PORT
:
304 case FILE_DEVICE_SCREEN
:
305 case FILE_DEVICE_SOUND
:
306 case FILE_DEVICE_MODEM
:
307 return FILE_TYPE_CHAR
;
309 case FILE_DEVICE_NAMED_PIPE
:
310 return FILE_TYPE_PIPE
;
313 return FILE_TYPE_UNKNOWN
;
318 GetFileSize(HANDLE hFile
,
319 LPDWORD lpFileSizeHigh
)
322 FILE_STANDARD_INFORMATION FileStandard
;
323 IO_STATUS_BLOCK IoStatusBlock
;
325 errCode
= NtQueryInformationFile(hFile
,
328 sizeof(FILE_STANDARD_INFORMATION
),
329 FileStandardInformation
);
330 if (!NT_SUCCESS(errCode
))
332 SetLastErrorByStatus(errCode
);
333 if ( lpFileSizeHigh
== NULL
)
342 if ( lpFileSizeHigh
!= NULL
)
343 *lpFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
345 return FileStandard
.EndOfFile
.u
.LowPart
;
350 GetCompressedFileSizeA(LPCSTR lpFileName
,
351 LPDWORD lpFileSizeHigh
)
353 UNICODE_STRING FileNameU
;
354 ANSI_STRING FileName
;
357 RtlInitAnsiString(&FileName
,
360 /* convert ansi (or oem) string to unicode */
362 RtlAnsiStringToUnicodeString(&FileNameU
,
366 RtlOemStringToUnicodeString(&FileNameU
,
370 Size
= GetCompressedFileSizeW(FileNameU
.Buffer
,
373 RtlFreeUnicodeString (&FileNameU
);
380 GetCompressedFileSizeW(LPCWSTR lpFileName
,
381 LPDWORD lpFileSizeHigh
)
383 FILE_COMPRESSION_INFORMATION FileCompression
;
385 IO_STATUS_BLOCK IoStatusBlock
;
388 hFile
= CreateFileW(lpFileName
,
393 FILE_ATTRIBUTE_NORMAL
,
396 errCode
= NtQueryInformationFile(hFile
,
399 sizeof(FILE_COMPRESSION_INFORMATION
),
400 FileCompressionInformation
);
401 if (!NT_SUCCESS(errCode
))
404 SetLastErrorByStatus(errCode
);
405 return INVALID_FILE_SIZE
;
410 *lpFileSizeHigh
= FileCompression
.CompressedFileSize
.u
.HighPart
;
412 return FileCompression
.CompressedFileSize
.u
.LowPart
;
417 GetFileInformationByHandle(HANDLE hFile
,
418 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
422 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
427 FILE_BASIC_INFORMATION FileBasic
;
428 FILE_INTERNAL_INFORMATION FileInternal
;
429 FILE_STANDARD_INFORMATION FileStandard
;
431 IO_STATUS_BLOCK IoStatusBlock
;
433 errCode
= NtQueryInformationFile(hFile
,
436 sizeof(FILE_BASIC_INFORMATION
),
437 FileBasicInformation
);
438 if (!NT_SUCCESS(errCode
))
440 SetLastErrorByStatus(errCode
);
444 lpFileInformation
->dwFileAttributes
= (DWORD
)FileBasic
.FileAttributes
;
445 memcpy(&lpFileInformation
->ftCreationTime
,&FileBasic
.CreationTime
,sizeof(LARGE_INTEGER
));
446 memcpy(&lpFileInformation
->ftLastAccessTime
,&FileBasic
.LastAccessTime
,sizeof(LARGE_INTEGER
));
447 memcpy(&lpFileInformation
->ftLastWriteTime
, &FileBasic
.LastWriteTime
,sizeof(LARGE_INTEGER
));
449 errCode
= NtQueryInformationFile(hFile
,
452 sizeof(FILE_INTERNAL_INFORMATION
),
453 FileInternalInformation
);
454 if (!NT_SUCCESS(errCode
))
456 SetLastErrorByStatus(errCode
);
460 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
461 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
463 errCode
= NtQueryVolumeInformationFile(hFile
,
466 sizeof(FileFsVolume
),
467 FileFsVolumeInformation
);
468 if (!NT_SUCCESS(errCode
))
470 SetLastErrorByStatus(errCode
);
474 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.FileFsVolume
.VolumeSerialNumber
;
476 errCode
= NtQueryInformationFile(hFile
,
479 sizeof(FILE_STANDARD_INFORMATION
),
480 FileStandardInformation
);
481 if (!NT_SUCCESS(errCode
))
483 SetLastErrorByStatus(errCode
);
487 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
488 lpFileInformation
->nFileSizeHigh
= FileStandard
.EndOfFile
.u
.HighPart
;
489 lpFileInformation
->nFileSizeLow
= FileStandard
.EndOfFile
.u
.LowPart
;
496 GetFileAttributesA(LPCSTR lpFileName
)
498 UNICODE_STRING FileNameU
;
499 ANSI_STRING FileName
;
502 RtlInitAnsiString (&FileName
,
505 /* convert ansi (or oem) string to unicode */
507 RtlAnsiStringToUnicodeString (&FileNameU
,
511 RtlOemStringToUnicodeString (&FileNameU
,
515 Result
= GetFileAttributesW (FileNameU
.Buffer
);
517 RtlFreeUnicodeString (&FileNameU
);
524 GetFileAttributesW(LPCWSTR lpFileName
)
526 FILE_BASIC_INFORMATION FileInformation
;
527 OBJECT_ATTRIBUTES ObjectAttributes
;
528 IO_STATUS_BLOCK IoStatusBlock
;
529 UNICODE_STRING FileName
;
533 DPRINT ("GetFileAttributeW(%S) called\n", lpFileName
);
535 /* Validate and translate the filename */
536 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
541 DPRINT ("Invalid path\n");
542 SetLastError (ERROR_BAD_PATHNAME
);
545 DPRINT ("FileName: \'%wZ\'\n", &FileName
);
547 /* build the object attributes */
548 InitializeObjectAttributes (&ObjectAttributes
,
550 OBJ_CASE_INSENSITIVE
,
555 Status
= NtOpenFile (&FileHandle
,
556 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
,
559 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
560 FILE_SYNCHRONOUS_IO_NONALERT
);
561 RtlFreeUnicodeString (&FileName
);
562 if (!NT_SUCCESS (Status
))
564 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
565 SetLastErrorByStatus (Status
);
569 /* Get file attributes */
570 Status
= NtQueryInformationFile (FileHandle
,
573 sizeof(FILE_BASIC_INFORMATION
),
574 FileBasicInformation
);
575 NtClose (FileHandle
);
576 if (!NT_SUCCESS (Status
))
578 DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status
);
579 SetLastErrorByStatus (Status
);
583 return (DWORD
)FileInformation
.FileAttributes
;
588 SetFileAttributesA(LPCSTR lpFileName
,
589 DWORD dwFileAttributes
)
591 UNICODE_STRING FileNameU
;
592 ANSI_STRING FileName
;
595 RtlInitAnsiString (&FileName
,
598 /* convert ansi (or oem) string to unicode */
600 RtlAnsiStringToUnicodeString (&FileNameU
,
604 RtlOemStringToUnicodeString (&FileNameU
,
608 Result
= SetFileAttributesW (FileNameU
.Buffer
,
611 RtlFreeUnicodeString (&FileNameU
);
618 SetFileAttributesW(LPCWSTR lpFileName
,
619 DWORD dwFileAttributes
)
621 FILE_BASIC_INFORMATION FileInformation
;
622 OBJECT_ATTRIBUTES ObjectAttributes
;
623 IO_STATUS_BLOCK IoStatusBlock
;
624 UNICODE_STRING FileName
;
628 DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName
, dwFileAttributes
);
630 /* Validate and translate the filename */
631 if (!RtlDosPathNameToNtPathName_U ((LPWSTR
)lpFileName
,
636 DPRINT ("Invalid path\n");
637 SetLastError (ERROR_BAD_PATHNAME
);
640 DPRINT ("FileName: \'%wZ\'\n", &FileName
);
642 /* build the object attributes */
643 InitializeObjectAttributes (&ObjectAttributes
,
645 OBJ_CASE_INSENSITIVE
,
650 Status
= NtOpenFile (&FileHandle
,
651 SYNCHRONIZE
| FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
654 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
,
655 FILE_SYNCHRONOUS_IO_NONALERT
);
656 RtlFreeUnicodeString (&FileName
);
657 if (!NT_SUCCESS (Status
))
659 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status
);
660 SetLastErrorByStatus (Status
);
664 Status
= NtQueryInformationFile(FileHandle
,
667 sizeof(FILE_BASIC_INFORMATION
),
668 FileBasicInformation
);
669 if (!NT_SUCCESS(Status
))
671 DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status
);
672 NtClose (FileHandle
);
673 SetLastErrorByStatus (Status
);
677 FileInformation
.FileAttributes
= dwFileAttributes
;
678 Status
= NtSetInformationFile(FileHandle
,
681 sizeof(FILE_BASIC_INFORMATION
),
682 FileBasicInformation
);
683 NtClose (FileHandle
);
684 if (!NT_SUCCESS(Status
))
686 DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status
);
687 SetLastErrorByStatus (Status
);
696 GetTempFileNameA(LPCSTR lpPathName
,
697 LPCSTR lpPrefixString
,
699 LPSTR lpTempFileName
)
702 UINT unique
= uUnique
;
704 const char *format
= "%.*s\\~%.3s%4.4x.TMP";
706 DPRINT("GetTempFileNameA(lpPathName %s, lpPrefixString %.*s, "
707 "uUnique %x, lpTempFileName %x)\n", lpPathName
, 4,
708 lpPrefixString
, uUnique
, lpTempFileName
);
710 if (lpPathName
== NULL
)
713 len
= strlen(lpPathName
);
714 if (len
> 0 && (lpPathName
[len
-1] == '\\' || lpPathName
[len
-1] == '/'))
718 uUnique
= GetCurrentTime();
720 sprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,uUnique
);
725 while ((hFile
= CreateFileA(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
726 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
727 0)) == INVALID_HANDLE_VALUE
)
729 if (GetLastError() != ERROR_ALREADY_EXISTS
)
733 sprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,++uUnique
);
741 GetTempFileNameW(LPCWSTR lpPathName
,
742 LPCWSTR lpPrefixString
,
744 LPWSTR lpTempFileName
)
747 UINT unique
= uUnique
;
749 const WCHAR
*format
= L
"%.*S\\~%.3S%4.4x.TMP";
751 DPRINT("GetTempFileNameW(lpPathName %S, lpPrefixString %.*S, "
752 "uUnique %x, lpTempFileName %x)\n", lpPathName
, 4,
753 lpPrefixString
, uUnique
, lpTempFileName
);
755 if (lpPathName
== NULL
)
758 len
= wcslen(lpPathName
);
759 if (len
> 0 && (lpPathName
[len
-1] == L
'\\' || lpPathName
[len
-1] == L
'/'))
763 uUnique
= GetCurrentTime();
765 swprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,uUnique
);
770 while ((hFile
= CreateFileW(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
771 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
772 0)) == INVALID_HANDLE_VALUE
)
774 if (GetLastError() != ERROR_ALREADY_EXISTS
)
778 swprintf(lpTempFileName
,format
,len
,lpPathName
,lpPrefixString
,++uUnique
);
786 GetFileTime(HANDLE hFile
,
787 LPFILETIME lpCreationTime
,
788 LPFILETIME lpLastAccessTime
,
789 LPFILETIME lpLastWriteTime
)
791 IO_STATUS_BLOCK IoStatusBlock
;
792 FILE_BASIC_INFORMATION FileBasic
;
795 Status
= NtQueryInformationFile(hFile
,
798 sizeof(FILE_BASIC_INFORMATION
),
799 FileBasicInformation
);
800 if (!NT_SUCCESS(Status
))
802 SetLastErrorByStatus(Status
);
807 memcpy(lpCreationTime
, &FileBasic
.CreationTime
, sizeof(FILETIME
));
808 if (lpLastAccessTime
)
809 memcpy(lpLastAccessTime
, &FileBasic
.LastAccessTime
, sizeof(FILETIME
));
811 memcpy(lpLastWriteTime
, &FileBasic
.LastWriteTime
, sizeof(FILETIME
));
818 SetFileTime(HANDLE hFile
,
819 CONST FILETIME
*lpCreationTime
,
820 CONST FILETIME
*lpLastAccessTime
,
821 CONST FILETIME
*lpLastWriteTime
)
823 FILE_BASIC_INFORMATION FileBasic
;
824 IO_STATUS_BLOCK IoStatusBlock
;
827 Status
= NtQueryInformationFile(hFile
,
830 sizeof(FILE_BASIC_INFORMATION
),
831 FileBasicInformation
);
832 if (!NT_SUCCESS(Status
))
834 SetLastErrorByStatus(Status
);
839 memcpy(&FileBasic
.CreationTime
, lpCreationTime
, sizeof(FILETIME
));
840 if (lpLastAccessTime
)
841 memcpy(&FileBasic
.LastAccessTime
, lpLastAccessTime
, sizeof(FILETIME
));
843 memcpy(&FileBasic
.LastWriteTime
, lpLastWriteTime
, sizeof(FILETIME
));
845 // should i initialize changetime ???
847 Status
= NtSetInformationFile(hFile
,
850 sizeof(FILE_BASIC_INFORMATION
),
851 FileBasicInformation
);
852 if (!NT_SUCCESS(Status
))
854 SetLastErrorByStatus(Status
);
863 The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
866 SetEndOfFile(HANDLE hFile
)
868 IO_STATUS_BLOCK IoStatusBlock
;
869 FILE_END_OF_FILE_INFORMATION EndOfFileInfo
;
870 FILE_ALLOCATION_INFORMATION FileAllocationInfo
;
871 FILE_POSITION_INFORMATION FilePosInfo
;
874 //get current position
875 Status
= NtQueryInformationFile(
879 sizeof(FILE_POSITION_INFORMATION
),
880 FilePositionInformation
883 if (!NT_SUCCESS(Status
)){
884 SetLastErrorByStatus(Status
);
888 EndOfFileInfo
.EndOfFile
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
892 This call is not supposed to free up any space after the eof marker
893 if the file gets truncated. We have to deallocate the space explicitly afterwards.
894 But...most file systems dispatch both FileEndOfFileInformation
895 and FileAllocationInformation as they were the same command.
898 Status
= NtSetInformationFile(
900 &IoStatusBlock
, //out
902 sizeof(FILE_END_OF_FILE_INFORMATION
),
903 FileEndOfFileInformation
906 if (!NT_SUCCESS(Status
)){
907 SetLastErrorByStatus(Status
);
911 FileAllocationInfo
.AllocationSize
.QuadPart
= FilePosInfo
.CurrentByteOffset
.QuadPart
;
914 Status
= NtSetInformationFile(
916 &IoStatusBlock
, //out
918 sizeof(FILE_ALLOCATION_INFORMATION
),
919 FileAllocationInformation
922 if (!NT_SUCCESS(Status
)){
923 SetLastErrorByStatus(Status
);