📄 cpgpdiskdiskimpwin32.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: CPGPdiskDiskImpWin32.cpp,v 1.20 2002/10/31 05:17:03 wjb Exp $
____________________________________________________________________________*/
#include "pgpClassesConfig.h"
#include <dbt.h>
#include <shlobj.h>
#include "CFile.h"
#include "UString.h"
#include "UUnicode.h"
#include "CPath.h"
#include "CRegistryKey.h"
#include "UDynLink.h"
#include "UUnicode.h"
#include "UWinVersion.h"
#include "pgpClientErrors.h"
#include "CPGPclPrefs.h"
#include "CPGPdiskContext.h"
#include "CCipherContext.h"
#include "DriverAPI.h"
#include "FileSys.h"
#include "CPGPdiskDiskImpWin32.h"
#include "pgplnlib.h"
_USING_PGP
_UNNAMED_BEGIN
// Constants
const HKEY kRegistryBitBucketRoot = HKEY_LOCAL_MACHINE;
const char *kRegistryBitBucketSection =
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\BitBucket";
_UNNAMED_END
// Class CPGPdiskDiskImpWin32 member functions
PGPBoolean
CPGPdiskDiskImpWin32::ComparePaths(const char *path) const
{
CPath cpath(path);
try {
cpath.Canonicalize(kPGPdiskFileExtension);
} catch (CComboError&) { }
return CPGPdiskDiskImp::ComparePaths(cpath);
}
PGPBoolean
CPGPdiskDiskImpWin32::CompareRoots(const char *root) const
{
CPath croot(root);
try {
croot.Canonicalize();
} catch (CComboError&) { }
// end in slash regardless of canonicalization
croot.EndInSlash();
return CPGPdiskDiskImp::CompareRoots(croot);
}
void
CPGPdiskDiskImpWin32::CheckFilesystemCompatibility(
const CCipherContext& cipher,
PGPBoolean readOnly) const
{
pgpAssert(mDiskFile.IsOpened());
pgpAssert(cipher.IsInitialized());
// Read in the boot block.
CArray<PGPUInt8> bootBlock(kPGPdiskBlockSize);
PGPUInt64 firstByteData = mHeaders.NumHeaderBlocks() *
kPGPdiskBlockSize;
mDiskFile.Read(bootBlock.Get(), firstByteData, kPGPdiskBlockSize);
// Decrypt it.
cipher.DecryptCFB(0, 1, bootBlock.Get(), bootBlock.Get());
// Is it NTFS?
PGPBoolean isNTFS = (strncmp(reinterpret_cast<const char *>(
&bootBlock[FileSys::kNTFSOffset]), FileSys::kNTFSIdStr,
strlen(FileSys::kNTFSIdStr)) == 0);
// Is it FAT32?
PGPBoolean isFAT32 = (strncmp(reinterpret_cast<const char *>(
&bootBlock[FileSys::kFat32Offset]), FileSys::kFat32IdStr,
strlen(FileSys::kFat32IdStr)) == 0);
// If either, perform checks.
if (isNTFS)
{
if (UWinVersion::IsWin95Compatible())
{
// check for 3rd-party NTFS driver, else fail
try
{
CPath ntfsDrv;
PGPUInt32 result = GetEnvironmentVariable("WINDIR",
ntfsDrv.GetBuffer(kPGPdiskMaxPathLength),
kPGPdiskMaxPathLength);
ntfsDrv.ReleaseBuffer();
if (result == 0)
THROW_PGPERROR(kPGPError_OutOfMemory);
ntfsDrv.EndInSlash();
ntfsDrv.Append("SYSTEM\\IOSUBSYS\\NTFSFSD.VXD");
ntfsDrv.Canonicalize();
}
catch (CComboError&)
{
THROW_PGPERROR(kPGPClientError_DiskTriedNTFSOnWin95);
}
}
if (readOnly)
{
THROW_PGPERROR(kPGPClientError_DiskTriedReadOnlyNTFS);
}
}
else if (isFAT32)
{
// check for 3rd-party FAT32 driver, else fail
if (UWinVersion::IsWinNT4Compatible() &&
!UWinVersion::IsWin2000Compatible())
{
try
{
CPath fat32Drv;
PGPUInt32 result = GetEnvironmentVariable("SYSTEMROOT",
fat32Drv.GetBuffer(kPGPdiskMaxPathLength),
kPGPdiskMaxPathLength);
fat32Drv.ReleaseBuffer();
if (result == 0)
THROW_PGPERROR(kPGPError_OutOfMemory);
fat32Drv.EndInSlash();
fat32Drv.Append("SYSTEM32\\DRIVERS\\FAT32.SYS");
fat32Drv.Canonicalize();
}
catch (CComboError&)
{
THROW_PGPERROR(kPGPClientError_DiskTriedFAT32OnNT4);
}
}
}
}
BOOL IsWindowsXPOrGreater()
{
OSVERSIONINFOEXA osvi = {0};
osvi.dwOSVersionInfoSize = sizeof(osvi);
if (!GetVersionExA((OSVERSIONINFOA*)&osvi))
{
// If it failed, it must be a down level platform
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
GetVersionExA((OSVERSIONINFOA*)&osvi);
}
return (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId &&
((osvi.dwMajorVersion > 5) ||
(osvi.dwMajorVersion == 5 && (osvi.dwMinorVersion > 0 ||
(osvi.dwMinorVersion == 0 && LOWORD(osvi.dwBuildNumber) > 2195)))));
}
void
CPGPdiskDiskImpWin32::Mount(
const CPGPdiskContext *pContext,
const char *path,
const CCipherContext &cipher,
const char *root,
PGPBoolean readOnly)
{
// PGPclWindowsGenus genus;
CPath croot(root);
CPath cpath(path);
if(!PGPlnPGPdiskEnabled())
THROW_PGPERROR(kPGPError_UserAbort);
croot.EndInSlash();
cpath.Canonicalize(kPGPdiskFileExtension);
if (CFile::IsFileInUseByWriter(cpath))
THROW_PGPERROR(kPGPClientError_DiskDiskAlreadyInUse);
if (UWinVersion::IsWinNT4Compatible() && cpath.IsCompressed())
{
try
{
CFile file;
file.Open(cpath);
file.SetIsCompressed(FALSE);
file.Close();
}
catch (CComboError&)
{
THROW_PGPERROR(kPGPClientError_DiskCantRemoveCompression);
}
}
CPGPdiskDiskImp::Mount(pContext, cpath, cipher, croot, readOnly);
croot.BroadcastDriveMessage(DBT_DEVICEARRIVAL);
/*
if(IsWindowsXPOrGreater())
{
// Do nothing. XP explorer has race condition problem for post mount shell cmds
;
}
else
{
if (croot.IsPlainLocalRoot())
SHChangeNotify(SHCNE_DRIVEADD, SHCNF_PATH, croot, NULL);
else
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH, croot, NULL);
PGPclGetWindowsVersion (NULL, &genus, NULL);
if (genus == kPGPclWindowsGenusMillenium)
{
// WinME automatically puts up an explorer view
;
}
else
{
try
{
if (pContext->PGPclPrefs().GetBoolean(kPGPPrefDiskBrowseAfterMount))
croot.Browse();
}
catch (CComboError&) { }
}
}*/
}
void
CPGPdiskDiskImpWin32::Unmount(PGPBoolean isForced)
{
pgpAssert(IsMounted());
CPath savedRoot(Root());
if (UWinVersion::IsWinNT4Compatible())
if (savedRoot.IsPlainLocalRoot()) // Only drive letters get these
savedRoot.BroadcastDriveMessage(DBT_DEVICEREMOVEPENDING);
CPGPdiskDiskImp::Unmount(isForced);
if (savedRoot.IsPlainLocalRoot())
SHChangeNotify(SHCNE_DRIVEREMOVED, SHCNF_PATH, savedRoot, NULL);
else
SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_PATH, savedRoot, NULL);
if (UWinVersion::IsWinNT4Compatible())
if (savedRoot.IsPlainLocalRoot()) // Only drive letters get these
savedRoot.BroadcastDriveMessage(DBT_DEVICEREMOVECOMPLETE);
if (UWinVersion::IsWin95Compatible())
{
try
{
CString bitBucketValue;
bitBucketValue.Assign(toupper(savedRoot.GetDriveLet()));
CRegistryKey bitBucketKey;
bitBucketKey.Open(kRegistryBitBucketRoot,
kRegistryBitBucketSection, KEY_ALL_ACCESS);
bitBucketKey.DeleteValue(bitBucketValue);
bitBucketKey.Close();
}
catch (CComboError&) { }
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -