DOSBox-X
|
00001 #include "config.h" 00002 #include "logging.h" 00003 00004 #if defined(_MSC_VER) 00005 # pragma warning(disable:4244) /* const fmath::local::uint64_t to double possible loss of data */ 00006 # pragma warning(disable:4267) /* ... possible loss of data */ 00007 # pragma warning(disable:4305) /* truncation from double to float */ 00008 #endif 00009 00010 #if defined (_MSC_VER) 00011 # if defined (_M_IX86)/*x86 only*/ 00012 void outportb(Bit32u portid, Bit8u value) { 00013 __asm mov edx,portid 00014 __asm mov al,value 00015 __asm out dx,al 00016 } 00017 00018 Bit8u inportb(Bit32u portid) { 00019 Bit8u value; 00020 00021 __asm mov edx,portid 00022 __asm in al,dx 00023 __asm mov value,al 00024 return value; 00025 } 00026 00027 void outportw(Bit32u portid, Bit16u value) { 00028 __asm mov edx,portid 00029 __asm mov ax,value 00030 __asm out dx,ax 00031 } 00032 00033 Bit16u inportw(Bit32u portid) { 00034 Bit16u value; 00035 00036 __asm mov edx,portid 00037 __asm in ax,dx 00038 __asm mov value,ax 00039 return value; 00040 } 00041 00042 void outportd(Bit32u portid, Bit32u value) { 00043 __asm mov edx,portid 00044 __asm mov eax,value 00045 __asm out dx,eax 00046 } 00047 00048 Bit32u inportd(Bit32u portid) { 00049 Bit32u value; 00050 00051 __asm mov edx,portid 00052 __asm in eax,dx 00053 __asm mov value,eax 00054 return value; 00055 } 00056 # endif 00057 #else 00058 # if defined(__i386__) || defined(__amd64__) || defined(__x86_64__) 00059 void outportb(Bit32u portid, Bit8u value) { 00060 __asm__ volatile ( 00061 "movl %0,%%edx \n" 00062 "movb %1,%%al \n" 00063 "outb %%al,%%dx " 00064 : 00065 : "r" (portid), "r" (value) 00066 : "edx", "al" 00067 ); 00068 } 00069 Bit8u inportb(Bit32u portid) { 00070 Bit8u value; 00071 __asm__ volatile ( 00072 "movl %1,%%edx \n" 00073 "inb %%dx,%%al \n" 00074 "movb %%al,%0 " 00075 : "=m" (value) 00076 : "r" (portid) 00077 : "edx", "al", "memory" 00078 ); 00079 return value; 00080 } 00081 # endif 00082 #endif 00083 00084 #if defined(WIN32) && defined(_M_IX86)/*WIN32 x86 only*/ 00085 00086 // WIN specific 00087 #include "sdl.h" 00088 #include <windows.h> 00089 #include <winioctl.h> // NEEDED by GCC 00090 #include "porttalk.h" 00091 #include <stdio.h> 00092 #include <process.h> 00093 00094 // PortTalk_IOCTL.h can be downloaded with PortTalk 00095 #include "PortTalk_IOCTL.h" 00096 00097 typedef struct driverpermstruct { 00098 Bit16u offset; 00099 Bit8u value; 00100 } permblock; 00101 00102 static HANDLE porttalkhandle=INVALID_HANDLE_VALUE; 00103 static Bit8u ioperm[8192]; 00104 static bool isNT = false; 00105 00106 bool initPorttalk() { 00107 // handles neded for starting service 00108 SC_HANDLE ServiceManager = NULL; 00109 SC_HANDLE PorttalkService = NULL; 00110 00111 // check which platform we are on 00112 OSVERSIONINFO osvi; 00113 memset(&osvi,0,sizeof(OSVERSIONINFO)); 00114 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); 00115 if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) { 00116 LOG_MSG("GET VERSION failed!"); 00117 return false; 00118 } 00119 if(osvi.dwPlatformId==2) isNT=true; 00120 00121 if(isNT && porttalkhandle==INVALID_HANDLE_VALUE) { 00122 porttalkhandle = CreateFile("\\\\.\\PortTalk", GENERIC_READ, 00123 0, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_DEVICE, NULL); 00124 00125 if (porttalkhandle == INVALID_HANDLE_VALUE) { 00126 Bitu retval=0; 00127 // Porttalk service is not started. Attempt to start it. 00128 ServiceManager = OpenSCManager (NULL, // NULL is local machine 00129 NULL, // default database 00130 SC_MANAGER_ENUMERATE_SERVICE); // desired access 00131 00132 if(ServiceManager==NULL) { 00133 // No rights to enumerate services 00134 LOG_MSG("You do not have the rights to enumerate services."); 00135 return false; 00136 } 00137 PorttalkService = OpenService(ServiceManager, 00138 "PortTalk", // service name 00139 SERVICE_START); // desired access 00140 00141 if(PorttalkService==NULL) { 00142 // get causes 00143 switch (retval=GetLastError()) { 00144 case ERROR_ACCESS_DENIED: 00145 LOG_MSG("You do not have the rights to enumerate services."); 00146 break; 00147 case ERROR_SERVICE_DOES_NOT_EXIST: 00148 LOG_MSG("Porttalk service is not installed."); 00149 break; 00150 default: 00151 LOG_MSG("Error %d occured accessing porttalk dirver.",retval); 00152 break; 00153 } 00154 goto error; 00155 } 00156 00157 // start it 00158 retval = StartService (PorttalkService, 00159 0, // number of arguments 00160 NULL); // pointer to arguments 00161 if(!retval) { 00162 // couldn't start it 00163 if((retval=GetLastError())!=ERROR_SERVICE_ALREADY_RUNNING) { 00164 LOG_MSG("Could not start Porttalk service. Error %d.",retval); 00165 goto error; 00166 } 00167 } 00168 CloseServiceHandle(PorttalkService); 00169 CloseServiceHandle(ServiceManager); 00170 00171 // try again 00172 porttalkhandle = CreateFile("\\\\.\\PortTalk", GENERIC_READ, 00173 0, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_DEVICE, NULL); 00174 00175 if (porttalkhandle == INVALID_HANDLE_VALUE) { 00176 // bullshit 00177 LOG_MSG( 00178 "Porttalk driver could not be opened after being started successully."); 00179 return false; 00180 } 00181 00182 } 00183 for(size_t i = 0; i < sizeof(ioperm); i++) ioperm[i]=0xff; 00184 int retval; 00185 00186 DeviceIoControl( porttalkhandle, 00187 IOCTL_IOPM_RESTRICT_ALL_ACCESS, 00188 NULL,0, 00189 NULL,0, 00190 (LPDWORD)&retval, 00191 NULL); 00192 } 00193 return true; 00194 error: 00195 if(PorttalkService) CloseServiceHandle(PorttalkService); 00196 if(ServiceManager) CloseServiceHandle(ServiceManager); 00197 return false; 00198 } 00199 void addIOPermission(Bit16u port) { 00200 if(isNT) 00201 ioperm[(port>>3)]&=(~(1<<(port&0x7))); 00202 } 00203 00204 bool setPermissionList() { 00205 if(!isNT) return true; 00206 if(porttalkhandle!=INVALID_HANDLE_VALUE) { 00207 permblock b; 00208 int pid = _getpid(); 00209 int reetval=0; 00210 Bit32u retval=0; 00211 //output permission list to driver 00212 for(size_t i = 0; i < sizeof(ioperm);i++) { 00213 b.offset=i; 00214 b.value=ioperm[i]; 00215 00216 retval=DeviceIoControl( porttalkhandle, 00217 IOCTL_SET_IOPM, 00218 (LPDWORD)&b,3, 00219 NULL,0, 00220 (LPDWORD)&reetval, 00221 NULL); 00222 if(retval==0) return false; 00223 } 00224 00225 00226 reetval=DeviceIoControl( porttalkhandle, 00227 IOCTL_ENABLE_IOPM_ON_PROCESSID, 00228 (LPDWORD)&pid,4, 00229 NULL,0, 00230 (LPDWORD)&retval, 00231 NULL); 00232 SDL_Delay(100); 00233 return reetval!=0; 00234 } 00235 else return false; 00236 } 00237 #endif 00238 00239 #ifdef LINUX 00240 # if defined(__i386__) || defined(__amd64__) || defined(__x86_64__) 00241 // This Linux ioperm only works up to port 0x3FF 00242 #include <sys/perm.h> 00243 00244 bool initPorttalk() { 00245 if(ioperm(0x3da,1,1) < 0) return false; 00246 return true; 00247 } 00248 00249 void addIOPermission(Bit16u port) { 00250 ioperm(port,1,1); 00251 } 00252 00253 bool setPermissionList() { 00254 return true; 00255 } 00256 00257 # endif 00258 #endif 00259