Convert most of the file APIs to Unicode.
This commit is contained in:
parent
ad0b42a099
commit
d75aed2c92
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
1155
files/dos_fs.c
1155
files/dos_fs.c
File diff suppressed because it is too large
Load Diff
613
files/drive.c
613
files/drive.c
File diff suppressed because it is too large
Load Diff
682
files/file.c
682
files/file.c
File diff suppressed because it is too large
Load Diff
751
files/profile.c
751
files/profile.c
File diff suppressed because it is too large
Load Diff
31
files/smb.c
31
files/smb.c
|
@ -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++;
|
||||
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
197
misc/registry.c
197
misc/registry.c
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue