Convert most of the file APIs to Unicode.

This commit is contained in:
Dmitry Timoshkov 2002-08-27 01:13:58 +00:00 committed by Alexandre Julliard
parent ad0b42a099
commit d75aed2c92
21 changed files with 2874 additions and 1579 deletions

View file

@ -20,7 +20,9 @@
#include "wine/winbase16.h"
#include "winbase.h"
#include "winerror.h"
#include "wownt32.h"
#include "ntddk.h"
#include "file.h"
#include "miscemu.h"
#include "stackframe.h"
@ -319,17 +321,35 @@ DWORD WINAPI LoadLibraryEx32W16( LPCSTR lpszLibFile, DWORD hFile, DWORD dwFlags
HMODULE hModule;
DOS_FULL_NAME full_name;
DWORD mutex_count;
UNICODE_STRING libfileW;
LPCWSTR filenameW;
static const WCHAR dllW[] = {'.','D','L','L',0};
if (!lpszLibFile)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!RtlCreateUnicodeStringFromAsciiz(&libfileW, lpszLibFile))
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
}
/* if the file can not be found, call LoadLibraryExA anyway, since it might be
a buildin module. This case is handled in MODULE_LoadLibraryExA */
if ( ! DIR_SearchPath ( NULL, lpszLibFile, ".DLL", &full_name, FALSE ) ) {
strcpy ( full_name.short_name, lpszLibFile );
}
filenameW = libfileW.Buffer;
if ( DIR_SearchPath( NULL, filenameW, dllW, &full_name, FALSE ) )
filenameW = full_name.short_name;
ReleaseThunkLock( &mutex_count );
hModule = LoadLibraryExA( full_name.short_name, (HANDLE)hFile, dwFlags );
hModule = LoadLibraryExW( filenameW, (HANDLE)hFile, dwFlags );
RestoreThunkLock( mutex_count );
RtlFreeUnicodeString(&libfileW);
return (DWORD)hModule;
}

View file

@ -29,6 +29,7 @@
#ifdef HAVE_SYS_ERRNO_H
#include <sys/errno.h>
#endif
#include "wine/unicode.h"
#include "wine/debug.h"
#include "wine/server.h"
#include "ntdll_misc.h"
@ -60,9 +61,8 @@ NTSTATUS WINAPI NtOpenFile(
ULONG ShareAccess,
ULONG OpenOptions)
{
ULONG len = 0;
PSTR filename;
CHAR szDosDevices[] = "\\DosDevices\\";
LPWSTR filename;
static const WCHAR szDosDevices[] = {'\\','D','o','s','D','e','v','i','c','e','s','\\',0};
DOS_FULL_NAME full_name;
NTSTATUS r;
@ -79,20 +79,14 @@ NTSTATUS WINAPI NtOpenFile(
return STATUS_OBJECT_NAME_NOT_FOUND;
}
/* create an ascii string from the unicode filename */
RtlUnicodeToMultiByteSize( &len, ObjectAttributes->ObjectName->Buffer,
ObjectAttributes->ObjectName->Length );
filename = RtlAllocateHeap( GetProcessHeap(), 0, len + 1);
RtlUnicodeToMultiByteN(filename, len, NULL, ObjectAttributes->ObjectName->Buffer,
ObjectAttributes->ObjectName->Length );
filename[len]=0;
filename = ObjectAttributes->ObjectName->Buffer;
/* FIXME: DOSFS stuff should call here, not vice-versa */
if(strncmp(filename, szDosDevices, strlen(szDosDevices)))
if(strncmpW(filename, szDosDevices, strlenW(szDosDevices)))
return STATUS_OBJECT_NAME_NOT_FOUND;
/* FIXME: this calls SetLastError() -> bad */
if(!DOSFS_GetFullName(&filename[strlen(szDosDevices)], TRUE,
if(!DOSFS_GetFullName(&filename[strlenW(szDosDevices)], TRUE,
&full_name))
return STATUS_OBJECT_NAME_NOT_FOUND;
@ -105,7 +99,7 @@ NTSTATUS WINAPI NtOpenFile(
req->sharing = ShareAccess;
req->create = OPEN_EXISTING;
req->attrs = 0;
req->drive_type = GetDriveTypeA( full_name.short_name );
req->drive_type = GetDriveTypeW( full_name.short_name );
wine_server_add_data( req, full_name.long_name, strlen(full_name.long_name) );
SetLastError(0);
r = wine_server_call( req );

View file

@ -32,16 +32,18 @@
#include "miscemu.h"
#include "msdos.h"
#include "file.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(int21);
void WINAPI DOSVM_Int21Handler_Ioctl( CONTEXT86 *context )
{
static const WCHAR emmxxxx0W[] = {'E','M','M','X','X','X','X','0',0};
const DOS_DEVICE *dev = DOSFS_GetDeviceByHandle(
DosFileHandleToWin32Handle(BX_reg(context)) );
if (dev && !strcasecmp( dev->name, "EMMXXXX0" )) {
if (dev && !strcmpiW( dev->name, emmxxxx0W )) {
EMS_Ioctl_Handler(context);
return;
}

View file

@ -41,6 +41,8 @@
#include "wine/winuser16.h"
#include "winerror.h"
#include "winreg.h"
#include "ntddk.h"
#include "wine/unicode.h"
#include "drive.h"
#include "file.h"
#include "heap.h"
@ -53,27 +55,30 @@ WINE_DECLARE_DEBUG_CHANNEL(file);
static DOS_FULL_NAME DIR_Windows;
static DOS_FULL_NAME DIR_System;
static const WCHAR wineW[] = {'w','i','n','e',0};
/***********************************************************************
* DIR_GetPath
*
* Get a path name from the wine.ini file and make sure it is valid.
*/
static int DIR_GetPath( const char *keyname, const char *defval,
DOS_FULL_NAME *full_name, char * longname, BOOL warn )
static int DIR_GetPath( LPCWSTR keyname, LPCWSTR defval, DOS_FULL_NAME *full_name,
LPWSTR longname, INT longname_len, BOOL warn )
{
char path[MAX_PATHNAME_LEN];
WCHAR path[MAX_PATHNAME_LEN];
BY_HANDLE_FILE_INFORMATION info;
const char *mess = "does not exist";
PROFILE_GetWineIniString( "wine", keyname, defval, path, sizeof(path) );
PROFILE_GetWineIniString( wineW, keyname, defval, path, MAX_PATHNAME_LEN );
if (!DOSFS_GetFullName( path, TRUE, full_name ) ||
(!FILE_Stat( full_name->long_name, &info ) && (mess=strerror(errno)))||
(!(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (mess="not a directory")) ||
(!(GetLongPathNameA(full_name->short_name, longname, MAX_PATHNAME_LEN))) )
(!(GetLongPathNameW(full_name->short_name, longname, longname_len))) )
{
if (warn)
MESSAGE("Invalid path '%s' for %s directory: %s\n", path, keyname, mess);
MESSAGE("Invalid path %s for %s directory: %s\n",
debugstr_w(path), debugstr_w(keyname), mess);
return 0;
}
return 1;
@ -86,10 +91,27 @@ static int DIR_GetPath( const char *keyname, const char *defval,
int DIR_Init(void)
{
char path[MAX_PATHNAME_LEN];
char longpath[MAX_PATHNAME_LEN];
WCHAR longpath[MAX_PATHNAME_LEN];
DOS_FULL_NAME tmp_dir, profile_dir;
int drive;
const char *cwd;
static const WCHAR windowsW[] = {'w','i','n','d','o','w','s',0};
static const WCHAR systemW[] = {'s','y','s','t','e','m',0};
static const WCHAR tempW[] = {'t','e','m','p',0};
static const WCHAR profileW[] = {'p','r','o','f','i','l','e',0};
static const WCHAR windows_dirW[] = {'c',':','\\','w','i','n','d','o','w','s',0};
static const WCHAR system_dirW[] = {'c',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m',0};
static const WCHAR pathW[] = {'p','a','t','h',0};
static const WCHAR path_dirW[] = {'c',':','\\','w','i','n','d','o','w','s',';',
'c',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m',0};
static const WCHAR path_capsW[] = {'P','A','T','H',0};
static const WCHAR temp_capsW[] = {'T','E','M','P',0};
static const WCHAR tmp_capsW[] = {'T','M','P',0};
static const WCHAR windirW[] = {'w','i','n','d','i','r',0};
static const WCHAR winsysdirW[] = {'w','i','n','s','y','s','d','i','r',0};
static const WCHAR userprofileW[] = {'U','S','E','R','P','R','O','F','I','L','E',0};
static const WCHAR systemrootW[] = {'S','Y','S','T','E','M','R','O','O','T',0};
static const WCHAR empty_strW[] = { 0 };
if (!getcwd( path, MAX_PATHNAME_LEN ))
{
@ -105,13 +127,17 @@ int DIR_Init(void)
}
else
{
WCHAR szdrive[3]={drive+'A',':',0};
MultiByteToWideChar(DRIVE_GetCodepage(drive), 0, cwd, -1, longpath, MAX_PATHNAME_LEN);
DRIVE_SetCurrentDrive( drive );
DRIVE_Chdir( drive, cwd );
DRIVE_Chdir( drive, longpath );
if(GetDriveTypeW(szdrive)==DRIVE_CDROM)
chdir("/"); /* change to root directory so as not to lock cdroms */
}
if (!(DIR_GetPath( "windows", "c:\\windows", &DIR_Windows, longpath, TRUE )) ||
!(DIR_GetPath( "system", "c:\\windows\\system", &DIR_System, longpath, TRUE )) ||
!(DIR_GetPath( "temp", "c:\\windows", &tmp_dir, longpath, TRUE )))
if (!(DIR_GetPath( windowsW, windows_dirW, &DIR_Windows, longpath, MAX_PATHNAME_LEN, TRUE )) ||
!(DIR_GetPath( systemW, system_dirW, &DIR_System, longpath, MAX_PATHNAME_LEN, TRUE )) ||
!(DIR_GetPath( tempW, windows_dirW, &tmp_dir, longpath, MAX_PATHNAME_LEN, TRUE )))
{
PROFILE_UsageWineIni();
return 0;
@ -135,9 +161,8 @@ int DIR_Init(void)
DRIVE_Chdir( drive, DIR_Windows.short_name + 2 );
}
PROFILE_GetWineIniString("wine", "path", "c:\\windows;c:\\windows\\system",
path, sizeof(path) );
if (strchr(path, '/'))
PROFILE_GetWineIniString(wineW, pathW, path_dirW, longpath, MAX_PATHNAME_LEN);
if (strchrW(longpath, '/'))
{
MESSAGE("Fix your wine config to use DOS drive syntax in [wine] 'Path=' statement! (no '/' allowed)\n");
PROFILE_UsageWineIni();
@ -146,34 +171,34 @@ int DIR_Init(void)
/* Set the environment variables */
SetEnvironmentVariableA( "PATH", path );
SetEnvironmentVariableA( "TEMP", tmp_dir.short_name );
SetEnvironmentVariableA( "TMP", tmp_dir.short_name );
SetEnvironmentVariableA( "windir", DIR_Windows.short_name );
SetEnvironmentVariableA( "winsysdir", DIR_System.short_name );
SetEnvironmentVariableW( path_capsW, longpath );
SetEnvironmentVariableW( temp_capsW, tmp_dir.short_name );
SetEnvironmentVariableW( tmp_capsW, tmp_dir.short_name );
SetEnvironmentVariableW( windirW, DIR_Windows.short_name );
SetEnvironmentVariableW( winsysdirW, DIR_System.short_name );
/* set COMSPEC only if it doesn't exist already */
if (!GetEnvironmentVariableA( "COMSPEC", NULL, 0 ))
SetEnvironmentVariableA( "COMSPEC", "c:\\command.com" );
TRACE("WindowsDir = %s (%s)\n",
DIR_Windows.short_name, DIR_Windows.long_name );
debugstr_w(DIR_Windows.short_name), DIR_Windows.long_name );
TRACE("SystemDir = %s (%s)\n",
DIR_System.short_name, DIR_System.long_name );
debugstr_w(DIR_System.short_name), DIR_System.long_name );
TRACE("TempDir = %s (%s)\n",
tmp_dir.short_name, tmp_dir.long_name );
TRACE("Path = %s\n", path );
debugstr_w(tmp_dir.short_name), tmp_dir.long_name );
TRACE("Path = %s\n", debugstr_w(longpath) );
TRACE("Cwd = %c:\\%s\n",
'A' + drive, DRIVE_GetDosCwd( drive ) );
'A' + drive, debugstr_w(DRIVE_GetDosCwd(drive)) );
if (DIR_GetPath( "profile", "", &profile_dir, longpath, FALSE ))
if (DIR_GetPath( profileW, empty_strW, &profile_dir, longpath, MAX_PATHNAME_LEN, FALSE ))
{
TRACE("USERPROFILE= %s\n", longpath );
SetEnvironmentVariableA( "USERPROFILE", longpath );
TRACE("USERPROFILE= %s\n", debugstr_w(longpath) );
SetEnvironmentVariableW( userprofileW, longpath );
}
TRACE("SYSTEMROOT = %s\n", DIR_Windows.short_name );
SetEnvironmentVariableA( "SYSTEMROOT", DIR_Windows.short_name );
TRACE("SYSTEMROOT = %s\n", debugstr_w(DIR_Windows.short_name) );
SetEnvironmentVariableW( systemrootW, DIR_Windows.short_name );
return 1;
}
@ -184,15 +209,25 @@ int DIR_Init(void)
*/
UINT WINAPI GetTempPathA( UINT count, LPSTR path )
{
WCHAR pathW[MAX_PATH];
UINT ret;
if (!(ret = GetEnvironmentVariableA( "TMP", path, count )))
if (!(ret = GetEnvironmentVariableA( "TEMP", path, count )))
if (!(ret = GetCurrentDirectoryA( count, path )))
return 0;
if (count && (ret < count - 1) && (path[ret-1] != '\\'))
ret = GetTempPathW(MAX_PATH, pathW);
if (!ret)
return 0;
if (ret > MAX_PATH)
{
path[ret++] = '\\';
path[ret] = '\0';
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;
}
@ -205,16 +240,49 @@ UINT WINAPI GetTempPathW( UINT count, LPWSTR path )
{
static const WCHAR tmp[] = { 'T', 'M', 'P', 0 };
static const WCHAR temp[] = { 'T', 'E', 'M', 'P', 0 };
WCHAR tmp_path[MAX_PATH];
UINT ret;
if (!(ret = GetEnvironmentVariableW( tmp, path, count )))
if (!(ret = GetEnvironmentVariableW( temp, path, count )))
if (!(ret = GetCurrentDirectoryW( count, path )))
TRACE("%u,%p\n", count, path);
if (!(ret = GetEnvironmentVariableW( tmp, tmp_path, MAX_PATH )))
if (!(ret = GetEnvironmentVariableW( temp, tmp_path, MAX_PATH )))
if (!(ret = GetCurrentDirectoryW( MAX_PATH, tmp_path )))
return 0;
if (count && (ret < count - 1) && (path[ret-1] != '\\'))
if (ret > MAX_PATH)
{
path[ret++] = '\\';
path[ret] = '\0';
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
ret = GetFullPathNameW(tmp_path, MAX_PATH, tmp_path, NULL);
if (!ret) return 0;
if (ret > MAX_PATH - 2)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
if (tmp_path[ret-1] != '\\')
{
tmp_path[ret++] = '\\';
tmp_path[ret] = '\0';
}
ret++; /* add space for terminating 0 */
if (count)
{
lstrcpynW(path, tmp_path, count);
if (count >= ret)
ret--; /* return length without 0 */
else if (count < 4)
path[0] = 0; /* avoid returning ambiguous "X:" */
}
TRACE("returning %u, %s\n", ret, debugstr_w(path));
return ret;
}
@ -278,16 +346,16 @@ UINT16 WINAPI GetWindowsDirectory16( LPSTR path, UINT16 count )
/***********************************************************************
* GetWindowsDirectoryA (KERNEL32.@)
* GetWindowsDirectoryW (KERNEL32.@)
*
* See comment for GetWindowsDirectoryW.
* See comment for GetWindowsDirectoryA.
*/
UINT WINAPI GetWindowsDirectoryA( LPSTR path, UINT count )
UINT WINAPI GetWindowsDirectoryW( LPWSTR path, UINT count )
{
UINT len = strlen( DIR_Windows.short_name ) + 1;
UINT len = strlenW( DIR_Windows.short_name ) + 1;
if (path && count >= len)
{
strcpy( path, DIR_Windows.short_name );
strcpyW( path, DIR_Windows.short_name );
len--;
}
return len;
@ -295,7 +363,7 @@ UINT WINAPI GetWindowsDirectoryA( LPSTR path, UINT count )
/***********************************************************************
* GetWindowsDirectoryW (KERNEL32.@)
* GetWindowsDirectoryA (KERNEL32.@)
*
* Return value:
* If buffer is large enough to hold full path and terminating '\0' character
@ -303,12 +371,12 @@ UINT WINAPI GetWindowsDirectoryA( LPSTR path, UINT count )
* Otherwise function returns required size including '\0' character and
* does not touch the buffer.
*/
UINT WINAPI GetWindowsDirectoryW( LPWSTR path, UINT count )
UINT WINAPI GetWindowsDirectoryA( LPSTR path, UINT count )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, DIR_Windows.short_name, -1, NULL, 0 );
UINT len = WideCharToMultiByte( CP_ACP, 0, DIR_Windows.short_name, -1, NULL, 0, NULL, NULL );
if (path && count >= len)
{
MultiByteToWideChar( CP_ACP, 0, DIR_Windows.short_name, -1, path, count );
WideCharToMultiByte( CP_ACP, 0, DIR_Windows.short_name, -1, path, count, NULL, NULL );
len--;
}
return len;
@ -343,16 +411,16 @@ UINT16 WINAPI GetSystemDirectory16( LPSTR path, UINT16 count )
/***********************************************************************
* GetSystemDirectoryA (KERNEL32.@)
* GetSystemDirectoryW (KERNEL32.@)
*
* See comment for GetWindowsDirectoryW.
* See comment for GetWindowsDirectoryA.
*/
UINT WINAPI GetSystemDirectoryA( LPSTR path, UINT count )
UINT WINAPI GetSystemDirectoryW( LPWSTR path, UINT count )
{
UINT len = strlen( DIR_System.short_name ) + 1;
UINT len = strlenW( DIR_System.short_name ) + 1;
if (path && count >= len)
{
strcpy( path, DIR_System.short_name );
strcpyW( path, DIR_System.short_name );
len--;
}
return len;
@ -360,16 +428,16 @@ UINT WINAPI GetSystemDirectoryA( LPSTR path, UINT count )
/***********************************************************************
* GetSystemDirectoryW (KERNEL32.@)
* GetSystemDirectoryA (KERNEL32.@)
*
* See comment for GetWindowsDirectoryW.
* See comment for GetWindowsDirectoryA.
*/
UINT WINAPI GetSystemDirectoryW( LPWSTR path, UINT count )
UINT WINAPI GetSystemDirectoryA( LPSTR path, UINT count )
{
UINT len = MultiByteToWideChar( CP_ACP, 0, DIR_System.short_name, -1, NULL, 0 );
UINT len = WideCharToMultiByte( CP_ACP, 0, DIR_System.short_name, -1, NULL, 0, NULL, NULL );
if (path && count >= len)
{
MultiByteToWideChar( CP_ACP, 0, DIR_System.short_name, -1, path, count );
WideCharToMultiByte( CP_ACP, 0, DIR_System.short_name, -1, path, count, NULL, NULL );
len--;
}
return len;
@ -387,7 +455,7 @@ BOOL16 WINAPI CreateDirectory16( LPCSTR path, LPVOID dummy )
/***********************************************************************
* CreateDirectoryA (KERNEL32.@)
* CreateDirectoryW (KERNEL32.@)
* RETURNS:
* TRUE : success
* FALSE : failure
@ -396,15 +464,22 @@ BOOL16 WINAPI CreateDirectory16( LPCSTR path, LPVOID dummy )
* ERROR_ACCESS_DENIED: on permission problems
* ERROR_FILENAME_EXCED_RANGE: too long filename(s)
*/
BOOL WINAPI CreateDirectoryA( LPCSTR path,
BOOL WINAPI CreateDirectoryW( LPCWSTR path,
LPSECURITY_ATTRIBUTES lpsecattribs )
{
DOS_FULL_NAME full_name;
TRACE_(file)("(%s,%p)\n", path, lpsecattribs );
if (!path || !*path)
{
SetLastError(ERROR_PATH_NOT_FOUND);
return FALSE;
}
TRACE_(file)("(%s,%p)\n", debugstr_w(path), lpsecattribs );
if (DOSFS_GetDevice( path ))
{
TRACE_(file)("cannot use device '%s'!\n",path);
TRACE_(file)("cannot use device %s!\n", debugstr_w(path));
SetLastError( ERROR_ACCESS_DENIED );
return FALSE;
}
@ -414,7 +489,14 @@ BOOL WINAPI CreateDirectoryA( LPCSTR path,
/* the FILE_SetDosError() generated error codes don't match the
* CreateDirectory ones for some errnos */
switch (errno) {
case EEXIST: SetLastError(ERROR_ALREADY_EXISTS); break;
case EEXIST:
{
if (!strcmp(DRIVE_GetRoot(full_name.drive), full_name.long_name))
SetLastError(ERROR_ACCESS_DENIED);
else
SetLastError(ERROR_ALREADY_EXISTS);
break;
}
case ENOSPC: SetLastError(ERROR_DISK_FULL); break;
default: FILE_SetDosError();break;
}
@ -425,14 +507,27 @@ BOOL WINAPI CreateDirectoryA( LPCSTR path,
/***********************************************************************
* CreateDirectoryW (KERNEL32.@)
* CreateDirectoryA (KERNEL32.@)
*/
BOOL WINAPI CreateDirectoryW( LPCWSTR path,
BOOL WINAPI CreateDirectoryA( LPCSTR path,
LPSECURITY_ATTRIBUTES lpsecattribs )
{
LPSTR xpath = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
BOOL ret = CreateDirectoryA( xpath, lpsecattribs );
HeapFree( GetProcessHeap(), 0, xpath );
UNICODE_STRING pathW;
BOOL ret = FALSE;
if (!path || !*path)
{
SetLastError(ERROR_PATH_NOT_FOUND);
return FALSE;
}
if (RtlCreateUnicodeStringFromAsciiz(&pathW, path))
{
ret = CreateDirectoryW(pathW.Buffer, lpsecattribs);
RtlFreeUnicodeString(&pathW);
}
else
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return ret;
}
@ -467,17 +562,23 @@ BOOL16 WINAPI RemoveDirectory16( LPCSTR path )
/***********************************************************************
* RemoveDirectoryA (KERNEL32.@)
* RemoveDirectoryW (KERNEL32.@)
*/
BOOL WINAPI RemoveDirectoryA( LPCSTR path )
BOOL WINAPI RemoveDirectoryW( LPCWSTR path )
{
DOS_FULL_NAME full_name;
TRACE_(file)("'%s'\n", path );
if (!path)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
TRACE_(file)("%s\n", debugstr_w(path));
if (DOSFS_GetDevice( path ))
{
TRACE_(file)("cannot remove device '%s'!\n", path);
TRACE_(file)("cannot remove device %s!\n", debugstr_w(path));
SetLastError( ERROR_FILE_NOT_FOUND );
return FALSE;
}
@ -492,13 +593,26 @@ BOOL WINAPI RemoveDirectoryA( LPCSTR path )
/***********************************************************************
* RemoveDirectoryW (KERNEL32.@)
* RemoveDirectoryA (KERNEL32.@)
*/
BOOL WINAPI RemoveDirectoryW( LPCWSTR path )
BOOL WINAPI RemoveDirectoryA( LPCSTR path )
{
LPSTR xpath = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
BOOL ret = RemoveDirectoryA( xpath );
HeapFree( GetProcessHeap(), 0, xpath );
UNICODE_STRING pathW;
BOOL ret = FALSE;
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;
}
@ -508,53 +622,58 @@ BOOL WINAPI RemoveDirectoryW( LPCWSTR path )
*
* Helper function for DIR_SearchPath.
*/
static BOOL DIR_TryPath( const DOS_FULL_NAME *dir, LPCSTR name,
static BOOL DIR_TryPath( const DOS_FULL_NAME *dir, LPCWSTR name,
DOS_FULL_NAME *full_name )
{
LPSTR p_l = full_name->long_name + strlen(dir->long_name) + 1;
LPSTR p_s = full_name->short_name + strlen(dir->short_name) + 1;
LPWSTR p_s = full_name->short_name + strlenW(dir->short_name) + 1;
if ((p_s >= full_name->short_name + sizeof(full_name->short_name) - 14) ||
if ((p_s >= full_name->short_name + sizeof(full_name->short_name)/sizeof(full_name->short_name[0]) - 14) ||
(p_l >= full_name->long_name + sizeof(full_name->long_name) - 1))
{
SetLastError( ERROR_PATH_NOT_FOUND );
return FALSE;
}
if (!DOSFS_FindUnixName( dir->long_name, name, p_l,
if (!DOSFS_FindUnixName( dir, name, p_l,
sizeof(full_name->long_name) - (p_l - full_name->long_name),
p_s, !(DRIVE_GetFlags(dir->drive) & DRIVE_CASE_SENSITIVE) ))
return FALSE;
full_name->drive = dir->drive;
strcpy( full_name->long_name, dir->long_name );
p_l[-1] = '/';
strcpy( full_name->short_name, dir->short_name );
strcpyW( full_name->short_name, dir->short_name );
p_s[-1] = '\\';
return TRUE;
}
static BOOL DIR_SearchSemicolonedPaths(LPCSTR name, DOS_FULL_NAME *full_name, LPSTR pathlist)
static BOOL DIR_SearchSemicolonedPaths(LPCWSTR name, DOS_FULL_NAME *full_name, LPWSTR pathlist)
{
LPSTR next, buffer = NULL;
INT len = strlen(name), newlen, currlen = 0;
LPWSTR next, buffer = NULL;
INT len = strlenW(name), newlen, currlen = 0;
BOOL ret = FALSE;
next = pathlist;
while (!ret && next)
{
LPSTR cur = next;
static const WCHAR bkslashW[] = {'\\',0};
LPWSTR cur = next;
while (*cur == ';') cur++;
if (!*cur) break;
next = strchr( cur, ';' );
next = strchrW( cur, ';' );
if (next) *next++ = '\0';
newlen = strlen(cur) + len + 2;
newlen = strlenW(cur) + len + 2;
if (newlen > currlen)
{
if (!(buffer = HeapReAlloc( GetProcessHeap(), 0, buffer, newlen)))
if (!(buffer = HeapReAlloc( GetProcessHeap(), 0, buffer, newlen * sizeof(WCHAR))))
goto done;
currlen = newlen;
}
strcpy( buffer, cur );
strcat( buffer, "\\" );
strcat( buffer, name );
strcpyW( buffer, cur );
strcatW( buffer, bkslashW );
strcatW( buffer, name );
ret = DOSFS_GetFullName( buffer, TRUE, full_name );
}
done:
@ -569,17 +688,18 @@ done:
* Helper function for DIR_SearchPath.
* Search in the specified path, or in $PATH if NULL.
*/
static BOOL DIR_TryEnvironmentPath( LPCSTR name, DOS_FULL_NAME *full_name, LPCSTR envpath )
static BOOL DIR_TryEnvironmentPath( LPCWSTR name, DOS_FULL_NAME *full_name, LPCWSTR envpath )
{
LPSTR path;
LPWSTR path;
BOOL ret = FALSE;
DWORD size;
static const WCHAR pathW[] = {'P','A','T','H',0};
size = envpath ? strlen(envpath)+1 : GetEnvironmentVariableA( "PATH", NULL, 0 );
size = envpath ? strlenW(envpath)+1 : GetEnvironmentVariableW( pathW, NULL, 0 );
if (!size) return FALSE;
if (!(path = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
if (envpath) strcpy( path, envpath );
else if (!GetEnvironmentVariableA( "PATH", path, size )) goto done;
if (!(path = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return FALSE;
if (envpath) strcpyW( path, envpath );
else if (!GetEnvironmentVariableW( pathW, path, size )) goto done;
ret = DIR_SearchSemicolonedPaths(name, full_name, path);
@ -594,27 +714,28 @@ done:
*
* Helper function for DIR_SearchPath.
*/
static BOOL DIR_TryModulePath( LPCSTR name, DOS_FULL_NAME *full_name, BOOL win32 )
static BOOL DIR_TryModulePath( LPCWSTR name, DOS_FULL_NAME *full_name, BOOL win32 )
{
/* FIXME: for now, GetModuleFileNameA can't return more */
/* FIXME: for now, GetModuleFileNameW can't return more */
/* than OFS_MAXPATHNAME. This may change with Win32. */
char buffer[OFS_MAXPATHNAME];
LPSTR p;
WCHAR bufferW[OFS_MAXPATHNAME];
LPWSTR p;
if (!win32)
{
char buffer[OFS_MAXPATHNAME];
if (!GetCurrentTask()) return FALSE;
if (!GetModuleFileName16( GetCurrentTask(), buffer, sizeof(buffer) ))
buffer[0]='\0';
return FALSE;
MultiByteToWideChar(CP_ACP, 0, buffer, -1, bufferW, OFS_MAXPATHNAME);
} else {
if (!GetModuleFileNameA( 0, buffer, sizeof(buffer) ))
buffer[0]='\0';
if (!GetModuleFileNameW( 0, bufferW, OFS_MAXPATHNAME ) )
return FALSE;
}
if (!(p = strrchr( buffer, '\\' ))) return FALSE;
if (sizeof(buffer) - (++p - buffer) <= strlen(name)) return FALSE;
strcpy( p, name );
return DOSFS_GetFullName( buffer, TRUE, full_name );
if (!(p = strrchrW( bufferW, '\\' ))) return FALSE;
if (OFS_MAXPATHNAME - (++p - bufferW) <= strlenW(name)) return FALSE;
strcpyW( p, name );
return DOSFS_GetFullName( bufferW, TRUE, full_name );
}
@ -623,32 +744,33 @@ static BOOL DIR_TryModulePath( LPCSTR name, DOS_FULL_NAME *full_name, BOOL win32
*
* Helper function for DIR_SearchPath.
*/
static BOOL DIR_TryAppPath( LPCSTR name, DOS_FULL_NAME *full_name )
static BOOL DIR_TryAppPath( LPCWSTR name, DOS_FULL_NAME *full_name )
{
HKEY hkAppPaths = 0, hkApp = 0;
char lpAppName[MAX_PATHNAME_LEN], lpAppPaths[MAX_PATHNAME_LEN];
LPSTR lpFileName;
WCHAR lpAppName[MAX_PATHNAME_LEN], lpAppPaths[MAX_PATHNAME_LEN];
LPWSTR lpFileName;
BOOL res = FALSE;
DWORD type, count;
static const WCHAR PathW[] = {'P','a','t','h',0};
if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths", &hkAppPaths) != ERROR_SUCCESS)
return FALSE;
if (GetModuleFileNameA(0, lpAppName, sizeof(lpAppName)) == 0)
if (!GetModuleFileNameW(0, lpAppName, MAX_PATHNAME_LEN))
{
WARN("huh, module not found ??\n");
goto end;
}
lpFileName = strrchr(lpAppName, '\\');
lpFileName = strrchrW(lpAppName, '\\');
if (!lpFileName)
goto end;
else lpFileName++; /* skip '\\' */
if (RegOpenKeyA(hkAppPaths, lpFileName, &hkApp) != ERROR_SUCCESS)
if (RegOpenKeyW(hkAppPaths, lpFileName, &hkApp) != ERROR_SUCCESS)
goto end;
count = sizeof(lpAppPaths);
if (RegQueryValueExA(hkApp, "Path", 0, &type, (LPBYTE)lpAppPaths, &count) != ERROR_SUCCESS)
if (RegQueryValueExW(hkApp, PathW, 0, &type, (LPBYTE)lpAppPaths, &count) != ERROR_SUCCESS)
goto end;
TRACE("successfully opened App Paths for '%s'\n", lpFileName);
TRACE("successfully opened App Paths for %s\n", debugstr_w(lpFileName));
res = DIR_SearchSemicolonedPaths(name, full_name, lpAppPaths);
end:
@ -667,19 +789,19 @@ end:
*
* FIXME: should return long path names.
*/
DWORD DIR_SearchPath( LPCSTR path, LPCSTR name, LPCSTR ext,
DWORD DIR_SearchPath( LPCWSTR path, LPCWSTR name, LPCWSTR ext,
DOS_FULL_NAME *full_name, BOOL win32 )
{
LPCSTR p;
LPSTR tmp = NULL;
LPCWSTR p;
LPWSTR tmp = NULL;
BOOL ret = TRUE;
/* First check the supplied parameters */
p = strrchr( name, '.' );
if (p && !strchr( p, '/' ) && !strchr( p, '\\' ))
p = strrchrW( name, '.' );
if (p && !strchrW( p, '/' ) && !strchrW( p, '\\' ))
ext = NULL; /* Ignore the specified extension */
if (FILE_contains_path (name))
if (FILE_contains_pathW (name))
path = NULL; /* Ignore path if name already contains a path */
if (path && !*path) path = NULL; /* Ignore empty path */
@ -687,20 +809,20 @@ DWORD DIR_SearchPath( LPCSTR path, LPCSTR name, LPCSTR ext,
if (ext)
{
DWORD len = strlen(name) + strlen(ext);
if (!(tmp = HeapAlloc( GetProcessHeap(), 0, len + 1 )))
DWORD len = strlenW(name) + strlenW(ext);
if (!(tmp = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
strcpy( tmp, name );
strcat( tmp, ext );
strcpyW( tmp, name );
strcatW( tmp, ext );
name = tmp;
}
/* If the name contains an explicit path, everything's easy */
if (FILE_contains_path(name))
if (FILE_contains_pathW(name))
{
ret = DOSFS_GetFullName( name, TRUE, full_name );
goto done;
@ -751,7 +873,7 @@ done:
/***********************************************************************
* SearchPathA [KERNEL32.@]
* SearchPathW [KERNEL32.@]
*
* Searches for a specified file in the search path.
*
@ -778,10 +900,10 @@ done:
* If the file is not found, calls SetLastError(ERROR_FILE_NOT_FOUND)
* (tested on NT 4.0)
*/
DWORD WINAPI SearchPathA( LPCSTR path, LPCSTR name, LPCSTR ext, DWORD buflen,
LPSTR buffer, LPSTR *lastpart )
DWORD WINAPI SearchPathW( LPCWSTR path, LPCWSTR name, LPCWSTR ext, DWORD buflen,
LPWSTR buffer, LPWSTR *lastpart )
{
LPSTR p, res;
LPSTR res;
DOS_FULL_NAME full_name;
if (!DIR_SearchPath( path, name, ext, &full_name, TRUE ))
@ -789,60 +911,72 @@ DWORD WINAPI SearchPathA( LPCSTR path, LPCSTR name, LPCSTR ext, DWORD buflen,
SetLastError(ERROR_FILE_NOT_FOUND);
return 0;
}
lstrcpynA( buffer, full_name.short_name, buflen );
TRACE("found %s %s\n", full_name.long_name, debugstr_w(full_name.short_name));
TRACE("drive %c: root %s\n", 'A' + full_name.drive, DRIVE_GetRoot(full_name.drive));
lstrcpynW( buffer, full_name.short_name, buflen );
res = full_name.long_name +
strlen(DRIVE_GetRoot( full_name.short_name[0] - 'A' ));
strlen(DRIVE_GetRoot( full_name.drive ));
while (*res == '/') res++;
if (buflen)
{
if (buflen > 3) lstrcpynA( buffer + 3, res, buflen - 3 );
LPWSTR p;
if (buflen > 3)
{
MultiByteToWideChar(DRIVE_GetCodepage(full_name.drive), 0,
res, -1, buffer + 3, buflen - 3);
buffer[buflen - 1] = 0;
}
for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
if (lastpart) *lastpart = strrchr( buffer, '\\' ) + 1;
if (lastpart) *lastpart = strrchrW( buffer, '\\' ) + 1;
}
TRACE("Returning %d\n", strlen(res) + 3 );
return strlen(res) + 3;
TRACE("Returning %s\n", debugstr_w(buffer) );
return strlenW(buffer);
}
/***********************************************************************
* SearchPathW (KERNEL32.@)
* SearchPathA (KERNEL32.@)
*/
DWORD WINAPI SearchPathW( LPCWSTR path, LPCWSTR name, LPCWSTR ext,
DWORD buflen, LPWSTR buffer, LPWSTR *lastpart )
DWORD WINAPI SearchPathA( LPCSTR path, LPCSTR name, LPCSTR ext,
DWORD buflen, LPSTR buffer, LPSTR *lastpart )
{
LPWSTR p;
LPSTR res;
DOS_FULL_NAME full_name;
UNICODE_STRING pathW, nameW, extW;
WCHAR bufferW[MAX_PATH];
DWORD ret, retW;
LPSTR pathA = HEAP_strdupWtoA( GetProcessHeap(), 0, path );
LPSTR nameA = HEAP_strdupWtoA( GetProcessHeap(), 0, name );
LPSTR extA = HEAP_strdupWtoA( GetProcessHeap(), 0, ext );
DWORD ret = DIR_SearchPath( pathA, nameA, extA, &full_name, TRUE );
HeapFree( GetProcessHeap(), 0, extA );
HeapFree( GetProcessHeap(), 0, nameA );
HeapFree( GetProcessHeap(), 0, pathA );
if (!ret) return 0;
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 (buflen > 0 && !MultiByteToWideChar( CP_ACP, 0, full_name.short_name, -1, buffer, buflen ))
buffer[buflen-1] = 0;
res = full_name.long_name +
strlen(DRIVE_GetRoot( full_name.short_name[0] - 'A' ));
while (*res == '/') res++;
if (buflen)
retW = SearchPathW(pathW.Buffer, nameW.Buffer, extW.Buffer, MAX_PATH, bufferW, NULL);
if (!retW)
ret = 0;
else if (retW > MAX_PATH)
{
if (buflen > 3)
SetLastError(ERROR_FILENAME_EXCED_RANGE);
ret = 0;
}
else
{
ret = WideCharToMultiByte(CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL);
if (buflen >= ret)
{
if (!MultiByteToWideChar( CP_ACP, 0, res, -1, buffer+3, buflen-3 ))
buffer[buflen-1] = 0;
}
for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
if (lastpart)
{
for (p = *lastpart = buffer; *p; p++)
if (*p == '\\') *lastpart = p + 1;
WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, buflen, NULL, NULL);
ret--; /* length without 0 */
if (lastpart) *lastpart = strrchr(buffer, '\\') + 1;
}
}
return strlen(res) + 3;
RtlFreeUnicodeString(&pathW);
RtlFreeUnicodeString(&nameW);
RtlFreeUnicodeString(&extW);
return ret;
}
@ -852,31 +986,31 @@ DWORD WINAPI SearchPathW( LPCWSTR path, LPCWSTR name, LPCWSTR ext,
*
* FIXME: should return long path names.?
*/
static BOOL search_alternate_path(LPCSTR dll_path, LPCSTR name, LPCSTR ext,
static BOOL search_alternate_path(LPCWSTR dll_path, LPCWSTR name, LPCWSTR ext,
DOS_FULL_NAME *full_name)
{
LPCSTR p;
LPSTR tmp = NULL;
LPCWSTR p;
LPWSTR tmp = NULL;
BOOL ret = TRUE;
/* First check the supplied parameters */
p = strrchr( name, '.' );
if (p && !strchr( p, '/' ) && !strchr( p, '\\' ))
p = strrchrW( name, '.' );
if (p && !strchrW( p, '/' ) && !strchrW( p, '\\' ))
ext = NULL; /* Ignore the specified extension */
/* Allocate a buffer for the file name and extension */
if (ext)
{
DWORD len = strlen(name) + strlen(ext);
if (!(tmp = HeapAlloc( GetProcessHeap(), 0, len + 1 )))
DWORD len = strlenW(name) + strlenW(ext);
if (!(tmp = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
strcpy( tmp, name );
strcat( tmp, ext );
strcpyW( tmp, name );
strcatW( tmp, ext );
name = tmp;
}
@ -922,28 +1056,42 @@ static BOOL search_alternate_path(LPCSTR dll_path, LPCSTR name, LPCSTR ext,
*
* NOTES
* If the file is not found, calls SetLastError(ERROR_FILE_NOT_FOUND)
*
* FIXME: convert to unicode
*/
DWORD DIR_SearchAlternatePath( LPCSTR dll_path, LPCSTR name, LPCSTR ext,
DWORD buflen, LPSTR buffer, LPSTR *lastpart )
{
LPSTR p, res;
LPSTR p;
DOS_FULL_NAME full_name;
DWORD ret = 0;
UNICODE_STRING dll_pathW, nameW, extW;
if (!search_alternate_path( dll_path, name, ext, &full_name))
if (dll_path) RtlCreateUnicodeStringFromAsciiz(&dll_pathW, dll_path);
else dll_pathW.Buffer = NULL;
if (name) RtlCreateUnicodeStringFromAsciiz(&nameW, name);
else nameW.Buffer = NULL;
if (ext) RtlCreateUnicodeStringFromAsciiz(&extW, ext);
else extW.Buffer = NULL;
if (search_alternate_path( dll_pathW.Buffer, nameW.Buffer, extW.Buffer, &full_name))
{
SetLastError(ERROR_FILE_NOT_FOUND);
return 0;
ret = WideCharToMultiByte(CP_ACP, 0, full_name.short_name, -1, NULL, 0, NULL, NULL);
if (buflen >= ret)
{
WideCharToMultiByte(CP_ACP, 0, full_name.short_name, -1, buffer, buflen, NULL, NULL);
for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
if (lastpart) *lastpart = strrchr( buffer, '\\' ) + 1;
ret--; /* length without 0 */
}
}
lstrcpynA( buffer, full_name.short_name, buflen );
res = full_name.long_name +
strlen(DRIVE_GetRoot( full_name.short_name[0] - 'A' ));
while (*res == '/') res++;
if (buflen)
{
if (buflen > 3) lstrcpynA( buffer + 3, res, buflen - 3 );
for (p = buffer; *p; p++) if (*p == '/') *p = '\\';
if (lastpart) *lastpart = strrchr( buffer, '\\' ) + 1;
}
TRACE("Returning %d\n", strlen(res) + 3 );
return strlen(res) + 3;
else
SetLastError(ERROR_FILE_NOT_FOUND);
RtlFreeUnicodeString(&dll_pathW);
RtlFreeUnicodeString(&nameW);
RtlFreeUnicodeString(&extW);
TRACE("Returning %ld\n", ret );
return ret;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1392,7 +1392,7 @@ static HANDLE SMB_RegisterFile( int fd, USHORT tree_id, USHORT user_id, USHORT d
return ret;
}
HANDLE WINAPI SMB_CreateFileA( LPCSTR uncname, DWORD access, DWORD sharing,
HANDLE WINAPI SMB_CreateFileW( LPCWSTR uncname, DWORD access, DWORD sharing,
LPSECURITY_ATTRIBUTES sa, DWORD creation,
DWORD attributes, HANDLE template )
{
@ -1400,12 +1400,14 @@ HANDLE WINAPI SMB_CreateFileA( LPCSTR uncname, DWORD access, DWORD sharing,
USHORT tree_id=0, user_id=0, dialect=0, file_id=0;
LPSTR name,host,share,file;
HANDLE handle = INVALID_HANDLE_VALUE;
INT len;
name = HeapAlloc(GetProcessHeap(),0,lstrlenA(uncname));
len = WideCharToMultiByte(CP_ACP, 0, uncname, -1, NULL, 0, NULL, NULL);
name = HeapAlloc(GetProcessHeap(), 0, len);
if(!name)
return handle;
lstrcpyA(name,uncname);
WideCharToMultiByte(CP_ACP, 0, uncname, -1, name, len, NULL, NULL);
if( !UNC_SplitName(name, &host, &share, &file) )
{
@ -1545,21 +1547,22 @@ BOOL WINAPI SMB_ReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPDWORD
return r;
}
SMB_DIR* WINAPI SMB_FindFirst(LPCSTR name)
SMB_DIR* WINAPI SMB_FindFirst(LPCWSTR name)
{
int fd = -1;
LPSTR host,share,file;
USHORT tree_id=0, user_id=0, dialect=0;
SMB_DIR *ret = NULL;
LPSTR filename;
DWORD len;
TRACE("Find %s\n",debugstr_a(name));
TRACE("Find %s\n",debugstr_w(name));
filename = HeapAlloc(GetProcessHeap(),0,lstrlenA(name)+1);
len = WideCharToMultiByte( CP_ACP, 0, name, -1, NULL, 0, NULL, NULL );
filename = HeapAlloc(GetProcessHeap(),0,len);
if(!filename)
return ret;
lstrcpyA(filename,name);
WideCharToMultiByte( CP_ACP, 0, name, -1, filename, len, NULL, NULL );
if( !UNC_SplitName(filename, &host, &share, &file) )
goto done;
@ -1587,7 +1590,7 @@ done:
}
BOOL WINAPI SMB_FindNext(SMB_DIR *dir, WIN32_FIND_DATAA *data )
BOOL WINAPI SMB_FindNext(SMB_DIR *dir, WIN32_FIND_DATAW *data )
{
unsigned char *ent;
int len, fnlen;
@ -1613,14 +1616,16 @@ BOOL WINAPI SMB_FindNext(SMB_DIR *dir, WIN32_FIND_DATAA *data )
/* copy the long filename */
fnlen = SMB_GETDWORD(&ent[0x3c]);
if ( fnlen > (sizeof data->cFileName/sizeof(CHAR)) )
if ( fnlen > (sizeof data->cFileName/sizeof(WCHAR)) )
return FALSE;
memcpy(data->cFileName, &ent[0x5e], fnlen);
MultiByteToWideChar( CP_ACP, 0, &ent[0x5e], fnlen, data->cFileName,
sizeof(data->cFileName)/sizeof(WCHAR) );
/* copy the short filename */
if ( ent[0x44] > (sizeof data->cAlternateFileName/sizeof(CHAR)) )
if ( ent[0x44] > (sizeof data->cAlternateFileName/sizeof(WCHAR)) )
return FALSE;
memcpy(data->cAlternateFileName, &ent[0x5e + len], ent[0x44]);
MultiByteToWideChar( CP_ACP, 0, &ent[0x5e + len], ent[0x44], data->cAlternateFileName,
sizeof(data->cAlternateFileName)/sizeof(WCHAR) );
dir->current++;

View file

@ -96,7 +96,7 @@
#define TRANS2_FIND_NEXT2 0x02
extern BOOL WINAPI SMB_ReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead, LPOVERLAPPED lpOverlapped);
extern HANDLE WINAPI SMB_CreateFileA( LPCSTR filename, DWORD access, DWORD sharing,
extern HANDLE WINAPI SMB_CreateFileW( LPCWSTR filename, DWORD access, DWORD sharing,
LPSECURITY_ATTRIBUTES sa, DWORD creation,
DWORD attributes, HANDLE template );
@ -108,8 +108,8 @@ typedef struct tagSMB_DIR
unsigned char *buffer;
} SMB_DIR;
extern SMB_DIR* WINAPI SMB_FindFirst(LPCSTR filename);
extern BOOL WINAPI SMB_FindNext(SMB_DIR *dir, WIN32_FIND_DATAA *data );
extern SMB_DIR* WINAPI SMB_FindFirst(LPCWSTR filename);
extern BOOL WINAPI SMB_FindNext(SMB_DIR *dir, WIN32_FIND_DATAW *data );
extern BOOL WINAPI SMB_CloseDir(SMB_DIR *dir);
#endif /* __INC_SMB__ */

View file

@ -39,15 +39,17 @@ extern int DRIVE_IsValid( int drive );
extern int DRIVE_GetCurrentDrive(void);
extern int DRIVE_SetCurrentDrive( int drive );
extern int DRIVE_FindDriveRoot( const char **path );
extern int DRIVE_FindDriveRootW( LPCWSTR *path );
extern const char * DRIVE_GetRoot( int drive );
extern const char * DRIVE_GetDosCwd( int drive );
extern LPCWSTR DRIVE_GetDosCwd( int drive );
extern const char * DRIVE_GetUnixCwd( int drive );
extern const char * DRIVE_GetDevice( int drive );
extern const char * DRIVE_GetLabel( int drive );
extern LPCWSTR DRIVE_GetLabel( int drive );
extern DWORD DRIVE_GetSerialNumber( int drive );
extern int DRIVE_SetSerialNumber( int drive, DWORD serial );
extern UINT DRIVE_GetFlags( int drive );
extern int DRIVE_Chdir( int drive, const char *path );
extern UINT DRIVE_GetCodepage( int drive );
extern int DRIVE_Chdir( int drive, LPCWSTR path );
extern int DRIVE_Disable( int drive );
extern int DRIVE_Enable( int drive );
extern int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive );

View file

@ -26,6 +26,7 @@
#include <sys/types.h>
#include "winbase.h"
#include "wine/windef16.h" /* HFILE16 */
#include "wine/unicode.h"
#define MAX_PATHNAME_LEN 1024
@ -33,7 +34,7 @@
typedef struct
{
char long_name[MAX_PATHNAME_LEN]; /* Long pathname in Unix format */
char short_name[MAX_PATHNAME_LEN]; /* Short pathname in DOS 8.3 format */
WCHAR short_name[MAX_PATHNAME_LEN]; /* Short pathname in DOS 8.3 format */
int drive;
} DOS_FULL_NAME;
@ -42,8 +43,9 @@ typedef struct
/* DOS device descriptor */
typedef struct
{
char *name;
const WCHAR name[9];
int flags;
UINT codepage;
} DOS_DEVICE;
/* locale-independent case conversion */
@ -64,6 +66,12 @@ inline static int FILE_contains_path (LPCSTR name)
strchr (name, '/') || strchr (name, '\\'));
}
inline static int FILE_contains_pathW (LPCWSTR name)
{
return ((*name && (name[1] == ':')) ||
strchrW (name, '/') || strchrW (name, '\\'));
}
/* files/file.c */
extern mode_t FILE_umask;
extern int FILE_strcasecmp( const char *str1, const char *str2 );
@ -86,21 +94,20 @@ extern UINT DIR_GetWindowsUnixDir( LPSTR path, UINT count );
extern UINT DIR_GetSystemUnixDir( LPSTR path, UINT count );
extern DWORD DIR_SearchAlternatePath( LPCSTR dll_path, LPCSTR name, LPCSTR ext,
DWORD buflen, LPSTR buffer, LPSTR *lastpart);
extern DWORD DIR_SearchPath( LPCSTR path, LPCSTR name, LPCSTR ext,
extern DWORD DIR_SearchPath( LPCWSTR path, LPCWSTR name, LPCWSTR ext,
DOS_FULL_NAME *full_name, BOOL win32 );
/* files/dos_fs.c */
extern void DOSFS_UnixTimeToFileTime( time_t unixtime, LPFILETIME ft,
DWORD remainder );
extern time_t DOSFS_FileTimeToUnixTime( const FILETIME *ft, DWORD *remainder );
extern BOOL DOSFS_ToDosFCBFormat( LPCSTR name, LPSTR buffer );
extern const DOS_DEVICE *DOSFS_GetDevice( const char *name );
extern BOOL DOSFS_ToDosFCBFormat( LPCWSTR name, LPWSTR buffer );
extern const DOS_DEVICE *DOSFS_GetDevice( LPCWSTR name );
extern const DOS_DEVICE *DOSFS_GetDeviceByHandle( HANDLE hFile );
extern HANDLE DOSFS_OpenDevice( const char *name, DWORD access, DWORD attributes, LPSECURITY_ATTRIBUTES sa);
extern BOOL DOSFS_FindUnixName( LPCSTR path, LPCSTR name, LPSTR long_buf,
INT long_len, LPSTR short_buf,
BOOL ignore_case );
extern BOOL DOSFS_GetFullName( LPCSTR name, BOOL check_last,
extern HANDLE DOSFS_OpenDevice( LPCWSTR name, DWORD access, DWORD attributes, LPSECURITY_ATTRIBUTES sa);
extern BOOL DOSFS_FindUnixName( const DOS_FULL_NAME *path, LPCWSTR name, char *long_buf,
INT long_len, LPWSTR short_buf, BOOL ignore_case );
extern BOOL DOSFS_GetFullName( LPCWSTR name, BOOL check_last,
DOS_FULL_NAME *full );
extern int DOSFS_FindNext( const char *path, const char *short_mask,
const char *long_mask, int drive, BYTE attr,
@ -109,12 +116,12 @@ extern int DOSFS_FindNext( const char *path, const char *short_mask,
/* profile.c */
extern int PROFILE_LoadWineIni(void);
extern void PROFILE_UsageWineIni(void);
extern int PROFILE_GetWineIniString( const char *section, const char *key_name,
const char *def, char *buffer, int len );
extern int PROFILE_GetWineIniBool( char const *section, char const *key_name, int def );
extern int PROFILE_GetWineIniString( LPCWSTR section, LPCWSTR key_name,
LPCWSTR def, LPWSTR buffer, int len );
extern int PROFILE_GetWineIniBool( LPCWSTR section, LPCWSTR key_name, int def );
/* win32/device.c */
extern HANDLE DEVICE_Open( LPCSTR filename, DWORD access, LPSECURITY_ATTRIBUTES sa );
extern HANDLE DEVICE_Open( LPCWSTR filename, DWORD access, LPSECURITY_ATTRIBUTES sa );
/* ntdll/cdrom.c.c */
extern BOOL CDROM_DeviceIoControl(DWORD clientID, HANDLE hDevice, DWORD dwIoControlCode,

View file

@ -290,8 +290,9 @@ static TDB *TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, TEB *teb, LPCSTR cm
pTask->teb = teb;
pTask->curdrive = DRIVE_GetCurrentDrive() | 0x80;
strcpy( pTask->curdir, "\\" );
lstrcpynA( pTask->curdir + 1, DRIVE_GetDosCwd( DRIVE_GetCurrentDrive() ),
sizeof(pTask->curdir) - 1 );
WideCharToMultiByte(CP_ACP, 0, DRIVE_GetDosCwd(DRIVE_GetCurrentDrive()), -1,
pTask->curdir + 1, sizeof(pTask->curdir) - 1, NULL, NULL);
pTask->curdir[sizeof(pTask->curdir) - 1] = 0; /* ensure 0 termination */
/* Create the thunks block */

View file

@ -46,11 +46,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(reg);
/* check if value type needs string conversion (Ansi<->Unicode) */
static inline int is_string( DWORD type )
inline static int is_string( DWORD type )
{
return (type == REG_SZ) || (type == REG_EXPAND_SZ) || (type == REG_MULTI_SZ);
}
/* check if current version is NT or Win95 */
inline static int is_version_nt(void)
{
return !(GetVersion() & 0x80000000);
}
/******************************************************************************
* RegCreateKeyExA [ADVAPI32.@]
@ -90,6 +95,27 @@ DWORD WINAPI RegCreateKeyExA( HKEY hkey, LPCSTR name, DWORD reserved, LPSTR clas
}
/******************************************************************************
* RegOpenKeyW [ADVAPI32.@]
*
* PARAMS
* hkey [I] Handle of open key
* name [I] Address of name of subkey to open
* retkey [O] Handle to open key
*
* RETURNS
* Success: ERROR_SUCCESS
* Failure: Error code
*
* NOTES
* in case of failing is retkey = 0
*/
DWORD WINAPI RegOpenKeyW( HKEY hkey, LPCWSTR name, LPHKEY retkey )
{
return RegOpenKeyExW( hkey, name, 0, KEY_ALL_ACCESS, retkey );
}
/******************************************************************************
* RegCreateKeyA [ADVAPI32.@]
*/
@ -101,6 +127,43 @@ DWORD WINAPI RegCreateKeyA( HKEY hkey, LPCSTR name, LPHKEY retkey )
/******************************************************************************
* RegOpenKeyExW [ADVAPI32.@]
*
* Opens the specified key
*
* Unlike RegCreateKeyEx, this does not create the key if it does not exist.
*
* PARAMS
* hkey [I] Handle of open key
* name [I] Name of subkey to open
* reserved [I] Reserved - must be zero
* access [I] Security access mask
* retkey [O] Handle to open key
*
* RETURNS
* Success: ERROR_SUCCESS
* Failure: Error code
*
* NOTES
* in case of failing is retkey = 0
*/
DWORD WINAPI RegOpenKeyExW( HKEY hkey, LPCWSTR name, DWORD reserved, REGSAM access, LPHKEY retkey )
{
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW;
attr.Length = sizeof(attr);
attr.RootDirectory = hkey;
attr.ObjectName = &nameW;
attr.Attributes = 0;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
RtlInitUnicodeString( &nameW, name );
return RtlNtStatusToDosError( NtOpenKey( retkey, access, &attr ) );
}
/******************************************************************************
* RegOpenKeyExA [ADVAPI32.@]
*/
@ -228,8 +291,7 @@ DWORD WINAPI RegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDWOR
TRACE( "(0x%x,%p,%ld,%p,%p,%p,%p,%p,%p,%p,%p)\n", hkey, class, class_len ? *class_len : 0,
reserved, subkeys, max_subkey, values, max_value, max_data, security, modif );
if (class && !class_len && !(GetVersion() & 0x80000000 /*NT*/))
return ERROR_INVALID_PARAMETER;
if (class && !class_len && is_version_nt()) return ERROR_INVALID_PARAMETER;
status = NtQueryKey( hkey, KeyFullInformation, buffer, sizeof(buffer), &total_size );
if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
@ -314,6 +376,48 @@ DWORD WINAPI RegDeleteKeyA( HKEY hkey, LPCSTR name )
}
/******************************************************************************
* RegSetValueExW [ADVAPI32.@]
*
* Sets the data and type of a value under a register key
*
* PARAMS
* hkey [I] Handle of key to set value for
* name [I] Name of value to set
* reserved [I] Reserved - must be zero
* type [I] Flag for value type
* data [I] Address of value data
* count [I] Size of value data
*
* RETURNS
* Success: ERROR_SUCCESS
* Failure: Error code
*
* NOTES
* win95 does not care about count for REG_SZ and finds out the len by itself (js)
* NT does definitely care (aj)
*/
DWORD WINAPI RegSetValueExW( HKEY hkey, LPCWSTR name, DWORD reserved,
DWORD type, CONST BYTE *data, DWORD count )
{
UNICODE_STRING nameW;
if (!is_version_nt()) /* win95 */
{
if (type == REG_SZ) count = (strlenW( (WCHAR *)data ) + 1) * sizeof(WCHAR);
}
else if (count && is_string(type))
{
LPCWSTR str = (LPCWSTR)data;
/* if user forgot to count terminating null, add it (yes NT does this) */
if (str[count / sizeof(WCHAR) - 1] && !str[count / sizeof(WCHAR)])
count += sizeof(WCHAR);
}
RtlInitUnicodeString( &nameW, name );
return RtlNtStatusToDosError( NtSetValueKey( hkey, &nameW, 0, type, data, count ) );
}
/******************************************************************************
* RegSetValueExA [ADVAPI32.@]
@ -376,6 +480,86 @@ DWORD WINAPI RegSetValueA( HKEY hkey, LPCSTR name, DWORD type, LPCSTR data, DWOR
}
/******************************************************************************
* RegQueryValueExW [ADVAPI32.@]
*
* Retrieves type and data for a specified name associated with an open key
*
* PARAMS
* hkey [I] Handle of key to query
* name [I] Name of value to query
* reserved [I] Reserved - must be NULL
* type [O] Address of buffer for value type. If NULL, the type
* is not required.
* data [O] Address of data buffer. If NULL, the actual data is
* not required.
* count [I/O] Address of data buffer size
*
* RETURNS
* ERROR_SUCCESS: Success
* ERROR_MORE_DATA: !!! if the specified buffer is not big enough to hold the data
* buffer is left untouched. The MS-documentation is wrong (js) !!!
*/
DWORD WINAPI RegQueryValueExW( HKEY hkey, LPCWSTR name, LPDWORD reserved, LPDWORD type,
LPBYTE data, LPDWORD count )
{
NTSTATUS status;
UNICODE_STRING name_str;
DWORD total_size;
char buffer[256], *buf_ptr = buffer;
KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
static const int info_size = info->Data - (UCHAR *)info;
TRACE("(0x%x,%s,%p,%p,%p,%p=%ld)\n",
hkey, debugstr_w(name), reserved, type, data, count, count ? *count : 0 );
if ((data && !count) || reserved) return ERROR_INVALID_PARAMETER;
RtlInitUnicodeString( &name_str, name );
if (data) total_size = min( sizeof(buffer), *count + info_size );
else total_size = info_size;
status = NtQueryValueKey( hkey, &name_str, KeyValuePartialInformation,
buffer, total_size, &total_size );
if (status && status != STATUS_BUFFER_OVERFLOW) goto done;
if (data)
{
/* retry with a dynamically allocated buffer */
while (status == STATUS_BUFFER_OVERFLOW && total_size - info_size <= *count)
{
if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
if (!(buf_ptr = HeapAlloc( GetProcessHeap(), 0, total_size )))
return ERROR_NOT_ENOUGH_MEMORY;
info = (KEY_VALUE_PARTIAL_INFORMATION *)buf_ptr;
status = NtQueryValueKey( hkey, &name_str, KeyValuePartialInformation,
buf_ptr, total_size, &total_size );
}
if (!status)
{
memcpy( data, buf_ptr + info_size, total_size - info_size );
/* if the type is REG_SZ and data is not 0-terminated
* and there is enough space in the buffer NT appends a \0 */
if (total_size - info_size <= *count-sizeof(WCHAR) && is_string(info->Type))
{
WCHAR *ptr = (WCHAR *)(data + total_size - info_size);
if (ptr > (WCHAR *)data && ptr[-1]) *ptr = 0;
}
}
else if (status != STATUS_BUFFER_OVERFLOW) goto done;
}
else status = STATUS_SUCCESS;
if (type) *type = info->Type;
if (count) *count = total_size - info_size;
done:
if (buf_ptr != buffer) HeapFree( GetProcessHeap(), 0, buf_ptr );
return RtlNtStatusToDosError(status);
}
/******************************************************************************
* RegQueryValueExA [ADVAPI32.@]
@ -715,3 +899,56 @@ done:
SetLastError( err ); /* restore last error code */
return ret;
}
/******************************************************************************
* RegUnLoadKeyA [ADVAPI32.@]
*
* PARAMS
* hkey [I] Handle of open key
* lpSubKey [I] Address of name of subkey to unload
*/
LONG WINAPI RegUnLoadKeyA( HKEY hkey, LPCSTR lpSubKey )
{
FIXME("(%x,%s): stub\n",hkey, debugstr_a(lpSubKey));
return ERROR_SUCCESS;
}
/******************************************************************************
* RegReplaceKeyA [ADVAPI32.@]
*
* PARAMS
* hkey [I] Handle of open key
* lpSubKey [I] Address of name of subkey
* lpNewFile [I] Address of filename for file with new data
* lpOldFile [I] Address of filename for backup file
*/
LONG WINAPI RegReplaceKeyA( HKEY hkey, LPCSTR lpSubKey, LPCSTR lpNewFile,
LPCSTR lpOldFile )
{
FIXME("(%x,%s,%s,%s): stub\n", hkey, debugstr_a(lpSubKey),
debugstr_a(lpNewFile),debugstr_a(lpOldFile));
return ERROR_SUCCESS;
}
/******************************************************************************
* RegFlushKey [ADVAPI32.@]
* Immediately writes key to registry.
* Only returns after data has been written to disk.
*
* FIXME: does it really wait until data is written ?
*
* PARAMS
* hkey [I] Handle of key to write
*
* RETURNS
* Success: ERROR_SUCCESS
* Failure: Error code
*/
DWORD WINAPI RegFlushKey( HKEY hkey )
{
FIXME( "(%x): stub\n", hkey );
return ERROR_SUCCESS;
}

View file

@ -1050,16 +1050,21 @@ static void _init_registry_saving( HKEY hkey_users_default )
{
int all;
int period = 0;
char buffer[20];
WCHAR buffer[20];
static const WCHAR registryW[] = {'r','e','g','i','s','t','r','y',0};
static const WCHAR SaveOnlyUpdatedKeysW[] = {'S','a','v','e','O','n','l','y','U','p','d','a','t','e','d','K','e','y','s',0};
static const WCHAR PeriodicSaveW[] = {'P','e','r','i','o','d','i','c','S','a','v','e',0};
static const WCHAR WritetoHomeRegistryFilesW[] = {'W','r','i','t','e','t','o','H','o','m','e','R','e','g','i','s','t','r','y','F','i','l','e','s',0};
static const WCHAR empty_strW[] = { 0 };
all = !PROFILE_GetWineIniBool("registry","SaveOnlyUpdatedKeys",1);
PROFILE_GetWineIniString( "registry", "PeriodicSave", "", buffer, sizeof(buffer) );
if (buffer[0]) period = atoi(buffer);
all = !PROFILE_GetWineIniBool(registryW, SaveOnlyUpdatedKeysW, 1);
PROFILE_GetWineIniString( registryW, PeriodicSaveW, empty_strW, buffer, 20 );
if (buffer[0]) period = (int)strtolW(buffer, NULL, 10);
/* set saving level (0 for saving everything, 1 for saving only modified keys) */
_set_registry_levels(1,!all,period*1000);
if (PROFILE_GetWineIniBool("registry","WritetoHomeRegistryFiles",1))
if (PROFILE_GetWineIniBool(registryW, WritetoHomeRegistryFilesW, 1))
{
_save_at_exit(HKEY_CURRENT_USER,"/" SAVE_LOCAL_REGBRANCH_CURRENT_USER );
_save_at_exit(HKEY_LOCAL_MACHINE,"/" SAVE_LOCAL_REGBRANCH_LOCAL_MACHINE);
@ -1118,29 +1123,33 @@ static void _allocate_default_keys(void) {
/* return the type of native registry [Internal] */
static int _get_reg_type(void)
{
char windir[MAX_PATHNAME_LEN];
char tmp[MAX_PATHNAME_LEN];
WCHAR windir[MAX_PATHNAME_LEN];
WCHAR tmp[MAX_PATHNAME_LEN];
int ret = REG_WIN31;
static const WCHAR nt_reg_pathW[] = {'\\','s','y','s','t','e','m','3','2','\\','c','o','n','f','i','g','\\','s','y','s','t','e','m',0};
static const WCHAR win9x_reg_pathW[] = {'\\','s','y','s','t','e','m','.','d','a','t',0};
static const WCHAR WineW[] = {'W','i','n','e',0};
static const WCHAR ProfileW[] = {'P','r','o','f','i','l','e',0};
static const WCHAR empty_strW[] = { 0 };
GetWindowsDirectoryA(windir,MAX_PATHNAME_LEN);
GetWindowsDirectoryW(windir, MAX_PATHNAME_LEN);
/* test %windir%/system32/config/system --> winnt */
strcpy(tmp, windir);
strncat(tmp, "\\system32\\config\\system", MAX_PATHNAME_LEN - strlen(tmp) - 1);
if(GetFileAttributesA(tmp) != (DWORD)-1) {
strcpyW(tmp, windir);
strcatW(tmp, nt_reg_pathW);
if(GetFileAttributesW(tmp) != (DWORD)-1)
ret = REG_WINNT;
}
else
{
/* test %windir%/system.dat --> win95 */
strcpy(tmp, windir);
strncat(tmp, "\\system.dat", MAX_PATHNAME_LEN - strlen(tmp) - 1);
if(GetFileAttributesA(tmp) != (DWORD)-1) {
strcpyW(tmp, windir);
strcatW(tmp, win9x_reg_pathW);
if(GetFileAttributesW(tmp) != (DWORD)-1)
ret = REG_WIN95;
}
}
if ((ret == REG_WINNT) && (!PROFILE_GetWineIniString( "Wine", "Profile", "", tmp, MAX_PATHNAME_LEN))) {
if ((ret == REG_WINNT) && (!PROFILE_GetWineIniString( WineW, ProfileW, empty_strW, tmp, MAX_PATHNAME_LEN )))
{
MESSAGE("When you are running with a native NT directory specify\n");
MESSAGE("'Profile=<profiledirectory>' or disable loading of Windows\n");
MESSAGE("registry (LoadWindowsRegistryFiles=N)\n");
@ -1255,7 +1264,7 @@ static LPSTR _get_tmp_fn(FILE **f)
}
/* convert win95 native registry file to wine format [Internal] */
static LPSTR _convert_win95_registry_to_wine_format(LPCSTR fn,int level)
static LPSTR _convert_win95_registry_to_wine_format(LPCWSTR fn, int level)
{
int fd;
FILE *f;
@ -1278,7 +1287,8 @@ static LPSTR _convert_win95_registry_to_wine_format(LPCSTR fn,int level)
/* control signature */
if (*(LPDWORD)base != W95_REG_CREG_ID) {
ERR("unable to load native win95 registry file %s: unknown signature.\n",fn);
ERR("unable to load native win95 registry file %s: unknown signature.\n",
debugstr_w(fn));
goto error;
}
@ -1324,7 +1334,7 @@ static LPSTR _convert_win95_registry_to_wine_format(LPCSTR fn,int level)
error:
if(ret == NULL) {
ERR("Unable to load native win95 registry file %s.\n",fn);
ERR("Unable to load native win95 registry file %s.\n", debugstr_w(fn));
ERR("Please report this.\n");
ERR("Make a backup of the file, run a good reg cleaner program and try again!\n");
}
@ -1336,7 +1346,7 @@ error1:
}
/* convert winnt native registry file to wine format [Internal] */
static LPSTR _convert_winnt_registry_to_wine_format(LPCSTR fn,int level)
static LPSTR _convert_winnt_registry_to_wine_format(LPCWSTR fn, int level)
{
FILE *f;
void *base;
@ -1349,11 +1359,11 @@ static LPSTR _convert_winnt_registry_to_wine_format(LPCSTR fn,int level)
nt_hbin_sub *hbin_sub;
nt_nk *nk;
TRACE("%s\n", fn);
TRACE("%s\n", debugstr_w(fn));
hFile = CreateFileA( fn, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
hFile = CreateFileW( fn, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
if ( hFile == INVALID_HANDLE_VALUE ) return NULL;
hMapping = CreateFileMappingA( hFile, NULL, PAGE_READONLY|SEC_COMMIT, 0, 0, NULL );
hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY|SEC_COMMIT, 0, 0, NULL );
if (!hMapping) goto error1;
base = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
CloseHandle( hMapping );
@ -1361,7 +1371,8 @@ static LPSTR _convert_winnt_registry_to_wine_format(LPCSTR fn,int level)
/* control signature */
if (*(LPDWORD)base != NT_REG_HEADER_BLOCK_ID) {
ERR("unable to load native winnt registry file %s: unknown signature.\n",fn);
ERR("unable to load native winnt registry file %s: unknown signature.\n",
debugstr_w(fn));
goto error;
}
@ -1402,7 +1413,7 @@ error1:
}
/* convert native registry to wine format and load it via server call [Internal] */
static void _convert_and_load_native_registry(LPCSTR fn,HKEY hkey,int reg_type,int level)
static void _convert_and_load_native_registry(LPCWSTR fn, HKEY hkey, int reg_type, int level)
{
LPSTR tmp = NULL;
@ -1424,10 +1435,11 @@ static void _convert_and_load_native_registry(LPCSTR fn,HKEY hkey,int reg_type,i
if (tmp != NULL) {
load_wine_registry(hkey,tmp);
TRACE("File %s successfully converted to %s and loaded to registry.\n",fn,tmp);
TRACE("File %s successfully converted to %s and loaded to registry.\n",
debugstr_w(fn), tmp);
unlink(tmp);
}
else WARN("Unable to convert %s (doesn't exist?)\n",fn);
else WARN("Unable to convert %s (doesn't exist?)\n", debugstr_w(fn));
free(tmp);
}
@ -1435,26 +1447,35 @@ static void _convert_and_load_native_registry(LPCSTR fn,HKEY hkey,int reg_type,i
static void _load_windows_registry( HKEY hkey_users_default )
{
int reg_type;
char windir[MAX_PATHNAME_LEN];
char path[MAX_PATHNAME_LEN];
WCHAR windir[MAX_PATHNAME_LEN];
WCHAR path[MAX_PATHNAME_LEN];
static const WCHAR WineW[] = {'W','i','n','e',0};
static const WCHAR ProfileW[] = {'P','r','o','f','i','l','e',0};
static const WCHAR empty_strW[] = { 0 };
GetWindowsDirectoryA(windir,MAX_PATHNAME_LEN);
GetWindowsDirectoryW(windir, MAX_PATHNAME_LEN);
reg_type = _get_reg_type();
switch (reg_type) {
case REG_WINNT: {
HKEY hkey;
static const WCHAR ntuser_datW[] = {'\\','n','t','u','s','e','r','.','d','a','t',0};
static const WCHAR defaultW[] = {'\\','s','y','s','t','e','m','3','2','\\','c','o','n','f','i','g','\\','d','e','f','a','u','l','t',0};
static const WCHAR systemW[] = {'\\','s','y','s','t','e','m','3','2','\\','c','o','n','f','i','g','\\','s','y','s','t','e','m',0};
static const WCHAR softwareW[] = {'\\','s','y','s','t','e','m','3','2','\\','c','o','n','f','i','g','\\','s','o','f','t','w','a','r','e',0};
static const WCHAR samW[] = {'\\','s','y','s','t','e','m','3','2','\\','c','o','n','f','i','g','\\','s','a','m',0};
static const WCHAR securityW[] = {'\\','s','y','s','t','e','m','3','2','\\','c','o','n','f','i','g','\\','s','e','c','u','r','i','t','y',0};
/* user specific ntuser.dat */
if (PROFILE_GetWineIniString( "Wine", "Profile", "", path, MAX_PATHNAME_LEN)) {
strcat(path,"\\ntuser.dat");
if (PROFILE_GetWineIniString( WineW, ProfileW, empty_strW, path, MAX_PATHNAME_LEN )) {
strcatW(path, ntuser_datW);
_convert_and_load_native_registry(path,HKEY_CURRENT_USER,REG_WINNT,1);
}
/* default user.dat */
if (hkey_users_default) {
strcpy(path,windir);
strcat(path,"\\system32\\config\\default");
strcpyW(path, windir);
strcatW(path, defaultW);
_convert_and_load_native_registry(path,hkey_users_default,REG_WINNT,1);
}
@ -1464,25 +1485,25 @@ static void _load_windows_registry( HKEY hkey_users_default )
*/
if (!RegCreateKeyA(HKEY_LOCAL_MACHINE, "SYSTEM", &hkey)) {
strcpy(path,windir);
strcat(path,"\\system32\\config\\system");
strcpyW(path, windir);
strcatW(path, systemW);
_convert_and_load_native_registry(path,hkey,REG_WINNT,1);
RegCloseKey(hkey);
}
if (!RegCreateKeyA(HKEY_LOCAL_MACHINE, "SOFTWARE", &hkey)) {
strcpy(path,windir);
strcat(path,"\\system32\\config\\software");
strcpyW(path, windir);
strcatW(path, softwareW);
_convert_and_load_native_registry(path,hkey,REG_WINNT,1);
RegCloseKey(hkey);
}
strcpy(path,windir);
strcat(path,"\\system32\\config\\sam");
strcpyW(path, windir);
strcatW(path, samW);
_convert_and_load_native_registry(path,HKEY_LOCAL_MACHINE,REG_WINNT,0);
strcpy(path,windir);
strcat(path,"\\system32\\config\\security");
strcpyW(path,windir);
strcatW(path, securityW);
_convert_and_load_native_registry(path,HKEY_LOCAL_MACHINE,REG_WINNT,0);
/* this key is generated when the nt-core booted successfully */
@ -1491,33 +1512,40 @@ static void _load_windows_registry( HKEY hkey_users_default )
}
case REG_WIN95:
_convert_and_load_native_registry("c:\\system.1st",HKEY_LOCAL_MACHINE,REG_WIN95,0);
{
static const WCHAR system_1stW[] = {'c',':','\\','s','y','s','t','e','m','.','1','s','t',0};
static const WCHAR system_datW[] = {'\\','s','y','s','t','e','m','.','d','a','t',0};
static const WCHAR classes_datW[] = {'\\','c','l','a','s','s','e','s','.','d','a','t',0};
static const WCHAR user_datW[] = {'\\','u','s','e','r','.','d','a','t',0};
strcpy(path,windir);
strcat(path,"\\system.dat");
_convert_and_load_native_registry(system_1stW,HKEY_LOCAL_MACHINE,REG_WIN95,0);
strcpyW(path, windir);
strcatW(path, system_datW);
_convert_and_load_native_registry(path,HKEY_LOCAL_MACHINE,REG_WIN95,0);
strcpy(path,windir);
strcat(path,"\\classes.dat");
strcpyW(path, windir);
strcatW(path, classes_datW);
_convert_and_load_native_registry(path,HKEY_CLASSES_ROOT,REG_WIN95,0);
if (PROFILE_GetWineIniString("Wine","Profile","",path,MAX_PATHNAME_LEN)) {
if (PROFILE_GetWineIniString(WineW, ProfileW, empty_strW, path, MAX_PATHNAME_LEN)) {
/* user specific user.dat */
strncat(path, "\\user.dat", MAX_PATHNAME_LEN - strlen(path) - 1);
strcatW(path, user_datW);
_convert_and_load_native_registry(path,HKEY_CURRENT_USER,REG_WIN95,1);
/* default user.dat */
if (hkey_users_default) {
strcpy(path,windir);
strcat(path,"\\user.dat");
strcpyW(path, windir);
strcatW(path, user_datW);
_convert_and_load_native_registry(path,hkey_users_default,REG_WIN95,1);
}
} else {
strcpy(path,windir);
strcat(path,"\\user.dat");
strcpyW(path, windir);
strcatW(path, user_datW);
_convert_and_load_native_registry(path,HKEY_CURRENT_USER,REG_WIN95,1);
}
break;
}
case REG_WIN31:
/* FIXME: here we should convert to *.reg file supported by server and call REQ_LOAD_REGISTRY, see REG_WIN95 case */
@ -1572,6 +1600,10 @@ static void _load_home_registry( HKEY hkey_users_default )
void SHELL_LoadRegistry( void )
{
HKEY hkey_users_default;
static const WCHAR RegistryW[] = {'R','e','g','i','s','t','r','y',0};
static const WCHAR load_win_reg_filesW[] = {'L','o','a','d','W','i','n','d','o','w','s','R','e','g','i','s','t','r','y','F','i','l','e','s',0};
static const WCHAR load_global_reg_filesW[] = {'L','o','a','d','G','l','o','b','a','l','R','e','g','i','s','t','r','y','F','i','l','e','s',0};
static const WCHAR load_home_reg_filesW[] = {'L','o','a','d','H','o','m','e','R','e','g','i','s','t','r','y','F','i','l','e','s',0};
TRACE("(void)\n");
@ -1585,70 +1617,21 @@ void SHELL_LoadRegistry( void )
_allocate_default_keys();
_set_registry_levels(0,0,0);
if (PROFILE_GetWineIniBool("Registry","LoadWindowsRegistryFiles",1))
if (PROFILE_GetWineIniBool(RegistryW, load_win_reg_filesW, 1))
_load_windows_registry( hkey_users_default );
if (PROFILE_GetWineIniBool("Registry","LoadGlobalRegistryFiles",1))
if (PROFILE_GetWineIniBool(RegistryW, load_global_reg_filesW, 1))
_load_global_registry();
_set_registry_levels(1,0,0);
if (PROFILE_GetWineIniBool("Registry","LoadHomeRegistryFiles",1))
if (PROFILE_GetWineIniBool(RegistryW, load_home_reg_filesW, 1))
_load_home_registry( hkey_users_default );
_init_registry_saving( hkey_users_default );
RegCloseKey(hkey_users_default);
}
/***************************************************************************/
/* API FUNCTIONS */
/* 16-BIT API FUNCTIONS */
/***************************************************************************/
/******************************************************************************
* RegFlushKey [ADVAPI32.@]
* Immediately writes key to registry.
* Only returns after data has been written to disk.
*
* FIXME: does it really wait until data is written ?
*
* PARAMS
* hkey [I] Handle of key to write
*
* RETURNS
* Success: ERROR_SUCCESS
* Failure: Error code
*/
DWORD WINAPI RegFlushKey( HKEY hkey )
{
FIXME( "(%x): stub\n", hkey );
return ERROR_SUCCESS;
}
/******************************************************************************
* RegUnLoadKeyA [ADVAPI32.@]
*/
LONG WINAPI RegUnLoadKeyA( HKEY hkey, LPCSTR lpSubKey )
{
FIXME("(%x,%s): stub\n",hkey, debugstr_a(lpSubKey));
return ERROR_SUCCESS;
}
/******************************************************************************
* RegReplaceKeyA [ADVAPI32.@]
*/
LONG WINAPI RegReplaceKeyA( HKEY hkey, LPCSTR lpSubKey, LPCSTR lpNewFile,
LPCSTR lpOldFile )
{
FIXME("(%x,%s,%s,%s): stub\n", hkey, debugstr_a(lpSubKey),
debugstr_a(lpNewFile),debugstr_a(lpOldFile));
return ERROR_SUCCESS;
}
/* 16-bit functions */
/* 0 and 1 are valid rootkeys in win16 shell.dll and are used by
* some programs. Do not remove those cases. -MM
*/

View file

@ -435,17 +435,19 @@ static void DOSCONF_Parse(char *menuname)
int DOSCONF_ReadConfig(void)
{
char buffer[256];
WCHAR filename[MAX_PATH];
DOS_FULL_NAME fullname;
char *filename, *menuname;
WCHAR *p;
int ret = 1;
static const WCHAR wineW[] = {'w','i','n','e',0};
static const WCHAR config_sysW[] = {'c','o','n','f','i','g','.','s','y','s',0};
static const WCHAR empty_strW[] = { 0 };
PROFILE_GetWineIniString( "wine", "config.sys", "", buffer, sizeof(buffer) );
if (!(filename = strtok(buffer, ","))) return ret;
menuname = strtok(NULL, ",");
PROFILE_GetWineIniString( wineW, config_sysW, empty_strW, filename, MAX_PATH );
if ((p = strchrW(filename, ','))) *p = 0;
if (!filename[0]) return ret;
DOSFS_GetFullName(filename, FALSE, &fullname);
if (menuname) menu_default = strdup(menuname);
if ((cfg_fd = fopen(fullname.long_name, "r")))
{
DOSCONF_Parse(NULL);
@ -453,10 +455,9 @@ int DOSCONF_ReadConfig(void)
}
else
{
MESSAGE("Couldn't open config.sys file given as \"%s\" in" \
" wine.conf or .winerc, section [wine] !\n", filename);
MESSAGE("Couldn't open config.sys file given as %s in" \
" wine.conf or .winerc, section [wine] !\n", debugstr_w(filename));
ret = 0;
}
if (menu_default) free(menu_default);
return ret;
}

View file

@ -28,6 +28,7 @@
#include "miscemu.h"
#include "msdos.h"
#include "file.h"
#include "wine/unicode.h"
#include "wine/debug.h"
/**********************************************************************
@ -74,16 +75,21 @@ void WINAPI INT_Int11Handler( CONTEXT86 *context )
for (x=0; x < 9; x++)
{
char temp[16],name[16];
WCHAR temp[16];
WCHAR comW[] = {'C','O','M','?',0};
WCHAR lptW[] = {'L','P','T','?',0};
static const WCHAR serialportsW[] = {'s','e','r','i','a','l','p','o','r','t','s',0};
static const WCHAR parallelportsW[] = {'p','a','r','a','l','l','e','l','p','o','r','t','s',0};
static const WCHAR asteriskW[] = {'*',0};
sprintf(name,"COM%d",x+1);
PROFILE_GetWineIniString("serialports",name,"*",temp,sizeof temp);
if(strcmp(temp,"*"))
comW[3] = '0' + x;
PROFILE_GetWineIniString(serialportsW, comW, asteriskW, temp, 16);
if(strcmpW(temp, asteriskW))
serialports++;
sprintf(name,"LPT%d",x+1);
PROFILE_GetWineIniString("parallelports",name,"*",temp,sizeof temp);
if(strcmp(temp,"*"))
lptW[3] = '0' + x;
PROFILE_GetWineIniString(parallelportsW, lptW, asteriskW, temp, 16);
if(strcmpW(temp, asteriskW))
parallelports++;
}
if (serialports > 7) /* 3 bits -- maximum value = 7 */

View file

@ -57,6 +57,7 @@
#include "msdos.h"
#include "miscemu.h"
#include "task.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(int21);
@ -428,30 +429,37 @@ static void INT21_ParseFileNameIntoFCB( CONTEXT86 *context )
CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Esi );
char *fcb =
CTX_SEG_OFF_TO_LIN(context, context->SegEs, context->Edi );
char *buffer, *s, *d;
char *s;
WCHAR *buffer;
WCHAR fcbW[12];
INT buffer_len, len;
AL_reg(context) = 0xff; /* failed */
TRACE("filename: '%s'\n", filename);
buffer = HeapAlloc( GetProcessHeap(), 0, strlen(filename) + 1);
s = filename;
d = buffer;
len = 0;
while (*s)
{
if ((*s != ' ') && (*s != '\r') && (*s != '\n'))
*d++ = *s++;
{
s++;
len++;
}
else
break;
}
*d = '\0';
DOSFS_ToDosFCBFormat(buffer, fcb + 1);
buffer_len = MultiByteToWideChar(CP_OEMCP, 0, filename, len, NULL, 0);
buffer = HeapAlloc( GetProcessHeap(), 0, (buffer_len + 1) * sizeof(WCHAR));
len = MultiByteToWideChar(CP_OEMCP, 0, filename, len, buffer, buffer_len);
buffer[len] = 0;
DOSFS_ToDosFCBFormat(buffer, fcbW);
HeapFree(GetProcessHeap(), 0, buffer);
WideCharToMultiByte(CP_OEMCP, 0, fcbW, 12, fcb + 1, 12, NULL, NULL);
*fcb = 0;
TRACE("FCB: '%s'\n", ((CHAR *)fcb + 1));
HeapFree( GetProcessHeap(), 0, buffer);
TRACE("FCB: '%s'\n", fcb + 1);
AL_reg(context) =
((strchr(filename, '*')) || (strchr(filename, '$'))) != 0;
@ -618,6 +626,7 @@ static BOOL INT21_ChangeDir( CONTEXT86 *context )
{
int drive;
char *dirname = CTX_SEG_OFF_TO_LIN(context, context->SegDs,context->Edx);
WCHAR dirnameW[MAX_PATH];
TRACE("changedir %s\n", dirname);
if (dirname[0] && (dirname[1] == ':'))
@ -626,7 +635,8 @@ static BOOL INT21_ChangeDir( CONTEXT86 *context )
dirname += 2;
}
else drive = DRIVE_GetCurrentDrive();
return DRIVE_Chdir( drive, dirname );
MultiByteToWideChar(CP_OEMCP, 0, dirname, -1, dirnameW, MAX_PATH);
return DRIVE_Chdir( drive, dirnameW );
}
@ -636,10 +646,14 @@ static int INT21_FindFirst( CONTEXT86 *context )
const char *path;
DOS_FULL_NAME full_name;
FINDFILE_DTA *dta = (FINDFILE_DTA *)GetCurrentDTA(context);
WCHAR pathW[MAX_PATH];
WCHAR maskW[12];
path = (const char *)CTX_SEG_OFF_TO_LIN(context, context->SegDs, context->Edx);
MultiByteToWideChar(CP_OEMCP, 0, path, -1, pathW, MAX_PATH);
dta->unixPath = NULL;
if (!DOSFS_GetFullName( path, FALSE, &full_name ))
if (!DOSFS_GetFullName( pathW, FALSE, &full_name ))
{
AX_reg(context) = GetLastError();
SET_CFLAG(context);
@ -650,10 +664,12 @@ static int INT21_FindFirst( CONTEXT86 *context )
p = strrchr( dta->unixPath, '/' );
*p = '\0';
MultiByteToWideChar(CP_OEMCP, 0, p + 1, -1, pathW, MAX_PATH);
/* Note: terminating NULL in dta->mask overwrites dta->search_attr
* (doesn't matter as it is set below anyway)
*/
if (!DOSFS_ToDosFCBFormat( p + 1, dta->mask ))
if (!DOSFS_ToDosFCBFormat( pathW, maskW ))
{
HeapFree( GetProcessHeap(), 0, dta->unixPath );
dta->unixPath = NULL;
@ -662,6 +678,7 @@ static int INT21_FindFirst( CONTEXT86 *context )
SET_CFLAG(context);
return 0;
}
WideCharToMultiByte(CP_OEMCP, 0, maskW, 12, dta->mask, sizeof(dta->mask), NULL, NULL);
dta->drive = (path[0] && (path[1] == ':')) ? toupper(path[0]) - 'A'
: DRIVE_GetCurrentDrive();
dta->count = 0;
@ -743,7 +760,8 @@ static BOOL INT21_GetCurrentDirectory( CONTEXT86 *context )
SetLastError( ERROR_INVALID_DRIVE );
return FALSE;
}
lstrcpynA( ptr, DRIVE_GetDosCwd(drive), 64 );
WideCharToMultiByte(CP_OEMCP, 0, DRIVE_GetDosCwd(drive), -1, ptr, 64, NULL, NULL);
ptr[63] = 0; /* ensure 0 termination */
AX_reg(context) = 0x0100; /* success return code */
return TRUE;
}
@ -1586,8 +1604,9 @@ void WINAPI DOS3Call( CONTEXT86 *context )
break;
case 0x02:{
const DOS_DEVICE *dev;
static const WCHAR scsimgrW[] = {'S','C','S','I','M','G','R','$',0};
if ((dev = DOSFS_GetDeviceByHandle( DosFileHandleToWin32Handle(BX_reg(context)) )) &&
!strcasecmp( dev->name, "SCSIMGR$" ))
!strcmpiW( dev->name, scsimgrW ))
{
ASPI_DOS_HandleInt(context);
}

View file

@ -36,6 +36,7 @@
# include <unistd.h>
#endif
#include "windef.h"
#include "winnls.h"
#include "callback.h"
#include "file.h"
#include "miscemu.h"
@ -249,17 +250,22 @@ static inline void outl( DWORD value, WORD port )
static void IO_port_init(void)
{
char temp[1024];
WCHAR tempW[1024];
static const WCHAR portsW[] = {'p','o','r','t','s',0};
static const WCHAR readW[] = {'r','e','a','d',0};
static const WCHAR writeW[] = {'w','r','i','t','e',0};
static const WCHAR asteriskW[] = {'*',0};
do_direct_port_access = 0;
/* Can we do that? */
if (!iopl(3)) {
iopl(0);
PROFILE_GetWineIniString( "ports", "read", "*",
temp, sizeof(temp) );
PROFILE_GetWineIniString( portsW, readW, asteriskW, tempW, 1024 );
WideCharToMultiByte(CP_ACP, 0, tempW, -1, temp, 1024, NULL, NULL);
do_IO_port_init_read_or_write(temp, IO_READ);
PROFILE_GetWineIniString( "ports", "write", "*",
temp, sizeof(temp) );
PROFILE_GetWineIniString( portsW, writeW, asteriskW, tempW, 1024 );
WideCharToMultiByte(CP_ACP, 0, tempW, -1, temp, 1024, NULL, NULL);
do_IO_port_init_read_or_write(temp, IO_WRITE);
}
IO_FixCMOSCheckSum();

View file

@ -650,9 +650,12 @@ void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name, HANDLE *win
{
DOS_FULL_NAME full_name;
const char *name = main_exe_name;
UNICODE_STRING nameW;
TRACE( "starting Winelib app %s\n", debugstr_a(main_exe_name) );
if (DOSFS_GetFullName( name, TRUE, &full_name )) name = full_name.long_name;
RtlCreateUnicodeStringFromAsciiz(&nameW, name);
if (DOSFS_GetFullName( nameW.Buffer, TRUE, &full_name )) name = full_name.long_name;
RtlFreeUnicodeString(&nameW);
CloseHandle( main_exe_file );
main_exe_file = 0;
if (wine_dlopen( name, RTLD_NOW, error, sizeof(error) ))
@ -1194,13 +1197,16 @@ BOOL WINAPI CreateProcessA( LPCSTR app_name, LPSTR cmd_line, LPSECURITY_ATTRIBUT
if (cur_dir)
{
if (DOSFS_GetFullName( cur_dir, TRUE, &full_dir ))
UNICODE_STRING cur_dirW;
RtlCreateUnicodeStringFromAsciiz(&cur_dirW, cur_dir);
if (DOSFS_GetFullName( cur_dirW.Buffer, TRUE, &full_dir ))
unixdir = full_dir.long_name;
RtlFreeUnicodeString(&cur_dirW);
}
else
{
char buf[MAX_PATH];
if (GetCurrentDirectoryA(sizeof(buf),buf))
WCHAR buf[MAX_PATH];
if (GetCurrentDirectoryW(MAX_PATH, buf))
{
if (DOSFS_GetFullName( buf, TRUE, &full_dir )) unixdir = full_dir.long_name;
}
@ -1253,11 +1259,16 @@ BOOL WINAPI CreateProcessA( LPCSTR app_name, LPSTR cmd_line, LPSECURITY_ATTRIBUT
/* fall through */
case BINARY_UNIX_EXE:
{
/* unknown file, try as unix executable */
UNICODE_STRING nameW;
DOS_FULL_NAME full_name;
const char *unixfilename = name;
TRACE( "starting %s as Unix binary\n", debugstr_a(name) );
if (DOSFS_GetFullName( name, TRUE, &full_name )) unixfilename = full_name.long_name;
RtlCreateUnicodeStringFromAsciiz(&nameW, name);
if (DOSFS_GetFullName( nameW.Buffer, TRUE, &full_name )) unixfilename = full_name.long_name;
RtlFreeUnicodeString(&nameW);
retv = (fork_and_exec( unixfilename, tidy_cmdline, env, unixdir ) != -1);
}
break;

View file

@ -344,9 +344,16 @@ LPCSTR VMM_Service_Name[N_VMM_SERVICE] =
HANDLE DEVICE_Open( LPCSTR filename, DWORD access, LPSECURITY_ATTRIBUTES sa )
HANDLE DEVICE_Open( LPCWSTR filenameW, DWORD access, LPSECURITY_ATTRIBUTES sa )
{
const struct VxDInfo *info;
char filename[MAX_PATH];
if (!WideCharToMultiByte(CP_ACP, 0, filenameW, -1, filename, MAX_PATH, NULL, NULL))
{
SetLastError( ERROR_FILE_NOT_FOUND );
return 0;
}
for (info = VxDList; info->name; info++)
if (!strncasecmp( info->name, filename, strlen(info->name) ))
@ -1563,4 +1570,3 @@ static BOOL DeviceIo_HASP(DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInB
return retv;
}