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:
parent
eee90c26a9
commit
0d33e5e32d
|
@ -28,6 +28,7 @@
|
|||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "ntstatus.h"
|
||||
#include "kernel_private.h"
|
||||
#include "wine/windef16.h"
|
||||
#include "wine/server.h"
|
||||
#include "wine/debug.h"
|
||||
|
@ -40,16 +41,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(file);
|
|||
HANDLE WINAPI FindFirstChangeNotificationA( LPCSTR lpPathName, BOOL bWatchSubtree,
|
||||
DWORD dwNotifyFilter )
|
||||
{
|
||||
UNICODE_STRING pathW;
|
||||
HANDLE ret = INVALID_HANDLE_VALUE;
|
||||
WCHAR *pathW;
|
||||
|
||||
if (RtlCreateUnicodeStringFromAsciiz( &pathW, lpPathName ))
|
||||
{
|
||||
ret = FindFirstChangeNotificationW( pathW.Buffer, bWatchSubtree, dwNotifyFilter );
|
||||
RtlFreeUnicodeString( &pathW );
|
||||
}
|
||||
else SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||
return ret;
|
||||
if (!(pathW = FILE_name_AtoW( lpPathName, FALSE ))) return INVALID_HANDLE_VALUE;
|
||||
return FindFirstChangeNotificationW( pathW, bWatchSubtree, dwNotifyFilter );
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
@ -60,6 +60,7 @@ typedef struct
|
|||
BYTE data[8192]; /* directory data */
|
||||
} FIND_FIRST_INFO;
|
||||
|
||||
static BOOL oem_file_apis;
|
||||
|
||||
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 *
|
||||
**************************************************************************/
|
||||
|
@ -1231,27 +1314,13 @@ HANDLE WINAPI CreateFileW( LPCWSTR filename, DWORD access, DWORD sharing,
|
|||
* CreateFileA (KERNEL32.@)
|
||||
*/
|
||||
HANDLE WINAPI CreateFileA( LPCSTR filename, DWORD access, DWORD sharing,
|
||||
LPSECURITY_ATTRIBUTES sa, DWORD creation,
|
||||
DWORD attributes, HANDLE template)
|
||||
LPSECURITY_ATTRIBUTES sa, DWORD creation,
|
||||
DWORD attributes, HANDLE template)
|
||||
{
|
||||
UNICODE_STRING filenameW;
|
||||
HANDLE ret = INVALID_HANDLE_VALUE;
|
||||
WCHAR *nameW;
|
||||
|
||||
if (!filename)
|
||||
{
|
||||
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;
|
||||
if (!(nameW = FILE_name_AtoW( filename, FALSE ))) return INVALID_HANDLE_VALUE;
|
||||
return CreateFileW( nameW, access, sharing, sa, creation, attributes, template );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1279,17 +1348,10 @@ BOOL WINAPI DeleteFileW( LPCWSTR path )
|
|||
*/
|
||||
BOOL WINAPI DeleteFileA( LPCSTR path )
|
||||
{
|
||||
UNICODE_STRING pathW;
|
||||
BOOL ret = FALSE;
|
||||
WCHAR *pathW;
|
||||
|
||||
if (RtlCreateUnicodeStringFromAsciiz(&pathW, path))
|
||||
{
|
||||
ret = DeleteFileW(pathW.Buffer);
|
||||
RtlFreeUnicodeString(&pathW);
|
||||
}
|
||||
else
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return ret;
|
||||
if (!(pathW = FILE_name_AtoW( path, FALSE ))) return FALSE;
|
||||
return DeleteFileW( pathW );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1555,22 +1617,11 @@ HANDLE WINAPI FindFirstFileExA( LPCSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevel
|
|||
HANDLE handle;
|
||||
WIN32_FIND_DATAA *dataA;
|
||||
WIN32_FIND_DATAW dataW;
|
||||
UNICODE_STRING pathW;
|
||||
WCHAR *nameW;
|
||||
|
||||
if (!lpFileName)
|
||||
{
|
||||
SetLastError(ERROR_PATH_NOT_FOUND);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if (!(nameW = FILE_name_AtoW( lpFileName, FALSE ))) return INVALID_HANDLE_VALUE;
|
||||
|
||||
if (!RtlCreateUnicodeStringFromAsciiz(&pathW, lpFileName))
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
handle = FindFirstFileExW(pathW.Buffer, fInfoLevelId, &dataW, fSearchOp, lpSearchFilter, dwAdditionalFlags);
|
||||
RtlFreeUnicodeString(&pathW);
|
||||
handle = FindFirstFileExW(nameW, fInfoLevelId, &dataW, fSearchOp, lpSearchFilter, dwAdditionalFlags);
|
||||
if (handle == INVALID_HANDLE_VALUE) return handle;
|
||||
|
||||
dataA = (WIN32_FIND_DATAA *) lpFindFileData;
|
||||
|
@ -1580,10 +1631,9 @@ HANDLE WINAPI FindFirstFileExA( LPCSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevel
|
|||
dataA->ftLastWriteTime = dataW.ftLastWriteTime;
|
||||
dataA->nFileSizeHigh = dataW.nFileSizeHigh;
|
||||
dataA->nFileSizeLow = dataW.nFileSizeLow;
|
||||
WideCharToMultiByte( CP_ACP, 0, dataW.cFileName, -1,
|
||||
dataA->cFileName, sizeof(dataA->cFileName), NULL, NULL );
|
||||
WideCharToMultiByte( CP_ACP, 0, dataW.cAlternateFileName, -1,
|
||||
dataA->cAlternateFileName, sizeof(dataA->cAlternateFileName), NULL, NULL );
|
||||
FILE_name_WtoA( dataW.cFileName, -1, dataA->cFileName, sizeof(dataA->cFileName) );
|
||||
FILE_name_WtoA( dataW.cAlternateFileName, -1, dataA->cAlternateFileName,
|
||||
sizeof(dataA->cAlternateFileName) );
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -1612,11 +1662,9 @@ BOOL WINAPI FindNextFileA( HANDLE handle, WIN32_FIND_DATAA *data )
|
|||
data->ftLastWriteTime = dataW.ftLastWriteTime;
|
||||
data->nFileSizeHigh = dataW.nFileSizeHigh;
|
||||
data->nFileSizeLow = dataW.nFileSizeLow;
|
||||
WideCharToMultiByte( CP_ACP, 0, dataW.cFileName, -1,
|
||||
data->cFileName, sizeof(data->cFileName), NULL, NULL );
|
||||
WideCharToMultiByte( CP_ACP, 0, dataW.cAlternateFileName, -1,
|
||||
data->cAlternateFileName,
|
||||
sizeof(data->cAlternateFileName), NULL, NULL );
|
||||
FILE_name_WtoA( dataW.cFileName, -1, data->cFileName, sizeof(data->cFileName) );
|
||||
FILE_name_WtoA( dataW.cAlternateFileName, -1, data->cAlternateFileName,
|
||||
sizeof(data->cAlternateFileName) );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -1662,23 +1710,10 @@ DWORD WINAPI GetFileAttributesW( LPCWSTR name )
|
|||
*/
|
||||
DWORD WINAPI GetFileAttributesA( LPCSTR name )
|
||||
{
|
||||
UNICODE_STRING nameW;
|
||||
DWORD ret = INVALID_FILE_ATTRIBUTES;
|
||||
WCHAR *nameW;
|
||||
|
||||
if (!name)
|
||||
{
|
||||
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;
|
||||
if (!(nameW = FILE_name_AtoW( name, FALSE ))) return INVALID_FILE_ATTRIBUTES;
|
||||
return GetFileAttributesW( nameW );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1730,23 +1765,10 @@ BOOL WINAPI SetFileAttributesW( LPCWSTR name, DWORD attributes )
|
|||
*/
|
||||
BOOL WINAPI SetFileAttributesA( LPCSTR name, DWORD attributes )
|
||||
{
|
||||
UNICODE_STRING filenameW;
|
||||
BOOL ret = FALSE;
|
||||
WCHAR *nameW;
|
||||
|
||||
if (!name)
|
||||
{
|
||||
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;
|
||||
if (!(nameW = FILE_name_AtoW( name, FALSE ))) return FALSE;
|
||||
return SetFileAttributesW( nameW, attributes );
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 )
|
||||
{
|
||||
UNICODE_STRING filenameW;
|
||||
BOOL ret = FALSE;
|
||||
WCHAR *nameW;
|
||||
|
||||
if (!name)
|
||||
{
|
||||
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;
|
||||
if (!(nameW = FILE_name_AtoW( name, FALSE ))) return FALSE;
|
||||
return GetFileAttributesExW( nameW, level, ptr );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1878,20 +1887,10 @@ DWORD WINAPI GetCompressedFileSizeW(
|
|||
*/
|
||||
DWORD WINAPI GetCompressedFileSizeA( LPCSTR name, LPDWORD size_high )
|
||||
{
|
||||
UNICODE_STRING filenameW;
|
||||
DWORD ret;
|
||||
WCHAR *nameW;
|
||||
|
||||
if (RtlCreateUnicodeStringFromAsciiz(&filenameW, name))
|
||||
{
|
||||
ret = GetCompressedFileSizeW(filenameW.Buffer, size_high);
|
||||
RtlFreeUnicodeString(&filenameW);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = INVALID_FILE_SIZE;
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
}
|
||||
return ret;
|
||||
if (!(nameW = FILE_name_AtoW( name, FALSE ))) return INVALID_FILE_SIZE;
|
||||
return GetCompressedFileSizeW( nameW, size_high );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -50,12 +50,17 @@ extern HMODULE kernel32_handle;
|
|||
#define DOS_TABLE_SIZE 256
|
||||
extern HANDLE dos_handles[DOS_TABLE_SIZE];
|
||||
|
||||
extern WCHAR *DIR_Windows;
|
||||
extern WCHAR *DIR_System;
|
||||
|
||||
extern void PTHREAD_Init(void);
|
||||
extern BOOL WOWTHUNK_Init(void);
|
||||
|
||||
extern VOID SYSLEVEL_CheckNotLevel( INT level );
|
||||
|
||||
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 void INSTR_CallBuiltinHandler( CONTEXT86 *context, BYTE intnum );
|
||||
|
|
|
@ -387,21 +387,11 @@ BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType )
|
|||
*/
|
||||
HMODULE WINAPI GetModuleHandleA(LPCSTR module)
|
||||
{
|
||||
NTSTATUS nts;
|
||||
HMODULE ret;
|
||||
UNICODE_STRING wstr;
|
||||
WCHAR *moduleW;
|
||||
|
||||
if (!module) return NtCurrentTeb()->Peb->ImageBaseAddress;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz(&wstr, module);
|
||||
nts = LdrGetDllHandle(0, 0, &wstr, &ret);
|
||||
RtlFreeUnicodeString( &wstr );
|
||||
if (nts != STATUS_SUCCESS)
|
||||
{
|
||||
ret = 0;
|
||||
SetLastError( RtlNtStatusToDosError( nts ) );
|
||||
}
|
||||
return ret;
|
||||
if (!(moduleW = FILE_name_AtoW( module, FALSE ))) return 0;
|
||||
return GetModuleHandleW( moduleW );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -456,7 +446,7 @@ DWORD WINAPI GetModuleFileNameA(
|
|||
return 0;
|
||||
}
|
||||
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 );
|
||||
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)
|
||||
{
|
||||
UNICODE_STRING wstr;
|
||||
HMODULE hModule;
|
||||
WCHAR *libnameW;
|
||||
|
||||
if (!libname)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
RtlCreateUnicodeStringFromAsciiz( &wstr, libname );
|
||||
hModule = load_library( &wstr, flags );
|
||||
RtlFreeUnicodeString( &wstr );
|
||||
return hModule;
|
||||
if (!(libnameW = FILE_name_AtoW( libname, FALSE ))) return 0;
|
||||
return LoadLibraryExW( libnameW, hfile, flags );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -57,6 +57,34 @@ inline static BOOL is_executable( const WCHAR *name )
|
|||
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
|
||||
|
@ -222,54 +250,32 @@ DWORD WINAPI GetFullPathNameW( LPCWSTR name, DWORD len, LPWSTR buffer,
|
|||
DWORD WINAPI GetFullPathNameA( LPCSTR name, DWORD len, LPSTR buffer,
|
||||
LPSTR *lastpart )
|
||||
{
|
||||
UNICODE_STRING nameW;
|
||||
WCHAR *nameW;
|
||||
WCHAR bufferW[MAX_PATH];
|
||||
DWORD ret, retW;
|
||||
DWORD ret;
|
||||
|
||||
if (!name)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
if (!(nameW = FILE_name_AtoW( name, FALSE ))) return 0;
|
||||
|
||||
if (!RtlCreateUnicodeStringFromAsciiz(&nameW, name))
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return 0;
|
||||
}
|
||||
ret = GetFullPathNameW( nameW, MAX_PATH, bufferW, NULL);
|
||||
|
||||
retW = GetFullPathNameW( nameW.Buffer, MAX_PATH, bufferW, NULL);
|
||||
|
||||
if (!retW)
|
||||
ret = 0;
|
||||
else if (retW > MAX_PATH)
|
||||
if (!ret) return 0;
|
||||
if (ret > MAX_PATH)
|
||||
{
|
||||
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)
|
||||
LPSTR p = buffer + strlen(buffer) - 1;
|
||||
|
||||
if (*p != '\\')
|
||||
{
|
||||
WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, len, NULL, NULL);
|
||||
ret--; /* length without 0 */
|
||||
|
||||
if (lastpart)
|
||||
{
|
||||
LPSTR p = buffer + strlen(buffer) - 1;
|
||||
|
||||
if (*p != '\\')
|
||||
{
|
||||
while ((p > buffer + 2) && (*p != '\\')) p--;
|
||||
*lastpart = p + 1;
|
||||
}
|
||||
else *lastpart = NULL;
|
||||
}
|
||||
while ((p > buffer + 2) && (*p != '\\')) p--;
|
||||
*lastpart = p + 1;
|
||||
}
|
||||
else *lastpart = NULL;
|
||||
}
|
||||
|
||||
RtlFreeUnicodeString(&nameW);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -379,45 +385,23 @@ DWORD WINAPI GetLongPathNameW( LPCWSTR shortpath, LPWSTR longpath, DWORD longlen
|
|||
*/
|
||||
DWORD WINAPI GetLongPathNameA( LPCSTR shortpath, LPSTR longpath, DWORD longlen )
|
||||
{
|
||||
UNICODE_STRING shortpathW;
|
||||
WCHAR *shortpathW;
|
||||
WCHAR longpathW[MAX_PATH];
|
||||
DWORD ret, retW;
|
||||
|
||||
if (!shortpath)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
DWORD ret;
|
||||
|
||||
TRACE("%s\n", debugstr_a(shortpath));
|
||||
|
||||
if (!RtlCreateUnicodeStringFromAsciiz(&shortpathW, shortpath))
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return 0;
|
||||
}
|
||||
if (!(shortpathW = FILE_name_AtoW( shortpath, FALSE ))) return 0;
|
||||
|
||||
retW = GetLongPathNameW(shortpathW.Buffer, longpathW, MAX_PATH);
|
||||
ret = GetLongPathNameW(shortpathW, longpathW, MAX_PATH);
|
||||
|
||||
if (!retW)
|
||||
ret = 0;
|
||||
else if (retW > MAX_PATH)
|
||||
if (!ret) return 0;
|
||||
if (ret > MAX_PATH)
|
||||
{
|
||||
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
||||
ret = 0;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
return copy_filename_WtoA( longpathW, longpath, longlen );
|
||||
}
|
||||
|
||||
|
||||
|
@ -543,45 +527,23 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl
|
|||
*/
|
||||
DWORD WINAPI GetShortPathNameA( LPCSTR longpath, LPSTR shortpath, DWORD shortlen )
|
||||
{
|
||||
UNICODE_STRING longpathW;
|
||||
WCHAR *longpathW;
|
||||
WCHAR shortpathW[MAX_PATH];
|
||||
DWORD ret, retW;
|
||||
|
||||
if (!longpath)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
DWORD ret;
|
||||
|
||||
TRACE("%s\n", debugstr_a(longpath));
|
||||
|
||||
if (!RtlCreateUnicodeStringFromAsciiz(&longpathW, longpath))
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return 0;
|
||||
}
|
||||
if (!(longpathW = FILE_name_AtoW( longpath, FALSE ))) return 0;
|
||||
|
||||
retW = GetShortPathNameW(longpathW.Buffer, shortpathW, MAX_PATH);
|
||||
ret = GetShortPathNameW(longpathW, shortpathW, MAX_PATH);
|
||||
|
||||
if (!retW)
|
||||
ret = 0;
|
||||
else if (retW > MAX_PATH)
|
||||
if (!ret) return 0;
|
||||
if (ret > MAX_PATH)
|
||||
{
|
||||
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
||||
ret = 0;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
return copy_filename_WtoA( shortpathW, shortpath, shortlen );
|
||||
}
|
||||
|
||||
|
||||
|
@ -603,14 +565,7 @@ UINT WINAPI GetTempPathA( UINT count, LPSTR path )
|
|||
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
return copy_filename_WtoA( pathW, path, count );
|
||||
}
|
||||
|
||||
|
||||
|
@ -673,25 +628,17 @@ UINT WINAPI GetTempPathW( UINT count, LPWSTR path )
|
|||
*/
|
||||
UINT WINAPI GetTempFileNameA( LPCSTR path, LPCSTR prefix, UINT unique, LPSTR buffer)
|
||||
{
|
||||
UNICODE_STRING pathW, prefixW;
|
||||
WCHAR *pathW, *prefixW = NULL;
|
||||
WCHAR bufferW[MAX_PATH];
|
||||
UINT ret;
|
||||
|
||||
if ( !path || !prefix || !buffer )
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
if (!(pathW = FILE_name_AtoW( path, FALSE ))) return 0;
|
||||
if (prefix && !(prefixW = FILE_name_AtoW( prefix, TRUE ))) return 0;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz(&pathW, path);
|
||||
RtlCreateUnicodeStringFromAsciiz(&prefixW, prefix);
|
||||
ret = GetTempFileNameW(pathW, prefixW, unique, bufferW);
|
||||
if (ret) FILE_name_WtoA( bufferW, -1, buffer, MAX_PATH );
|
||||
|
||||
ret = GetTempFileNameW(pathW.Buffer, prefixW.Buffer, unique, bufferW);
|
||||
if (ret)
|
||||
WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_PATH, NULL, NULL);
|
||||
|
||||
RtlFreeUnicodeString(&pathW);
|
||||
RtlFreeUnicodeString(&prefixW);
|
||||
if (prefixW) HeapFree( GetProcessHeap(), 0, prefixW );
|
||||
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 buflen, LPSTR buffer, LPSTR *lastpart )
|
||||
{
|
||||
UNICODE_STRING pathW, nameW, extW;
|
||||
WCHAR *pathW, *nameW = NULL, *extW = NULL;
|
||||
WCHAR bufferW[MAX_PATH];
|
||||
DWORD ret, retW;
|
||||
DWORD ret;
|
||||
|
||||
if (path) RtlCreateUnicodeStringFromAsciiz(&pathW, path);
|
||||
else pathW.Buffer = NULL;
|
||||
if (name) RtlCreateUnicodeStringFromAsciiz(&nameW, name);
|
||||
else nameW.Buffer = NULL;
|
||||
if (ext) RtlCreateUnicodeStringFromAsciiz(&extW, ext);
|
||||
else extW.Buffer = NULL;
|
||||
if (!(pathW = FILE_name_AtoW( path, FALSE ))) return 0;
|
||||
if (name && !(nameW = FILE_name_AtoW( name, TRUE ))) return 0;
|
||||
if (ext && !(extW = FILE_name_AtoW( ext, TRUE )))
|
||||
{
|
||||
if (nameW) HeapFree( GetProcessHeap(), 0, nameW );
|
||||
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)
|
||||
ret = 0;
|
||||
else if (retW > MAX_PATH)
|
||||
if (nameW) HeapFree( GetProcessHeap(), 0, nameW );
|
||||
if (extW) HeapFree( GetProcessHeap(), 0, extW );
|
||||
|
||||
if (!ret) return 0;
|
||||
if (ret > MAX_PATH)
|
||||
{
|
||||
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
||||
ret = 0;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = WideCharToMultiByte(CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL);
|
||||
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);
|
||||
ret = copy_filename_WtoA( bufferW, buffer, buflen );
|
||||
if (buflen > ret && lastpart)
|
||||
*lastpart = strrchr(buffer, '\\') + 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -972,22 +911,15 @@ done:
|
|||
*/
|
||||
BOOL WINAPI CopyFileA( LPCSTR source, LPCSTR dest, BOOL fail_if_exists)
|
||||
{
|
||||
UNICODE_STRING sourceW, destW;
|
||||
WCHAR *sourceW, *destW;
|
||||
BOOL ret;
|
||||
|
||||
if (!source || !dest)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
if (!(sourceW = FILE_name_AtoW( source, FALSE ))) return FALSE;
|
||||
if (!(destW = FILE_name_AtoW( dest, TRUE ))) return FALSE;
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz(&sourceW, source);
|
||||
RtlCreateUnicodeStringFromAsciiz(&destW, dest);
|
||||
ret = CopyFileW( sourceW, destW, fail_if_exists );
|
||||
|
||||
ret = CopyFileW(sourceW.Buffer, destW.Buffer, fail_if_exists);
|
||||
|
||||
RtlFreeUnicodeString(&sourceW);
|
||||
RtlFreeUnicodeString(&destW);
|
||||
HeapFree( GetProcessHeap(), 0, destW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1017,23 +949,20 @@ BOOL WINAPI CopyFileExA(LPCSTR sourceFilename, LPCSTR destFilename,
|
|||
LPPROGRESS_ROUTINE progressRoutine, LPVOID appData,
|
||||
LPBOOL cancelFlagPointer, DWORD copyFlags)
|
||||
{
|
||||
UNICODE_STRING sourceW, destW;
|
||||
WCHAR *sourceW, *destW;
|
||||
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;
|
||||
}
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz(&sourceW, sourceFilename);
|
||||
RtlCreateUnicodeStringFromAsciiz(&destW, destFilename);
|
||||
|
||||
ret = CopyFileExW(sourceW.Buffer, destW.Buffer, progressRoutine, appData,
|
||||
ret = CopyFileExW(sourceW, destW, progressRoutine, appData,
|
||||
cancelFlagPointer, copyFlags);
|
||||
|
||||
RtlFreeUnicodeString(&sourceW);
|
||||
RtlFreeUnicodeString(&destW);
|
||||
HeapFree( GetProcessHeap(), 0, sourceW );
|
||||
HeapFree( GetProcessHeap(), 0, destW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1185,23 +1114,13 @@ error:
|
|||
*/
|
||||
BOOL WINAPI MoveFileExA( LPCSTR source, LPCSTR dest, DWORD flag )
|
||||
{
|
||||
UNICODE_STRING sourceW, destW;
|
||||
WCHAR *sourceW, *destW;
|
||||
BOOL ret;
|
||||
|
||||
if (!source)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RtlCreateUnicodeStringFromAsciiz(&sourceW, source);
|
||||
if (dest) RtlCreateUnicodeStringFromAsciiz(&destW, dest);
|
||||
else destW.Buffer = NULL;
|
||||
|
||||
ret = MoveFileExW( sourceW.Buffer, destW.Buffer, flag );
|
||||
|
||||
RtlFreeUnicodeString(&sourceW);
|
||||
RtlFreeUnicodeString(&destW);
|
||||
if (!(sourceW = FILE_name_AtoW( source, FALSE ))) return FALSE;
|
||||
if (!(destW = FILE_name_AtoW( dest, TRUE ))) return FALSE;
|
||||
ret = MoveFileExW( sourceW, destW, flag );
|
||||
HeapFree( GetProcessHeap(), 0, destW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1280,21 +1199,10 @@ BOOL WINAPI CreateDirectoryW( LPCWSTR path, LPSECURITY_ATTRIBUTES sa )
|
|||
*/
|
||||
BOOL WINAPI CreateDirectoryA( LPCSTR path, LPSECURITY_ATTRIBUTES sa )
|
||||
{
|
||||
UNICODE_STRING pathW;
|
||||
BOOL ret;
|
||||
WCHAR *pathW;
|
||||
|
||||
if (path)
|
||||
{
|
||||
if (!RtlCreateUnicodeStringFromAsciiz(&pathW, path))
|
||||
{
|
||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else pathW.Buffer = NULL;
|
||||
ret = CreateDirectoryW( pathW.Buffer, sa );
|
||||
RtlFreeUnicodeString( &pathW );
|
||||
return ret;
|
||||
if (!(pathW = FILE_name_AtoW( path, FALSE ))) return FALSE;
|
||||
return CreateDirectoryW( pathW, sa );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1303,33 +1211,14 @@ BOOL WINAPI CreateDirectoryA( 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;
|
||||
|
||||
if (path)
|
||||
{
|
||||
if (!RtlCreateUnicodeStringFromAsciiz( &pathW, path ))
|
||||
{
|
||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else pathW.Buffer = NULL;
|
||||
if (!(pathW = FILE_name_AtoW( path, FALSE ))) return FALSE;
|
||||
if (template && !(templateW = FILE_name_AtoW( template, TRUE ))) return FALSE;
|
||||
|
||||
if (template)
|
||||
{
|
||||
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 );
|
||||
ret = CreateDirectoryExW( templateW, pathW, sa );
|
||||
if (templateW) HeapFree( GetProcessHeap(), 0, templateW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1395,23 +1284,10 @@ BOOL WINAPI RemoveDirectoryW( LPCWSTR path )
|
|||
*/
|
||||
BOOL WINAPI RemoveDirectoryA( LPCSTR path )
|
||||
{
|
||||
UNICODE_STRING pathW;
|
||||
BOOL ret = FALSE;
|
||||
WCHAR *pathW;
|
||||
|
||||
if (!path)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (RtlCreateUnicodeStringFromAsciiz(&pathW, path))
|
||||
{
|
||||
ret = RemoveDirectoryW(pathW.Buffer);
|
||||
RtlFreeUnicodeString(&pathW);
|
||||
}
|
||||
else
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return ret;
|
||||
if (!(pathW = FILE_name_AtoW( path, FALSE ))) return FALSE;
|
||||
return RemoveDirectoryW( pathW );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1430,27 +1306,17 @@ UINT WINAPI GetCurrentDirectoryW( UINT buflen, LPWSTR buf )
|
|||
UINT WINAPI GetCurrentDirectoryA( UINT buflen, LPSTR buf )
|
||||
{
|
||||
WCHAR bufferW[MAX_PATH];
|
||||
DWORD ret, retW;
|
||||
DWORD ret;
|
||||
|
||||
retW = GetCurrentDirectoryW(MAX_PATH, bufferW);
|
||||
ret = GetCurrentDirectoryW(MAX_PATH, bufferW);
|
||||
|
||||
if (!retW)
|
||||
ret = 0;
|
||||
else if (retW > MAX_PATH)
|
||||
if (!ret) return 0;
|
||||
if (ret > MAX_PATH)
|
||||
{
|
||||
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
||||
ret = 0;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
return copy_filename_WtoA( bufferW, buf, buflen );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1478,21 +1344,88 @@ BOOL WINAPI SetCurrentDirectoryW( LPCWSTR dir )
|
|||
*/
|
||||
BOOL WINAPI SetCurrentDirectoryA( LPCSTR dir )
|
||||
{
|
||||
UNICODE_STRING dirW;
|
||||
NTSTATUS status;
|
||||
WCHAR *dirW;
|
||||
|
||||
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 );
|
||||
return FALSE;
|
||||
strcpyW( path, DIR_Windows );
|
||||
len--;
|
||||
}
|
||||
status = RtlSetCurrentDirectory_U( &dirW );
|
||||
if (status != STATUS_SUCCESS)
|
||||
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 )
|
||||
{
|
||||
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) );
|
||||
return FALSE;
|
||||
strcpyW( path, DIR_System );
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -62,7 +62,6 @@ static HANDLE main_exe_file;
|
|||
static DWORD shutdown_flags = 0;
|
||||
static DWORD shutdown_priority = 0x280;
|
||||
static DWORD process_dword;
|
||||
static BOOL oem_file_apis;
|
||||
|
||||
static unsigned int server_startticks;
|
||||
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 )
|
||||
{
|
||||
WCHAR *file_part;
|
||||
WCHAR sysdir[MAX_PATH];
|
||||
UINT len = GetSystemDirectoryW( sysdir, MAX_PATH );
|
||||
UINT len = strlenW( DIR_System );
|
||||
|
||||
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))
|
||||
return FALSE; /* too long */
|
||||
|
||||
if (strncmpiW( filename, sysdir, len ) || filename[len] != '\\')
|
||||
if (strncmpiW( filename, DIR_System, len ) || filename[len] != '\\')
|
||||
return FALSE;
|
||||
while (filename[len] == '\\') len++;
|
||||
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
|
||||
{
|
||||
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;
|
||||
if (file_part > filename && file_part[-1] != '\\') *file_part++ = '\\';
|
||||
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,
|
||||
LPSTARTUPINFOA startup_info, LPPROCESS_INFORMATION info )
|
||||
{
|
||||
BOOL ret;
|
||||
UNICODE_STRING app_nameW, cmd_lineW, cur_dirW, desktopW, titleW;
|
||||
BOOL ret = FALSE;
|
||||
WCHAR *app_nameW = NULL, *cmd_lineW = NULL, *cur_dirW = NULL;
|
||||
UNICODE_STRING desktopW, titleW;
|
||||
STARTUPINFOW infoW;
|
||||
|
||||
if (app_name) RtlCreateUnicodeStringFromAsciiz( &app_nameW, app_name );
|
||||
else app_nameW.Buffer = NULL;
|
||||
if (cmd_line) RtlCreateUnicodeStringFromAsciiz( &cmd_lineW, cmd_line );
|
||||
else cmd_lineW.Buffer = NULL;
|
||||
if (cur_dir) RtlCreateUnicodeStringFromAsciiz( &cur_dirW, cur_dir );
|
||||
else cur_dirW.Buffer = NULL;
|
||||
desktopW.Buffer = NULL;
|
||||
titleW.Buffer = NULL;
|
||||
if (app_name && !(app_nameW = FILE_name_AtoW( app_name, TRUE ))) goto done;
|
||||
if (cmd_line && !(cmd_lineW = FILE_name_AtoW( cmd_line, TRUE ))) goto done;
|
||||
if (cur_dir && !(cur_dirW = FILE_name_AtoW( cur_dir, TRUE ))) goto done;
|
||||
|
||||
if (startup_info->lpDesktop) RtlCreateUnicodeStringFromAsciiz( &desktopW, startup_info->lpDesktop );
|
||||
else desktopW.Buffer = NULL;
|
||||
if (startup_info->lpTitle) RtlCreateUnicodeStringFromAsciiz( &titleW, startup_info->lpTitle );
|
||||
else titleW.Buffer = NULL;
|
||||
|
||||
memcpy( &infoW, startup_info, sizeof(infoW) );
|
||||
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",
|
||||
debugstr_a(startup_info->lpReserved));
|
||||
|
||||
ret = CreateProcessW( app_nameW.Buffer, cmd_lineW.Buffer, process_attr, thread_attr,
|
||||
inherit, flags, env, cur_dirW.Buffer, &infoW, info );
|
||||
|
||||
RtlFreeUnicodeString( &app_nameW );
|
||||
RtlFreeUnicodeString( &cmd_lineW );
|
||||
RtlFreeUnicodeString( &cur_dirW );
|
||||
ret = CreateProcessW( app_nameW, cmd_lineW, process_attr, thread_attr,
|
||||
inherit, flags, env, cur_dirW, &infoW, info );
|
||||
done:
|
||||
if (app_nameW) HeapFree( GetProcessHeap(), 0, app_nameW );
|
||||
if (cmd_lineW) HeapFree( GetProcessHeap(), 0, cmd_lineW );
|
||||
if (cur_dirW) HeapFree( GetProcessHeap(), 0, cur_dirW );
|
||||
RtlFreeUnicodeString( &desktopW );
|
||||
RtlFreeUnicodeString( &titleW );
|
||||
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)
|
||||
* GetTickCount (KERNEL32.@)
|
||||
|
|
|
@ -859,27 +859,26 @@ fill_fs_info: /* now fill in the information that depends on the file system ty
|
|||
* GetVolumeInformationA (KERNEL32.@)
|
||||
*/
|
||||
BOOL WINAPI GetVolumeInformationA( LPCSTR root, LPSTR label,
|
||||
DWORD label_len, DWORD *serial,
|
||||
DWORD *filename_len, DWORD *flags,
|
||||
LPSTR fsname, DWORD fsname_len )
|
||||
DWORD label_len, DWORD *serial,
|
||||
DWORD *filename_len, DWORD *flags,
|
||||
LPSTR fsname, DWORD fsname_len )
|
||||
{
|
||||
UNICODE_STRING rootW;
|
||||
WCHAR *rootW = NULL;
|
||||
LPWSTR labelW, fsnameW;
|
||||
BOOL ret;
|
||||
|
||||
if (root) RtlCreateUnicodeStringFromAsciiz(&rootW, root);
|
||||
else rootW.Buffer = NULL;
|
||||
if (root && !(rootW = FILE_name_AtoW( root, FALSE ))) return FALSE;
|
||||
|
||||
labelW = label ? HeapAlloc(GetProcessHeap(), 0, label_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)))
|
||||
{
|
||||
if (label) WideCharToMultiByte(CP_ACP, 0, labelW, -1, label, label_len, NULL, NULL);
|
||||
if (fsname) WideCharToMultiByte(CP_ACP, 0, fsnameW, -1, fsname, fsname_len, NULL, NULL);
|
||||
if (label) FILE_name_WtoA( labelW, -1, label, label_len );
|
||||
if (fsname) FILE_name_WtoA( fsnameW, -1, fsname, fsname_len );
|
||||
}
|
||||
|
||||
RtlFreeUnicodeString(&rootW);
|
||||
if (labelW) HeapFree( GetProcessHeap(), 0, labelW );
|
||||
if (fsnameW) HeapFree( GetProcessHeap(), 0, fsnameW );
|
||||
return ret;
|
||||
|
@ -989,18 +988,13 @@ BOOL WINAPI SetVolumeLabelW( LPCWSTR root, LPCWSTR label )
|
|||
*/
|
||||
BOOL WINAPI SetVolumeLabelA(LPCSTR root, LPCSTR volname)
|
||||
{
|
||||
UNICODE_STRING rootW, volnameW;
|
||||
WCHAR *rootW = NULL, *volnameW = NULL;
|
||||
BOOL ret;
|
||||
|
||||
if (root) RtlCreateUnicodeStringFromAsciiz(&rootW, root);
|
||||
else rootW.Buffer = NULL;
|
||||
if (volname) RtlCreateUnicodeStringFromAsciiz(&volnameW, volname);
|
||||
else volnameW.Buffer = NULL;
|
||||
|
||||
ret = SetVolumeLabelW( rootW.Buffer, volnameW.Buffer );
|
||||
|
||||
RtlFreeUnicodeString(&rootW);
|
||||
RtlFreeUnicodeString(&volnameW);
|
||||
if (root && !(rootW = FILE_name_AtoW( root, FALSE ))) return FALSE;
|
||||
if (volname && !(volnameW = FILE_name_AtoW( volname, TRUE ))) return FALSE;
|
||||
ret = SetVolumeLabelW( rootW, volnameW );
|
||||
if (volnameW) HeapFree( GetProcessHeap(), 0, volnameW );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1091,23 +1085,13 @@ BOOL WINAPI DefineDosDeviceW( DWORD flags, LPCWSTR devname, LPCWSTR targetpath )
|
|||
*/
|
||||
BOOL WINAPI DefineDosDeviceA(DWORD flags, LPCSTR devname, LPCSTR targetpath)
|
||||
{
|
||||
UNICODE_STRING d, t;
|
||||
WCHAR *devW, *targetW = NULL;
|
||||
BOOL ret;
|
||||
|
||||
if (!RtlCreateUnicodeStringFromAsciiz(&d, devname))
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
if (!RtlCreateUnicodeStringFromAsciiz(&t, targetpath))
|
||||
{
|
||||
RtlFreeUnicodeString(&d);
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
ret = DefineDosDeviceW(flags, d.Buffer, t.Buffer);
|
||||
RtlFreeUnicodeString(&d);
|
||||
RtlFreeUnicodeString(&t);
|
||||
if (!(devW = FILE_name_AtoW( devname, FALSE ))) return FALSE;
|
||||
if (targetpath && !(targetW = FILE_name_AtoW( targetpath, TRUE ))) return FALSE;
|
||||
ret = DefineDosDeviceW(flags, devW, targetW);
|
||||
if (targetW) HeapFree( GetProcessHeap(), 0, targetW );
|
||||
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 ret = 0, retW;
|
||||
UNICODE_STRING devnameW;
|
||||
LPWSTR targetW = HeapAlloc( GetProcessHeap(),0, bufsize * sizeof(WCHAR) );
|
||||
WCHAR *devnameW;
|
||||
LPWSTR targetW;
|
||||
|
||||
if (!(devnameW = FILE_name_AtoW( devname, FALSE ))) return 0;
|
||||
|
||||
targetW = HeapAlloc( GetProcessHeap(),0, bufsize * sizeof(WCHAR) );
|
||||
if (!targetW)
|
||||
{
|
||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (devname) RtlCreateUnicodeStringFromAsciiz(&devnameW, devname);
|
||||
else devnameW.Buffer = NULL;
|
||||
retW = QueryDosDeviceW(devnameW, targetW, bufsize);
|
||||
|
||||
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);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1472,23 +1455,10 @@ UINT WINAPI GetDriveTypeW(LPCWSTR root) /* [in] String describing drive */
|
|||
*/
|
||||
UINT WINAPI GetDriveTypeA( LPCSTR root )
|
||||
{
|
||||
UNICODE_STRING rootW;
|
||||
UINT ret;
|
||||
WCHAR *rootW = NULL;
|
||||
|
||||
if (root)
|
||||
{
|
||||
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;
|
||||
if (root && !(rootW = FILE_name_AtoW( root, FALSE ))) return DRIVE_NO_ROOT_DIR;
|
||||
return GetDriveTypeW( rootW );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1540,16 +1510,10 @@ BOOL WINAPI GetDiskFreeSpaceExW( LPCWSTR root, PULARGE_INTEGER avail,
|
|||
BOOL WINAPI GetDiskFreeSpaceExA( LPCSTR root, PULARGE_INTEGER avail,
|
||||
PULARGE_INTEGER total, PULARGE_INTEGER totalfree )
|
||||
{
|
||||
UNICODE_STRING rootW;
|
||||
BOOL ret;
|
||||
WCHAR *rootW = NULL;
|
||||
|
||||
if (root) RtlCreateUnicodeStringFromAsciiz(&rootW, root);
|
||||
else rootW.Buffer = NULL;
|
||||
|
||||
ret = GetDiskFreeSpaceExW( rootW.Buffer, avail, total, totalfree);
|
||||
|
||||
RtlFreeUnicodeString(&rootW);
|
||||
return ret;
|
||||
if (root && !(rootW = FILE_name_AtoW( root, FALSE ))) return FALSE;
|
||||
return GetDiskFreeSpaceExW( rootW, avail, total, totalfree );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1602,22 +1566,8 @@ BOOL WINAPI GetDiskFreeSpaceA( LPCSTR root, LPDWORD cluster_sectors,
|
|||
LPDWORD sector_bytes, LPDWORD free_clusters,
|
||||
LPDWORD total_clusters )
|
||||
{
|
||||
UNICODE_STRING rootW;
|
||||
BOOL ret = FALSE;
|
||||
WCHAR *rootW = NULL;
|
||||
|
||||
if (root)
|
||||
{
|
||||
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;
|
||||
if (root && !(rootW = FILE_name_AtoW( root, FALSE ))) return FALSE;
|
||||
return GetDiskFreeSpaceW( rootW, cluster_sectors, sector_bytes, free_clusters, total_clusters );
|
||||
}
|
||||
|
|
|
@ -53,8 +53,8 @@ WINE_DECLARE_DEBUG_CHANNEL(file);
|
|||
|
||||
#define MAX_PATHNAME_LEN 1024
|
||||
|
||||
static WCHAR *DIR_Windows;
|
||||
static WCHAR *DIR_System;
|
||||
WCHAR *DIR_Windows = NULL;
|
||||
WCHAR *DIR_System = NULL;
|
||||
|
||||
/***********************************************************************
|
||||
* DIR_GetPath
|
||||
|
@ -233,93 +233,3 @@ int DIR_Init(void)
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue