Fixed ANSI/OEM <--> Unicode conversions

svn path=/trunk/; revision=1057
This commit is contained in:
Eric Kohl 2000-03-15 12:25:47 +00:00
parent 1c5d2b7204
commit 9658579d48
3 changed files with 682 additions and 419 deletions

View file

@ -1,4 +1,5 @@
/* /* $Id: cnotify.c,v 1.2 2000/03/15 12:25:47 ekohl Exp $
*
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
* FILE: lib/kernel32/file/find.c * FILE: lib/kernel32/file/find.c
@ -7,62 +8,76 @@
* UPDATE HISTORY: * UPDATE HISTORY:
* Created 01/11/98 * Created 01/11/98
*/ */
#include <windows.h> #include <windows.h>
#include <wstring.h> #include <wstring.h>
WINBOOL
FindCloseChangeNotification(
HANDLE hChangeHandle
)
{
return FALSE;
}
HANDLE WINBOOL
STDCALL FindCloseChangeNotification (
FindFirstChangeNotificationA( HANDLE hChangeHandle
LPCSTR lpPathName,
WINBOOL bWatchSubtree,
DWORD dwNotifyFilter
)
{
ULONG i;
WCHAR PathNameW[MAX_PATH];
i = 0;
while ((*lpPathName)!=0 && i < MAX_PATH)
{
PathNameW[i] = *lpPathName;
lpPathName++;
i++;
}
PathNameW[i] = 0;
return FindFirstChangeNotificationW(PathNameW, bWatchSubtree, dwNotifyFilter );
}
HANDLE
STDCALL
FindFirstChangeNotificationW(
LPCWSTR lpPathName,
WINBOOL bWatchSubtree,
DWORD dwNotifyFilter
)
{
return NULL;
}
WINBOOL
STDCALL
FindNextChangeNotification(
HANDLE hChangeHandle
) )
{ {
return FALSE; return FALSE;
} }
HANDLE
STDCALL
FindFirstChangeNotificationA (
LPCSTR lpPathName,
WINBOOL bWatchSubtree,
DWORD dwNotifyFilter
)
{
UNICODE_STRING PathNameU;
ANSI_STRING PathName;
HANDLE Result;
RtlInitAnsiString (&PathName,
(LPSTR)lpPathName);
/* convert ansi (or oem) string to unicode */
if (bIsFileApiAnsi)
RtlAnsiStringToUnicodeString (&PathNameU,
&PathName,
TRUE);
else
RtlOemStringToUnicodeString (&PathNameU,
&PathName,
TRUE);
Result = FindFirstChangeNotificationW (PathNameU.Buffer,
bWatchSubtree,
dwNotifyFilter);
RtlFreeHeap (RtlGetProcessHeap (),
0,
RootPathNameU.Buffer);
return Result;
}
HANDLE
STDCALL
FindFirstChangeNotificationW (
LPCWSTR lpPathName,
WINBOOL bWatchSubtree,
DWORD dwNotifyFilter
)
{
return NULL;
}
WINBOOL
STDCALL
FindNextChangeNotification (
HANDLE hChangeHandle
)
{
return FALSE;
}
/* EOF */

View file

@ -1,4 +1,4 @@
/* $Id: find.c,v 1.23 2000/01/11 17:30:16 ekohl Exp $ /* $Id: find.c,v 1.24 2000/03/15 12:25:47 ekohl Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries * PROJECT: ReactOS system libraries
@ -12,6 +12,7 @@
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <ntdll/rtl.h>
#include <windows.h> #include <windows.h>
#include <wchar.h> #include <wchar.h>
#include <string.h> #include <string.h>
@ -58,177 +59,245 @@ typedef struct _WIN32_FIND_DATA_ASCII {
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
static void FileDataToWin32Data(LPWIN32_FIND_DATA lpFindFileData, PKERNEL32_FIND_FILE_DATA IData) static void
FileDataToWin32Data (
LPWIN32_FIND_DATA lpFindFileData,
PKERNEL32_FIND_FILE_DATA IData
)
{ {
lpFindFileData->dwFileAttributes = IData->FileInfo.FileAttributes; lpFindFileData->dwFileAttributes = IData->FileInfo.FileAttributes;
memcpy(&lpFindFileData->ftCreationTime,&IData->FileInfo.CreationTime,sizeof(FILETIME)); memcpy (&lpFindFileData->ftCreationTime,
memcpy(&lpFindFileData->ftLastAccessTime,&IData->FileInfo.LastAccessTime,sizeof(FILETIME)); &IData->FileInfo.CreationTime,
memcpy(&lpFindFileData->ftLastWriteTime,&IData->FileInfo.LastWriteTime,sizeof(FILETIME)); sizeof(FILETIME));
lpFindFileData->nFileSizeHigh = IData->FileInfo.EndOfFile.u.HighPart; memcpy (&lpFindFileData->ftLastAccessTime,
lpFindFileData->nFileSizeLow = IData->FileInfo.EndOfFile.u.LowPart; &IData->FileInfo.LastAccessTime,
sizeof(FILETIME));
memcpy (&lpFindFileData->ftLastWriteTime,
&IData->FileInfo.LastWriteTime,
sizeof(FILETIME));
lpFindFileData->nFileSizeHigh = IData->FileInfo.EndOfFile.u.HighPart;
lpFindFileData->nFileSizeLow = IData->FileInfo.EndOfFile.u.LowPart;
} }
WINBOOL STDCALL InternalFindNextFile(HANDLE hFindFile,
LPWIN32_FIND_DATA lpFindFileData) WINBOOL
STDCALL
InternalFindNextFile (
HANDLE hFindFile,
LPWIN32_FIND_DATA lpFindFileData
)
{ {
IO_STATUS_BLOCK IoStatusBlock; PKERNEL32_FIND_FILE_DATA IData;
NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock;
PKERNEL32_FIND_FILE_DATA IData; NTSTATUS Status;
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
Status = NtQueryDirectoryFile(IData->DirectoryHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
(PVOID)&IData->FileInfo,
sizeof(IData->FileInfo) +
sizeof(IData->FileNameExtra),
FileBothDirectoryInformation,
TRUE,
&(IData->PatternStr),
FALSE);
DPRINT("Found %S\n",IData->FileInfo.FileName);
if (Status != STATUS_SUCCESS)
{
return(FALSE);
}
FileDataToWin32Data(lpFindFileData, IData); IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
return(TRUE); Status = NtQueryDirectoryFile (IData->DirectoryHandle,
} NULL,
NULL,
NULL,
&IoStatusBlock,
(PVOID)&IData->FileInfo,
sizeof(IData->FileInfo) +
sizeof(IData->FileNameExtra),
FileBothDirectoryInformation,
TRUE,
&(IData->PatternStr),
FALSE);
DPRINT("Found %S\n",IData->FileInfo.FileName);
if (!NT_SUCCESS(Status))
{
SetLastError (RtlNtStatusToDosError (Status));
return FALSE;
}
HANDLE STDCALL InternalFindFirstFile(LPCWSTR lpFileName, FileDataToWin32Data (lpFindFileData, IData);
LPWIN32_FIND_DATA lpFindFileData)
{
WCHAR CurrentDirectory[MAX_PATH];
WCHAR Pattern[MAX_PATH];
WCHAR Directory[MAX_PATH];
PWSTR End;
PKERNEL32_FIND_FILE_DATA IData;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING DirectoryNameStr;
IO_STATUS_BLOCK IoStatusBlock;
DPRINT("FindFirstFileW(lpFileName %S, lpFindFileData %x)\n", return TRUE;
lpFileName, lpFindFileData);
GetFullPathNameW(lpFileName, MAX_PATH, CurrentDirectory, NULL);
Directory[0] = '\\';
Directory[1] = '?';
Directory[2] = '?';
Directory[3] = '\\';
Directory[4] = 0;
DPRINT("Directory %S\n",Directory);
wcscat(Directory, CurrentDirectory);
DPRINT("Directory %S\n",Directory);
End = wcsrchr(Directory, '\\');
*End = 0;
wcscpy(Pattern, End+1);
*(End+1) = 0;
*End = '\\';
/* change pattern: "*.*" --> "*" */
if (!wcscmp(Pattern, L"*.*"))
Pattern[1] = 0;
DPRINT("Directory %S Pattern %S\n",Directory,Pattern);
IData = HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
sizeof(KERNEL32_FIND_FILE_DATA));
RtlInitUnicodeString(&DirectoryNameStr, Directory);
InitializeObjectAttributes(&ObjectAttributes,
&DirectoryNameStr,
0,
NULL,
NULL);
if (ZwOpenFile(&IData->DirectoryHandle,
FILE_LIST_DIRECTORY,
&ObjectAttributes,
&IoStatusBlock,
FILE_OPEN_IF,
OPEN_EXISTING)!=STATUS_SUCCESS)
{
return(NULL);
}
RtlInitUnicodeString(&(IData->PatternStr), Pattern);
NtQueryDirectoryFile(IData->DirectoryHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
(PVOID)&IData->FileInfo,
sizeof(IData->FileInfo) +
sizeof(IData->FileNameExtra),
FileBothDirectoryInformation,
TRUE,
&(IData->PatternStr),
FALSE);
DPRINT("Found %S\n",IData->FileInfo.FileName);
FileDataToWin32Data(lpFindFileData, IData);
return(IData);
} }
HANDLE HANDLE
STDCALL STDCALL
FindFirstFileA(LPCTSTR lpFileName, LPWIN32_FIND_DATA lpFindFileData) InternalFindFirstFile (
LPCWSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData
)
{ {
WCHAR lpFileNameW[MAX_PATH]; OBJECT_ATTRIBUTES ObjectAttributes;
ULONG i; PKERNEL32_FIND_FILE_DATA IData;
PKERNEL32_FIND_FILE_DATA IData; IO_STATUS_BLOCK IoStatusBlock;
PWIN32_FIND_DATA_ASCII Ret; UNICODE_STRING NtPathU;
NTSTATUS Status;
PWSTR End;
i = 0; DPRINT("FindFirstFileW(lpFileName %S, lpFindFileData %x)\n",
while (lpFileName[i]!=0) lpFileName, lpFindFileData);
{
lpFileNameW[i] = lpFileName[i]; if (!RtlDosPathNameToNtPathName_U ((LPWSTR)lpFileName,
i++; &NtPathU,
} &End,
lpFileNameW[i] = 0; NULL))
return FALSE;
IData = InternalFindFirstFile(lpFileNameW,lpFindFileData);
if (IData == NULL) DPRINT("NtPathU \'%S\' End \'%S\'\n", NtPathU.Buffer, End);
{
DPRINT("Failing request\n"); IData = RtlAllocateHeap (RtlGetProcessHeap (),
return(INVALID_HANDLE_VALUE); HEAP_ZERO_MEMORY,
} sizeof(KERNEL32_FIND_FILE_DATA));
/* move seach pattern to separate string */
RtlCreateUnicodeString (&IData->PatternStr,
End);
*End = 0;
NtPathU.Length = wcslen(NtPathU.Buffer)*sizeof(WCHAR);
/* change pattern: "*.*" --> "*" */
if (!wcscmp (IData->PatternStr.Buffer, L"*.*"))
{
IData->PatternStr.Buffer[1] = 0;
IData->PatternStr.Length = sizeof(WCHAR);
}
DPRINT("NtPathU \'%S\' Pattern \'%S\'\n",
NtPathU.Buffer, IData->PatternStr.Buffer);
InitializeObjectAttributes (&ObjectAttributes,
&NtPathU,
0,
NULL,
NULL);
Status = NtOpenFile (&IData->DirectoryHandle,
FILE_LIST_DIRECTORY,
&ObjectAttributes,
&IoStatusBlock,
FILE_OPEN_IF,
OPEN_EXISTING);
RtlFreeHeap (RtlGetProcessHeap (),
0,
NtPathU.Buffer);
if (!NT_SUCCESS(Status))
{
RtlFreeHeap (RtlGetProcessHeap (), 0, IData->PatternStr.Buffer);
RtlFreeHeap (RtlGetProcessHeap (), 0, IData);
SetLastError (RtlNtStatusToDosError (Status));
return(NULL);
}
Status = NtQueryDirectoryFile (IData->DirectoryHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
(PVOID)&IData->FileInfo,
sizeof(IData->FileInfo) +
sizeof(IData->FileNameExtra),
FileBothDirectoryInformation,
TRUE,
&(IData->PatternStr),
FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT("Status %lx\n", Status);
RtlFreeHeap (RtlGetProcessHeap (), 0, IData->PatternStr.Buffer);
RtlFreeHeap (RtlGetProcessHeap (), 0, IData);
SetLastError (RtlNtStatusToDosError (Status));
return NULL;
}
DPRINT("Found %S\n",IData->FileInfo.FileName);
FileDataToWin32Data(lpFindFileData, IData);
return IData;
}
Ret = (PWIN32_FIND_DATA_ASCII)lpFindFileData; HANDLE
STDCALL
FindFirstFileA (
LPCTSTR lpFileName,
LPWIN32_FIND_DATA lpFindFileData
)
{
PKERNEL32_FIND_FILE_DATA IData;
PWIN32_FIND_DATA_ASCII Ret;
UNICODE_STRING FileNameU;
ANSI_STRING FileName;
DPRINT("IData->FileInfo.FileNameLength %d\n", RtlInitAnsiString (&FileName,
IData->FileInfo.FileNameLength); (LPSTR)lpFileName);
for (i=0; i<IData->FileInfo.FileNameLength; i++)
{
Ret->cFileName[i] = IData->FileInfo.FileName[i];
}
Ret->cFileName[i] = 0;
DPRINT("IData->FileInfo.ShortNameLength %d\n", /* convert ansi (or oem) string to unicode */
IData->FileInfo.ShortNameLength); if (bIsFileApiAnsi)
if (IData->FileInfo.ShortNameLength > 13) RtlAnsiStringToUnicodeString (&FileNameU,
{ &FileName,
IData->FileInfo.ShortNameLength = 13; TRUE);
} else
for (i=0; i<IData->FileInfo.ShortNameLength; i++) RtlOemStringToUnicodeString (&FileNameU,
{ &FileName,
Ret->cAlternateFileName[i] = IData->FileInfo.ShortName[i]; TRUE);
}
Ret->cAlternateFileName[i] = 0;
IData = InternalFindFirstFile (FileNameU.Buffer, lpFindFileData);
return(IData); RtlFreeHeap (RtlGetProcessHeap (),
0,
FileNameU.Buffer);
if (IData == NULL)
{
DPRINT("Failing request\n");
return INVALID_HANDLE_VALUE;
}
Ret = (PWIN32_FIND_DATA_ASCII)lpFindFileData;
DPRINT("IData->FileInfo.FileNameLength %d\n",
IData->FileInfo.FileNameLength);
FileNameU.Length = IData->FileInfo.FileNameLength * sizeof(WCHAR);
FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR);
FileNameU.Buffer = IData->FileInfo.FileName;
FileName.Length = 0;
FileName.MaximumLength = MAX_PATH;
FileName.Buffer = Ret->cFileName;
/* convert unicode string to ansi (or oem) */
if (bIsFileApiAnsi)
RtlUnicodeStringToAnsiString (&FileName,
&FileNameU,
FALSE);
else
RtlUnicodeStringToOemString (&FileName,
&FileNameU,
FALSE);
DPRINT("IData->FileInfo.ShortNameLength %d\n",
IData->FileInfo.ShortNameLength);
FileNameU.Length = IData->FileInfo.ShortNameLength * sizeof(WCHAR);
FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR);
FileNameU.Buffer = IData->FileInfo.FileName;
FileName.Length = 0;
FileName.MaximumLength = 14;
FileName.Buffer = Ret->cAlternateFileName;
/* convert unicode string to ansi (or oem) */
if (bIsFileApiAnsi)
RtlUnicodeStringToAnsiString (&FileName,
&FileNameU,
FALSE);
else
RtlUnicodeStringToOemString (&FileName,
&FileNameU,
FALSE);
return IData;
} }
@ -236,60 +305,95 @@ WINBOOL
STDCALL STDCALL
FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData) FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATA lpFindFileData)
{ {
PWIN32_FIND_DATA_ASCII Ret; PWIN32_FIND_DATA_ASCII Ret;
PKERNEL32_FIND_FILE_DATA IData; PKERNEL32_FIND_FILE_DATA IData;
ULONG i; UNICODE_STRING FileNameU;
ANSI_STRING FileName;
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile; IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
if (IData == NULL) if (IData == NULL)
{ {
return(FALSE); return FALSE;
} }
if (!InternalFindNextFile(hFindFile, lpFindFileData))
{
DPRINT("InternalFindNextFile() failed\n");
return(FALSE);
}
Ret = (PWIN32_FIND_DATA_ASCII)lpFindFileData; if (!InternalFindNextFile (hFindFile, lpFindFileData))
{
DPRINT("InternalFindNextFile() failed\n");
return FALSE;
}
DPRINT("IData->FileInfo.FileNameLength %d\n", Ret = (PWIN32_FIND_DATA_ASCII)lpFindFileData;
IData->FileInfo.FileNameLength);
for (i=0; i<IData->FileInfo.FileNameLength; i++)
{
Ret->cFileName[i] = IData->FileInfo.FileName[i];
}
Ret->cFileName[i] = 0;
DPRINT("IData->FileInfo.ShortNameLength %d\n",
IData->FileInfo.ShortNameLength);
for (i=0; i<IData->FileInfo.ShortNameLength; i++)
{
Ret->cAlternateFileName[i] = IData->FileInfo.ShortName[i];
}
Ret->cAlternateFileName[i] = 0;
return(TRUE); DPRINT("IData->FileInfo.FileNameLength %d\n",
IData->FileInfo.FileNameLength);
FileNameU.Length = IData->FileInfo.FileNameLength * sizeof(WCHAR);
FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR);
FileNameU.Buffer = IData->FileInfo.FileName;
FileName.Length = 0;
FileName.MaximumLength = MAX_PATH;
FileName.Buffer = Ret->cFileName;
/* convert unicode string to ansi (or oem) */
if (bIsFileApiAnsi)
RtlUnicodeStringToAnsiString (&FileName,
&FileNameU,
FALSE);
else
RtlUnicodeStringToOemString (&FileName,
&FileNameU,
FALSE);
DPRINT("IData->FileInfo.ShortNameLength %d\n",
IData->FileInfo.ShortNameLength);
FileNameU.Length = IData->FileInfo.ShortNameLength * sizeof(WCHAR);
FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR);
FileNameU.Buffer = IData->FileInfo.FileName;
FileName.Length = 0;
FileName.MaximumLength = 14;
FileName.Buffer = Ret->cAlternateFileName;
/* convert unicode string to ansi (or oem) */
if (bIsFileApiAnsi)
RtlUnicodeStringToAnsiString (&FileName,
&FileNameU,
FALSE);
else
RtlUnicodeStringToOemString (&FileName,
&FileNameU,
FALSE);
return TRUE;
} }
BOOL BOOL
STDCALL STDCALL
FindClose(HANDLE hFindFile) FindClose (
HANDLE hFindFile
)
{ {
PKERNEL32_FIND_FILE_DATA IData; PKERNEL32_FIND_FILE_DATA IData;
DPRINT("FindClose(hFindFile %x)\n",hFindFile);
if (hFindFile || hFindFile == INVALID_HANDLE_VALUE) DPRINT("FindClose(hFindFile %x)\n",hFindFile);
{
SetLastError (ERROR_INVALID_HANDLE); if (hFindFile || hFindFile == INVALID_HANDLE_VALUE)
return(FALSE); {
} SetLastError (ERROR_INVALID_HANDLE);
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile; return FALSE;
CloseHandle(IData->DirectoryHandle); }
HeapFree(GetProcessHeap(), 0, IData);
return(TRUE); IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
CloseHandle (IData->DirectoryHandle);
if (IData->PatternStr.Buffer)
RtlFreeHeap (RtlGetProcessHeap (), 0, IData->PatternStr.Buffer);
RtlFreeHeap (RtlGetProcessHeap (), 0, IData);
return TRUE;
} }
@ -300,18 +404,26 @@ FindFirstFileW (
LPWIN32_FIND_DATA lpFindFileData LPWIN32_FIND_DATA lpFindFileData
) )
{ {
PWIN32_FIND_DATA_UNICODE Ret; PWIN32_FIND_DATA_UNICODE Ret;
PKERNEL32_FIND_FILE_DATA IData; PKERNEL32_FIND_FILE_DATA IData;
IData = InternalFindFirstFile(lpFileName,lpFindFileData); IData = InternalFindFirstFile (lpFileName, lpFindFileData);
Ret = (PWIN32_FIND_DATA_UNICODE)lpFindFileData; if (IData == NULL)
{
DPRINT("Failing request\n");
return INVALID_HANDLE_VALUE;
}
memcpy(Ret->cFileName, IData->FileInfo.FileName, Ret = (PWIN32_FIND_DATA_UNICODE)lpFindFileData;
IData->FileInfo.FileNameLength);
memcpy(Ret->cAlternateFileName, IData->FileInfo.ShortName,
IData->FileInfo.ShortNameLength);
return(IData); memcpy (Ret->cFileName,
IData->FileInfo.FileName,
IData->FileInfo.FileNameLength);
memcpy (Ret->cAlternateFileName,
IData->FileInfo.ShortName,
IData->FileInfo.ShortNameLength);
return IData;
} }
@ -322,23 +434,27 @@ FindNextFileW (
LPWIN32_FIND_DATA lpFindFileData LPWIN32_FIND_DATA lpFindFileData
) )
{ {
PWIN32_FIND_DATA_UNICODE Ret; PWIN32_FIND_DATA_UNICODE Ret;
PKERNEL32_FIND_FILE_DATA IData; PKERNEL32_FIND_FILE_DATA IData;
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile; IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
if (!InternalFindNextFile(hFindFile, lpFindFileData)) if (!InternalFindNextFile(hFindFile, lpFindFileData))
{ {
return(FALSE); DPRINT("Failing request\n");
} return FALSE;
}
Ret = (PWIN32_FIND_DATA_UNICODE)lpFindFileData; Ret = (PWIN32_FIND_DATA_UNICODE)lpFindFileData;
memcpy(Ret->cFileName, IData->FileInfo.FileName, memcpy (Ret->cFileName,
IData->FileInfo.FileNameLength); IData->FileInfo.FileName,
memcpy(Ret->cAlternateFileName, IData->FileInfo.ShortName, IData->FileInfo.FileNameLength);
IData->FileInfo.ShortNameLength);
return(TRUE); memcpy (Ret->cAlternateFileName,
IData->FileInfo.ShortName,
IData->FileInfo.ShortNameLength);
return TRUE;
} }
/* EOF */ /* EOF */

View file

@ -20,8 +20,6 @@
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <windows.h> #include <windows.h>
#include <wchar.h>
#include <string.h>
#define NDEBUG #define NDEBUG
#include <kernel32/kernel32.h> #include <kernel32/kernel32.h>
@ -117,38 +115,56 @@ GetLogicalDrives(VOID)
} }
WINBOOL WINBOOL
STDCALL STDCALL
GetDiskFreeSpaceA( GetDiskFreeSpaceA (
LPCSTR lpRootPathName, LPCSTR lpRootPathName,
LPDWORD lpSectorsPerCluster, LPDWORD lpSectorsPerCluster,
LPDWORD lpBytesPerSector, LPDWORD lpBytesPerSector,
LPDWORD lpNumberOfFreeClusters, LPDWORD lpNumberOfFreeClusters,
LPDWORD lpTotalNumberOfClusters LPDWORD lpTotalNumberOfClusters
) )
{ {
WCHAR RootPathNameW[MAX_PATH]; UNICODE_STRING RootPathNameU;
ANSI_STRING RootPathName;
WINBOOL Result;
if (lpRootPathName) RtlInitAnsiString (&RootPathName,
{ (LPSTR)lpRootPathName);
ULONG i = 0;
while ((*lpRootPathName)!=0 && i < MAX_PATH)
{
RootPathNameW[i] = *lpRootPathName;
lpRootPathName++;
i++;
}
RootPathNameW[i] = 0;
}
return GetDiskFreeSpaceW(lpRootPathName?RootPathNameW:NULL, RtlInitUnicodeString (&RootPathNameU,
lpSectorsPerCluster, NULL);
lpBytesPerSector,
lpNumberOfFreeClusters, if (lpRootPathName)
lpTotalNumberOfClusters); {
/* convert ansi (or oem) string to unicode */
if (bIsFileApiAnsi)
RtlAnsiStringToUnicodeString (&RootPathNameU,
&RootPathName,
TRUE);
else
RtlOemStringToUnicodeString (&RootPathNameU,
&RootPathName,
TRUE);
}
Result = GetDiskFreeSpaceW (RootPathNameU.Buffer,
lpSectorsPerCluster,
lpBytesPerSector,
lpNumberOfFreeClusters,
lpTotalNumberOfClusters);
if (lpRootPathName)
{
RtlFreeHeap (RtlGetProcessHeap (),
0,
RootPathNameU.Buffer);
}
return Result;
} }
WINBOOL WINBOOL
STDCALL STDCALL
GetDiskFreeSpaceW( GetDiskFreeSpaceW(
@ -203,33 +219,52 @@ GetDiskFreeSpaceW(
return TRUE; return TRUE;
} }
WINBOOL WINBOOL
STDCALL STDCALL
GetDiskFreeSpaceExA( GetDiskFreeSpaceExA (
LPCSTR lpDirectoryName, LPCSTR lpDirectoryName,
PULARGE_INTEGER lpFreeBytesAvailableToCaller, PULARGE_INTEGER lpFreeBytesAvailableToCaller,
PULARGE_INTEGER lpTotalNumberOfBytes, PULARGE_INTEGER lpTotalNumberOfBytes,
PULARGE_INTEGER lpTotalNumberOfFreeBytes PULARGE_INTEGER lpTotalNumberOfFreeBytes
) )
{ {
WCHAR DirectoryNameW[MAX_PATH]; UNICODE_STRING DirectoryNameU;
ANSI_STRING DirectoryName;
WINBOOL Result;
if (lpDirectoryName) RtlInitAnsiString (&DirectoryName,
{ (LPSTR)lpDirectoryName);
ULONG i = 0;
while ((*lpDirectoryName)!=0 && i < MAX_PATH)
{
DirectoryNameW[i] = *lpDirectoryName;
lpDirectoryName++;
i++;
}
DirectoryNameW[i] = 0;
}
return GetDiskFreeSpaceExW(lpDirectoryName?DirectoryNameW:NULL, RtlInitUnicodeString (&DirectoryNameU,
lpFreeBytesAvailableToCaller, NULL);
lpTotalNumberOfBytes,
lpTotalNumberOfFreeBytes); if (lpDirectoryName)
{
/* convert ansi (or oem) string to unicode */
if (bIsFileApiAnsi)
RtlAnsiStringToUnicodeString (&DirectoryNameU,
&DirectoryName,
TRUE);
else
RtlOemStringToUnicodeString (&DirectoryNameU,
&DirectoryName,
TRUE);
}
Result = GetDiskFreeSpaceExW (DirectoryNameU.Buffer,
lpFreeBytesAvailableToCaller,
lpTotalNumberOfBytes,
lpTotalNumberOfFreeBytes);
if (lpDirectoryName)
{
RtlFreeHeap (RtlGetProcessHeap (),
0,
DirectoryNameU.Buffer);
}
return Result;
} }
@ -298,28 +333,42 @@ GetDiskFreeSpaceExW(
UINT UINT
STDCALL STDCALL
GetDriveTypeA( GetDriveTypeA (
LPCSTR lpRootPathName LPCSTR lpRootPathName
) )
{ {
ULONG i; UNICODE_STRING RootPathNameU;
WCHAR RootPathNameW[MAX_PATH]; ANSI_STRING RootPathName;
i = 0; UINT Result;
while ((*lpRootPathName)!=0 && i < MAX_PATH)
{ RtlInitAnsiString (&RootPathName,
RootPathNameW[i] = *lpRootPathName; (LPSTR)lpRootPathName);
lpRootPathName++;
i++; /* convert ansi (or oem) string to unicode */
} if (bIsFileApiAnsi)
RootPathNameW[i] = 0; RtlAnsiStringToUnicodeString (&RootPathNameU,
return GetDriveTypeW(RootPathNameW); &RootPathName,
TRUE);
else
RtlOemStringToUnicodeString (&RootPathNameU,
&RootPathName,
TRUE);
Result = GetDriveTypeW (RootPathNameU.Buffer);
RtlFreeHeap (RtlGetProcessHeap (),
0,
RootPathNameU.Buffer);
return Result;
} }
UINT UINT
STDCALL STDCALL
GetDriveTypeW( GetDriveTypeW (
LPCWSTR lpRootPathName LPCWSTR lpRootPathName
) )
{ {
FILE_FS_DEVICE_INFORMATION FileFsDevice; FILE_FS_DEVICE_INFORMATION FileFsDevice;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
@ -327,75 +376,127 @@ GetDriveTypeW(
HANDLE hFile; HANDLE hFile;
NTSTATUS errCode; NTSTATUS errCode;
hFile = CreateFileW( hFile = CreateFileW (lpRootPathName,
lpRootPathName, GENERIC_ALL,
GENERIC_ALL, FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
NULL, OPEN_EXISTING,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
FILE_ATTRIBUTE_NORMAL, NULL);
NULL
);
errCode = NtQueryVolumeInformationFile(hFile,&IoStatusBlock,&FileFsDevice, sizeof(FILE_FS_DEVICE_INFORMATION),FileFsDeviceInformation); errCode = NtQueryVolumeInformationFile (hFile,
if ( !NT_SUCCESS(errCode) ) { &IoStatusBlock,
&FileFsDevice,
sizeof(FILE_FS_DEVICE_INFORMATION),
FileFsDeviceInformation);
if (!NT_SUCCESS(errCode))
{
CloseHandle(hFile); CloseHandle(hFile);
SetLastError(RtlNtStatusToDosError(errCode)); SetLastError(RtlNtStatusToDosError(errCode));
return 0; return 0;
} }
CloseHandle(hFile); CloseHandle(hFile);
return (UINT)FileFsDevice.DeviceType; return (UINT)FileFsDevice.DeviceType;
} }
WINBOOL WINBOOL
STDCALL STDCALL
GetVolumeInformationA( GetVolumeInformationA (
LPCSTR lpRootPathName, LPCSTR lpRootPathName,
LPSTR lpVolumeNameBuffer, LPSTR lpVolumeNameBuffer,
DWORD nVolumeNameSize, DWORD nVolumeNameSize,
LPDWORD lpVolumeSerialNumber, LPDWORD lpVolumeSerialNumber,
LPDWORD lpMaximumComponentLength, LPDWORD lpMaximumComponentLength,
LPDWORD lpFileSystemFlags, LPDWORD lpFileSystemFlags,
LPSTR lpFileSystemNameBuffer, LPSTR lpFileSystemNameBuffer,
DWORD nFileSystemNameSize DWORD nFileSystemNameSize
) )
{ {
ULONG i; UNICODE_STRING RootPathNameU;
WCHAR RootPathNameW[MAX_PATH]; UNICODE_STRING FileSystemNameU;
WCHAR VolumeNameBufferW[MAX_PATH]; UNICODE_STRING VolumeNameU;
WCHAR FileSystemNameBufferW[MAX_PATH]; ANSI_STRING RootPathName;
ANSI_STRING VolumeName;
ANSI_STRING FileSystemName;
WINBOOL Result;
i = 0; RtlInitAnsiString (&RootPathName,
while ((*lpRootPathName)!=0 && i < MAX_PATH) (LPSTR)lpRootPathName);
{
RootPathNameW[i] = *lpRootPathName;
lpRootPathName++;
i++;
}
RootPathNameW[i] = 0;
if ( GetVolumeInformationW(RootPathNameW, /* convert ansi (or oem) string to unicode */
VolumeNameBufferW, if (bIsFileApiAnsi)
nVolumeNameSize, RtlAnsiStringToUnicodeString (&RootPathNameU,
lpVolumeSerialNumber, &RootPathName,
lpMaximumComponentLength, TRUE);
lpFileSystemFlags, else
FileSystemNameBufferW, RtlOemStringToUnicodeString (&RootPathNameU,
nFileSystemNameSize ) ) { &RootPathName,
for(i=0;i<nVolumeNameSize;i++) TRUE);
lpVolumeNameBuffer[i] = (CHAR)VolumeNameBufferW[i];
for(i=0;i<nFileSystemNameSize;i++) VolumeNameU.Length = 0;
lpFileSystemNameBuffer[i] = (CHAR)FileSystemNameBufferW[i]; VolumeNameU.MaximumLength = nVolumeNameSize * sizeof(WCHAR);
VolumeNameU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
return TRUE; 0,
VolumeNameU.MaximumLength);
FileSystemNameU.Length = 0;
FileSystemNameU.MaximumLength = nFileSystemNameSize * sizeof(WCHAR);
FileSystemNameU.Buffer = RtlAllocateHeap (RtlGetProcessHeap (),
0,
FileSystemNameU.MaximumLength);
Result = GetVolumeInformationW (RootPathNameU.Buffer,
VolumeNameU.Buffer,
nVolumeNameSize,
lpVolumeSerialNumber,
lpMaximumComponentLength,
lpFileSystemFlags,
FileSystemNameU.Buffer,
nFileSystemNameSize);
if (Result)
{
VolumeName.Length = 0;
VolumeName.MaximumLength = nVolumeNameSize;
VolumeName.Buffer = lpVolumeNameBuffer;
FileSystemName.Length = 0;
FileSystemName.MaximumLength = nFileSystemNameSize;
FileSystemName.Buffer = lpFileSystemNameBuffer;
/* convert unicode strings to ansi (or oem) */
if (bIsFileApiAnsi)
{
RtlUnicodeStringToAnsiString (&VolumeName,
&VolumeNameU,
FALSE);
RtlUnicodeStringToAnsiString (&FileSystemName,
&FileSystemNameU,
FALSE);
}
else
{
RtlUnicodeStringToOemString (&VolumeName,
&VolumeNameU,
FALSE);
RtlUnicodeStringToOemString (&FileSystemName,
&FileSystemNameU,
FALSE);
}
} }
return FALSE;
RtlFreeHeap (RtlGetProcessHeap (),
0,
RootPathNameU.Buffer);
RtlFreeHeap (RtlGetProcessHeap (),
0,
VolumeNameU.Buffer);
RtlFreeHeap (RtlGetProcessHeap (),
0,
FileSystemNameU.Buffer);
return Result;
} }
@ -419,8 +520,8 @@ GetVolumeInformationW(
DWORD nFileSystemNameSize DWORD nFileSystemNameSize
) )
{ {
PFILE_FS_VOLUME_INFORMATION FileFsVolume; PFILE_FS_VOLUME_INFORMATION FileFsVolume;
PFILE_FS_ATTRIBUTE_INFORMATION FileFsAttribute; PFILE_FS_ATTRIBUTE_INFORMATION FileFsAttribute;
IO_STATUS_BLOCK IoStatusBlock; IO_STATUS_BLOCK IoStatusBlock;
USHORT Buffer[FS_VOLUME_BUFFER_SIZE]; USHORT Buffer[FS_VOLUME_BUFFER_SIZE];
USHORT Buffer2[FS_ATTRIBUTE_BUFFER_SIZE]; USHORT Buffer2[FS_ATTRIBUTE_BUFFER_SIZE];
@ -458,12 +559,19 @@ GetVolumeInformationW(
if (lpVolumeSerialNumber) if (lpVolumeSerialNumber)
*lpVolumeSerialNumber = FileFsVolume->VolumeSerialNumber; *lpVolumeSerialNumber = FileFsVolume->VolumeSerialNumber;
if (lpVolumeNameBuffer) if (lpVolumeNameBuffer)
wcsncpy(lpVolumeNameBuffer, FileFsVolume->VolumeLabel,min(nVolumeNameSize,MAX_PATH)); wcsncpy (lpVolumeNameBuffer,
FileFsVolume->VolumeLabel,
min(nVolumeNameSize,MAX_PATH));
errCode = NtQueryVolumeInformationFile(hFile,&IoStatusBlock,FileFsAttribute, FS_ATTRIBUTE_BUFFER_SIZE,FileFsAttributeInformation); errCode = NtQueryVolumeInformationFile (hFile,
if ( !NT_SUCCESS(errCode) ) { &IoStatusBlock,
DPRINT("Status: %x\n", errCode); FileFsAttribute,
FS_ATTRIBUTE_BUFFER_SIZE,
FileFsAttributeInformation);
if (!NT_SUCCESS(errCode))
{
DPRINT("Status: %x\n", errCode);
CloseHandle(hFile); CloseHandle(hFile);
SetLastError(RtlNtStatusToDosError(errCode)); SetLastError(RtlNtStatusToDosError(errCode));
return FALSE; return FALSE;
@ -480,43 +588,67 @@ GetVolumeInformationW(
return TRUE; return TRUE;
} }
WINBOOL WINBOOL
STDCALL STDCALL
SetVolumeLabelA( SetVolumeLabelA (
LPCSTR lpRootPathName, LPCSTR lpRootPathName,
LPCSTR lpVolumeName LPCSTR lpVolumeName
) )
{ {
WCHAR RootPathNameW[MAX_PATH]; UNICODE_STRING RootPathNameU;
WCHAR VolumeNameW[MAX_PATH]; ANSI_STRING RootPathName;
UINT i; UNICODE_STRING VolumeNameU;
ANSI_STRING VolumeName;
WINBOOL Result;
i = 0; RtlInitAnsiString (&RootPathName,
while ((*lpRootPathName)!=0 && i < MAX_PATH) (LPSTR)lpRootPathName);
{ RtlInitAnsiString (&VolumeName,
RootPathNameW[i] = *lpRootPathName; (LPSTR)lpVolumeName);
lpRootPathName++;
i++;
}
RootPathNameW[i] = 0;
i = 0; /* convert ansi (or oem) strings to unicode */
while ((*lpVolumeName)!=0 && i < MAX_PATH) if (bIsFileApiAnsi)
{ {
VolumeNameW[i] = *lpVolumeName; RtlAnsiStringToUnicodeString (&RootPathNameU,
lpVolumeName++; &RootPathName,
i++; TRUE);
} RtlAnsiStringToUnicodeString (&VolumeNameU,
VolumeNameW[i] = 0; &VolumeName,
return SetVolumeLabelW(RootPathNameW,VolumeNameW); TRUE);
}
else
{
RtlOemStringToUnicodeString (&RootPathNameU,
&RootPathName,
TRUE);
RtlOemStringToUnicodeString (&VolumeNameU,
&VolumeName,
TRUE);
}
Result = SetVolumeLabelW (RootPathNameU.Buffer,
VolumeNameU.Buffer);
RtlFreeHeap (RtlGetProcessHeap (),
0,
RootPathNameU.Buffer);
RtlFreeHeap (RtlGetProcessHeap (),
0,
VolumeNameU.Buffer);
return Result;
} }
WINBOOL WINBOOL
STDCALL STDCALL
SetVolumeLabelW( SetVolumeLabelW (
LPCWSTR lpRootPathName, LPCWSTR lpRootPathName,
LPCWSTR lpVolumeName LPCWSTR lpVolumeName
) )
{ {
return FALSE; return FALSE;
} }
/* EOF */