VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/MediumAttachmentImpl.cpp

Last change on this file was 98262, checked in by vboxsync, 17 months ago

Main: rc() -> hrc()/vrc(). bugref:10223

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 16.9 KB
RevLine 
[55401]1/* $Id: MediumAttachmentImpl.cpp 98262 2023-01-24 01:42:14Z vboxsync $ */
[23269]2/** @file
3 * VirtualBox COM class implementation
4 */
5
6/*
[98103]7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[23269]8 *
[96407]9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
[23269]26 */
27
[76592]28#define LOG_GROUP LOG_GROUP_MAIN_MEDIUMATTACHMENT
[23269]29#include "MediumAttachmentImpl.h"
30#include "MachineImpl.h"
[25200]31#include "MediumImpl.h"
[24934]32#include "Global.h"
[93410]33#include "StringifyEnums.h"
[23269]34
[25860]35#include "AutoCaller.h"
[76592]36#include "LoggingNew.h"
[23269]37
[30681]38#include <iprt/cpp/utils.h>
39
[25200]40////////////////////////////////////////////////////////////////////////////////
41//
42// private member data definition
43//
44////////////////////////////////////////////////////////////////////////////////
45
46struct BackupableMediumAttachmentData
47{
48 BackupableMediumAttachmentData()
[61377]49 : fImplicit(false)
[25200]50 { }
51
[61377]52 ComObjPtr<Medium> pMedium;
[25200]53 /* Since MediumAttachment is not a first class citizen when it
54 * comes to managing settings, having a reference to the storage
55 * controller will not work - when settings are changed it will point
56 * to the old, uninitialized instance. Changing this requires
57 * substantial changes to MediumImpl.cpp. */
[36058]58 /* Same counts for the assigned bandwidth group */
[61377]59 bool fImplicit;
60 const Utf8Str strControllerName;
61 settings::AttachedDevice mData;
[25200]62};
63
64struct MediumAttachment::Data
65{
[38718]66 Data(Machine * const aMachine = NULL)
67 : pMachine(aMachine),
[37695]68 fIsEjected(false)
[25200]69 { }
70
71 /** Reference to Machine object, for checking mutable state. */
[61377]72 Machine * const pMachine;
[25200]73 /* later: const ComObjPtr<MediumAttachment> mPeer; */
[61377]74 bool fIsEjected;
[25200]75 Backupable<BackupableMediumAttachmentData> bd;
76};
77
[23269]78// constructor / destructor
79/////////////////////////////////////////////////////////////////////////////
80
[49871]81DEFINE_EMPTY_CTOR_DTOR(MediumAttachment)
82
[23269]83HRESULT MediumAttachment::FinalConstruct()
84{
[23394]85 LogFlowThisFunc(("\n"));
[35638]86 return BaseFinalConstruct();
[23269]87}
88
89void MediumAttachment::FinalRelease()
90{
[23394]91 LogFlowThisFuncEnter();
[23269]92 uninit();
[35638]93 BaseFinalRelease();
[23394]94 LogFlowThisFuncLeave();
[23269]95}
96
97// public initializer/uninitializer for internal purposes only
98/////////////////////////////////////////////////////////////////////////////
99
100/**
101 * Initializes the medium attachment object.
102 *
[31301]103 * @param aParent Machine object.
104 * @param aMedium Medium object.
[65103]105 * @param aControllerName Controller the hard disk is attached to.
[31301]106 * @param aPort Port number.
107 * @param aDevice Device number on the port.
[65103]108 * @param aType Device type.
[65186]109 * @param aImplicit
[31301]110 * @param aPassthrough Whether accesses are directly passed to the host drive.
[65120]111 * @param aTempEject Whether guest-triggered eject results in unmounting the medium.
[65103]112 * @param aNonRotational Whether this medium is non-rotational (aka SSD).
[65120]113 * @param aDiscard Whether this medium supports discarding unused blocks.
[65103]114 * @param aHotPluggable Whether this medium is hot-pluggable.
[65120]115 * @param strBandwidthGroup Bandwidth group.
[23269]116 */
[23394]117HRESULT MediumAttachment::init(Machine *aParent,
[23269]118 Medium *aMedium,
[56820]119 const Utf8Str &aControllerName,
[23269]120 LONG aPort,
121 LONG aDevice,
122 DeviceType_T aType,
[37709]123 bool aImplicit,
[31301]124 bool aPassthrough,
[37709]125 bool aTempEject,
[37824]126 bool aNonRotational,
[38873]127 bool aDiscard,
[48879]128 bool aHotPluggable,
[36058]129 const Utf8Str &strBandwidthGroup)
[23269]130{
[23394]131 LogFlowThisFuncEnter();
[56820]132 LogFlowThisFunc(("aParent=%p aMedium=%p aControllerName=%s aPort=%d aDevice=%d aType=%d aImplicit=%d aPassthrough=%d aTempEject=%d aNonRotational=%d aDiscard=%d aHotPluggable=%d strBandwithGroup=%s\n", aParent, aMedium, aControllerName.c_str(), aPort, aDevice, aType, aImplicit, aPassthrough, aTempEject, aNonRotational, aDiscard, aHotPluggable, strBandwidthGroup.c_str()));
[23394]133
[23269]134 if (aType == DeviceType_HardDisk)
135 AssertReturn(aMedium, E_INVALIDARG);
136
137 /* Enclose the state transition NotReady->InInit->Ready */
138 AutoInitSpan autoInitSpan(this);
139 AssertReturn(autoInitSpan.isOk(), E_FAIL);
140
[25200]141 m = new Data();
[23394]142
[25200]143 unconst(m->pMachine) = aParent;
[23269]144
[25200]145 m->bd.allocate();
146 m->bd->pMedium = aMedium;
[61377]147 m->bd->mData.strBwGroup = strBandwidthGroup;
[56820]148 unconst(m->bd->strControllerName) = aControllerName;
[61713]149 m->bd->mData.lPort = aPort;
[61377]150 m->bd->mData.lDevice = aDevice;
[61713]151 m->bd->mData.deviceType = aType;
[23269]152
[61377]153 m->bd->mData.fPassThrough = aPassthrough;
154 m->bd->mData.fTempEject = aTempEject;
155 m->bd->mData.fNonRotational = aNonRotational;
156 m->bd->mData.fDiscard = aDiscard;
[37709]157 m->bd->fImplicit = aImplicit;
[61377]158 m->bd->mData.fHotPluggable = aHotPluggable;
[25200]159
[23269]160 /* Confirm a successful initialization when it's the case */
161 autoInitSpan.setSucceeded();
162
[24934]163 /* Construct a short log name for this attachment. */
[61713]164 i_updateLogName();
[24934]165
[49871]166 LogFlowThisFunc(("LEAVE - %s\n", i_getLogName()));
[23269]167 return S_OK;
168}
169
170/**
[38718]171 * Initializes the medium attachment object given another guest object
172 * (a kind of copy constructor). This object makes a private copy of data
173 * of the original object passed as an argument.
174 */
175HRESULT MediumAttachment::initCopy(Machine *aParent, MediumAttachment *aThat)
176{
177 LogFlowThisFunc(("aParent=%p, aThat=%p\n", aParent, aThat));
178
179 ComAssertRet(aParent && aThat, E_INVALIDARG);
180
181 /* Enclose the state transition NotReady->InInit->Ready */
182 AutoInitSpan autoInitSpan(this);
183 AssertReturn(autoInitSpan.isOk(), E_FAIL);
184
185 m = new Data(aParent);
186 /* m->pPeer is left null */
187
188 AutoCaller thatCaller(aThat);
[98262]189 AssertComRCReturnRC(thatCaller.hrc());
[38718]190
191 AutoReadLock thatlock(aThat COMMA_LOCKVAL_SRC_POS);
192 m->bd.attachCopy(aThat->m->bd);
193
194 /* Confirm a successful initialization */
195 autoInitSpan.setSucceeded();
196
[61713]197 /* Construct a short log name for this attachment. */
198 i_updateLogName();
199
200 LogFlowThisFunc(("LEAVE - %s\n", i_getLogName()));
[38718]201 return S_OK;
202}
203
204/**
[23269]205 * Uninitializes the instance.
206 * Called from FinalRelease().
207 */
208void MediumAttachment::uninit()
209{
[49871]210 LogFlowThisFunc(("ENTER - %s\n", i_getLogName()));
[23394]211
[23269]212 /* Enclose the state transition Ready->InUninit->NotReady */
213 AutoUninitSpan autoUninitSpan(this);
214 if (autoUninitSpan.uninitDone())
215 return;
[23394]216
[25200]217 m->bd.free();
[23394]218
[27607]219 unconst(m->pMachine) = NULL;
[23394]220
[25200]221 delete m;
222 m = NULL;
[23269]223
[23394]224 LogFlowThisFuncLeave();
[23269]225}
226
227// IHardDiskAttachment properties
228/////////////////////////////////////////////////////////////////////////////
229
[49871]230
[78786]231HRESULT MediumAttachment::getMachine(ComPtr<IMachine> &aMachine)
232{
233 LogFlowThisFuncEnter();
234
235 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
236
237 ComObjPtr<Machine> pMachine(m->pMachine);
238 pMachine.queryInterfaceTo(aMachine.asOutParam());
239
240 LogFlowThisFuncLeave();
241 return S_OK;
242}
243
244
[49871]245HRESULT MediumAttachment::getMedium(ComPtr<IMedium> &aHardDisk)
[23269]246{
[23394]247 LogFlowThisFuncEnter();
248
[25310]249 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
[23269]250
[49871]251 aHardDisk = m->bd->pMedium;
[23269]252
[23394]253 LogFlowThisFuncLeave();
[23269]254 return S_OK;
255}
256
[49871]257
258HRESULT MediumAttachment::getController(com::Utf8Str &aController)
[23269]259{
[23394]260 LogFlowThisFuncEnter();
261
[23269]262 /* m->controller is constant during life time, no need to lock */
[56820]263 aController = Utf8Str(m->bd->strControllerName);
[23269]264
[23394]265 LogFlowThisFuncLeave();
[24511]266 return S_OK;
[23269]267}
268
[49871]269
270HRESULT MediumAttachment::getPort(LONG *aPort)
[23269]271{
[23394]272 LogFlowThisFuncEnter();
273
[25200]274 /* m->bd->port is constant during life time, no need to lock */
[61377]275 *aPort = m->bd->mData.lPort;
[23269]276
[23394]277 LogFlowThisFuncLeave();
[23269]278 return S_OK;
279}
280
[49871]281HRESULT MediumAttachment::getDevice(LONG *aDevice)
[23269]282{
[23394]283 LogFlowThisFuncEnter();
284
[25200]285 /* m->bd->device is constant during life time, no need to lock */
[61377]286 *aDevice = m->bd->mData.lDevice;
[23269]287
[23394]288 LogFlowThisFuncLeave();
[23269]289 return S_OK;
290}
291
[49871]292HRESULT MediumAttachment::getType(DeviceType_T *aType)
[23269]293{
[23394]294 LogFlowThisFuncEnter();
295
[25200]296 /* m->bd->type is constant during life time, no need to lock */
[61377]297 *aType = m->bd->mData.deviceType;
[23269]298
[23394]299 LogFlowThisFuncLeave();
[23269]300 return S_OK;
301}
302
[49871]303
304HRESULT MediumAttachment::getPassthrough(BOOL *aPassthrough)
[23269]305{
[23394]306 LogFlowThisFuncEnter();
307
[25310]308 AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
[23269]309
[61377]310 *aPassthrough = m->bd->mData.fPassThrough;
[23394]311
312 LogFlowThisFuncLeave();
[23269]313 return S_OK;
314}
315
[49871]316
317HRESULT MediumAttachment::getTemporaryEject(BOOL *aTemporaryEject)
[37709]318{
319 LogFlowThisFuncEnter();
320
321 AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
322
[61377]323 *aTemporaryEject = m->bd->mData.fTempEject;
[37709]324
325 LogFlowThisFuncLeave();
326 return S_OK;
327}
328
[49871]329
330HRESULT MediumAttachment::getIsEjected(BOOL *aEjected)
[37695]331{
332 LogFlowThisFuncEnter();
333
334 AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
335
336 *aEjected = m->fIsEjected;
337
338 LogFlowThisFuncLeave();
339 return S_OK;
340}
341
[49871]342
343HRESULT MediumAttachment::getNonRotational(BOOL *aNonRotational)
[37824]344{
345 LogFlowThisFuncEnter();
346
347 AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
348
[61377]349 *aNonRotational = m->bd->mData.fNonRotational;
[37824]350
351 LogFlowThisFuncLeave();
352 return S_OK;
353}
354
[49871]355HRESULT MediumAttachment::getDiscard(BOOL *aDiscard)
[38873]356{
357 LogFlowThisFuncEnter();
358
359 AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
360
[61377]361 *aDiscard = m->bd->mData.fDiscard;
[38873]362
363 LogFlowThisFuncLeave();
364 return S_OK;
365}
366
[49871]367
368HRESULT MediumAttachment::getBandwidthGroup(ComPtr<IBandwidthGroup> &aBandwidthGroup)
[31287]369{
[36181]370 LogFlowThisFuncEnter();
[31287]371
372 AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
373
[36058]374 HRESULT hrc = S_OK;
[61377]375 if (m->bd->mData.strBwGroup.isNotEmpty())
[36058]376 {
377 ComObjPtr<BandwidthGroup> pBwGroup;
[61377]378 hrc = m->pMachine->i_getBandwidthGroup(m->bd->mData.strBwGroup, pBwGroup, true /* fSetError */);
[31287]379
[51092]380 Assert(SUCCEEDED(hrc)); /* This is not allowed to fail because the existence of the
381 group was checked when it was attached. */
[36058]382
383 if (SUCCEEDED(hrc))
[49871]384 pBwGroup.queryInterfaceTo(aBandwidthGroup.asOutParam());
[36058]385 }
386
[36181]387 LogFlowThisFuncLeave();
[36058]388 return hrc;
[31287]389}
390
[49871]391HRESULT MediumAttachment::getHotPluggable(BOOL *aHotPluggable)
[48879]392{
393 LogFlowThisFuncEnter();
394
395 AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
396
[61377]397 *aHotPluggable = m->bd->mData.fHotPluggable;
[48879]398
399 LogFlowThisFuncLeave();
400 return S_OK;
401}
402
[25200]403/**
404 * @note Locks this object for writing.
405 */
[49871]406void MediumAttachment::i_rollback()
[25200]407{
[49871]408 LogFlowThisFunc(("ENTER - %s\n", i_getLogName()));
[25200]409
410 /* sanity */
411 AutoCaller autoCaller(this);
[98262]412 AssertComRCReturnVoid(autoCaller.hrc());
[25200]413
[25310]414 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
[25200]415
[26171]416 m->bd.rollback();
[25200]417
[49871]418 LogFlowThisFunc(("LEAVE - %s\n", i_getLogName()));
[25200]419}
420
421/**
422 * @note Locks this object for writing.
423 */
[49871]424void MediumAttachment::i_commit()
[25200]425{
[49871]426 LogFlowThisFunc(("ENTER - %s\n", i_getLogName()));
[25200]427
428 /* sanity */
429 AutoCaller autoCaller(this);
[98262]430 AssertComRCReturnVoid(autoCaller.hrc());
[25200]431
[25310]432 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
[25200]433
434 if (m->bd.isBackedUp())
435 m->bd.commit();
436
[49871]437 LogFlowThisFunc(("LEAVE - %s\n", i_getLogName()));
[25200]438}
439
[49871]440bool MediumAttachment::i_isImplicit() const
[25200]441{
442 return m->bd->fImplicit;
443}
444
[49871]445void MediumAttachment::i_setImplicit(bool aImplicit)
[25200]446{
[61713]447 Assert(!m->pMachine->i_isSnapshotMachine());
[25200]448 m->bd->fImplicit = aImplicit;
[61713]449
450 /* Construct a short log name for this attachment. */
451 i_updateLogName();
[25200]452}
453
[49871]454const ComObjPtr<Medium>& MediumAttachment::i_getMedium() const
[25200]455{
456 return m->bd->pMedium;
457}
458
[56820]459const Utf8Str &MediumAttachment::i_getControllerName() const
[25200]460{
[56820]461 return m->bd->strControllerName;
[25200]462}
463
[49871]464LONG MediumAttachment::i_getPort() const
[25200]465{
[61377]466 return m->bd->mData.lPort;
[25200]467}
468
[49871]469LONG MediumAttachment::i_getDevice() const
[25200]470{
[61377]471 return m->bd->mData.lDevice;
[25200]472}
473
[49871]474DeviceType_T MediumAttachment::i_getType() const
[25200]475{
[61377]476 return m->bd->mData.deviceType;
[25200]477}
478
[49871]479bool MediumAttachment::i_getPassthrough() const
[25200]480{
[25310]481 AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
[61377]482 return m->bd->mData.fPassThrough;
[25200]483}
484
[49871]485bool MediumAttachment::i_getTempEject() const
[37709]486{
487 AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
[61377]488 return m->bd->mData.fTempEject;
[37709]489}
490
[49871]491bool MediumAttachment::i_getNonRotational() const
[37824]492{
493 AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
[61377]494 return m->bd->mData.fNonRotational;
[37824]495}
496
[49871]497bool MediumAttachment::i_getDiscard() const
[38873]498{
499 AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
[61377]500 return m->bd->mData.fDiscard;
[38873]501}
502
[49871]503bool MediumAttachment::i_getHotPluggable() const
[48879]504{
505 AutoReadLock lock(this COMMA_LOCKVAL_SRC_POS);
[61377]506 return m->bd->mData.fHotPluggable;
[48879]507}
508
[49871]509Utf8Str& MediumAttachment::i_getBandwidthGroup() const
[34587]510{
[61377]511 return m->bd->mData.strBwGroup;
[34587]512}
513
[56820]514bool MediumAttachment::i_matches(const Utf8Str &aControllerName, LONG aPort, LONG aDevice)
[25200]515{
[56820]516 return ( aControllerName == m->bd->strControllerName
[61377]517 && aPort == m->bd->mData.lPort
518 && aDevice == m->bd->mData.lDevice);
[25200]519}
520
[56820]521/** Must be called from under this object's write lock. */
522void MediumAttachment::i_updateName(const Utf8Str &aName)
523{
524 Assert(isWriteLockOnCurrentThread());
[61713]525 Assert(!m->pMachine->i_isSnapshotMachine());
[56820]526
527 m->bd.backup();
528 unconst(m->bd->strControllerName) = aName;
[61713]529
530 /* Construct a short log name for this attachment. */
531 i_updateLogName();
[56820]532}
533
[33078]534/**
535 * Sets the medium of this attachment and unsets the "implicit" flag.
536 * @param aMedium
537 */
[49871]538void MediumAttachment::i_updateMedium(const ComObjPtr<Medium> &aMedium)
[25200]539{
[26167]540 Assert(isWriteLockOnCurrentThread());
[67492]541 /* No assertion for a snapshot. Method used in deleting snapshot. */
[26167]542
[25200]543 m->bd.backup();
544 m->bd->pMedium = aMedium;
[33078]545 m->bd->fImplicit = false;
[37695]546 m->fIsEjected = false;
[25200]547}
548
[26200]549/** Must be called from under this object's write lock. */
[49871]550void MediumAttachment::i_updatePassthrough(bool aPassthrough)
[25200]551{
[26167]552 Assert(isWriteLockOnCurrentThread());
[61713]553 Assert(!m->pMachine->i_isSnapshotMachine());
[26167]554
[25200]555 m->bd.backup();
[61377]556 m->bd->mData.fPassThrough = aPassthrough;
[25200]557}
558
[37695]559/** Must be called from under this object's write lock. */
[49871]560void MediumAttachment::i_updateTempEject(bool aTempEject)
[37709]561{
562 Assert(isWriteLockOnCurrentThread());
[61713]563 Assert(!m->pMachine->i_isSnapshotMachine());
[37709]564
565 m->bd.backup();
[61377]566 m->bd->mData.fTempEject = aTempEject;
[37709]567}
568
569/** Must be called from under this object's write lock. */
[49871]570void MediumAttachment::i_updateEjected()
[37695]571{
572 Assert(isWriteLockOnCurrentThread());
[61713]573 Assert(!m->pMachine->i_isSnapshotMachine());
[37695]574
575 m->fIsEjected = true;
576}
577
[37824]578/** Must be called from under this object's write lock. */
[49871]579void MediumAttachment::i_updateNonRotational(bool aNonRotational)
[37824]580{
581 Assert(isWriteLockOnCurrentThread());
[61713]582 Assert(!m->pMachine->i_isSnapshotMachine());
[37824]583
584 m->bd.backup();
[61377]585 m->bd->mData.fNonRotational = aNonRotational;
[37824]586}
587
[38873]588/** Must be called from under this object's write lock. */
[49871]589void MediumAttachment::i_updateDiscard(bool aDiscard)
[38873]590{
591 Assert(isWriteLockOnCurrentThread());
[61713]592 Assert(!m->pMachine->i_isSnapshotMachine());
[38873]593
594 m->bd.backup();
[61377]595 m->bd->mData.fDiscard = aDiscard;
[38873]596}
597
[48880]598/** Must be called from under this object's write lock. */
[49871]599void MediumAttachment::i_updateHotPluggable(bool aHotPluggable)
[48880]600{
601 Assert(isWriteLockOnCurrentThread());
[61713]602 Assert(!m->pMachine->i_isSnapshotMachine());
[48880]603
604 m->bd.backup();
[61377]605 m->bd->mData.fHotPluggable = aHotPluggable;
[48880]606}
607
[49871]608void MediumAttachment::i_updateBandwidthGroup(const Utf8Str &aBandwidthGroup)
[34587]609{
[36058]610 LogFlowThisFuncEnter();
[34587]611 Assert(isWriteLockOnCurrentThread());
[61713]612 Assert(!m->pMachine->i_isSnapshotMachine());
[34587]613
614 m->bd.backup();
[61377]615 m->bd->mData.strBwGroup = aBandwidthGroup;
[34587]616
[36058]617 LogFlowThisFuncLeave();
[34587]618}
619
[49871]620void MediumAttachment::i_updateParentMachine(Machine * const pMachine)
[36181]621{
[49871]622 LogFlowThisFunc(("ENTER - %s\n", i_getLogName()));
[36181]623 /* sanity */
624 AutoCaller autoCaller(this);
[98262]625 AssertComRCReturnVoid(autoCaller.hrc());
[61713]626 Assert(!m->pMachine->i_isSnapshotMachine());
[36181]627
628 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
629
630 unconst(m->pMachine) = pMachine;
631
[49871]632 LogFlowThisFunc(("LEAVE - %s\n", i_getLogName()));
[36181]633}
634
[61713]635void MediumAttachment::i_updateLogName()
636{
637 const char *pszName = m->bd->strControllerName.c_str();
638 const char *pszEndNick = strpbrk(pszName, " \t:-");
639 mLogName = Utf8StrFmt("MA%p[%.*s:%u:%u:%s%s]",
640 this,
641 pszEndNick ? pszEndNick - pszName : 4, pszName,
[93410]642 m->bd->mData.lPort, m->bd->mData.lDevice, ::stringifyDeviceType(m->bd->mData.deviceType),
[61713]643 m->bd->fImplicit ? ":I" : "");
644}
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use