-/* $Id: file.c,v 1.27 2001/08/06 18:35:15 hbirr Exp $
+/* $Id: file.c,v 1.38 2002/11/07 02:52:37 robd Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
PWCHAR FilePart;
ULONG Len;
+ DPRINT("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName, lpReOpenBuff, uStyle);
+
if (lpReOpenBuff == NULL)
{
return FALSE;
}
- RtlInitAnsiString (&FileName,
- (LPSTR)lpFileName);
+ RtlInitAnsiString (&FileName, (LPSTR)lpFileName);
/* convert ansi (or oem) string to unicode */
if (bIsFileApiAnsi)
- RtlAnsiStringToUnicodeString (&FileNameU,
- &FileName,
- TRUE);
+ RtlAnsiStringToUnicodeString (&FileNameU, &FileName, TRUE);
else
- RtlOemStringToUnicodeString (&FileNameU,
- &FileName,
- TRUE);
+ RtlOemStringToUnicodeString (&FileNameU, &FileName, TRUE);
Len = SearchPathW (NULL,
FileNameU.Buffer,
NULL,
- MAX_PATH,
+ OFS_MAXPATHNAME,
PathNameW,
&FilePart);
- RtlFreeHeap (RtlGetProcessHeap (),
- 0,
- FileNameU.Buffer);
+ RtlFreeUnicodeString(&FileNameU);
- if (Len == 0)
- return (HFILE)NULL;
+ if (Len == 0 || Len > OFS_MAXPATHNAME)
+ {
+ return (HFILE)INVALID_HANDLE_VALUE;
+ }
- if (Len > MAX_PATH)
- return (HFILE)NULL;
+ FileName.Buffer = lpReOpenBuff->szPathName;
+ FileName.Length = 0;
+ FileName.MaximumLength = OFS_MAXPATHNAME;
- FileNameString.Length = lstrlenW(PathNameW) * sizeof(WCHAR);
- FileNameString.Buffer = PathNameW;
- FileNameString.MaximumLength = FileNameString.Length + sizeof(WCHAR);
+ RtlInitUnicodeString(&FileNameU, PathNameW);
+
+ /* convert unicode string to ansi (or oem) */
+ if (bIsFileApiAnsi)
+ RtlUnicodeStringToAnsiString (&FileName, &FileNameU, FALSE);
+ else
+ RtlUnicodeStringToOemString (&FileName, &FileNameU, FALSE);
+
+ if (!RtlDosPathNameToNtPathName_U ((LPWSTR)PathNameW,
+ &FileNameString,
+ NULL,
+ NULL))
+ {
+ return (HFILE)INVALID_HANDLE_VALUE;
+ }
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
ObjectAttributes.RootDirectory = NULL;
// FILE_NO_INTERMEDIATE_BUFFERING
if ((uStyle & OF_PARSE) == OF_PARSE)
+ {
+ RtlFreeUnicodeString(&FileNameString);
return (HFILE)NULL;
+ }
errCode = NtOpenFile (&FileHandle,
GENERIC_READ|SYNCHRONIZE,
FILE_SHARE_READ,
FILE_NON_DIRECTORY_FILE);
+ RtlFreeUnicodeString(&FileNameString);
+
lpReOpenBuff->nErrCode = RtlNtStatusToDosError(errCode);
if (!NT_SUCCESS(errCode))
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
+ if (IsConsoleHandle(hFile))
+ {
+ return FALSE;
+ }
+
errCode = NtFlushBuffersFile(hFile,
&IoStatusBlock);
if (!NT_SUCCESS(errCode))
hFile,lDistanceToMove,dwMoveMethod);
Distance.u.LowPart = lDistanceToMove;
- Distance.u.HighPart = (lpDistanceToMoveHigh) ? *lpDistanceToMoveHigh : 0;
+ if (lpDistanceToMoveHigh)
+ {
+ Distance.u.HighPart = *lpDistanceToMoveHigh;
+ }
+ else if (lDistanceToMove >= 0)
+ {
+ Distance.u.HighPart = 0;
+ }
+ else
+ {
+ Distance.u.HighPart = -1;
+ }
if (dwMoveMethod == FILE_CURRENT)
{
switch ((ULONG)hFile)
{
case STD_INPUT_HANDLE:
- hFile = NtCurrentPeb()->ProcessParameters->InputHandle;
+ hFile = NtCurrentPeb()->ProcessParameters->hStdInput;
+
break;
case STD_OUTPUT_HANDLE:
- hFile = NtCurrentPeb()->ProcessParameters->OutputHandle;
+ hFile = NtCurrentPeb()->ProcessParameters->hStdOutput;
+
break;
case STD_ERROR_HANDLE:
- hFile = NtCurrentPeb()->ProcessParameters->ErrorHandle;
+ hFile = NtCurrentPeb()->ProcessParameters->hStdError;
+
break;
}
/* check console handles */
- if (((ULONG)hFile & 3) == 3)
+ if (IsConsoleHandle(hFile))
{
// if (VerifyConsoleHandle(hFile))
return FILE_TYPE_CHAR;
}
}
if ( lpFileSizeHigh != NULL )
- *lpFileSizeHigh = FileStandard.AllocationSize.u.HighPart;
+ *lpFileSizeHigh = FileStandard.EndOfFile.u.HighPart;
- return FileStandard.AllocationSize.u.LowPart;
+ return FileStandard.EndOfFile.u.LowPart;
}
GetFileInformationByHandle(HANDLE hFile,
LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
{
- FILE_DIRECTORY_INFORMATION FileDirectory;
+ struct
+ {
+ FILE_FS_VOLUME_INFORMATION FileFsVolume;
+ WCHAR Name[255];
+ }
+ FileFsVolume;
+
+ FILE_BASIC_INFORMATION FileBasic;
FILE_INTERNAL_INFORMATION FileInternal;
- FILE_FS_VOLUME_INFORMATION FileFsVolume;
FILE_STANDARD_INFORMATION FileStandard;
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
-
+
errCode = NtQueryInformationFile(hFile,
&IoStatusBlock,
- &FileDirectory,
- sizeof(FILE_DIRECTORY_INFORMATION),
- FileDirectoryInformation);
+ &FileBasic,
+ sizeof(FILE_BASIC_INFORMATION),
+ FileBasicInformation);
if (!NT_SUCCESS(errCode))
{
SetLastErrorByStatus(errCode);
return FALSE;
}
- lpFileInformation->dwFileAttributes = (DWORD)FileDirectory.FileAttributes;
- memcpy(&lpFileInformation->ftCreationTime,&FileDirectory.CreationTime,sizeof(LARGE_INTEGER));
- memcpy(&lpFileInformation->ftLastAccessTime,&FileDirectory.LastAccessTime,sizeof(LARGE_INTEGER));
- memcpy(&lpFileInformation->ftLastWriteTime, &FileDirectory.LastWriteTime,sizeof(LARGE_INTEGER));
- lpFileInformation->nFileSizeHigh = FileDirectory.AllocationSize.u.HighPart;
- lpFileInformation->nFileSizeLow = FileDirectory.AllocationSize.u.LowPart;
-
+ lpFileInformation->dwFileAttributes = (DWORD)FileBasic.FileAttributes;
+ memcpy(&lpFileInformation->ftCreationTime,&FileBasic.CreationTime,sizeof(LARGE_INTEGER));
+ memcpy(&lpFileInformation->ftLastAccessTime,&FileBasic.LastAccessTime,sizeof(LARGE_INTEGER));
+ memcpy(&lpFileInformation->ftLastWriteTime, &FileBasic.LastWriteTime,sizeof(LARGE_INTEGER));
+
errCode = NtQueryInformationFile(hFile,
&IoStatusBlock,
&FileInternal,
lpFileInformation->nFileIndexHigh = FileInternal.IndexNumber.u.HighPart;
lpFileInformation->nFileIndexLow = FileInternal.IndexNumber.u.LowPart;
-
+
errCode = NtQueryVolumeInformationFile(hFile,
&IoStatusBlock,
&FileFsVolume,
- sizeof(FILE_FS_VOLUME_INFORMATION),
+ sizeof(FileFsVolume),
FileFsVolumeInformation);
if (!NT_SUCCESS(errCode))
{
return FALSE;
}
- lpFileInformation->dwVolumeSerialNumber = FileFsVolume.VolumeSerialNumber;
-
+ lpFileInformation->dwVolumeSerialNumber = FileFsVolume.FileFsVolume.VolumeSerialNumber;
+
errCode = NtQueryInformationFile(hFile,
&IoStatusBlock,
&FileStandard,
}
lpFileInformation->nNumberOfLinks = FileStandard.NumberOfLinks;
+ lpFileInformation->nFileSizeHigh = FileStandard.EndOfFile.u.HighPart;
+ lpFileInformation->nFileSizeLow = FileStandard.EndOfFile.u.LowPart;
return TRUE;
}
{
HANDLE hFile;
UINT unique = uUnique;
+ UINT len;
+ const char *format = "%.*s\\~%.3s%4.4x.TMP";
+
+ DPRINT("GetTempFileNameA(lpPathName %s, lpPrefixString %.*s, "
+ "uUnique %x, lpTempFileName %x)\n", lpPathName, 4,
+ lpPrefixString, uUnique, lpTempFileName);
if (lpPathName == NULL)
return 0;
-
+
+ len = strlen(lpPathName);
+ if (len > 0 && (lpPathName[len-1] == '\\' || lpPathName[len-1] == '/'))
+ len--;
+
if (uUnique == 0)
uUnique = GetCurrentTime();
- /*
- * sprintf(lpTempFileName,"%s\\%c%.3s%4.4x%s",
- * lpPathName,'~',lpPrefixString,uUnique,".tmp");
- */
+
+ sprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,uUnique);
+
if (unique)
return uUnique;
while ((hFile = CreateFileA(lpTempFileName, GENERIC_WRITE, 0, NULL,
CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
0)) == INVALID_HANDLE_VALUE)
- {
- // wsprintfA(lpTempFileName,"%s\\%c%.3s%4.4x%s",
- // lpPathName,'~',lpPrefixString,++uUnique,".tmp");
- }
-
- CloseHandle((HANDLE)hFile);
+ {
+ if (GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ return 0;
+ }
+ sprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,++uUnique);
+ }
+ CloseHandle(hFile);
return uUnique;
}
{
HANDLE hFile;
UINT unique = uUnique;
+ UINT len;
+ const WCHAR *format = L"%.*S\\~%.3S%4.4x.TMP";
+ DPRINT("GetTempFileNameW(lpPathName %S, lpPrefixString %.*S, "
+ "uUnique %x, lpTempFileName %x)\n", lpPathName, 4,
+ lpPrefixString, uUnique, lpTempFileName);
+
if (lpPathName == NULL)
return 0;
+
+ len = wcslen(lpPathName);
+ if (len > 0 && (lpPathName[len-1] == L'\\' || lpPathName[len-1] == L'/'))
+ len--;
if (uUnique == 0)
uUnique = GetCurrentTime();
- // swprintf(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
- // lpPathName,'~',lpPrefixString,uUnique,L".tmp");
+ swprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,uUnique);
if (unique)
return uUnique;
while ((hFile = CreateFileW(lpTempFileName, GENERIC_WRITE, 0, NULL,
CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
0)) == INVALID_HANDLE_VALUE)
- {
- // wsprintfW(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
- // lpPathName,'~',lpPrefixString,++uUnique,L".tmp");
- }
-
- CloseHandle((HANDLE)hFile);
+ {
+ if (GetLastError() != ERROR_ALREADY_EXISTS)
+ {
+ return 0;
+ }
+ swprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,++uUnique);
+ }
+ CloseHandle(hFile);
return uUnique;
}
}
+/*
+The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
+*/
WINBOOL STDCALL
SetEndOfFile(HANDLE hFile)
{
- int x = -1;
- DWORD Num;
- return WriteFile(hFile,&x,1,&Num,NULL);
+ IO_STATUS_BLOCK IoStatusBlock;
+ FILE_END_OF_FILE_INFORMATION EndOfFileInfo;
+ FILE_ALLOCATION_INFORMATION FileAllocationInfo;
+ FILE_POSITION_INFORMATION FilePosInfo;
+ NTSTATUS Status;
+
+ //get current position
+ Status = NtQueryInformationFile(
+ hFile,
+ &IoStatusBlock,
+ &FilePosInfo,
+ sizeof(FILE_POSITION_INFORMATION),
+ FilePositionInformation
+ );
+
+ if (!NT_SUCCESS(Status)){
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ EndOfFileInfo.EndOfFile.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
+
+ /*
+ NOTE:
+ This call is not supposed to free up any space after the eof marker
+ if the file gets truncated. We have to deallocate the space explicitly afterwards.
+ But...most file systems dispatch both FileEndOfFileInformation
+ and FileAllocationInformation as they were the same command.
+
+ */
+ Status = NtSetInformationFile(
+ hFile,
+ &IoStatusBlock, //out
+ &EndOfFileInfo,
+ sizeof(FILE_END_OF_FILE_INFORMATION),
+ FileEndOfFileInformation
+ );
+
+ if (!NT_SUCCESS(Status)){
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ FileAllocationInfo.AllocationSize.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
+
+
+ Status = NtSetInformationFile(
+ hFile,
+ &IoStatusBlock, //out
+ &FileAllocationInfo,
+ sizeof(FILE_ALLOCATION_INFORMATION),
+ FileAllocationInformation
+ );
+
+ if (!NT_SUCCESS(Status)){
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ return TRUE;
+
}
/* EOF */