BOOL bIsFileApiAnsi = TRUE; // set the file api to ansi or oem
-
/* FUNCTIONS ****************************************************************/
-PWCHAR
-FilenameA2W(LPCSTR NameA, BOOL alloc)
-{
- PUNICODE_STRING pstrW;
- pstrW = FilenameA2U(NameA, alloc);
-
- return pstrW ? pstrW->Buffer : NULL;
-}
-
-
-PUNICODE_STRING
-FilenameA2U(LPCSTR NameA, BOOL alloc)
+PWCHAR
+FilenameA2W(LPCSTR NameA, BOOL alloc)
{
ANSI_STRING str;
UNICODE_STRING strW;
Status= RtlOemStringToUnicodeString( pstrW, &str, alloc );
if (NT_SUCCESS(Status))
- return pstrW;
+ return pstrW->Buffer;
if (Status== STATUS_BUFFER_OVERFLOW)
SetLastError( ERROR_FILENAME_EXCED_RANGE );
else
SetLastErrorByStatus(Status);
-
+
return NULL;
}
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
+DWORD
FilenameU2A_FitOrFail(
LPSTR DestA,
INT destLen, /* buffer size in TCHARS incl. nullchar */
ret = bIsFileApiAnsi? RtlUnicodeStringToAnsiSize(SourceU) : RtlUnicodeStringToOemSize(SourceU);
/* ret incl. nullchar */
-
- if (DestA && ret <= destLen)
+
+ 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;
}
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
+DWORD
FilenameW2A_FitOrFail(
LPSTR DestA,
INT destLen, /* buffer size in TCHARS incl. nullchar */
strW.MaximumLength = sourceLen * sizeof(WCHAR);
strW.Length = strW.MaximumLength - sizeof(WCHAR);
- return FilenameU2A_FitOrFail(DestA, destLen, &strW);
+ return FilenameU2A_FitOrFail(DestA, destLen, &strW);
}
-
-DWORD
-FilenameA2W_N(
- LPWSTR dest,
+/*
+Return: num. TCHARS copied into dest including nullterm
+*/
+DWORD
+FilenameA2W_N(
+ LPWSTR dest,
INT destlen, /* buffer size in TCHARS incl. nullchar */
- LPCSTR src,
+ 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 );
+ 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;
-}
+ return ret/sizeof(WCHAR);
+}
-DWORD
-FilenameW2A_N(
- LPSTR dest,
+/*
+Return: num. TCHARS copied into dest including nullterm
+*/
+DWORD
+FilenameW2A_N(
+ LPSTR dest,
INT destlen, /* buffer size in TCHARS incl. nullchar */
- LPCWSTR src,
+ 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) );
-
+ RtlUnicodeToOemN( dest, destlen, &ret, (LPWSTR) src, srclen * sizeof(WCHAR) );
+
if (ret) dest[ret-1]=0;
-
+
return ret;
}
/*
* @implemented
*/
-VOID STDCALL
+VOID
+STDCALL
SetFileApisToOEM(VOID)
{
- bIsFileApiAnsi = FALSE;
+ /* Set the correct Base Api */
+ Basep8BitStringToUnicodeString = (PRTL_CONVERT_STRING)RtlOemStringToUnicodeString;
+
+ /* FIXME: Old, deprecated way */
+ bIsFileApiAnsi = FALSE;
}
/*
* @implemented
*/
-VOID STDCALL
+VOID
+STDCALL
SetFileApisToANSI(VOID)
{
- bIsFileApiAnsi = TRUE;
+ /* Set the correct Base Api */
+ Basep8BitStringToUnicodeString = RtlAnsiStringToUnicodeString;
+
+ /* FIXME: Old, deprecated way */
+ bIsFileApiAnsi = TRUE;
}
RtlAnsiStringToUnicodeString (&FileNameU, &FileName, TRUE);
else
RtlOemStringToUnicodeString (&FileNameU, &FileName, TRUE);
-
+
Len = SearchPathW (NULL,
FileNameU.Buffer,
NULL,
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER Distance;
-
+
DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
hFile,lDistanceToMove,dwMoveMethod);
{
Distance.u.HighPart = -1;
}
-
+
switch(dwMoveMethod)
{
case FILE_CURRENT:
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;
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
-
+
if(FilePosition.CurrentByteOffset.QuadPart < 0)
{
SetLastError(ERROR_NEGATIVE_SEEK);
return FALSE;
}
-
+
errCode = NtSetInformationFile(hFile,
&IoStatusBlock,
&FilePosition,
SetLastErrorByStatus(errCode);
return FALSE;
}
-
+
if (lpNewFilePointer)
{
*lpNewFilePointer = FilePosition.CurrentByteOffset;
switch ((ULONG)hFile)
{
case STD_INPUT_HANDLE:
- hFile = NtCurrentPeb()->ProcessParameters->hStdInput;
+ hFile = NtCurrentPeb()->ProcessParameters->StandardInput;
break;
case STD_OUTPUT_HANDLE:
- hFile = NtCurrentPeb()->ProcessParameters->hStdOutput;
+ hFile = NtCurrentPeb()->ProcessParameters->StandardOutput;
break;
case STD_ERROR_HANDLE:
- hFile = NtCurrentPeb()->ProcessParameters->hStdError;
+ hFile = NtCurrentPeb()->ProcessParameters->StandardError;
break;
}
NTSTATUS errCode;
IO_STATUS_BLOCK IoStatusBlock;
HANDLE hFile;
-
+
hFile = CreateFileW(lpFileName,
GENERIC_READ,
FILE_SHARE_READ,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
-
+
if (hFile == INVALID_HANDLE_VALUE)
return INVALID_FILE_SIZE;
}
lpFileInformation->dwFileAttributes = (DWORD)FileBasic.FileAttributes;
-
+
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;
* @implemented
*/
BOOL STDCALL
-GetFileAttributesExW(LPCWSTR lpFileName,
- GET_FILEEX_INFO_LEVELS fInfoLevelId,
+GetFileAttributesExW(LPCWSTR lpFileName,
+ GET_FILEEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFileInformation)
{
FILE_NETWORK_OPEN_INFORMATION FileInformation;
NULL);
/* Open the file */
+
+
Status = NtOpenFile (&FileHandle,
- SYNCHRONIZE | FILE_READ_ATTRIBUTES,
+ SYNCHRONIZE | GENERIC_ALL,
&ObjectAttributes,
&IoStatusBlock,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_SYNCHRONOUS_IO_NONALERT);
+
+
+
+
RtlFreeUnicodeString (&FileName);
if (!NT_SUCCESS (Status))
{
*/
BOOL STDCALL
GetFileAttributesExA(LPCSTR lpFileName,
- GET_FILEEX_INFO_LEVELS fInfoLevelId,
+ GET_FILEEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFileInformation)
{
PWCHAR FileNameW;
-
+
if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
return FALSE;
if (!(FileNameW = FilenameA2W(lpFileName, FALSE)))
return INVALID_FILE_ATTRIBUTES;
-
+
ret = GetFileAttributesExW(FileNameW, GetFileExInfoStandard, &FileAttributeData);
return ret ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES;
return Result ? FileAttributeData.dwFileAttributes : INVALID_FILE_ATTRIBUTES;
}
+
+/*
+ * @implemented
+ */
+BOOL STDCALL
+GetFileAttributesByHandle(IN HANDLE hFile,
+ OUT LPDWORD 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))
+ {
+ *dwFileAttributes = FileBasic.FileAttributes;
+ return TRUE;
+ }
+
+ SetLastErrorByStatus(Status);
+ return FALSE;
+}
+
+
+/*
+ * @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;
+}
+
+
+/*
+ * @implemented
+ */
BOOL STDCALL
SetFileAttributesA(
LPCSTR lpFileName,
PWCHAR PathW;
WCHAR PrefixW[3+1];
UINT ret;
-
+
if (!(PathW = FilenameA2W(path, FALSE)))
return 0;
-
+
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;
}
SetLastErrorByStatus(Status);
return FALSE;
}
-
+
return TRUE;
}
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;
}
IO_STATUS_BLOCK IoStatusBlock;
FILE_VALID_DATA_LENGTH_INFORMATION ValidDataLengthInformation;
NTSTATUS Status;
-
+
ValidDataLengthInformation.ValidDataLength.QuadPart = ValidDataLength;
-
+
Status = NtSetInformationFile(
hFile,
&IoStatusBlock, //out
sizeof(FILE_VALID_DATA_LENGTH_INFORMATION),
FileValidDataLengthInformation
);
-
+
if (!NT_SUCCESS(Status)){
SetLastErrorByStatus(Status);
return FALSE;
}
-
+
return TRUE;
}
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);
}
)
{
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;