From 4d984fd9c156164bb8454f9da8aacf321ac96899 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 20 Feb 2004 05:22:20 +0000 Subject: [PATCH] Create real file handles for VxDs instead of using the server device object hack (partly based on a patch by Eric Pouech). --- dlls/kernel/Makefile.in | 1 - dlls/kernel/device.c | 350 ---------------------------------------- dlls/kernel/vxd.c | 243 ++++++++++++++++++++++++++++ files/file.c | 2 +- include/file.h | 4 +- 5 files changed, 246 insertions(+), 354 deletions(-) delete mode 100644 dlls/kernel/device.c diff --git a/dlls/kernel/Makefile.in b/dlls/kernel/Makefile.in index 8192fc17d6..9892f5ceda 100644 --- a/dlls/kernel/Makefile.in +++ b/dlls/kernel/Makefile.in @@ -33,7 +33,6 @@ C_SRCS = \ console.c \ cpu.c \ debugger.c \ - device.c \ dosmem.c \ editline.c \ environ.c \ diff --git a/dlls/kernel/device.c b/dlls/kernel/device.c deleted file mode 100644 index 9c34dcc24d..0000000000 --- a/dlls/kernel/device.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Win32 device functions - * - * Copyright 1998 Marcus Meissner - * Copyright 1998 Ulrich Weigand - * Copyright 1998 Patrik Stridvall - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "config.h" -#include "wine/port.h" - -#include -#include -#include -#include -#include - -#include "ntstatus.h" -#include "windef.h" -#include "winbase.h" -#include "winreg.h" -#include "winerror.h" -#include "winnls.h" -#include "file.h" -#include "kernel_private.h" -#include "wine/server.h" -#include "wine/unicode.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(file); - - -/* - * VxD names are taken from the Win95 DDK - */ - -struct VxDInfo -{ - LPCSTR name; - WORD id; - HMODULE module; - BOOL (*deviceio)(DWORD, LPVOID, DWORD, - LPVOID, DWORD, LPDWORD, LPOVERLAPPED); -}; - -static struct VxDInfo VxDList[] = -{ - /* Standard VxD IDs */ - { "VMM", 0x0001, NULL, NULL }, - { "DEBUG", 0x0002, NULL, NULL }, - { "VPICD", 0x0003, NULL, NULL }, - { "VDMAD", 0x0004, NULL, NULL }, - { "VTD", 0x0005, NULL, NULL }, - { "V86MMGR", 0x0006, NULL, NULL }, - { "PAGESWAP", 0x0007, NULL, NULL }, - { "PARITY", 0x0008, NULL, NULL }, - { "REBOOT", 0x0009, NULL, NULL }, - { "VDD", 0x000A, NULL, NULL }, - { "VSD", 0x000B, NULL, NULL }, - { "VMD", 0x000C, NULL, NULL }, - { "VKD", 0x000D, NULL, NULL }, - { "VCD", 0x000E, NULL, NULL }, - { "VPD", 0x000F, NULL, NULL }, - { "BLOCKDEV", 0x0010, NULL, NULL }, - { "VMCPD", 0x0011, NULL, NULL }, - { "EBIOS", 0x0012, NULL, NULL }, - { "BIOSXLAT", 0x0013, NULL, NULL }, - { "VNETBIOS", 0x0014, NULL, NULL }, - { "DOSMGR", 0x0015, NULL, NULL }, - { "WINLOAD", 0x0016, NULL, NULL }, - { "SHELL", 0x0017, NULL, NULL }, - { "VMPOLL", 0x0018, NULL, NULL }, - { "VPROD", 0x0019, NULL, NULL }, - { "DOSNET", 0x001A, NULL, NULL }, - { "VFD", 0x001B, NULL, NULL }, - { "VDD2", 0x001C, NULL, NULL }, - { "WINDEBUG", 0x001D, NULL, NULL }, - { "TSRLOAD", 0x001E, NULL, NULL }, - { "BIOSHOOK", 0x001F, NULL, NULL }, - { "INT13", 0x0020, NULL, NULL }, - { "PAGEFILE", 0x0021, NULL, NULL }, - { "SCSI", 0x0022, NULL, NULL }, - { "MCA_POS", 0x0023, NULL, NULL }, - { "SCSIFD", 0x0024, NULL, NULL }, - { "VPEND", 0x0025, NULL, NULL }, - { "VPOWERD", 0x0026, NULL, NULL }, - { "VXDLDR", 0x0027, NULL, NULL }, - { "NDIS", 0x0028, NULL, NULL }, - { "BIOS_EXT", 0x0029, NULL, NULL }, - { "VWIN32", 0x002A, NULL, NULL }, - { "VCOMM", 0x002B, NULL, NULL }, - { "SPOOLER", 0x002C, NULL, NULL }, - { "WIN32S", 0x002D, NULL, NULL }, - { "DEBUGCMD", 0x002E, NULL, NULL }, - - { "VNB", 0x0031, NULL, NULL }, - { "SERVER", 0x0032, NULL, NULL }, - { "CONFIGMG", 0x0033, NULL, NULL }, - { "DWCFGMG", 0x0034, NULL, NULL }, - { "SCSIPORT", 0x0035, NULL, NULL }, - { "VFBACKUP", 0x0036, NULL, NULL }, - { "ENABLE", 0x0037, NULL, NULL }, - { "VCOND", 0x0038, NULL, NULL }, - - { "EFAX", 0x003A, NULL, NULL }, - { "DSVXD", 0x003B, NULL, NULL }, - { "ISAPNP", 0x003C, NULL, NULL }, - { "BIOS", 0x003D, NULL, NULL }, - { "WINSOCK", 0x003E, NULL, NULL }, - { "WSOCK", 0x003E, NULL, NULL }, - { "WSIPX", 0x003F, NULL, NULL }, - { "IFSMgr", 0x0040, NULL, NULL }, - { "VCDFSD", 0x0041, NULL, NULL }, - { "MRCI2", 0x0042, NULL, NULL }, - { "PCI", 0x0043, NULL, NULL }, - { "PELOADER", 0x0044, NULL, NULL }, - { "EISA", 0x0045, NULL, NULL }, - { "DRAGCLI", 0x0046, NULL, NULL }, - { "DRAGSRV", 0x0047, NULL, NULL }, - { "PERF", 0x0048, NULL, NULL }, - { "AWREDIR", 0x0049, NULL, NULL }, - - /* Far East support */ - { "ETEN", 0x0060, NULL, NULL }, - { "CHBIOS", 0x0061, NULL, NULL }, - { "VMSGD", 0x0062, NULL, NULL }, - { "VPPID", 0x0063, NULL, NULL }, - { "VIME", 0x0064, NULL, NULL }, - { "VHBIOSD", 0x0065, NULL, NULL }, - - /* Multimedia OEM IDs */ - { "VTDAPI", 0x0442, NULL, NULL }, - { "MMDEVLDR", 0x044A, NULL, NULL }, - - /* Network Device IDs */ - { "VNetSup", 0x0480, NULL, NULL }, - { "VRedir", 0x0481, NULL, NULL }, - { "VBrowse", 0x0482, NULL, NULL }, - { "VSHARE", 0x0483, NULL, NULL }, - { "IFSMgr", 0x0484, NULL, NULL }, - { "MEMPROBE", 0x0485, NULL, NULL }, - { "VFAT", 0x0486, NULL, NULL }, - { "NWLINK", 0x0487, NULL, NULL }, - { "VNWLINK", 0x0487, NULL, NULL }, - { "NWSUP", 0x0487, NULL, NULL }, - { "VTDI", 0x0488, NULL, NULL }, - { "VIP", 0x0489, NULL, NULL }, - { "VTCP", 0x048A, NULL, NULL }, - { "VCache", 0x048B, NULL, NULL }, - { "VUDP", 0x048C, NULL, NULL }, - { "VAsync", 0x048D, NULL, NULL }, - { "NWREDIR", 0x048E, NULL, NULL }, - { "STAT80", 0x048F, NULL, NULL }, - { "SCSIPORT", 0x0490, NULL, NULL }, - { "FILESEC", 0x0491, NULL, NULL }, - { "NWSERVER", 0x0492, NULL, NULL }, - { "SECPROV", 0x0493, NULL, NULL }, - { "NSCL", 0x0494, NULL, NULL }, - { "WSTCP", 0x0495, NULL, NULL }, - { "NDIS2SUP", 0x0496, NULL, NULL }, - { "MSODISUP", 0x0497, NULL, NULL }, - { "Splitter", 0x0498, NULL, NULL }, - { "PPP", 0x0499, NULL, NULL }, - { "VDHCP", 0x049A, NULL, NULL }, - { "VNBT", 0x049B, NULL, NULL }, - { "LOGGER", 0x049D, NULL, NULL }, - { "EFILTER", 0x049E, NULL, NULL }, - { "FFILTER", 0x049F, NULL, NULL }, - { "TFILTER", 0x04A0, NULL, NULL }, - { "AFILTER", 0x04A1, NULL, NULL }, - { "IRLAMP", 0x04A2, NULL, NULL }, - - { "PCCARD", 0x097C, NULL, NULL }, - { "HASP95", 0x3721, NULL, NULL }, - - /* WINE additions, ids unknown */ - { "MONODEBG", 0x4242, NULL, NULL }, - - { NULL, 0, NULL, NULL } -}; - - -HANDLE DEVICE_Open( LPCWSTR filenameW, DWORD access, LPSECURITY_ATTRIBUTES sa ) -{ - static const WCHAR dotVxDW[] = {'.','v','x','d',0}; - struct VxDInfo *info; - WCHAR *p, buffer[16]; - char filename[32]; - - if (strlenW( filenameW ) >= sizeof(buffer)/sizeof(WCHAR) - 4 || - strchrW( filenameW, '/' ) || strchrW( filenameW, '\\' )) - { - SetLastError( ERROR_FILE_NOT_FOUND ); - return 0; - } - strcpyW( buffer, filenameW ); - p = strchrW( buffer, '.' ); - if (!p) strcatW( buffer, dotVxDW ); - else if (strcmpiW( p, dotVxDW )) /* existing extension has to be .vxd */ - { - SetLastError( ERROR_FILE_NOT_FOUND ); - return 0; - } - - if (!WideCharToMultiByte(CP_ACP, 0, buffer, -1, filename, sizeof(filename), NULL, NULL)) - { - SetLastError( ERROR_FILE_NOT_FOUND ); - return 0; - } - - for (info = VxDList; info->name; info++) - if (!strncasecmp( info->name, filename, strlen(info->name) )) - { - if (!info->module) - { - info->module = LoadLibraryW( buffer ); - if (info->module) - info->deviceio = (void *)GetProcAddress( info->module, "DeviceIoControl" ); - } - return FILE_CreateDevice( info->id | 0x10000, access, sa ); - } - - FIXME( "Unknown/unsupported VxD %s. Try setting Windows version to 'nt40' or 'win31'.\n", - filename); - - SetLastError( ERROR_FILE_NOT_FOUND ); - return 0; -} - -static DWORD DEVICE_GetClientID( HANDLE handle ) -{ - DWORD ret = 0; - SERVER_START_REQ( get_device_id ) - { - req->handle = handle; - if (!wine_server_call( req )) ret = reply->id; - } - SERVER_END_REQ; - return ret; -} - -static const struct VxDInfo *DEVICE_GetInfo( DWORD clientID ) -{ - const struct VxDInfo *info = NULL; - - if (clientID & 0x10000) - { - for (info = VxDList; info->name; info++) - if (info->id == LOWORD(clientID)) break; - } - return info; -} - -/**************************************************************************** - * DeviceIoControl (KERNEL32.@) - * This is one of those big ugly nasty procedure which can do - * a million and one things when it comes to devices. It can also be - * used for VxD communication. - * - * A return value of FALSE indicates that something has gone wrong which - * GetLastError can decipher. - */ -BOOL WINAPI DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, - LPVOID lpvInBuffer, DWORD cbInBuffer, - LPVOID lpvOutBuffer, DWORD cbOutBuffer, - LPDWORD lpcbBytesReturned, - LPOVERLAPPED lpOverlapped) -{ - DWORD clientID; - - TRACE( "(%p,%ld,%p,%ld,%p,%ld,%p,%p)\n", - hDevice,dwIoControlCode,lpvInBuffer,cbInBuffer, - lpvOutBuffer,cbOutBuffer,lpcbBytesReturned,lpOverlapped ); - - if (!(clientID = DEVICE_GetClientID( hDevice ))) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return FALSE; - } - - /* Check if this is a user defined control code for a VxD */ - if( HIWORD( dwIoControlCode ) == 0 ) - { - const struct VxDInfo *info; - if (!(info = DEVICE_GetInfo( clientID ))) - { - FIXME( "No device found for id %lx\n", clientID); - } - else if ( info->deviceio ) - { - return info->deviceio( dwIoControlCode, - lpvInBuffer, cbInBuffer, - lpvOutBuffer, cbOutBuffer, - lpcbBytesReturned, lpOverlapped ); - } - else - { - FIXME( "Unimplemented control %ld for VxD device %s\n", - dwIoControlCode, info->name ? info->name : "???" ); - /* FIXME: this is for invalid calls on W98SE, - * but maybe we should use ERROR_CALL_NOT_IMPLEMENTED - * instead ? */ - SetLastError( ERROR_INVALID_FUNCTION ); - } - } - else - { - NTSTATUS status; - - if (lpOverlapped) - { - status = NtDeviceIoControlFile(hDevice, lpOverlapped->hEvent, - NULL, NULL, - (PIO_STATUS_BLOCK)lpOverlapped, - dwIoControlCode, - lpvInBuffer, cbInBuffer, - lpvOutBuffer, cbOutBuffer); - if (status) SetLastError(RtlNtStatusToDosError(status)); - if (lpcbBytesReturned) *lpcbBytesReturned = lpOverlapped->InternalHigh; - return !status; - } - else - { - IO_STATUS_BLOCK iosb; - - status = NtDeviceIoControlFile(hDevice, NULL, NULL, NULL, &iosb, - dwIoControlCode, - lpvInBuffer, cbInBuffer, - lpvOutBuffer, cbOutBuffer); - if (status) SetLastError(RtlNtStatusToDosError(status)); - if (lpcbBytesReturned) *lpcbBytesReturned = iosb.Information; - return !status; - } - } - return FALSE; -} diff --git a/dlls/kernel/vxd.c b/dlls/kernel/vxd.c index bddbf5a2e6..ad14e64cb3 100644 --- a/dlls/kernel/vxd.c +++ b/dlls/kernel/vxd.c @@ -28,6 +28,7 @@ # include #endif #include +#include #include #include @@ -40,11 +41,198 @@ #include "winnt.h" #include "winternl.h" #include "wine/winbase16.h" +#include "file.h" #include "kernel_private.h" +#include "wine/unicode.h" +#include "wine/server.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(vxd); +typedef BOOL (WINAPI *DeviceIoProc)(DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPOVERLAPPED); + +struct vxd_module +{ + dev_t dev; + ino_t ino; + HANDLE handle; + HMODULE module; + DeviceIoProc proc; +}; + +#define MAX_VXD_MODULES 32 + +static struct vxd_module vxd_modules[MAX_VXD_MODULES]; + +static CRITICAL_SECTION vxd_section; +static CRITICAL_SECTION_DEBUG critsect_debug = +{ + 0, 0, &vxd_section, + { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, + 0, 0, { 0, (DWORD)(__FILE__ ": vxd_section") } +}; +static CRITICAL_SECTION vxd_section = { &critsect_debug, -1, 0, 0, 0, 0 }; + + +/* create a file handle to represent a VxD, by opening a dummy file in the wineserver directory */ +static HANDLE open_vxd_handle( LPCWSTR name ) +{ + const char *dir = wine_get_server_dir(); + char *unix_name; + int len1, len2; + HANDLE ret; + + len1 = strlen( dir ); + len2 = WideCharToMultiByte( CP_UNIXCP, 0, name, -1, NULL, 0, NULL, NULL); + if (!(unix_name = HeapAlloc( GetProcessHeap(), 0, len1 + len2 + 1 ))) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return 0; + } + strcpy( unix_name, dir ); + unix_name[len1] = '/'; + WideCharToMultiByte( CP_UNIXCP, 0, name, -1, unix_name + len1 + 1, len2, NULL, NULL); + ret = FILE_CreateFile( unix_name, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, + OPEN_ALWAYS, 0, 0, TRUE, DRIVE_FIXED ); + HeapFree( GetProcessHeap(), 0, unix_name ); + return ret; +} + +/* retrieve the DeviceIoControl function for a Vxd given a file handle */ +static DeviceIoProc get_vxd_proc( HANDLE handle ) +{ + struct stat st; + DeviceIoProc ret = NULL; + int status, i, fd; + + status = wine_server_handle_to_fd( handle, 0, &fd, NULL, NULL ); + if (status) + { + SetLastError( RtlNtStatusToDosError(status) ); + return NULL; + } + if (fstat( fd, &st ) == -1) + { + wine_server_release_fd( handle, fd ); + SetLastError( ERROR_INVALID_HANDLE ); + return NULL; + } + + RtlEnterCriticalSection( &vxd_section ); + + for (i = 0; i < MAX_VXD_MODULES; i++) + { + if (!vxd_modules[i].module) break; + if (vxd_modules[i].dev == st.st_dev && vxd_modules[i].ino == st.st_ino) + { + if (!(ret = vxd_modules[i].proc)) SetLastError( ERROR_INVALID_FUNCTION ); + goto done; + } + } + /* FIXME: Here we could go through the directory to find the VxD name and load it. */ + /* Let's wait to find out if there are actually apps out there that try to share */ + /* VxD handles between processes, before we go to the trouble of implementing it. */ + ERR( "handle %p not found in module list, inherited from another process?\n", handle ); + +done: + RtlLeaveCriticalSection( &vxd_section ); + return ret; +} + + +/* load a VxD and return a file handle to it */ +HANDLE VXD_Open( LPCWSTR filenameW, DWORD access, SECURITY_ATTRIBUTES *sa ) +{ + static const WCHAR dotVxDW[] = {'.','v','x','d',0}; + int i; + HANDLE handle; + HMODULE module; + WCHAR *p, name[16]; + + if (!(GetVersion() & 0x80000000)) /* there are no VxDs on NT */ + { + SetLastError( ERROR_INVALID_PARAMETER ); + return 0; + } + + /* normalize the filename */ + + if (strlenW( filenameW ) >= sizeof(name)/sizeof(WCHAR) - 4 || + strchrW( filenameW, '/' ) || strchrW( filenameW, '\\' )) + { + SetLastError( ERROR_FILE_NOT_FOUND ); + return 0; + } + strcpyW( name, filenameW ); + strlwrW( name ); + p = strchrW( name, '.' ); + if (!p) strcatW( name, dotVxDW ); + else if (strcmpW( p, dotVxDW )) /* existing extension has to be .vxd */ + { + SetLastError( ERROR_FILE_NOT_FOUND ); + return 0; + } + + /* try to load the module first */ + + if (!(module = LoadLibraryW( name ))) + { + FIXME( "Unknown/unsupported VxD %s. Try setting Windows version to 'nt40' or 'win31'.\n", + debugstr_w(name) ); + return 0; + } + + /* register the module in the global list if necessary */ + + RtlEnterCriticalSection( &vxd_section ); + + for (i = 0; i < MAX_VXD_MODULES; i++) + { + if (vxd_modules[i].module == module) + { + handle = vxd_modules[i].handle; + goto done; /* already registered */ + } + if (!vxd_modules[i].module) /* new one, register it */ + { + struct stat st; + int fd; + + /* get a file handle to the dummy file */ + if (!(handle = open_vxd_handle( name ))) + { + FreeLibrary( module ); + goto done; + } + wine_server_handle_to_fd( handle, 0, &fd, NULL, NULL ); + if (fstat( fd, &st ) != -1) + { + vxd_modules[i].dev = st.st_dev; + vxd_modules[i].ino = st.st_ino; + } + vxd_modules[i].module = module; + vxd_modules[i].handle = handle; + vxd_modules[i].proc = (DeviceIoProc)GetProcAddress( module, "DeviceIoControl" ); + wine_server_release_fd( handle, fd ); + goto done; + } + } + + ERR("too many open VxD modules, please report\n" ); + CloseHandle( handle ); + FreeLibrary( module ); + handle = 0; + +done: + RtlLeaveCriticalSection( &vxd_section ); + if (!DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), &handle, 0, + (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle), + DUP_HANDLE_SAME_ACCESS )) + handle = 0; + return handle; +} + + /* * VMM VxDCall service names are (mostly) taken from Stan Mitchell's * "Inside the Windows 95 File System" @@ -1164,3 +1352,58 @@ HANDLE WINAPI OpenVxDHandle(HANDLE hHandleRing3) FIXME( "(%p), stub! (returning Ring 3 handle instead of Ring 0)\n", hHandleRing3); return hHandleRing3; } + + +/**************************************************************************** + * DeviceIoControl (KERNEL32.@) + * This is one of those big ugly nasty procedure which can do + * a million and one things when it comes to devices. It can also be + * used for VxD communication. + * + * A return value of FALSE indicates that something has gone wrong which + * GetLastError can decipher. + */ +BOOL WINAPI DeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, + LPVOID lpvInBuffer, DWORD cbInBuffer, + LPVOID lpvOutBuffer, DWORD cbOutBuffer, + LPDWORD lpcbBytesReturned, + LPOVERLAPPED lpOverlapped) +{ + NTSTATUS status; + + TRACE( "(%p,%lx,%p,%ld,%p,%ld,%p,%p)\n", + hDevice,dwIoControlCode,lpvInBuffer,cbInBuffer, + lpvOutBuffer,cbOutBuffer,lpcbBytesReturned,lpOverlapped ); + + /* Check if this is a user defined control code for a VxD */ + + if( HIWORD( dwIoControlCode ) == 0 ) + { + DeviceIoProc proc = get_vxd_proc( hDevice ); + if (proc) return proc( dwIoControlCode, lpvInBuffer, cbInBuffer, + lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpOverlapped ); + return FALSE; + } + + /* Not a VxD, let ntdll handle it */ + + if (lpOverlapped) + { + status = NtDeviceIoControlFile(hDevice, lpOverlapped->hEvent, + NULL, NULL, (PIO_STATUS_BLOCK)lpOverlapped, + dwIoControlCode, lpvInBuffer, cbInBuffer, + lpvOutBuffer, cbOutBuffer); + if (lpcbBytesReturned) *lpcbBytesReturned = lpOverlapped->InternalHigh; + } + else + { + IO_STATUS_BLOCK iosb; + + status = NtDeviceIoControlFile(hDevice, NULL, NULL, NULL, &iosb, + dwIoControlCode, lpvInBuffer, cbInBuffer, + lpvOutBuffer, cbOutBuffer); + if (lpcbBytesReturned) *lpcbBytesReturned = iosb.Information; + } + if (status) SetLastError( RtlNtStatusToDosError(status) ); + return !status; +} diff --git a/files/file.c b/files/file.c index 21ee69e49e..bb344def6f 100644 --- a/files/file.c +++ b/files/file.c @@ -397,7 +397,7 @@ HANDLE WINAPI CreateFileW( LPCWSTR filename, DWORD access, DWORD sharing, } else if (!DOSFS_GetDevice( filename )) { - ret = DEVICE_Open( filename+4, access, sa ); + ret = VXD_Open( filename+4, access, sa ); goto done; } else diff --git a/include/file.h b/include/file.h index 3c875265ee..7a704a844b 100644 --- a/include/file.h +++ b/include/file.h @@ -97,7 +97,7 @@ extern BOOL DOSFS_FindUnixName( const DOS_FULL_NAME *path, LPCWSTR name, char *l extern BOOL DOSFS_GetFullName( LPCWSTR name, BOOL check_last, DOS_FULL_NAME *full ); -/* win32/device.c */ -extern HANDLE DEVICE_Open( LPCWSTR filename, DWORD access, LPSECURITY_ATTRIBUTES sa ); +/* vxd.c */ +extern HANDLE VXD_Open( LPCWSTR filename, DWORD access, LPSECURITY_ATTRIBUTES sa ); #endif /* __WINE_FILE_H */