📄 utils.cpp
字号:
/*
* Copyright (c) Satish Kumar Janarthanan (vsat_in@yahoo.com) 2004 - 2005
*
* Project: Win2fs
*
* Module Name: \GUI\MainApp\Utils.cpp
*
* Abstract: Misc. utility functions.
*
* Notes: None
*
* Revision History:
*
* Date Version Author Change Log
* ------------------------------------------------------------------------
*
* 03-DEC-05 0.0.1 Satish Kumar J Initial Version
*/
//////////////////////////////////////////////////////////////////////////////
// Includes.
#include "StdAfx.h"
#include "Utils.h"
#include "..\..\Other\Registry.h"
//////////////////////////////////////////////////////////////////////////////
// Static data.
#define STR_SERVICE_NAME "Win2fs"
// The NT object name for disk drives.
static LPCSTR gs_szVolName = (LPCSTR) "\\\\.\\PhysicalDrive%lu";
struct SFilesystem
{
__U8 nFSId;
__S8 szFilesys[20];
};
typedef struct SFilesystem FILESYSTEM ;
static FILESYSTEM gs_FilesystemTable[] =
{
{ 0x01, TEXT("MSDOS FAT12 ") },
{ 0x04, TEXT("MSDOS FAT16 ") },
{ 0x05, TEXT("Windows Extended ") },
{ 0x06, TEXT("Windows FAT16 ") },
{ 0x07, TEXT("Windows NTFS ") },
{ 0x0B, TEXT("Windows FAT32 ") },
{ 0x0C, TEXT("Large Windows FAT32") },
{ 0x0E, TEXT("LBA VFAT (16-Bit) ") },
{ 0x0F, TEXT("LBA VFAT Extended ") },
{ 0x11, TEXT("Hidden FAT12 ") },
{ 0x14, TEXT("Hidden DOS FAT16 ") },
{ 0x16, TEXT("Hidden FAT16 ") },
{ 0x17, TEXT("Hidden NTFS ") },
{ 0x1B, TEXT("Hidden FAT32 ") },
{ 0x1C, TEXT("Hidden FAT32 LBA ") },
{ 0x1E, TEXT("Hidden FAT16 LBA ") },
{ 0x78, TEXT("XOSL Filesystem ") },
{ 0x80, TEXT("Minix Filesystem ") },
{ 0x81, TEXT("Old Linux ") },
{ 0x82, TEXT("Linux Swap ") },
{ 0x83, TEXT("Linux Ext2fs ") },
{ 0x85, TEXT("Linux Extended ") },
{ 0x00, TEXT("Unknown ") }
};
struct SPartitionRecord
{
__U8 nDiskNumber; // 1, 2, ...
__U8 nPartNumber; // 1, 2, ... (for this disk).
__U8 nVolumeNumber; // 1, 2, ... (Across all disks).
__U32 nSectorCount; // The number of 512 byte sectors.
__U32 nStartSector; // The starting sector number.
__U8 nDriveLetter; // The driver leter (if mounted).
__U8 nId; // The type of the partition.
PVOID pDCB; // Pointer to the device handle.
};
typedef struct SPartitionRecord PARTITION_RECORD ;
struct SDriveLayoutInfo
{
__U32 PartitionCount;
__U32 Signature;
PARTITION_INFORMATION PartitionEntry[MAX_PART_RECORDS];
};
typedef struct SDriveLayoutInfo DRIVE_LAYOUT_INFO ;
//////////////////////////////////////////////////////////////////////////////
// Static functions.
static __U32 UtilComputeFreeSpace (DWORD dwFree, DWORD dwSPC, DWORD dwBPS)
{
__U32 nRet = 0;
if (dwFree >= 1024)
{
dwFree = dwFree / 1024;
if (dwSPC >= 2)
{
dwSPC = (dwSPC * dwBPS) / 1024;
nRet = dwFree * dwSPC;
}
else
{
nRet = (dwFree * dwSPC * dwBPS) / 1024;
}
}
else
{
if (dwSPC >= 2)
{
dwSPC = (dwSPC * dwBPS) / 1024;
nRet = (dwFree * dwSPC) / 1024;
}
else
{
nRet = (dwFree * dwSPC * dwBPS) / 1024;
}
}
return nRet;
}
static __U8 UtilFindVolumeMountPoint ( PARTITION_RECORD* Part )
{
__U8 nPos;
__U8 chMountPt;
BOOL bCheck2;
CHAR szBuf[16];
CHAR szVolName1[128];
CHAR szVolName2[128];
nPos = 2;
chMountPt = 255;
bCheck2 = FALSE;
ZeroMemory (szBuf, sizeof (szBuf));
ZeroMemory (szVolName1, sizeof (szVolName1));
ZeroMemory (szVolName2, sizeof (szVolName2));
// Volume to be queried.
sprintf ( szVolName1, "\\Device\\HarddiskVolume%lu", Part->nVolumeNumber );
CheckAgain:
while (nPos <= 26)
{
sprintf (szBuf, "%C:", nPos+'A');
if (QueryDosDevice (szBuf, szVolName2, 128))
{
if (0 == strcmpi (szVolName1, szVolName2))
{
chMountPt = nPos ;
break;
}
}
nPos++;
}
if ( !isalpha (chMountPt+'A') && (!bCheck2) )
{
// Sometimes, volume names follow a different naming convention.
sprintf (
szVolName1,
"\\Device\\Harddisk%d\\Partition%d",
Part->nDiskNumber,
Part->nPartNumber+1
);
nPos = 2;
bCheck2 = TRUE;
goto CheckAgain;
}
return chMountPt;
}
static BOOL UtilGetPartitionRecords ( PARTITION_RECORD Partitions[MAX_PART_RECORDS] )
{
__U32 i;
BOOL bRet;
HANDLE hDev;
__U32 nSize;
__U32 nCount;
__U32 nLastVolume;
__U32 nVolumeNumber;
__U32 nBytesReturned;
CHAR szDeviceName[512];
DRIVE_LAYOUT_INFO DriveLayout;
i = 0;
nCount = 0;
bRet = FALSE;
nLastVolume = 0;
nVolumeNumber = 0;
nBytesReturned = 0;
hDev = INVALID_HANDLE_VALUE;
nSize = MAX_PART_RECORDS * sizeof ( PARTITION_RECORD );
ZeroMemory ( &DriveLayout, sizeof ( DRIVE_LAYOUT_INFO ) );
ZeroMemory ( szDeviceName, sizeof ( szDeviceName ) );
for ( i = 0; i < (MAX_IDE_DISK+MAX_SCSI_DISK); i++ )
{
sprintf ( (PCHAR)szDeviceName, gs_szVolName, i );
hDev = CreateFileA ( szDeviceName,
GENERIC_READ,
FILE_SHARE_READ,
NULL, OPEN_EXISTING, 0, NULL );
BREAK_IF_EQUAL ( hDev, INVALID_HANDLE_VALUE );
bRet = DeviceIoControl (hDev,
IOCTL_DISK_GET_DRIVE_LAYOUT,
NULL,
0,
&DriveLayout,
sizeof (DriveLayout),
(PULONG) &nBytesReturned,
NULL);
BREAK_IF_FALSE ( bRet );
for ( nCount = 0, nLastVolume = 0; nCount < DriveLayout.PartitionCount; nCount++ )
{
if ( nCount > MAX_PART_RECORDS )
{
break;
}
Partitions->nDiskNumber = i;
Partitions->nPartNumber = nCount;
Partitions->nVolumeNumber = nVolumeNumber+DriveLayout.PartitionEntry[nCount].PartitionNumber;
Partitions->nDriveLetter = UtilFindVolumeMountPoint (Partitions);
Partitions->nId = DriveLayout.PartitionEntry[nCount].PartitionType;
// Had to hack this !.
__int64 t = DriveLayout.PartitionEntry[nCount].StartingOffset.QuadPart/512;
Partitions->nStartSector = (__U32) t;
t = DriveLayout.PartitionEntry[nCount].PartitionLength.QuadPart/512;
Partitions->nSectorCount = (__U32) t;
Partitions++;
if ( nLastVolume < DriveLayout.PartitionEntry[nCount].PartitionNumber )
{
nLastVolume = DriveLayout.PartitionEntry[nCount].PartitionNumber;
}
}
nVolumeNumber += nLastVolume;
SAFE_CLOSE_HANDLE ( hDev );
}
SAFE_CLOSE_HANDLE ( hDev );
return bRet;
}
static BOOL UtilSetupDriver2AutoStart (BOOL bYes)
{
CRegDWORD dwStart (
HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Services\\Win2fs",
"Start"
);
if (bYes)
{
dwStart = 1; // System start.
}
else
{
dwStart = 3; // Manual start.
}
return TRUE;
}
static BOOL UtilSetAutoMount (__U32 nDisk, __U32 nPartition, __U8 chDriveLetter)
{
BOOL bRet = FALSE;
if (isalpha(chDriveLetter))
{
bRet = UtilSetupDriver2AutoStart (TRUE);
if (bRet)
{
CHAR mp[32];
sprintf (mp, "%C:", chDriveLetter);
CHAR dev[128];
sprintf (dev, "\\Device\\Harddisk%d\\Partition%d", nDisk, nPartition);
CRegString rsDD(
HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\DOS Devices",
mp
);
rsDD = dev;
bRet = TRUE;
}
}
return bRet;
}
static BOOL UtilRemoveAutoMount (__U8 chDriveLetter)
{
BOOL bRet = FALSE;
if (isalpha(chDriveLetter))
{
CHAR mp[32];
sprintf (mp, "%C:", chDriveLetter);
CRegString rsDD(
HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrenrControlSet\\Control\\Session Manager\\DOS Devices",
mp
);
rsDD.RemoveValue ();
bRet = TRUE;
}
return bRet;
}
//////////////////////////////////////////////////////////////////////////////
// Global funtions.
BOOL UtilGetPartitionTable ( PARTITION_INFO PartitionTable[MAX_PART_RECORDS] )
{
__U32 i, j;
__U32 nVol;
BOOL bRet;
BOOL bFirstExtended;
PARTITION_RECORD PartitionRecords[MAX_PART_RECORDS];
bRet = FALSE;
bFirstExtended = TRUE;
ZeroMemory ( PartitionRecords, sizeof ( PartitionRecords ) );
do
{
// Get the Partition records first.
bRet = UtilGetPartitionRecords ( PartitionRecords );
BREAK_IF_FALSE ( bRet );
// Map them to PARTITION_INFO records.
ZeroMemory ( PartitionTable, sizeof ( PartitionTable ) );
for ( i = 0, j = 0, nVol = 1; i < MAX_PART_RECORDS; i++ )
{
//
// Win2000 inserts empty partition records,
// to indicate the MBR of extended partitions.
// we must adjust for that.
//
if ( 0 == PartitionRecords[i].nSectorCount )
{
continue;
}
//
// Leave out the 'inner' extended partitions themselves,
// we are interested only in the logical drives they contain.
//
if ( IS_EXTENDED_PARTITION ( PartitionRecords[i].nId ) )
{
if ( ! bFirstExtended )
{
continue;
}
bFirstExtended = FALSE;
}
//
// Are we done with the previous disk ?
//
if ( i > 0 )
{
if ( PartitionRecords[i].nDiskNumber != PartitionRecords[i-1].nDiskNumber )
{
nVol = 1;
}
}
PartitionTable[j].nDiskNumber = PartitionRecords[i].nDiskNumber;
PartitionTable[j].nPartNumber = nVol;
PartitionTable[j].nFilesystemId = PartitionRecords[i].nId;
// 0 => A, 1 => B, etc
PartitionTable[j].chMountPoint = PartitionRecords[i].nDriveLetter + 'A';
// In Mb.
PartitionTable[j].nSize = PartitionRecords[i].nSectorCount/2048;
if (isalpha(PartitionTable[j].chMountPoint))
{
UtilGetFreeDiskSpace(PartitionTable[j].chMountPoint, &PartitionTable[j].nFree);
UtilGetVolumeLabel(PartitionTable[j].chMountPoint, PartitionTable[j].szVolumeLabel);
}
PartitionTable[j].pReserved = &(PartitionRecords[i]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -