You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
900 lines
23 KiB
900 lines
23 KiB
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include "pch.h"
|
|
#include <atlbase.h>
|
|
#include <stdio.h>
|
|
#include <wbemcli.h>
|
|
#include <comdef.h>
|
|
#include <winioctl.h>
|
|
#include <ntddvol.h> // IOCTL_VOLUME_IS_OFFLINE
|
|
#include "..\..\..\inc\ntrkcomm.h"
|
|
#include "..\..\..\inc\objectpath.h"
|
|
#include "..\..\schema.cpp"
|
|
#include "..\..\volutil.cpp"
|
|
|
|
#define INITGUIDS
|
|
#include <dskquota.h>
|
|
|
|
BOOL g_fVerbose = FALSE;
|
|
|
|
typedef enum _Variation
|
|
{
|
|
Variation_None = 0,
|
|
Variation_ValProp,
|
|
Variation_End
|
|
} Variation;
|
|
|
|
void
|
|
PrintVerbose(CHAR* pwszFormat, ...)
|
|
{
|
|
if (g_fVerbose)
|
|
{
|
|
va_list marker;
|
|
va_start( marker, pwszFormat );
|
|
vprintf(pwszFormat, marker );
|
|
va_end( marker );
|
|
}
|
|
}
|
|
|
|
class CVolumeValidation
|
|
{
|
|
public:
|
|
|
|
CVolumeValidation()
|
|
{
|
|
m_fStatus = TRUE;
|
|
m_wszLabel[0] = L'\0';
|
|
m_wszFileSystem[0] = L'\0';
|
|
m_dwSerialNumber = 0;
|
|
m_cchMaxFileNameLen = 0;
|
|
m_dwFileSystemFlags = 0;
|
|
m_fGotVolumeInformation = FALSE;
|
|
m_fGotQuotaInformation = FALSE;
|
|
m_fGotSizeInformation = FALSE;
|
|
m_cbCapacity = 0;
|
|
m_cbFreeSpace = 0;
|
|
m_fQuotasEnabled = FALSE;
|
|
m_fQuotasIncomplete = FALSE;
|
|
m_fQuotasRebuilding = FALSE;
|
|
}
|
|
~CVolumeValidation() {}
|
|
BOOL Validate(IWbemClassObject* pIObj);
|
|
|
|
private:
|
|
|
|
CWbemClassObject m_wcoVol;
|
|
BOOL m_fStatus;
|
|
BOOL m_fGotVolumeInformation;
|
|
BOOL m_fGotQuotaInformation;
|
|
BOOL m_fGotSizeInformation;
|
|
_bstr_t m_bstrVolume;
|
|
WCHAR m_wszLabel[g_cchVolumeLabelMax+1];
|
|
WCHAR m_wszFileSystem[g_cchFileSystemNameMax+1];
|
|
DWORD m_dwSerialNumber;
|
|
DWORD m_cchMaxFileNameLen;
|
|
DWORD m_dwFileSystemFlags;
|
|
ULONGLONG m_cbCapacity;
|
|
ULONGLONG m_cbFreeSpace;
|
|
BOOL m_fQuotasEnabled;
|
|
BOOL m_fQuotasIncomplete;
|
|
BOOL m_fQuotasRebuilding;
|
|
|
|
void ValidateAutomount();
|
|
void ValidateBlockSize();
|
|
void ValidateBootVolume();
|
|
void ValidateCapacity();
|
|
void ValidateCaptionName();
|
|
void ValidateCompressed();
|
|
void ValidateCrashdump();
|
|
void ValidateDirtyBitSet();
|
|
void ValidateDriveLetter();
|
|
void ValidateDriveType();
|
|
void ValidateFileSystem();
|
|
void ValidateFreeSpace();
|
|
void ValidateIndexingEnabled();
|
|
void ValidateLabel();
|
|
void ValidateMaximumFileNameLength();
|
|
void ValidatePagefile();
|
|
void ValidateQuotasEnabled();
|
|
void ValidateQuotasIncomplete();
|
|
void ValidateQuotasRebuilding();
|
|
void ValidateSerialNumber();
|
|
void ValidateSupportsDiskQuotas();
|
|
void ValidateSupportsFileBasedCompression();
|
|
void ValidateSystemName();
|
|
void ValidateSystemVolume();
|
|
|
|
BOOL ValidatePropertyIsNull(
|
|
IN const WCHAR* pwszName);
|
|
|
|
BOOL ValidatePropertyNotNull(
|
|
IN const WCHAR* pwszName);
|
|
|
|
void CompareProperty(
|
|
IN const WCHAR* pwszName,
|
|
IN WCHAR* pwszAPI);
|
|
|
|
void CompareProperty(
|
|
IN const WCHAR* pwszName,
|
|
IN DWORD dwAPI);
|
|
|
|
void CompareProperty(
|
|
IN const WCHAR* pwszName,
|
|
IN ULONGLONG llAPI);
|
|
|
|
void GetVolumeInformationLocal();
|
|
void GetSizeInformation();
|
|
void GetQuotaInformation();
|
|
};
|
|
|
|
void
|
|
CVolumeValidation::CompareProperty(
|
|
const WCHAR* pwszName,
|
|
WCHAR* pwszAPI)
|
|
{
|
|
_bstr_t bstrWMI;
|
|
|
|
m_wcoVol.GetProperty(bstrWMI, pwszName);
|
|
|
|
if (pwszAPI == NULL && bstrWMI.length() == 0)
|
|
{
|
|
PrintVerbose(" %lS<%lS> OK\n", pwszName, (WCHAR*)bstrWMI);
|
|
}
|
|
else if (pwszAPI == NULL && bstrWMI.length() != 0)
|
|
{
|
|
m_fStatus = FALSE;
|
|
printf(" Error: %lS<%lS> should be <NULL>\n", pwszName, (WCHAR*)bstrWMI);
|
|
}
|
|
else if (bstrWMI.length() == 0 && wcslen(pwszAPI) == 0)
|
|
{
|
|
PrintVerbose(" %lS<NULL> OK\n", pwszName, (WCHAR*)bstrWMI);
|
|
}
|
|
else if (bstrWMI.length() != 0 && _wcsicmp((WCHAR*)bstrWMI, pwszAPI) == 0)
|
|
{
|
|
PrintVerbose(" %lS<%lS> OK\n", pwszName, (WCHAR*)bstrWMI);
|
|
}
|
|
else
|
|
{
|
|
m_fStatus = FALSE;
|
|
printf(" Error: %lS<NULL> should be <%lS>\n", pwszName, pwszAPI);
|
|
}
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::CompareProperty(
|
|
const WCHAR* pwszName,
|
|
ULONGLONG llAPI)
|
|
{
|
|
LONGLONG llWMI = 0;
|
|
|
|
if (ValidatePropertyNotNull(pwszName))
|
|
{
|
|
m_wcoVol.GetPropertyI64(&llWMI, pwszName);
|
|
|
|
if (llWMI == llAPI)
|
|
{
|
|
PrintVerbose(" %lS<%I64d> OK\n", pwszName, llWMI);
|
|
}
|
|
else
|
|
{
|
|
m_fStatus = FALSE;
|
|
printf(" Error: %lS<%I64d> should be <%I64d>\n", pwszName, llWMI, llAPI);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::CompareProperty(
|
|
const WCHAR* pwszName,
|
|
DWORD dwAPI)
|
|
{
|
|
DWORD dwWMI = 0;
|
|
|
|
if (ValidatePropertyNotNull(pwszName))
|
|
{
|
|
m_wcoVol.GetProperty(&dwWMI, pwszName);
|
|
|
|
if (dwWMI == dwAPI)
|
|
{
|
|
PrintVerbose(" %lS<%d> OK\n", pwszName, dwWMI);
|
|
}
|
|
else
|
|
{
|
|
m_fStatus = FALSE;
|
|
printf(" Error: %lS<%d> should be <%d>\n", pwszName, dwWMI, dwAPI);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
CVolumeValidation::ValidatePropertyIsNull(
|
|
const WCHAR* pwszName)
|
|
{
|
|
_variant_t varVal;
|
|
BOOL fStatus = TRUE;
|
|
|
|
HRESULT hr = m_wcoVol.data()->Get(
|
|
_bstr_t(pwszName),
|
|
0,
|
|
&varVal,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (varVal.vt == VT_NULL)
|
|
{
|
|
PrintVerbose(" %lS<NULL> OK\n", pwszName);
|
|
}
|
|
else
|
|
{
|
|
printf(" Error: %lS should be NULL\n", pwszName);
|
|
m_fStatus = FALSE;
|
|
fStatus = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf(" Error: %lS not found\n", pwszName);
|
|
m_fStatus = FALSE;
|
|
fStatus = FALSE;
|
|
}
|
|
|
|
return fStatus;
|
|
}
|
|
|
|
BOOL
|
|
CVolumeValidation::ValidatePropertyNotNull(
|
|
const WCHAR* pwszName)
|
|
{
|
|
_variant_t varVal;
|
|
BOOL fStatus = TRUE;
|
|
|
|
HRESULT hr = m_wcoVol.data()->Get(
|
|
_bstr_t(pwszName),
|
|
0,
|
|
&varVal,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (varVal.vt == VT_NULL)
|
|
{
|
|
printf(" Error: %lS should not be NULL\n", pwszName);
|
|
m_fStatus = FALSE;
|
|
fStatus = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf(" Error: %lS not found\n", pwszName);
|
|
m_fStatus = FALSE;
|
|
fStatus = FALSE;
|
|
}
|
|
|
|
return fStatus;
|
|
}
|
|
|
|
BOOL
|
|
CVolumeValidation::Validate(IWbemClassObject* pIVolume)
|
|
{
|
|
m_wcoVol = pIVolume;
|
|
|
|
try
|
|
{
|
|
m_wcoVol.GetProperty(m_bstrVolume, PVDR_PROP_DEVICEID);
|
|
printf("VolumeGUID<%lS>\n", (WCHAR*)m_bstrVolume);
|
|
|
|
ValidateSystemName();
|
|
ValidateCaptionName();
|
|
ValidateAutomount();
|
|
ValidateDriveType();
|
|
|
|
if (VolumeIsMountable(m_bstrVolume) && VolumeIsReady(m_bstrVolume))
|
|
{
|
|
ValidateBlockSize();
|
|
ValidateBootVolume();
|
|
ValidateCapacity();
|
|
ValidateCompressed();
|
|
ValidateCrashdump();
|
|
ValidateDirtyBitSet();
|
|
ValidateDriveLetter();
|
|
ValidateFileSystem();
|
|
ValidateFreeSpace();
|
|
ValidateIndexingEnabled();
|
|
ValidateLabel();
|
|
ValidateMaximumFileNameLength();
|
|
ValidatePagefile();
|
|
ValidateQuotasEnabled();
|
|
ValidateQuotasIncomplete();
|
|
ValidateQuotasRebuilding();
|
|
ValidateSerialNumber();
|
|
ValidateSupportsDiskQuotas();
|
|
ValidateSupportsFileBasedCompression();
|
|
ValidateSystemVolume();
|
|
}
|
|
else
|
|
{
|
|
ValidatePropertyIsNull(PVDR_PROP_BLOCKSIZE);
|
|
ValidatePropertyIsNull(PVDR_PROP_CAPACITY);
|
|
ValidatePropertyIsNull(PVDR_PROP_COMPRESSED);
|
|
ValidatePropertyIsNull(PVDR_PROP_DIRTYBITSET);
|
|
ValidatePropertyIsNull(PVDR_PROP_FILESYSTEM);
|
|
ValidatePropertyIsNull(PVDR_PROP_FREESPACE);
|
|
ValidatePropertyIsNull(PVDR_PROP_INDEXINGENABLED);
|
|
ValidatePropertyIsNull(PVDR_PROP_LABEL);
|
|
ValidatePropertyIsNull(PVDR_PROP_MAXIMUMFILENAMELENGTH);
|
|
ValidatePropertyIsNull(PVDR_PROP_QUOTASENABLED);
|
|
ValidatePropertyIsNull(PVDR_PROP_QUOTASINCOMPLETE);
|
|
ValidatePropertyIsNull(PVDR_PROP_QUOTASREBUILDING);
|
|
ValidatePropertyIsNull(PVDR_PROP_SERIALNUMBER);
|
|
ValidatePropertyIsNull(PVDR_PROP_SUPPORTSDISKQUOTAS);
|
|
}
|
|
|
|
ValidatePropertyIsNull(PVDR_PROP_DESCRIPTION);
|
|
ValidatePropertyIsNull(L"Access");
|
|
ValidatePropertyIsNull(L"Availability");
|
|
ValidatePropertyIsNull(L"ConfigManagerErrorCode");
|
|
ValidatePropertyIsNull(L"ConfigManagerUserConfig");
|
|
ValidatePropertyIsNull(L"CreationClassName");
|
|
ValidatePropertyIsNull(L"ErrorCleared");
|
|
ValidatePropertyIsNull(L"ErrorDescription");
|
|
ValidatePropertyIsNull(L"ErrorMethodology");
|
|
ValidatePropertyIsNull(L"InstallDate");
|
|
ValidatePropertyIsNull(L"LastErrorCode");
|
|
ValidatePropertyIsNull(L"NumberOfBlocks");
|
|
ValidatePropertyIsNull(L"PNPDeviceID");
|
|
ValidatePropertyIsNull(L"PowerManagementCapabilities");
|
|
ValidatePropertyIsNull(L"PowerManagementSupported");
|
|
ValidatePropertyIsNull(L"Purpose");
|
|
ValidatePropertyIsNull(L"Status");
|
|
ValidatePropertyIsNull(L"StatusInfo");
|
|
ValidatePropertyIsNull(L"SystemCreationClassName");
|
|
|
|
#ifdef NEVER
|
|
ft.hr = CoCreateInstance(
|
|
CLSID_DiskQuotaControl,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IDiskQuotaControl,
|
|
(void **)&pIDQC);
|
|
if (ft.HrFailed())
|
|
{
|
|
ft.Throw(VSSDBG_VSSADMIN, ft.hr, L"unable to CoCreate IDiskQuotaControl");
|
|
}
|
|
|
|
spIDQC.Attach(pIDQC);
|
|
|
|
ft.hr = spIDQC->Initialize(pwszVolume, FALSE /* read only */);
|
|
if (ft.HrFailed())
|
|
{
|
|
ft.Trace(VSSDBG_VSSADMIN, L"IDiskQuotaControl::Initialize failed for volume %lS", pwszVolume);
|
|
}
|
|
else
|
|
{
|
|
DWORD dwState = 0;
|
|
ft.hr = spIDQC->GetQuotaState(&dwState);
|
|
if (ft.HrSucceeded())
|
|
{
|
|
wcoInstance.SetProperty(!(DISKQUOTA_IS_DISABLED(dwState)), PVDR_PROP_QUOTASENABLED);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
catch(CProvException ex)
|
|
{
|
|
printf("exception caught while validating volume, hr<%#x>\n", ex.hrGetError());
|
|
m_fStatus = FALSE;
|
|
}
|
|
catch(HRESULT hrEx)
|
|
{
|
|
printf("exception caught while validating volume, hr<%#x>\n", hrEx);
|
|
m_fStatus = FALSE;
|
|
}
|
|
|
|
return m_fStatus;
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateAutomount()
|
|
{
|
|
WCHAR wszPath[MAX_PATH+1] ;
|
|
DWORD dwProp = 0;
|
|
|
|
// Check Mountable (Automount)
|
|
BOOL fMountable = VolumeIsMountable(m_bstrVolume);
|
|
CompareProperty(PVDR_PROP_MOUNTABLE, (DWORD)fMountable);
|
|
}
|
|
|
|
|
|
void
|
|
CVolumeValidation::ValidateBlockSize()
|
|
{
|
|
LONGLONG llProp = 0;
|
|
DWORD cSectorsPerCluster = 0;
|
|
DWORD cBytesPerSector = 0;
|
|
DWORD cDontCare = 0;
|
|
|
|
// Check BlockSize
|
|
if (GetDiskFreeSpace(
|
|
m_bstrVolume,
|
|
&cSectorsPerCluster,
|
|
&cBytesPerSector,
|
|
&cDontCare, // total bytes
|
|
&cDontCare)) // total free bytes
|
|
{
|
|
LONGLONG cbBytesPerCluster = cBytesPerSector * cSectorsPerCluster;
|
|
CompareProperty(PVDR_PROP_BLOCKSIZE, (ULONGLONG)cbBytesPerCluster);
|
|
}
|
|
else
|
|
{
|
|
ValidatePropertyIsNull(PVDR_PROP_BLOCKSIZE);
|
|
}
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateCapacity()
|
|
{
|
|
GetSizeInformation();
|
|
CompareProperty(PVDR_PROP_CAPACITY, m_cbCapacity);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateCaptionName()
|
|
{
|
|
WCHAR wszPath[MAX_PATH+1] ;
|
|
_bstr_t bstrProp;
|
|
|
|
// Check Name & Caption
|
|
VssGetVolumeDisplayName(
|
|
m_bstrVolume,
|
|
wszPath,
|
|
MAX_PATH);
|
|
|
|
CompareProperty(PVDR_PROP_NAME, wszPath);
|
|
|
|
CompareProperty(PVDR_PROP_CAPTION, wszPath);
|
|
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateCompressed()
|
|
{
|
|
GetVolumeInformationLocal();
|
|
CompareProperty(PVDR_PROP_COMPRESSED, m_dwFileSystemFlags & FS_VOL_IS_COMPRESSED);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateDirtyBitSet()
|
|
{
|
|
DWORD dwProp = 0;
|
|
BOOL fDirty = FALSE;
|
|
DWORD dwRet = VolumeIsDirty(m_bstrVolume, &fDirty);
|
|
if (dwRet != ERROR_SUCCESS)
|
|
{
|
|
printf("VolumeIsDirty failed %#x\n", dwRet);
|
|
throw HRESULT_FROM_WIN32(dwRet);
|
|
}
|
|
CompareProperty(PVDR_PROP_DIRTYBITSET, (DWORD)fDirty);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateDriveLetter()
|
|
{
|
|
WCHAR wszDriveLetter[g_cchDriveName];
|
|
_bstr_t bstrProp;
|
|
|
|
if (GetVolumeDrive(
|
|
m_bstrVolume,
|
|
g_cchDriveName,
|
|
wszDriveLetter))
|
|
{
|
|
wszDriveLetter[wcslen(wszDriveLetter) - 1] = L'\0'; // Remove the trailing '\'
|
|
CompareProperty(PVDR_PROP_DRIVELETTER, wszDriveLetter);
|
|
}
|
|
else
|
|
ValidatePropertyIsNull(PVDR_PROP_DRIVELETTER);
|
|
|
|
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateDriveType()
|
|
{
|
|
WCHAR wszDriveLetter[g_cchDriveName];
|
|
_bstr_t bstrProp;
|
|
|
|
CompareProperty(PVDR_PROP_DRIVETYPE, (DWORD)GetDriveType(m_bstrVolume));
|
|
|
|
}
|
|
|
|
|
|
void
|
|
CVolumeValidation::ValidateFreeSpace()
|
|
{
|
|
GetSizeInformation();
|
|
CompareProperty(PVDR_PROP_FREESPACE, m_cbFreeSpace);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateFileSystem()
|
|
{
|
|
GetVolumeInformationLocal();
|
|
CompareProperty(PVDR_PROP_FILESYSTEM, m_wszFileSystem);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateLabel()
|
|
{
|
|
GetVolumeInformationLocal();
|
|
CompareProperty(PVDR_PROP_LABEL, m_wszLabel);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateIndexingEnabled()
|
|
{
|
|
DWORD dwAttributes = GetFileAttributes(m_bstrVolume);
|
|
if (dwAttributes == INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
printf("GetFileAttributes failed %#x\n", GetLastError());
|
|
throw HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
BOOL fIndexingEnabled = !(dwAttributes & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED);
|
|
CompareProperty(PVDR_PROP_INDEXINGENABLED, (DWORD)fIndexingEnabled);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateMaximumFileNameLength()
|
|
{
|
|
GetVolumeInformationLocal();
|
|
CompareProperty(PVDR_PROP_MAXIMUMFILENAMELENGTH, m_cchMaxFileNameLen);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateQuotasEnabled()
|
|
{
|
|
GetQuotaInformation();
|
|
if (m_fGotQuotaInformation)
|
|
CompareProperty(PVDR_PROP_QUOTASENABLED, (DWORD)m_fQuotasEnabled);
|
|
else
|
|
ValidatePropertyIsNull(PVDR_PROP_QUOTASENABLED);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateQuotasIncomplete()
|
|
{
|
|
GetQuotaInformation();
|
|
if (m_fGotQuotaInformation)
|
|
CompareProperty(PVDR_PROP_QUOTASINCOMPLETE, (DWORD)m_fQuotasIncomplete);
|
|
else
|
|
ValidatePropertyIsNull(PVDR_PROP_QUOTASINCOMPLETE);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateQuotasRebuilding()
|
|
{
|
|
GetQuotaInformation();
|
|
if (m_fGotQuotaInformation)
|
|
CompareProperty(PVDR_PROP_QUOTASREBUILDING, (DWORD)m_fQuotasRebuilding);
|
|
else
|
|
ValidatePropertyIsNull(PVDR_PROP_QUOTASREBUILDING);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateSerialNumber()
|
|
{
|
|
GetVolumeInformationLocal();
|
|
CompareProperty(PVDR_PROP_SERIALNUMBER, m_dwSerialNumber);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateSupportsDiskQuotas()
|
|
{
|
|
GetVolumeInformationLocal();
|
|
CompareProperty(PVDR_PROP_SUPPORTSDISKQUOTAS,
|
|
(m_dwFileSystemFlags & FILE_VOLUME_QUOTAS)?(DWORD)1:(DWORD)0);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateSupportsFileBasedCompression()
|
|
{
|
|
GetVolumeInformationLocal();
|
|
CompareProperty(PVDR_PROP_SUPPORTSFILEBASEDCOMPRESSION,
|
|
(DWORD)(m_dwFileSystemFlags & FS_FILE_COMPRESSION)?(DWORD)1:(DWORD)0);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateSystemName()
|
|
{
|
|
WCHAR wszComputerName[MAX_COMPUTERNAME_LENGTH];
|
|
DWORD cchBuf = MAX_COMPUTERNAME_LENGTH;
|
|
|
|
// Check SystemName
|
|
if (!GetComputerName(wszComputerName, &cchBuf))
|
|
{
|
|
printf("GetComputerName failed %#x\n", GetLastError());
|
|
throw HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
CompareProperty(PVDR_PROP_SYSTEMNAME, wszComputerName);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateBootVolume()
|
|
{
|
|
CompareProperty(PVDR_PROP_BOOTVOLUME, (DWORD)FALSE);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateCrashdump()
|
|
{
|
|
CompareProperty(PVDR_PROP_CRASHDUMP, (DWORD)FALSE);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidatePagefile()
|
|
{
|
|
CompareProperty(PVDR_PROP_PAGEFILE, (DWORD)FALSE);
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::ValidateSystemVolume()
|
|
{
|
|
CompareProperty(PVDR_PROP_SYSTEMVOLUME, (DWORD)FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
CVolumeValidation::GetVolumeInformationLocal()
|
|
{
|
|
if (!m_fGotVolumeInformation)
|
|
{
|
|
if (!GetVolumeInformation(
|
|
m_bstrVolume,
|
|
m_wszLabel,
|
|
g_cchVolumeLabelMax,
|
|
&m_dwSerialNumber,
|
|
&m_cchMaxFileNameLen,
|
|
&m_dwFileSystemFlags,
|
|
m_wszFileSystem,
|
|
g_cchFileSystemNameMax))
|
|
{
|
|
printf("GetVolumeInformation failed for volume %lS, %#x\n", (WCHAR*)m_bstrVolume, GetLastError());
|
|
throw HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
m_fGotVolumeInformation = TRUE;
|
|
}
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::GetSizeInformation()
|
|
{
|
|
if (!m_fGotSizeInformation)
|
|
{
|
|
ULARGE_INTEGER cbCapacity = {0, 0};
|
|
ULARGE_INTEGER cbFreeSpace = {0, 0};
|
|
ULARGE_INTEGER cbUserFreeSpace = {0, 0};
|
|
|
|
if (!GetDiskFreeSpaceEx(
|
|
m_bstrVolume,
|
|
&cbUserFreeSpace,
|
|
&cbCapacity,
|
|
&cbFreeSpace))
|
|
{
|
|
printf("GetDiskFreeSpaceEx failed for volume %lS, %#x\n", (WCHAR*)m_bstrVolume, GetLastError());
|
|
throw HRESULT_FROM_WIN32(GetLastError());
|
|
}
|
|
|
|
m_cbCapacity = cbCapacity.QuadPart;
|
|
m_cbFreeSpace = cbFreeSpace.QuadPart;
|
|
m_fGotSizeInformation = TRUE;
|
|
}
|
|
}
|
|
|
|
void
|
|
CVolumeValidation::GetQuotaInformation()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<IDiskQuotaControl> spIDQC;
|
|
IDiskQuotaControl* pIDQC = NULL;
|
|
|
|
hr = CoCreateInstance(
|
|
CLSID_DiskQuotaControl,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IDiskQuotaControl,
|
|
(void **)&pIDQC);
|
|
if (FAILED(hr))
|
|
{
|
|
printf("IDiskQuotaControl CoCreateInstance failed, %#x\n",hr);
|
|
throw hr;
|
|
}
|
|
|
|
spIDQC.Attach(pIDQC);
|
|
|
|
// OK if this fails on some volumes with file systems that don't support quotas.
|
|
hr = spIDQC->Initialize(m_bstrVolume, FALSE /* read only */);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
DWORD dwState = 0;
|
|
hr = spIDQC->GetQuotaState(&dwState);
|
|
if (FAILED(hr))
|
|
{
|
|
printf("IDiskQuotaControl::GetQuotaState failed for volume %lS, %#x\n", m_bstrVolume, hr);
|
|
throw hr;
|
|
}
|
|
|
|
m_fQuotasEnabled = !(DISKQUOTA_IS_DISABLED(dwState));
|
|
m_fQuotasIncomplete = DISKQUOTA_FILE_INCOMPLETE(dwState);
|
|
m_fQuotasRebuilding = DISKQUOTA_FILE_REBUILDING(dwState);
|
|
m_fGotQuotaInformation = TRUE;
|
|
}
|
|
}
|
|
|
|
HRESULT
|
|
testValProp(IWbemServices* pISvc)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL bStatus = TRUE;
|
|
|
|
do
|
|
{
|
|
CComPtr<IEnumWbemClassObject> spEnum;
|
|
hr = pISvc->CreateInstanceEnum(
|
|
_bstr_t(L"Win32_Volume"), 0, NULL, &spEnum);
|
|
if (FAILED(hr))
|
|
{
|
|
printf("Win32_Volume enumeration failed <%#x>\n", hr);
|
|
break;
|
|
}
|
|
|
|
while(true)
|
|
{
|
|
CComPtr<IWbemClassObject> spVolume;
|
|
CVolumeValidation validation;
|
|
|
|
ULONG cVolume = 0;
|
|
|
|
hr = spEnum->Next(WBEM_INFINITE, 1, &spVolume, &cVolume);
|
|
if (FAILED(hr))
|
|
{
|
|
printf("IEnumWbem::Next failed <%#x>\n", hr);
|
|
goto Exit;
|
|
}
|
|
if (hr == S_FALSE)
|
|
{
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
|
|
if (!validation.Validate(spVolume))
|
|
{
|
|
bStatus = FALSE;
|
|
}
|
|
}
|
|
}
|
|
while (false);
|
|
|
|
if (bStatus == FALSE)
|
|
{
|
|
printf("testValProp: instance validation failed for at least one volume\n");
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
void
|
|
PrintUsage()
|
|
{
|
|
printf("Usage: valprop [-v] variation_number [volume_name]\n");
|
|
printf("variations:\n");
|
|
printf("1 - validate properties against Win32 APIs\n");
|
|
}
|
|
|
|
HRESULT
|
|
RunTest(
|
|
WCHAR* pwszVolume,
|
|
long nVariation)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
do
|
|
{
|
|
CComPtr<IWbemLocator> spILocator;
|
|
CComPtr<IWbemServices> spISvc;
|
|
hr = CoInitialize(NULL);
|
|
if (FAILED(hr))
|
|
{
|
|
printf("CoInitialize failed <%#x>\n", hr);
|
|
break;
|
|
}
|
|
|
|
hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
|
|
RPC_C_AUTHN_LEVEL_CONNECT,
|
|
RPC_C_IMP_LEVEL_IMPERSONATE,
|
|
NULL, EOAC_NONE, 0);
|
|
if (FAILED(hr))
|
|
{
|
|
printf("CoInitializeSecurity failed <%#x>\n", hr);
|
|
break;
|
|
}
|
|
|
|
hr = spILocator.CoCreateInstance(__uuidof(WbemLocator));
|
|
if (FAILED(hr))
|
|
{
|
|
printf("IWbemLocator CoCreateInstance failed <%#x>\n", hr);
|
|
break;
|
|
}
|
|
|
|
hr = spILocator->ConnectServer(
|
|
_bstr_t("\\\\.\\root\\cimv2"),
|
|
NULL, NULL, NULL, 0, NULL, NULL, &spISvc);
|
|
if (FAILED(hr))
|
|
{
|
|
printf("IWbemLocator::ConnectServer failed <%#x>\n", hr);
|
|
break;
|
|
}
|
|
|
|
switch (nVariation)
|
|
{
|
|
case Variation_ValProp:
|
|
hr = testValProp(spISvc);
|
|
break;
|
|
|
|
default:
|
|
printf("invalid variation number <%d>\n", nVariation);
|
|
PrintUsage();
|
|
hr = E_INVALIDARG;
|
|
}
|
|
}
|
|
while (false);
|
|
|
|
CoUninitialize();
|
|
return hr;
|
|
}
|
|
|
|
_cdecl wmain(int argc, wchar_t* argv[])
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if (argc < 2)
|
|
{
|
|
PrintUsage();
|
|
return 1;
|
|
}
|
|
|
|
int nArg = 1;
|
|
if (_wcsicmp(argv[nArg], L"-v") == 0)
|
|
{
|
|
g_fVerbose = TRUE;
|
|
nArg++;
|
|
}
|
|
long nVariation = wcstol(argv[nArg++], NULL, 10);
|
|
WCHAR* pwszVolume = argv[nArg];
|
|
|
|
hr = RunTest(pwszVolume, nVariation);
|
|
|
|
if (hr != S_OK)
|
|
printf("test failed <%#x>\n", hr);
|
|
else
|
|
printf("test succeeded\n");
|
|
|
|
return hr == S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|