Added proper support for switching file APIs between ANSI and OEM

codepages. Optimized some of the A->W conversions by using the
per-thread Unicode string buffer.
This commit is contained in:
Alexandre Julliard 2004-05-13 20:21:25 +00:00
parent eee90c26a9
commit 0d33e5e32d
8 changed files with 380 additions and 640 deletions

View file

@ -28,6 +28,7 @@
#include "winbase.h" #include "winbase.h"
#include "winerror.h" #include "winerror.h"
#include "ntstatus.h" #include "ntstatus.h"
#include "kernel_private.h"
#include "wine/windef16.h" #include "wine/windef16.h"
#include "wine/server.h" #include "wine/server.h"
#include "wine/debug.h" #include "wine/debug.h"
@ -40,16 +41,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(file);
HANDLE WINAPI FindFirstChangeNotificationA( LPCSTR lpPathName, BOOL bWatchSubtree, HANDLE WINAPI FindFirstChangeNotificationA( LPCSTR lpPathName, BOOL bWatchSubtree,
DWORD dwNotifyFilter ) DWORD dwNotifyFilter )
{ {
UNICODE_STRING pathW; WCHAR *pathW;
HANDLE ret = INVALID_HANDLE_VALUE;
if (RtlCreateUnicodeStringFromAsciiz( &pathW, lpPathName )) if (!(pathW = FILE_name_AtoW( lpPathName, FALSE ))) return INVALID_HANDLE_VALUE;
{ return FindFirstChangeNotificationW( pathW, bWatchSubtree, dwNotifyFilter );
ret = FindFirstChangeNotificationW( pathW.Buffer, bWatchSubtree, dwNotifyFilter );
RtlFreeUnicodeString( &pathW );
}
else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return ret;
} }
/**************************************************************************** /****************************************************************************

View file

@ -60,6 +60,7 @@ typedef struct
BYTE data[8192]; /* directory data */ BYTE data[8192]; /* directory data */
} FIND_FIRST_INFO; } FIND_FIRST_INFO;
static BOOL oem_file_apis;
static WINE_EXCEPTION_FILTER(page_fault) static WINE_EXCEPTION_FILTER(page_fault)
{ {
@ -175,6 +176,88 @@ void FILE_SetDosError(void)
} }
/***********************************************************************
* FILE_name_AtoW
*
* Convert a file name to Unicode, taking into account the OEM/Ansi API mode.
*
* If alloc is FALSE uses the TEB static buffer, so it can only be used when
* there is no possibility for the function to do that twice, taking into
* account any called function.
*/
WCHAR *FILE_name_AtoW( LPCSTR name, BOOL alloc )
{
ANSI_STRING str;
UNICODE_STRING strW, *pstrW;
NTSTATUS status;
RtlInitAnsiString( &str, name );
pstrW = alloc ? &strW : &NtCurrentTeb()->StaticUnicodeString;
if (oem_file_apis)
status = RtlOemStringToUnicodeString( pstrW, &str, alloc );
else
status = RtlAnsiStringToUnicodeString( pstrW, &str, alloc );
if (status == STATUS_SUCCESS) return pstrW->Buffer;
if (status == STATUS_BUFFER_OVERFLOW)
SetLastError( ERROR_FILENAME_EXCED_RANGE );
else
SetLastError( RtlNtStatusToDosError(status) );
return NULL;
}
/***********************************************************************
* FILE_name_WtoA
*
* Convert a file name back to OEM/Ansi. Returns number of bytes copied.
*/
DWORD FILE_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen )
{
DWORD ret;
if (srclen < 0) srclen = strlenW( src ) + 1;
if (oem_file_apis)
RtlUnicodeToOemN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) );
else
RtlUnicodeToMultiByteN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) );
return ret;
}
/**************************************************************************
* SetFileApisToOEM (KERNEL32.@)
*/
VOID WINAPI SetFileApisToOEM(void)
{
oem_file_apis = TRUE;
}
/**************************************************************************
* SetFileApisToANSI (KERNEL32.@)
*/
VOID WINAPI SetFileApisToANSI(void)
{
oem_file_apis = FALSE;
}
/******************************************************************************
* AreFileApisANSI (KERNEL32.@)
*
* Determines if file functions are using ANSI
*
* RETURNS
* TRUE: Set of file functions is using ANSI code page
* FALSE: Set of file functions is using OEM code page
*/
BOOL WINAPI AreFileApisANSI(void)
{
return !oem_file_apis;
}
/************************************************************************** /**************************************************************************
* Operations on file handles * * Operations on file handles *
**************************************************************************/ **************************************************************************/
@ -1234,24 +1317,10 @@ HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD sharing,
LPSECURITY_ATTRIBUTES sa, DWORD creation, LPSECURITY_ATTRIBUTES sa, DWORD creation,
DWORD attributes, HANDLE template) DWORD attributes, HANDLE template)
{ {
UNICODE_STRING filenameW; WCHAR *nameW;
HANDLE ret = INVALID_HANDLE_VALUE;
if (!filename) if (!(nameW = FILE_name_AtoW( filename, FALSE ))) return INVALID_HANDLE_VALUE;
{ return CreateFileW( nameW, access, sharing, sa, creation, attributes, template );
SetLastError( ERROR_INVALID_PARAMETER );
return INVALID_HANDLE_VALUE;
}
if (RtlCreateUnicodeStringFromAsciiz(&filenameW, filename))
{
ret = CreateFileW(filenameW.Buffer, access, sharing, sa, creation,
attributes, template);
RtlFreeUnicodeString(&filenameW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
} }
@ -1279,17 +1348,10 @@ BOOL WINAPI DeleteFileW( LPCWSTR path )
*/ */
BOOL WINAPI DeleteFileA( LPCSTR path ) BOOL WINAPI DeleteFileA( LPCSTR path )
{ {
UNICODE_STRING pathW; WCHAR *pathW;
BOOL ret = FALSE;
if (RtlCreateUnicodeStringFromAsciiz(&pathW, path)) if (!(pathW = FILE_name_AtoW( path, FALSE ))) return FALSE;
{ return DeleteFileW( pathW );
ret = DeleteFileW(pathW.Buffer);
RtlFreeUnicodeString(&pathW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
} }
@ -1555,22 +1617,11 @@ HANDLE WINAPI FindFirstFileExA( LPCSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevel
HANDLE handle; HANDLE handle;
WIN32_FIND_DATAA *dataA; WIN32_FIND_DATAA *dataA;
WIN32_FIND_DATAW dataW; WIN32_FIND_DATAW dataW;
UNICODE_STRING pathW; WCHAR *nameW;
if (!lpFileName) if (!(nameW = FILE_name_AtoW( lpFileName, FALSE ))) return INVALID_HANDLE_VALUE;
{
SetLastError(ERROR_PATH_NOT_FOUND);
return INVALID_HANDLE_VALUE;
}
if (!RtlCreateUnicodeStringFromAsciiz(&pathW, lpFileName)) handle = FindFirstFileExW(nameW, fInfoLevelId, &dataW, fSearchOp, lpSearchFilter, dwAdditionalFlags);
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return INVALID_HANDLE_VALUE;
}
handle = FindFirstFileExW(pathW.Buffer, fInfoLevelId, &dataW, fSearchOp, lpSearchFilter, dwAdditionalFlags);
RtlFreeUnicodeString(&pathW);
if (handle == INVALID_HANDLE_VALUE) return handle; if (handle == INVALID_HANDLE_VALUE) return handle;
dataA = (WIN32_FIND_DATAA *) lpFindFileData; dataA = (WIN32_FIND_DATAA *) lpFindFileData;
@ -1580,10 +1631,9 @@ HANDLE WINAPI FindFirstFileExA( LPCSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevel
dataA->ftLastWriteTime = dataW.ftLastWriteTime; dataA->ftLastWriteTime = dataW.ftLastWriteTime;
dataA->nFileSizeHigh = dataW.nFileSizeHigh; dataA->nFileSizeHigh = dataW.nFileSizeHigh;
dataA->nFileSizeLow = dataW.nFileSizeLow; dataA->nFileSizeLow = dataW.nFileSizeLow;
WideCharToMultiByte( CP_ACP, 0, dataW.cFileName, -1, FILE_name_WtoA( dataW.cFileName, -1, dataA->cFileName, sizeof(dataA->cFileName) );
dataA->cFileName, sizeof(dataA->cFileName), NULL, NULL ); FILE_name_WtoA( dataW.cAlternateFileName, -1, dataA->cAlternateFileName,
WideCharToMultiByte( CP_ACP, 0, dataW.cAlternateFileName, -1, sizeof(dataA->cAlternateFileName) );
dataA->cAlternateFileName, sizeof(dataA->cAlternateFileName), NULL, NULL );
return handle; return handle;
} }
@ -1612,11 +1662,9 @@ BOOL WINAPI FindNextFileA( HANDLE handle, WIN32_FIND_DATAA *data )
data->ftLastWriteTime = dataW.ftLastWriteTime; data->ftLastWriteTime = dataW.ftLastWriteTime;
data->nFileSizeHigh = dataW.nFileSizeHigh; data->nFileSizeHigh = dataW.nFileSizeHigh;
data->nFileSizeLow = dataW.nFileSizeLow; data->nFileSizeLow = dataW.nFileSizeLow;
WideCharToMultiByte( CP_ACP, 0, dataW.cFileName, -1, FILE_name_WtoA( dataW.cFileName, -1, data->cFileName, sizeof(data->cFileName) );
data->cFileName, sizeof(data->cFileName), NULL, NULL ); FILE_name_WtoA( dataW.cAlternateFileName, -1, data->cAlternateFileName,
WideCharToMultiByte( CP_ACP, 0, dataW.cAlternateFileName, -1, sizeof(data->cAlternateFileName) );
data->cAlternateFileName,
sizeof(data->cAlternateFileName), NULL, NULL );
return TRUE; return TRUE;
} }
@ -1662,23 +1710,10 @@ DWORD WINAPI GetFileAttributesW( LPCWSTR name )
*/ */
DWORD WINAPI GetFileAttributesA( LPCSTR name ) DWORD WINAPI GetFileAttributesA( LPCSTR name )
{ {
UNICODE_STRING nameW; WCHAR *nameW;
DWORD ret = INVALID_FILE_ATTRIBUTES;
if (!name) if (!(nameW = FILE_name_AtoW( name, FALSE ))) return INVALID_FILE_ATTRIBUTES;
{ return GetFileAttributesW( nameW );
SetLastError( ERROR_INVALID_PARAMETER );
return INVALID_FILE_ATTRIBUTES;
}
if (RtlCreateUnicodeStringFromAsciiz(&nameW, name))
{
ret = GetFileAttributesW(nameW.Buffer);
RtlFreeUnicodeString(&nameW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
} }
@ -1730,23 +1765,10 @@ BOOL WINAPI SetFileAttributesW( LPCWSTR name, DWORD attributes )
*/ */
BOOL WINAPI SetFileAttributesA( LPCSTR name, DWORD attributes ) BOOL WINAPI SetFileAttributesA( LPCSTR name, DWORD attributes )
{ {
UNICODE_STRING filenameW; WCHAR *nameW;
BOOL ret = FALSE;
if (!name) if (!(nameW = FILE_name_AtoW( name, FALSE ))) return FALSE;
{ return SetFileAttributesW( nameW, attributes );
SetLastError( ERROR_INVALID_PARAMETER );
return FALSE;
}
if (RtlCreateUnicodeStringFromAsciiz(&filenameW, name))
{
ret = SetFileAttributesW(filenameW.Buffer, attributes);
RtlFreeUnicodeString(&filenameW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
} }
@ -1807,23 +1829,10 @@ BOOL WINAPI GetFileAttributesExW( LPCWSTR name, GET_FILEEX_INFO_LEVELS level, LP
*/ */
BOOL WINAPI GetFileAttributesExA( LPCSTR name, GET_FILEEX_INFO_LEVELS level, LPVOID ptr ) BOOL WINAPI GetFileAttributesExA( LPCSTR name, GET_FILEEX_INFO_LEVELS level, LPVOID ptr )
{ {
UNICODE_STRING filenameW; WCHAR *nameW;
BOOL ret = FALSE;
if (!name) if (!(nameW = FILE_name_AtoW( name, FALSE ))) return FALSE;
{ return GetFileAttributesExW( nameW, level, ptr );
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (RtlCreateUnicodeStringFromAsciiz(&filenameW, name))
{
ret = GetFileAttributesExW(filenameW.Buffer, level, ptr);
RtlFreeUnicodeString(&filenameW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
} }
@ -1878,20 +1887,10 @@ DWORD WINAPI GetCompressedFileSizeW(
*/ */
DWORD WINAPI GetCompressedFileSizeA( LPCSTR name, LPDWORD size_high ) DWORD WINAPI GetCompressedFileSizeA( LPCSTR name, LPDWORD size_high )
{ {
UNICODE_STRING filenameW; WCHAR *nameW;
DWORD ret;
if (RtlCreateUnicodeStringFromAsciiz(&filenameW, name)) if (!(nameW = FILE_name_AtoW( name, FALSE ))) return INVALID_FILE_SIZE;
{ return GetCompressedFileSizeW( nameW, size_high );
ret = GetCompressedFileSizeW(filenameW.Buffer, size_high);
RtlFreeUnicodeString(&filenameW);
}
else
{
ret = INVALID_FILE_SIZE;
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
}
return ret;
} }

View file

@ -50,12 +50,17 @@ extern HMODULE kernel32_handle;
#define DOS_TABLE_SIZE 256 #define DOS_TABLE_SIZE 256
extern HANDLE dos_handles[DOS_TABLE_SIZE]; extern HANDLE dos_handles[DOS_TABLE_SIZE];
extern WCHAR *DIR_Windows;
extern WCHAR *DIR_System;
extern void PTHREAD_Init(void); extern void PTHREAD_Init(void);
extern BOOL WOWTHUNK_Init(void); extern BOOL WOWTHUNK_Init(void);
extern VOID SYSLEVEL_CheckNotLevel( INT level ); extern VOID SYSLEVEL_CheckNotLevel( INT level );
extern void FILE_SetDosError(void); extern void FILE_SetDosError(void);
extern WCHAR *FILE_name_AtoW( LPCSTR name, BOOL alloc );
extern DWORD FILE_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen );
extern DWORD INSTR_EmulateInstruction( EXCEPTION_RECORD *rec, CONTEXT86 *context ); extern DWORD INSTR_EmulateInstruction( EXCEPTION_RECORD *rec, CONTEXT86 *context );
extern void INSTR_CallBuiltinHandler( CONTEXT86 *context, BYTE intnum ); extern void INSTR_CallBuiltinHandler( CONTEXT86 *context, BYTE intnum );

View file

@ -387,21 +387,11 @@ BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType )
*/ */
HMODULE WINAPI GetModuleHandleA(LPCSTR module) HMODULE WINAPI GetModuleHandleA(LPCSTR module)
{ {
NTSTATUS nts; WCHAR *moduleW;
HMODULE ret;
UNICODE_STRING wstr;
if (!module) return NtCurrentTeb()->Peb->ImageBaseAddress; if (!module) return NtCurrentTeb()->Peb->ImageBaseAddress;
if (!(moduleW = FILE_name_AtoW( module, FALSE ))) return 0;
RtlCreateUnicodeStringFromAsciiz(&wstr, module); return GetModuleHandleW( moduleW );
nts = LdrGetDllHandle(0, 0, &wstr, &ret);
RtlFreeUnicodeString( &wstr );
if (nts != STATUS_SUCCESS)
{
ret = 0;
SetLastError( RtlNtStatusToDosError( nts ) );
}
return ret;
} }
/*********************************************************************** /***********************************************************************
@ -456,7 +446,7 @@ DWORD WINAPI GetModuleFileNameA(
return 0; return 0;
} }
GetModuleFileNameW( hModule, filenameW, size ); GetModuleFileNameW( hModule, filenameW, size );
WideCharToMultiByte( CP_ACP, 0, filenameW, -1, lpFileName, size, NULL, NULL ); FILE_name_WtoA( filenameW, -1, lpFileName, size );
HeapFree( GetProcessHeap(), 0, filenameW ); HeapFree( GetProcessHeap(), 0, filenameW );
return strlen( lpFileName ); return strlen( lpFileName );
} }
@ -691,18 +681,10 @@ static HMODULE load_library( const UNICODE_STRING *libname, DWORD flags )
*/ */
HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags) HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags)
{ {
UNICODE_STRING wstr; WCHAR *libnameW;
HMODULE hModule;
if (!libname) if (!(libnameW = FILE_name_AtoW( libname, FALSE ))) return 0;
{ return LoadLibraryExW( libnameW, hfile, flags );
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
RtlCreateUnicodeStringFromAsciiz( &wstr, libname );
hModule = load_library( &wstr, flags );
RtlFreeUnicodeString( &wstr );
return hModule;
} }
/*********************************************************************** /***********************************************************************

View file

@ -57,6 +57,34 @@ inline static BOOL is_executable( const WCHAR *name )
return (!strcmpiW( name + len - 4, exeW ) || !strcmpiW( name + len - 4, comW )); return (!strcmpiW( name + len - 4, exeW ) || !strcmpiW( name + len - 4, comW ));
} }
/***********************************************************************
* copy_filename_WtoA
*
* copy a file name back to OEM/Ansi, but only if the buffer is large enough
*/
static DWORD copy_filename_WtoA( LPCWSTR nameW, LPSTR buffer, DWORD len )
{
UNICODE_STRING strW;
DWORD ret;
BOOL is_ansi = AreFileApisANSI();
RtlInitUnicodeString( &strW, nameW );
ret = is_ansi ? RtlUnicodeStringToAnsiSize(&strW) : RtlUnicodeStringToOemSize(&strW);
if (buffer && ret <= len)
{
ANSI_STRING str;
str.Buffer = buffer;
str.MaximumLength = len;
if (is_ansi)
RtlUnicodeStringToAnsiString( &str, &strW, FALSE );
else
RtlUnicodeStringToOemString( &str, &strW, FALSE );
ret = str.Length; /* length without terminating 0 */
}
return ret;
}
/*********************************************************************** /***********************************************************************
* add_boot_rename_entry * add_boot_rename_entry
@ -222,40 +250,22 @@ DWORD WINAPI GetFullPathNameW( LPCWSTR name, DWORD len, LPWSTR buffer,
DWORD WINAPI GetFullPathNameA( LPCSTR name, DWORD len, LPSTR buffer, DWORD WINAPI GetFullPathNameA( LPCSTR name, DWORD len, LPSTR buffer,
LPSTR *lastpart ) LPSTR *lastpart )
{ {
UNICODE_STRING nameW; WCHAR *nameW;
WCHAR bufferW[MAX_PATH]; WCHAR bufferW[MAX_PATH];
DWORD ret, retW; DWORD ret;
if (!name) if (!(nameW = FILE_name_AtoW( name, FALSE ))) return 0;
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!RtlCreateUnicodeStringFromAsciiz(&nameW, name)) ret = GetFullPathNameW( nameW, MAX_PATH, bufferW, NULL);
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
retW = GetFullPathNameW( nameW.Buffer, MAX_PATH, bufferW, NULL); if (!ret) return 0;
if (ret > MAX_PATH)
if (!retW)
ret = 0;
else if (retW > MAX_PATH)
{ {
SetLastError(ERROR_FILENAME_EXCED_RANGE); SetLastError(ERROR_FILENAME_EXCED_RANGE);
ret = 0; return 0;
} }
else ret = copy_filename_WtoA( bufferW, buffer, len );
{ if (ret < len && lastpart)
ret = WideCharToMultiByte(CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL);
if (ret && ret <= len)
{
WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, len, NULL, NULL);
ret--; /* length without 0 */
if (lastpart)
{ {
LPSTR p = buffer + strlen(buffer) - 1; LPSTR p = buffer + strlen(buffer) - 1;
@ -266,10 +276,6 @@ DWORD WINAPI GetFullPathNameA( LPCSTR name, DWORD len, LPSTR buffer,
} }
else *lastpart = NULL; else *lastpart = NULL;
} }
}
}
RtlFreeUnicodeString(&nameW);
return ret; return ret;
} }
@ -379,45 +385,23 @@ DWORD WINAPI GetLongPathNameW( LPCWSTR shortpath, LPWSTR longpath, DWORD longlen
*/ */
DWORD WINAPI GetLongPathNameA( LPCSTR shortpath, LPSTR longpath, DWORD longlen ) DWORD WINAPI GetLongPathNameA( LPCSTR shortpath, LPSTR longpath, DWORD longlen )
{ {
UNICODE_STRING shortpathW; WCHAR *shortpathW;
WCHAR longpathW[MAX_PATH]; WCHAR longpathW[MAX_PATH];
DWORD ret, retW; DWORD ret;
if (!shortpath)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
TRACE("%s\n", debugstr_a(shortpath)); TRACE("%s\n", debugstr_a(shortpath));
if (!RtlCreateUnicodeStringFromAsciiz(&shortpathW, shortpath)) if (!(shortpathW = FILE_name_AtoW( shortpath, FALSE ))) return 0;
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
retW = GetLongPathNameW(shortpathW.Buffer, longpathW, MAX_PATH); ret = GetLongPathNameW(shortpathW, longpathW, MAX_PATH);
if (!retW) if (!ret) return 0;
ret = 0; if (ret > MAX_PATH)
else if (retW > MAX_PATH)
{ {
SetLastError(ERROR_FILENAME_EXCED_RANGE); SetLastError(ERROR_FILENAME_EXCED_RANGE);
ret = 0; return 0;
} }
else return copy_filename_WtoA( longpathW, longpath, longlen );
{
ret = WideCharToMultiByte(CP_ACP, 0, longpathW, -1, NULL, 0, NULL, NULL);
if (ret <= longlen)
{
WideCharToMultiByte(CP_ACP, 0, longpathW, -1, longpath, longlen, NULL, NULL);
ret--; /* length without 0 */
}
}
RtlFreeUnicodeString(&shortpathW);
return ret;
} }
@ -543,45 +527,23 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl
*/ */
DWORD WINAPI GetShortPathNameA( LPCSTR longpath, LPSTR shortpath, DWORD shortlen ) DWORD WINAPI GetShortPathNameA( LPCSTR longpath, LPSTR shortpath, DWORD shortlen )
{ {
UNICODE_STRING longpathW; WCHAR *longpathW;
WCHAR shortpathW[MAX_PATH]; WCHAR shortpathW[MAX_PATH];
DWORD ret, retW; DWORD ret;
if (!longpath)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
TRACE("%s\n", debugstr_a(longpath)); TRACE("%s\n", debugstr_a(longpath));
if (!RtlCreateUnicodeStringFromAsciiz(&longpathW, longpath)) if (!(longpathW = FILE_name_AtoW( longpath, FALSE ))) return 0;
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
retW = GetShortPathNameW(longpathW.Buffer, shortpathW, MAX_PATH); ret = GetShortPathNameW(longpathW, shortpathW, MAX_PATH);
if (!retW) if (!ret) return 0;
ret = 0; if (ret > MAX_PATH)
else if (retW > MAX_PATH)
{ {
SetLastError(ERROR_FILENAME_EXCED_RANGE); SetLastError(ERROR_FILENAME_EXCED_RANGE);
ret = 0; return 0;
} }
else return copy_filename_WtoA( shortpathW, shortpath, shortlen );
{
ret = WideCharToMultiByte(CP_ACP, 0, shortpathW, -1, NULL, 0, NULL, NULL);
if (ret <= shortlen)
{
WideCharToMultiByte(CP_ACP, 0, shortpathW, -1, shortpath, shortlen, NULL, NULL);
ret--; /* length without 0 */
}
}
RtlFreeUnicodeString(&longpathW);
return ret;
} }
@ -603,14 +565,7 @@ UINT WINAPI GetTempPathA( UINT count, LPSTR path )
SetLastError(ERROR_FILENAME_EXCED_RANGE); SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0; return 0;
} }
return copy_filename_WtoA( pathW, path, count );
ret = WideCharToMultiByte(CP_ACP, 0, pathW, -1, NULL, 0, NULL, NULL);
if (ret <= count)
{
WideCharToMultiByte(CP_ACP, 0, pathW, -1, path, count, NULL, NULL);
ret--; /* length without 0 */
}
return ret;
} }
@ -673,25 +628,17 @@ UINT WINAPI GetTempPathW( UINT count, LPWSTR path )
*/ */
UINT WINAPI GetTempFileNameA( LPCSTR path, LPCSTR prefix, UINT unique, LPSTR buffer) UINT WINAPI GetTempFileNameA( LPCSTR path, LPCSTR prefix, UINT unique, LPSTR buffer)
{ {
UNICODE_STRING pathW, prefixW; WCHAR *pathW, *prefixW = NULL;
WCHAR bufferW[MAX_PATH]; WCHAR bufferW[MAX_PATH];
UINT ret; UINT ret;
if ( !path || !prefix || !buffer ) if (!(pathW = FILE_name_AtoW( path, FALSE ))) return 0;
{ if (prefix && !(prefixW = FILE_name_AtoW( prefix, TRUE ))) return 0;
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
RtlCreateUnicodeStringFromAsciiz(&pathW, path); ret = GetTempFileNameW(pathW, prefixW, unique, bufferW);
RtlCreateUnicodeStringFromAsciiz(&prefixW, prefix); if (ret) FILE_name_WtoA( bufferW, -1, buffer, MAX_PATH );
ret = GetTempFileNameW(pathW.Buffer, prefixW.Buffer, unique, bufferW); if (prefixW) HeapFree( GetProcessHeap(), 0, prefixW );
if (ret)
WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
RtlFreeUnicodeString(&pathW);
RtlFreeUnicodeString(&prefixW);
return ret; return ret;
} }
@ -868,40 +815,32 @@ DWORD WINAPI SearchPathW( LPCWSTR path, LPCWSTR name, LPCWSTR ext, DWORD buflen,
DWORD WINAPI SearchPathA( LPCSTR path, LPCSTR name, LPCSTR ext, DWORD WINAPI SearchPathA( LPCSTR path, LPCSTR name, LPCSTR ext,
DWORD buflen, LPSTR buffer, LPSTR *lastpart ) DWORD buflen, LPSTR buffer, LPSTR *lastpart )
{ {
UNICODE_STRING pathW, nameW, extW; WCHAR *pathW, *nameW = NULL, *extW = NULL;
WCHAR bufferW[MAX_PATH]; WCHAR bufferW[MAX_PATH];
DWORD ret, retW; DWORD ret;
if (path) RtlCreateUnicodeStringFromAsciiz(&pathW, path); if (!(pathW = FILE_name_AtoW( path, FALSE ))) return 0;
else pathW.Buffer = NULL; if (name && !(nameW = FILE_name_AtoW( name, TRUE ))) return 0;
if (name) RtlCreateUnicodeStringFromAsciiz(&nameW, name); if (ext && !(extW = FILE_name_AtoW( ext, TRUE )))
else nameW.Buffer = NULL; {
if (ext) RtlCreateUnicodeStringFromAsciiz(&extW, ext); if (nameW) HeapFree( GetProcessHeap(), 0, nameW );
else extW.Buffer = NULL; return 0;
}
retW = SearchPathW(pathW.Buffer, nameW.Buffer, extW.Buffer, MAX_PATH, bufferW, NULL); ret = SearchPathW(pathW, nameW, extW, MAX_PATH, bufferW, NULL);
if (!retW) if (nameW) HeapFree( GetProcessHeap(), 0, nameW );
ret = 0; if (extW) HeapFree( GetProcessHeap(), 0, extW );
else if (retW > MAX_PATH)
if (!ret) return 0;
if (ret > MAX_PATH)
{ {
SetLastError(ERROR_FILENAME_EXCED_RANGE); SetLastError(ERROR_FILENAME_EXCED_RANGE);
ret = 0; return 0;
} }
else ret = copy_filename_WtoA( bufferW, buffer, buflen );
{ if (buflen > ret && lastpart)
ret = WideCharToMultiByte(CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL); *lastpart = strrchr(buffer, '\\') + 1;
if (buflen >= ret)
{
WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, buflen, NULL, NULL);
ret--; /* length without 0 */
if (lastpart) *lastpart = strrchr(buffer, '\\') + 1;
}
}
RtlFreeUnicodeString(&pathW);
RtlFreeUnicodeString(&nameW);
RtlFreeUnicodeString(&extW);
return ret; return ret;
} }
@ -972,22 +911,15 @@ done:
*/ */
BOOL WINAPI CopyFileA( LPCSTR source, LPCSTR dest, BOOL fail_if_exists) BOOL WINAPI CopyFileA( LPCSTR source, LPCSTR dest, BOOL fail_if_exists)
{ {
UNICODE_STRING sourceW, destW; WCHAR *sourceW, *destW;
BOOL ret; BOOL ret;
if (!source || !dest) if (!(sourceW = FILE_name_AtoW( source, FALSE ))) return FALSE;
{ if (!(destW = FILE_name_AtoW( dest, TRUE ))) return FALSE;
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
RtlCreateUnicodeStringFromAsciiz(&sourceW, source); ret = CopyFileW( sourceW, destW, fail_if_exists );
RtlCreateUnicodeStringFromAsciiz(&destW, dest);
ret = CopyFileW(sourceW.Buffer, destW.Buffer, fail_if_exists); HeapFree( GetProcessHeap(), 0, destW );
RtlFreeUnicodeString(&sourceW);
RtlFreeUnicodeString(&destW);
return ret; return ret;
} }
@ -1017,23 +949,20 @@ BOOL WINAPI CopyFileExA(LPCSTR sourceFilename, LPCSTR destFilename,
LPPROGRESS_ROUTINE progressRoutine, LPVOID appData, LPPROGRESS_ROUTINE progressRoutine, LPVOID appData,
LPBOOL cancelFlagPointer, DWORD copyFlags) LPBOOL cancelFlagPointer, DWORD copyFlags)
{ {
UNICODE_STRING sourceW, destW; WCHAR *sourceW, *destW;
BOOL ret; BOOL ret;
if (!sourceFilename || !destFilename) /* can't use the TEB buffer since we may have a callback routine */
if (!(sourceW = FILE_name_AtoW( sourceFilename, TRUE ))) return FALSE;
if (!(destW = FILE_name_AtoW( destFilename, TRUE )))
{ {
SetLastError(ERROR_INVALID_PARAMETER); HeapFree( GetProcessHeap(), 0, sourceW );
return FALSE; return FALSE;
} }
ret = CopyFileExW(sourceW, destW, progressRoutine, appData,
RtlCreateUnicodeStringFromAsciiz(&sourceW, sourceFilename);
RtlCreateUnicodeStringFromAsciiz(&destW, destFilename);
ret = CopyFileExW(sourceW.Buffer, destW.Buffer, progressRoutine, appData,
cancelFlagPointer, copyFlags); cancelFlagPointer, copyFlags);
HeapFree( GetProcessHeap(), 0, sourceW );
RtlFreeUnicodeString(&sourceW); HeapFree( GetProcessHeap(), 0, destW );
RtlFreeUnicodeString(&destW);
return ret; return ret;
} }
@ -1185,23 +1114,13 @@ error:
*/ */
BOOL WINAPI MoveFileExA( LPCSTR source, LPCSTR dest, DWORD flag ) BOOL WINAPI MoveFileExA( LPCSTR source, LPCSTR dest, DWORD flag )
{ {
UNICODE_STRING sourceW, destW; WCHAR *sourceW, *destW;
BOOL ret; BOOL ret;
if (!source) if (!(sourceW = FILE_name_AtoW( source, FALSE ))) return FALSE;
{ if (!(destW = FILE_name_AtoW( dest, TRUE ))) return FALSE;
SetLastError(ERROR_INVALID_PARAMETER); ret = MoveFileExW( sourceW, destW, flag );
return FALSE; HeapFree( GetProcessHeap(), 0, destW );
}
RtlCreateUnicodeStringFromAsciiz(&sourceW, source);
if (dest) RtlCreateUnicodeStringFromAsciiz(&destW, dest);
else destW.Buffer = NULL;
ret = MoveFileExW( sourceW.Buffer, destW.Buffer, flag );
RtlFreeUnicodeString(&sourceW);
RtlFreeUnicodeString(&destW);
return ret; return ret;
} }
@ -1280,21 +1199,10 @@ BOOL WINAPI CreateDirectoryW( LPCWSTR path, LPSECURITY_ATTRIBUTES sa )
*/ */
BOOL WINAPI CreateDirectoryA( LPCSTR path, LPSECURITY_ATTRIBUTES sa ) BOOL WINAPI CreateDirectoryA( LPCSTR path, LPSECURITY_ATTRIBUTES sa )
{ {
UNICODE_STRING pathW; WCHAR *pathW;
BOOL ret;
if (path) if (!(pathW = FILE_name_AtoW( path, FALSE ))) return FALSE;
{ return CreateDirectoryW( pathW, sa );
if (!RtlCreateUnicodeStringFromAsciiz(&pathW, path))
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE;
}
}
else pathW.Buffer = NULL;
ret = CreateDirectoryW( pathW.Buffer, sa );
RtlFreeUnicodeString( &pathW );
return ret;
} }
@ -1303,33 +1211,14 @@ BOOL WINAPI CreateDirectoryA( LPCSTR path, LPSECURITY_ATTRIBUTES sa )
*/ */
BOOL WINAPI CreateDirectoryExA( LPCSTR template, LPCSTR path, LPSECURITY_ATTRIBUTES sa ) BOOL WINAPI CreateDirectoryExA( LPCSTR template, LPCSTR path, LPSECURITY_ATTRIBUTES sa )
{ {
UNICODE_STRING pathW, templateW; WCHAR *pathW, *templateW = NULL;
BOOL ret; BOOL ret;
if (path) if (!(pathW = FILE_name_AtoW( path, FALSE ))) return FALSE;
{ if (template && !(templateW = FILE_name_AtoW( template, TRUE ))) return FALSE;
if (!RtlCreateUnicodeStringFromAsciiz( &pathW, path ))
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE;
}
}
else pathW.Buffer = NULL;
if (template) ret = CreateDirectoryExW( templateW, pathW, sa );
{ if (templateW) HeapFree( GetProcessHeap(), 0, templateW );
if (!RtlCreateUnicodeStringFromAsciiz( &templateW, template ))
{
RtlFreeUnicodeString( &pathW );
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return FALSE;
}
}
else templateW.Buffer = NULL;
ret = CreateDirectoryExW( templateW.Buffer, pathW.Buffer, sa );
RtlFreeUnicodeString( &pathW );
RtlFreeUnicodeString( &templateW );
return ret; return ret;
} }
@ -1395,23 +1284,10 @@ BOOL WINAPI RemoveDirectoryW( LPCWSTR path )
*/ */
BOOL WINAPI RemoveDirectoryA( LPCSTR path ) BOOL WINAPI RemoveDirectoryA( LPCSTR path )
{ {
UNICODE_STRING pathW; WCHAR *pathW;
BOOL ret = FALSE;
if (!path) if (!(pathW = FILE_name_AtoW( path, FALSE ))) return FALSE;
{ return RemoveDirectoryW( pathW );
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
if (RtlCreateUnicodeStringFromAsciiz(&pathW, path))
{
ret = RemoveDirectoryW(pathW.Buffer);
RtlFreeUnicodeString(&pathW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
} }
@ -1430,27 +1306,17 @@ UINT WINAPI GetCurrentDirectoryW( UINT buflen, LPWSTR buf )
UINT WINAPI GetCurrentDirectoryA( UINT buflen, LPSTR buf ) UINT WINAPI GetCurrentDirectoryA( UINT buflen, LPSTR buf )
{ {
WCHAR bufferW[MAX_PATH]; WCHAR bufferW[MAX_PATH];
DWORD ret, retW; DWORD ret;
retW = GetCurrentDirectoryW(MAX_PATH, bufferW); ret = GetCurrentDirectoryW(MAX_PATH, bufferW);
if (!retW) if (!ret) return 0;
ret = 0; if (ret > MAX_PATH)
else if (retW > MAX_PATH)
{ {
SetLastError(ERROR_FILENAME_EXCED_RANGE); SetLastError(ERROR_FILENAME_EXCED_RANGE);
ret = 0; return 0;
} }
else return copy_filename_WtoA( bufferW, buf, buflen );
{
ret = WideCharToMultiByte(CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL);
if (buflen >= ret)
{
WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buf, buflen, NULL, NULL);
ret--; /* length without 0 */
}
}
return ret;
} }
@ -1478,21 +1344,88 @@ BOOL WINAPI SetCurrentDirectoryW( LPCWSTR dir )
*/ */
BOOL WINAPI SetCurrentDirectoryA( LPCSTR dir ) BOOL WINAPI SetCurrentDirectoryA( LPCSTR dir )
{ {
UNICODE_STRING dirW; WCHAR *dirW;
NTSTATUS status;
if (!RtlCreateUnicodeStringFromAsciiz( &dirW, dir )) if (!(dirW = FILE_name_AtoW( dir, FALSE ))) return FALSE;
return SetCurrentDirectoryW( dirW );
}
/***********************************************************************
* GetWindowsDirectoryW (KERNEL32.@)
*
* See comment for GetWindowsDirectoryA.
*/
UINT WINAPI GetWindowsDirectoryW( LPWSTR path, UINT count )
{
UINT len = strlenW( DIR_Windows ) + 1;
if (path && count >= len)
{ {
SetLastError( ERROR_NOT_ENOUGH_MEMORY ); strcpyW( path, DIR_Windows );
return FALSE; len--;
} }
status = RtlSetCurrentDirectory_U( &dirW ); return len;
if (status != STATUS_SUCCESS) }
/***********************************************************************
* GetWindowsDirectoryA (KERNEL32.@)
*
* Return value:
* If buffer is large enough to hold full path and terminating '\0' character
* function copies path to buffer and returns length of the path without '\0'.
* Otherwise function returns required size including '\0' character and
* does not touch the buffer.
*/
UINT WINAPI GetWindowsDirectoryA( LPSTR path, UINT count )
{
return copy_filename_WtoA( DIR_Windows, path, count );
}
/***********************************************************************
* GetSystemWindowsDirectoryA (KERNEL32.@) W2K, TS4.0SP4
*/
UINT WINAPI GetSystemWindowsDirectoryA( LPSTR path, UINT count )
{
return GetWindowsDirectoryA( path, count );
}
/***********************************************************************
* GetSystemWindowsDirectoryW (KERNEL32.@) W2K, TS4.0SP4
*/
UINT WINAPI GetSystemWindowsDirectoryW( LPWSTR path, UINT count )
{
return GetWindowsDirectoryW( path, count );
}
/***********************************************************************
* GetSystemDirectoryW (KERNEL32.@)
*
* See comment for GetWindowsDirectoryA.
*/
UINT WINAPI GetSystemDirectoryW( LPWSTR path, UINT count )
{
UINT len = strlenW( DIR_System ) + 1;
if (path && count >= len)
{ {
SetLastError( RtlNtStatusToDosError(status) ); strcpyW( path, DIR_System );
return FALSE; len--;
} }
return TRUE; return len;
}
/***********************************************************************
* GetSystemDirectoryA (KERNEL32.@)
*
* See comment for GetWindowsDirectoryA.
*/
UINT WINAPI GetSystemDirectoryA( LPSTR path, UINT count )
{
return copy_filename_WtoA( DIR_System, path, count );
} }

View file

@ -62,7 +62,6 @@ static HANDLE main_exe_file;
static DWORD shutdown_flags = 0; static DWORD shutdown_flags = 0;
static DWORD shutdown_priority = 0x280; static DWORD shutdown_priority = 0x280;
static DWORD process_dword; static DWORD process_dword;
static BOOL oem_file_apis;
static unsigned int server_startticks; static unsigned int server_startticks;
int main_create_flags = 0; int main_create_flags = 0;
@ -117,8 +116,7 @@ inline static int is_special_env_var( const char *var )
static BOOL get_builtin_path( const WCHAR *libname, const WCHAR *ext, WCHAR *filename, UINT size ) static BOOL get_builtin_path( const WCHAR *libname, const WCHAR *ext, WCHAR *filename, UINT size )
{ {
WCHAR *file_part; WCHAR *file_part;
WCHAR sysdir[MAX_PATH]; UINT len = strlenW( DIR_System );
UINT len = GetSystemDirectoryW( sysdir, MAX_PATH );
if (contains_path( libname )) if (contains_path( libname ))
{ {
@ -126,7 +124,7 @@ static BOOL get_builtin_path( const WCHAR *libname, const WCHAR *ext, WCHAR *fil
filename, &file_part ) > size * sizeof(WCHAR)) filename, &file_part ) > size * sizeof(WCHAR))
return FALSE; /* too long */ return FALSE; /* too long */
if (strncmpiW( filename, sysdir, len ) || filename[len] != '\\') if (strncmpiW( filename, DIR_System, len ) || filename[len] != '\\')
return FALSE; return FALSE;
while (filename[len] == '\\') len++; while (filename[len] == '\\') len++;
if (filename + len != file_part) return FALSE; if (filename + len != file_part) return FALSE;
@ -134,7 +132,7 @@ static BOOL get_builtin_path( const WCHAR *libname, const WCHAR *ext, WCHAR *fil
else else
{ {
if (strlenW(libname) + len + 2 >= size) return FALSE; /* too long */ if (strlenW(libname) + len + 2 >= size) return FALSE; /* too long */
memcpy( filename, sysdir, len * sizeof(WCHAR) ); memcpy( filename, DIR_System, len * sizeof(WCHAR) );
file_part = filename + len; file_part = filename + len;
if (file_part > filename && file_part[-1] != '\\') *file_part++ = '\\'; if (file_part > filename && file_part[-1] != '\\') *file_part++ = '\\';
strcpyW( file_part, libname ); strcpyW( file_part, libname );
@ -1602,20 +1600,19 @@ BOOL WINAPI CreateProcessA( LPCSTR app_name, LPSTR cmd_line, LPSECURITY_ATTRIBUT
DWORD flags, LPVOID env, LPCSTR cur_dir, DWORD flags, LPVOID env, LPCSTR cur_dir,
LPSTARTUPINFOA startup_info, LPPROCESS_INFORMATION info ) LPSTARTUPINFOA startup_info, LPPROCESS_INFORMATION info )
{ {
BOOL ret; BOOL ret = FALSE;
UNICODE_STRING app_nameW, cmd_lineW, cur_dirW, desktopW, titleW; WCHAR *app_nameW = NULL, *cmd_lineW = NULL, *cur_dirW = NULL;
UNICODE_STRING desktopW, titleW;
STARTUPINFOW infoW; STARTUPINFOW infoW;
if (app_name) RtlCreateUnicodeStringFromAsciiz( &app_nameW, app_name ); desktopW.Buffer = NULL;
else app_nameW.Buffer = NULL; titleW.Buffer = NULL;
if (cmd_line) RtlCreateUnicodeStringFromAsciiz( &cmd_lineW, cmd_line ); if (app_name && !(app_nameW = FILE_name_AtoW( app_name, TRUE ))) goto done;
else cmd_lineW.Buffer = NULL; if (cmd_line && !(cmd_lineW = FILE_name_AtoW( cmd_line, TRUE ))) goto done;
if (cur_dir) RtlCreateUnicodeStringFromAsciiz( &cur_dirW, cur_dir ); if (cur_dir && !(cur_dirW = FILE_name_AtoW( cur_dir, TRUE ))) goto done;
else cur_dirW.Buffer = NULL;
if (startup_info->lpDesktop) RtlCreateUnicodeStringFromAsciiz( &desktopW, startup_info->lpDesktop ); if (startup_info->lpDesktop) RtlCreateUnicodeStringFromAsciiz( &desktopW, startup_info->lpDesktop );
else desktopW.Buffer = NULL;
if (startup_info->lpTitle) RtlCreateUnicodeStringFromAsciiz( &titleW, startup_info->lpTitle ); if (startup_info->lpTitle) RtlCreateUnicodeStringFromAsciiz( &titleW, startup_info->lpTitle );
else titleW.Buffer = NULL;
memcpy( &infoW, startup_info, sizeof(infoW) ); memcpy( &infoW, startup_info, sizeof(infoW) );
infoW.lpDesktop = desktopW.Buffer; infoW.lpDesktop = desktopW.Buffer;
@ -1625,12 +1622,12 @@ BOOL WINAPI CreateProcessA( LPCSTR app_name, LPSTR cmd_line, LPSECURITY_ATTRIBUT
FIXME("StartupInfo.lpReserved is used, please report (%s)\n", FIXME("StartupInfo.lpReserved is used, please report (%s)\n",
debugstr_a(startup_info->lpReserved)); debugstr_a(startup_info->lpReserved));
ret = CreateProcessW( app_nameW.Buffer, cmd_lineW.Buffer, process_attr, thread_attr, ret = CreateProcessW( app_nameW, cmd_lineW, process_attr, thread_attr,
inherit, flags, env, cur_dirW.Buffer, &infoW, info ); inherit, flags, env, cur_dirW, &infoW, info );
done:
RtlFreeUnicodeString( &app_nameW ); if (app_nameW) HeapFree( GetProcessHeap(), 0, app_nameW );
RtlFreeUnicodeString( &cmd_lineW ); if (cmd_lineW) HeapFree( GetProcessHeap(), 0, cmd_lineW );
RtlFreeUnicodeString( &cur_dirW ); if (cur_dirW) HeapFree( GetProcessHeap(), 0, cur_dirW );
RtlFreeUnicodeString( &desktopW ); RtlFreeUnicodeString( &desktopW );
RtlFreeUnicodeString( &titleW ); RtlFreeUnicodeString( &titleW );
return ret; return ret;
@ -2618,37 +2615,6 @@ DWORD WINAPI RegisterServiceProcess(DWORD dwProcessId, DWORD dwType)
} }
/**************************************************************************
* SetFileApisToOEM (KERNEL32.@)
*/
VOID WINAPI SetFileApisToOEM(void)
{
oem_file_apis = TRUE;
}
/**************************************************************************
* SetFileApisToANSI (KERNEL32.@)
*/
VOID WINAPI SetFileApisToANSI(void)
{
oem_file_apis = FALSE;
}
/******************************************************************************
* AreFileApisANSI [KERNEL32.@] Determines if file functions are using ANSI
*
* RETURNS
* TRUE: Set of file functions is using ANSI code page
* FALSE: Set of file functions is using OEM code page
*/
BOOL WINAPI AreFileApisANSI(void)
{
return !oem_file_apis;
}
/*********************************************************************** /***********************************************************************
* GetSystemMSecCount (SYSTEM.6) * GetSystemMSecCount (SYSTEM.6)
* GetTickCount (KERNEL32.@) * GetTickCount (KERNEL32.@)

View file

@ -863,23 +863,22 @@ BOOL WINAPI GetVolumeInformationA( LPCSTR root, LPSTR label,
DWORD *filename_len, DWORD *flags, DWORD *filename_len, DWORD *flags,
LPSTR fsname, DWORD fsname_len ) LPSTR fsname, DWORD fsname_len )
{ {
UNICODE_STRING rootW; WCHAR *rootW = NULL;
LPWSTR labelW, fsnameW; LPWSTR labelW, fsnameW;
BOOL ret; BOOL ret;
if (root) RtlCreateUnicodeStringFromAsciiz(&rootW, root); if (root && !(rootW = FILE_name_AtoW( root, FALSE ))) return FALSE;
else rootW.Buffer = NULL;
labelW = label ? HeapAlloc(GetProcessHeap(), 0, label_len * sizeof(WCHAR)) : NULL; labelW = label ? HeapAlloc(GetProcessHeap(), 0, label_len * sizeof(WCHAR)) : NULL;
fsnameW = fsname ? HeapAlloc(GetProcessHeap(), 0, fsname_len * sizeof(WCHAR)) : NULL; fsnameW = fsname ? HeapAlloc(GetProcessHeap(), 0, fsname_len * sizeof(WCHAR)) : NULL;
if ((ret = GetVolumeInformationW(rootW.Buffer, labelW, label_len, serial, if ((ret = GetVolumeInformationW(rootW, labelW, label_len, serial,
filename_len, flags, fsnameW, fsname_len))) filename_len, flags, fsnameW, fsname_len)))
{ {
if (label) WideCharToMultiByte(CP_ACP, 0, labelW, -1, label, label_len, NULL, NULL); if (label) FILE_name_WtoA( labelW, -1, label, label_len );
if (fsname) WideCharToMultiByte(CP_ACP, 0, fsnameW, -1, fsname, fsname_len, NULL, NULL); if (fsname) FILE_name_WtoA( fsnameW, -1, fsname, fsname_len );
} }
RtlFreeUnicodeString(&rootW);
if (labelW) HeapFree( GetProcessHeap(), 0, labelW ); if (labelW) HeapFree( GetProcessHeap(), 0, labelW );
if (fsnameW) HeapFree( GetProcessHeap(), 0, fsnameW ); if (fsnameW) HeapFree( GetProcessHeap(), 0, fsnameW );
return ret; return ret;
@ -989,18 +988,13 @@ BOOL WINAPI SetVolumeLabelW( LPCWSTR root, LPCWSTR label )
*/ */
BOOL WINAPI SetVolumeLabelA(LPCSTR root, LPCSTR volname) BOOL WINAPI SetVolumeLabelA(LPCSTR root, LPCSTR volname)
{ {
UNICODE_STRING rootW, volnameW; WCHAR *rootW = NULL, *volnameW = NULL;
BOOL ret; BOOL ret;
if (root) RtlCreateUnicodeStringFromAsciiz(&rootW, root); if (root && !(rootW = FILE_name_AtoW( root, FALSE ))) return FALSE;
else rootW.Buffer = NULL; if (volname && !(volnameW = FILE_name_AtoW( volname, TRUE ))) return FALSE;
if (volname) RtlCreateUnicodeStringFromAsciiz(&volnameW, volname); ret = SetVolumeLabelW( rootW, volnameW );
else volnameW.Buffer = NULL; if (volnameW) HeapFree( GetProcessHeap(), 0, volnameW );
ret = SetVolumeLabelW( rootW.Buffer, volnameW.Buffer );
RtlFreeUnicodeString(&rootW);
RtlFreeUnicodeString(&volnameW);
return ret; return ret;
} }
@ -1091,23 +1085,13 @@ BOOL WINAPI DefineDosDeviceW( DWORD flags, LPCWSTR devname, LPCWSTR targetpath )
*/ */
BOOL WINAPI DefineDosDeviceA(DWORD flags, LPCSTR devname, LPCSTR targetpath) BOOL WINAPI DefineDosDeviceA(DWORD flags, LPCSTR devname, LPCSTR targetpath)
{ {
UNICODE_STRING d, t; WCHAR *devW, *targetW = NULL;
BOOL ret; BOOL ret;
if (!RtlCreateUnicodeStringFromAsciiz(&d, devname)) if (!(devW = FILE_name_AtoW( devname, FALSE ))) return FALSE;
{ if (targetpath && !(targetW = FILE_name_AtoW( targetpath, TRUE ))) return FALSE;
SetLastError(ERROR_NOT_ENOUGH_MEMORY); ret = DefineDosDeviceW(flags, devW, targetW);
return FALSE; if (targetW) HeapFree( GetProcessHeap(), 0, targetW );
}
if (!RtlCreateUnicodeStringFromAsciiz(&t, targetpath))
{
RtlFreeUnicodeString(&d);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
ret = DefineDosDeviceW(flags, d.Buffer, t.Buffer);
RtlFreeUnicodeString(&d);
RtlFreeUnicodeString(&t);
return ret; return ret;
} }
@ -1306,23 +1290,22 @@ DWORD WINAPI QueryDosDeviceW( LPCWSTR devname, LPWSTR target, DWORD bufsize )
DWORD WINAPI QueryDosDeviceA( LPCSTR devname, LPSTR target, DWORD bufsize ) DWORD WINAPI QueryDosDeviceA( LPCSTR devname, LPSTR target, DWORD bufsize )
{ {
DWORD ret = 0, retW; DWORD ret = 0, retW;
UNICODE_STRING devnameW; WCHAR *devnameW;
LPWSTR targetW = HeapAlloc( GetProcessHeap(),0, bufsize * sizeof(WCHAR) ); LPWSTR targetW;
if (!(devnameW = FILE_name_AtoW( devname, FALSE ))) return 0;
targetW = HeapAlloc( GetProcessHeap(),0, bufsize * sizeof(WCHAR) );
if (!targetW) if (!targetW)
{ {
SetLastError( ERROR_NOT_ENOUGH_MEMORY ); SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return 0; return 0;
} }
if (devname) RtlCreateUnicodeStringFromAsciiz(&devnameW, devname); retW = QueryDosDeviceW(devnameW, targetW, bufsize);
else devnameW.Buffer = NULL;
retW = QueryDosDeviceW(devnameW.Buffer, targetW, bufsize); ret = FILE_name_WtoA( targetW, retW, target, bufsize );
ret = WideCharToMultiByte(CP_ACP, 0, targetW, retW, target, bufsize, NULL, NULL);
RtlFreeUnicodeString(&devnameW);
HeapFree(GetProcessHeap(), 0, targetW); HeapFree(GetProcessHeap(), 0, targetW);
return ret; return ret;
} }
@ -1472,23 +1455,10 @@ UINT WINAPI GetDriveTypeW(LPCWSTR root) /* [in] String describing drive */
*/ */
UINT WINAPI GetDriveTypeA( LPCSTR root ) UINT WINAPI GetDriveTypeA( LPCSTR root )
{ {
UNICODE_STRING rootW; WCHAR *rootW = NULL;
UINT ret;
if (root) if (root && !(rootW = FILE_name_AtoW( root, FALSE ))) return DRIVE_NO_ROOT_DIR;
{ return GetDriveTypeW( rootW );
if( !RtlCreateUnicodeStringFromAsciiz(&rootW, root))
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return DRIVE_NO_ROOT_DIR;
}
}
else rootW.Buffer = NULL;
ret = GetDriveTypeW(rootW.Buffer);
RtlFreeUnicodeString(&rootW);
return ret;
} }
@ -1540,16 +1510,10 @@ BOOL WINAPI GetDiskFreeSpaceExW( LPCWSTR root, PULARGE_INTEGER avail,
BOOL WINAPI GetDiskFreeSpaceExA( LPCSTR root, PULARGE_INTEGER avail, BOOL WINAPI GetDiskFreeSpaceExA( LPCSTR root, PULARGE_INTEGER avail,
PULARGE_INTEGER total, PULARGE_INTEGER totalfree ) PULARGE_INTEGER total, PULARGE_INTEGER totalfree )
{ {
UNICODE_STRING rootW; WCHAR *rootW = NULL;
BOOL ret;
if (root) RtlCreateUnicodeStringFromAsciiz(&rootW, root); if (root && !(rootW = FILE_name_AtoW( root, FALSE ))) return FALSE;
else rootW.Buffer = NULL; return GetDiskFreeSpaceExW( rootW, avail, total, totalfree );
ret = GetDiskFreeSpaceExW( rootW.Buffer, avail, total, totalfree);
RtlFreeUnicodeString(&rootW);
return ret;
} }
@ -1602,22 +1566,8 @@ BOOL WINAPI GetDiskFreeSpaceA( LPCSTR root, LPDWORD cluster_sectors,
LPDWORD sector_bytes, LPDWORD free_clusters, LPDWORD sector_bytes, LPDWORD free_clusters,
LPDWORD total_clusters ) LPDWORD total_clusters )
{ {
UNICODE_STRING rootW; WCHAR *rootW = NULL;
BOOL ret = FALSE;
if (root) if (root && !(rootW = FILE_name_AtoW( root, FALSE ))) return FALSE;
{ return GetDiskFreeSpaceW( rootW, cluster_sectors, sector_bytes, free_clusters, total_clusters );
if(!RtlCreateUnicodeStringFromAsciiz(&rootW, root))
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
}
else rootW.Buffer = NULL;
ret = GetDiskFreeSpaceW(rootW.Buffer, cluster_sectors, sector_bytes,
free_clusters, total_clusters );
RtlFreeUnicodeString(&rootW);
return ret;
} }

View file

@ -53,8 +53,8 @@ WINE_DECLARE_DEBUG_CHANNEL(file);
#define MAX_PATHNAME_LEN 1024 #define MAX_PATHNAME_LEN 1024
static WCHAR *DIR_Windows; WCHAR *DIR_Windows = NULL;
static WCHAR *DIR_System; WCHAR *DIR_System = NULL;
/*********************************************************************** /***********************************************************************
* DIR_GetPath * DIR_GetPath
@ -233,93 +233,3 @@ int DIR_Init(void)
return 1; return 1;
} }
/***********************************************************************
* GetWindowsDirectoryW (KERNEL32.@)
*
* See comment for GetWindowsDirectoryA.
*/
UINT WINAPI GetWindowsDirectoryW( LPWSTR path, UINT count )
{
UINT len = strlenW( DIR_Windows ) + 1;
if (path && count >= len)
{
strcpyW( path, DIR_Windows );
len--;
}
return len;
}
/***********************************************************************
* GetWindowsDirectoryA (KERNEL32.@)
*
* Return value:
* If buffer is large enough to hold full path and terminating '\0' character
* function copies path to buffer and returns length of the path without '\0'.
* Otherwise function returns required size including '\0' character and
* does not touch the buffer.
*/
UINT WINAPI GetWindowsDirectoryA( LPSTR path, UINT count )
{
UINT len = WideCharToMultiByte( CP_ACP, 0, DIR_Windows, -1, NULL, 0, NULL, NULL );
if (path && count >= len)
{
WideCharToMultiByte( CP_ACP, 0, DIR_Windows, -1, path, count, NULL, NULL );
len--;
}
return len;
}
/***********************************************************************
* GetSystemWindowsDirectoryA (KERNEL32.@) W2K, TS4.0SP4
*/
UINT WINAPI GetSystemWindowsDirectoryA( LPSTR path, UINT count )
{
return GetWindowsDirectoryA( path, count );
}
/***********************************************************************
* GetSystemWindowsDirectoryW (KERNEL32.@) W2K, TS4.0SP4
*/
UINT WINAPI GetSystemWindowsDirectoryW( LPWSTR path, UINT count )
{
return GetWindowsDirectoryW( path, count );
}
/***********************************************************************
* GetSystemDirectoryW (KERNEL32.@)
*
* See comment for GetWindowsDirectoryA.
*/
UINT WINAPI GetSystemDirectoryW( LPWSTR path, UINT count )
{
UINT len = strlenW( DIR_System ) + 1;
if (path && count >= len)
{
strcpyW( path, DIR_System );
len--;
}
return len;
}
/***********************************************************************
* GetSystemDirectoryA (KERNEL32.@)
*
* See comment for GetWindowsDirectoryA.
*/
UINT WINAPI GetSystemDirectoryA( LPSTR path, UINT count )
{
UINT len = WideCharToMultiByte( CP_ACP, 0, DIR_System, -1, NULL, 0, NULL, NULL );
if (path && count >= len)
{
WideCharToMultiByte( CP_ACP, 0, DIR_System, -1, path, count, NULL, NULL );
len--;
}
return len;
}