Hi!

I'm preparing a patch (some of you are already aware of it) and in
order to do it I need to create a new COM interface and its
implementation. I've created it, but when compiling, it fails at
linking time saying a lot of  "undefined reference to vtable/VTT"
errors. I thought I was doing something wrong in my C++ code, so I
replicated INetworkAdapter  and NetworkAdapter in a new class and it
still gives me the same linker error. I'm clueless about what is the
problem.. there must be something else that I have to do beside
writing the code and adding the interface to the xidl file but I don't
know what it is so please help me! Attached to this email you can find
the patch and the errors.

Thanks in advance,
    Eduardo Robles Elvira.

Attachment: errors
Description: Binary data

Index: src/VBox/Main/include/NetworkAdapterImpl.h
===================================================================
--- src/VBox/Main/include/NetworkAdapterImpl.h  (revisión: 18845)
+++ src/VBox/Main/include/NetworkAdapterImpl.h  (copia de trabajo)
@@ -29,6 +29,61 @@
 class Machine;
 class GuestOSType;
 
+class ATL_NO_VTABLE NetworkAdapterRef :
+    public VirtualBoxBaseNEXT,
+    public VirtualBoxSupportErrorInfoImpl <NetworkAdapterRef, INetworkAdapterRef>,
+    public VirtualBoxSupportTranslation <NetworkAdapterRef>,
+    public INetworkAdapterRef
+{
+public:
+    VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT (NetworkAdapterRef)
+
+    DECLARE_NOT_AGGREGATABLE(NetworkAdapterRef)
+
+    DECLARE_PROTECT_FINAL_CONSTRUCT()
+
+    BEGIN_COM_MAP(NetworkAdapterRef)
+        COM_INTERFACE_ENTRY(ISupportErrorInfo)
+        COM_INTERFACE_ENTRY(INetworkAdapterRef)
+    END_COM_MAP()
+
+    NS_DECL_ISUPPORTS
+
+    DECLARE_EMPTY_CTOR_DTOR (NetworkAdapterRef)
+
+    HRESULT FinalConstruct();
+    void FinalRelease();
+
+    // public initializer/uninitializer for internal purposes only
+    HRESULT init ( const Guid &machineId, ULONG mSlot );
+    void uninit();
+
+    // INetworkAdapterRef properties
+    STDMETHOD(COMGETTER(Slot)) (ULONG *aSlot);
+    STDMETHOD(COMGETTER(MachineId)) (OUT_GUID aId);
+
+    // public methods only for internal purposes
+    const Guid &machineId() const { return mData.machineId; }
+    const ULONG &slot() const { return mData.slot; }
+
+    // for VirtualBoxSupportErrorInfoImpl
+    static const wchar_t *getComponentName() { return L"NetworkAdapterRef"; }
+
+private:
+
+    struct Data
+    {
+        Data() : machineId (0), slot (0) {}
+
+        /** The UUID of the parent machine. */
+        const Guid machineId;
+        /** The slot in which this netowrk adapter resides in the parent machine. */
+        const ULONG slot;
+    };
+
+    Data mData;
+};
+
 class ATL_NO_VTABLE NetworkAdapter :
     public VirtualBoxBaseNEXT,
     public VirtualBoxSupportErrorInfoImpl <NetworkAdapter, INetworkAdapter>,
@@ -36,14 +91,14 @@
     public INetworkAdapter
 {
 public:
-
+    typedef std::list <ComObjPtr <NetworkAdapterRef> > NetworkAdapterRefList;
     struct Data
     {
         Data()
             : mSlot (0), mEnabled (FALSE)
             , mAttachmentType (NetworkAttachmentType_Null)
             ,  mCableConnected (TRUE), mLineSpeed (0), mTraceEnabled (FALSE)
-            , mHostInterface ("") /* cannot be null */
+            , mHostInterface ("") /* cannot be null */, mMesh (FALSE)
         {}
 
         bool operator== (const Data &that) const
@@ -58,7 +113,8 @@
                     mTraceEnabled == that.mTraceEnabled &&
                     mHostInterface == that.mHostInterface &&
                     mInternalNetwork == that.mInternalNetwork &&
-                    mNATNetwork == that.mNATNetwork);
+                    mNATNetwork == that.mNATNetwork &&
+                    mMesh == that.mMesh);
         }
 
         NetworkAdapterType_T mAdapterType;
@@ -73,6 +129,8 @@
         Bstr mHostInterface;
         Bstr mInternalNetwork;
         Bstr mNATNetwork;
+        BOOL mMesh;
+        NetworkAdapterRefList mMeshNeighbours;
     };
 
     VIRTUALBOXBASE_ADD_ERRORINFO_SUPPORT (NetworkAdapter)
@@ -122,6 +180,10 @@
     STDMETHOD(COMSETTER(LineSpeed)) (ULONG aSpeed);
     STDMETHOD(COMGETTER(TraceFile)) (BSTR *aTraceFile);
     STDMETHOD(COMSETTER(TraceFile)) (IN_BSTR aTraceFile);
+    STDMETHOD(COMGETTER(MeshEnabled)) (BOOL *aEnabled);
+    STDMETHOD(COMSETTER(MeshEnabled)) (BOOL aEnabled);
+    STDMETHOD(COMGETTER(MeshNeighbours)) (ComSafeArrayOut (INetworkAdapterRef *, aNetworkAdapterRefs));
+    STDMETHOD(COMGETTER(Parent)) (IMachine **aMachine);
 
     // INetworkAdapter methods
     STDMETHOD(AttachToNAT)();
@@ -146,6 +208,7 @@
     // (ensure there is a caller and a read lock before calling them!)
 
     const Backupable <Data> &data() const { return mData; }
+    const ComObjPtr <Machine, ComWeakRef> &parent() const { return mParent; }
 
     // for VirtualBoxSupportErrorInfoImpl
     static const wchar_t *getComponentName() { return L"NetworkAdapter"; }
Index: src/VBox/Main/NetworkAdapterImpl.cpp
===================================================================
--- src/VBox/Main/NetworkAdapterImpl.cpp  (revisión: 18845)
+++ src/VBox/Main/NetworkAdapterImpl.cpp  (copia de trabajo)
@@ -682,6 +682,80 @@
     return S_OK;
 }
 
+ 
+STDMETHODIMP NetworkAdapter::COMGETTER(MeshEnabled) (BOOL *aEnabled)
+{
+    CheckComArgOutPointerValid(aEnabled);
+
+    AutoCaller autoCaller (this);
+    CheckComRCReturnRC (autoCaller.rc());
+
+    AutoReadLock alock (this);
+
+    *aEnabled = mData->mMesh;
+
+    return S_OK;
+}
+
+STDMETHODIMP NetworkAdapter::COMSETTER(MeshEnabled) (BOOL aEnabled)
+{
+    AutoCaller autoCaller (this);
+    CheckComRCReturnRC (autoCaller.rc());
+
+    /* the machine needs to be mutable */
+    Machine::AutoMutableStateDependency adep (mParent);
+    CheckComRCReturnRC (adep.rc());
+
+    AutoWriteLock alock (this);
+
+    if (mData->mMesh != aEnabled)
+    {
+        mData.backup();
+        mData->mMesh = aEnabled;
+
+        /* leave the lock before informing callbacks */
+        alock.unlock();
+
+        mParent->onNetworkAdapterChange (this);
+    }
+
+    return S_OK;
+}
+
+STDMETHODIMP NetworkAdapter::
+COMGETTER(MeshNeighbours) (ComSafeArrayOut (INetworkAdapterRef *, aNetworkAdapterRefs))
+{
+    if (ComSafeArrayOutIsNull (aNetworkAdapterRefs))
+        return E_POINTER;
+    
+    AssertReturn (mData->mMesh, E_FAIL);
+
+    AutoCaller autoCaller (this);
+    CheckComRCReturnRC (autoCaller.rc());
+
+    AutoReadLock alock (this);
+
+    SafeIfaceArray <INetworkAdapterRef> networkAdapterRefs (mData->mMeshNeighbours);
+    networkAdapterRefs.detachTo (ComSafeArrayOutArg (aNetworkAdapterRefs));
+
+    return S_OK;
+}
+
+STDMETHODIMP NetworkAdapter::COMGETTER(Parent) (IMachine **aParent)
+{
+    CheckComArgOutPointerValid(aParent);
+
+    AutoCaller autoCaller (this);
+    CheckComRCReturnRC (autoCaller.rc());
+
+    AutoReadLock alock (this);
+
+    /* mParent is const, no need to lock */
+    mParent.queryInterfaceTo (aParent);
+
+    return S_OK;
+}
+
 // INetworkAdapter methods
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -950,6 +1024,22 @@
         Bstr name = attachmentNode.stringValue ("name");
         /* name can be empty, but not null */
         ComAssertRet (!name.isNull(), E_FAIL);
+        mData->mMesh = attachmentNode.value <bool> ("mesh");
+ 
+        if(mData->mMesh)
+        {
+            Key meshNeighbourNode;
+            while (!(meshNeighbourNode = attachmentNode.findKey ("MeshNeighbour")).isNull())
+            {
+               Guid machineId = meshNeighbourNode.value<Guid>("machine");
+                ULONG aSlot = meshNeighbourNode.value <ULONG> ("slot");
+                
+                NetworkAdapterRef *networkAdapterRef = new NetworkAdapterRef();
+                networkAdapterRef->init(machineId, aSlot);
+                ComObjPtr <NetworkAdapterRef> aRef(networkAdapterRef);
+                mData->mMeshNeighbours.push_back(aRef);
+            }
+        }
 
         rc = COMSETTER(HostInterface) (name);
         CheckComRCReturnRC (rc);
@@ -1060,6 +1150,17 @@
 #if defined(VBOX_WITH_NETFLT)
             Assert (!mData->mHostInterface.isNull());
             attachmentNode.setValue <Bstr> ("name", mData->mHostInterface);
+            attachmentNode.setValue <bool> ("mesh", mData->mMesh);
+            
+            if(mData->mMesh)
+            {
+                for (NetworkAdapterRefList::const_iterator it = mData->mMeshNeighbours.begin(); it != mData->mMeshNeighbours.end(); ++ it)
+                {
+                    Key meshNeighbourNode = attachmentNode.createKey ("MeshNeighbour");
+                    meshNeighbourNode.setValue <Guid> ("machine", (*it)->machineId());
+                    meshNeighbourNode.setValue <ULONG> ("slot", (*it)->slot());
+                }
+            }
 #endif
             break;
         }
@@ -1253,4 +1354,102 @@
     LogFlowThisFunc (("generated MAC: '%s'\n", strMAC));
     mData->mMACAddress = strMAC;
 }
+
+
+
+
+// constructor / destructor
+////////////////////////////////////////////////////////////////////////////////
+
+DEFINE_EMPTY_CTOR_DTOR (NetworkAdapterRef)
+
+HRESULT NetworkAdapterRef::FinalConstruct()
+{
+    return S_OK;
+}
+
+void NetworkAdapterRef::FinalRelease()
+{
+    uninit ();
+}
+
+// public initializer/uninitializer for internal purposes only
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ *  Initializes the network adapter object.
+ */
+HRESULT NetworkAdapterRef::init (const Guid &machineId, ULONG aSlot)
+{
+    LogFlowThisFunc (("machineId=%p, aSlot=%d\n", machineId, aSlot));
+
+    ComAssertRet (aSlot < SchemaDefs::NetworkAdapterCount, E_INVALIDARG);
+
+    /* Enclose the state transition NotReady->InInit->Ready */
+    AutoInitSpan autoInitSpan (this);
+    AssertReturn (autoInitSpan.isOk(), E_FAIL);
+
+    /* initialize data */
+    unconst(mData.slot) = aSlot;
+    unconst(mData.machineId) = machineId;
+
+    /* Confirm a successful initialization */
+    autoInitSpan.setSucceeded();
+
+    return S_OK;
+}
+
+/**
+ *  Uninitializes the instance and sets the ready flag to FALSE.
+ *  Called either from FinalRelease() or by the parent when it gets destroyed.
+ */
+void NetworkAdapterRef::uninit()
+{
+    LogFlowThisFunc (("\n"));
+
+    /* Enclose the state transition Ready->InUninit->NotReady */
+    AutoUninitSpan autoUninitSpan (this);
+    if (autoUninitSpan.uninitDone())
+        return;
+
+    unconst (mData.machineId).clear();
+
+    unconst (mData.slot) = 0;
+}
+// INetworkAdapterRef properties
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Returns the GUID.
+ *
+ * @returns COM status code
+ * @param   aId   Address of result variable.
+ */
+STDMETHODIMP NetworkAdapterRef::COMGETTER(MachineId)(OUT_GUID aId)
+{
+    CheckComArgOutPointerValid(aId);
+
+    AutoCaller autoCaller (this);
+    CheckComRCReturnRC (autoCaller.rc());
+
+    /* this is const, no need to lock */
+    mData.machineId.cloneTo (aId);
+
+    return S_OK;
+}
+
+STDMETHODIMP NetworkAdapterRef::COMGETTER(Slot) (ULONG *aSlot)
+{
+    CheckComArgOutPointerValid(aSlot);
+
+    AutoCaller autoCaller (this);
+    CheckComRCReturnRC (autoCaller.rc());
+
+    AutoReadLock alock (this);
+
+    *aSlot = mData.slot;
+
+    return S_OK;
+}
+
 /* vi: set tabstop=4 shiftwidth=4 expandtab: */
Index: src/VBox/Main/idl/VirtualBox.xidl
===================================================================
--- src/VBox/Main/idl/VirtualBox.xidl (revisión: 18845)
+++ src/VBox/Main/idl/VirtualBox.xidl (copia de trabajo)
@@ -10929,6 +10929,26 @@
         <desc>Intel PRO/1000 MT Server network card (82545EM).</desc>
     </const>
   </enum>
+  
+  <interface
+     name="INetworkAdapterRef" extends="$unknown"
+     uuid="2a90d238-5eb4-109b-ce14-1488a720c2dd"
+     wsmap="managed"
+     >
+    <desc>
+        Represents a reference to a virtual network adapter using two attributes:
+        the machine to which the network adpater is attached, and the slot in
+        which the network adapter is attached in that machine. It's used instead
+        of INetworkAdapter to reference NetworkAdapters that might not have been
+        created yet.
+    </desc>
+    <attribute name="machineId" type="uuid" readonly="yes">
+      <desc>The machine ID to which this network interface is attached to.</desc>
+    </attribute>
+    <attribute name="slot" type="unsigned long" readonly="yes">
+      <desc>The slot in which the network adapter is attached to.</desc>
+    </attribute>
+  </interface>
 
   <interface
      name="INetworkAdapter" extends="$unknown"
@@ -11026,6 +11046,29 @@
       </desc>
     </attribute>
 
+ 
+    <attribute name="meshEnabled" type="boolean">
+      <desc>
+        Flag whether this network will be mesh, meaning that instead of everyone
+        being neighbours, a given network interface is connected to a subset of
+        other network interfaces, forming a mesh network.
+      </desc>
+    </attribute>
+
+    <attribute name="parent" type="IMachine" readonly="yes">
+      <desc>
+        Associated parent object.
+      </desc>
+    </attribute>
+
+    <attribute name="meshNeighbours" type="INetworkAdapterRef" safearray="yes" readonly="yes">
+      <desc>
+        List of all the other network adapters connected to this one in a mesh
+        network. In order to call get the list, the network adapter must be
+        in mesh mode or else it will return E_FAIL.
+      </desc>
+    </attribute>
+
     <method name="attachToNAT">
       <desc>
         Attach the network adapter to the Network Address Translation (NAT) interface.
_______________________________________________
vbox-dev mailing list
[email protected]
http://vbox.innotek.de/mailman/listinfo/vbox-dev

Reply via email to