📄 cpgpdiskappwinutils.cpp
字号:
//////////////////////////////////////////////////////////////////////////////
// CPGPdiskAppWinutils.cpp
//
// Wrapper functions around useful system calls.
//////////////////////////////////////////////////////////////////////////////
// $Id: CPGPdiskAppWinutils.cpp,v 1.13 1998/12/15 01:25:03 nryan Exp $
// Copyright (C) 1998 by Network Associates, Inc.
// All rights reserved.
#include "StdAfx.h"
#include "Required.h"
#include "DriverComm.h"
#include "PGPdiskPrefs.h"
#include "PGPdiskVersion.h"
#include "StringAssociation.h"
#include "UtilityFunctions.h"
#include "Win32Utils.h"
#include "CMainDialog.h"
#include "CPGPdiskApp.h"
#include "CPGPdiskAppWinutils.h"
#include "Globals.h"
#include "PGPdisk.h"
#include "Resource.h"
////////////
// Constants
////////////
const PGPUInt32 kRegTextInc = 16;
const PGPUInt32 kLicenseToGap = 8;
////////////////////////////////////
// File and Volume Utility Functions
////////////////////////////////////
// AreAnyDriveLettersFree returns TRUE if there are any drive letters free
// for mounting PGPdisks, otherwise FALSE.
PGPBoolean
CPGPdiskApp::AreAnyDriveLettersFree()
{
PGPBoolean anyFree = FALSE;
PGPUInt8 i;
PGPUInt32 drives;
// Fill the combo box with available drive letters.
drives = GetLogicalDrives();
for (i = 2; i < kMaxDrives; i++)
{
if (!(drives & (1 << i)) && !IsDriveNetworkMapped(i))
{
anyFree = TRUE;
break;
}
}
return anyFree;
}
// IsDirectoryValid returns TRUE if the specified directory exists, FALSE
// otherwise.
PGPBoolean
CPGPdiskApp::IsDirectoryValid(LPCSTR path)
{
PGPUInt32 attribs;
pgpAssertStrValid(path);
attribs = GetFileAttributes(path);
if (attribs == 0xFFFFFFFF)
return FALSE;
else
return (attribs & FILE_ATTRIBUTE_DIRECTORY ? TRUE : FALSE);
}
// IsFileValid returns TRUE if the specified file exists, FALSE otherwise.
PGPBoolean
CPGPdiskApp::IsFileValid(LPCSTR path)
{
PGPUInt32 attribs;
pgpAssertStrValid(path);
attribs = GetFileAttributes(path);
if (attribs == 0xFFFFFFFF)
return FALSE;
else
return (attribs & FILE_ATTRIBUTE_DIRECTORY ? FALSE : TRUE);
}
// IsPathValid returns TRUE if the specified path exists, FALSE otherwise.
PGPBoolean
CPGPdiskApp::IsPathValid(LPCSTR path)
{
return (IsFileValid(path) || IsDirectoryValid(path));
}
// IsVolumeValid returns TRUE if the specified volume is valid, FALSE
// otherwise.
PGPBoolean
CPGPdiskApp::IsVolumeValid(PGPUInt8 drive)
{
CString root;
pgpAssert(IsLegalDriveNumber(drive));
return ((GetLogicalDrives() & (1 << drive)) ? TRUE : FALSE);
}
// IsVolumeFormatted returns TRUE if the specified volume is formatted, FALSE
// otherwise.
PGPBoolean
CPGPdiskApp::IsVolumeFormatted(PGPUInt8 drive)
{
CString root;
pgpAssert(IsLegalDriveNumber(drive));
if (MakeRoot(drive, &root).IsntError())
{
return GetVolumeInformation(root, NULL, 0, NULL, NULL, NULL, NULL, 0);
}
else
{
return TRUE;
}
}
// IsDirectoryReadOnly returns TRUE if the directory specified by path is
// read-only, FALSE otherwise.
PGPBoolean
CPGPdiskApp::IsDirectoryReadOnly(LPCSTR path)
{
CString dir, csPath, temp;
DualErr derr;
PGPBoolean isDirReadOnly;
PGPUInt32 result;
pgpAssertStrValid(path);
// Attempt to create a temporary file.
try
{
csPath = path;
dir = csPath.Left(csPath.ReverseFind('\\') + 1);
result = GetTempFileName(dir, "pgp", 0,
temp.GetBuffer(kMaxStringSize));
temp.ReleaseBuffer();
}
catch (CMemoryException *ex)
{
derr = DualErr(kPGDMinorError_OutOfMemory);
ex->Delete();
}
// If failure, we assume read-only.
if (derr.IsntError())
{
if (result == 0)
{
isDirReadOnly = TRUE;
}
else
{
isDirReadOnly = FALSE;
DeleteFile(temp);
}
}
if (derr.IsntError())
return isDirReadOnly;
else
return TRUE;
}
// IsFileReadOnly returns TRUE if the file specified by path is read-only,
// FALSE otherwise.
PGPBoolean
CPGPdiskApp::IsFileReadOnly(LPCSTR path)
{
DualErr derr;
File theFile;
PGPUInt8 firstByte = 0;
PGPUInt64 length;
// Open a read/write handle to the file and try to write a byte. If
// anything fails, we aren't going to be doing any writing. Handle
// 0-length files as a special case.
derr = theFile.Open(path, kOF_MustExist);
if (derr.IsntError())
{
derr = theFile.GetLength(&length);
}
if (derr.IsntError())
{
if (length > 0)
derr = theFile.Read((PGPUInt8 *) &firstByte, 0, 1);
}
if (derr.IsntError())
{
derr = theFile.Write((PGPUInt8 *) &firstByte, 0, 1);
}
if (derr.IsntError())
{
if (length == 0)
theFile.SetLength(0);
}
if (theFile.Opened())
theFile.Close();
return derr.IsError();
}
// IsFileInUseByReader returns TRUE if someone has opened the specified file
// with read access, FALSE otherwise.
PGPBoolean
CPGPdiskApp::IsFileInUseByReader(LPCSTR path)
{
File existingFile;
DualErr derr;
pgpAssertStrValid(path);
derr = existingFile.Open(path,
kOF_ReadOnly | kOF_DenyRead | kOF_MustExist);
if (existingFile.Opened())
{
existingFile.Close();
}
return derr.IsError();
}
// IsFileInUseByWriter returns TRUE if someone has opened the specified file
// with write access, FALSE otherwise.
PGPBoolean
CPGPdiskApp::IsFileInUseByWriter(LPCSTR path)
{
File existingFile;
DualErr derr;
pgpAssertStrValid(path);
derr = existingFile.Open(path,
kOF_ReadOnly | kOF_DenyWrite | kOF_MustExist);
if (existingFile.Opened())
{
existingFile.Close();
}
return derr.IsError();
}
// IsFileInUseByWriter returns TRUE if someone has opened the specified file,
// FALSE otherwise.
PGPBoolean
CPGPdiskApp::IsFileInUse(LPCSTR path)
{
return (IsFileInUseByReader(path) || IsFileInUseByWriter(path));
}
// BruteForceTestIfEnoughSpace tests if the desired directory has enough
// space to hold a file of the specified size. It does this by creating a
// temporary file of the desired size.
DualErr
CPGPdiskApp::BruteForceTestIfEnoughSpace(
LPCSTR dir,
PGPUInt32 kbLength,
PGPBoolean *isEnoughSpace)
{
DualErr derr;
try
{
File tempFile;
CString tempPath;
DualErr setLengthErr;
PGPBoolean createdTemp = FALSE;
PGPUInt64 tempSize;
pgpAssertStrValid(dir);
pgpAssertAddrValid(isEnoughSpace, PGPBoolean);
// Open a temporary file in the desired directory.
GetTempFileName(dir, "pgp", 0, tempPath.GetBuffer(kMaxStringSize));
tempPath.ReleaseBuffer();
derr = tempFile.Open(tempPath, kOF_Trunc);
createdTemp = derr.IsntError();
// Set the file to the desired length.
if (derr.IsntError())
{
setLengthErr = tempFile.SetLength(kbLength * kBytesPerKb);
// Did we fail to set the size of the file?
if (setLengthErr.IsError())
{
(* isEnoughSpace) = FALSE;
}
}
// Verify the set succeeded by closing and re-opening the file.
if (derr.IsntError() && setLengthErr.IsntError())
{
tempFile.Close();
derr = tempFile.Open(tempPath, kOF_MustExist);
}
if (derr.IsntError() && setLengthErr.IsntError())
{
derr = tempFile.GetLength(&tempSize);
}
// Do the sizes match?
if (derr.IsntError() && setLengthErr.IsntError())
{
(* isEnoughSpace) = (tempSize == kbLength*kBytesPerKb);
}
if (tempFile.Opened())
{
tempFile.Close();
}
if (createdTemp)
{
DeleteFile(tempPath);
}
}
catch (CMemoryException *ex)
{
ex->Delete();
derr = DualErr(kPGDMinorError_OutOfMemory);
}
return derr;
}
// HowMuchFreeSpace returns the amount of free space on the specified drive,
// in bytes.
DualErr
CPGPdiskApp::HowMuchFreeSpace(LPCSTR path, PGPUInt64 *bytesFree)
{
CString root;
DualErr derr;
ULARGE_INTEGER freeAvail;
pgpAssertAddrValid(bytesFree, PGPUInt64);
// We must pass the root, not the path, to the system.
derr = GetRoot(path, &root);
// There are two different functions for OSR1 and OSR2.
if (derr.IsntError())
{
if (IsWin95OSR2CompatibleMachine() || IsWinNT4CompatibleMachine())
{
PGPUInt32 result;
ULARGE_INTEGER freeBytes, totalBytes;
result = GetDiskFreeSpaceEx(root, &freeAvail, &totalBytes,
&freeBytes);
if (!result)
{
derr = DualErr(kPGDMinorError_GetFreeSpaceFailed,
GetLastError());
}
}
else
{
unsigned long spc, bps, freeClust, totalClust;
if (!::GetDiskFreeSpace(root, &spc, &bps, &freeClust,
&totalClust))
{
derr = DualErr(kPGDMinorError_GetFreeSpaceFailed,
GetLastError());
}
if (derr.IsntError())
{
freeAvail.QuadPart = (bps*spc*freeClust);
}
}
}
if (derr.IsntError())
{
(* bytesFree) = freeAvail.QuadPart;
}
return derr;
}
// ExceptionFilter determines whether to handle the Windows exception passed
// to it.
int
CPGPdiskApp::ExceptionFilter(int exception)
{
switch (exception)
{
case STATUS_BREAKPOINT:
case STATUS_DATATYPE_MISALIGNMENT:
case STATUS_SINGLE_STEP:
return EXCEPTION_CONTINUE_SEARCH;
default:
return EXCEPTION_EXECUTE_HANDLER;
}
}
// ShowWindowsFormatDialog brings up the Windows formatting dialog for the
// specified drive letter.
DualErr
CPGPdiskApp::ShowWindowsFormatDialog(PGPUInt8 drive)
{
DualErr derr;
HINSTANCE shell32Handle;
PGPBoolean loadedShell32 = FALSE;
PVOID SHFormatDriveFunc;
pgpAssert(IsWin95CompatibleMachine() || IsWinNT4CompatibleMachine());
// Open handle to shell32.dll
shell32Handle = LoadLibrary("shell32.dll");
loadedShell32 = IsntNull(shell32Handle);
if (!loadedShell32)
derr = DualErr(kPGDMinorError_LoadLibraryFailed, GetLastError());
// Get procedure address for the formatting function.
if (derr.IsntError())
{
SHFormatDriveFunc = GetProcAddress(shell32Handle,
"SHFormatDrive");
if (IsNull(SHFormatDriveFunc))
{
derr = DualErr(kPGDMinorError_GetProcAddrFailed,
GetLastError());
}
}
// Attempt to call the function, catching all crashes in the process.
if (derr.IsntError())
{
HWND parentHwnd = mMainDialog->GetSafeHwnd();
PGPUInt32 largeDrive = drive;
__try
{
__asm
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -