📄 cpgpdiskhandlerimp.cpp
字号:
mPGPdiskListLock.StopReading();
return pDisk;
}
CPGPdisk *
CPGPdiskHandlerImp::GetPGPdiskByDeviceName(const char *deviceName) const
{
pgpAssertStrValid(deviceName);
CPGPdisk *pDisk = NULL;
CString cdeviceName(deviceName);
if (cdeviceName.Status().IsntError())
{
mPGPdiskListLock.StartReading();
pDisk = mPGPdiskList.Head();
while (IsntNull(pDisk))
{
if (cdeviceName == pDisk->DeviceName())
break;
pDisk = mPGPdiskList.Next(pDisk);
}
mPGPdiskListLock.StopReading();
}
return pDisk;
}
CComboError
CPGPdiskHandlerImp::UnmountPGPdiskAux(CPGPdisk *pDisk, PGPBoolean isForced)
{
pgpAssertAddrValid(pDisk, CPGPdisk);
pgpAssert(pDisk->IsMounted());
CComboError error;
// unmount all PGPdisks stacked on this one
CPGPdisk *pClient = mPGPdiskList.Head();
while (IsntNull(pClient))
{
CString path(pClient->Path());
CString pathRoot;
CString root(pDisk->Root());
if (path.Status().IsntError() &&
pathRoot.Status().IsntError() &&
root.Status().IsntError() &&
(pDisk != pClient) &&
(path.Length() > root.Length()) &&
path.Left(root.Length(), pathRoot).IsntError() &&
pathRoot.CompareNoCase(root) &&
UnmountPGPdiskAux(pClient, isForced).IsntError())
{
pClient = mPGPdiskList.Head();
}
else
{
pClient = mPGPdiskList.Next(pClient);
}
}
// Peform the unmount.
if (error.IsntError())
error = pDisk->Unmount(isForced);
if (error.IsntError())
{
// De-list and delete the PGPdisk object.
mPGPdiskList.Remove(pDisk);
mPGPdiskAllocator.Free(pDisk);
}
return error;
}
CComboError
CPGPdiskHandlerImp::MountPGPdiskCallback(MountTaskInfo *pMTI)
{
pgpAssertAddrValid(pMTI, MountTaskInfo);
CComboError error;
// Check if we've already mounted this PGPdisk.
if (IsFileAMountedPGPdisk(pMTI->path))
error.pgpErr = kPGPClientError_DiskAlreadyMounted;
if (error.IsntError())
{
// Create a new PGPdisk object.
CPGPdisk *pDisk;
CString deviceName;
error = deviceName.Status();
if (error.IsntError())
error = ConstructDeviceName(deviceName);
if (error.IsntError())
error = mPGPdiskAllocator.Allocate(pDisk);
if (error.IsntError())
{
error = pDisk->Status();
if (error.IsntError())
{
// Mount the PGPdisk.
error = pDisk->Mount(pMTI->path, pMTI->root, deviceName,
pMTI->algorithm, pMTI->exportedContext,
pMTI->sizeContext, pMTI->firstDataBlock,
pMTI->numDataBlocks, GetPlatformIoHandlerFunc(),
pMTI->procId, pMTI->isReadOnly);
}
if (error.IsntError())
{
// Add the PGPdisk to the list.
mPGPdiskListLock.StartWriting();
mPGPdiskList.AddHead(pDisk);
mPGPdiskListLock.StopWriting();
strcpy(pMTI->deviceName, deviceName);
}
if (error.IsError())
mPGPdiskAllocator.Free(pDisk);
}
}
pgpAssert(pMTI->header.trueIfSync);
return error;
}
CComboError
CPGPdiskHandlerImp::UnmountPGPdiskCallback(UnmountTaskInfo *pUTI)
{
pgpAssertAddrValid(pUTI, UnmountTaskInfo);
pgpAssert(pUTI->header.trueIfSync);
CComboError error;
mPGPdiskListLock.StartWriting();
// Find the PGPdisk in question.
CPGPdisk *pDisk = mPGPdiskList.Head();
while (IsntNull(pDisk))
{
CString root(pDisk->Root());
if (root.Status().IsntError())
{
if (root.CompareNoCase(pUTI->root))
break;
}
pDisk = mPGPdiskList.Next(pDisk);
}
if (IsNull(pDisk))
error.pgpErr = kPGPError_ItemNotFound;
if (error.IsntError())
error = UnmountPGPdiskAux(pDisk, pUTI->isForced);
mPGPdiskListLock.StopWriting();
return error;
}
CComboError
CPGPdiskHandlerImp::UnmountAllPGPdisksCallback(UnmountAllTaskInfo *pUATI)
{
pgpAssertAddrValid(pUATI, UnmountAllTaskInfo);
pgpAssert(pUATI->header.trueIfSync);
CComboError error;
mPGPdiskListLock.StartWriting();
CPGPdisk *pDisk = mPGPdiskList.Head();
// Unmount all PGPdisks, skipping those we can't unmount.
while (IsntNull(pDisk))
{
CComboError tempErr = UnmountPGPdiskAux(pDisk, pUATI->isForced);
if (tempErr.IsError())
{
error = tempErr;
pDisk = mPGPdiskList.Next(pDisk);
}
else
{
pDisk = mPGPdiskList.Head();
}
}
mPGPdiskListLock.StopWriting();
if (NumPGPdisks() > 0)
return error;
else
return CComboError();
}
void
CPGPdiskHandlerImp::EverySecondThreadCallback(EverySecondTaskInfo *pESTI)
{
pgpAssertAddrValid(pESTI, EverySecondTaskInfo);
static PGPUInt32 lastToggleTime = 0;
static PGPUInt32 lastVerifyTime = 0;
// Set toggle/verify time flags.
PGPBoolean shouldToggleContexts = FALSE;
PGPBoolean shouldVerifyContexts = FALSE;
if (lastToggleTime++ > ContextToggleSeconds)
{
lastToggleTime = 0;
shouldToggleContexts = TRUE;
}
if (lastVerifyTime++ > ContextVerifySeconds)
{
lastVerifyTime = 0;
shouldVerifyContexts = TRUE;
}
// If we are in 'unmount all mode', keep trying to unmount all PGPdisks.
if (mInUnmountAllMode)
{
CComboError error;
// We're in thread context, fake an 'UnmountAllTask' callback.
UnmountAllTaskInfo UATI;
UATI.header.trueIfSync = TRUE;
UATI.isForced = FALSE;
error = UnmountAllPGPdisksCallback(&UATI);
if (error.IsntError())
mInUnmountAllMode = FALSE;
}
// Perform various tasks on each PGPdisk.
mPGPdiskListLock.StartReading();
CPGPdisk *pDisk = mPGPdiskList.Head();
while (IsntNull(pDisk))
{
if (shouldToggleContexts)
pDisk->FlipContexts();
if (shouldVerifyContexts)
{
CComboError error = pDisk->ValidateContexts();
// Forcibly unmount PGPdisk if cipher context is invalid.
if (error.IsError())
{
pgpAssert("PGPdisk cipher context corrupted!");
UnmountPGPdiskAux(pDisk, TRUE);
}
}
pDisk = mPGPdiskList.Next(pDisk);
}
mPGPdiskListLock.StopReading();
}
void
CPGPdiskHandlerImp::PGPdiskTaskCallbackAux(TaskInfoHeader *pTIH)
{
pgpAssertAddrValid(pTIH, TaskInfoHeader);
CComboError error;
switch (pTIH->task)
{
case kMountTask:
error = MountPGPdiskCallback(
reinterpret_cast<MountTaskInfo *>(pTIH));
break;
case kUnmountTask:
error = UnmountPGPdiskCallback(
reinterpret_cast<UnmountTaskInfo *>(pTIH));
break;
case kUnmountAllTask:
error = UnmountAllPGPdisksCallback(
reinterpret_cast<UnmountAllTaskInfo *>(pTIH));
break;
case kEverySecondTask:
EverySecondThreadCallback(
reinterpret_cast<EverySecondTaskInfo *>(pTIH));
break;
default:
pgpAssert(FALSE);
error.pgpErr = kPGPError_BadParams;
break;
}
if (pTIH->trueIfSync)
pTIH->error = error;
else
delete pTIH;
}
void
_cdecl
CPGPdiskHandlerImp::PGPdiskTaskCallback(void *refPtr)
{
TaskInfoHeader *pTIH = static_cast<TaskInfoHeader *>(refPtr);
pgpAssertAddrValid(pTIH, TaskInfoHeader);
CPGPdiskHandlerImp *pImp = static_cast<CPGPdiskHandlerImp *>(
pTIH->origThis);
pgpAssertAddrValid(pImp, CPGPdiskHandlerImp);
pImp->PGPdiskTaskCallbackAux(pTIH);
}
CComboError
CPGPdiskHandlerImp::PerformPGPdiskTask(
TaskInfoHeader *pTIH,
HandlerTask task)
{
CComboError error;
// Create worker thread on demand, but leave it running.
if (!mWorkerThreadCreated)
error = CreateWorkerThread();
if (error.IsntError())
{
pgpAssertAddrValid(pTIH, TaskInfoHeader);
pTIH->origThis = this;
pTIH->trueIfSync = TRUE;
pTIH->task = task;
error = mTaskThread.PerformSyncCallback(PGPdiskTaskCallback, pTIH);
if (error.IsntError())
error = pTIH->error;
}
return error;
}
CComboError
CPGPdiskHandlerImp::SchedulePGPdiskTask(
TaskInfoHeader *pTIH,
HandlerTask task)
{
pgpAssertAddrValid(pTIH, TaskInfoHeader);
CComboError error;
// Create worker thread on demand, but leave it running.
if (!mWorkerThreadCreated)
error = CreateWorkerThread();
if (error.IsntError())
{
pTIH->origThis = this;
pTIH->trueIfSync = FALSE;
pTIH->task = task;
error = mTaskThread.PerformAsyncCallback(PGPdiskTaskCallback, pTIH);
}
return error;
}
void
CPGPdiskHandlerImp::EverySecondTimerCallbackAux()
{
// Execute this command in thread context.
EverySecondTaskInfo *pESTI = new EverySecondTaskInfo;
if (IsntNull(pESTI))
{
CComboError error = SchedulePGPdiskTask(&pESTI->header,
kEverySecondTask);
if (error.IsError())
delete pESTI;
}
}
void
_cdecl
CPGPdiskHandlerImp::EverySecondTimerCallback(void *refPtr)
{
CPGPdiskHandlerImp *pImp = static_cast<CPGPdiskHandlerImp *>(refPtr);
pgpAssertAddrValid(pImp, CPGPdiskHandlerImp);
pImp->EverySecondTimerCallbackAux();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -