209 lines
7.3 KiB
C
209 lines
7.3 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 1998 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
FTMan
|
||
|
|
||
|
File Name:
|
||
|
|
||
|
DiskMap.h
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
Definition of classes used to keep the disk array map in memory. Used in retrieving partitions and free spaces,
|
||
|
in creating and deleting partitions
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Cristian Teodorescu November 20, 1998
|
||
|
|
||
|
Notes:
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
/////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#if !defined(AFX_DISKMAP_H_INCLUDED_)
|
||
|
#define AFX_DISKMAP_H_INCLUDED_
|
||
|
|
||
|
#if _MSC_VER > 1000
|
||
|
#pragma once
|
||
|
#endif // _MSC_VER > 1000
|
||
|
|
||
|
#include <winioctl.h>
|
||
|
|
||
|
#include "FTManDef.h"
|
||
|
|
||
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
|
// Class CDiskMap
|
||
|
|
||
|
class CItemData;
|
||
|
|
||
|
class CDiskMap
|
||
|
{
|
||
|
public:
|
||
|
// Constructor
|
||
|
CDiskMap();
|
||
|
// Constructor providing the disk number
|
||
|
CDiskMap( DWORD dwDiskNumber );
|
||
|
|
||
|
~CDiskMap();
|
||
|
|
||
|
// Operations
|
||
|
public:
|
||
|
// Set the disk number and reset m_bLoaded
|
||
|
void SetDiskNumber( DWORD dwDiskNumber );
|
||
|
|
||
|
// Load disk layout and geometry
|
||
|
BOOL LoadDiskInfo( CString& strErrors, BOOL& bMissingDisk );
|
||
|
|
||
|
// Save the disk layout on disk
|
||
|
BOOL SaveDiskInfo( CString& strErrors, BOOL& bMissingDisk );
|
||
|
|
||
|
// Retrieve all non-container partitions on the disk and create CPhysicalPartitionData instances for them
|
||
|
// If the disk info is not loaded the method calls LoadDiskInfo first
|
||
|
BOOL ReadPartitions( CObArray& arrPartitions, CString& strErrors, BOOL& bMissingDisk, CItemData* pParentData = NULL );
|
||
|
|
||
|
// Retrieve all free spaces on the disk and create CFreeSpaceData instances for them
|
||
|
// If the disk info is not loaded the method calls LoadDiskInfo first
|
||
|
BOOL ReadFreeSpaces( CObArray& arrFreeSpaces, CString& strErrors, BOOL& bMissingDisk, CItemData* pParentData = NULL );
|
||
|
|
||
|
// Retrieve a non-container partition information from the disk layout given the partition offset
|
||
|
BOOL ReadPartitionInformation( LONGLONG llPartStartOffset, PARTITION_INFORMATION& partInfo,
|
||
|
PARTITION_TYPE& wPartitionType, CString& strErrors, BOOL& bMissingDisk );
|
||
|
|
||
|
// Delete a non-container partition from the disk
|
||
|
BOOL DeletePartition( LONGLONG llPartStartOffset );
|
||
|
|
||
|
// Deletes an extended partition from the disk
|
||
|
// The extended partition should not be contained by another extended partition
|
||
|
BOOL DeleteExtendedPartition( LONGLONG llPartStartOffset );
|
||
|
|
||
|
// Create a partition on the disk ( m_dwDiskNumber )
|
||
|
BOOL CreatePartition( LONGLONG llPartStartOffset, LONGLONG llPartSize, LONGLONG& llExactPartStartOffset );
|
||
|
|
||
|
// Create an extended partition on the disk ( m_dwDiskNumber )
|
||
|
BOOL CreateExtendedPartition( LONGLONG llPartStartOffset, LONGLONG llPartSize, LONGLONG& llNewFreeSpaceOffset );
|
||
|
|
||
|
//Data members
|
||
|
public:
|
||
|
|
||
|
protected:
|
||
|
// Disk number
|
||
|
DWORD m_dwDiskNumber;
|
||
|
|
||
|
// Disk geometry
|
||
|
LONGLONG m_llTrackSize;
|
||
|
LONGLONG m_llSectorSize;
|
||
|
LONGLONG m_llCylinderSize;
|
||
|
LONGLONG m_llDiskSize;
|
||
|
|
||
|
// Pointer to the drive layout buffer
|
||
|
PDRIVE_LAYOUT_INFORMATION m_pBuffer;
|
||
|
|
||
|
// The size of the drive layout buffer
|
||
|
DWORD m_dwBufferSize;
|
||
|
|
||
|
// Is the information related to disk m_dwDiskNumber loaded into this object ?
|
||
|
BOOL m_bLoaded;
|
||
|
|
||
|
protected:
|
||
|
|
||
|
// Some recursive methods
|
||
|
|
||
|
// Given an extended partition table index in m_pBuffer->PartitionInfo, scan recursively
|
||
|
// the extended partition tree and find the chunk of m_pBuffer->PartitionInfo filled with
|
||
|
// members of the extended partition
|
||
|
// Then return the next index. This index is the index of the following extended partition
|
||
|
// from the same ( or superior ) level as the given extended partition
|
||
|
DWORD GetNextIndex( DWORD dwTableIndex );
|
||
|
|
||
|
// Search for free spaces inside an extended partition given its starting offset, size and partitions table
|
||
|
// index inside m_pBuffer
|
||
|
// For every found free space create a CFreeSpace instance and add it to arrFreeSpaces
|
||
|
void GetExtendedPartitionFreeSpaces( LONGLONG llExtPartStartOffset, LONGLONG llExtPartEndOffset,
|
||
|
DWORD dwTableIndex, DWORD& dwNextIndex, CObArray& arrFreeSpaces,
|
||
|
CItemData* pParentData = NULL );
|
||
|
|
||
|
// Search recursively for a partition inside an extended partition
|
||
|
// This method may be called also to search for a partition inside the whole disk.
|
||
|
BOOL SearchForPartitionInExtendedPartition( LONGLONG llPartOffset, DWORD dwExtPartIndex, DWORD dwTableIndex,
|
||
|
DWORD& dwNextIndex, DWORD& dwPartIndex, DWORD& dwParentIndex );
|
||
|
|
||
|
|
||
|
// Given an offset and size search recursively for an appropriate free space
|
||
|
// inside an extended partition ( or the whole disk ).
|
||
|
// Return the start and end offset of the whole free space and the index in the partition table
|
||
|
// where a new partition having the given offset and size might be inserted.
|
||
|
BOOL SearchForFreeSpaceInExtendedPartition( LONGLONG llOffset, LONGLONG llSize, LONGLONG llExtPartStartOffset,
|
||
|
LONGLONG llExtPartEndOffset, DWORD dwTableIndex,
|
||
|
LONGLONG& llFreeSpaceStartOffset, LONGLONG& llFreeSpaceEndOffset,
|
||
|
BOOL &bAtBeginningOfExtendedPartition, DWORD& dwNewPartIndex);
|
||
|
|
||
|
// Sort a partition table by starting offset without actually changing the table
|
||
|
DWORD SortPartitionsByOffset( PARTITION_INFORMATION* arrTable, DWORD dwSize, DWORD* arrOrder );
|
||
|
|
||
|
// Get the greatest cylinder border less than or equal with an offset
|
||
|
LONGLONG GetCylinderBorderBefore( LONGLONG llOffset );
|
||
|
// Get the lowest cylinder border greater than or equal with an offset
|
||
|
LONGLONG GetCylinderBorderAfter( LONGLONG llOffset );
|
||
|
|
||
|
// Delete a partition from m_pBuffer->PartitionInfo table
|
||
|
void DeletePartitionFromTable( DWORD dwPartIndex );
|
||
|
|
||
|
// Update / Delete an extended partition after one of its members was deleted
|
||
|
// If the extended partition remains empty then it must be deleted
|
||
|
// If only one member is left and this member is an extended partition too then replace the
|
||
|
// extended partition with its member ( promote the member on the superior level )
|
||
|
// All other situations are unlikely to happen so I don't treat them here
|
||
|
void UpdateExtendedPartitionAfterMemberDeletion( DWORD dwPartIndex, DWORD dwTableIndex );
|
||
|
|
||
|
// Add a new container partition AND/OR a new non-container partition to m_pBuffer->PartitionInfo table
|
||
|
// and make all necessary changes to the partition table
|
||
|
BOOL AddPartitionToTable( LONGLONG llPartStartOffset, LONGLONG llPartSize,
|
||
|
DWORD dwNewPartIndex, BOOL bCreateContainer, BOOL bCreateNonContainer );
|
||
|
|
||
|
// Fill a PARTITION_INFORMATION structure with the info of a new partition
|
||
|
void FillNewPartitionInfo( LONGLONG llPartStartOffset, LONGLONG llPartSize,
|
||
|
PARTITION_INFORMATION* pPartInfo, BOOL bContainer );
|
||
|
|
||
|
// Add a error message to a string
|
||
|
// The error message will be formatted like this:
|
||
|
// <Disk Number: >< My error message > [ System error message ]
|
||
|
void AddError( CString& strErrors, UINT unErrorMsg, BOOL bAddSystemMsg = FALSE );
|
||
|
|
||
|
};
|
||
|
|
||
|
inline CDiskMap::CDiskMap()
|
||
|
: m_dwDiskNumber(-1), m_pBuffer(NULL), m_dwBufferSize(0), m_bLoaded(FALSE)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
inline CDiskMap::CDiskMap( DWORD dwDiskNumber )
|
||
|
: m_dwDiskNumber( dwDiskNumber ), m_pBuffer(NULL), m_dwBufferSize(0), m_bLoaded(FALSE)
|
||
|
{
|
||
|
ASSERT( dwDiskNumber >= 0 );
|
||
|
}
|
||
|
|
||
|
|
||
|
inline CDiskMap::~CDiskMap()
|
||
|
{
|
||
|
if( m_pBuffer )
|
||
|
LocalFree( m_pBuffer );
|
||
|
}
|
||
|
|
||
|
inline void CDiskMap::SetDiskNumber( DWORD dwDiskNumber )
|
||
|
{
|
||
|
ASSERT( dwDiskNumber >= 0 );
|
||
|
if( m_dwDiskNumber != dwDiskNumber )
|
||
|
{
|
||
|
m_dwDiskNumber = dwDiskNumber;
|
||
|
m_bLoaded = FALSE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif // !defined(AFX_DISKMAP_H_INCLUDED_)
|