-/* $Id: file.c,v 1.38 2002/11/07 02:52:37 robd Exp $
+/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
/* INCLUDES *****************************************************************/
-#include <ddk/ntddk.h>
-#include <windows.h>
-#include <wchar.h>
-#include <string.h>
+#include <k32.h>
#define NDEBUG
-#include <kernel32/kernel32.h>
-#include <kernel32/error.h>
-
-#define LPPROGRESS_ROUTINE void*
+#include "../include/debug.h"
/* GLOBALS ******************************************************************/
-WINBOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem
-
+BOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem
/* FUNCTIONS ****************************************************************/
-VOID STDCALL
+
+
+PWCHAR
+FilenameA2W(LPCSTR NameA, BOOL alloc)
+{
+ ANSI_STRING str;
+ UNICODE_STRING strW;
+ PUNICODE_STRING pstrW;
+ NTSTATUS Status;
+
+ ASSERT(NtCurrentTeb()->StaticUnicodeString.Buffer == NtCurrentTeb()->StaticUnicodeBuffer);
+ ASSERT(NtCurrentTeb()->StaticUnicodeString.MaximumLength == sizeof(NtCurrentTeb()->StaticUnicodeBuffer));
+
+ RtlInitAnsiString(&str, NameA);
+ pstrW = alloc ? &strW : &NtCurrentTeb()->StaticUnicodeString;
+
+ if (bIsFileApiAnsi)
+ Status= RtlAnsiStringToUnicodeString( pstrW, &str, alloc );
+ else
+ Status= RtlOemStringToUnicodeString( pstrW, &str, alloc );
+
+ if (NT_SUCCESS(Status))
+ return pstrW->Buffer;
+
+ if (Status== STATUS_BUFFER_OVERFLOW)
+ SetLastError( ERROR_FILENAME_EXCED_RANGE );
+ else
+ SetLastErrorByStatus(Status);
+
+ return NULL;
+}
+
+
+/*
+No copy/conversion is done if the dest. buffer is too small.
+
+Returns:
+ Success: number of TCHARS copied into dest. buffer NOT including nullterm
+ Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
+*/
+DWORD
+FilenameU2A_FitOrFail(
+ LPSTR DestA,
+ INT destLen, /* buffer size in TCHARS incl. nullchar */
+ PUNICODE_STRING SourceU
+ )
+{
+ DWORD ret;
+
+ ret = bIsFileApiAnsi? RtlUnicodeStringToAnsiSize(SourceU) : RtlUnicodeStringToOemSize(SourceU);
+ /* ret incl. nullchar */
+
+ if (DestA && (INT)ret <= destLen)
+ {
+ ANSI_STRING str;
+
+ str.Buffer = DestA;
+ str.MaximumLength = destLen;
+
+
+ if (bIsFileApiAnsi)
+ RtlUnicodeStringToAnsiString(&str, SourceU, FALSE );
+ else
+ RtlUnicodeStringToOemString(&str, SourceU, FALSE );
+
+ ret = str.Length; /* SUCCESS: length without terminating 0 */
+ }
+
+ return ret;
+}
+
+
+/*
+No copy/conversion is done if the dest. buffer is too small.
+
+Returns:
+ Success: number of TCHARS copied into dest. buffer NOT including nullterm
+ Fail: size of buffer in TCHARS required to hold the converted filename, including nullterm
+*/
+DWORD
+FilenameW2A_FitOrFail(
+ LPSTR DestA,
+ INT destLen, /* buffer size in TCHARS incl. nullchar */
+ LPCWSTR SourceW,
+ INT sourceLen /* buffer size in TCHARS incl. nullchar */
+ )
+{
+ UNICODE_STRING strW;
+
+ if (sourceLen < 0) sourceLen = wcslen(SourceW) + 1;
+
+ strW.Buffer = (PWCHAR)SourceW;
+ strW.MaximumLength = sourceLen * sizeof(WCHAR);
+ strW.Length = strW.MaximumLength - sizeof(WCHAR);
+
+ return FilenameU2A_FitOrFail(DestA, destLen, &strW);
+}
+
+
+/*
+Return: num. TCHARS copied into dest including nullterm
+*/
+DWORD
+FilenameA2W_N(
+ LPWSTR dest,
+ INT destlen, /* buffer size in TCHARS incl. nullchar */
+ LPCSTR src,
+ INT srclen /* buffer size in TCHARS incl. nullchar */
+ )
+{
+ DWORD ret;
+
+ if (srclen < 0) srclen = strlen( src ) + 1;
+
+ if (bIsFileApiAnsi)
+ RtlMultiByteToUnicodeN( dest, destlen* sizeof(WCHAR), &ret, (LPSTR)src, srclen );
+ else
+ RtlOemToUnicodeN( dest, destlen* sizeof(WCHAR), &ret, (LPSTR)src, srclen );
+
+ if (ret) dest[(ret/sizeof(WCHAR))-1]=0;
+
+ return ret/sizeof(WCHAR);
+}
+
+/*
+Return: num. TCHARS copied into dest including nullterm
+*/
+DWORD
+FilenameW2A_N(
+ LPSTR dest,
+ INT destlen, /* buffer size in TCHARS incl. nullchar */
+ LPCWSTR src,
+ INT srclen /* buffer size in TCHARS incl. nullchar */
+ )
+{
+ DWORD ret;
+
+ if (srclen < 0) srclen = wcslen( src ) + 1;
+
+ if (bIsFileApiAnsi)
+ RtlUnicodeToMultiByteN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR));
+ else
+ RtlUnicodeToOemN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR) );
+
+ if (ret) dest[ret-1]=0;
+
+ return ret;
+}
+
+
+/*
+ * @implemented
+ */
+VOID
+STDCALL
SetFileApisToOEM(VOID)
{
- bIsFileApiAnsi = FALSE;
+ /* Set the correct Base Api */
+ Basep8BitStringToUnicodeString = (PRTL_CONVERT_STRING)RtlOemStringToUnicodeString;
+
+ /* FIXME: Old, deprecated way */
+ bIsFileApiAnsi = FALSE;
}
-VOID STDCALL
+/*
+ * @implemented
+ */
+VOID
+STDCALL
SetFileApisToANSI(VOID)
{
- bIsFileApiAnsi = TRUE;
+ /* Set the correct Base Api */
+ Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString;
+
+ /* FIXME: Old, deprecated way */
+ bIsFileApiAnsi = TRUE;
}
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
AreFileApisANSI(VOID)
{
return bIsFileApiAnsi;
}
+/*
+ * @implemented
+ */
HFILE STDCALL
OpenFile(LPCSTR lpFileName,
LPOFSTRUCT lpReOpenBuff,
return FALSE;
}
+ if ((uStyle & OF_CREATE) == OF_CREATE)
+ {
+ DWORD Sharing;
+ switch (uStyle & 0x70)
+ {
+ case OF_SHARE_EXCLUSIVE: Sharing = 0; break;
+ case OF_SHARE_DENY_WRITE: Sharing = FILE_SHARE_READ; break;
+ case OF_SHARE_DENY_READ: Sharing = FILE_SHARE_WRITE; break;
+ case OF_SHARE_DENY_NONE:
+ case OF_SHARE_COMPAT:
+ default:
+ Sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ }
+ return (HFILE) CreateFileA (lpFileName,
+ GENERIC_READ | GENERIC_WRITE,
+ Sharing,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ 0);
+ }
+
RtlInitAnsiString (&FileName, (LPSTR)lpFileName);
/* convert ansi (or oem) string to unicode */
Len = SearchPathW (NULL,
FileNameU.Buffer,
- NULL,
+ NULL,
OFS_MAXPATHNAME,
PathNameW,
- &FilePart);
+ &FilePart);
RtlFreeUnicodeString(&FileNameU);
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
return (HFILE)NULL;
}
+ ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
+ ObjectAttributes.RootDirectory = NULL;
+ ObjectAttributes.ObjectName = &FileNameString;
+ ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
+ ObjectAttributes.SecurityDescriptor = NULL;
+ ObjectAttributes.SecurityQualityOfService = NULL;
+
errCode = NtOpenFile (&FileHandle,
GENERIC_READ|SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_READ,
- FILE_NON_DIRECTORY_FILE);
+ FILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT);
RtlFreeUnicodeString(&FileNameString);
}
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
FlushFileBuffers(HANDLE hFile)
{
NTSTATUS errCode;
}
+/*
+ * @implemented
+ */
DWORD STDCALL
SetFilePointer(HANDLE hFile,
LONG lDistanceToMove,
DWORD dwMoveMethod)
{
FILE_POSITION_INFORMATION FilePosition;
- FILE_STANDARD_INFORMATION FileStandart;
+ FILE_STANDARD_INFORMATION FileStandard;
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER Distance;
-
+
DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
hFile,lDistanceToMove,dwMoveMethod);
+ if(IsConsoleHandle(hFile))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return -1;
+ }
+
Distance.u.LowPart = lDistanceToMove;
if (lpDistanceToMoveHigh)
{
Distance.u.HighPart = -1;
}
- if (dwMoveMethod == FILE_CURRENT)
- {
+ switch(dwMoveMethod)
+ {
+ case FILE_CURRENT:
NtQueryInformationFile(hFile,
&IoStatusBlock,
&FilePosition,
sizeof(FILE_POSITION_INFORMATION),
FilePositionInformation);
FilePosition.CurrentByteOffset.QuadPart += Distance.QuadPart;
- }
- else if (dwMoveMethod == FILE_END)
- {
+ break;
+ case FILE_END:
NtQueryInformationFile(hFile,
&IoStatusBlock,
- &FileStandart,
+ &FileStandard,
sizeof(FILE_STANDARD_INFORMATION),
FileStandardInformation);
FilePosition.CurrentByteOffset.QuadPart =
- FileStandart.EndOfFile.QuadPart + Distance.QuadPart;
- }
- else if ( dwMoveMethod == FILE_BEGIN )
- {
+ FileStandard.EndOfFile.QuadPart + Distance.QuadPart;
+ break;
+ case FILE_BEGIN:
FilePosition.CurrentByteOffset.QuadPart = Distance.QuadPart;
- }
-
+ break;
+ default:
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return -1;
+ }
+
+ if(FilePosition.CurrentByteOffset.QuadPart < 0)
+ {
+ SetLastError(ERROR_NEGATIVE_SEEK);
+ return -1;
+ }
+
errCode = NtSetInformationFile(hFile,
&IoStatusBlock,
&FilePosition,
SetLastErrorByStatus(errCode);
return -1;
}
-
+
if (lpDistanceToMoveHigh != NULL)
{
*lpDistanceToMoveHigh = FilePosition.CurrentByteOffset.u.HighPart;
}
-DWORD STDCALL
-GetFileType(HANDLE hFile)
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+SetFilePointerEx(HANDLE hFile,
+ LARGE_INTEGER liDistanceToMove,
+ PLARGE_INTEGER lpNewFilePointer,
+ DWORD dwMoveMethod)
{
- 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;
+ FILE_POSITION_INFORMATION FilePosition;
+ FILE_STANDARD_INFORMATION FileStandard;
+ NTSTATUS errCode;
+ IO_STATUS_BLOCK IoStatusBlock;
- break;
+ if(IsConsoleHandle(hFile))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
- case STD_ERROR_HANDLE:
- hFile = NtCurrentPeb()->ProcessParameters->hStdError;
+ switch(dwMoveMethod)
+ {
+ case FILE_CURRENT:
+ NtQueryInformationFile(hFile,
+ &IoStatusBlock,
+ &FilePosition,
+ sizeof(FILE_POSITION_INFORMATION),
+ FilePositionInformation);
+ FilePosition.CurrentByteOffset.QuadPart += liDistanceToMove.QuadPart;
+ break;
+ case FILE_END:
+ NtQueryInformationFile(hFile,
+ &IoStatusBlock,
+ &FileStandard,
+ sizeof(FILE_STANDARD_INFORMATION),
+ FileStandardInformation);
+ FilePosition.CurrentByteOffset.QuadPart =
+ FileStandard.EndOfFile.QuadPart + liDistanceToMove.QuadPart;
+ break;
+ case FILE_BEGIN:
+ FilePosition.CurrentByteOffset.QuadPart = liDistanceToMove.QuadPart;
+ break;
+ default:
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
- break;
- }
+ if(FilePosition.CurrentByteOffset.QuadPart < 0)
+ {
+ SetLastError(ERROR_NEGATIVE_SEEK);
+ return FALSE;
+ }
- /* check console handles */
- if (IsConsoleHandle(hFile))
+ errCode = NtSetInformationFile(hFile,
+ &IoStatusBlock,
+ &FilePosition,
+ sizeof(FILE_POSITION_INFORMATION),
+ FilePositionInformation);
+ if (!NT_SUCCESS(errCode))
{
-// if (VerifyConsoleHandle(hFile))
- return FILE_TYPE_CHAR;
+ SetLastErrorByStatus(errCode);
+ return FALSE;
}
- Status = NtQueryVolumeInformationFile(hFile,
- &StatusBlock,
- &DeviceInfo,
- sizeof(FILE_FS_DEVICE_INFORMATION),
- FileFsDeviceInformation);
- if (!NT_SUCCESS(Status))
+ if (lpNewFilePointer)
{
- SetLastErrorByStatus(Status);
- return FILE_TYPE_UNKNOWN;
+ *lpNewFilePointer = FilePosition.CurrentByteOffset;
}
+ return TRUE;
+}
- 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;
+/*
+ * @implemented
+ */
+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->StandardInput;
+ break;
+
+ case STD_OUTPUT_HANDLE:
+ hFile = NtCurrentPeb()->ProcessParameters->StandardOutput;
+ break;
+
+ case STD_ERROR_HANDLE:
+ hFile = NtCurrentPeb()->ProcessParameters->StandardError;
+ break;
+ }
+
+ /* Check for console handle */
+ if (IsConsoleHandle(hFile))
+ {
+ if (VerifyConsoleIoHandle(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;
}
+/*
+ * @implemented
+ */
DWORD STDCALL
GetFileSize(HANDLE hFile,
LPDWORD lpFileSizeHigh)
}
-DWORD STDCALL
-GetCompressedFileSizeA(LPCSTR lpFileName,
- LPDWORD lpFileSizeHigh)
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+GetFileSizeEx(
+ HANDLE hFile,
+ PLARGE_INTEGER lpFileSize
+ )
{
- UNICODE_STRING FileNameU;
- ANSI_STRING FileName;
- DWORD Size;
+ NTSTATUS errCode;
+ FILE_STANDARD_INFORMATION FileStandard;
+ IO_STATUS_BLOCK IoStatusBlock;
- RtlInitAnsiString(&FileName,
- (LPSTR)lpFileName);
+ errCode = NtQueryInformationFile(hFile,
+ &IoStatusBlock,
+ &FileStandard,
+ sizeof(FILE_STANDARD_INFORMATION),
+ FileStandardInformation);
+ if (!NT_SUCCESS(errCode))
+ {
+ SetLastErrorByStatus(errCode);
+ return FALSE;
+ }
+ if (lpFileSize)
+ *lpFileSize = FileStandard.EndOfFile;
- /* convert ansi (or oem) string to unicode */
- if (bIsFileApiAnsi)
- RtlAnsiStringToUnicodeString(&FileNameU,
- &FileName,
- TRUE);
- else
- RtlOemStringToUnicodeString(&FileNameU,
- &FileName,
- TRUE);
+ return TRUE;
+}
- Size = GetCompressedFileSizeW(FileNameU.Buffer,
- lpFileSizeHigh);
- RtlFreeUnicodeString (&FileNameU);
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetCompressedFileSizeA(LPCSTR lpFileName,
+ LPDWORD lpFileSizeHigh)
+{
+ PWCHAR FileNameW;
+
+ if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+ return INVALID_FILE_SIZE;
- return Size;
+ return GetCompressedFileSizeW(FileNameW, lpFileSizeHigh);
}
+/*
+ * @implemented
+ */
DWORD STDCALL
GetCompressedFileSizeW(LPCWSTR lpFileName,
LPDWORD lpFileSizeHigh)
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE hFile;
-
+
hFile = CreateFileW(lpFileName,
GENERIC_READ,
FILE_SHARE_READ,
FILE_ATTRIBUTE_NORMAL,
NULL);
+ if (hFile == INVALID_HANDLE_VALUE)
+ return INVALID_FILE_SIZE;
+
errCode = NtQueryInformationFile(hFile,
&IoStatusBlock,
&FileCompression,
sizeof(FILE_COMPRESSION_INFORMATION),
FileCompressionInformation);
+
+ CloseHandle(hFile);
+
if (!NT_SUCCESS(errCode))
{
- CloseHandle(hFile);
SetLastErrorByStatus(errCode);
- return 0;
+ return INVALID_FILE_SIZE;
}
- CloseHandle(hFile);
- return 0;
+
+ if(lpFileSizeHigh)
+ *lpFileSizeHigh = FileCompression.CompressedFileSize.u.HighPart;
+
+ SetLastError(NO_ERROR);
+ return FileCompression.CompressedFileSize.u.LowPart;
}
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
GetFileInformationByHandle(HANDLE hFile,
LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
{
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
+ if(IsConsoleHandle(hFile))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
errCode = NtQueryInformationFile(hFile,
&IoStatusBlock,
&FileBasic,
}
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));
+
+ lpFileInformation->ftCreationTime.dwHighDateTime = FileBasic.CreationTime.u.HighPart;
+ lpFileInformation->ftCreationTime.dwLowDateTime = FileBasic.CreationTime.u.LowPart;
+
+ lpFileInformation->ftLastAccessTime.dwHighDateTime = FileBasic.LastAccessTime.u.HighPart;
+ lpFileInformation->ftLastAccessTime.dwLowDateTime = FileBasic.LastAccessTime.u.LowPart;
+
+ lpFileInformation->ftLastWriteTime.dwHighDateTime = FileBasic.LastWriteTime.u.HighPart;
+ lpFileInformation->ftLastWriteTime.dwLowDateTime = FileBasic.LastWriteTime.u.LowPart;
errCode = NtQueryInformationFile(hFile,
&IoStatusBlock,
}
-DWORD STDCALL
-GetFileAttributesA(LPCSTR lpFileName)
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetFileAttributesExW(LPCWSTR lpFileName,
+ GET_FILEEX_INFO_LEVELS fInfoLevelId,
+ LPVOID lpFileInformation)
{
- UNICODE_STRING FileNameU;
- ANSI_STRING FileName;
- WINBOOL Result;
+ FILE_NETWORK_OPEN_INFORMATION FileInformation;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING FileName;
+ HANDLE FileHandle;
+ NTSTATUS Status;
+ WIN32_FILE_ATTRIBUTE_DATA* FileAttributeData;
+
+ DPRINT("GetFileAttributesExW(%S) called\n", lpFileName);
+
+
+ if (fInfoLevelId != GetFileExInfoStandard || lpFileInformation == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ /* Validate and translate the filename */
+ if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName,
+ &FileName,
+ NULL,
+ NULL))
+ {
+ DPRINT1 ("Invalid path\n");
+ SetLastError (ERROR_BAD_PATHNAME);
+ return FALSE;
+ }
- RtlInitAnsiString (&FileName,
- (LPSTR)lpFileName);
+ /* build the object attributes */
+ InitializeObjectAttributes (&ObjectAttributes,
+ &FileName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ /* Open the file */
- /* convert ansi (or oem) string to unicode */
- if (bIsFileApiAnsi)
- RtlAnsiStringToUnicodeString (&FileNameU,
- &FileName,
- TRUE);
- else
- RtlOemStringToUnicodeString (&FileNameU,
- &FileName,
- TRUE);
- Result = GetFileAttributesW (FileNameU.Buffer);
+ Status = NtOpenFile (&FileHandle,
+ SYNCHRONIZE | GENERIC_ALL,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ FILE_SYNCHRONOUS_IO_NONALERT);
- RtlFreeUnicodeString (&FileNameU);
- return Result;
+
+
+ RtlFreeUnicodeString (&FileName);
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT ("NtOpenFile() failed %x (Status %lx)\n", &ObjectAttributes, Status);
+ SetLastErrorByStatus (Status);
+ return FALSE;
+ }
+
+ /* Get file attributes */
+ Status = NtQueryInformationFile (FileHandle,
+ &IoStatusBlock,
+ &FileInformation,
+ sizeof(FILE_NETWORK_OPEN_INFORMATION),
+ FileNetworkOpenInformation);
+ NtClose (FileHandle);
+
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT1 ("NtQueryInformationFile() failed (Status %lx)\n", Status);
+ SetLastErrorByStatus (Status);
+ return FALSE;
+ }
+
+ FileAttributeData = (WIN32_FILE_ATTRIBUTE_DATA*)lpFileInformation;
+ FileAttributeData->dwFileAttributes = FileInformation.FileAttributes;
+ FileAttributeData->ftCreationTime.dwLowDateTime = FileInformation.CreationTime.u.LowPart;
+ FileAttributeData->ftCreationTime.dwHighDateTime = FileInformation.CreationTime.u.HighPart;
+ FileAttributeData->ftLastAccessTime.dwLowDateTime = FileInformation.LastAccessTime.u.LowPart;
+ FileAttributeData->ftLastAccessTime.dwHighDateTime = FileInformation.LastAccessTime.u.HighPart;
+ FileAttributeData->ftLastWriteTime.dwLowDateTime = FileInformation.LastWriteTime.u.LowPart;
+ FileAttributeData->ftLastWriteTime.dwHighDateTime = FileInformation.LastWriteTime.u.HighPart;
+ FileAttributeData->nFileSizeLow = FileInformation.EndOfFile.u.LowPart;
+ FileAttributeData->nFileSizeHigh = FileInformation.EndOfFile.u.HighPart;
+
+ return TRUE;
}
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetFileAttributesExA(LPCSTR lpFileName,
+ GET_FILEEX_INFO_LEVELS fInfoLevelId,
+ LPVOID lpFileInformation)
+{
+ PWCHAR FileNameW;
+ if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+ return FALSE;
+
+ return GetFileAttributesExW(FileNameW, fInfoLevelId, lpFileInformation);
+}
+
+
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetFileAttributesA(LPCSTR lpFileName)
+{
+ WIN32_FILE_ATTRIBUTE_DATA FileAttributeData;
+ PWSTR FileNameW;
+ BOOL ret;
+
+ if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+ return INVALID_FILE_ATTRIBUTES;
+
+ ret = GetFileAttributesExW(FileNameW, GetFileExInfoStandard, &FileAttributeData);
+
+ return ret ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES;
+}
+
+
+/*
+ * @implemented
+ */
DWORD STDCALL
GetFileAttributesW(LPCWSTR lpFileName)
{
- IO_STATUS_BLOCK IoStatusBlock;
- FILE_BASIC_INFORMATION FileBasic;
- HANDLE hFile;
- NTSTATUS errCode;
+ WIN32_FILE_ATTRIBUTE_DATA FileAttributeData;
+ BOOL Result;
- hFile = CreateFileW(lpFileName,
- FILE_READ_ATTRIBUTES,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- if (hFile == INVALID_HANDLE_VALUE)
- {
- return 0xFFFFFFFF;
- }
+ DPRINT ("GetFileAttributeW(%S) called\n", lpFileName);
- errCode = NtQueryInformationFile(hFile,
- &IoStatusBlock,
- &FileBasic,
- sizeof(FILE_BASIC_INFORMATION),
- FileBasicInformation);
- if (!NT_SUCCESS(errCode))
- {
- CloseHandle(hFile);
- SetLastErrorByStatus(errCode);
- return 0xFFFFFFFF;
- }
- CloseHandle(hFile);
- return (DWORD)FileBasic.FileAttributes;
+ Result = GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &FileAttributeData);
+
+ return Result ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES;
}
-WINBOOL STDCALL
-SetFileAttributesA(LPCSTR lpFileName,
- DWORD dwFileAttributes)
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetFileAttributesByHandle(IN HANDLE hFile,
+ OUT LPDWORD dwFileAttributes,
+ IN DWORD dwFlags)
{
- UNICODE_STRING FileNameU;
- ANSI_STRING FileName;
- WINBOOL Result;
+ FILE_BASIC_INFORMATION FileBasic;
+ IO_STATUS_BLOCK IoStatusBlock;
+ NTSTATUS Status;
+
+ UNREFERENCED_PARAMETER(dwFlags);
+
+ if (IsConsoleHandle(hFile))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ Status = NtQueryInformationFile(hFile,
+ &IoStatusBlock,
+ &FileBasic,
+ sizeof(FileBasic),
+ FileBasicInformation);
+ if (NT_SUCCESS(Status))
+ {
+ *dwFileAttributes = FileBasic.FileAttributes;
+ return TRUE;
+ }
+
+ SetLastErrorByStatus(Status);
+ return FALSE;
+}
- RtlInitAnsiString(&FileName,
- (LPSTR)lpFileName);
- /* convert ansi (or oem) string to unicode */
- if (bIsFileApiAnsi)
- RtlAnsiStringToUnicodeString(&FileNameU,
- &FileName,
- TRUE);
- else
- RtlOemStringToUnicodeString(&FileNameU,
- &FileName,
- TRUE);
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetFileAttributesByHandle(IN HANDLE hFile,
+ IN DWORD dwFileAttributes,
+ IN DWORD dwFlags)
+{
+ FILE_BASIC_INFORMATION FileBasic;
+ IO_STATUS_BLOCK IoStatusBlock;
+ NTSTATUS Status;
+
+ UNREFERENCED_PARAMETER(dwFlags);
+
+ if (IsConsoleHandle(hFile))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ Status = NtQueryInformationFile(hFile,
+ &IoStatusBlock,
+ &FileBasic,
+ sizeof(FileBasic),
+ FileBasicInformation);
+ if (NT_SUCCESS(Status))
+ {
+ FileBasic.FileAttributes = dwFileAttributes;
+
+ Status = NtSetInformationFile(hFile,
+ &IoStatusBlock,
+ &FileBasic,
+ sizeof(FileBasic),
+ FileBasicInformation);
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ return TRUE;
+}
- Result = SetFileAttributesW(FileNameU.Buffer,
- dwFileAttributes);
- RtlFreeUnicodeString(&FileNameU);
+/*
+ * @implemented
+ */
+BOOL STDCALL
+SetFileAttributesA(
+ LPCSTR lpFileName,
+ DWORD dwFileAttributes)
+{
+ PWCHAR FileNameW;
+
+ if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
+ return FALSE;
- return Result;
+ return SetFileAttributesW(FileNameW, dwFileAttributes);
}
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
SetFileAttributesW(LPCWSTR lpFileName,
DWORD dwFileAttributes)
{
- IO_STATUS_BLOCK IoStatusBlock;
- FILE_BASIC_INFORMATION FileBasic;
- HANDLE hFile;
- NTSTATUS errCode;
-
- hFile = CreateFileW(lpFileName,
- FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
- FILE_SHARE_READ,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
+ FILE_BASIC_INFORMATION FileInformation;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING FileName;
+ HANDLE FileHandle;
+ NTSTATUS Status;
+
+ DPRINT ("SetFileAttributeW(%S, 0x%lx) called\n", lpFileName, dwFileAttributes);
+
+ /* Validate and translate the filename */
+ if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName,
+ &FileName,
+ NULL,
+ NULL))
+ {
+ DPRINT ("Invalid path\n");
+ SetLastError (ERROR_BAD_PATHNAME);
+ return FALSE;
+ }
+ DPRINT ("FileName: \'%wZ\'\n", &FileName);
+
+ /* build the object attributes */
+ InitializeObjectAttributes (&ObjectAttributes,
+ &FileName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ /* Open the file */
+ Status = NtOpenFile (&FileHandle,
+ SYNCHRONIZE | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ RtlFreeUnicodeString (&FileName);
+ if (!NT_SUCCESS (Status))
+ {
+ DPRINT ("NtOpenFile() failed (Status %lx)\n", Status);
+ SetLastErrorByStatus (Status);
+ return FALSE;
+ }
- errCode = NtQueryInformationFile(hFile,
- &IoStatusBlock,
- &FileBasic,
- sizeof(FILE_BASIC_INFORMATION),
- FileBasicInformation);
- if (!NT_SUCCESS(errCode))
- {
- CloseHandle(hFile);
- SetLastErrorByStatus(errCode);
- return FALSE;
- }
- FileBasic.FileAttributes = dwFileAttributes;
- errCode = NtSetInformationFile(hFile,
+ Status = NtQueryInformationFile(FileHandle,
&IoStatusBlock,
- &FileBasic,
+ &FileInformation,
sizeof(FILE_BASIC_INFORMATION),
FileBasicInformation);
- if (!NT_SUCCESS(errCode))
- {
- CloseHandle(hFile);
- SetLastErrorByStatus(errCode);
- return FALSE;
- }
- CloseHandle(hFile);
- return TRUE;
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT ("SetFileAttributes NtQueryInformationFile failed with status 0x%08x\n", Status);
+ NtClose (FileHandle);
+ SetLastErrorByStatus (Status);
+ return FALSE;
+ }
+
+ FileInformation.FileAttributes = dwFileAttributes;
+ Status = NtSetInformationFile(FileHandle,
+ &IoStatusBlock,
+ &FileInformation,
+ sizeof(FILE_BASIC_INFORMATION),
+ FileBasicInformation);
+ NtClose (FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT ("SetFileAttributes NtSetInformationFile failed with status 0x%08x\n", Status);
+ SetLastErrorByStatus (Status);
+ return FALSE;
+ }
+
+ return TRUE;
}
-UINT STDCALL
-GetTempFileNameA(LPCSTR lpPathName,
- LPCSTR lpPrefixString,
- UINT uUnique,
- LPSTR lpTempFileName)
+
+
+/***********************************************************************
+ * GetTempFileNameA (KERNEL32.@)
+ */
+UINT WINAPI GetTempFileNameA( LPCSTR path, LPCSTR prefix, UINT unique, LPSTR buffer)
{
- 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,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)
- {
- if (GetLastError() != ERROR_ALREADY_EXISTS)
- {
- return 0;
- }
- sprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,++uUnique);
- }
- CloseHandle(hFile);
- return uUnique;
-}
+ WCHAR BufferW[MAX_PATH];
+ PWCHAR PathW;
+ WCHAR PrefixW[3+1];
+ UINT ret;
+ if (!(PathW = FilenameA2W(path, FALSE)))
+ return 0;
-UINT STDCALL
-GetTempFileNameW(LPCWSTR lpPathName,
- LPCWSTR lpPrefixString,
- UINT uUnique,
- LPWSTR lpTempFileName)
+ if (prefix)
+ FilenameA2W_N(PrefixW, 3+1, prefix, -1);
+
+ ret = GetTempFileNameW(PathW, prefix ? PrefixW : NULL, unique, BufferW);
+
+ if (ret)
+ FilenameW2A_N(buffer, MAX_PATH, BufferW, -1);
+
+ return ret;
+}
+
+/***********************************************************************
+ * GetTempFileNameW (KERNEL32.@)
+ */
+UINT WINAPI GetTempFileNameW( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR buffer )
{
- 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,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)
- {
- if (GetLastError() != ERROR_ALREADY_EXISTS)
- {
- return 0;
- }
- swprintf(lpTempFileName,format,len,lpPathName,lpPrefixString,++uUnique);
- }
- CloseHandle(hFile);
- return uUnique;
+ static const WCHAR formatW[] = L"%x.tmp";
+
+ int i;
+ LPWSTR p;
+
+ if ( !path || !prefix || !buffer )
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return 0;
+ }
+
+ wcscpy( buffer, path );
+ p = buffer + wcslen(buffer);
+
+ /* add a \, if there isn't one */
+ if ((p == buffer) || (p[-1] != '\\')) *p++ = '\\';
+
+ for (i = 3; (i > 0) && (*prefix); i--) *p++ = *prefix++;
+
+ unique &= 0xffff;
+
+ if (unique) swprintf( p, formatW, unique );
+ else
+ {
+ /* get a "random" unique number and try to create the file */
+ HANDLE handle;
+ UINT num = GetTickCount() & 0xffff;
+
+ if (!num) num = 1;
+ unique = num;
+ do
+ {
+ swprintf( p, formatW, unique );
+ handle = CreateFileW( buffer, GENERIC_WRITE, 0, NULL,
+ CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
+ if (handle != INVALID_HANDLE_VALUE)
+ { /* We created it */
+ DPRINT("created %S\n", buffer);
+ CloseHandle( handle );
+ break;
+ }
+ if (GetLastError() != ERROR_FILE_EXISTS &&
+ GetLastError() != ERROR_SHARING_VIOLATION)
+ break; /* No need to go on */
+ if (!(++unique & 0xffff)) unique = 1;
+ } while (unique != num);
+ }
+
+ DPRINT("returning %S\n", buffer);
+ return unique;
}
-WINBOOL STDCALL
+
+
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
GetFileTime(HANDLE hFile,
LPFILETIME lpCreationTime,
LPFILETIME lpLastAccessTime,
FILE_BASIC_INFORMATION FileBasic;
NTSTATUS Status;
+ if(IsConsoleHandle(hFile))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
Status = NtQueryInformationFile(hFile,
&IoStatusBlock,
&FileBasic,
}
-WINBOOL STDCALL
+/*
+ * @implemented
+ */
+BOOL STDCALL
SetFileTime(HANDLE hFile,
CONST FILETIME *lpCreationTime,
CONST FILETIME *lpLastAccessTime,
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
+ if(IsConsoleHandle(hFile))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
Status = NtQueryInformationFile(hFile,
&IoStatusBlock,
&FileBasic,
SetLastErrorByStatus(Status);
return FALSE;
}
-
+
return TRUE;
}
/*
-The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
-*/
-WINBOOL STDCALL
+ * The caller must have opened the file with the DesiredAccess FILE_WRITE_DATA flag set.
+ *
+ * @implemented
+ */
+BOOL STDCALL
SetEndOfFile(HANDLE hFile)
{
IO_STATUS_BLOCK IoStatusBlock;
FILE_POSITION_INFORMATION FilePosInfo;
NTSTATUS Status;
+ if(IsConsoleHandle(hFile))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
//get current position
Status = NtQueryInformationFile(
hFile,
EndOfFileInfo.EndOfFile.QuadPart = FilePosInfo.CurrentByteOffset.QuadPart;
/*
- NOTE:
+ 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
+ But...most file systems dispatch both FileEndOfFileInformation
and FileAllocationInformation as they were the same command.
*/
SetLastErrorByStatus(Status);
return FALSE;
}
-
+
+ return TRUE;
+
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+SetFileValidData(
+ HANDLE hFile,
+ LONGLONG ValidDataLength
+ )
+{
+ IO_STATUS_BLOCK IoStatusBlock;
+ FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation;
+ NTSTATUS Status;
+
+ ValidDataLengthInformation.ValidDataLength.QuadPart = ValidDataLength;
+
+ Status = NtSetInformationFile(
+ hFile,
+ &IoStatusBlock, //out
+ &ValidDataLengthInformation,
+ sizeof(FILE_VALID_DATA_LENGTH_INFORMATION),
+ FileValidDataLengthInformation
+ );
+
+ if (!NT_SUCCESS(Status)){
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
return TRUE;
+}
+
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+SetFileShortNameW(
+ HANDLE hFile,
+ LPCWSTR lpShortName)
+{
+ NTSTATUS Status;
+ ULONG NeededSize;
+ UNICODE_STRING ShortName;
+ IO_STATUS_BLOCK IoStatusBlock;
+ PFILE_NAME_INFORMATION FileNameInformation;
+
+ if(IsConsoleHandle(hFile))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if(!lpShortName)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ RtlInitUnicodeString(&ShortName, lpShortName);
+
+ NeededSize = sizeof(FILE_NAME_INFORMATION) + ShortName.Length + sizeof(WCHAR);
+ if(!(FileNameInformation = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, NeededSize)))
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ FileNameInformation->FileNameLength = ShortName.Length;
+ RtlCopyMemory(FileNameInformation->FileName, ShortName.Buffer, ShortName.Length);
+
+ Status = NtSetInformationFile(hFile,
+ &IoStatusBlock, //out
+ FileNameInformation,
+ NeededSize,
+ FileShortNameInformation);
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, FileNameInformation);
+ if(!NT_SUCCESS(Status))
+ {
+
+ SetLastErrorByStatus(Status);
+ }
+
+ return NT_SUCCESS(Status);
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+SetFileShortNameA(
+ HANDLE hFile,
+ LPCSTR lpShortName
+ )
+{
+ PWCHAR ShortNameW;
+
+ if(IsConsoleHandle(hFile))
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if(!lpShortName)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if (!(ShortNameW = FilenameA2W(lpShortName, FALSE)))
+ return FALSE;
+
+ return SetFileShortNameW(hFile, ShortNameW);
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+CheckNameLegalDOS8Dot3W(
+ LPCWSTR lpName,
+ LPSTR lpOemName OPTIONAL,
+ DWORD OemNameSize OPTIONAL,
+ PBOOL pbNameContainsSpaces OPTIONAL,
+ PBOOL pbNameLegal
+ )
+{
+ UNICODE_STRING Name;
+ ANSI_STRING AnsiName;
+
+ if(lpName == NULL ||
+ (lpOemName == NULL && OemNameSize != 0) ||
+ pbNameLegal == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if(lpOemName != NULL)
+ {
+ AnsiName.Buffer = lpOemName;
+ AnsiName.MaximumLength = OemNameSize * sizeof(CHAR);
+ AnsiName.Length = 0;
+ }
+
+ RtlInitUnicodeString(&Name, lpName);
+
+ *pbNameLegal = RtlIsNameLegalDOS8Dot3(&Name,
+ (lpOemName ? &AnsiName : NULL),
+ (BOOLEAN*)pbNameContainsSpaces);
+
+ return TRUE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+CheckNameLegalDOS8Dot3A(
+ LPCSTR lpName,
+ LPSTR lpOemName OPTIONAL,
+ DWORD OemNameSize OPTIONAL,
+ PBOOL pbNameContainsSpaces OPTIONAL,
+ PBOOL pbNameLegal
+ )
+{
+ UNICODE_STRING Name;
+ ANSI_STRING AnsiName, AnsiInputName;
+ NTSTATUS Status;
+
+ if(lpName == NULL ||
+ (lpOemName == NULL && OemNameSize != 0) ||
+ pbNameLegal == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if(lpOemName != NULL)
+ {
+ AnsiName.Buffer = lpOemName;
+ AnsiName.MaximumLength = OemNameSize * sizeof(CHAR);
+ AnsiName.Length = 0;
+ }
+
+ RtlInitAnsiString(&AnsiInputName, (LPSTR)lpName);
+ if(bIsFileApiAnsi)
+ Status = RtlAnsiStringToUnicodeString(&Name, &AnsiInputName, TRUE);
+ else
+ Status = RtlOemStringToUnicodeString(&Name, &AnsiInputName, TRUE);
+
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastErrorByStatus(Status);
+ return FALSE;
+ }
+
+ *pbNameLegal = RtlIsNameLegalDOS8Dot3(&Name,
+ (lpOemName ? &AnsiName : NULL),
+ (BOOLEAN*)pbNameContainsSpaces);
+
+ RtlFreeUnicodeString(&Name);
+ return TRUE;
}
/* EOF */