diff --git a/dlls/winedos/Makefile.in b/dlls/winedos/Makefile.in index 208968e7cba..8cf3db86c53 100644 --- a/dlls/winedos/Makefile.in +++ b/dlls/winedos/Makefile.in @@ -28,7 +28,6 @@ C_SRCS = \ interrupts.c \ ioports.c \ module.c \ - ppdev.c \ relay.c \ soundblaster.c \ timer.c \ diff --git a/dlls/winedos/dosexe.h b/dlls/winedos/dosexe.h index 1a9b593ef1f..108a603c680 100644 --- a/dlls/winedos/dosexe.h +++ b/dlls/winedos/dosexe.h @@ -478,11 +478,6 @@ void DOSVM_BuildCallFrame( CONTEXT86 *, DOSRELAY, LPVOID ); extern void SB_ioport_out( WORD port, BYTE val ); extern BYTE SB_ioport_in( WORD port ); -/* ppdev.c */ -extern BOOL IO_pp_outp(int port, DWORD* res); -extern int IO_pp_inp(int port, DWORD* res); -extern char IO_pp_init(void); - /* timer.c */ extern void WINAPI DOSVM_Int08Handler(CONTEXT86*); diff --git a/dlls/winedos/ioports.c b/dlls/winedos/ioports.c index fef2d859320..57100461972 100644 --- a/dlls/winedos/ioports.c +++ b/dlls/winedos/ioports.c @@ -3,6 +3,7 @@ * * Copyright 1995 Morten Welinder * Copyright 1998 Andreas Mohr, Ove Kaaven + * Copyright 2001 Uwe Bonnes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,6 +30,22 @@ #include #include +#include +#ifdef HAVE_SYS_STAT_H +# include +#endif + +#ifdef HAVE_PPDEV +#include +#include +#ifdef HAVE_SYS_IOCTL_H +# include +#endif +#ifdef HAVE_LINUX_IOCTL_H +# include +#endif +#include +#endif #include "windef.h" #include "winbase.h" @@ -42,11 +59,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(int); -#if defined(linux) && defined(__i386__) +#ifdef linux # define DIRECT_IO_ACCESS #else # undef DIRECT_IO_ACCESS -#endif /* linux && __i386__ */ +#endif static struct { WORD countmax; @@ -425,8 +442,294 @@ static void IO_port_init(void) #endif /* DIRECT_IO_ACCESS */ +#ifdef HAVE_PPDEV + +typedef struct _PPDEVICESTRUCT{ + int fd; /* NULL if device not available */ + char *devicename; + int userbase; /* where wine thinks the ports are */ + DWORD lastaccess; /* or NULL if release */ + int timeout; /* time in second of inactivity to release the port */ +} PPDeviceStruct; + +static PPDeviceStruct PPDeviceList[5]; +static int PPDeviceNum=0; + +static int IO_pp_sort(const void *p1,const void *p2) +{ + return ((const PPDeviceStruct*)p1)->userbase - ((const PPDeviceStruct*)p2)->userbase; +} + +/* IO_pp_init + * + * Read the ppdev entries from wine.conf, open the device and check + * for necessary IOCTRL + * Report verbose about possible errors + */ +static char IO_pp_init(void) +{ + char name[80]; + char buffer[256]; + HANDLE root, hkey; + int i,idx=0,fd,res,userbase,nports=0; + char * timeout; + char ret=1; + int lasterror; + OBJECT_ATTRIBUTES attr; + UNICODE_STRING nameW; + + static const WCHAR configW[] = {'S','o','f','t','w','a','r','e','\\', + 'W','i','n','e','\\','V','D','M','\\','p','p','d','e','v',0}; + + TRACE("\n"); + + RtlOpenCurrentUser( KEY_ALL_ACCESS, &root ); + attr.Length = sizeof(attr); + attr.RootDirectory = root; + attr.ObjectName = &nameW; + attr.Attributes = 0; + attr.SecurityDescriptor = NULL; + attr.SecurityQualityOfService = NULL; + RtlInitUnicodeString( &nameW, configW ); + + /* @@ Wine registry key: HKCU\Software\Wine\VDM\ppdev */ + if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) hkey = 0; + NtClose( root ); + if (!hkey) return 1; + + for (;;) + { + DWORD total_size, len; + char temp[256]; + KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)temp; + + if (NtEnumerateValueKey( hkey, idx, KeyValueFullInformation, + temp, sizeof(temp), &total_size )) break; + if (info->Type != REG_SZ) break; + + RtlUnicodeToMultiByteN( name, sizeof(name)-1, &len, info->Name, info->NameLength ); + name[len] = 0; + RtlUnicodeToMultiByteN( buffer, sizeof(buffer)-1, &len, + (WCHAR *)(temp + info->DataOffset), total_size-info->DataOffset ); + buffer[len] = 0; + + idx++; + if(nports >4) + { + FIXME("Make the PPDeviceList larger than 5 elements\n"); + break; + } + TRACE("Device '%s' at virtual userbase '%s'\n", buffer,name); + timeout = strchr(buffer,','); + if (timeout) + *timeout++=0; + fd=open(buffer,O_RDWR); + lasterror=errno; + if (fd == -1) + { + WARN("Configuration: No access to %s Cause: %s\n",buffer,strerror(lasterror)); + WARN("Rejecting configuration item\n"); + if (lasterror == ENODEV) + ERR("Is the ppdev module loaded?\n"); + continue; + } + userbase = strtol(name, NULL, 16); + if ( errno == ERANGE) + { + WARN("Configuration: Invalid base %s for %s\n",name,buffer); + WARN("Rejecting configuration item\n"); + continue; + } + if (ioctl (fd,PPCLAIM,0)) + { + ERR("PPCLAIM rejected %s\n",buffer); + ERR("Perhaps the device is already in use or nonexistent\n"); + continue; + } + if (nports > 0) + { + for (i=0; i<= nports; i++) + { + if (PPDeviceList[i].userbase == userbase) + { + WARN("Configuration: %s uses the same virtual ports as %s\n", + buffer,PPDeviceList[0].devicename); + WARN("Configuration: Rejecting configuration item\n"); + userbase = 0; + break; + } + } + if (!userbase) continue; + } + /* Check for the minimum required IOCTLS */ + if ((ioctl(fd,PPRDATA,&res))|| + (ioctl(fd,PPRSTATUS,&res))|| + (ioctl(fd,PPRCONTROL,&res))) + { + ERR("PPUSER IOCTL not available for parport device %s\n",buffer); + continue; + } + if (ioctl (fd,PPRELEASE,0)) + { + ERR("PPRELEASE rejected %s\n",buffer); + ERR("Perhaps the device is already in use or nonexistent\n"); + continue; + } + PPDeviceList[nports].devicename = HeapAlloc(GetProcessHeap(), 0, sizeof(buffer)+1); + if (!PPDeviceList[nports].devicename) + { + ERR("No (more) space for devicename\n"); + break; + } + strcpy(PPDeviceList[nports].devicename,buffer); + PPDeviceList[nports].fd = fd; + PPDeviceList[nports].userbase = userbase; + PPDeviceList[nports].lastaccess=GetTickCount(); + if (timeout) + { + PPDeviceList[nports].timeout = strtol(timeout, NULL, 10); + if (errno == ERANGE) + { + WARN("Configuration: Invalid timeout %s in configuration for %s, Setting to 0\n", + timeout,buffer); + PPDeviceList[nports].timeout = 0; + } + } + else + PPDeviceList[nports].timeout = 0; + nports++; + } + TRACE("found %d ports\n",nports); + NtClose( hkey ); + + PPDeviceNum= nports; + if (nports > 1) + /* sort in ascending order for userbase for faster access */ + qsort (PPDeviceList,PPDeviceNum,sizeof(PPDeviceStruct),IO_pp_sort); + + if (nports) + ret=0; + for (idx= 0;idx -#include -#include -#ifdef HAVE_SYS_STAT_H -# include -#endif -#include -#include -#ifdef HAVE_SYS_IOCTL_H -# include -#endif -#ifdef HAVE_LINUX_IOCTL_H -# include -#endif -#include - -#include "winerror.h" -#include "winbase.h" -#include "winreg.h" -#include "winternl.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(int); - -typedef struct _PPDEVICESTRUCT{ - int fd; /* NULL if device not available */ - char *devicename; - int userbase; /* where wine thinks the ports are */ - DWORD lastaccess; /* or NULL if release */ - int timeout; /* time in second of inactivity to release the port */ -} PPDeviceStruct; - -static PPDeviceStruct PPDeviceList[5]; -static int PPDeviceNum=0; - -static int IO_pp_sort(const void *p1,const void *p2) -{ - return ((const PPDeviceStruct*)p1)->userbase - ((const PPDeviceStruct*)p2)->userbase; -} - -/* IO_pp_init - * - * Read the ppdev entries from wine.conf, open the device and check - * for necessary IOCTRL - * Report verbose about possible errors - */ -char IO_pp_init(void) -{ - char name[80]; - char buffer[256]; - HANDLE root, hkey; - int i,idx=0,fd,res,userbase,nports=0; - char * timeout; - char ret=1; - int lasterror; - OBJECT_ATTRIBUTES attr; - UNICODE_STRING nameW; - - static const WCHAR configW[] = {'S','o','f','t','w','a','r','e','\\', - 'W','i','n','e','\\','V','D','M','\\','p','p','d','e','v',0}; - - TRACE("\n"); - - RtlOpenCurrentUser( KEY_ALL_ACCESS, &root ); - attr.Length = sizeof(attr); - attr.RootDirectory = root; - attr.ObjectName = &nameW; - attr.Attributes = 0; - attr.SecurityDescriptor = NULL; - attr.SecurityQualityOfService = NULL; - RtlInitUnicodeString( &nameW, configW ); - - /* @@ Wine registry key: HKCU\Software\Wine\VDM\ppdev */ - if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) hkey = 0; - NtClose( root ); - if (!hkey) return 1; - - for (;;) - { - DWORD total_size, len; - char temp[256]; - KEY_VALUE_FULL_INFORMATION *info = (KEY_VALUE_FULL_INFORMATION *)temp; - - if (NtEnumerateValueKey( hkey, idx, KeyValueFullInformation, - temp, sizeof(temp), &total_size )) break; - if (info->Type != REG_SZ) break; - - RtlUnicodeToMultiByteN( name, sizeof(name)-1, &len, info->Name, info->NameLength ); - name[len] = 0; - RtlUnicodeToMultiByteN( buffer, sizeof(buffer)-1, &len, - (WCHAR *)(temp + info->DataOffset), total_size-info->DataOffset ); - buffer[len] = 0; - - idx++; - if(nports >4) - { - FIXME("Make the PPDeviceList larger than 5 elements\n"); - break; - } - TRACE("Device '%s' at virtual userbase '%s'\n", buffer,name); - timeout = strchr(buffer,','); - if (timeout) - *timeout++=0; - fd=open(buffer,O_RDWR); - lasterror=errno; - if (fd == -1) - { - WARN("Configuration: No access to %s Cause: %s\n",buffer,strerror(lasterror)); - WARN("Rejecting configuration item\n"); - if (lasterror == ENODEV) - ERR("Is the ppdev module loaded?\n"); - continue; - } - userbase = strtol(name, NULL, 16); - if ( errno == ERANGE) - { - WARN("Configuration: Invalid base %s for %s\n",name,buffer); - WARN("Rejecting configuration item\n"); - continue; - } - if (ioctl (fd,PPCLAIM,0)) - { - ERR("PPCLAIM rejected %s\n",buffer); - ERR("Perhaps the device is already in use or nonexistent\n"); - continue; - } - if (nports > 0) - { - for (i=0; i<= nports; i++) - { - if (PPDeviceList[i].userbase == userbase) - { - WARN("Configuration: %s uses the same virtual ports as %s\n", - buffer,PPDeviceList[0].devicename); - WARN("Configuration: Rejecting configuration item\n"); - userbase = 0; - break; - } - } - if (!userbase) continue; - } - /* Check for the minimum required IOCTLS */ - if ((ioctl(fd,PPRDATA,&res))|| - (ioctl(fd,PPRSTATUS,&res))|| - (ioctl(fd,PPRCONTROL,&res))) - { - ERR("PPUSER IOCTL not available for parport device %s\n",buffer); - continue; - } - if (ioctl (fd,PPRELEASE,0)) - { - ERR("PPRELEASE rejected %s\n",buffer); - ERR("Perhaps the device is already in use or nonexistent\n"); - continue; - } - PPDeviceList[nports].devicename = HeapAlloc(GetProcessHeap(), 0, sizeof(buffer)+1); - if (!PPDeviceList[nports].devicename) - { - ERR("No (more) space for devicename\n"); - break; - } - strcpy(PPDeviceList[nports].devicename,buffer); - PPDeviceList[nports].fd = fd; - PPDeviceList[nports].userbase = userbase; - PPDeviceList[nports].lastaccess=GetTickCount(); - if (timeout) - { - PPDeviceList[nports].timeout = strtol(timeout, NULL, 10); - if (errno == ERANGE) - { - WARN("Configuration: Invalid timeout %s in configuration for %s, Setting to 0\n", - timeout,buffer); - PPDeviceList[nports].timeout = 0; - } - } - else - PPDeviceList[nports].timeout = 0; - nports++; - } - TRACE("found %d ports\n",nports); - NtClose( hkey ); - - PPDeviceNum= nports; - if (nports > 1) - /* sort in ascending order for userbase for faster access */ - qsort (PPDeviceList,PPDeviceNum,sizeof(PPDeviceStruct),IO_pp_sort); - - if (nports) - ret=0; - for (idx= 0;idx