📄 cpgpdiskdiskset.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: CPGPdiskDiskSet.cpp,v 1.14 2002/08/06 20:09:36 dallen Exp $
____________________________________________________________________________*/
#include "pgpClassesConfig.h"
#include "CArray.h"
#include "CList.h"
#include "CString.h"
#include "CDriverComm.h"
#include "CEngineSubsystems.h"
#include "CPGPdiskContext.h"
#include "CPGPdiskDisk.h"
#include "CPGPdiskDiskSet.h"
#include "CPGPdiskUser.h"
#include "pgpClientErrors.h" // wjb
_USING_PGP
_UNNAMED_BEGIN
// Types
struct StringHolder : public CListableObject<StringHolder>
{
CString path;
};
_UNNAMED_END
// Class CPGPdiskDiskSet member functions
CPGPdiskDiskSet::CPGPdiskDiskSet(const CPGPdiskContext *pContext) :
mPContext(pContext)
{
pgpAssertAddrValid(pContext, CPGPdiskContext);
Update();
}
CPGPdiskDiskSet::~CPGPdiskDiskSet()
{
pgpAssert(mDiskIters.IsEmpty());
Empty();
}
CPGPdiskDisk *
CPGPdiskDiskSet::Mount(
const char *path,
const CPGPdiskUser& diskUser,
const char *root,
PGPBoolean readOnly)
{
pgpAssertStrValid(path);
pgpAssert(diskUser.IsAssigned());
pgpAssertStrValid(root);
auto_ptr<CPGPdiskDisk> pNewDisk(new CPGPdiskDisk);
pNewDisk->Mount(Context(), path, diskUser, root, readOnly);
mDisks.AddTail(pNewDisk.get());
return pNewDisk.release();
}
void
CPGPdiskDiskSet::Unmount(CPGPdiskDisk *pDisk, PGPBoolean isForced)
{
pgpAssertAddrValid(pDisk, CPGPdiskDisk);
pgpAssert(pDisk->IsMounted());
if (!FindExactDisk(pDisk))
THROW_PGPERROR(kPGPError_BadParams);
// unmount the PGPdisk
UnmountAux(pDisk, isForced);
}
void
CPGPdiskDiskSet::UnmountTimedOut(PGPBoolean isForced)
{
UnmountAllAux(TRUE, isForced);
}
void
CPGPdiskDiskSet::UnmountAll(PGPBoolean isForced)
{
UnmountAllAux(FALSE, isForced);
}
void
CPGPdiskDiskSet::UpdateTimeouts()
{
CComboError storedErr;
PGPBoolean autoUnmount = mPContext->PGPclPrefs().GetBoolean(
kPGPPrefDiskUnmountOnInactivity);
PGPUInt32 unmountTimeout = mPContext->PGPclPrefs().GetNumber(
kPGPPrefDiskAutoUnmountTimeout);
CPGPdiskDisk *pDisk = mDisks.Head();
while (IsntNull(pDisk))
{
try
{
if (!pDisk->UsesCustomTimeout())
{
if (autoUnmount)
{
CEngineSubsystems::DriverComm().SetTimeout(
pDisk->Root(), unmountTimeout);
}
else
{
CEngineSubsystems::DriverComm().SetTimeout(
pDisk->Root(), 0);
}
}
}
catch (CComboError& caughtErr)
{
if (storedErr.IsntError())
storedErr = caughtErr;
}
pDisk = mDisks.Next(pDisk);
}
if (storedErr.IsError())
throw storedErr;
}
void
CPGPdiskDiskSet::WipeAllUsers()
{
CComboError storedErr;
// Save all paths.
CList<StringHolder> savedPaths;
try
{
CPGPdiskDisk *pDisk = mDisks.Head();
while (IsntNull(pDisk))
{
auto_ptr<StringHolder> pHolder(new StringHolder);
pHolder->path = pDisk->Path();
savedPaths.AddTail(pHolder.release());
pDisk = mDisks.Next(pDisk);
}
// Unmount all disks.
try
{
UnmountAll(TRUE);
}
catch (CComboError&) { }
// Wipe all PGPdisks. Skip over disks that fail to wipe.
StringHolder *pHolder = savedPaths.Head();
while (IsntNull(pHolder))
{
try
{
CPGPdiskDisk disk;
disk.Open(Context(), pHolder->path);
disk.WipeUsers();
}
catch (CComboError& caughtErr)
{
if (storedErr.IsntError())
storedErr = caughtErr;
}
pHolder = savedPaths.Next(pHolder);
}
if (storedErr.IsError())
throw storedErr;
savedPaths.EmptyWithDelete();
}
catch (CComboError&)
{
savedPaths.EmptyWithDelete();
throw;
}
}
CPGPdiskDisk *
CPGPdiskDiskSet::CreateDisk(
const char *path,
PGPUInt64 blocksDisk,
PGPdiskEncryptionAlgorithm algorithm,
const char *passphrase,
const char *userName,
const char *defaultRoot,
NewDiskStatusFuncType statusFunc,
void *userValue)
{
pgpAssertStrValid(path);
pgpAssertStrValid(passphrase);
pgpAssertStrValid(userName);
pgpAssertStrValid(defaultRoot);
pgpAssertAddrValid(statusFunc, NewDiskStatusFuncType);
auto_ptr<CPGPdiskDisk> pNewDisk(new CPGPdiskDisk);
pNewDisk->Create(Context(), path, blocksDisk, algorithm, passphrase,
userName, defaultRoot, statusFunc, userValue);
mDisks.AddTail(pNewDisk.get());
return pNewDisk.release();
}
CPGPdiskDisk *
CPGPdiskDiskSet::CreateDisk(
const char *path,
PGPUInt64 blocksDisk,
PGPdiskEncryptionAlgorithm algorithm,
const CPGPKey& key,
const char *defaultRoot,
NewDiskStatusFuncType statusFunc,
void *userValue)
{
pgpAssertStrValid(path);
pgpAssertStrValid(defaultRoot);
pgpAssertAddrValid(statusFunc, NewDiskStatusFuncType);
auto_ptr<CPGPdiskDisk> pNewDisk(new CPGPdiskDisk);
pNewDisk->Create(Context(), path, blocksDisk, algorithm, key,
defaultRoot, statusFunc, userValue);
mDisks.AddTail(pNewDisk.get());
return pNewDisk.release();
}
void
CPGPdiskDiskSet::Update()
{
Context()->UpdateDiskSet(*this);
}
CPGPdiskDiskSet::CPGPdiskDiskSet(const CPGPdiskDisk *pDisk) : mPContext(NULL)
{
pgpAssertAddrValid(pDisk, CPGPdiskDisk);
mPContext = pDisk->Context();
Singleton(pDisk);
}
CPGPdiskDisk *
CPGPdiskDiskSet::FindEqualDisk(const CPGPdiskDisk& disk) const
{
CPGPdiskDisk *pCurDisk = mDisks.Head();
// Search on operator==.
while (IsntNull(pCurDisk))
{
if (disk == *pCurDisk)
return pCurDisk;
pCurDisk = mDisks.Next(pCurDisk);
}
return NULL;
}
CPGPdiskDisk *
CPGPdiskDiskSet::FindExactDisk(const CPGPdiskDisk *pDisk) const
{
CPGPdiskDisk *pListDisk = mDisks.Head();
// Search on pointer address.
while (IsntNull(pDisk))
{
if (pDisk == pListDisk)
return pListDisk;
pListDisk = mDisks.Next(pListDisk);
}
return NULL;
}
void
CPGPdiskDiskSet::UnmountAux(CPGPdiskDisk *pDisk, PGPBoolean isForced)
{
// unmount all PGPdisks stacked on top of this one
CPGPdiskDisk *pClient = mDisks.Head();
while (IsntNull(pClient))
{
CString path(pClient->Path());
CString root(pDisk->Root());
if ((pClient != pDisk) &&
(path.Length() > root.Length()))
{
CString pathRoot;
path.Left(root.Length(), pathRoot);
if (pathRoot.CompareNoCase(root))
{
UnmountAux(pClient, isForced);
pClient = mDisks.Head();
continue;
}
}
pClient = mDisks.Next(pClient);
}
// unmount the PGPdisk
pDisk->Unmount(isForced);
mDisks.Remove(pDisk);
delete pDisk;
}
void
CPGPdiskDiskSet::UnmountAllAux(PGPBoolean timedOutOnly, PGPBoolean isForced)
{
CComboError error;
CPGPdiskDisk *pDisk = mDisks.Head();
// There are no disks to unmount wjb
if(IsNull(pDisk))
{
THROW_PGPERROR(kPGPClientError_DiskNotMounted);
}
while (IsntNull(pDisk))
{
if (timedOutOnly && !pDisk->HasInactivityTimedOut())
{
pDisk = mDisks.Next(pDisk);
continue;
}
try
{
UnmountAux(pDisk, isForced);
pDisk = mDisks.Head();
}
catch (CComboError& caughtErr)
{
// Give up on this disk.
if (error.IsntError())
error = caughtErr;
if (timedOutOnly)
pDisk->ResetTimedOut();
pDisk = mDisks.Next(pDisk);
}
}
RewindAllDiskIters();
if (error.IsError())
throw error;
}
void
CPGPdiskDiskSet::AddMounted(const CPGPdiskDiskSet& disksToAdd)
{
if (&disksToAdd == this)
return;
CPGPdiskDisk *pDisk = disksToAdd.mDisks.Head();
while (IsntNull(pDisk))
{
if (IsNull(FindEqualDisk(*pDisk)))
{
auto_ptr<CPGPdiskDisk> pNewDisk(new CPGPdiskDisk);
pNewDisk->AttachMounted(pDisk->Context(), pDisk->Path(),
pDisk->Root(), pDisk->DeviceName(), pDisk->IsReadOnly(),
pDisk->HasInactivityTimedOut());
mDisks.AddTail(pNewDisk.release());
}
pDisk = disksToAdd.mDisks.Next(pDisk);
}
RewindAllDiskIters();
}
void
CPGPdiskDiskSet::AddMounted(const CPGPdiskDisk& diskToAdd)
{
if (IsNull(FindEqualDisk(diskToAdd)))
{
auto_ptr<CPGPdiskDisk> pNewDisk(new CPGPdiskDisk);
pNewDisk->AttachMounted(diskToAdd.Context(), diskToAdd.Path(),
diskToAdd.Root(), diskToAdd.DeviceName(),
diskToAdd.IsReadOnly(), diskToAdd.HasInactivityTimedOut());
mDisks.AddTail(pNewDisk.release());
}
RewindAllDiskIters();
}
void
CPGPdiskDiskSet::Remove(const CPGPdiskDiskSet& disksToRemove)
{
if (&disksToRemove == this)
{
Empty();
return;
}
CPGPdiskDisk *pDisk = disksToRemove.mDisks.Head();
while (IsntNull(pDisk))
{
CPGPdiskDisk *pEqualDisk = FindEqualDisk(*pDisk);
if (IsntNull(pEqualDisk))
{
mDisks.Remove(pEqualDisk);
delete pEqualDisk;
}
pDisk = disksToRemove.mDisks.Next(pDisk);
}
RewindAllDiskIters();
}
void
CPGPdiskDiskSet::Remove(const CPGPdiskDisk& diskToRemove)
{
CPGPdiskDisk *pEqualDisk = FindEqualDisk(diskToRemove);
if (IsntNull(pEqualDisk))
{
mDisks.Remove(pEqualDisk);
delete pEqualDisk;
}
RewindAllDiskIters();
}
void
CPGPdiskDiskSet::Singleton(const CPGPdiskDisk *pDisk)
{
pgpAssert(pDisk->IsMounted());
Empty();
auto_ptr<CPGPdiskDisk> pNewDisk(new CPGPdiskDisk);
pNewDisk->AttachMounted(pDisk->Context(), pDisk->Path(), pDisk->Root(),
pDisk->DeviceName(), pDisk->IsReadOnly(),
pDisk->HasInactivityTimedOut());
mDisks.AddTail(pNewDisk.release());
RewindAllDiskIters();
}
void
CPGPdiskDiskSet::Empty()
{
mDisks.EmptyWithDelete();
RewindAllDiskIters();
}
void
CPGPdiskDiskSet::RewindAllDiskIters()
{
CPGPdiskDiskIter *pDiskIter = mDiskIters.Head();
while (IsntNull(pDiskIter))
{
pDiskIter->Rewind();
pDiskIter = mDiskIters.Next(pDiskIter);
}
}
void
CPGPdiskDiskSet::RegisterDiskIter(CPGPdiskDiskIter *pDiskIter) const
{
pgpAssertAddrValid(pDiskIter, CPGPdiskDiskIter);
mDiskIters.AddTail(pDiskIter);
}
void
CPGPdiskDiskSet::DeregisterDiskIter(CPGPdiskDiskIter *pDiskIter) const
{
pgpAssertAddrValid(pDiskIter, CPGPdiskDiskIter);
mDiskIters.Remove(pDiskIter);
}
// Class CPGPdiskDiskIter functions
CPGPdiskDiskIter::CPGPdiskDiskIter(const CPGPdiskDiskSet *pDiskSet) :
CIter<CPGPdiskDisk>(&pDiskSet->mDisks), mPDiskSet(pDiskSet)
{
pgpAssertAddrValid(pDiskSet, CPGPdiskDiskSet);
pDiskSet->RegisterDiskIter(this);
}
CPGPdiskDiskIter::~CPGPdiskDiskIter()
{
DiskSet()->DeregisterDiskIter(this);
}
CPGPdiskDisk *
CPGPdiskDiskIter::SearchOnPath(const char *path)
{
pgpAssertStrValid(path);
Rewind();
CPGPdiskDisk *pDisk;
while (TRUE)
{
pDisk = Next();
if (IsNull(pDisk))
break;
if (pDisk->ComparePaths(path))
break;
}
return pDisk;
}
CPGPdiskDisk *
CPGPdiskDiskIter::SearchOnRoot(const char *root)
{
pgpAssertStrValid(root);
Rewind();
CPGPdiskDisk *pDisk;
while (TRUE)
{
pDisk = Next();
if (IsNull(pDisk))
break;
if (pDisk->CompareRoots(root))
break;
}
return pDisk;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -