Uniform SYS/VXD Handling 1/6: Load also system files
Uwe Bonnes
bon at elektron.ikp.physik.tu-darmstadt.de
Sun Jul 10 09:18:59 CDT 2005
Changelog:
wine/dlls/kernel/file.c, dlls/kernel/vxd.c,
dlls/kernel/kernel_private.h
Load .sys drivers too, also for raw disk/cdroms
Call DeviceIoProc with Device Handle
--
Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
Index: wine/dlls/kernel/file.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/file.c,v
retrieving revision 1.39
diff -u -r1.39 file.c
--- wine/dlls/kernel/file.c 20 Jun 2005 10:40:37 -0000 1.39
+++ wine/dlls/kernel/file.c 10 Jul 2005 12:52:45 -0000
@@ -1184,6 +1184,7 @@
IO_STATUS_BLOCK io;
HANDLE ret;
DWORD dosdev;
+ WCHAR driver[16] = {0};
static const WCHAR bkslashes_with_dotW[] = {'\\','\\','.','\\',0};
static const WCHAR coninW[] = {'C','O','N','I','N','$',0};
static const WCHAR conoutW[] = {'C','O','N','O','U','T','$',0};
@@ -1228,9 +1229,21 @@
static const WCHAR pipeW[] = {'P','I','P','E','\\',0};
static const WCHAR mailslotW[] = {'M','A','I','L','S','L','O','T','\\',0};
- if ((isalphaW(filename[4]) && filename[5] == ':' && filename[6] == '\0') ||
- !strncmpiW( filename + 4, pipeW, 5 ) ||
- !strncmpiW( filename + 4, mailslotW, 9 ))
+ if ((isalphaW(filename[4]) && filename[5] == ':' && filename[6] == '\0') )
+ {
+ static const WCHAR cdromW[] = {'c','d','r','o','m','.','s','y','s',0};
+ UINT type = GetDriveTypeW(&filename[4]);
+ switch (type)
+ {
+ case DRIVE_CDROM:
+ strcpyW(driver, cdromW);
+ break;
+ default:
+ TRACE("Raw Device of type %d should be handled by appropriate driver\n", type);
+ }
+ dosdev = 0;
+ }
+ else if (!strncmpiW( filename + 4, pipeW, 5 ) || !strncmpiW( filename + 4, mailslotW, 9 ))
{
dosdev = 0;
}
@@ -1240,7 +1253,7 @@
}
else if (filename[4])
{
- ret = VXD_Open( filename+4, access, sa );
+ ret = VXD_Open( filename+4, NULL, access, sa );
goto done;
}
else
@@ -1327,7 +1340,12 @@
else
SetLastError( RtlNtStatusToDosError(status) );
}
- else SetLastError(0);
+ else
+ {
+ SetLastError(0);
+ if (driver[0])
+ ret = VXD_Open( driver, ret, access, sa );
+ }
RtlFreeUnicodeString( &nameW );
done:
Index: wine/dlls/kernel/vxd.c
===================================================================
RCS file: /home/wine/wine/dlls/kernel/vxd.c,v
retrieving revision 1.19
diff -u -r1.19 vxd.c
--- wine/dlls/kernel/vxd.c 20 Jun 2005 10:40:37 -0000 1.19
+++ wine/dlls/kernel/vxd.c 10 Jul 2005 12:52:45 -0000
@@ -46,7 +46,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(vxd);
-typedef BOOL (WINAPI *DeviceIoProc)(DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
+typedef BOOL (WINAPI *DeviceIoProc)(HANDLE, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
typedef DWORD (WINAPI *VxDCallProc)(DWORD, CONTEXT86 *);
struct vxd_module
@@ -56,6 +56,7 @@
HANDLE handle;
HMODULE module;
DeviceIoProc proc;
+ HANDLE devicehandle;
};
struct vxdcall_service
@@ -174,55 +175,75 @@
/* load a VxD and return a file handle to it */
-HANDLE VXD_Open( LPCWSTR filenameW, DWORD access, SECURITY_ATTRIBUTES *sa )
+HANDLE VXD_Open( LPCWSTR drivernameW, HANDLE device, DWORD access, SECURITY_ATTRIBUTES *sa )
{
static const WCHAR dotVxDW[] = {'.','v','x','d',0};
+ static const WCHAR dotSysW[] = {'.','s','y','s',0};
int i;
HANDLE handle;
HMODULE module;
- WCHAR *p, name[16];
+ WCHAR *p, *q = NULL, name[16];
- if (!(GetVersion() & 0x80000000)) /* there are no VxDs on NT */
- {
- SetLastError( ERROR_FILE_NOT_FOUND );
- return 0;
- }
+ TRACE("drivername %s handle %p\n", debugstr_w(drivernameW), device);
+ /* normalize the drivername */
- /* normalize the filename */
-
- if (strlenW( filenameW ) >= sizeof(name)/sizeof(WCHAR) - 4 ||
- strchrW( filenameW, '/' ) || strchrW( filenameW, '\\' ))
+ if (strlenW( drivernameW ) >= sizeof(name)/sizeof(WCHAR) - 4 ||
+ strchrW( drivernameW, '/' ) || strchrW( drivernameW, '\\' ))
{
SetLastError( ERROR_FILE_NOT_FOUND );
return 0;
}
- strcpyW( name, filenameW );
+ strcpyW( name, drivernameW );
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 )))
+ if (!p)
+ q = name + strlenW(name);
+ /* Try first to open as .sys file */
+ if (!p)
+ strcatW( name, dotSysW );
+ else
{
- FIXME( "Unknown/unsupported VxD %s. Try setting Windows version to 'nt40' or 'win31'.\n",
- debugstr_w(name) );
- SetLastError( ERROR_FILE_NOT_FOUND );
- return 0;
+ if(strcmpW( p, dotVxDW ) && strcmpW( p, dotSysW ))
+ {
+ SetLastError( ERROR_FILE_NOT_FOUND );
+ return 0;
+ }
+ }
+
+ module = LoadLibraryW( name );
+ if (!module)
+ {
+ if (!(GetVersion() & 0x80000000)) /* there are no VxDs on NT, try as .sys */
+ {
+ FIXME( "Unsupported driver%s\n", debugstr_w(name) );
+ SetLastError( ERROR_FILE_NOT_FOUND );
+ return 0;
+ }
+ else /* now try as VXD as we are emulating a non-NT system */
+ {
+ if (!p)
+ strcatW( q, dotVxDW );
+ else if (strcmpW( p, dotVxDW )) /* existing extension has to be .vxd */
+ {
+ SetLastError( ERROR_FILE_NOT_FOUND );
+ return 0;
+ }
+ if (!(module = LoadLibraryW( name )))
+ {
+ FIXME( "Unknown/unsupported VxD %s. Try setting Windows version to 'nt40' or 'win31'.\n",
+ debugstr_w(name) );
+ SetLastError( ERROR_FILE_NOT_FOUND );
+ 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)
+ if (vxd_modules[i].module == module && (!device|| vxd_modules[i].devicehandle == device))
{
handle = vxd_modules[i].handle;
goto done; /* already registered */
@@ -232,12 +253,17 @@
struct stat st;
int fd;
- /* get a file handle to the dummy file */
- if (!(handle = open_vxd_handle( name )))
- {
- FreeLibrary( module );
- goto done;
- }
+ if(!device)
+ {
+ /* get a file handle to the dummy file */
+ if (!(handle = open_vxd_handle( name )))
+ {
+ FreeLibrary( module );
+ goto done;
+ }
+ }
+ else
+ handle = device;
wine_server_handle_to_fd( handle, 0, &fd, NULL );
if (fstat( fd, &st ) != -1)
{
@@ -328,10 +354,8 @@
* 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.
+ * used for Driver communication (*.sys or *.vxd files)
*
- * 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,
@@ -345,35 +369,9 @@
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;
+ DeviceIoProc proc = get_vxd_proc( hDevice );
+ if (proc)
+ return proc( hDevice, dwIoControlCode, lpvInBuffer, cbInBuffer,
+ lpvOutBuffer, cbOutBuffer, lpcbBytesReturned, lpOverlapped );
+ return FALSE;
}
Index: wine/dlls/kernel/kernel_private.h
===================================================================
RCS file: /home/wine/wine/dlls/kernel/kernel_private.h,v
retrieving revision 1.25
diff -u -r1.25 kernel_private.h
--- wine/dlls/kernel/kernel_private.h 14 Jun 2005 11:42:34 -0000 1.25
+++ wine/dlls/kernel/kernel_private.h 10 Jul 2005 12:52:45 -0000
@@ -102,7 +102,7 @@
extern BOOL NLS_IsUnicodeOnlyLcid(LCID);
-extern HANDLE VXD_Open( LPCWSTR filename, DWORD access, LPSECURITY_ATTRIBUTES sa );
+extern HANDLE VXD_Open( LPCWSTR filename, HANDLE device, DWORD access, LPSECURITY_ATTRIBUTES sa );
extern WORD DOSMEM_0000H;
extern WORD DOSMEM_BiosDataSeg;
More information about the wine-patches
mailing list