Changeset 7564 for trunk/src/kernel32/hmcomm.cpp
- Timestamp:
- Dec 7, 2001, 12:28:11 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kernel32/hmcomm.cpp
r7550 r7564 1 /* $Id: hmcomm.cpp,v 1.2 7 2001-12-05 18:06:00sandervl Exp $ */1 /* $Id: hmcomm.cpp,v 1.28 2001-12-07 11:28:09 sandervl Exp $ */ 2 2 3 3 /* … … 9 9 * 2001 Sander van Leeuwen <sandervl@xs4all.nl> 10 10 * 11 * TODO: Overlapped IO only supports one request at a time12 * TODO: Overlapped IO not thread safe13 11 * 14 12 */ … … 21 19 #include "handlenames.h" 22 20 #include <heapstring.h> 23 #include "hmdevice.h"24 21 #include "hmcomm.h" 25 22 #include "oslibdos.h" … … 61 58 #define BaudTableSize (sizeof(BaudTable)/sizeof(BAUDTABLEENTRY)) 62 59 60 static BOOL CommReadIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut); 61 static BOOL CommWriteIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut); 62 static BOOL CommPollIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut); 63 63 64 //****************************************************************************** 64 65 //****************************************************************************** 65 66 static VOID *CreateDevData() 66 67 { 67 PHMDEVCOMDATA pData; 68 pData = new HMDEVCOMDATA(); 69 if(NULL!=pData) 70 { 71 memset(pData,0,sizeof(HMDEVCOMDATA)); 72 pData->ulMagic = MAGIC_COM; 73 pData->CommCfg.dwSize = sizeof(COMMCONFIG); 74 pData->CommCfg.wVersion = 1; 75 pData->CommCfg.dwProviderSubType = PST_RS232; 76 pData->CommCfg.dcb.DCBlength = sizeof(DCB); 77 pData->CommCfg.dcb.BaudRate = CBR_1200; 78 pData->CommCfg.dcb.ByteSize = 8; 79 pData->CommCfg.dcb.Parity = NOPARITY; 80 pData->CommCfg.dcb.StopBits = ONESTOPBIT; 81 pData->dwInBuffer = 16; 82 pData->dwOutBuffer = 16; 83 } 84 return pData; 68 PHMDEVCOMDATA pData; 69 70 pData = new HMDEVCOMDATA(); 71 if(NULL!=pData) 72 { 73 memset(pData,0,sizeof(HMDEVCOMDATA)); 74 pData->ulMagic = MAGIC_COM; 75 pData->CommCfg.dwSize = sizeof(COMMCONFIG); 76 pData->CommCfg.wVersion = 1; 77 pData->CommCfg.dwProviderSubType = PST_RS232; 78 pData->CommCfg.dcb.DCBlength = sizeof(DCB); 79 pData->CommCfg.dcb.BaudRate = CBR_1200; 80 pData->CommCfg.dcb.ByteSize = 8; 81 pData->CommCfg.dcb.Parity = NOPARITY; 82 pData->CommCfg.dcb.StopBits = ONESTOPBIT; 83 pData->dwInBuffer = 16; 84 pData->dwOutBuffer = 16; 85 } 86 return pData; 85 87 } 86 88 //****************************************************************************** … … 88 90 HMDeviceCommClass::HMDeviceCommClass(LPCSTR lpDeviceName) : HMDeviceHandler(lpDeviceName) 89 91 { 90 VOID *pData;91 dprintf(("HMDeviceCommClass: Register COM1 to COM8 with Handle Manager\n")); 92 pData = CreateDevData();93 if(pData!= NULL)94 HMDeviceRegisterEx("COM1", this, pData);95 96 // add symbolic links to the "real name" of the device 97 {92 VOID *pData; 93 94 dprintf(("HMDeviceCommClass: Register COM1 to COM8 with Handle Manager\n")); 95 pData = CreateDevData(); 96 if(pData!= NULL) 97 HMDeviceRegisterEx("COM1", this, pData); 98 99 // add symbolic links to the "real name" of the device 98 100 // @@@PH what's the long device name: SerialPortx ? 99 101 // HandleNamesAddSymbolicLink("\\Device\\ParallelPort3", "COM3"); 100 102 // Note: \\.\COMx: is invalid (NT4SP6) 101 103 102 104 PSZ pszCOM = strdup("\\\\.\\COMx"); 103 for (char ch = '1'; ch < ='9'; ch++)105 for (char ch = '1'; ch < '9'; ch++) 104 106 { 105 pszCOM[7] = ch;106 HandleNamesAddSymbolicLink(pszCOM, pszCOM+4);107 pszCOM[7] = ch; 108 HandleNamesAddSymbolicLink(pszCOM, pszCOM+4); 107 109 } 108 110 free(pszCOM); 109 111 110 112 // add "AUX" device 111 113 HandleNamesAddSymbolicLink("AUX", "COM1"); 112 114 HandleNamesAddSymbolicLink("AUX:", "COM1"); 113 115 HandleNamesAddSymbolicLink("\\\\.\\AUX", "COM1"); 114 }115 116 } 116 117 … … 131 132 { 132 133 dprintf2(("HMDeviceCommClass::FindDevice %s %s", lpClassDevName, lpDeviceName)); 133 134 134 135 //first 3 letters 'COM'? 135 136 if(lstrncmpiA(lpDeviceName, lpClassDevName, 3) != 0) { … … 163 164 DWORD ret = ERROR_SUCCESS; 164 165 165 dprintf(("HMComm: Serial communication port %s open request\n", lpFileName)); 166 167 if(strlen(lpFileName) > 5) { 168 lpFileName += 4; //skip prefix 169 } 170 171 pHMHandleData->hHMHandle = 0; 172 173 strcpy(comname, lpFileName); 174 comname[4] = 0; //get rid of : (if present) (eg COM1:) 175 176 //AH: TODO parse Win32 security handles 177 ULONG oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS); 178 pHMHandleData->hHMHandle = OSLibDosOpen(comname, 179 OSLIB_ACCESS_READWRITE | 180 OSLIB_ACCESS_SHAREDENYREAD | 181 OSLIB_ACCESS_SHAREDENYWRITE); 182 ::SetErrorMode(oldmode); 183 if (pHMHandleData->hHMHandle != 0) 184 { 185 ULONG ulLen; 186 APIRET rc; 187 pHMHandleData->lpHandlerData = new HMDEVCOMDATA(); 188 // Init The handle instance with the default default device config 189 memcpy( pHMHandleData->lpHandlerData, 190 pHMHandleData->lpDeviceData, 191 sizeof(HMDEVCOMDATA)); 192 193 ulLen = sizeof(DCBINFO); 194 195 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle, 196 IOCTL_ASYNC, 197 ASYNC_GETDCBINFO, 198 0,0,0, 199 &((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2,ulLen,&ulLen); 200 dprintf(("DCB Of %s :\n" 201 " WriteTimeout : %d\n" 202 " ReadTimeout : %d\n" 203 " CtlHandshake : 0x%x\n" 204 " FlowReplace : 0x%x\n" 205 " Timeout : 0x%x\n" 206 " Error replacement Char : 0x%x\n" 207 " Break replacement Char : 0x%x\n" 208 " XON Char : 0x%x\n" 209 " XOFF Char : 0x%x\n", 210 comname, 211 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usWriteTimeout, 212 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usReadTimeout, 213 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbCtlHndShake, 214 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbFlowReplace, 215 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbTimeOut, 216 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bErrorReplacementChar, 217 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bBreakReplacementChar, 218 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXONChar, 219 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXOFFChar)); 220 221 if(rc) 166 dprintf(("HMComm: Serial communication port %s open request\n", lpFileName)); 167 168 if(strlen(lpFileName) > 5) { 169 lpFileName += 4; //skip prefix 170 } 171 172 pHMHandleData->hHMHandle = 0; 173 174 strcpy(comname, lpFileName); 175 comname[4] = 0; //get rid of : (if present) (eg COM1:) 176 177 //AH: TODO parse Win32 security handles 178 ULONG oldmode = ::SetErrorMode(SEM_FAILCRITICALERRORS); 179 pHMHandleData->hHMHandle = OSLibDosOpen(comname, 180 OSLIB_ACCESS_READWRITE | 181 OSLIB_ACCESS_SHAREDENYREAD | 182 OSLIB_ACCESS_SHAREDENYWRITE); 183 ::SetErrorMode(oldmode); 184 if (pHMHandleData->hHMHandle != 0) 222 185 { 223 OSLibDosClose(pHMHandleData->hHMHandle); 224 delete pHMHandleData->lpHandlerData; 225 return rc; 226 } 227 rc = SetBaud(pHMHandleData,9600); 228 dprintf(("Init Baud to 9600 rc = %d",rc)); 229 rc = SetLine(pHMHandleData,8,0,0); 230 dprintf(("Set Line to 8/N/1 rc = %d",rc)); 231 232 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) 233 { 234 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData; 235 DWORD dwThreadId; 236 237 } 238 return ERROR_SUCCESS; 239 } 240 else 241 return ERROR_ACCESS_DENIED; 242 186 ULONG ulLen; 187 APIRET rc; 188 pHMHandleData->lpHandlerData = new HMDEVCOMDATA(); 189 // Init The handle instance with the default default device config 190 memcpy( pHMHandleData->lpHandlerData, 191 pHMHandleData->lpDeviceData, 192 sizeof(HMDEVCOMDATA)); 193 194 ulLen = sizeof(DCBINFO); 195 196 rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle, 197 IOCTL_ASYNC, 198 ASYNC_GETDCBINFO, 199 0,0,0, 200 &((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2,ulLen,&ulLen); 201 dprintf(("DCB Of %s :\n" 202 " WriteTimeout : %d\n" 203 " ReadTimeout : %d\n" 204 " CtlHandshake : 0x%x\n" 205 " FlowReplace : 0x%x\n" 206 " Timeout : 0x%x\n" 207 " Error replacement Char : 0x%x\n" 208 " Break replacement Char : 0x%x\n" 209 " XON Char : 0x%x\n" 210 " XOFF Char : 0x%x\n", 211 comname, 212 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usWriteTimeout, 213 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.usReadTimeout, 214 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbCtlHndShake, 215 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbFlowReplace, 216 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.fbTimeOut, 217 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bErrorReplacementChar, 218 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bBreakReplacementChar, 219 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXONChar, 220 ((PHMDEVCOMDATA)pHMHandleData->lpHandlerData)->dcbOS2.bXOFFChar)); 221 222 if(rc) 223 { 224 OSLibDosClose(pHMHandleData->hHMHandle); 225 delete pHMHandleData->lpHandlerData; 226 return rc; 227 } 228 rc = SetBaud(pHMHandleData,9600); 229 dprintf(("Init Baud to 9600 rc = %d",rc)); 230 rc = SetLine(pHMHandleData,8,0,0); 231 dprintf(("Set Line to 8/N/1 rc = %d",rc)); 232 233 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) 234 { 235 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData; 236 int comnr; 237 238 comnr = comname[3] - '1'; 239 240 if(handler[comnr] == NULL) { 241 try { 242 handler[comnr] = new OverlappedIOHandler(CommReadIOHandler, CommWriteIOHandler, CommPollIOHandler); 243 } 244 catch(...) 245 { 246 ret = ERROR_NOT_ENOUGH_MEMORY; 247 goto fail; 248 } 249 } 250 pDevData->iohandler = handler[comnr]; 251 } 252 return ERROR_SUCCESS; 253 } 254 else 255 return ERROR_ACCESS_DENIED; 243 256 244 257 fail: 245 258 246 delete pHMHandleData->lpHandlerData;247 OSLibDosClose(pHMHandleData->hHMHandle);248 return ret;259 delete pHMHandleData->lpHandlerData; 260 OSLibDosClose(pHMHandleData->hHMHandle); 261 return ret; 249 262 } 250 263 /***************************************************************************** … … 262 275 DWORD HMDeviceCommClass::GetFileType(PHMHANDLEDATA pHMHandleData) 263 276 { 264 dprintf(("KERNEL32: HMDeviceCommClass::GetFileType %s(%08x)\n", 265 lpHMDeviceName, 266 pHMHandleData)); 267 268 return FILE_TYPE_CHAR; 277 dprintf(("KERNEL32: HMDeviceCommClass::GetFileType %s(%08x)\n", 278 lpHMDeviceName, pHMHandleData)); 279 280 return FILE_TYPE_CHAR; 269 281 } 270 282 //****************************************************************************** … … 272 284 BOOL HMDeviceCommClass::CloseHandle(PHMHANDLEDATA pHMHandleData) 273 285 { 274 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData; 275 dprintf(("HMComm: Serial communication port close request")); 276 277 if(pDevData && pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) 278 { 279 DebugInt3(); 280 } 281 delete pHMHandleData->lpHandlerData; 282 return OSLibDosClose(pHMHandleData->hHMHandle); 286 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData; 287 dprintf(("HMComm: Serial communication port close request")); 288 289 if(pDevData && pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) 290 { 291 DebugInt3(); 292 } 293 delete pHMHandleData->lpHandlerData; 294 return OSLibDosClose(pHMHandleData->hHMHandle); 295 } 296 //****************************************************************************** 297 //Overlapped read handler 298 //****************************************************************************** 299 BOOL CommReadIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut) 300 { 301 return FALSE; 302 } 303 //****************************************************************************** 304 //Overlapped write handler 305 //****************************************************************************** 306 BOOL CommWriteIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut) 307 { 308 return FALSE; 309 } 310 //****************************************************************************** 311 //Overlapped WaitCommEvent handler 312 //****************************************************************************** 313 BOOL CommPollIOHandler(LPASYNCIOREQUEST lpRequest, DWORD *lpdwResult, DWORD *lpdwTimeOut) 314 { 315 *lpdwTimeOut = TIMEOUT_COMM; 316 return FALSE; 283 317 } 284 318 /***************************************************************************** … … 304 338 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) 305 339 { 306 dprintf(("KERNEL32:HMDeviceCommClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)", 307 lpHMDeviceName, 308 pHMHandleData->hHMHandle, 309 lpBuffer, 310 nNumberOfBytesToWrite, 311 lpNumberOfBytesWritten, 312 lpOverlapped)); 313 314 BOOL ret; 315 ULONG ulBytesWritten; 316 317 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) { 318 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!")); 319 ::SetLastError(ERROR_INVALID_PARAMETER); 320 return FALSE; 321 } 322 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) { 323 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation")); 324 } 325 if(lpCompletionRoutine) { 326 dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO")); 327 } 328 329 //testestestest 330 dprintf2(("Bytes to write:")); 331 for(int i=0;i<nNumberOfBytesToWrite;i++) { 332 dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i])); 333 } 334 //testestestset 335 336 ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite, 337 &ulBytesWritten); 338 339 if(lpNumberOfBytesWritten) { 340 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData; 341 BOOL ret; 342 ULONG ulBytesWritten; 343 344 dprintf(("KERNEL32:HMDeviceCommClass::WriteFile %s(%08x,%08x,%08x,%08x,%08x)", 345 lpHMDeviceName, pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToWrite, 346 lpNumberOfBytesWritten, lpOverlapped)); 347 348 349 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) ) 350 { 351 ::SetLastError(ERROR_INVALID_HANDLE); 352 return FALSE; 353 } 354 355 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) { 356 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!")); 357 ::SetLastError(ERROR_INVALID_PARAMETER); 358 return FALSE; 359 } 360 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) { 361 dprintf(("Warning: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation")); 362 } 363 if(lpCompletionRoutine) { 364 dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO")); 365 } 366 367 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) { 368 return pDevData->iohandler->WriteFile(pHMHandleData->hWin32Handle, lpBuffer, nNumberOfBytesToWrite, 369 lpNumberOfBytesWritten, lpOverlapped, lpCompletionRoutine, (DWORD)pDevData); 370 } 371 372 //testestestest 373 dprintf2(("Bytes to write:")); 374 for(int i=0;i<nNumberOfBytesToWrite;i++) { 375 dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i])); 376 } 377 //testestestset 378 379 ret = OSLibDosWrite(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToWrite, 380 &ulBytesWritten); 381 382 if(lpNumberOfBytesWritten) { 340 383 *lpNumberOfBytesWritten = (ret) ? ulBytesWritten : 0; 341 384 dprintf2(("KERNEL32:HMDeviceCommClass::WriteFile %d byte(s) written", *lpNumberOfBytesWritten)); 342 }343 if(ret == FALSE) {385 } 386 if(ret == FALSE) { 344 387 dprintf(("!ERROR!: WriteFile failed with rc %d", GetLastError())); 345 }346 347 return ret;388 } 389 390 return ret; 348 391 } 349 392 /***************************************************************************** … … 370 413 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine) 371 414 { 372 dprintf(("KERNEL32:HMDeviceCommClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)", 373 lpHMDeviceName, 374 pHMHandleData->hHMHandle, 375 lpBuffer, 376 nNumberOfBytesToRead, 377 lpNumberOfBytesRead, 378 lpOverlapped)); 379 380 BOOL ret; 381 ULONG ulBytesRead; 382 383 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) { 384 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!")); 385 ::SetLastError(ERROR_INVALID_PARAMETER); 386 return FALSE; 387 } 388 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) { 389 dprintf(("!WARNING!: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation")); 390 } 391 392 if(lpCompletionRoutine) { 393 dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO")); 394 } 395 396 RXQUEUE qInfo; 397 ULONG ulLen = sizeof(qInfo); 398 ULONG rc = OSLibDosDevIOCtl( pHMHandleData->hHMHandle, 399 IOCTL_ASYNC, 400 ASYNC_GETINQUECOUNT, 401 0,0,0, 402 &qInfo,ulLen,&ulLen); 403 dprintf(("ASYNC_GETINQUECOUNT -> qInfo.cch %d (queue size %d) rc %d", qInfo.cch, qInfo.cb, rc)); 404 405 ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead, 406 &ulBytesRead); 407 408 if(lpNumberOfBytesRead) { 409 *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0; 410 dprintf2(("KERNEL32:HMDeviceCommClass::ReadFile %d bytes read", *lpNumberOfBytesRead)); 411 } 412 if(ret == FALSE) { 413 dprintf(("!ERROR!: ReadFile failed with rc %d", GetLastError())); 414 } 415 else { 416 //testestestest 417 dprintf2(("%d Bytes read:", ulBytesRead)); 418 for(int i=0;i<ulBytesRead;i++) { 419 dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i])); 420 } 421 //testestestset 422 } 423 return ret; 424 } 425 415 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData; 416 BOOL ret; 417 ULONG ulBytesRead; 418 419 dprintf(("KERNEL32:HMDeviceCommClass::ReadFile %s(%08x,%08x,%08x,%08x,%08x)", 420 lpHMDeviceName, pHMHandleData->hHMHandle, lpBuffer, nNumberOfBytesToRead, 421 lpNumberOfBytesRead, lpOverlapped)); 422 423 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) ) 424 { 425 ::SetLastError(ERROR_INVALID_HANDLE); 426 return FALSE; 427 } 428 429 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpOverlapped) { 430 dprintf(("FILE_FLAG_OVERLAPPED flag set, but lpOverlapped NULL!!")); 431 ::SetLastError(ERROR_INVALID_PARAMETER); 432 return FALSE; 433 } 434 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && lpOverlapped) { 435 dprintf(("!WARNING!: lpOverlapped != NULL & !FILE_FLAG_OVERLAPPED; sync operation")); 436 } 437 438 if(lpCompletionRoutine) { 439 dprintf(("!WARNING!: lpCompletionRoutine not supported -> fall back to sync IO")); 440 } 441 442 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) { 443 return pDevData->iohandler->ReadFile(pHMHandleData->hWin32Handle, lpBuffer, nNumberOfBytesToRead, 444 lpNumberOfBytesRead, lpOverlapped, lpCompletionRoutine, (DWORD)pDevData); 445 } 446 447 RXQUEUE qInfo; 448 ULONG ulLen = sizeof(qInfo); 449 ULONG rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 450 IOCTL_ASYNC, 451 ASYNC_GETINQUECOUNT, 452 0,0,0, 453 &qInfo,ulLen,&ulLen); 454 dprintf(("ASYNC_GETINQUECOUNT -> qInfo.cch %d (queue size %d) rc %d", qInfo.cch, qInfo.cb, rc)); 455 456 ret = OSLibDosRead(pHMHandleData->hHMHandle, (LPVOID)lpBuffer, nNumberOfBytesToRead, 457 &ulBytesRead); 458 459 if(lpNumberOfBytesRead) { 460 *lpNumberOfBytesRead = (ret) ? ulBytesRead : 0; 461 dprintf2(("KERNEL32:HMDeviceCommClass::ReadFile %d bytes read", *lpNumberOfBytesRead)); 462 } 463 if(ret == FALSE) { 464 dprintf(("!ERROR!: ReadFile failed with rc %d", GetLastError())); 465 } 466 else { 467 //testestestest 468 dprintf2(("%d Bytes read:", ulBytesRead)); 469 for(int i=0;i<ulBytesRead;i++) { 470 dprintf2(("%x %c", ((char *)lpBuffer)[i], ((char *)lpBuffer)[i])); 471 } 472 //testestestset 473 } 474 return ret; 475 } 426 476 /***************************************************************************** 427 477 * Name : DWORD HMDeviceHandler::SetupComm … … 439 489 DWORD dwOutQueue) 440 490 { 441 dprintf(("HMDeviceCommClass::SetupComm "));442 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData; 443 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) )444 {445 ::SetLastError(ERROR_INVALID_HANDLE);446 return FALSE;447 }448 pDevData->dwInBuffer = dwInQueue;449 pDevData->dwOutBuffer = dwOutQueue;450 451 return(TRUE); 452 } 453 //****************************************************************************** 454 #define TIMEOUT_COMM 50 491 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData; 492 493 dprintf(("HMDeviceCommClass::SetupComm ")); 494 if((NULL==pDevData) || (pDevData->ulMagic != MAGIC_COM) ) 495 { 496 ::SetLastError(ERROR_INVALID_HANDLE); 497 return FALSE; 498 } 499 pDevData->dwInBuffer = dwInQueue; 500 pDevData->dwOutBuffer = dwOutQueue; 501 502 return(TRUE); 503 } 504 //****************************************************************************** 455 505 //****************************************************************************** 456 506 BOOL HMDeviceCommClass::WaitCommEvent( PHMHANDLEDATA pHMHandleData, … … 458 508 LPOVERLAPPED lpo) 459 509 { 460 APIRET rc; 461 ULONG ulLen; 462 USHORT COMEvt; 463 DWORD dwEvent,dwMask; 464 465 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData; 466 467 dprintf(("HMDeviceCommClass::WaitCommEvent %x %x %x", pHMHandleData->hHMHandle, lpfdwEvtMask, lpo)); 468 469 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo) { 470 dprintf(("!WARNING! pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo")); 471 ::SetLastError(ERROR_INVALID_PARAMETER); 472 return FALSE; 473 } 474 475 ulLen = sizeof(CHAR); 476 477 dwEvent = 0; 478 rc = 0; 479 ulLen = sizeof(COMEvt); 480 dwMask = pDevData->dwEventMask; 481 while( (0==rc) && 482 !(dwEvent & dwMask) && 483 (dwMask ==pDevData->dwEventMask) ) // Exit if the Mask gets changed 484 { 485 rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 486 IOCTL_ASYNC, 487 ASYNC_GETCOMMEVENT, 488 0,0,0, 489 &COMEvt,ulLen,&ulLen); 490 if(!rc) 510 APIRET rc; 511 ULONG ulLen; 512 USHORT COMEvt; 513 DWORD dwEvent,dwMask; 514 515 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData; 516 517 dprintf(("HMDeviceCommClass::WaitCommEvent %x %x %x", pHMHandleData->hHMHandle, lpfdwEvtMask, lpo)); 518 519 if((pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo) { 520 dprintf(("!WARNING! pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) && !lpo")); 521 ::SetLastError(ERROR_INVALID_PARAMETER); 522 return FALSE; 523 } 524 525 ulLen = sizeof(CHAR); 526 527 dwEvent = 0; 528 rc = 0; 529 ulLen = sizeof(COMEvt); 530 dwMask = pDevData->dwEventMask; 531 while( (0==rc) && 532 !(dwEvent & dwMask) && 533 (dwMask ==pDevData->dwEventMask) ) // Exit if the Mask gets changed 491 534 { 492 dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0; 493 //dwEvent |= (COMEvt&0x0002)? 0:0; 494 dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0; 495 dwEvent |= (COMEvt&0x0008)? EV_CTS:0; 496 dwEvent |= (COMEvt&0x0010)? EV_DSR:0; 497 //dwEvent |= (COMEvt&0x0020)? 0:0; DCS = RLSD? 498 dwEvent |= (COMEvt&0x0040)? EV_BREAK:0; 499 dwEvent |= (COMEvt&0x0080)? EV_ERR:0; 500 dwEvent |= (COMEvt&0x0100)? EV_RING:0; 501 if((dwEvent & dwMask)) break; 502 } 503 else break; 504 505 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) 506 { 507 memcpy(&pDevData->overlapped, lpo, sizeof(pDevData->overlapped)); 508 pDevData->overlapped.Internal = 0; 509 pDevData->overlapped.InternalHigh = 0; 510 pDevData->overlapped.Offset = 0; 511 pDevData->overlapped.OffsetHigh = 0; 512 //We're also supposed to write the result to the address supplied 513 //by this call 514 pDevData->lpfdwEvtMask = lpfdwEvtMask; 515 //Set app event semaphore to non-signalled state 516 ::ResetEvent(lpo->hEvent); 517 518 ::SetLastError(ERROR_IO_PENDING); 519 return FALSE; 520 } 521 DosSleep(TIMEOUT_COMM); 522 } 523 if(dwMask == pDevData->dwEventMask) { 524 *lpfdwEvtMask = (rc==0) ? (dwEvent & dwMask) : 0; 525 dprintf(("WaitCommEvent returned %x", *lpfdwEvtMask)); 526 } 527 else *lpfdwEvtMask = 0; 528 529 ::SetLastError(rc); 530 return (rc==0); 535 rc = OSLibDosDevIOCtl(pHMHandleData->hHMHandle, 536 IOCTL_ASYNC, 537 ASYNC_GETCOMMEVENT, 538 0,0,0, 539 &COMEvt,ulLen,&ulLen); 540 if(!rc) 541 { 542 dwEvent |= (COMEvt&0x0001)? EV_RXCHAR:0; 543 //dwEvent |= (COMEvt&0x0002)? 0:0; 544 dwEvent |= (COMEvt&0x0004)? EV_TXEMPTY:0; 545 dwEvent |= (COMEvt&0x0008)? EV_CTS:0; 546 dwEvent |= (COMEvt&0x0010)? EV_DSR:0; 547 //dwEvent |= (COMEvt&0x0020)? 0:0; DCS = RLSD? 548 dwEvent |= (COMEvt&0x0040)? EV_BREAK:0; 549 dwEvent |= (COMEvt&0x0080)? EV_ERR:0; 550 dwEvent |= (COMEvt&0x0100)? EV_RING:0; 551 if((dwEvent & dwMask)) break; 552 } 553 else break; 554 555 if(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED) 556 { 557 return pDevData->iohandler->WaitForEvent(pHMHandleData->hWin32Handle, lpfdwEvtMask, 558 lpo, NULL, (DWORD)pDevData); 559 } 560 DosSleep(TIMEOUT_COMM); 561 } 562 if(dwMask == pDevData->dwEventMask) { 563 *lpfdwEvtMask = (rc==0) ? (dwEvent & dwMask) : 0; 564 dprintf(("WaitCommEvent returned %x", *lpfdwEvtMask)); 565 } 566 else *lpfdwEvtMask = 0; 567 568 ::SetLastError(rc); 569 return (rc==0); 531 570 } 532 571 /***************************************************************************** … … 550 589 } 551 590 552 //signal serial thread to cancel pending IO operation 553 pDevData->fCancelIo = TRUE; 554 // ::SetEvent(pDevData->hEventSem); 555 556 ::SetLastError(ERROR_SUCCESS); 557 return(TRUE); 591 return pDevData->iohandler->CancelIo(pHMHandleData->hWin32Handle); 558 592 } 559 593 /***************************************************************************** … … 572 606 *****************************************************************************/ 573 607 BOOL HMDeviceCommClass::GetOverlappedResult(PHMHANDLEDATA pHMHandleData, 574 LPOVERLAPPED lp oOverlapped,608 LPOVERLAPPED lpOverlapped, 575 609 LPDWORD lpcbTransfer, 576 610 BOOL fWait) … … 578 612 PHMDEVCOMDATA pDevData = (PHMDEVCOMDATA)pHMHandleData->lpHandlerData; 579 613 580 dprintf(("KERNEL32-WARNING: HMDeviceCommClass::GetOverlappedResult(%08xh,%08xh,%08xh,%08xh) partly implemented", 581 pHMHandleData->hHMHandle, 582 lpoOverlapped, 583 lpcbTransfer, 584 fWait)); 585 586 if(pDevData == NULL || !(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) { 587 ::SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error? 588 return FALSE; 589 } 590 if(!lpoOverlapped) { 591 ::SetLastError(ERROR_INVALID_PARAMETER); 592 return FALSE; 593 } 594 if(lpoOverlapped->hEvent != pDevData->overlapped.hEvent) { 595 dprintf(("!WARNING!: GetOverlappedResult called for unknown operation")); 596 ::SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error? 597 return FALSE; 598 } 599 if(pDevData->overlapped.Internal) { 600 lpoOverlapped->Internal = pDevData->overlapped.Internal; 601 pDevData->overlapped.Internal = 0; //not entirely safe 602 pDevData->dwLastError = 0; 603 ::SetLastError(pDevData->dwLastError); 604 return lpoOverlapped->Internal; 605 } 606 if(fWait) { 607 ::WaitForSingleObject(pDevData->overlapped.hEvent, INFINITE); 608 ::ResetEvent(pDevData->overlapped.hEvent); 609 lpoOverlapped->Internal = pDevData->overlapped.Internal; 610 pDevData->overlapped.Internal = 0; //not entirely safe 611 ::SetLastError(ERROR_SUCCESS); 612 return lpoOverlapped->Internal; 613 } 614 else { 615 ::SetLastError(ERROR_IO_PENDING); 616 return FALSE; 617 } 618 } 619 //****************************************************************************** 620 //****************************************************************************** 621 BOOL HMDeviceCommClass::GetCommProperties( PHMHANDLEDATA pHMHandleData, 622 LPCOMMPROP lpcmmp) 614 dprintf(("KERNEL32-WARNING: HMDeviceCommClass::GetOverlappedResult(%08xh,%08xh,%08xh,%08xh) partly implemented", 615 pHMHandleData->hHMHandle, lpOverlapped, lpcbTransfer, fWait)); 616 617 if(!(pHMHandleData->dwFlags & FILE_FLAG_OVERLAPPED)) { 618 dprintf(("!WARNING!: GetOverlappedResult called for a handle that wasn't opened with FILE_FLAG_OVERLAPPED")); 619 return TRUE; //NT4, SP6 doesn't fail 620 } 621 622 if(pDevData == NULL) { 623 ::SetLastError(ERROR_ACCESS_DENIED); //todo: wrong error? 624 return FALSE; 625 } 626 if(!lpOverlapped) { 627 ::SetLastError(ERROR_INVALID_PARAMETER); 628 return FALSE; 629 } 630 return pDevData->iohandler->GetOverlappedResult(pHMHandleData->hWin32Handle, lpOverlapped, lpcbTransfer, fWait); 631 } 632 //****************************************************************************** 633 //****************************************************************************** 634 BOOL HMDeviceCommClass::GetCommProperties(PHMHANDLEDATA pHMHandleData, 635 LPCOMMPROP lpcmmp) 623 636 { 624 637 EXTBAUDGET BaudInfo; … … 719 732 } 720 733 if(rc) { 721 dprintf(("!WARNING! OSLibDosDevIOCtl failed with rc %d", rc)); 734 dprintf(("!WARNING! OSLibDosDevIOCtl failed with rc %d", rc)); 722 735 } 723 736 return (rc == ERROR_SUCCESS); … … 980 993 } 981 994 if( (0==pDevData->CommTOuts.WriteTotalTimeoutMultiplier) && 982 (0==pDevData->CommTOuts.WriteTotalTimeoutConstant)) 995 (0==pDevData->CommTOuts.WriteTotalTimeoutConstant)) 983 996 {//no timeout used for writing 984 997 os2dcb.fbTimeOut |= 1; //write infinite timeout … … 1423 1436 //****************************************************************************** 1424 1437 //****************************************************************************** 1425 1426 1438 void HMDeviceCommClass::CloseOverlappedIOHandlers() 1439 { 1440 for(int i=0;i<MAX_COMPORTS;i++) { 1441 if(handler[i]) { 1442 delete handler[i]; 1443 handler[i] = NULL; 1444 } 1445 } 1446 } 1447 //****************************************************************************** 1448 //****************************************************************************** 1449 OverlappedIOHandler *HMDeviceCommClass::handler[MAX_COMPORTS] = {NULL}; 1450
Note:
See TracChangeset
for help on using the changeset viewer.