📄 ccommandclaimer.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: CCommandClaimer.cpp,v 1.7 2002/08/06 20:09:23 dallen Exp $
____________________________________________________________________________*/
#include "pgpClassesConfig.h"
#include "CSharedMemory.h"
#include "CWindow.h"
#include "UMath.h"
#include "CCRC32.h"
#include "CCommandClaimer.h"
_USING_PGP
_UNNAMED_BEGIN
// Constants
const char *kCommandMutexName = "PGPdiskUI Commands Mutex";
const char *kSharedCommandsName = "PGPdiskUI Commands Array";
_UNNAMED_END
// Types
struct CCommandClaimer::CCCommandInfo
{
PGPBoolean inUse;
CCommandClaimer::CommandID commandID;
PGPUInt32 pathCRC;
PGPUInt32 threadID;
};
// Class CCommandClaimer member functions
void
CCommandClaimer::ClaimCommand(CommandID commandID, const char *pathOrRoot)
{
// Calculate CRC of path.
PGPUInt32 pathCRC = (IsntNull(pathOrRoot) ?
MakeCRCFromString(pathOrRoot) : 0);
// Examine existing commands.
mCommandsMutex.Enter();
try
{
CCCommandInfo curCmd = {TRUE, commandID, pathCRC,
GetCurrentThreadId()};
CCCommandInfo *mPCI = static_cast<CCCommandInfo *>(
mCommands.Get());
PGPBoolean foundExisting = FALSE;
PGPUInt32 i;
// Search for similar instance of this command. Show one if found.
for (i = 0; i < kMaxNumCommands; i++)
{
if (mPCI[i].inUse && AreCommandsSimilar(mPCI[i], curCmd))
{
// Found an existing instance, show it.
PGPBoolean showedWindow = FALSE;
EnumThreadWindows(mPCI[i].threadID, ShowFirstVisibleWndFunc,
reinterpret_cast<LPARAM>(&showedWindow));
if (showedWindow)
{
foundExisting = TRUE;
break;
}
else
{
mPCI[i].inUse = FALSE;
}
}
}
// If found existing instance, fail silently, otherwise create one.
if (foundExisting)
THROW_PGPERROR(kPGPError_UserAbort);
for (i = 0; i < kMaxNumCommands; i++)
{
if (!mPCI[i].inUse)
{
mPCI[i] = curCmd;
break;
}
}
mCommandsMutex.Leave();
}
catch (CComboError&)
{
mCommandsMutex.Leave();
throw;
}
}
void
CCommandClaimer::ReleaseCommand(CommandID commandID, const char *pathOrRoot)
{
// Calculate CRC of path.
PGPUInt32 pathCRC = (IsntNull(pathOrRoot) ?
MakeCRCFromString(pathOrRoot) : 0);
// Examine existing commands.
mCommandsMutex.Enter();
try
{
CCCommandInfo *mPCI = static_cast<CCCommandInfo *>(
mCommands.Get());
PGPBoolean foundExisting = FALSE;
PGPUInt32 threadID = GetCurrentThreadId();
PGPUInt32 i;
// Search for exact instance of this command and wipe it.
for (i = 0; i < kMaxNumCommands; i++)
{
if (mPCI[i].inUse)
{
if ((mPCI[i].commandID == commandID) &&
(mPCI[i].pathCRC == pathCRC) &&
(mPCI[i].threadID == threadID))
{
mPCI[i].inUse = FALSE;
foundExisting = TRUE;
break;
}
}
}
if (!foundExisting)
THROW_PGPERROR(kPGPError_ItemNotFound);
mCommandsMutex.Leave();
}
catch (CComboError&)
{
mCommandsMutex.Leave();
throw;
}
}
void
CCommandClaimer::Startup()
{
mCommandsMutex.CreateAttach(kCommandMutexName);
mCommandsMutex.Enter();
try
{
mCommands.CreateAttach(kSharedCommandsName, kMaxNumCommands *
sizeof(CCCommandInfo));
mCommandsMutex.Leave();
}
catch (CComboError&)
{
mCommandsMutex.Leave();
throw;
}
}
PGPBoolean
CCommandClaimer::AreCommandsSimilar(
const CCCommandInfo& cmd1,
const CCCommandInfo& cmd2) const
{
PGPBoolean areSimilar = FALSE;
// Compare the commands.
switch (cmd1.commandID)
{
case kMountDisk:
case kUnmountDisk:
case kEditDisk:
case kInvokeDeleteHook:
// 'op2' must be identical.
if (cmd1.commandID != cmd2.commandID)
break;
// Also the paths must match.
if (cmd1.pathCRC == cmd2.pathCRC)
areSimilar = TRUE;
break;
default:
// All others match only if the command IDs are equal.
if (cmd1.commandID == cmd2.commandID)
areSimilar = TRUE;
break;
}
return areSimilar;
}
PGPUInt32
CCommandClaimer::MakeCRCFromString(const char *str) const
{
pgpAssertStrValid(str);
// Pad path to dword size beforehand.
PGPUInt32 sizeString = strlen(str) + 1;
CArray<PGPUInt32> paddedString(UMath::CeilDiv(sizeString,
sizeof(PGPUInt32)));
paddedString.Wipe();
strcpy(reinterpret_cast<char *>(paddedString.Get()), str);
// Calculate CRC of path.
CCRC32 stringCRC;
stringCRC.Continue(paddedString.Get(), paddedString.Size());
return stringCRC.GetCRC();
}
BOOL
CALLBACK
CCommandClaimer::ShowFirstVisibleWndFunc(HWND hwnd, LPARAM lParam)
{
CWindow wnd(hwnd);
if (wnd.IsWindowVisible())
{
wnd.SetForegroundWindow();
*reinterpret_cast<PGPBoolean *>(lParam) = TRUE;
return FALSE;
}
else
{
return TRUE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -