bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/* $Id$ */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/** @file
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync *
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * Token COM class implementation: MachineToken and MediumLockToken
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/*
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * Copyright (C) 2013 Oracle Corporation
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync *
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * available from http://www.virtualbox.org. This file is free software;
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * you can redistribute it and/or modify it under the terms of the GNU
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * General Public License (GPL) as published by the Free Software
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync#include "TokenImpl.h"
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync#include "MachineImpl.h"
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync#include "MediumImpl.h"
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync#include "AutoCaller.h"
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync#include "Logging.h"
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync// constructor / destructor
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/////////////////////////////////////////////////////////////////////////////
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsyncDEFINE_EMPTY_CTOR_DTOR(MachineToken)
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsyncHRESULT MachineToken::FinalConstruct()
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync{
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync return BaseFinalConstruct();
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync}
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsyncvoid MachineToken::FinalRelease()
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync{
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync uninit(false);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync BaseFinalRelease();
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync}
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync// public initializer/uninitializer for internal purposes only
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/////////////////////////////////////////////////////////////////////////////
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/**
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * Initializes the token object.
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync *
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * @param pSessionMachine Pointer to a SessionMachine object.
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsyncHRESULT MachineToken::init(const ComObjPtr<SessionMachine> &pSessionMachine)
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync{
320612173761d40306e8483d01127ee4a39c54f1vboxsync LogFlowThisFunc(("pSessionMachine=%p\n", &pSessionMachine));
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync ComAssertRet(!pSessionMachine.isNull(), E_INVALIDARG);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* Enclose the state transition NotReady->InInit->Ready */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync AutoInitSpan autoInitSpan(this);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync AssertReturn(autoInitSpan.isOk(), E_FAIL);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync m.pSessionMachine = pSessionMachine;
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* Confirm a successful initialization */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync autoInitSpan.setSucceeded();
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync return S_OK;
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync}
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/**
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * Uninitializes the instance and sets the ready flag to FALSE.
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * Called either from FinalRelease() or by the parent when it gets destroyed.
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync */
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsyncvoid MachineToken::uninit(bool fAbandon)
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync{
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync LogFlowThisFunc(("\n"));
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* Enclose the state transition Ready->InUninit->NotReady */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync AutoUninitSpan autoUninitSpan(this);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync if (autoUninitSpan.uninitDone())
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync return;
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* Destroy the SessionMachine object, check is paranoia */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync if (!m.pSessionMachine.isNull())
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync {
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync m.pSessionMachine->uninit(fAbandon ? SessionMachine::Uninit::Normal : SessionMachine::Uninit::Abnormal);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync m.pSessionMachine.setNull();
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync }
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync}
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync// IToken methods
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/////////////////////////////////////////////////////////////////////////////
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsyncHRESULT MachineToken::abandon(AutoCaller &aAutoCaller)
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync{
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* have to release the AutoCaller before calling uninit(), self-deadlock */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync aAutoCaller.release();
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* uninit does everything we need */
8157dba118de0fdf8d1a2c7664edd82cc69dcf4fvboxsync uninit(true);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync return S_OK;
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync}
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsyncHRESULT MachineToken::dummy()
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync{
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* Remember, the wrapper contains the AutoCaller, which means that after
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * uninit() this code won't be reached any more. */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* this is a NOOP, no need to lock */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync return S_OK;
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync}
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync// public methods only for internal purposes
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/////////////////////////////////////////////////////////////////////////////
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync// constructor / destructor
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/////////////////////////////////////////////////////////////////////////////
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsyncDEFINE_EMPTY_CTOR_DTOR(MediumLockToken)
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsyncHRESULT MediumLockToken::FinalConstruct()
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync{
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync return BaseFinalConstruct();
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync}
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsyncvoid MediumLockToken::FinalRelease()
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync{
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync uninit();
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync BaseFinalRelease();
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync}
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync// public initializer/uninitializer for internal purposes only
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/////////////////////////////////////////////////////////////////////////////
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/**
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * Initializes the token object.
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync *
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * @param pMedium Pointer to a Medium object.
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * @param fWrite True if this is a write lock, false otherwise.
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsyncHRESULT MediumLockToken::init(const ComObjPtr<Medium> &pMedium, bool fWrite)
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync{
320612173761d40306e8483d01127ee4a39c54f1vboxsync LogFlowThisFunc(("pMedium=%p\n", &pMedium));
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync ComAssertRet(!pMedium.isNull(), E_INVALIDARG);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* Enclose the state transition NotReady->InInit->Ready */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync AutoInitSpan autoInitSpan(this);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync AssertReturn(autoInitSpan.isOk(), E_FAIL);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync m.pMedium = pMedium;
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync m.fWrite = fWrite;
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* Confirm a successful initialization */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync autoInitSpan.setSucceeded();
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync return S_OK;
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync}
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/**
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * Uninitializes the instance and sets the ready flag to FALSE.
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * Called either from FinalRelease() or by the parent when it gets destroyed.
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsyncvoid MediumLockToken::uninit()
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync{
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync LogFlowThisFunc(("\n"));
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* Enclose the state transition Ready->InUninit->NotReady */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync AutoUninitSpan autoUninitSpan(this);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync if (autoUninitSpan.uninitDone())
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync return;
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* Release the appropriate lock, check is paranoia */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync if (!m.pMedium.isNull())
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync {
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync if (m.fWrite)
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync {
0c35a87bba26b2572d7e014744c0acd58f725bd3vboxsync HRESULT rc = m.pMedium->i_unlockWrite(NULL);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync AssertComRC(rc);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync }
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync else
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync {
0c35a87bba26b2572d7e014744c0acd58f725bd3vboxsync HRESULT rc = m.pMedium->i_unlockRead(NULL);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync AssertComRC(rc);
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync }
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync m.pMedium.setNull();
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync }
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync}
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync// IToken methods
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/////////////////////////////////////////////////////////////////////////////
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsyncHRESULT MediumLockToken::abandon(AutoCaller &aAutoCaller)
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync{
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* have to release the AutoCaller before calling uninit(), self-deadlock */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync aAutoCaller.release();
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* uninit does everything we need */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync uninit();
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync return S_OK;
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync}
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsyncHRESULT MediumLockToken::dummy()
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync{
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* Remember, the wrapper contains the AutoCaller, which means that after
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync * uninit() this code won't be reached any more. */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync /* this is a NOOP, no need to lock */
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync return S_OK;
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync}
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync// public methods only for internal purposes
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/////////////////////////////////////////////////////////////////////////////
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync
bf17ed67e9d9e0767b4432ae0043fea2e27434f2vboxsync/* vi: set tabstop=4 shiftwidth=4 expandtab: */