-/*
+/* $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
* FILE: lib/kernel32/file/file.c
/* INCLUDES *****************************************************************/
-#include <windows.h>
#include <ddk/ntddk.h>
+#include <windows.h>
#include <wchar.h>
#include <string.h>
#define NDEBUG
#include <kernel32/kernel32.h>
+#include <kernel32/error.h>
#define LPPROGRESS_ROUTINE void*
+
/* GLOBALS ******************************************************************/
-static BOOLEAN bIsFileApiAnsi; // set the file api to ansi or oem
+WINBOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem
+
/* FUNCTIONS ****************************************************************/
-VOID STDCALL SetFileApisToOEM(VOID)
+VOID STDCALL
+SetFileApisToOEM(VOID)
{
- bIsFileApiAnsi = FALSE;
+ bIsFileApiAnsi = FALSE;
}
-VOID STDCALL SetFileApisToANSI(VOID)
+VOID STDCALL
+SetFileApisToANSI(VOID)
{
bIsFileApiAnsi = TRUE;
}
-WINBOOL STDCALL AreFileApisANSI(VOID)
+WINBOOL STDCALL
+AreFileApisANSI(VOID)
{
- return(bIsFileApiAnsi);
+ return bIsFileApiAnsi;
}
-HFILE STDCALL OpenFile(LPCSTR lpFileName,
- LPOFSTRUCT lpReOpenBuff,
- UINT uStyle)
+HFILE STDCALL
+OpenFile(LPCSTR lpFileName,
+ LPOFSTRUCT lpReOpenBuff,
+ UINT uStyle)
{
- NTSTATUS errCode;
- HANDLE FileHandle = NULL;
- UNICODE_STRING FileNameString;
- WCHAR FileNameW[MAX_PATH];
- WCHAR PathNameW[MAX_PATH];
- ULONG i;
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- WCHAR *FilePart;
- ULONG Len;
-
- if (lpReOpenBuff == NULL)
- {
- return FALSE;
- }
-
- i = 0;
- while ((*lpFileName)!=0 && i < MAX_PATH)
- {
- FileNameW[i] = *lpFileName;
- lpFileName++;
- i++;
- }
- FileNameW[i] = 0;
+ 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;
+
+ DPRINT("OpenFile('%s', lpReOpenBuff %x, uStyle %x)\n", lpFileName, lpReOpenBuff, uStyle);
+
+ if (lpReOpenBuff == NULL)
+ {
+ return FALSE;
+ }
+
+ RtlInitAnsiString (&FileName, (LPSTR)lpFileName);
+
+ /* convert ansi (or oem) string to unicode */
+ if (bIsFileApiAnsi)
+ RtlAnsiStringToUnicodeString (&FileNameU, &FileName, TRUE);
+ else
+ RtlOemStringToUnicodeString (&FileNameU, &FileName, TRUE);
- Len = SearchPathW(NULL,FileNameW,NULL,MAX_PATH,PathNameW,&FilePart);
- if ( Len == 0 )
- return (HFILE)NULL;
+ Len = SearchPathW (NULL,
+ FileNameU.Buffer,
+ NULL,
+ OFS_MAXPATHNAME,
+ PathNameW,
+ &FilePart);
- if ( Len > MAX_PATH )
- return (HFILE)NULL;
-
- FileNameString.Length = lstrlenW(PathNameW)*sizeof(WCHAR);
- FileNameString.Buffer = PathNameW;
- FileNameString.MaximumLength = FileNameString.Length+sizeof(WCHAR);
-
- 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 )
- return (HFILE)NULL;
-
- errCode = NtOpenFile(&FileHandle,
- GENERIC_READ|SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- FILE_SHARE_READ,
- FILE_NON_DIRECTORY_FILE);
-
- lpReOpenBuff->nErrCode = RtlNtStatusToDosError(errCode);
-
- if (!NT_SUCCESS(errCode))
- {
- SetLastError(RtlNtStatusToDosError(errCode));
- return (HFILE)INVALID_HANDLE_VALUE;
- }
-
- return (HFILE)FileHandle;
+ RtlFreeUnicodeString(&FileNameU);
+
+ if (Len == 0 || Len > OFS_MAXPATHNAME)
+ {
+ return (HFILE)INVALID_HANDLE_VALUE;
+ }
+
+ 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);
+
+ if (!RtlDosPathNameToNtPathName_U ((LPWSTR)PathNameW,
+ &FileNameString,
+ NULL,
+ NULL))
+ {
+ return (HFILE)INVALID_HANDLE_VALUE;
+ }
+
+ 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)
+ {
+ RtlFreeUnicodeString(&FileNameString);
+ return (HFILE)NULL;
+ }
+
+ errCode = NtOpenFile (&FileHandle,
+ GENERIC_READ|SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ,
+ FILE_NON_DIRECTORY_FILE);
+
+ RtlFreeUnicodeString(&FileNameString);
+
+ lpReOpenBuff->nErrCode = RtlNtStatusToDosError(errCode);
+
+ if (!NT_SUCCESS(errCode))
+ {
+ SetLastErrorByStatus (errCode);
+ return (HFILE)INVALID_HANDLE_VALUE;
+ }
+
+ return (HFILE)FileHandle;
}
-WINBOOL STDCALL FlushFileBuffers(HANDLE hFile)
+WINBOOL STDCALL
+FlushFileBuffers(HANDLE hFile)
{
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
-
+
+ if (IsConsoleHandle(hFile))
+ {
+ return FALSE;
+ }
+
errCode = NtFlushBuffersFile(hFile,
&IoStatusBlock);
- if (!NT_SUCCESS(errCode))
+ if (!NT_SUCCESS(errCode))
{
- SetLastError(RtlNtStatusToDosError(errCode));
+ SetLastErrorByStatus(errCode);
return(FALSE);
}
return(TRUE);
}
-DWORD STDCALL SetFilePointer(HANDLE hFile,
- LONG lDistanceToMove,
- PLONG lpDistanceToMoveHigh,
- DWORD dwMoveMethod)
+DWORD STDCALL
+SetFilePointer(HANDLE hFile,
+ LONG lDistanceToMove,
+ PLONG lpDistanceToMoveHigh,
+ DWORD dwMoveMethod)
{
FILE_POSITION_INFORMATION FilePosition;
- FILE_END_OF_FILE_INFORMATION FileEndOfFile;
+ FILE_STANDARD_INFORMATION FileStandart;
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER Distance;
hFile,lDistanceToMove,dwMoveMethod);
Distance.u.LowPart = lDistanceToMove;
- Distance.u.HighPart = (lpDistanceToMoveHigh) ? *lpDistanceToMoveHigh : 0;
-
- if (dwMoveMethod == FILE_CURRENT)
+ if (lpDistanceToMoveHigh)
+ {
+ Distance.u.HighPart = *lpDistanceToMoveHigh;
+ }
+ else if (lDistanceToMove >= 0)
+ {
+ Distance.u.HighPart = 0;
+ }
+ else
+ {
+ Distance.u.HighPart = -1;
+ }
+
+ if (dwMoveMethod == FILE_CURRENT)
{
NtQueryInformationFile(hFile,
&IoStatusBlock,
- &FilePosition,
+ &FilePosition,
sizeof(FILE_POSITION_INFORMATION),
FilePositionInformation);
- FilePosition.CurrentByteOffset.QuadPart += Distance.QuadPart;
+ FilePosition.CurrentByteOffset.QuadPart += Distance.QuadPart;
}
- else if (dwMoveMethod == FILE_END)
+ else if (dwMoveMethod == FILE_END)
{
NtQueryInformationFile(hFile,
&IoStatusBlock,
- &FileEndOfFile,
- sizeof(FILE_END_OF_FILE_INFORMATION),
- FileEndOfFileInformation);
+ &FileStandart,
+ sizeof(FILE_STANDARD_INFORMATION),
+ FileStandardInformation);
FilePosition.CurrentByteOffset.QuadPart =
- FileEndOfFile.EndOfFile.QuadPart - Distance.QuadPart;
+ FileStandart.EndOfFile.QuadPart + Distance.QuadPart;
}
- else if ( dwMoveMethod == FILE_BEGIN )
+ else if ( dwMoveMethod == FILE_BEGIN )
{
FilePosition.CurrentByteOffset.QuadPart = Distance.QuadPart;
}
errCode = NtSetInformationFile(hFile,
&IoStatusBlock,
- &FilePosition,
+ &FilePosition,
sizeof(FILE_POSITION_INFORMATION),
FilePositionInformation);
- if (!NT_SUCCESS(errCode))
+ if (!NT_SUCCESS(errCode))
{
- SetLastError(RtlNtStatusToDosError(errCode));
+ SetLastErrorByStatus(errCode);
return -1;
}
- if (lpDistanceToMoveHigh != NULL)
+ if (lpDistanceToMoveHigh != NULL)
{
*lpDistanceToMoveHigh = FilePosition.CurrentByteOffset.u.HighPart;
}
}
-DWORD STDCALL GetFileType(HANDLE hFile)
+DWORD STDCALL
+GetFileType(HANDLE hFile)
{
+ FILE_FS_DEVICE_INFORMATION DeviceInfo;
+ IO_STATUS_BLOCK StatusBlock;
+ NTSTATUS Status;
+
+ /* get real handle */
+ switch ((ULONG)hFile)
+ {
+ case STD_INPUT_HANDLE:
+ hFile = NtCurrentPeb()->ProcessParameters->hStdInput;
+
+ break;
+
+ case STD_OUTPUT_HANDLE:
+ hFile = NtCurrentPeb()->ProcessParameters->hStdOutput;
+
+ break;
+
+ case STD_ERROR_HANDLE:
+ hFile = NtCurrentPeb()->ProcessParameters->hStdError;
+
+ break;
+ }
+
+ /* check console handles */
+ if (IsConsoleHandle(hFile))
+ {
+// 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;
+ }
+
return FILE_TYPE_UNKNOWN;
}
-DWORD STDCALL GetFileSize(HANDLE hFile,
- LPDWORD lpFileSizeHigh)
+DWORD STDCALL
+GetFileSize(HANDLE hFile,
+ LPDWORD lpFileSizeHigh)
{
NTSTATUS errCode;
FILE_STANDARD_INFORMATION FileStandard;
errCode = NtQueryInformationFile(hFile,
&IoStatusBlock,
- &FileStandard,
+ &FileStandard,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation);
- if (!NT_SUCCESS(errCode))
+ if (!NT_SUCCESS(errCode))
{
- SetLastError(RtlNtStatusToDosError(errCode));
- if ( lpFileSizeHigh == NULL )
+ SetLastErrorByStatus(errCode);
+ if ( lpFileSizeHigh == NULL )
{
return -1;
}
}
}
if ( lpFileSizeHigh != NULL )
- *lpFileSizeHigh = FileStandard.AllocationSize.u.HighPart;
+ *lpFileSizeHigh = FileStandard.EndOfFile.u.HighPart;
- return FileStandard.AllocationSize.u.LowPart;
+ return FileStandard.EndOfFile.u.LowPart;
}
-DWORD STDCALL GetCompressedFileSizeA(LPCSTR lpFileName,
- LPDWORD lpFileSizeHigh)
+DWORD STDCALL
+GetCompressedFileSizeA(LPCSTR lpFileName,
+ LPDWORD lpFileSizeHigh)
{
- WCHAR FileNameW[MAX_PATH];
- ULONG i;
-
- i = 0;
- while ((*lpFileName)!=0 && i < MAX_PATH)
- {
- FileNameW[i] = *lpFileName;
- lpFileName++;
- i++;
- }
- FileNameW[i] = 0;
-
- return GetCompressedFileSizeW(FileNameW,lpFileSizeHigh);
+ 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;
}
-DWORD STDCALL GetCompressedFileSizeW(LPCWSTR lpFileName,
- LPDWORD lpFileSizeHigh)
+DWORD STDCALL
+GetCompressedFileSizeW(LPCWSTR lpFileName,
+ LPDWORD lpFileSizeHigh)
{
FILE_COMPRESSION_INFORMATION FileCompression;
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE hFile;
- hFile = CreateFileW(lpFileName,
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
+ hFile = CreateFileW(lpFileName,
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
NULL);
errCode = NtQueryInformationFile(hFile,
&IoStatusBlock,
- &FileCompression,
+ &FileCompression,
sizeof(FILE_COMPRESSION_INFORMATION),
FileCompressionInformation);
- if (!NT_SUCCESS(errCode))
+ if (!NT_SUCCESS(errCode))
{
CloseHandle(hFile);
- SetLastError(RtlNtStatusToDosError(errCode));
+ SetLastErrorByStatus(errCode);
return 0;
}
CloseHandle(hFile);
}
-WINBOOL STDCALL GetFileInformationByHandle(HANDLE hFile,
- LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
+WINBOOL STDCALL
+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);
- if (!NT_SUCCESS(errCode))
+ &FileBasic,
+ sizeof(FILE_BASIC_INFORMATION),
+ FileBasicInformation);
+ if (!NT_SUCCESS(errCode))
{
- SetLastError(RtlNtStatusToDosError(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,
+ &FileInternal,
sizeof(FILE_INTERNAL_INFORMATION),
FileInternalInformation);
- if (!NT_SUCCESS(errCode))
+ if (!NT_SUCCESS(errCode))
{
- SetLastError(RtlNtStatusToDosError(errCode));
+ SetLastErrorByStatus(errCode);
return FALSE;
}
lpFileInformation->nFileIndexHigh = FileInternal.IndexNumber.u.HighPart;
lpFileInformation->nFileIndexLow = FileInternal.IndexNumber.u.LowPart;
-
+
errCode = NtQueryVolumeInformationFile(hFile,
&IoStatusBlock,
- &FileFsVolume,
- sizeof(FILE_FS_VOLUME_INFORMATION),
+ &FileFsVolume,
+ sizeof(FileFsVolume),
FileFsVolumeInformation);
- if (!NT_SUCCESS(errCode))
+ if (!NT_SUCCESS(errCode))
{
- SetLastError(RtlNtStatusToDosError(errCode));
+ SetLastErrorByStatus(errCode);
return FALSE;
}
- lpFileInformation->dwVolumeSerialNumber = FileFsVolume.VolumeSerialNumber;
-
+ lpFileInformation->dwVolumeSerialNumber = FileFsVolume.FileFsVolume.VolumeSerialNumber;
+
errCode = NtQueryInformationFile(hFile,
&IoStatusBlock,
- &FileStandard,
+ &FileStandard,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation);
if (!NT_SUCCESS(errCode))
{
- SetLastError(RtlNtStatusToDosError(errCode));
+ SetLastErrorByStatus(errCode);
return FALSE;
}
lpFileInformation->nNumberOfLinks = FileStandard.NumberOfLinks;
+ lpFileInformation->nFileSizeHigh = FileStandard.EndOfFile.u.HighPart;
+ lpFileInformation->nFileSizeLow = FileStandard.EndOfFile.u.LowPart;
return TRUE;
}
-DWORD STDCALL GetFileAttributesA(LPCSTR lpFileName)
+DWORD STDCALL
+GetFileAttributesA(LPCSTR lpFileName)
{
- ULONG i;
- WCHAR FileNameW[MAX_PATH];
-
- i = 0;
- while ((*lpFileName)!=0 && i < MAX_PATH)
- {
- FileNameW[i] = *lpFileName;
- lpFileName++;
- i++;
- }
- FileNameW[i] = 0;
- return GetFileAttributesW(FileNameW);
+ 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);
+
+ RtlFreeUnicodeString (&FileNameU);
+
+ return Result;
}
-DWORD STDCALL GetFileAttributesW(LPCWSTR lpFileName)
+DWORD STDCALL
+GetFileAttributesW(LPCWSTR lpFileName)
{
IO_STATUS_BLOCK IoStatusBlock;
FILE_BASIC_INFORMATION FileBasic;
HANDLE hFile;
NTSTATUS errCode;
- hFile = CreateFileW(lpFileName,
- FILE_READ_ATTRIBUTES,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
+ hFile = CreateFileW(lpFileName,
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
NULL);
-
-
+ if (hFile == INVALID_HANDLE_VALUE)
+ {
+ return 0xFFFFFFFF;
+ }
+
errCode = NtQueryInformationFile(hFile,
&IoStatusBlock,
- &FileBasic,
+ &FileBasic,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
- if (!NT_SUCCESS(errCode))
+ if (!NT_SUCCESS(errCode))
{
CloseHandle(hFile);
- SetLastError(RtlNtStatusToDosError(errCode));
- return 0xFFFFFFFF;
+ SetLastErrorByStatus(errCode);
+ return 0xFFFFFFFF;
}
CloseHandle(hFile);
- return (DWORD)FileBasic.FileAttributes;
+ return (DWORD)FileBasic.FileAttributes;
}
-WINBOOL STDCALL SetFileAttributesA(LPCSTR lpFileName,
- DWORD dwFileAttributes)
+WINBOOL STDCALL
+SetFileAttributesA(LPCSTR lpFileName,
+ DWORD dwFileAttributes)
{
- ULONG i;
- WCHAR FileNameW[MAX_PATH];
- i = 0;
- while ((*lpFileName)!=0 && i < MAX_PATH)
- {
- FileNameW[i] = *lpFileName;
- lpFileName++;
- i++;
- }
- FileNameW[i] = 0;
- return SetFileAttributesW(FileNameW, dwFileAttributes);
+ 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 = SetFileAttributesW(FileNameU.Buffer,
+ dwFileAttributes);
+
+ RtlFreeUnicodeString(&FileNameU);
+
+ return Result;
}
-WINBOOL STDCALL SetFileAttributesW(LPCWSTR lpFileName,
- DWORD dwFileAttributes)
+WINBOOL STDCALL
+SetFileAttributesW(LPCWSTR lpFileName,
+ DWORD dwFileAttributes)
{
IO_STATUS_BLOCK IoStatusBlock;
FILE_BASIC_INFORMATION FileBasic;
HANDLE hFile;
NTSTATUS errCode;
- hFile = CreateFileW(lpFileName,
+ hFile = CreateFileW(lpFileName,
FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
NULL);
errCode = NtQueryInformationFile(hFile,
&IoStatusBlock,
- &FileBasic,
+ &FileBasic,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
- if (!NT_SUCCESS(errCode))
+ if (!NT_SUCCESS(errCode))
{
CloseHandle(hFile);
- SetLastError(RtlNtStatusToDosError(errCode));
+ SetLastErrorByStatus(errCode);
return FALSE;
}
FileBasic.FileAttributes = dwFileAttributes;
errCode = NtSetInformationFile(hFile,
&IoStatusBlock,
- &FileBasic,
+ &FileBasic,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
- if (!NT_SUCCESS(errCode))
+ if (!NT_SUCCESS(errCode))
{
CloseHandle(hFile);
- SetLastError(RtlNtStatusToDosError(errCode));
+ SetLastErrorByStatus(errCode);
return FALSE;
}
CloseHandle(hFile);
- return TRUE;
+ return TRUE;
}
-UINT STDCALL GetTempFileNameA(LPCSTR lpPathName,
- LPCSTR lpPrefixString,
- UINT uUnique,
- LPSTR lpTempFileName)
+UINT STDCALL
+GetTempFileNameA(LPCSTR lpPathName,
+ LPCSTR lpPrefixString,
+ UINT uUnique,
+ LPSTR lpTempFileName)
{
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;
}
-UINT STDCALL GetTempFileNameW(LPCWSTR lpPathName,
- LPCWSTR lpPrefixString,
- UINT uUnique,
- LPWSTR lpTempFileName)
+UINT STDCALL
+GetTempFileNameW(LPCWSTR lpPathName,
+ LPCWSTR lpPrefixString,
+ UINT uUnique,
+ LPWSTR lpTempFileName)
{
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;
}
-WINBOOL STDCALL GetFileTime(HANDLE hFile,
- LPFILETIME lpCreationTime,
- LPFILETIME lpLastAccessTime,
- LPFILETIME lpLastWriteTime)
+WINBOOL STDCALL
+GetFileTime(HANDLE hFile,
+ LPFILETIME lpCreationTime,
+ LPFILETIME lpLastAccessTime,
+ LPFILETIME lpLastWriteTime)
{
IO_STATUS_BLOCK IoStatusBlock;
FILE_BASIC_INFORMATION FileBasic;
- NTSTATUS errCode;
-
- errCode = NtQueryInformationFile(hFile,
- &IoStatusBlock,
- &FileBasic,
- sizeof(FILE_BASIC_INFORMATION),
- FileBasicInformation);
- if (!NT_SUCCESS(errCode))
+ NTSTATUS Status;
+
+ Status = NtQueryInformationFile(hFile,
+ &IoStatusBlock,
+ &FileBasic,
+ sizeof(FILE_BASIC_INFORMATION),
+ FileBasicInformation);
+ if (!NT_SUCCESS(Status))
{
- SetLastError(RtlNtStatusToDosError(errCode));
+ SetLastErrorByStatus(Status);
return FALSE;
}
- memcpy(lpCreationTime,&FileBasic.CreationTime,sizeof(FILETIME));
- memcpy(lpLastAccessTime,&FileBasic.LastAccessTime,sizeof(FILETIME));
- memcpy(lpLastWriteTime,&FileBasic.LastWriteTime,sizeof(FILETIME));
+ if (lpCreationTime)
+ memcpy(lpCreationTime, &FileBasic.CreationTime, sizeof(FILETIME));
+ if (lpLastAccessTime)
+ memcpy(lpLastAccessTime, &FileBasic.LastAccessTime, sizeof(FILETIME));
+ if (lpLastWriteTime)
+ memcpy(lpLastWriteTime, &FileBasic.LastWriteTime, sizeof(FILETIME));
return TRUE;
}
-WINBOOL STDCALL SetFileTime(HANDLE hFile,
- CONST FILETIME *lpCreationTime,
- CONST FILETIME *lpLastAccessTime,
- CONST FILETIME *lpLastWriteTime)
+WINBOOL STDCALL
+SetFileTime(HANDLE hFile,
+ CONST FILETIME *lpCreationTime,
+ CONST FILETIME *lpLastAccessTime,
+ CONST FILETIME *lpLastWriteTime)
{
FILE_BASIC_INFORMATION FileBasic;
IO_STATUS_BLOCK IoStatusBlock;
- NTSTATUS errCode;
-
- memcpy(&FileBasic.CreationTime,lpCreationTime,sizeof(FILETIME));
- memcpy(&FileBasic.LastAccessTime,lpLastAccessTime,sizeof(FILETIME));
- memcpy(&FileBasic.LastWriteTime,lpLastWriteTime,sizeof(FILETIME));
-
- // shoud i initialize changetime ???
-
- errCode = NtSetInformationFile(hFile,
- &IoStatusBlock,
- &FileBasic,
- sizeof(FILE_BASIC_INFORMATION),
- FileBasicInformation);
- if (!NT_SUCCESS(errCode))
+ NTSTATUS Status;
+
+ Status = NtQueryInformationFile(hFile,
+ &IoStatusBlock,
+ &FileBasic,
+ sizeof(FILE_BASIC_INFORMATION),
+ FileBasicInformation);
+ if (!NT_SUCCESS(Status))
{
- SetLastError(RtlNtStatusToDosError(errCode));
+ 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);
return FALSE;
}
}
-WINBOOL STDCALL SetEndOfFile(HANDLE hFile)
+/*
+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 */