Changeset 25203 in vbox for trunk/src/VBox/Main
- Timestamp:
- Dec 4, 2009 7:30:50 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 55684
- Location:
- trunk/src/VBox/Main
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/MachineImpl.cpp
r25198 r25203 500 500 501 501 /* Apply network adapters defaults */ 502 for (ULONG slot = 0; slot < RT_ELEMENTS 503 mNetworkAdapters [slot]->applyDefaults(aOsType);502 for (ULONG slot = 0; slot < RT_ELEMENTS(mNetworkAdapters); ++slot) 503 mNetworkAdapters[slot]->applyDefaults(aOsType); 504 504 505 505 /* Apply serial port defaults */ 506 for (ULONG slot = 0; slot < RT_ELEMENTS 507 mSerialPorts [slot]->applyDefaults(aOsType);506 for (ULONG slot = 0; slot < RT_ELEMENTS(mSerialPorts); ++slot) 507 mSerialPorts[slot]->applyDefaults(aOsType); 508 508 } 509 509 } -
trunk/src/VBox/Main/ParallelPortImpl.cpp
r25202 r25203 374 374 } 375 375 376 STDMETHODIMP ParallelPort::COMSETTER(Path) (IN_BSTR aPath) 377 { 378 AutoCaller autoCaller(this); 379 if (FAILED(autoCaller.rc())) return autoCaller.rc(); 380 381 /* the machine needs to be mutable */ 382 Machine::AutoMutableStateDependency adep(m->pMachine); 383 if (FAILED(adep.rc())) return adep.rc(); 384 385 AutoWriteLock alock(this); 386 387 Utf8Str str(aPath); 388 if (str != m->bd->strPath) 389 { 390 HRESULT rc = checkSetPath(str); 391 if (FAILED(rc)) return rc; 392 393 m->bd.backup(); 394 m->bd->strPath = str; 395 396 /* leave the lock before informing callbacks */ 397 alock.unlock(); 398 399 return m->pMachine->onParallelPortChange(this); 400 } 401 402 return S_OK; 403 } 404 405 // public methods only for internal purposes 406 //////////////////////////////////////////////////////////////////////////////// 407 408 /** 409 * Loads settings from the given port node. 410 * May be called once right after this object creation. 411 * 412 * @param aPortNode <Port> node. 413 * 414 * @note Locks this object for writing. 415 */ 416 HRESULT ParallelPort::loadSettings(const settings::ParallelPort &data) 417 { 418 AutoCaller autoCaller(this); 419 AssertComRCReturnRC(autoCaller.rc()); 420 421 AutoWriteLock alock(this); 422 423 // simply copy 424 *m->bd.data() = data; 425 426 return S_OK; 427 } 428 429 /** 430 * Saves settings to the given port node. 431 * 432 * Note that the given Port node is comletely empty on input. 433 * 434 * @param aPortNode <Port> node. 435 * 436 * @note Locks this object for reading. 437 */ 438 HRESULT ParallelPort::saveSettings(settings::ParallelPort &data) 439 { 440 AutoCaller autoCaller(this); 441 AssertComRCReturnRC(autoCaller.rc()); 442 443 AutoReadLock alock(this); 444 445 // simply copy 446 data = *m->bd.data(); 447 448 return S_OK; 449 } 450 451 bool ParallelPort::isModified() 452 { 453 AutoWriteLock alock (this); 454 return m->bd.isBackedUp(); 455 } 456 457 bool ParallelPort::isReallyModified() 458 { 459 AutoWriteLock alock(this); 460 return m->bd.hasActualChanges(); 461 } 462 463 /** 464 * @note Locks this object for writing. 465 */ 466 bool ParallelPort::rollback() 467 { 468 /* sanity */ 469 AutoCaller autoCaller(this); 470 AssertComRCReturn (autoCaller.rc(), false); 471 472 AutoWriteLock alock(this); 473 474 bool changed = false; 475 476 if (m->bd.isBackedUp()) 477 { 478 /* we need to check all data to see whether anything will be changed 479 * after rollback */ 480 changed = m->bd.hasActualChanges(); 481 m->bd.rollback(); 482 } 483 484 return changed; 485 } 486 487 /** 488 * @note Locks this object for writing, together with the peer object (also 489 * for writing) if there is one. 490 */ 491 void ParallelPort::commit() 492 { 493 /* sanity */ 494 AutoCaller autoCaller(this); 495 AssertComRCReturnVoid (autoCaller.rc()); 496 497 /* sanity too */ 498 AutoCaller peerCaller (m->pPeer); 499 AssertComRCReturnVoid (peerCaller.rc()); 500 501 /* lock both for writing since we modify both (m->pPeer is "master" so locked 502 * first) */ 503 AutoMultiWriteLock2 alock (m->pPeer, this); 504 505 if (m->bd.isBackedUp()) 506 { 507 m->bd.commit(); 508 if (m->pPeer) 509 { 510 /* attach new data to the peer and reshare it */ 511 m->pPeer->m->bd.attach(m->bd); 512 } 513 } 514 } 515 516 /** 517 * @note Locks this object for writing, together with the peer object 518 * represented by @a aThat (locked for reading). 519 */ 520 void ParallelPort::copyFrom(ParallelPort *aThat) 521 { 522 AssertReturnVoid (aThat != NULL); 523 524 /* sanity */ 525 AutoCaller autoCaller(this); 526 AssertComRCReturnVoid (autoCaller.rc()); 527 528 /* sanity too */ 529 AutoCaller thatCaller (aThat); 530 AssertComRCReturnVoid (thatCaller.rc()); 531 532 /* peer is not modified, lock it for reading (aThat is "master" so locked 533 * first) */ 534 AutoMultiLock2 alock (aThat->rlock(), this->wlock()); 535 536 /* this will back up current data */ 537 m->bd.assignCopy(aThat->m->bd); 538 } 539 376 540 /** 377 541 * Validates COMSETTER(Path) arguments. … … 392 556 } 393 557 394 STDMETHODIMP ParallelPort::COMSETTER(Path) (IN_BSTR aPath)395 {396 AutoCaller autoCaller(this);397 if (FAILED(autoCaller.rc())) return autoCaller.rc();398 399 /* the machine needs to be mutable */400 Machine::AutoMutableStateDependency adep(m->pMachine);401 if (FAILED(adep.rc())) return adep.rc();402 403 AutoWriteLock alock(this);404 405 Utf8Str str(aPath);406 if (str != m->bd->strPath)407 {408 HRESULT rc = checkSetPath(str);409 if (FAILED(rc)) return rc;410 411 m->bd.backup();412 m->bd->strPath = str;413 414 /* leave the lock before informing callbacks */415 alock.unlock();416 417 return m->pMachine->onParallelPortChange (this);418 }419 420 return S_OK;421 }422 423 // public methods only for internal purposes424 ////////////////////////////////////////////////////////////////////////////////425 426 /**427 * Loads settings from the given port node.428 * May be called once right after this object creation.429 *430 * @param aPortNode <Port> node.431 *432 * @note Locks this object for writing.433 */434 HRESULT ParallelPort::loadSettings(const settings::ParallelPort &data)435 {436 AutoCaller autoCaller(this);437 AssertComRCReturnRC(autoCaller.rc());438 439 AutoWriteLock alock(this);440 441 // simply copy442 *m->bd.data() = data;443 444 return S_OK;445 }446 447 /**448 * Saves settings to the given port node.449 *450 * Note that the given Port node is comletely empty on input.451 *452 * @param aPortNode <Port> node.453 *454 * @note Locks this object for reading.455 */456 HRESULT ParallelPort::saveSettings(settings::ParallelPort &data)457 {458 AutoCaller autoCaller(this);459 AssertComRCReturnRC(autoCaller.rc());460 461 AutoReadLock alock(this);462 463 // simply copy464 data = *m->bd.data();465 466 return S_OK;467 }468 469 bool ParallelPort::isModified()470 {471 AutoWriteLock alock (this);472 return m->bd.isBackedUp();473 }474 475 bool ParallelPort::isReallyModified()476 {477 AutoWriteLock alock(this);478 return m->bd.hasActualChanges();479 }480 481 /**482 * @note Locks this object for writing.483 */484 bool ParallelPort::rollback()485 {486 /* sanity */487 AutoCaller autoCaller(this);488 AssertComRCReturn (autoCaller.rc(), false);489 490 AutoWriteLock alock(this);491 492 bool changed = false;493 494 if (m->bd.isBackedUp())495 {496 /* we need to check all data to see whether anything will be changed497 * after rollback */498 changed = m->bd.hasActualChanges();499 m->bd.rollback();500 }501 502 return changed;503 }504 505 /**506 * @note Locks this object for writing, together with the peer object (also507 * for writing) if there is one.508 */509 void ParallelPort::commit()510 {511 /* sanity */512 AutoCaller autoCaller(this);513 AssertComRCReturnVoid (autoCaller.rc());514 515 /* sanity too */516 AutoCaller peerCaller (m->pPeer);517 AssertComRCReturnVoid (peerCaller.rc());518 519 /* lock both for writing since we modify both (m->pPeer is "master" so locked520 * first) */521 AutoMultiWriteLock2 alock (m->pPeer, this);522 523 if (m->bd.isBackedUp())524 {525 m->bd.commit();526 if (m->pPeer)527 {528 /* attach new data to the peer and reshare it */529 m->pPeer->m->bd.attach(m->bd);530 }531 }532 }533 534 /**535 * @note Locks this object for writing, together with the peer object536 * represented by @a aThat (locked for reading).537 */538 void ParallelPort::copyFrom (ParallelPort *aThat)539 {540 AssertReturnVoid (aThat != NULL);541 542 /* sanity */543 AutoCaller autoCaller(this);544 AssertComRCReturnVoid (autoCaller.rc());545 546 /* sanity too */547 AutoCaller thatCaller (aThat);548 AssertComRCReturnVoid (thatCaller.rc());549 550 /* peer is not modified, lock it for reading (aThat is "master" so locked551 * first) */552 AutoMultiLock2 alock (aThat->rlock(), this->wlock());553 554 /* this will back up current data */555 m->bd.assignCopy(aThat->m->bd);556 }557 558 558 559 559 /* vi: set tabstop=4 shiftwidth=4 expandtab: */ -
trunk/src/VBox/Main/SerialPortImpl.cpp
r25149 r25203 31 31 #include <VBox/settings.h> 32 32 33 //////////////////////////////////////////////////////////////////////////////// 34 // 35 // SerialPort private data definition 36 // 37 //////////////////////////////////////////////////////////////////////////////// 38 39 struct SerialPort::Data 40 { 41 Data() 42 { } 43 44 const ComObjPtr<Machine, ComWeakRef> pMachine; 45 const ComObjPtr<SerialPort> pPeer; 46 47 Backupable<settings::SerialPort> bd; 48 }; 49 33 50 // constructor / destructor 34 51 ///////////////////////////////////////////////////////////////////////////// … … 54 71 * @param aParent Handle of the parent object. 55 72 */ 56 HRESULT SerialPort::init 73 HRESULT SerialPort::init(Machine *aParent, ULONG aSlot) 57 74 { 58 75 LogFlowThisFunc(("aParent=%p, aSlot=%d\n", aParent, aSlot)); … … 64 81 AssertReturn(autoInitSpan.isOk(), E_FAIL); 65 82 66 unconst(mParent) = aParent; 67 /* mPeer is left null */ 68 69 mData.allocate(); 83 m = new Data(); 84 85 unconst(m->pMachine) = aParent; 86 /* m->pPeer is left null */ 87 88 m->bd.allocate(); 70 89 71 90 /* initialize data */ 72 m Data->mSlot = aSlot;91 m->bd->ulSlot = aSlot; 73 92 74 93 /* Confirm a successful initialization */ … … 88 107 * @note Locks @a aThat object for reading. 89 108 */ 90 HRESULT SerialPort::init 109 HRESULT SerialPort::init(Machine *aParent, SerialPort *aThat) 91 110 { 92 111 LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat)); … … 98 117 AssertReturn(autoInitSpan.isOk(), E_FAIL); 99 118 100 unconst(mParent) = aParent; 101 unconst(mPeer) = aThat; 119 m = new Data(); 120 121 unconst(m->pMachine) = aParent; 122 unconst(m->pPeer) = aThat; 102 123 103 124 AutoCaller thatCaller (aThat); … … 105 126 106 127 AutoReadLock thatLock (aThat); 107 m Data.share (aThat->mData);128 m->bd.share (aThat->m->bd); 108 129 109 130 /* Confirm a successful initialization */ … … 120 141 * @note Locks @a aThat object for reading. 121 142 */ 122 HRESULT SerialPort::initCopy 143 HRESULT SerialPort::initCopy(Machine *aParent, SerialPort *aThat) 123 144 { 124 145 LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat)); … … 130 151 AssertReturn(autoInitSpan.isOk(), E_FAIL); 131 152 132 unconst(mParent) = aParent; 133 /* mPeer is left null */ 153 m = new Data(); 154 155 unconst(m->pMachine) = aParent; 156 /* pPeer is left null */ 134 157 135 158 AutoCaller thatCaller (aThat); … … 137 160 138 161 AutoReadLock thatLock (aThat); 139 m Data.attachCopy (aThat->mData);162 m->bd.attachCopy (aThat->m->bd); 140 163 141 164 /* Confirm a successful initialization */ … … 158 181 return; 159 182 160 mData.free(); 161 162 unconst(mPeer).setNull(); 163 unconst(mParent).setNull(); 164 } 165 166 // public methods only for internal purposes 167 //////////////////////////////////////////////////////////////////////////////// 168 169 /** 170 * Loads settings from the given port node. 171 * May be called once right after this object creation. 172 * 173 * @param aPortNode <Port> node. 174 * 175 * @note Locks this object for writing. 176 */ 177 HRESULT SerialPort::loadSettings(const settings::SerialPort &data) 178 { 179 AutoCaller autoCaller(this); 180 AssertComRCReturnRC(autoCaller.rc()); 181 182 AutoWriteLock alock(this); 183 184 /* Note: we assume that the default values for attributes of optional 185 * nodes are assigned in the Data::Data() constructor and don't do it 186 * here. It implies that this method may only be called after constructing 187 * a new BIOSSettings object while all its data fields are in the default 188 * values. Exceptions are fields whose creation time defaults don't match 189 * values that should be applied when these fields are not explicitly set 190 * in the settings file (for backwards compatibility reasons). This takes 191 * place when a setting of a newly created object must default to A while 192 * the same setting of an object loaded from the old settings file must 193 * default to B. */ 194 195 /* enabled (required) */ 196 mData->mEnabled = data.fEnabled; 197 /* I/O base (required) */ 198 mData->mIOBase = data.ulIOBase; 199 /* IRQ (required) */ 200 mData->mIRQ = data.ulIRQ; 201 /* host mode (required) */ 202 mData->mHostMode = data.portMode; 203 204 /* pipe/device path (optional, defaults to null) */ 205 Bstr path(data.strPath); 206 HRESULT rc = checkSetPath(path); 207 if (FAILED(rc)) return rc; 208 mData->mPath = path; 209 210 /* server mode (optional, defaults to false) */ 211 mData->mServer = data.fServer; 212 213 return S_OK; 214 } 215 216 /** 217 * Saves the port settings to the given port node. 218 * 219 * Note that the given Port node is comletely empty on input. 220 * 221 * @param aPortNode <Port> node. 222 * 223 * @note Locks this object for reading. 224 */ 225 HRESULT SerialPort::saveSettings(settings::SerialPort &data) 226 { 227 AutoCaller autoCaller(this); 228 AssertComRCReturnRC(autoCaller.rc()); 229 230 AutoReadLock alock(this); 231 232 data.fEnabled = !!mData->mEnabled; 233 data.ulIOBase = mData->mIOBase; 234 data.ulIRQ = mData->mIRQ; 235 data.portMode = mData->mHostMode; 236 237 /* Always save non-null mPath and mServer to preserve the user values for 238 * later use. Note that 'server' is false by default in XML so we don't 239 * save it when it's false. */ 240 data.strPath = mData->mPath; 241 data.fServer = !!mData->mServer; 242 243 return S_OK; 244 } 245 246 /** 247 * @note Locks this object for writing. 248 */ 249 bool SerialPort::rollback() 250 { 251 /* sanity */ 252 AutoCaller autoCaller(this); 253 AssertComRCReturn (autoCaller.rc(), false); 254 255 AutoWriteLock alock(this); 256 257 bool changed = false; 258 259 if (mData.isBackedUp()) 260 { 261 /* we need to check all data to see whether anything will be changed 262 * after rollback */ 263 changed = mData.hasActualChanges(); 264 mData.rollback(); 265 } 266 267 return changed; 268 } 269 270 /** 271 * @note Locks this object for writing, together with the peer object (also 272 * for writing) if there is one. 273 */ 274 void SerialPort::commit() 275 { 276 /* sanity */ 277 AutoCaller autoCaller(this); 278 AssertComRCReturnVoid (autoCaller.rc()); 279 280 /* sanity too */ 281 AutoCaller peerCaller (mPeer); 282 AssertComRCReturnVoid (peerCaller.rc()); 283 284 /* lock both for writing since we modify both (mPeer is "master" so locked 285 * first) */ 286 AutoMultiWriteLock2 alock (mPeer, this); 287 288 if (mData.isBackedUp()) 289 { 290 mData.commit(); 291 if (mPeer) 292 { 293 /* attach new data to the peer and reshare it */ 294 mPeer->mData.attach (mData); 295 } 296 } 297 } 298 299 /** 300 * @note Locks this object for writing, together with the peer object 301 * represented by @a aThat (locked for reading). 302 */ 303 void SerialPort::copyFrom (SerialPort *aThat) 304 { 305 AssertReturnVoid (aThat != NULL); 306 307 /* sanity */ 308 AutoCaller autoCaller(this); 309 AssertComRCReturnVoid (autoCaller.rc()); 310 311 /* sanity too */ 312 AutoCaller thatCaller (aThat); 313 AssertComRCReturnVoid (thatCaller.rc()); 314 315 /* peer is not modified, lock it for reading (aThat is "master" so locked 316 * first) */ 317 AutoMultiLock2 alock (aThat->rlock(), this->wlock()); 318 319 /* this will back up current data */ 320 mData.assignCopy (aThat->mData); 321 } 322 323 void SerialPort::applyDefaults (GuestOSType *aOsType) 324 { 325 AssertReturnVoid (aOsType != NULL); 326 327 /* sanity */ 328 AutoCaller autoCaller(this); 329 AssertComRCReturnVoid (autoCaller.rc()); 330 331 AutoWriteLock alock(this); 332 333 uint32_t numSerialEnabled = aOsType->numSerialEnabled(); 334 335 /* Enable port if requested */ 336 if (mData->mSlot < numSerialEnabled) 337 { 338 mData->mEnabled = true; 339 } 183 m->bd.free(); 184 185 unconst(m->pPeer).setNull(); 186 unconst(m->pMachine).setNull(); 187 188 delete m; 189 m = NULL; 340 190 } 341 191 … … 352 202 AutoReadLock alock(this); 353 203 354 *aEnabled = m Data->mEnabled;204 *aEnabled = m->bd->fEnabled; 355 205 356 206 return S_OK; … … 365 215 366 216 /* the machine needs to be mutable */ 367 Machine::AutoMutableStateDependency adep(m Parent);217 Machine::AutoMutableStateDependency adep(m->pMachine); 368 218 if (FAILED(adep.rc())) return adep.rc(); 369 219 370 220 AutoWriteLock alock(this); 371 221 372 if (m Data->mEnabled != aEnabled)373 { 374 m Data.backup();375 m Data->mEnabled = aEnabled;222 if (m->bd->fEnabled != aEnabled) 223 { 224 m->bd.backup(); 225 m->bd->fEnabled = aEnabled; 376 226 377 227 /* leave the lock before informing callbacks */ 378 228 alock.unlock(); 379 229 380 m Parent->onSerialPortChange (this);230 m->pMachine->onSerialPortChange (this); 381 231 } 382 232 … … 393 243 AutoReadLock alock(this); 394 244 395 *aHostMode = m Data->mHostMode;245 *aHostMode = m->bd->portMode; 396 246 397 247 return S_OK; … … 404 254 405 255 /* the machine needs to be mutable */ 406 Machine::AutoMutableStateDependency adep(m Parent);256 Machine::AutoMutableStateDependency adep(m->pMachine); 407 257 if (FAILED(adep.rc())) return adep.rc(); 408 258 … … 412 262 bool emitChangeEvent = false; 413 263 414 if (m Data->mHostMode != aHostMode)264 if (m->bd->portMode != aHostMode) 415 265 { 416 266 switch (aHostMode) 417 267 { 418 268 case PortMode_RawFile: 419 if (m Data->mPath.isEmpty())269 if (m->bd->strPath.isEmpty()) 420 270 return setError (E_INVALIDARG, 421 271 tr ("Cannot set the raw file mode of the serial port %d " 422 272 "because the file path is empty or null"), 423 m Data->mSlot);273 m->bd->ulSlot); 424 274 break; 425 275 case PortMode_HostPipe: 426 if (m Data->mPath.isEmpty())276 if (m->bd->strPath.isEmpty()) 427 277 return setError (E_INVALIDARG, 428 278 tr ("Cannot set the host pipe mode of the serial port %d " 429 279 "because the pipe path is empty or null"), 430 m Data->mSlot);280 m->bd->ulSlot); 431 281 break; 432 282 case PortMode_HostDevice: 433 if (m Data->mPath.isEmpty())283 if (m->bd->strPath.isEmpty()) 434 284 return setError (E_INVALIDARG, 435 285 tr ("Cannot set the host device mode of the serial port %d " 436 286 "because the device path is empty or null"), 437 m Data->mSlot);287 m->bd->ulSlot); 438 288 break; 439 289 case PortMode_Disconnected: … … 441 291 } 442 292 443 m Data.backup();444 m Data->mHostMode = aHostMode;293 m->bd.backup(); 294 m->bd->portMode = aHostMode; 445 295 446 296 emitChangeEvent = true; … … 452 302 alock.unlock(); 453 303 454 m Parent->onSerialPortChange (this);304 m->pMachine->onSerialPortChange (this); 455 305 } 456 306 … … 467 317 AutoReadLock alock(this); 468 318 469 *aSlot = m Data->mSlot;319 *aSlot = m->bd->ulSlot; 470 320 471 321 return S_OK; … … 481 331 AutoReadLock alock(this); 482 332 483 *aIRQ = m Data->mIRQ;333 *aIRQ = m->bd->ulIRQ; 484 334 485 335 return S_OK; … … 494 344 tr ("Invalid IRQ number of the serial port %d: " 495 345 "%lu (must be in range [0, %lu])"), 496 m Data->mSlot, aIRQ, 255);346 m->bd->ulSlot, aIRQ, 255); 497 347 498 348 AutoCaller autoCaller(this); … … 500 350 501 351 /* the machine needs to be mutable */ 502 Machine::AutoMutableStateDependency adep(m Parent);352 Machine::AutoMutableStateDependency adep(m->pMachine); 503 353 if (FAILED(adep.rc())) return adep.rc(); 504 354 … … 508 358 bool emitChangeEvent = false; 509 359 510 if (m Data->mIRQ != aIRQ)511 { 512 m Data.backup();513 m Data->mIRQ = aIRQ;360 if (m->bd->ulIRQ != aIRQ) 361 { 362 m->bd.backup(); 363 m->bd->ulIRQ = aIRQ; 514 364 emitChangeEvent = true; 515 365 } … … 520 370 alock.unlock(); 521 371 522 m Parent->onSerialPortChange (this);372 m->pMachine->onSerialPortChange (this); 523 373 } 524 374 … … 535 385 AutoReadLock alock(this); 536 386 537 *aIOBase = m Data->mIOBase;387 *aIOBase = m->bd->ulIOBase; 538 388 539 389 return S_OK; … … 548 398 tr ("Invalid I/O port base address of the serial port %d: " 549 399 "%lu (must be in range [0, 0x%X])"), 550 m Data->mSlot, aIOBase, 0, 0xFFFF);400 m->bd->ulSlot, aIOBase, 0, 0xFFFF); 551 401 552 402 AutoCaller autoCaller(this); … … 554 404 555 405 /* the machine needs to be mutable */ 556 Machine::AutoMutableStateDependency adep(m Parent);406 Machine::AutoMutableStateDependency adep(m->pMachine); 557 407 if (FAILED(adep.rc())) return adep.rc(); 558 408 … … 562 412 bool emitChangeEvent = false; 563 413 564 if (m Data->mIOBase != aIOBase)565 { 566 m Data.backup();567 m Data->mIOBase = aIOBase;414 if (m->bd->ulIOBase != aIOBase) 415 { 416 m->bd.backup(); 417 m->bd->ulIOBase = aIOBase; 568 418 emitChangeEvent = true; 569 419 } … … 574 424 alock.unlock(); 575 425 576 m Parent->onSerialPortChange (this);426 m->pMachine->onSerialPortChange (this); 577 427 } 578 428 … … 589 439 AutoReadLock alock(this); 590 440 591 mData->mPath.cloneTo(aPath); 592 593 return S_OK; 594 } 595 596 /** 597 * Validates COMSETTER(Path) arguments. 598 */ 599 HRESULT SerialPort::checkSetPath (CBSTR aPath) 600 { 601 AssertReturn(isWriteLockOnCurrentThread(), E_FAIL); 602 603 if ((mData->mHostMode == PortMode_HostDevice || 604 mData->mHostMode == PortMode_HostPipe || 605 mData->mHostMode == PortMode_RawFile) && 606 (aPath == NULL || *aPath == '\0')) 607 return setError (E_INVALIDARG, 608 tr ("Path of the serial port %d may not be empty or null in " 609 "host pipe or host device mode"), 610 mData->mSlot); 441 m->bd->strPath.cloneTo(aPath); 611 442 612 443 return S_OK; … … 619 450 620 451 /* the machine needs to be mutable */ 621 Machine::AutoMutableStateDependency adep(m Parent);452 Machine::AutoMutableStateDependency adep(m->pMachine); 622 453 if (FAILED(adep.rc())) return adep.rc(); 623 454 … … 628 459 aPath = NULL; 629 460 630 if (mData->mPath != aPath) 631 { 632 HRESULT rc = checkSetPath (aPath); 461 Utf8Str str(aPath); 462 if (str != m->bd->strPath) 463 { 464 HRESULT rc = checkSetPath(str); 633 465 if (FAILED(rc)) return rc; 634 466 635 m Data.backup();636 m Data->mPath = aPath;467 m->bd.backup(); 468 m->bd->strPath = str; 637 469 638 470 /* leave the lock before informing callbacks */ 639 471 alock.unlock(); 640 472 641 return m Parent->onSerialPortChange(this);473 return m->pMachine->onSerialPortChange(this); 642 474 } 643 475 … … 654 486 AutoReadLock alock(this); 655 487 656 *aServer = m Data->mServer;488 *aServer = m->bd->fServer; 657 489 658 490 return S_OK; … … 665 497 666 498 /* the machine needs to be mutable */ 667 Machine::AutoMutableStateDependency adep(m Parent);499 Machine::AutoMutableStateDependency adep(m->pMachine); 668 500 if (FAILED(adep.rc())) return adep.rc(); 669 501 670 502 AutoWriteLock alock(this); 671 503 672 if (m Data->mServer != aServer)673 { 674 m Data.backup();675 m Data->mServer = aServer;504 if (m->bd->fServer != aServer) 505 { 506 m->bd.backup(); 507 m->bd->fServer = aServer; 676 508 677 509 /* leave the lock before informing callbacks */ 678 510 alock.unlock(); 679 511 680 mParent->onSerialPortChange (this); 681 } 682 683 return S_OK; 684 } 512 m->pMachine->onSerialPortChange (this); 513 } 514 515 return S_OK; 516 } 517 518 // public methods only for internal purposes 519 //////////////////////////////////////////////////////////////////////////////// 520 521 /** 522 * Loads settings from the given port node. 523 * May be called once right after this object creation. 524 * 525 * @param aPortNode <Port> node. 526 * 527 * @note Locks this object for writing. 528 */ 529 HRESULT SerialPort::loadSettings(const settings::SerialPort &data) 530 { 531 AutoCaller autoCaller(this); 532 AssertComRCReturnRC(autoCaller.rc()); 533 534 AutoWriteLock alock(this); 535 536 // simply copy 537 *m->bd.data() = data; 538 539 return S_OK; 540 } 541 542 /** 543 * Saves the port settings to the given port node. 544 * 545 * Note that the given Port node is comletely empty on input. 546 * 547 * @param aPortNode <Port> node. 548 * 549 * @note Locks this object for reading. 550 */ 551 HRESULT SerialPort::saveSettings(settings::SerialPort &data) 552 { 553 AutoCaller autoCaller(this); 554 AssertComRCReturnRC(autoCaller.rc()); 555 556 AutoReadLock alock(this); 557 558 // simply copy 559 data = *m->bd.data(); 560 561 return S_OK; 562 } 563 564 bool SerialPort::isModified() 565 { 566 AutoWriteLock alock (this); 567 return m->bd.isBackedUp(); 568 } 569 570 bool SerialPort::isReallyModified() 571 { 572 AutoWriteLock alock(this); 573 return m->bd.hasActualChanges(); 574 } 575 576 /** 577 * @note Locks this object for writing. 578 */ 579 bool SerialPort::rollback() 580 { 581 /* sanity */ 582 AutoCaller autoCaller(this); 583 AssertComRCReturn (autoCaller.rc(), false); 584 585 AutoWriteLock alock(this); 586 587 bool changed = false; 588 589 if (m->bd.isBackedUp()) 590 { 591 /* we need to check all data to see whether anything will be changed 592 * after rollback */ 593 changed = m->bd.hasActualChanges(); 594 m->bd.rollback(); 595 } 596 597 return changed; 598 } 599 600 /** 601 * @note Locks this object for writing, together with the peer object (also 602 * for writing) if there is one. 603 */ 604 void SerialPort::commit() 605 { 606 /* sanity */ 607 AutoCaller autoCaller(this); 608 AssertComRCReturnVoid (autoCaller.rc()); 609 610 /* sanity too */ 611 AutoCaller peerCaller(m->pPeer); 612 AssertComRCReturnVoid(peerCaller.rc()); 613 614 /* lock both for writing since we modify both (pPeer is "master" so locked 615 * first) */ 616 AutoMultiWriteLock2 alock(m->pPeer, this); 617 618 if (m->bd.isBackedUp()) 619 { 620 m->bd.commit(); 621 if (m->pPeer) 622 { 623 /* attach new data to the peer and reshare it */ 624 m->pPeer->m->bd.attach(m->bd); 625 } 626 } 627 } 628 629 /** 630 * @note Locks this object for writing, together with the peer object 631 * represented by @a aThat (locked for reading). 632 */ 633 void SerialPort::copyFrom (SerialPort *aThat) 634 { 635 AssertReturnVoid (aThat != NULL); 636 637 /* sanity */ 638 AutoCaller autoCaller(this); 639 AssertComRCReturnVoid (autoCaller.rc()); 640 641 /* sanity too */ 642 AutoCaller thatCaller (aThat); 643 AssertComRCReturnVoid (thatCaller.rc()); 644 645 /* peer is not modified, lock it for reading (aThat is "master" so locked 646 * first) */ 647 AutoMultiLock2 alock (aThat->rlock(), this->wlock()); 648 649 /* this will back up current data */ 650 m->bd.assignCopy (aThat->m->bd); 651 } 652 653 void SerialPort::applyDefaults (GuestOSType *aOsType) 654 { 655 AssertReturnVoid (aOsType != NULL); 656 657 /* sanity */ 658 AutoCaller autoCaller(this); 659 AssertComRCReturnVoid (autoCaller.rc()); 660 661 AutoWriteLock alock(this); 662 663 uint32_t numSerialEnabled = aOsType->numSerialEnabled(); 664 665 /* Enable port if requested */ 666 if (m->bd->ulSlot < numSerialEnabled) 667 { 668 m->bd->fEnabled = true; 669 } 670 } 671 672 /** 673 * Validates COMSETTER(Path) arguments. 674 */ 675 HRESULT SerialPort::checkSetPath(const Utf8Str &str) 676 { 677 AssertReturn(isWriteLockOnCurrentThread(), E_FAIL); 678 679 if ( ( m->bd->portMode == PortMode_HostDevice 680 || m->bd->portMode == PortMode_HostPipe 681 || m->bd->portMode == PortMode_RawFile 682 ) && str.isEmpty() 683 ) 684 return setError(E_INVALIDARG, 685 tr("Path of the serial port %d may not be empty or null in " 686 "host pipe or host device mode"), 687 m->bd->ulSlot); 688 689 return S_OK; 690 } 691 685 692 /* vi: set tabstop=4 shiftwidth=4 expandtab: */ -
trunk/src/VBox/Main/include/ParallelPortImpl.h
r25202 r25203 93 93 94 94 private: 95 96 95 HRESULT checkSetPath(const Utf8Str &str); 97 96 -
trunk/src/VBox/Main/include/SerialPortImpl.h
r24989 r25203 42 42 { 43 43 public: 44 45 struct Data46 {47 Data()48 : mSlot (0)49 , mEnabled (FALSE)50 , mIRQ (4)51 , mIOBase (0x3f8)52 , mHostMode (PortMode_Disconnected)53 , mServer (FALSE)54 {}55 56 bool operator== (const Data &that) const57 {58 return this == &that ||59 (mSlot == that.mSlot &&60 mEnabled == that.mEnabled &&61 mIRQ == that.mIRQ &&62 mIOBase == that.mIOBase &&63 mHostMode == that.mHostMode &&64 mPath == that.mPath &&65 mServer == that.mServer);66 }67 68 ULONG mSlot;69 BOOL mEnabled;70 ULONG mIRQ;71 ULONG mIOBase;72 PortMode_T mHostMode;73 Bstr mPath;74 BOOL mServer;75 };76 77 44 VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT (SerialPort) 78 45 … … 118 85 HRESULT saveSettings(settings::SerialPort &data); 119 86 120 bool isModified() { AutoWriteLock alock (this); return mData.isBackedUp(); }121 bool isReallyModified() { AutoWriteLock alock (this); return mData.hasActualChanges(); }87 bool isModified(); 88 bool isReallyModified(); 122 89 bool rollback(); 123 90 void commit(); 124 void copyFrom (SerialPort *aThat); 91 void copyFrom(SerialPort *aThat); 92 125 93 void applyDefaults (GuestOSType *aOsType); 126 94 … … 132 100 133 101 private: 102 HRESULT checkSetPath(const Utf8Str &str); 134 103 135 HRESULT checkSetPath (CBSTR aPath); 136 137 const ComObjPtr<Machine, ComWeakRef> mParent; 138 const ComObjPtr<SerialPort> mPeer; 139 140 Backupable<Data> mData; 104 struct Data; 105 Data *m; 141 106 }; 142 107
Note:
See TracChangeset
for help on using the changeset viewer.