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 ****************************************************************/
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 RtlInitAnsiString (&FileName, (LPSTR)lpFileName);
86 /* convert ansi (or oem) string to unicode */
88 RtlAnsiStringToUnicodeString (&FileNameU, &FileName, TRUE);
90 RtlOemStringToUnicodeString (&FileNameU, &FileName, TRUE);
92 Len = SearchPathW (NULL,
99 RtlFreeUnicodeString(&FileNameU);
101 if (Len == 0 || Len > OFS_MAXPATHNAME)
103 return (HFILE)INVALID_HANDLE_VALUE;
106 FileName.Buffer = lpReOpenBuff->szPathName;
108 FileName.MaximumLength = OFS_MAXPATHNAME;
110 RtlInitUnicodeString(&FileNameU, PathNameW);
112 /* convert unicode string to ansi (or oem) */
114 RtlUnicodeStringToAnsiString (&FileName, &FileNameU, FALSE);
116 RtlUnicodeStringToOemString (&FileName, &FileNameU, FALSE);
118 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)PathNameW,
123 return (HFILE)INVALID_HANDLE_VALUE;
126 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
127 ObjectAttributes.RootDirectory = NULL;
128 ObjectAttributes.ObjectName = &FileNameString;
129 ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
130 ObjectAttributes.SecurityDescriptor = NULL;
131 ObjectAttributes.SecurityQualityOfService = NULL;
134 // FILE_NO_INTERMEDIATE_BUFFERING
136 if ((uStyle & OF_PARSE) == OF_PARSE)
138 RtlFreeUnicodeString(&FileNameString);
142 errCode = NtOpenFile (&FileHandle,
143 GENERIC_READ|SYNCHRONIZE,
147 FILE_NON_DIRECTORY_FILE);
149 RtlFreeUnicodeString(&FileNameString);
151 lpReOpenBuff->nErrCode = RtlNtStatusToDosError(errCode);
153 if (!NT_SUCCESS(errCode))
155 SetLastErrorByStatus (errCode);
156 return (HFILE)INVALID_HANDLE_VALUE;
159 return (HFILE)FileHandle;
167 FlushFileBuffers(HANDLE hFile)
170 IO_STATUS_BLOCK IoStatusBlock;
172 if (IsConsoleHandle(hFile))
177 errCode = NtFlushBuffersFile(hFile,
179 if (!NT_SUCCESS(errCode))
181 SetLastErrorByStatus(errCode);
192 SetFilePointer(HANDLE hFile,
193 LONG lDistanceToMove,
194 PLONG lpDistanceToMoveHigh,
197 FILE_POSITION_INFORMATION FilePosition;
198 FILE_STANDARD_INFORMATION FileStandart;
200 IO_STATUS_BLOCK IoStatusBlock;
201 LARGE_INTEGER Distance;
203 DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
204 hFile,lDistanceToMove,dwMoveMethod);
206 Distance.u.LowPart = lDistanceToMove;
207 if (lpDistanceToMoveHigh)
209 Distance.u.HighPart = *lpDistanceToMoveHigh;
211 else if (lDistanceToMove >= 0)
213 Distance.u.HighPart = 0;
217 Distance.u.HighPart = -1;
220 if (dwMoveMethod == FILE_CURRENT)
222 NtQueryInformationFile(hFile,
225 sizeof(FILE_POSITION_INFORMATION),
226 FilePositionInformation);
227 FilePosition.CurrentByteOffset.QuadPart += Distance.QuadPart;
229 else if (dwMoveMethod == FILE_END)
231 NtQueryInformationFile(hFile,
234 sizeof(FILE_STANDARD_INFORMATION),
235 FileStandardInformation);
236 FilePosition.CurrentByteOffset.QuadPart =
237 FileStandart.EndOfFile.QuadPart + Distance.QuadPart;
239 else if ( dwMoveMethod == FILE_BEGIN )
241 FilePosition.CurrentByteOffset.QuadPart = Distance.QuadPart;
244 errCode = NtSetInformationFile(hFile,
247 sizeof(FILE_POSITION_INFORMATION),
248 FilePositionInformation);
249 if (!NT_SUCCESS(errCode))
251 SetLastErrorByStatus(errCode);
255 if (lpDistanceToMoveHigh != NULL)
257 *lpDistanceToMoveHigh = FilePosition.CurrentByteOffset.u.HighPart;
259 return FilePosition.CurrentByteOffset.u.LowPart;
267 GetFileType(HANDLE hFile)
269 FILE_FS_DEVICE_INFORMATION DeviceInfo;
270 IO_STATUS_BLOCK StatusBlock;
273 /* Get real handle */
274 switch ((ULONG)hFile)
276 case STD_INPUT_HANDLE:
277 hFile = NtCurrentPeb()->ProcessParameters->hStdInput;
280 case STD_OUTPUT_HANDLE:
281 hFile = NtCurrentPeb()->ProcessParameters->hStdOutput;
284 case STD_ERROR_HANDLE:
285 hFile = NtCurrentPeb()->ProcessParameters->hStdError;
289 /* Check for console handle */
290 if (IsConsoleHandle(hFile))
292 if (VerifyConsoleIoHandle(hFile))
293 return FILE_TYPE_CHAR;
296 Status = NtQueryVolumeInformationFile(hFile,
299 sizeof(FILE_FS_DEVICE_INFORMATION),
300 FileFsDeviceInformation);
301 if (!NT_SUCCESS(Status))
303 SetLastErrorByStatus(Status);
304 return FILE_TYPE_UNKNOWN;
307 switch (DeviceInfo.DeviceType)
309 case FILE_DEVICE_CD_ROM:
310 case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
311 case FILE_DEVICE_CONTROLLER:
312 case FILE_DEVICE_DATALINK:
313 case FILE_DEVICE_DFS:
314 case FILE_DEVICE_DISK:
315 case FILE_DEVICE_DISK_FILE_SYSTEM:
316 case FILE_DEVICE_VIRTUAL_DISK:
317 return FILE_TYPE_DISK;
319 case FILE_DEVICE_KEYBOARD:
320 case FILE_DEVICE_MOUSE:
321 case FILE_DEVICE_NULL:
322 case FILE_DEVICE_PARALLEL_PORT:
323 case FILE_DEVICE_PRINTER:
324 case FILE_DEVICE_SERIAL_PORT:
325 case FILE_DEVICE_SCREEN:
326 case FILE_DEVICE_SOUND:
327 case FILE_DEVICE_MODEM:
328 return FILE_TYPE_CHAR;
330 case FILE_DEVICE_NAMED_PIPE:
331 return FILE_TYPE_PIPE;
334 return FILE_TYPE_UNKNOWN;
342 GetFileSize(HANDLE hFile,
343 LPDWORD lpFileSizeHigh)
346 FILE_STANDARD_INFORMATION FileStandard;
347 IO_STATUS_BLOCK IoStatusBlock;
349 errCode = NtQueryInformationFile(hFile,
352 sizeof(FILE_STANDARD_INFORMATION),
353 FileStandardInformation);
354 if (!NT_SUCCESS(errCode))
356 SetLastErrorByStatus(errCode);
357 if ( lpFileSizeHigh == NULL )
366 if ( lpFileSizeHigh != NULL )
367 *lpFileSizeHigh = FileStandard.EndOfFile.u.HighPart;
369 return FileStandard.EndOfFile.u.LowPart;
377 GetCompressedFileSizeA(LPCSTR lpFileName,
378 LPDWORD lpFileSizeHigh)
380 UNICODE_STRING FileNameU;
381 ANSI_STRING FileName;
384 RtlInitAnsiString(&FileName,
387 /* convert ansi (or oem) string to unicode */
389 RtlAnsiStringToUnicodeString(&FileNameU,
393 RtlOemStringToUnicodeString(&FileNameU,
397 Size = GetCompressedFileSizeW(FileNameU.Buffer,
400 RtlFreeUnicodeString (&FileNameU);
410 GetCompressedFileSizeW(LPCWSTR lpFileName,
411 LPDWORD lpFileSizeHigh)
413 FILE_COMPRESSION_INFORMATION FileCompression;
415 IO_STATUS_BLOCK IoStatusBlock;
418 hFile = CreateFileW(lpFileName,
423 FILE_ATTRIBUTE_NORMAL,
426 errCode = NtQueryInformationFile(hFile,
429 sizeof(FILE_COMPRESSION_INFORMATION),
430 FileCompressionInformation);
431 if (!NT_SUCCESS(errCode))
434 SetLastErrorByStatus(errCode);
435 return INVALID_FILE_SIZE;
440 *lpFileSizeHigh = FileCompression.CompressedFileSize.u.HighPart;
442 return FileCompression.CompressedFileSize.u.LowPart;
450 GetFileInformationByHandle(HANDLE hFile,
451 LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
455 FILE_FS_VOLUME_INFORMATION FileFsVolume;
460 FILE_BASIC_INFORMATION FileBasic;
461 FILE_INTERNAL_INFORMATION FileInternal;
462 FILE_STANDARD_INFORMATION FileStandard;
464 IO_STATUS_BLOCK IoStatusBlock;
466 errCode = NtQueryInformationFile(hFile,
469 sizeof(FILE_BASIC_INFORMATION),
470 FileBasicInformation);
471 if (!NT_SUCCESS(errCode))
473 SetLastErrorByStatus(errCode);
477 lpFileInformation->dwFileAttributes = (DWORD)FileBasic.FileAttributes;
478 memcpy(&lpFileInformation->ftCreationTime,&FileBasic.CreationTime,sizeof(LARGE_INTEGER));
479 memcpy(&lpFileInformation->ftLastAccessTime,&FileBasic.LastAccessTime,sizeof(LARGE_INTEGER));
480 memcpy(&lpFileInformation->ftLastWriteTime, &FileBasic.LastWriteTime,sizeof(LARGE_INTEGER));
482 errCode = NtQueryInformationFile(hFile,
485 sizeof(FILE_INTERNAL_INFORMATION),
486 FileInternalInformation);
487 if (!NT_SUCCESS(errCode))
489 SetLastErrorByStatus(errCode);
493 lpFileInformation->nFileIndexHigh = FileInternal.IndexNumber.u.HighPart;
494 lpFileInformation->nFileIndexLow = FileInternal.IndexNumber.u.LowPart;
496 errCode = NtQueryVolumeInformationFile(hFile,
499 sizeof(FileFsVolume),
500 FileFsVolumeInformation);
501 if (!NT_SUCCESS(errCode))
503 SetLastErrorByStatus(errCode);
507 lpFileInformation->dwVolumeSerialNumber = FileFsVolume.FileFsVolume.VolumeSerialNumber;
509 errCode = NtQueryInformationFile(hFile,
512 sizeof(FILE_STANDARD_INFORMATION),
513 FileStandardInformation);
514 if (!NT_SUCCESS(errCode))
516 SetLastErrorByStatus(errCode);
520 lpFileInformation->nNumberOfLinks = FileStandard.NumberOfLinks;
521 lpFileInformation->nFileSizeHigh = FileStandard.EndOfFile.u.HighPart;
522 lpFileInformation->nFileSizeLow = FileStandard.EndOfFile.u.LowPart;
532 GetFileAttributesExW(LPCWSTR lpFileName,
533 GET_FILEEX_INFO_LEVELS fInfoLevelId,
534 LPVOID lpFileInformation)
536 FILE_NETWORK_OPEN_INFORMATION FileInformation;
537 OBJECT_ATTRIBUTES ObjectAttributes;
538 IO_STATUS_BLOCK IoStatusBlock;
539 UNICODE_STRING FileName;
542 WIN32_FILE_ATTRIBUTE_DATA* FileAttributeData;
544 DPRINT ("GetFileAttributesExW(%S) called\n", lpFileName);
547 if (fInfoLevelId != GetFileExInfoStandard || lpFileInformation == NULL)
549 SetLastError(ERROR_INVALID_PARAMETER);
553 /* Validate and translate the filename */
554 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName,
559 DPRINT ("Invalid path\n");
560 SetLastError (ERROR_BAD_PATHNAME);
564 /* build the object attributes */
565 InitializeObjectAttributes (&ObjectAttributes,
567 OBJ_CASE_INSENSITIVE,
572 Status = NtOpenFile (&FileHandle,
573 SYNCHRONIZE | FILE_READ_ATTRIBUTES,
576 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
577 FILE_SYNCHRONOUS_IO_NONALERT);
578 RtlFreeUnicodeString (&FileName);
579 if (!NT_SUCCESS (Status))
581 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status);
582 SetLastErrorByStatus (Status);
586 /* Get file attributes */
587 Status = NtQueryInformationFile (FileHandle,
590 sizeof(FILE_NETWORK_OPEN_INFORMATION),
591 FileNetworkOpenInformation);
592 NtClose (FileHandle);
594 if (!NT_SUCCESS (Status))
596 DPRINT ("NtQueryInformationFile() failed (Status %lx)\n", Status);
597 SetLastErrorByStatus (Status);
601 FileAttributeData = (WIN32_FILE_ATTRIBUTE_DATA*)lpFileInformation;
602 FileAttributeData->dwFileAttributes = FileInformation.FileAttributes;
603 FileAttributeData->ftCreationTime.dwLowDateTime = FileInformation.CreationTime.u.LowPart;
604 FileAttributeData->ftCreationTime.dwHighDateTime = FileInformation.CreationTime.u.HighPart;
605 FileAttributeData->ftLastAccessTime.dwLowDateTime = FileInformation.LastAccessTime.u.LowPart;
606 FileAttributeData->ftLastAccessTime.dwHighDateTime = FileInformation.LastAccessTime.u.HighPart;
607 FileAttributeData->ftLastWriteTime.dwLowDateTime = FileInformation.LastWriteTime.u.LowPart;
608 FileAttributeData->ftLastWriteTime.dwHighDateTime = FileInformation.LastWriteTime.u.HighPart;
609 FileAttributeData->nFileSizeLow = FileInformation.EndOfFile.u.LowPart;
610 FileAttributeData->nFileSizeHigh = FileInformation.EndOfFile.u.HighPart;
619 GetFileAttributesExA(LPCSTR lpFileName,
620 GET_FILEEX_INFO_LEVELS fInfoLevelId,
621 LPVOID lpFileInformation)
623 UNICODE_STRING FileNameU;
624 ANSI_STRING FileName;
626 RtlInitAnsiString (&FileName,
629 /* convert ansi (or oem) string to unicode */
631 RtlAnsiStringToUnicodeString (&FileNameU,
635 RtlOemStringToUnicodeString (&FileNameU,
639 Result = GetFileAttributesExW(FileNameU.Buffer, fInfoLevelId, lpFileInformation);
641 RtlFreeUnicodeString (&FileNameU);
651 GetFileAttributesA(LPCSTR lpFileName)
653 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData;
654 UNICODE_STRING FileNameU;
655 ANSI_STRING FileName;
658 RtlInitAnsiString (&FileName,
661 /* convert ansi (or oem) string to unicode */
663 RtlAnsiStringToUnicodeString (&FileNameU,
667 RtlOemStringToUnicodeString (&FileNameU,
671 Result = GetFileAttributesExW(FileNameU.Buffer, GetFileExInfoStandard, &FileAttributeData);
673 RtlFreeUnicodeString (&FileNameU);
675 return Result ? FileAttributeData.dwFileAttributes : 0xffffffff;
683 GetFileAttributesW(LPCWSTR lpFileName)
685 WIN32_FILE_ATTRIBUTE_DATA FileAttributeData;
688 DPRINT ("GetFileAttributeW(%S) called\n", lpFileName);
690 Result = GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &FileAttributeData);
692 return Result ? FileAttributeData.dwFileAttributes : 0xffffffff;
696 SetFileAttributesA(LPCSTR lpFileName,
697 DWORD dwFileAttributes)
699 UNICODE_STRING FileNameU;
700 ANSI_STRING FileName;
703 RtlInitAnsiString (&FileName,
706 /* convert ansi (or oem) string to unicode */
708 RtlAnsiStringToUnicodeString (&FileNameU,
712 RtlOemStringToUnicodeString (&FileNameU,
716 Result = SetFileAttributesW (FileNameU.Buffer,
719 RtlFreeUnicodeString (&FileNameU);
729 SetFileAttributesW(LPCWSTR lpFileName,
730 DWORD dwFileAttributes)
732 FILE_BASIC_INFORMATION FileInformation;
733 OBJECT_ATTRIBUTES ObjectAttributes;
734 IO_STATUS_BLOCK IoStatusBlock;
735 UNICODE_STRING FileName;
739 DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName, dwFileAttributes);
741 /* Validate and translate the filename */
742 if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName,
747 DPRINT ("Invalid path\n");
748 SetLastError (ERROR_BAD_PATHNAME);
751 DPRINT ("FileName: \'%wZ\'\n", &FileName);
753 /* build the object attributes */
754 InitializeObjectAttributes (&ObjectAttributes,
756 OBJ_CASE_INSENSITIVE,
761 Status = NtOpenFile (&FileHandle,
762 SYNCHRONIZE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
765 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
766 FILE_SYNCHRONOUS_IO_NONALERT);
767 RtlFreeUnicodeString (&FileName);
768 if (!NT_SUCCESS (Status))
770 DPRINT ("NtOpenFile() failed (Status %lx)\n", Status);
771 SetLastErrorByStatus (Status);
775 Status = NtQueryInformationFile(FileHandle,
778 sizeof(FILE_BASIC_INFORMATION),
779 FileBasicInformation);
780 if (!NT_SUCCESS(Status))
782 DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status);
783 NtClose (FileHandle);
784 SetLastErrorByStatus (Status);
788 FileInformation.FileAttributes = dwFileAttributes;
789 Status = NtSetInformationFile(FileHandle,
792 sizeof(FILE_BASIC_INFORMATION),
793 FileBasicInformation);
794 NtClose (FileHandle);
795 if (!NT_SUCCESS(Status))
797 DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status);
798 SetLastErrorByStatus (Status);
810 GetTempFileNameA(LPCSTR lpPathName,
811 LPCSTR lpPrefixString,
813 LPSTR lpTempFileName)
816 UINT unique = uUnique;
818 const char *format = "%.*s\\~%.3s%4.4x.TMP";
820 DPRINT("GetTempFileNameA(lpPathName %s, lpPrefixString %.*s, "
821 "uUnique %x, lpTempFileName %x)\n", lpPathName, 4,
822 lpPrefixString, uUnique, lpTempFileName);
824 if (lpPathName == NULL)
827 len = strlen(lpPathName);
828 if (len > 0 && (lpPathName[len-1] == '\\' || lpPathName[len-1] == '/'))
832 uUnique = GetCurrentTime();
834 sprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,uUnique);
839 while ((hFile = CreateFileA(lpTempFileName, GENERIC_WRITE, 0, NULL,
840 CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
841 0)) == INVALID_HANDLE_VALUE)
843 if (GetLastError() != ERROR_ALREADY_EXISTS)
847 sprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,++uUnique);
858 GetTempFileNameW(LPCWSTR lpPathName,
859 LPCWSTR lpPrefixString,
861 LPWSTR lpTempFileName)
864 UINT unique = uUnique;
866 const WCHAR *format = L"%.*s\\~%.3s%4.4x.TMP";
868 DPRINT("GetTempFileNameW(lpPathName %S, lpPrefixString %.*S, "
869 "uUnique %x, lpTempFileName %x)\n", lpPathName, 4,
870 lpPrefixString, uUnique, lpTempFileName);
872 if (lpPathName == NULL)
875 len = wcslen(lpPathName);
876 if (len > 0 && (lpPathName[len-1] == L'\\' || lpPathName[len-1] == L'/'))
880 uUnique = GetCurrentTime();
882 swprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,uUnique);
887 while ((hFile = CreateFileW(lpTempFileName, GENERIC_WRITE, 0, NULL,
888 CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
889 0)) == INVALID_HANDLE_VALUE)
891 if (GetLastError() != ERROR_ALREADY_EXISTS)
895 swprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,++uUnique);
906 GetFileTime(HANDLE hFile,
907 LPFILETIME lpCreationTime,
908 LPFILETIME lpLastAccessTime,
909 LPFILETIME lpLastWriteTime)
911 IO_STATUS_BLOCK IoStatusBlock;
912 FILE_BASIC_INFORMATION FileBasic;
915 Status = NtQueryInformationFile(hFile,
918 sizeof(FILE_BASIC_INFORMATION),
919 FileBasicInformation);
920 if (!NT_SUCCESS(Status))
922 SetLastErrorByStatus(Status);
927 memcpy(lpCreationTime, &FileBasic.CreationTime, sizeof(FILETIME));
928 if (lpLastAccessTime)
929 memcpy(lpLastAccessTime, &FileBasic.LastAccessTime, sizeof(FILETIME));
931 memcpy(lpLastWriteTime, &FileBasic.LastWriteTime, sizeof(FILETIME));
941 SetFileTime(HANDLE hFile,
942 CONST FILETIME *lpCreationTime,
943 CONST FILETIME *lpLastAccessTime,
944 CONST FILETIME *lpLastWriteTime)
946 FILE_BASIC_INFORMATION FileBasic;
947 IO_STATUS_BLOCK IoStatusBlock;
950 Status = NtQueryInformationFile(hFile,
953 sizeof(FILE_BASIC_INFORMATION),
954 FileBasicInformation);
955 if (!NT_SUCCESS(Status))
957 SetLastErrorByStatus(Status);
962 memcpy(&FileBasic.CreationTime, lpCreationTime, sizeof(FILETIME));
963 if (lpLastAccessTime)
964 memcpy(&FileBasic.LastAccessTime, lpLastAccessTime, sizeof(FILETIME));
966 memcpy(&FileBasic.LastWriteTime, lpLastWriteTime, sizeof(FILETIME));
968 // should i initialize changetime ???
970 Status = NtSetInformationFile(hFile,
973 sizeof(FILE_BASIC_INFORMATION),
974 FileBasicInformation);
975 if (!NT_SUCCESS(Status))
977 SetLastErrorByStatus(Status);
986 * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
991 SetEndOfFile(HANDLE hFile)
993 IO_STATUS_BLOCK IoStatusBlock;
994 FILE_END_OF_FILE_INFORMATION EndOfFileInfo;
995 FILE_ALLOCATION_INFORMATION FileAllocationInfo;
996 FILE_POSITION_INFORMATION FilePosInfo;
999 //get current position
1000 Status = NtQueryInformationFile(
1004 sizeof(FILE_POSITION_INFORMATION),
1005 FilePositionInformation
1008 if (!NT_SUCCESS(Status)){
1009 SetLastErrorByStatus(Status);
1013 EndOfFileInfo.EndOfFile.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
1017 This call is not supposed to free up any space after the eof marker
1018 if the file gets truncated. We have to deallocate the space explicitly afterwards.
1019 But...most file systems dispatch both FileEndOfFileInformation
1020 and FileAllocationInformation as they were the same command.
1023 Status = NtSetInformationFile(
1025 &IoStatusBlock, //out
1027 sizeof(FILE_END_OF_FILE_INFORMATION),
1028 FileEndOfFileInformation
1031 if (!NT_SUCCESS(Status)){
1032 SetLastErrorByStatus(Status);
1036 FileAllocationInfo.AllocationSize.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
1039 Status = NtSetInformationFile(
1041 &IoStatusBlock, //out
1042 &FileAllocationInfo,
1043 sizeof(FILE_ALLOCATION_INFORMATION),
1044 FileAllocationInformation
1047 if (!NT_SUCCESS(Status)){
1048 SetLastErrorByStatus(Status);