2002-12-27 23:50:21 +00:00
|
|
|
/* $Id: file.c,v 1.39 2002/12/27 23:50:21 gvg Exp $
|
2000-06-03 14:47:33 +00:00
|
|
|
*
|
1998-12-04 18:28:13 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS system libraries
|
|
|
|
* FILE: lib/kernel32/file/file.c
|
|
|
|
* PURPOSE: Directory functions
|
|
|
|
* PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
|
1999-02-07 00:37:29 +00:00
|
|
|
* GetTempFileName is modified from WINE [ Alexandre Juiliard ]
|
1998-12-04 18:28:13 +00:00
|
|
|
* UPDATE HISTORY:
|
|
|
|
* Created 01/11/98
|
1996-01-23 01:02:17 +00:00
|
|
|
*/
|
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
/* INCLUDES *****************************************************************/
|
1999-03-19 05:55:55 +00:00
|
|
|
|
2002-09-08 10:23:54 +00:00
|
|
|
#include <ddk/ntddk.h>
|
1999-10-07 23:46:27 +00:00
|
|
|
#include <windows.h>
|
1999-03-19 05:55:55 +00:00
|
|
|
#include <wchar.h>
|
1998-12-04 18:28:13 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
#define NDEBUG
|
1999-02-07 00:37:29 +00:00
|
|
|
#include <kernel32/kernel32.h>
|
2000-06-03 14:47:33 +00:00
|
|
|
#include <kernel32/error.h>
|
1999-02-07 00:37:29 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
|
1999-03-19 05:55:55 +00:00
|
|
|
/* GLOBALS ******************************************************************/
|
1998-12-04 18:28:13 +00:00
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
WINBOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem
|
|
|
|
|
1998-12-04 18:28:13 +00:00
|
|
|
|
1999-03-19 05:55:55 +00:00
|
|
|
/* FUNCTIONS ****************************************************************/
|
1998-12-04 18:28:13 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
VOID STDCALL
|
|
|
|
SetFileApisToOEM(VOID)
|
1996-01-23 01:02:17 +00:00
|
|
|
{
|
2001-07-19 18:42:02 +00:00
|
|
|
bIsFileApiAnsi = FALSE;
|
1996-01-23 01:02:17 +00:00
|
|
|
}
|
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
VOID STDCALL
|
|
|
|
SetFileApisToANSI(VOID)
|
1996-01-23 01:02:17 +00:00
|
|
|
{
|
2001-07-19 18:42:02 +00:00
|
|
|
bIsFileApiAnsi = TRUE;
|
1996-01-23 01:02:17 +00:00
|
|
|
}
|
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
WINBOOL STDCALL
|
|
|
|
AreFileApisANSI(VOID)
|
1996-01-23 01:02:17 +00:00
|
|
|
{
|
2001-07-19 18:42:02 +00:00
|
|
|
return bIsFileApiAnsi;
|
1996-01-23 01:02:17 +00:00
|
|
|
}
|
1998-10-05 04:01:30 +00:00
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
HFILE STDCALL
|
|
|
|
OpenFile(LPCSTR lpFileName,
|
|
|
|
LPOFSTRUCT lpReOpenBuff,
|
|
|
|
UINT uStyle)
|
1998-10-05 04:01:30 +00:00
|
|
|
{
|
2000-03-15 18:30:30 +00:00
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
UNICODE_STRING FileNameString;
|
|
|
|
UNICODE_STRING FileNameU;
|
|
|
|
ANSI_STRING FileName;
|
|
|
|
WCHAR PathNameW[MAX_PATH];
|
|
|
|
HANDLE FileHandle = NULL;
|
|
|
|
NTSTATUS errCode;
|
|
|
|
PWCHAR FilePart;
|
|
|
|
ULONG Len;
|
|
|
|
|
2002-04-01 22:06:51 +00:00
|
|
|
DPRINT("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName, lpReOpenBuff, uStyle);
|
|
|
|
|
2000-03-15 18:30:30 +00:00
|
|
|
if (lpReOpenBuff == NULL)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
1999-04-14 00:52:19 +00:00
|
|
|
|
2002-04-01 22:06:51 +00:00
|
|
|
RtlInitAnsiString (&FileName, (LPSTR)lpFileName);
|
1999-04-14 00:52:19 +00:00
|
|
|
|
2000-03-15 18:30:30 +00:00
|
|
|
/* convert ansi (or oem) string to unicode */
|
|
|
|
if (bIsFileApiAnsi)
|
2002-04-01 22:06:51 +00:00
|
|
|
RtlAnsiStringToUnicodeString (&FileNameU, &FileName, TRUE);
|
2000-03-15 18:30:30 +00:00
|
|
|
else
|
2002-04-01 22:06:51 +00:00
|
|
|
RtlOemStringToUnicodeString (&FileNameU, &FileName, TRUE);
|
2000-03-15 18:30:30 +00:00
|
|
|
|
|
|
|
Len = SearchPathW (NULL,
|
|
|
|
FileNameU.Buffer,
|
|
|
|
NULL,
|
2002-04-01 22:06:51 +00:00
|
|
|
OFS_MAXPATHNAME,
|
2000-03-15 18:30:30 +00:00
|
|
|
PathNameW,
|
|
|
|
&FilePart);
|
|
|
|
|
2002-04-01 22:06:51 +00:00
|
|
|
RtlFreeUnicodeString(&FileNameU);
|
2000-03-15 18:30:30 +00:00
|
|
|
|
2002-04-01 22:06:51 +00:00
|
|
|
if (Len == 0 || Len > OFS_MAXPATHNAME)
|
|
|
|
{
|
|
|
|
return (HFILE)INVALID_HANDLE_VALUE;
|
|
|
|
}
|
2000-03-15 18:30:30 +00:00
|
|
|
|
2002-04-01 22:06:51 +00:00
|
|
|
FileName.Buffer = lpReOpenBuff->szPathName;
|
|
|
|
FileName.Length = 0;
|
|
|
|
FileName.MaximumLength = OFS_MAXPATHNAME;
|
|
|
|
|
|
|
|
RtlInitUnicodeString(&FileNameU, PathNameW);
|
|
|
|
|
|
|
|
/* convert unicode string to ansi (or oem) */
|
|
|
|
if (bIsFileApiAnsi)
|
|
|
|
RtlUnicodeStringToAnsiString (&FileName, &FileNameU, FALSE);
|
|
|
|
else
|
|
|
|
RtlUnicodeStringToOemString (&FileName, &FileNameU, FALSE);
|
2000-03-15 18:30:30 +00:00
|
|
|
|
2002-04-01 22:06:51 +00:00
|
|
|
if (!RtlDosPathNameToNtPathName_U ((LPWSTR)PathNameW,
|
|
|
|
&FileNameString,
|
|
|
|
NULL,
|
|
|
|
NULL))
|
|
|
|
{
|
|
|
|
return (HFILE)INVALID_HANDLE_VALUE;
|
|
|
|
}
|
2000-03-15 18:30:30 +00:00
|
|
|
|
|
|
|
ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
|
|
|
|
ObjectAttributes.RootDirectory = NULL;
|
|
|
|
ObjectAttributes.ObjectName = &FileNameString;
|
|
|
|
ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
|
|
|
|
ObjectAttributes.SecurityDescriptor = NULL;
|
|
|
|
ObjectAttributes.SecurityQualityOfService = NULL;
|
|
|
|
|
|
|
|
// FILE_SHARE_READ
|
|
|
|
// FILE_NO_INTERMEDIATE_BUFFERING
|
|
|
|
|
|
|
|
if ((uStyle & OF_PARSE) == OF_PARSE)
|
2002-04-01 22:06:51 +00:00
|
|
|
{
|
|
|
|
RtlFreeUnicodeString(&FileNameString);
|
2000-03-15 18:30:30 +00:00
|
|
|
return (HFILE)NULL;
|
2002-04-01 22:06:51 +00:00
|
|
|
}
|
2000-03-15 18:30:30 +00:00
|
|
|
|
|
|
|
errCode = NtOpenFile (&FileHandle,
|
|
|
|
GENERIC_READ|SYNCHRONIZE,
|
|
|
|
&ObjectAttributes,
|
|
|
|
&IoStatusBlock,
|
|
|
|
FILE_SHARE_READ,
|
|
|
|
FILE_NON_DIRECTORY_FILE);
|
|
|
|
|
2002-04-01 22:06:51 +00:00
|
|
|
RtlFreeUnicodeString(&FileNameString);
|
|
|
|
|
2000-03-15 18:30:30 +00:00
|
|
|
lpReOpenBuff->nErrCode = RtlNtStatusToDosError(errCode);
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(errCode))
|
|
|
|
{
|
2000-06-03 14:47:33 +00:00
|
|
|
SetLastErrorByStatus (errCode);
|
2000-03-15 18:30:30 +00:00
|
|
|
return (HFILE)INVALID_HANDLE_VALUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (HFILE)FileHandle;
|
1999-04-14 00:52:19 +00:00
|
|
|
}
|
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
WINBOOL STDCALL
|
|
|
|
FlushFileBuffers(HANDLE hFile)
|
1999-04-14 00:52:19 +00:00
|
|
|
{
|
|
|
|
NTSTATUS errCode;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
2000-03-15 18:30:30 +00:00
|
|
|
|
2002-05-07 22:21:47 +00:00
|
|
|
if (IsConsoleHandle(hFile))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
errCode = NtFlushBuffersFile(hFile,
|
|
|
|
&IoStatusBlock);
|
2000-03-15 18:30:30 +00:00
|
|
|
if (!NT_SUCCESS(errCode))
|
1999-02-07 00:37:29 +00:00
|
|
|
{
|
2000-06-03 14:47:33 +00:00
|
|
|
SetLastErrorByStatus(errCode);
|
1999-04-14 00:52:19 +00:00
|
|
|
return(FALSE);
|
1999-02-07 00:37:29 +00:00
|
|
|
}
|
1998-10-05 04:01:30 +00:00
|
|
|
return(TRUE);
|
|
|
|
}
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
SetFilePointer(HANDLE hFile,
|
|
|
|
LONG lDistanceToMove,
|
|
|
|
PLONG lpDistanceToMoveHigh,
|
|
|
|
DWORD dwMoveMethod)
|
1998-10-05 04:01:30 +00:00
|
|
|
{
|
1999-04-14 00:52:19 +00:00
|
|
|
FILE_POSITION_INFORMATION FilePosition;
|
2001-08-06 18:35:15 +00:00
|
|
|
FILE_STANDARD_INFORMATION FileStandart;
|
1998-10-05 04:01:30 +00:00
|
|
|
NTSTATUS errCode;
|
1999-04-14 00:52:19 +00:00
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
1999-05-19 17:57:02 +00:00
|
|
|
LARGE_INTEGER Distance;
|
1999-03-19 05:55:55 +00:00
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
|
|
|
|
hFile,lDistanceToMove,dwMoveMethod);
|
1999-05-19 17:57:02 +00:00
|
|
|
|
|
|
|
Distance.u.LowPart = lDistanceToMove;
|
2002-03-25 21:07:17 +00:00
|
|
|
if (lpDistanceToMoveHigh)
|
|
|
|
{
|
|
|
|
Distance.u.HighPart = *lpDistanceToMoveHigh;
|
|
|
|
}
|
|
|
|
else if (lDistanceToMove >= 0)
|
|
|
|
{
|
|
|
|
Distance.u.HighPart = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Distance.u.HighPart = -1;
|
|
|
|
}
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2000-03-15 18:30:30 +00:00
|
|
|
if (dwMoveMethod == FILE_CURRENT)
|
1998-10-05 04:01:30 +00:00
|
|
|
{
|
1999-04-14 00:52:19 +00:00
|
|
|
NtQueryInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
2000-03-15 18:30:30 +00:00
|
|
|
&FilePosition,
|
1999-04-14 00:52:19 +00:00
|
|
|
sizeof(FILE_POSITION_INFORMATION),
|
|
|
|
FilePositionInformation);
|
2001-07-19 18:42:02 +00:00
|
|
|
FilePosition.CurrentByteOffset.QuadPart += Distance.QuadPart;
|
1998-10-05 04:01:30 +00:00
|
|
|
}
|
2000-03-15 18:30:30 +00:00
|
|
|
else if (dwMoveMethod == FILE_END)
|
1998-10-05 04:01:30 +00:00
|
|
|
{
|
1999-05-19 17:57:02 +00:00
|
|
|
NtQueryInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
2001-08-06 18:35:15 +00:00
|
|
|
&FileStandart,
|
|
|
|
sizeof(FILE_STANDARD_INFORMATION),
|
|
|
|
FileStandardInformation);
|
1999-05-19 17:57:02 +00:00
|
|
|
FilePosition.CurrentByteOffset.QuadPart =
|
2001-08-06 18:35:15 +00:00
|
|
|
FileStandart.EndOfFile.QuadPart + Distance.QuadPart;
|
1998-10-05 04:01:30 +00:00
|
|
|
}
|
2000-03-15 18:30:30 +00:00
|
|
|
else if ( dwMoveMethod == FILE_BEGIN )
|
1999-03-19 05:55:55 +00:00
|
|
|
{
|
1999-05-19 17:57:02 +00:00
|
|
|
FilePosition.CurrentByteOffset.QuadPart = Distance.QuadPart;
|
1998-10-05 04:01:30 +00:00
|
|
|
}
|
1999-03-19 05:55:55 +00:00
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
errCode = NtSetInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
2000-03-15 18:30:30 +00:00
|
|
|
&FilePosition,
|
1999-04-14 00:52:19 +00:00
|
|
|
sizeof(FILE_POSITION_INFORMATION),
|
|
|
|
FilePositionInformation);
|
2000-03-15 18:30:30 +00:00
|
|
|
if (!NT_SUCCESS(errCode))
|
1999-02-07 00:37:29 +00:00
|
|
|
{
|
2000-06-03 14:47:33 +00:00
|
|
|
SetLastErrorByStatus(errCode);
|
1999-04-14 00:52:19 +00:00
|
|
|
return -1;
|
1999-02-07 00:37:29 +00:00
|
|
|
}
|
1999-04-14 00:52:19 +00:00
|
|
|
|
2000-10-01 19:54:57 +00:00
|
|
|
if (lpDistanceToMoveHigh != NULL)
|
1999-04-14 00:52:19 +00:00
|
|
|
{
|
1999-05-11 19:32:15 +00:00
|
|
|
*lpDistanceToMoveHigh = FilePosition.CurrentByteOffset.u.HighPart;
|
1999-04-14 00:52:19 +00:00
|
|
|
}
|
1999-05-11 19:32:15 +00:00
|
|
|
return FilePosition.CurrentByteOffset.u.LowPart;
|
1999-03-19 05:55:55 +00:00
|
|
|
}
|
1999-02-05 19:24:10 +00:00
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
GetFileType(HANDLE hFile)
|
1999-03-19 05:55:55 +00:00
|
|
|
{
|
2000-10-01 19:54:57 +00:00
|
|
|
FILE_FS_DEVICE_INFORMATION DeviceInfo;
|
|
|
|
IO_STATUS_BLOCK StatusBlock;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
/* get real handle */
|
|
|
|
switch ((ULONG)hFile)
|
|
|
|
{
|
|
|
|
case STD_INPUT_HANDLE:
|
2002-11-07 02:52:37 +00:00
|
|
|
hFile = NtCurrentPeb()->ProcessParameters->hStdInput;
|
|
|
|
|
2000-10-01 19:54:57 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case STD_OUTPUT_HANDLE:
|
2002-11-07 02:52:37 +00:00
|
|
|
hFile = NtCurrentPeb()->ProcessParameters->hStdOutput;
|
|
|
|
|
2000-10-01 19:54:57 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case STD_ERROR_HANDLE:
|
2002-11-07 02:52:37 +00:00
|
|
|
hFile = NtCurrentPeb()->ProcessParameters->hStdError;
|
|
|
|
|
2000-10-01 19:54:57 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check console handles */
|
2002-05-07 22:21:47 +00:00
|
|
|
if (IsConsoleHandle(hFile))
|
2000-10-01 19:54:57 +00:00
|
|
|
{
|
|
|
|
// if (VerifyConsoleHandle(hFile))
|
|
|
|
return FILE_TYPE_CHAR;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = NtQueryVolumeInformationFile(hFile,
|
|
|
|
&StatusBlock,
|
|
|
|
&DeviceInfo,
|
|
|
|
sizeof(FILE_FS_DEVICE_INFORMATION),
|
|
|
|
FileFsDeviceInformation);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastErrorByStatus(Status);
|
|
|
|
return FILE_TYPE_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (DeviceInfo.DeviceType)
|
|
|
|
{
|
|
|
|
case FILE_DEVICE_CD_ROM:
|
|
|
|
case FILE_DEVICE_CD_ROM_FILE_SYSTEM:
|
|
|
|
case FILE_DEVICE_CONTROLLER:
|
|
|
|
case FILE_DEVICE_DATALINK:
|
|
|
|
case FILE_DEVICE_DFS:
|
|
|
|
case FILE_DEVICE_DISK:
|
|
|
|
case FILE_DEVICE_DISK_FILE_SYSTEM:
|
|
|
|
case FILE_DEVICE_VIRTUAL_DISK:
|
|
|
|
return FILE_TYPE_DISK;
|
|
|
|
|
|
|
|
case FILE_DEVICE_KEYBOARD:
|
|
|
|
case FILE_DEVICE_MOUSE:
|
|
|
|
case FILE_DEVICE_NULL:
|
|
|
|
case FILE_DEVICE_PARALLEL_PORT:
|
|
|
|
case FILE_DEVICE_PRINTER:
|
|
|
|
case FILE_DEVICE_SERIAL_PORT:
|
|
|
|
case FILE_DEVICE_SCREEN:
|
|
|
|
case FILE_DEVICE_SOUND:
|
|
|
|
case FILE_DEVICE_MODEM:
|
|
|
|
return FILE_TYPE_CHAR;
|
|
|
|
|
|
|
|
case FILE_DEVICE_NAMED_PIPE:
|
|
|
|
return FILE_TYPE_PIPE;
|
|
|
|
}
|
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
return FILE_TYPE_UNKNOWN;
|
1998-10-05 04:01:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
GetFileSize(HANDLE hFile,
|
|
|
|
LPDWORD lpFileSizeHigh)
|
1999-04-14 00:52:19 +00:00
|
|
|
{
|
|
|
|
NTSTATUS errCode;
|
|
|
|
FILE_STANDARD_INFORMATION FileStandard;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
1998-10-05 04:01:30 +00:00
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
errCode = NtQueryInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
2000-10-01 19:54:57 +00:00
|
|
|
&FileStandard,
|
1999-04-14 00:52:19 +00:00
|
|
|
sizeof(FILE_STANDARD_INFORMATION),
|
|
|
|
FileStandardInformation);
|
2000-10-01 19:54:57 +00:00
|
|
|
if (!NT_SUCCESS(errCode))
|
1999-04-14 00:52:19 +00:00
|
|
|
{
|
2000-06-03 14:47:33 +00:00
|
|
|
SetLastErrorByStatus(errCode);
|
2000-10-01 19:54:57 +00:00
|
|
|
if ( lpFileSizeHigh == NULL )
|
1999-04-14 00:52:19 +00:00
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( lpFileSizeHigh != NULL )
|
2002-06-07 16:54:04 +00:00
|
|
|
*lpFileSizeHigh = FileStandard.EndOfFile.u.HighPart;
|
1999-04-14 00:52:19 +00:00
|
|
|
|
2002-06-07 16:54:04 +00:00
|
|
|
return FileStandard.EndOfFile.u.LowPart;
|
1998-10-05 04:01:30 +00:00
|
|
|
}
|
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
GetCompressedFileSizeA(LPCSTR lpFileName,
|
|
|
|
LPDWORD lpFileSizeHigh)
|
1998-10-05 04:01:30 +00:00
|
|
|
{
|
2000-10-01 19:54:57 +00:00
|
|
|
UNICODE_STRING FileNameU;
|
|
|
|
ANSI_STRING FileName;
|
|
|
|
DWORD Size;
|
|
|
|
|
|
|
|
RtlInitAnsiString(&FileName,
|
|
|
|
(LPSTR)lpFileName);
|
|
|
|
|
|
|
|
/* convert ansi (or oem) string to unicode */
|
|
|
|
if (bIsFileApiAnsi)
|
|
|
|
RtlAnsiStringToUnicodeString(&FileNameU,
|
|
|
|
&FileName,
|
|
|
|
TRUE);
|
|
|
|
else
|
|
|
|
RtlOemStringToUnicodeString(&FileNameU,
|
|
|
|
&FileName,
|
|
|
|
TRUE);
|
|
|
|
|
|
|
|
Size = GetCompressedFileSizeW(FileNameU.Buffer,
|
|
|
|
lpFileSizeHigh);
|
|
|
|
|
|
|
|
RtlFreeUnicodeString (&FileNameU);
|
|
|
|
|
|
|
|
return Size;
|
1998-10-05 04:01:30 +00:00
|
|
|
}
|
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
GetCompressedFileSizeW(LPCWSTR lpFileName,
|
|
|
|
LPDWORD lpFileSizeHigh)
|
1998-10-05 04:01:30 +00:00
|
|
|
{
|
1999-04-14 00:52:19 +00:00
|
|
|
FILE_COMPRESSION_INFORMATION FileCompression;
|
|
|
|
NTSTATUS errCode;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
HANDLE hFile;
|
|
|
|
|
2000-10-01 19:54:57 +00:00
|
|
|
hFile = CreateFileW(lpFileName,
|
|
|
|
GENERIC_READ,
|
|
|
|
FILE_SHARE_READ,
|
|
|
|
NULL,
|
|
|
|
OPEN_EXISTING,
|
|
|
|
FILE_ATTRIBUTE_NORMAL,
|
1999-04-14 00:52:19 +00:00
|
|
|
NULL);
|
1998-10-05 04:01:30 +00:00
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
errCode = NtQueryInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
2000-10-01 19:54:57 +00:00
|
|
|
&FileCompression,
|
1999-04-14 00:52:19 +00:00
|
|
|
sizeof(FILE_COMPRESSION_INFORMATION),
|
|
|
|
FileCompressionInformation);
|
2000-10-01 19:54:57 +00:00
|
|
|
if (!NT_SUCCESS(errCode))
|
1999-04-14 00:52:19 +00:00
|
|
|
{
|
|
|
|
CloseHandle(hFile);
|
2000-06-03 14:47:33 +00:00
|
|
|
SetLastErrorByStatus(errCode);
|
1999-04-14 00:52:19 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
CloseHandle(hFile);
|
|
|
|
return 0;
|
1998-10-05 04:01:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
WINBOOL STDCALL
|
|
|
|
GetFileInformationByHandle(HANDLE hFile,
|
|
|
|
LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
|
1998-10-05 04:01:30 +00:00
|
|
|
{
|
2001-11-01 10:35:15 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
FILE_FS_VOLUME_INFORMATION FileFsVolume;
|
|
|
|
WCHAR Name[255];
|
|
|
|
}
|
|
|
|
FileFsVolume;
|
|
|
|
|
|
|
|
FILE_BASIC_INFORMATION FileBasic;
|
1999-04-14 00:52:19 +00:00
|
|
|
FILE_INTERNAL_INFORMATION FileInternal;
|
|
|
|
FILE_STANDARD_INFORMATION FileStandard;
|
1998-10-05 04:01:30 +00:00
|
|
|
NTSTATUS errCode;
|
1999-04-14 00:52:19 +00:00
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
2001-11-01 10:35:15 +00:00
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
errCode = NtQueryInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
2001-11-01 10:35:15 +00:00
|
|
|
&FileBasic,
|
|
|
|
sizeof(FILE_BASIC_INFORMATION),
|
|
|
|
FileBasicInformation);
|
2000-10-01 19:54:57 +00:00
|
|
|
if (!NT_SUCCESS(errCode))
|
1998-10-05 04:01:30 +00:00
|
|
|
{
|
2000-06-03 14:47:33 +00:00
|
|
|
SetLastErrorByStatus(errCode);
|
1998-10-05 04:01:30 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2001-11-01 10:35:15 +00:00
|
|
|
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));
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
errCode = NtQueryInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
2000-10-01 19:54:57 +00:00
|
|
|
&FileInternal,
|
1999-04-14 00:52:19 +00:00
|
|
|
sizeof(FILE_INTERNAL_INFORMATION),
|
|
|
|
FileInternalInformation);
|
2000-10-01 19:54:57 +00:00
|
|
|
if (!NT_SUCCESS(errCode))
|
1998-10-05 04:01:30 +00:00
|
|
|
{
|
2000-06-03 14:47:33 +00:00
|
|
|
SetLastErrorByStatus(errCode);
|
1998-10-05 04:01:30 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
1999-05-19 17:57:02 +00:00
|
|
|
|
1999-05-11 19:32:15 +00:00
|
|
|
lpFileInformation->nFileIndexHigh = FileInternal.IndexNumber.u.HighPart;
|
|
|
|
lpFileInformation->nFileIndexLow = FileInternal.IndexNumber.u.LowPart;
|
2001-11-01 10:35:15 +00:00
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
errCode = NtQueryVolumeInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
2000-10-01 19:54:57 +00:00
|
|
|
&FileFsVolume,
|
2001-11-01 10:35:15 +00:00
|
|
|
sizeof(FileFsVolume),
|
1999-04-14 00:52:19 +00:00
|
|
|
FileFsVolumeInformation);
|
2000-10-01 19:54:57 +00:00
|
|
|
if (!NT_SUCCESS(errCode))
|
1999-04-14 00:52:19 +00:00
|
|
|
{
|
2000-06-03 14:47:33 +00:00
|
|
|
SetLastErrorByStatus(errCode);
|
1999-04-14 00:52:19 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2001-11-01 10:35:15 +00:00
|
|
|
lpFileInformation->dwVolumeSerialNumber = FileFsVolume.FileFsVolume.VolumeSerialNumber;
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
errCode = NtQueryInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
2000-10-01 19:54:57 +00:00
|
|
|
&FileStandard,
|
1999-04-14 00:52:19 +00:00
|
|
|
sizeof(FILE_STANDARD_INFORMATION),
|
|
|
|
FileStandardInformation);
|
|
|
|
if (!NT_SUCCESS(errCode))
|
|
|
|
{
|
2000-06-03 14:47:33 +00:00
|
|
|
SetLastErrorByStatus(errCode);
|
1999-04-14 00:52:19 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
1998-12-04 18:28:13 +00:00
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
lpFileInformation->nNumberOfLinks = FileStandard.NumberOfLinks;
|
2002-05-27 18:23:49 +00:00
|
|
|
lpFileInformation->nFileSizeHigh = FileStandard.EndOfFile.u.HighPart;
|
|
|
|
lpFileInformation->nFileSizeLow = FileStandard.EndOfFile.u.LowPart;
|
1998-12-04 18:28:13 +00:00
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
1998-12-04 18:28:13 +00:00
|
|
|
|
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
GetFileAttributesA(LPCSTR lpFileName)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
2000-03-15 18:30:30 +00:00
|
|
|
UNICODE_STRING FileNameU;
|
|
|
|
ANSI_STRING FileName;
|
|
|
|
WINBOOL Result;
|
|
|
|
|
|
|
|
RtlInitAnsiString (&FileName,
|
|
|
|
(LPSTR)lpFileName);
|
|
|
|
|
|
|
|
/* convert ansi (or oem) string to unicode */
|
|
|
|
if (bIsFileApiAnsi)
|
|
|
|
RtlAnsiStringToUnicodeString (&FileNameU,
|
|
|
|
&FileName,
|
|
|
|
TRUE);
|
|
|
|
else
|
|
|
|
RtlOemStringToUnicodeString (&FileNameU,
|
|
|
|
&FileName,
|
|
|
|
TRUE);
|
|
|
|
|
|
|
|
Result = GetFileAttributesW (FileNameU.Buffer);
|
|
|
|
|
2000-10-01 19:54:57 +00:00
|
|
|
RtlFreeUnicodeString (&FileNameU);
|
2000-03-15 18:30:30 +00:00
|
|
|
|
|
|
|
return Result;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
DWORD STDCALL
|
|
|
|
GetFileAttributesW(LPCWSTR lpFileName)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
1999-04-14 00:52:19 +00:00
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
FILE_BASIC_INFORMATION FileBasic;
|
|
|
|
HANDLE hFile;
|
|
|
|
NTSTATUS errCode;
|
1998-12-04 18:28:13 +00:00
|
|
|
|
1999-12-24 17:16:32 +00:00
|
|
|
hFile = CreateFileW(lpFileName,
|
|
|
|
FILE_READ_ATTRIBUTES,
|
|
|
|
FILE_SHARE_READ,
|
|
|
|
NULL,
|
|
|
|
OPEN_EXISTING,
|
|
|
|
FILE_ATTRIBUTE_NORMAL,
|
1999-04-14 00:52:19 +00:00
|
|
|
NULL);
|
1999-12-24 17:16:32 +00:00
|
|
|
if (hFile == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
return 0xFFFFFFFF;
|
|
|
|
}
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
errCode = NtQueryInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
1999-12-24 17:16:32 +00:00
|
|
|
&FileBasic,
|
1999-04-14 00:52:19 +00:00
|
|
|
sizeof(FILE_BASIC_INFORMATION),
|
|
|
|
FileBasicInformation);
|
1999-12-24 17:16:32 +00:00
|
|
|
if (!NT_SUCCESS(errCode))
|
1999-04-14 00:52:19 +00:00
|
|
|
{
|
1998-12-04 18:28:13 +00:00
|
|
|
CloseHandle(hFile);
|
2000-06-03 14:47:33 +00:00
|
|
|
SetLastErrorByStatus(errCode);
|
1999-12-24 17:16:32 +00:00
|
|
|
return 0xFFFFFFFF;
|
1999-04-14 00:52:19 +00:00
|
|
|
}
|
|
|
|
CloseHandle(hFile);
|
1999-12-24 17:16:32 +00:00
|
|
|
return (DWORD)FileBasic.FileAttributes;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
WINBOOL STDCALL
|
|
|
|
SetFileAttributesA(LPCSTR lpFileName,
|
|
|
|
DWORD dwFileAttributes)
|
1999-01-16 02:11:45 +00:00
|
|
|
{
|
2001-07-19 18:42:02 +00:00
|
|
|
UNICODE_STRING FileNameU;
|
|
|
|
ANSI_STRING FileName;
|
|
|
|
WINBOOL Result;
|
2000-03-15 18:30:30 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
RtlInitAnsiString(&FileName,
|
|
|
|
(LPSTR)lpFileName);
|
2000-03-15 18:30:30 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
/* convert ansi (or oem) string to unicode */
|
|
|
|
if (bIsFileApiAnsi)
|
|
|
|
RtlAnsiStringToUnicodeString(&FileNameU,
|
|
|
|
&FileName,
|
|
|
|
TRUE);
|
|
|
|
else
|
|
|
|
RtlOemStringToUnicodeString(&FileNameU,
|
|
|
|
&FileName,
|
|
|
|
TRUE);
|
2000-03-15 18:30:30 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
Result = SetFileAttributesW(FileNameU.Buffer,
|
|
|
|
dwFileAttributes);
|
2000-03-15 18:30:30 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
RtlFreeUnicodeString(&FileNameU);
|
2000-03-15 18:30:30 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
return Result;
|
1999-01-16 02:11:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
WINBOOL STDCALL
|
|
|
|
SetFileAttributesW(LPCWSTR lpFileName,
|
|
|
|
DWORD dwFileAttributes)
|
1999-01-16 02:11:45 +00:00
|
|
|
{
|
1999-03-19 05:55:55 +00:00
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
FILE_BASIC_INFORMATION FileBasic;
|
|
|
|
HANDLE hFile;
|
|
|
|
NTSTATUS errCode;
|
|
|
|
|
2000-02-18 00:51:03 +00:00
|
|
|
hFile = CreateFileW(lpFileName,
|
1999-03-19 05:55:55 +00:00
|
|
|
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
|
2000-10-01 19:54:57 +00:00
|
|
|
FILE_SHARE_READ,
|
|
|
|
NULL,
|
|
|
|
OPEN_EXISTING,
|
|
|
|
FILE_ATTRIBUTE_NORMAL,
|
1999-03-19 05:55:55 +00:00
|
|
|
NULL);
|
2002-12-27 23:50:21 +00:00
|
|
|
if (INVALID_HANDLE_VALUE == hFile)
|
|
|
|
{
|
|
|
|
DPRINT("SetFileAttributes CreateFileW failed with code %d\n", GetLastError());
|
|
|
|
return FALSE;
|
|
|
|
}
|
1999-03-19 05:55:55 +00:00
|
|
|
|
|
|
|
errCode = NtQueryInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
2000-10-01 19:54:57 +00:00
|
|
|
&FileBasic,
|
1999-03-19 05:55:55 +00:00
|
|
|
sizeof(FILE_BASIC_INFORMATION),
|
|
|
|
FileBasicInformation);
|
2000-10-01 19:54:57 +00:00
|
|
|
if (!NT_SUCCESS(errCode))
|
1999-03-19 05:55:55 +00:00
|
|
|
{
|
1999-01-16 02:11:45 +00:00
|
|
|
CloseHandle(hFile);
|
2002-12-27 23:50:21 +00:00
|
|
|
DPRINT("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", errCode);
|
2000-06-03 14:47:33 +00:00
|
|
|
SetLastErrorByStatus(errCode);
|
1999-03-19 05:55:55 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
FileBasic.FileAttributes = dwFileAttributes;
|
|
|
|
errCode = NtSetInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
2000-10-01 19:54:57 +00:00
|
|
|
&FileBasic,
|
1999-03-19 05:55:55 +00:00
|
|
|
sizeof(FILE_BASIC_INFORMATION),
|
|
|
|
FileBasicInformation);
|
2000-10-01 19:54:57 +00:00
|
|
|
if (!NT_SUCCESS(errCode))
|
1999-03-19 05:55:55 +00:00
|
|
|
{
|
|
|
|
CloseHandle(hFile);
|
2002-12-27 23:50:21 +00:00
|
|
|
DPRINT("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", errCode);
|
2000-06-03 14:47:33 +00:00
|
|
|
SetLastErrorByStatus(errCode);
|
1999-03-19 05:55:55 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
CloseHandle(hFile);
|
2000-10-01 19:54:57 +00:00
|
|
|
return TRUE;
|
1999-01-16 02:11:45 +00:00
|
|
|
}
|
|
|
|
|
1998-12-04 18:28:13 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
UINT STDCALL
|
|
|
|
GetTempFileNameA(LPCSTR lpPathName,
|
|
|
|
LPCSTR lpPrefixString,
|
|
|
|
UINT uUnique,
|
|
|
|
LPSTR lpTempFileName)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
1999-04-14 00:52:19 +00:00
|
|
|
HANDLE hFile;
|
|
|
|
UINT unique = uUnique;
|
2002-04-27 19:15:00 +00:00
|
|
|
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);
|
1998-12-04 18:28:13 +00:00
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
if (lpPathName == NULL)
|
|
|
|
return 0;
|
2002-04-27 19:15:00 +00:00
|
|
|
|
|
|
|
len = strlen(lpPathName);
|
|
|
|
if (len > 0 && (lpPathName[len-1] == '\\' || lpPathName[len-1] == '/'))
|
|
|
|
len--;
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
if (uUnique == 0)
|
|
|
|
uUnique = GetCurrentTime();
|
2002-04-27 19:15:00 +00:00
|
|
|
|
|
|
|
sprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,uUnique);
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
if (unique)
|
|
|
|
return uUnique;
|
|
|
|
|
|
|
|
while ((hFile = CreateFileA(lpTempFileName, GENERIC_WRITE, 0, NULL,
|
|
|
|
CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
|
|
|
|
0)) == INVALID_HANDLE_VALUE)
|
2002-04-27 19:15:00 +00:00
|
|
|
{
|
|
|
|
if (GetLastError() != ERROR_ALREADY_EXISTS)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
sprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,++uUnique);
|
|
|
|
}
|
|
|
|
CloseHandle(hFile);
|
1999-04-14 00:52:19 +00:00
|
|
|
return uUnique;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
UINT STDCALL
|
|
|
|
GetTempFileNameW(LPCWSTR lpPathName,
|
|
|
|
LPCWSTR lpPrefixString,
|
|
|
|
UINT uUnique,
|
|
|
|
LPWSTR lpTempFileName)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
1999-04-14 00:52:19 +00:00
|
|
|
HANDLE hFile;
|
|
|
|
UINT unique = uUnique;
|
2002-04-27 19:15:00 +00:00
|
|
|
UINT len;
|
|
|
|
const WCHAR *format = L"%.*S\\~%.3S%4.4x.TMP";
|
1999-04-14 00:52:19 +00:00
|
|
|
|
2002-04-27 19:15:00 +00:00
|
|
|
DPRINT("GetTempFileNameW(lpPathName %S, lpPrefixString %.*S, "
|
|
|
|
"uUnique %x, lpTempFileName %x)\n", lpPathName, 4,
|
|
|
|
lpPrefixString, uUnique, lpTempFileName);
|
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
if (lpPathName == NULL)
|
|
|
|
return 0;
|
2002-04-27 19:15:00 +00:00
|
|
|
|
|
|
|
len = wcslen(lpPathName);
|
|
|
|
if (len > 0 && (lpPathName[len-1] == L'\\' || lpPathName[len-1] == L'/'))
|
|
|
|
len--;
|
1999-04-14 00:52:19 +00:00
|
|
|
|
|
|
|
if (uUnique == 0)
|
|
|
|
uUnique = GetCurrentTime();
|
|
|
|
|
2002-04-27 19:15:00 +00:00
|
|
|
swprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,uUnique);
|
1999-04-14 00:52:19 +00:00
|
|
|
|
|
|
|
if (unique)
|
|
|
|
return uUnique;
|
1998-12-04 18:28:13 +00:00
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
while ((hFile = CreateFileW(lpTempFileName, GENERIC_WRITE, 0, NULL,
|
|
|
|
CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
|
|
|
|
0)) == INVALID_HANDLE_VALUE)
|
2002-04-27 19:15:00 +00:00
|
|
|
{
|
|
|
|
if (GetLastError() != ERROR_ALREADY_EXISTS)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
swprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,++uUnique);
|
|
|
|
}
|
|
|
|
CloseHandle(hFile);
|
1999-04-14 00:52:19 +00:00
|
|
|
return uUnique;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
WINBOOL STDCALL
|
|
|
|
GetFileTime(HANDLE hFile,
|
|
|
|
LPFILETIME lpCreationTime,
|
|
|
|
LPFILETIME lpLastAccessTime,
|
|
|
|
LPFILETIME lpLastWriteTime)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
1999-04-14 00:52:19 +00:00
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
FILE_BASIC_INFORMATION FileBasic;
|
2001-07-19 18:42:02 +00:00
|
|
|
NTSTATUS Status;
|
2000-10-01 19:54:57 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
Status = NtQueryInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
|
|
|
&FileBasic,
|
|
|
|
sizeof(FILE_BASIC_INFORMATION),
|
|
|
|
FileBasicInformation);
|
|
|
|
if (!NT_SUCCESS(Status))
|
1999-04-14 00:52:19 +00:00
|
|
|
{
|
2001-07-19 18:42:02 +00:00
|
|
|
SetLastErrorByStatus(Status);
|
1999-04-14 00:52:19 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
if (lpCreationTime)
|
|
|
|
memcpy(lpCreationTime, &FileBasic.CreationTime, sizeof(FILETIME));
|
|
|
|
if (lpLastAccessTime)
|
|
|
|
memcpy(lpLastAccessTime, &FileBasic.LastAccessTime, sizeof(FILETIME));
|
|
|
|
if (lpLastWriteTime)
|
|
|
|
memcpy(lpLastWriteTime, &FileBasic.LastWriteTime, sizeof(FILETIME));
|
1999-05-19 17:57:02 +00:00
|
|
|
|
1999-04-14 00:52:19 +00:00
|
|
|
return TRUE;
|
1998-12-04 18:28:13 +00:00
|
|
|
}
|
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2001-07-19 18:42:02 +00:00
|
|
|
WINBOOL STDCALL
|
|
|
|
SetFileTime(HANDLE hFile,
|
|
|
|
CONST FILETIME *lpCreationTime,
|
|
|
|
CONST FILETIME *lpLastAccessTime,
|
|
|
|
CONST FILETIME *lpLastWriteTime)
|
1998-12-04 18:28:13 +00:00
|
|
|
{
|
1999-04-14 00:52:19 +00:00
|
|
|
FILE_BASIC_INFORMATION FileBasic;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
2001-07-19 18:42:02 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Status = NtQueryInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
|
|
|
&FileBasic,
|
|
|
|
sizeof(FILE_BASIC_INFORMATION),
|
|
|
|
FileBasicInformation);
|
|
|
|
if (!NT_SUCCESS(Status))
|
1999-04-14 00:52:19 +00:00
|
|
|
{
|
2001-07-19 18:42:02 +00:00
|
|
|
SetLastErrorByStatus(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lpCreationTime)
|
|
|
|
memcpy(&FileBasic.CreationTime, lpCreationTime, sizeof(FILETIME));
|
|
|
|
if (lpLastAccessTime)
|
|
|
|
memcpy(&FileBasic.LastAccessTime, lpLastAccessTime, sizeof(FILETIME));
|
|
|
|
if (lpLastWriteTime)
|
|
|
|
memcpy(&FileBasic.LastWriteTime, lpLastWriteTime, sizeof(FILETIME));
|
|
|
|
|
|
|
|
// should i initialize changetime ???
|
|
|
|
|
|
|
|
Status = NtSetInformationFile(hFile,
|
|
|
|
&IoStatusBlock,
|
|
|
|
&FileBasic,
|
|
|
|
sizeof(FILE_BASIC_INFORMATION),
|
|
|
|
FileBasicInformation);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastErrorByStatus(Status);
|
1999-04-14 00:52:19 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
1998-12-08 16:51:47 +00:00
|
|
|
}
|
1999-01-16 02:11:45 +00:00
|
|
|
|
1999-05-19 17:57:02 +00:00
|
|
|
|
2002-11-07 02:52:37 +00:00
|
|
|
/*
|
|
|
|
The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
|
|
|
|
*/
|
2001-07-19 18:42:02 +00:00
|
|
|
WINBOOL STDCALL
|
|
|
|
SetEndOfFile(HANDLE hFile)
|
1999-01-16 02:11:45 +00:00
|
|
|
{
|
2002-11-07 02:52:37 +00:00
|
|
|
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;
|
|
|
|
|
1999-01-16 02:11:45 +00:00
|
|
|
}
|
2000-03-15 18:30:30 +00:00
|
|
|
|
|
|
|
/* EOF */
|