- Timestamp:
- May 12, 2009 1:49:50 PM (16 years ago)
- Location:
- trunk/src/VBox
- Files:
-
- 14 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Builtins.cpp
r19351 r19624 256 256 if (RT_FAILURE(rc)) 257 257 return rc; 258 rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvRawFile); 259 if (RT_FAILURE(rc)) 260 return rc; 258 261 rc = pCallbacks->pfnRegister(pCallbacks, &g_DrvChar); 259 262 if (RT_FAILURE(rc)) -
trunk/src/VBox/Devices/Builtins.h
r19351 r19624 112 112 extern const PDMDRVREG g_DrvChar; 113 113 extern const PDMDRVREG g_DrvNamedPipe; 114 extern const PDMDRVREG g_DrvRawFile; 114 115 extern const PDMDRVREG g_DrvHostParallel; 115 116 extern const PDMDRVREG g_DrvHostSerial; -
trunk/src/VBox/Devices/Makefile.kmk
r19464 r19624 660 660 Serial/DrvChar.cpp \ 661 661 Serial/DrvNamedPipe.cpp \ 662 Serial/DrvRawFile.cpp \ 662 663 Storage/DrvBlock.cpp \ 663 664 Storage/DrvHostBase.cpp \ -
trunk/src/VBox/Devices/Serial/DrvChar.cpp
r11284 r19624 333 333 return PDMDrvHlpVMSetError(pDrvIns, VERR_PDM_MISSING_INTERFACE_BELOW, RT_SRC_POS, N_("Char#%d has no stream interface below"), pDrvIns->iInstance); 334 334 335 rc = RTThreadCreate(&pThis->ReceiveThread, drvCharReceiveLoop, (void *)pThis, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "CharRecv"); 336 if (RT_FAILURE(rc)) 337 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Char#%d cannot create receive thread"), pDrvIns->iInstance); 335 /* 336 * Don't start the receive thread if the driver doesn't support reading 337 */ 338 if (pThis->pDrvStream->pfnRead) 339 { 340 rc = RTThreadCreate(&pThis->ReceiveThread, drvCharReceiveLoop, (void *)pThis, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "CharRecv"); 341 if (RT_FAILURE(rc)) 342 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("Char#%d cannot create receive thread"), pDrvIns->iInstance); 343 } 338 344 339 345 rc = RTSemEventCreate(&pThis->SendSem); -
trunk/src/VBox/Devices/Serial/DrvRawFile.cpp
r19604 r19624 2 2 * 3 3 * VBox stream devices: 4 * Named pipe stream4 * Raw file output 5 5 */ 6 6 … … 36 36 #include "Builtins.h" 37 37 38 #ifdef RT_OS_WINDOWS39 #include <windows.h>40 #else /* !RT_OS_WINDOWS */41 #include <errno.h>42 #include <unistd.h>43 #include <sys/types.h>44 #include <sys/socket.h>45 #include <sys/un.h>46 #endif /* !RT_OS_WINDOWS */47 38 48 39 /******************************************************************************* … … 50 41 *******************************************************************************/ 51 42 52 /** Converts a pointer to DRV NAMEDPIPE::IMedia to a PDRVNAMEDPIPE. */53 #define PDMISTREAM_2_DRV NAMEDPIPE(pInterface) ( (PDRVNAMEDPIPE)((uintptr_t)pInterface - RT_OFFSETOF(DRVNAMEDPIPE, IStream)) )43 /** Converts a pointer to DRVOUTPUTFILE::IMedia to a PDRVOUTPUTFILE. */ 44 #define PDMISTREAM_2_DRVOUTPUTFILE(pInterface) ( (PDRVOUTPUTFILE)((uintptr_t)pInterface - RT_OFFSETOF(DRVOUTPUTFILE, IStream)) ) 54 45 55 46 /** Converts a pointer to PDMDRVINS::IBase to a PPDMDRVINS. */ … … 60 51 *******************************************************************************/ 61 52 /** 62 * Named pipedriver instance data.63 */ 64 typedef struct DRV NAMEDPIPE53 * Raw file output driver instance data. 54 */ 55 typedef struct DRVOUTPUTFILE 65 56 { 66 57 /** The stream interface. */ … … 68 59 /** Pointer to the driver instance. */ 69 60 PPDMDRVINS pDrvIns; 70 /** Pointer to the named pipefile name. (Freed by MM) */61 /** Pointer to the file name. (Freed by MM) */ 71 62 char *pszLocation; 72 63 /** Flag whether VirtualBox represents the server or client side. */ 73 bool fIsServer; 74 #ifdef RT_OS_WINDOWS 75 /* File handle of the named pipe. */ 76 HANDLE NamedPipe; 77 /* Overlapped structure for writes. */ 78 OVERLAPPED OverlappedWrite; 79 /* Overlapped structure for reads. */ 80 OVERLAPPED OverlappedRead; 81 /* Listen thread wakeup semaphore */ 82 RTSEMEVENT ListenSem; 83 #else /* !RT_OS_WINDOWS */ 84 /** Socket handle of the local socket for server. */ 85 RTSOCKET LocalSocketServer; 86 /** Socket handle of the local socket. */ 87 RTSOCKET LocalSocket; 88 #endif /* !RT_OS_WINDOWS */ 89 /** Thread for listening for new connections. */ 90 RTTHREAD ListenThread; 64 RTFILE OutputFile; 91 65 /** Flag to signal listening thread to shut down. */ 92 66 bool fShutdown; 93 } DRV NAMEDPIPE, *PDRVNAMEDPIPE;67 } DRVOUTPUTFILE, *PDRVOUTPUTFILE; 94 68 95 69 … … 99 73 100 74 101 /** @copydoc PDMISTREAM::pfn Read*/102 static DECLCALLBACK(int) drv NamedPipeRead(PPDMISTREAM pInterface, void *pvBuf, size_t *pcbRead)75 /** @copydoc PDMISTREAM::pfnWrite */ 76 static DECLCALLBACK(int) drvOutputFileWrite(PPDMISTREAM pInterface, const void *pvBuf, size_t *pcbWrite) 103 77 { 104 78 int rc = VINF_SUCCESS; 105 PDRV NAMEDPIPE pThis = PDMISTREAM_2_DRVNAMEDPIPE(pInterface);106 LogFlow(("%s: pvBuf=%p *pcb Read=%#x (%s)\n", __FUNCTION__, pvBuf, *pcbRead, pThis->pszLocation));79 PDRVOUTPUTFILE pThis = PDMISTREAM_2_DRVOUTPUTFILE(pInterface); 80 LogFlow(("%s: pvBuf=%p *pcbWrite=%#x (%s)\n", __FUNCTION__, pvBuf, *pcbWrite, pThis->pszLocation)); 107 81 108 82 Assert(pvBuf); 109 #ifdef RT_OS_WINDOWS 110 if (pThis->NamedPipe != INVALID_HANDLE_VALUE) 111 { 112 DWORD cbReallyRead; 113 pThis->OverlappedRead.Offset = 0; 114 pThis->OverlappedRead.OffsetHigh = 0; 115 if (!ReadFile(pThis->NamedPipe, pvBuf, (DWORD)*pcbRead, &cbReallyRead, &pThis->OverlappedRead)) 116 { 117 DWORD uError = GetLastError(); 118 119 if ( uError == ERROR_PIPE_LISTENING 120 || uError == ERROR_PIPE_NOT_CONNECTED) 121 { 122 /* No connection yet/anymore */ 123 cbReallyRead = 0; 124 125 /* wait a bit or else we'll be called right back. */ 126 RTThreadSleep(100); 127 } 128 else 129 { 130 if (uError == ERROR_IO_PENDING) 131 { 132 uError = 0; 133 134 /* Wait for incoming bytes. */ 135 if (GetOverlappedResult(pThis->NamedPipe, &pThis->OverlappedRead, &cbReallyRead, TRUE) == FALSE) 136 uError = GetLastError(); 137 } 138 139 rc = RTErrConvertFromWin32(uError); 140 Log(("drvNamedPipeRead: ReadFile returned %d (%Rrc)\n", uError, rc)); 141 } 142 } 143 144 if (RT_FAILURE(rc)) 145 { 146 Log(("drvNamedPipeRead: FileRead returned %Rrc fShutdown=%d\n", rc, pThis->fShutdown)); 147 if ( !pThis->fShutdown 148 && ( rc == VERR_EOF 149 || rc == VERR_BROKEN_PIPE 150 ) 151 ) 152 153 { 154 FlushFileBuffers(pThis->NamedPipe); 155 DisconnectNamedPipe(pThis->NamedPipe); 156 if (!pThis->fIsServer) 157 { 158 CloseHandle(pThis->NamedPipe); 159 pThis->NamedPipe = INVALID_HANDLE_VALUE; 160 } 161 /* pretend success */ 162 rc = VINF_SUCCESS; 163 } 164 cbReallyRead = 0; 165 } 166 *pcbRead = (size_t)cbReallyRead; 167 } 168 #else /* !RT_OS_WINDOWS */ 169 if (pThis->LocalSocket != NIL_RTSOCKET) 170 { 171 ssize_t cbReallyRead; 172 cbReallyRead = recv(pThis->LocalSocket, pvBuf, *pcbRead, 0); 173 if (cbReallyRead == 0) 174 { 175 RTSOCKET tmp = pThis->LocalSocket; 176 pThis->LocalSocket = NIL_RTSOCKET; 177 close(tmp); 178 } 179 else if (cbReallyRead == -1) 180 { 181 cbReallyRead = 0; 182 rc = RTErrConvertFromErrno(errno); 183 } 184 *pcbRead = cbReallyRead; 185 } 186 #endif /* !RT_OS_WINDOWS */ 187 else 188 { 189 RTThreadSleep(100); 190 *pcbRead = 0; 191 } 192 193 LogFlow(("%s: *pcbRead=%zu returns %Rrc\n", __FUNCTION__, *pcbRead, rc)); 194 return rc; 195 } 196 197 198 /** @copydoc PDMISTREAM::pfnWrite */ 199 static DECLCALLBACK(int) drvNamedPipeWrite(PPDMISTREAM pInterface, const void *pvBuf, size_t *pcbWrite) 200 { 201 int rc = VINF_SUCCESS; 202 PDRVNAMEDPIPE pThis = PDMISTREAM_2_DRVNAMEDPIPE(pInterface); 203 LogFlow(("%s: pvBuf=%p *pcbWrite=%#x (%s)\n", __FUNCTION__, pvBuf, *pcbWrite, pThis->pszLocation)); 204 205 Assert(pvBuf); 206 #ifdef RT_OS_WINDOWS 207 if (pThis->NamedPipe != INVALID_HANDLE_VALUE) 208 { 209 DWORD cbWritten = (DWORD)*pcbWrite; 210 pThis->OverlappedWrite.Offset = 0; 211 pThis->OverlappedWrite.OffsetHigh = 0; 212 if (!WriteFile(pThis->NamedPipe, pvBuf, cbWritten, NULL, &pThis->OverlappedWrite)) 213 { 214 DWORD uError = GetLastError(); 215 216 if ( uError == ERROR_PIPE_LISTENING 217 || uError == ERROR_PIPE_NOT_CONNECTED) 218 { 219 /* No connection yet/anymore; just discard the write (pretening everything was written). */; 220 } 221 else if (uError != ERROR_IO_PENDING) 222 { 223 rc = RTErrConvertFromWin32(uError); 224 Log(("drvNamedPipeWrite: WriteFile returned %d (%Rrc)\n", uError, rc)); 225 cbWritten = 0; 226 } 227 else 228 { 229 /* Wait for the write to complete. */ 230 if (GetOverlappedResult(pThis->NamedPipe, &pThis->OverlappedWrite, &cbWritten, TRUE /*bWait*/) == FALSE) 231 rc = RTErrConvertFromWin32(uError = GetLastError()); 232 } 233 } 234 235 if (RT_FAILURE(rc)) 236 { 237 if ( rc == VERR_EOF 238 || rc == VERR_BROKEN_PIPE) 239 { 240 FlushFileBuffers(pThis->NamedPipe); 241 DisconnectNamedPipe(pThis->NamedPipe); 242 if (!pThis->fIsServer) 243 { 244 CloseHandle(pThis->NamedPipe); 245 pThis->NamedPipe = INVALID_HANDLE_VALUE; 246 } 247 /* pretend success */ 248 rc = VINF_SUCCESS; 249 } 250 cbWritten = 0; 251 } 83 if (pThis->OutputFile != NIL_RTFILE) 84 { 85 size_t cbWritten; 86 rc = RTFileWrite(pThis->OutputFile, pvBuf, *pcbWrite, &cbWritten); 87 if (RT_SUCCESS(rc)) 88 RTFileFlush(pThis->OutputFile); 252 89 *pcbWrite = cbWritten; 253 90 } 254 #else /* !RT_OS_WINDOWS */255 if (pThis->LocalSocket != NIL_RTSOCKET)256 {257 ssize_t cbWritten;258 cbWritten = send(pThis->LocalSocket, pvBuf, *pcbWrite, 0);259 if (cbWritten == 0)260 {261 RTSOCKET tmp = pThis->LocalSocket;262 pThis->LocalSocket = NIL_RTSOCKET;263 close(tmp);264 }265 else if (cbWritten == -1)266 {267 cbWritten = 0;268 rc = RTErrConvertFromErrno(errno);269 }270 *pcbWrite = cbWritten;271 }272 #endif /* !RT_OS_WINDOWS */273 91 274 92 LogFlow(("%s: returns %Rrc\n", __FUNCTION__, rc)); … … 286 104 * @thread Any thread. 287 105 */ 288 static DECLCALLBACK(void *) drv NamedPipeQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)106 static DECLCALLBACK(void *) drvOutputFileQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface) 289 107 { 290 108 PPDMDRVINS pDrvIns = PDMIBASE_2_DRVINS(pInterface); 291 PDRV NAMEDPIPE pDrv = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);109 PDRVOUTPUTFILE pDrv = PDMINS_2_DATA(pDrvIns, PDRVOUTPUTFILE); 292 110 switch (enmInterface) 293 111 { … … 302 120 303 121 304 /* -=-=-=-=- listen thread -=-=-=-=- */ 305 306 /** 307 * Receive thread loop. 308 * 309 * @returns 0 on success. 310 * @param ThreadSelf Thread handle to this thread. 311 * @param pvUser User argument. 312 */ 313 static DECLCALLBACK(int) drvNamedPipeListenLoop(RTTHREAD ThreadSelf, void *pvUser) 314 { 315 PDRVNAMEDPIPE pThis = (PDRVNAMEDPIPE)pvUser; 316 int rc = VINF_SUCCESS; 317 #ifdef RT_OS_WINDOWS 318 HANDLE NamedPipe = pThis->NamedPipe; 319 HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, 0); 320 #endif 321 322 while (RT_LIKELY(!pThis->fShutdown)) 323 { 324 #ifdef RT_OS_WINDOWS 325 OVERLAPPED overlapped; 326 327 memset(&overlapped, 0, sizeof(overlapped)); 328 overlapped.hEvent = hEvent; 329 330 BOOL fConnected = ConnectNamedPipe(NamedPipe, &overlapped); 331 if ( !fConnected 332 && !pThis->fShutdown) 333 { 334 DWORD hrc = GetLastError(); 335 336 if (hrc == ERROR_IO_PENDING) 337 { 338 DWORD dummy; 339 340 hrc = 0; 341 if (GetOverlappedResult(pThis->NamedPipe, &overlapped, &dummy, TRUE) == FALSE) 342 hrc = GetLastError(); 343 344 } 345 346 if (pThis->fShutdown) 347 break; 348 349 if (hrc == ERROR_PIPE_CONNECTED) 350 { 351 RTSemEventWait(pThis->ListenSem, 250); 352 } 353 else if (hrc != ERROR_SUCCESS) 354 { 355 rc = RTErrConvertFromWin32(hrc); 356 LogRel(("NamedPipe%d: ConnectNamedPipe failed, rc=%Rrc\n", pThis->pDrvIns->iInstance, rc)); 357 break; 358 } 359 } 360 #else /* !RT_OS_WINDOWS */ 361 if (listen(pThis->LocalSocketServer, 0) == -1) 362 { 363 rc = RTErrConvertFromErrno(errno); 364 LogRel(("NamedPipe%d: listen failed, rc=%Rrc\n", pThis->pDrvIns->iInstance, rc)); 365 break; 366 } 367 int s = accept(pThis->LocalSocketServer, NULL, NULL); 368 if (s == -1) 369 { 370 rc = RTErrConvertFromErrno(errno); 371 LogRel(("NamedPipe%d: accept failed, rc=%Rrc\n", pThis->pDrvIns->iInstance, rc)); 372 break; 373 } 374 else 375 { 376 if (pThis->LocalSocket != NIL_RTSOCKET) 377 { 378 LogRel(("NamedPipe%d: only single connection supported\n", pThis->pDrvIns->iInstance)); 379 close(s); 380 } 381 else 382 pThis->LocalSocket = s; 383 } 384 #endif /* !RT_OS_WINDOWS */ 385 } 386 387 #ifdef RT_OS_WINDOWS 388 CloseHandle(hEvent); 389 #endif 390 pThis->ListenThread = NIL_RTTHREAD; 391 return VINF_SUCCESS; 392 } 393 394 395 /** 396 * Construct a named pipe stream driver instance. 122 /** 123 * Construct a raw output stream driver instance. 397 124 * 398 125 * @returns VBox status. … … 403 130 * iInstance it's expected to be used a bit in this function. 404 131 */ 405 static DECLCALLBACK(int) drv NamedPipeConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)132 static DECLCALLBACK(int) drvOutputFileConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle) 406 133 { 407 134 int rc; 408 135 char *pszLocation = NULL; 409 PDRV NAMEDPIPE pThis = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);136 PDRVOUTPUTFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVOUTPUTFILE); 410 137 411 138 /* … … 414 141 pThis->pDrvIns = pDrvIns; 415 142 pThis->pszLocation = NULL; 416 pThis->fIsServer = false; 417 #ifdef RT_OS_WINDOWS 418 pThis->NamedPipe = INVALID_HANDLE_VALUE; 419 #else /* !RT_OS_WINDOWS */ 420 pThis->LocalSocketServer = NIL_RTSOCKET; 421 pThis->LocalSocket = NIL_RTSOCKET; 422 #endif /* !RT_OS_WINDOWS */ 423 pThis->ListenThread = NIL_RTTHREAD; 143 pThis->OutputFile = NIL_RTFILE; 424 144 pThis->fShutdown = false; 425 145 /* IBase */ 426 pDrvIns->IBase.pfnQueryInterface = drv NamedPipeQueryInterface;146 pDrvIns->IBase.pfnQueryInterface = drvOutputFileQueryInterface; 427 147 /* IStream */ 428 pThis->IStream.pfnRead = drvNamedPipeRead; 429 pThis->IStream.pfnWrite = drvNamedPipeWrite; 148 pThis->IStream.pfnWrite = drvOutputFileWrite; 430 149 431 150 /* 432 151 * Read the configuration. 433 152 */ 434 if (!CFGMR3AreValuesValid(pCfgHandle, "Location\0 IsServer\0"))153 if (!CFGMR3AreValuesValid(pCfgHandle, "Location\0")) 435 154 { 436 155 rc = VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES; … … 446 165 pThis->pszLocation = pszLocation; 447 166 448 bool fIsServer; 449 rc = CFGMR3QueryBool(pCfgHandle, "IsServer", &fIsServer); 167 rc = RTFileOpen(&pThis->OutputFile, pThis->pszLocation, RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE); 450 168 if (RT_FAILURE(rc)) 451 169 { 452 AssertMsgFailed(("Configuration error: query \"IsServer\" resulted in %Rrc.\n", rc)); 453 goto out; 454 } 455 pThis->fIsServer = fIsServer; 456 457 #ifdef RT_OS_WINDOWS 458 if (fIsServer) 459 { 460 HANDLE hPipe = CreateNamedPipe(pThis->pszLocation, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 32, 32, 10000, NULL); 461 if (hPipe == INVALID_HANDLE_VALUE) 462 { 463 rc = RTErrConvertFromWin32(GetLastError()); 464 LogRel(("NamedPipe%d: CreateNamedPipe failed rc=%Rrc\n", pThis->pDrvIns->iInstance)); 465 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("NamedPipe#%d failed to create named pipe %s"), pDrvIns->iInstance, pszLocation); 466 } 467 pThis->NamedPipe = hPipe; 468 469 rc = RTSemEventCreate(&pThis->ListenSem); 470 AssertRC(rc); 471 472 rc = RTThreadCreate(&pThis->ListenThread, drvNamedPipeListenLoop, (void *)pThis, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SerPipe"); 473 if RT_FAILURE(rc) 474 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("NamedPipe#%d failed to create listening thread"), pDrvIns->iInstance); 475 476 } 477 else 478 { 479 /* Connect to the named pipe. */ 480 HANDLE hPipe = CreateFile(pThis->pszLocation, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 481 if (hPipe == INVALID_HANDLE_VALUE) 482 { 483 rc = RTErrConvertFromWin32(GetLastError()); 484 LogRel(("NamedPipe%d: CreateFile failed rc=%Rrc\n", pThis->pDrvIns->iInstance)); 485 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("NamedPipe#%d failed to connect to named pipe %s"), pDrvIns->iInstance, pszLocation); 486 } 487 pThis->NamedPipe = hPipe; 488 } 489 490 memset(&pThis->OverlappedWrite, 0, sizeof(pThis->OverlappedWrite)); 491 memset(&pThis->OverlappedRead, 0, sizeof(pThis->OverlappedRead)); 492 pThis->OverlappedWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 493 pThis->OverlappedRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 494 #else /* !RT_OS_WINDOWS */ 495 int s; 496 struct sockaddr_un addr; 497 498 if ((s = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) 499 return PDMDrvHlpVMSetError(pDrvIns, RTErrConvertFromErrno(errno), RT_SRC_POS, N_("NamedPipe#%d failed to create local socket"), pDrvIns->iInstance); 500 501 memset(&addr, 0, sizeof(addr)); 502 addr.sun_family = AF_UNIX; 503 strncpy(addr.sun_path, pszLocation, sizeof(addr.sun_path)-1); 504 505 if (fIsServer) 506 { 507 /* Bind address to the local socket. */ 508 RTFileDelete(pszLocation); 509 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) 510 return PDMDrvHlpVMSetError(pDrvIns, RTErrConvertFromErrno(errno), RT_SRC_POS, N_("NamedPipe#%d failed to bind to local socket %s"), pDrvIns->iInstance, pszLocation); 511 pThis->LocalSocketServer = s; 512 rc = RTThreadCreate(&pThis->ListenThread, drvNamedPipeListenLoop, (void *)pThis, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "SerPipe"); 513 if RT_FAILURE(rc) 514 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("NamedPipe#%d failed to create listening thread"), pDrvIns->iInstance); 515 } 516 else 517 { 518 /* Connect to the local socket. */ 519 if (connect(s, (struct sockaddr *)&addr, sizeof(addr)) == -1) 520 return PDMDrvHlpVMSetError(pDrvIns, RTErrConvertFromErrno(errno), RT_SRC_POS, N_("NamedPipe#%d failed to connect to local socket %s"), pDrvIns->iInstance, pszLocation); 521 pThis->LocalSocket = s; 522 } 523 #endif /* !RT_OS_WINDOWS */ 170 LogRel(("RawFile%d: CreateFile failed rc=%Rrc\n", pThis->pDrvIns->iInstance)); 171 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("RawFile#%d failed to create the raw output file %s"), pDrvIns->iInstance, pszLocation); 172 } 524 173 525 174 out: … … 528 177 if (pszLocation) 529 178 MMR3HeapFree(pszLocation); 530 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_(" NamedPipe#%d failed to initialize"), pDrvIns->iInstance);531 } 532 533 LogFlow(("drv NamedPipeConstruct: location %s isServer %d\n", pszLocation, fIsServer));534 LogRel((" NamedPipe: location %s, %s\n", pszLocation, fIsServer ? "server" : "client"));179 return PDMDrvHlpVMSetError(pDrvIns, rc, RT_SRC_POS, N_("RawFile#%d failed to initialize"), pDrvIns->iInstance); 180 } 181 182 LogFlow(("drvOutputFileConstruct: location %s\n", pszLocation)); 183 LogRel(("RawFile: location %s\n", pszLocation)); 535 184 return VINF_SUCCESS; 536 185 } … … 538 187 539 188 /** 540 * Destruct a named pipestream driver instance.189 * Destruct a raw output stream driver instance. 541 190 * 542 191 * Most VM resources are freed by the VM. This callback is provided so that … … 545 194 * @param pDrvIns The driver instance data. 546 195 */ 547 static DECLCALLBACK(void) drv NamedPipeDestruct(PPDMDRVINS pDrvIns)548 { 549 PDRV NAMEDPIPE pThis = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);196 static DECLCALLBACK(void) drvOutputFileDestruct(PPDMDRVINS pDrvIns) 197 { 198 PDRVOUTPUTFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVOUTPUTFILE); 550 199 LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation)); 551 552 if (pThis->ListenThread)553 {554 RTThreadWait(pThis->ListenThread, 250, NULL);555 if (pThis->ListenThread != NIL_RTTHREAD)556 LogRel(("NamedPipe%d: listen thread did not terminate\n", pDrvIns->iInstance));557 }558 200 559 201 if (pThis->pszLocation) … … 563 205 564 206 /** 565 * Power off a named pipestream driver instance.207 * Power off a raw output stream driver instance. 566 208 * 567 209 * This does most of the destruction work, to avoid ordering dependencies. … … 569 211 * @param pDrvIns The driver instance data. 570 212 */ 571 static DECLCALLBACK(void) drv NamedPipePowerOff(PPDMDRVINS pDrvIns)572 { 573 PDRV NAMEDPIPE pThis = PDMINS_2_DATA(pDrvIns, PDRVNAMEDPIPE);213 static DECLCALLBACK(void) drvOutputFilePowerOff(PPDMDRVINS pDrvIns) 214 { 215 PDRVOUTPUTFILE pThis = PDMINS_2_DATA(pDrvIns, PDRVOUTPUTFILE); 574 216 LogFlow(("%s: %s\n", __FUNCTION__, pThis->pszLocation)); 575 217 576 218 pThis->fShutdown = true; 577 219 578 #ifdef RT_OS_WINDOWS 579 if (pThis->NamedPipe != INVALID_HANDLE_VALUE) 580 { 581 if (pThis->fIsServer) 582 { 583 FlushFileBuffers(pThis->NamedPipe); 584 DisconnectNamedPipe(pThis->NamedPipe); 585 } 586 587 CloseHandle(pThis->NamedPipe); 588 pThis->NamedPipe = INVALID_HANDLE_VALUE; 589 CloseHandle(pThis->OverlappedRead.hEvent); 590 CloseHandle(pThis->OverlappedWrite.hEvent); 591 } 592 if (pThis->fIsServer) 593 { 594 /* Wake up listen thread */ 595 RTSemEventSignal(pThis->ListenSem); 596 RTSemEventDestroy(pThis->ListenSem); 597 } 598 #else /* !RT_OS_WINDOWS */ 599 if (pThis->fIsServer) 600 { 601 if (pThis->LocalSocketServer != NIL_RTSOCKET) 602 close(pThis->LocalSocketServer); 603 if (pThis->pszLocation) 604 RTFileDelete(pThis->pszLocation); 605 } 606 else 607 { 608 if (pThis->LocalSocket != NIL_RTSOCKET) 609 close(pThis->LocalSocket); 610 } 611 #endif /* !RT_OS_WINDOWS */ 612 } 613 614 615 /** 616 * Named pipe driver registration record. 617 */ 618 const PDMDRVREG g_DrvNamedPipe = 220 if (pThis->OutputFile != NIL_RTFILE) 221 RTFileClose(pThis->OutputFile); 222 } 223 224 225 /** 226 * Raw file driver registration record. 227 */ 228 const PDMDRVREG g_DrvRawFile = 619 229 { 620 230 /* u32Version */ 621 231 PDM_DRVREG_VERSION, 622 232 /* szDriverName */ 623 " NamedPipe",233 "RawFile", 624 234 /* pszDescription */ 625 " Named Pipe stream driver.",235 "RawFile stream driver.", 626 236 /* fFlags */ 627 237 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT, … … 631 241 ~0, 632 242 /* cbInstance */ 633 sizeof(DRV NAMEDPIPE),243 sizeof(DRVOUTPUTFILE), 634 244 /* pfnConstruct */ 635 drv NamedPipeConstruct,245 drvOutputFileConstruct, 636 246 /* pfnDestruct */ 637 drv NamedPipeDestruct,247 drvOutputFileDestruct, 638 248 /* pfnIOCtl */ 639 249 NULL, … … 649 259 NULL, 650 260 /* pfnPowerOff */ 651 drv NamedPipePowerOff,261 drvOutputFilePowerOff, 652 262 }; -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageHelp.cpp
r19377 r19624 181 181 " server <pipe>|\n" 182 182 " client <pipe>|\n" 183 " file <file>|\n" 183 184 " <devicename>]\n" 184 185 #ifdef VBOX_WITH_MEM_BALLOONING -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageInfo.cpp
r19622 r19624 849 849 RTPrintf(", disconnected\n"); 850 850 break; 851 case PortMode_RawFile: 852 if (details == VMINFO_MACHINEREADABLE) 853 RTPrintf("uartmode%d=\"%lS\"\n", currentUART + 1, 854 path.raw()); 855 else 856 RTPrintf(", attached to raw file '%lS'\n", 857 path.raw()); 858 break; 851 859 case PortMode_HostPipe: 852 860 if (details == VMINFO_MACHINEREADABLE) -
trunk/src/VBox/Frontends/VBoxManage/VBoxManageModifyVM.cpp
r19377 r19624 1732 1732 CHECK_ERROR_RET(uart, COMSETTER(Server) (FALSE), 1); 1733 1733 } 1734 else if (!strcmp(uarts_mode[n], "file")) 1735 { 1736 CHECK_ERROR_RET(uart, COMSETTER(HostMode) (PortMode_RawFile), 1); 1737 } 1734 1738 else 1735 1739 { -
trunk/src/VBox/Frontends/VirtualBox/src/VBoxGlobal.cpp
r19258 r19624 1951 1951 toCOMPortName (port.GetIRQ(), port.GetIOBase()) + ", "; 1952 1952 if (mode == KPortMode_HostPipe || 1953 mode == KPortMode_HostDevice) 1953 mode == KPortMode_HostDevice || 1954 mode == KPortMode_RawFile) 1954 1955 data += QString ("%1 (<nobr>%2</nobr>)") 1955 1956 .arg (vboxGlobal().toString (mode)) … … 2885 2886 mPortModeTypes [KPortMode_HostPipe] = tr ("Host Pipe", "PortMode"); 2886 2887 mPortModeTypes [KPortMode_HostDevice] = tr ("Host Device", "PortMode"); 2888 mPortModeTypes [KPortMode_RawFile] = tr ("Raw File", "PortMode"); 2887 2889 2888 2890 mUSBFilterActionTypes [KUSBDeviceFilterAction_Ignore] = -
trunk/src/VBox/Frontends/VirtualBox/src/VBoxVMSettingsSerial.cpp
r13580 r19624 52 52 mCbMode->addItem (""); /* KPortMode_HostPipe */ 53 53 mCbMode->addItem (""); /* KPortMode_HostDevice */ 54 mCbMode->addItem (""); /* KPortMode_RawFile */ 54 55 55 56 /* Setup connections */ … … 147 148 mCbNumber->setItemText (mCbNumber->count() - 1, vboxGlobal().toCOMPortName (0, 0)); 148 149 150 mCbMode->setItemText (3, vboxGlobal().toString (KPortMode_RawFile)); 149 151 mCbMode->setItemText (2, vboxGlobal().toString (KPortMode_HostDevice)); 150 152 mCbMode->setItemText (1, vboxGlobal().toString (KPortMode_HostPipe)); -
trunk/src/VBox/Frontends/VirtualBox/ui/VBoxVMSettingsSerial.ui
r11951 r19624 184 184 <widget class="QLabel" name="mLbPath" > 185 185 <property name="text" > 186 <string>Port &Path:</string>186 <string>Port/File &Path:</string> 187 187 </property> 188 188 <property name="alignment" > -
trunk/src/VBox/Main/ConsoleImpl2.cpp
r19410 r19624 2105 2105 rc = CFGMR3InsertString(pLunL1, "DevicePath", Utf8Str(path)); RC_CHECK(); 2106 2106 } 2107 else if (HostMode == PortMode_RawFile) 2108 { 2109 rc = CFGMR3InsertString(pLunL0, "Driver", "Char"); RC_CHECK(); 2110 rc = CFGMR3InsertNode(pLunL0, "AttachedDriver", &pLunL1); RC_CHECK(); 2111 rc = CFGMR3InsertString(pLunL1, "Driver", "RawFile"); RC_CHECK(); 2112 rc = CFGMR3InsertNode(pLunL1, "Config", &pLunL2); RC_CHECK(); 2113 rc = CFGMR3InsertString(pLunL2, "Location", Utf8Str(path)); RC_CHECK(); 2114 } 2107 2115 } 2108 2116 } -
trunk/src/VBox/Main/SerialPortImpl.cpp
r16560 r19624 204 204 /* host mode (required) */ 205 205 const char *mode = aPortNode.stringValue ("hostMode"); 206 if (strcmp (mode, "HostPipe") == 0) 206 if (strcmp (mode, "RawFile") == 0) 207 mData->mHostMode = PortMode_RawFile; 208 else if (strcmp (mode, "HostPipe") == 0) 207 209 mData->mHostMode = PortMode_HostPipe; 208 210 else if (strcmp (mode, "HostDevice") == 0) … … 261 263 mode = "HostDevice"; 262 264 break; 265 case PortMode_RawFile: 266 mode = "RawFile"; 267 break; 263 268 default: 264 269 ComAssertMsgFailedRet (("Invalid serial port mode: %d", … … 432 437 switch (aHostMode) 433 438 { 439 case PortMode_RawFile: 440 if (mData->mPath.isEmpty()) 441 return setError (E_INVALIDARG, 442 tr ("Cannot set the raw file mode of the serial port %d " 443 "because the file path is empty or null"), 444 mData->mSlot); 445 break; 434 446 case PortMode_HostPipe: 435 447 if (mData->mPath.isEmpty()) … … 611 623 612 624 if ((mData->mHostMode == PortMode_HostDevice || 613 mData->mHostMode == PortMode_HostPipe) && 625 mData->mHostMode == PortMode_HostPipe || 626 mData->mHostMode == PortMode_RawFile) && 614 627 (aPath == NULL || *aPath == '\0')) 615 628 return setError (E_INVALIDARG, -
trunk/src/VBox/Main/idl/VirtualBox.xidl
r19249 r19624 11090 11090 <desc>Virtual device is attached to a host device.</desc> 11091 11091 </const> 11092 <const name="RawFile" value="3"> 11093 <desc>Virtual device is attached to a raw file.</desc> 11094 </const> 11092 11095 </enum> 11093 11096 -
trunk/src/VBox/Main/xml/VirtualBox-settings-common.xsd
r18591 r19624 247 247 <xsd:restriction base="xsd:string"> 248 248 <xsd:enumeration value="Disconnected"/> 249 <xsd:enumeration value="RawFile"/> 249 250 <xsd:enumeration value="HostPipe"/> 250 251 <xsd:enumeration value="HostDevice"/>
Note:
See TracChangeset
for help on using the changeset viewer.