#include "precomp.h"
#include "physicaldrive.h"
#include "assert.h"
#include "reiserfs.h"
#ifdef _WIN32
#include "pdrive95.h"
#include "pdrivent.h"
#else
#include "pdriveposix.h"
#endif
#ifdef _WIN32
typedef enum
{
IS_WINDOWS_NT,
IS_WINDOWS_2000,
IS_WINDOWS_XP,
IS_WINDOWS_95,
IS_WINDOWS_98,
IS_WINDOWS_98SE,
IS_WINDOWS_ME,
IS_WINDOWS_UNKNOWN,
} WINDOWS_VERSION;
WINDOWS_VERSION RefreshWindowsVersion()
{
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
memset(&osvi, 0, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if( !(bOsVersionInfoEx = GetVersionEx( (OSVERSIONINFO*) &osvi)) )
{
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if( !GetVersionEx( (OSVERSIONINFO*) &osvi) )
return IS_WINDOWS_UNKNOWN;
}
switch (osvi.dwPlatformId)
{
case VER_PLATFORM_WIN32_NT:
if( osvi.dwMajorVersion <= 4 )
return IS_WINDOWS_NT;
if( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
return IS_WINDOWS_2000;
if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
return IS_WINDOWS_XP;
return IS_WINDOWS_NT;
case VER_PLATFORM_WIN32_WINDOWS:
if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
return IS_WINDOWS_95;
if(osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
{
if( osvi.szCSDVersion[1] == 'A' )
return IS_WINDOWS_98SE;
return IS_WINDOWS_98;
}
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
return IS_WINDOWS_ME;
return IS_WINDOWS_95;
}
return IS_WINDOWS_UNKNOWN;
}
static WINDOWS_VERSION wv;
IPhysicalDrive* CreatePhysicalDriveInstance()
{
wv = RefreshWindowsVersion();
if( (wv == IS_WINDOWS_NT) || (wv == IS_WINDOWS_2000) || (wv == IS_WINDOWS_XP) )
{
return new PNtPhysicalDrive();
}
else
{
return new P9xPhysicalDrive();
}
}
#else
IPhysicalDrive* CreatePhysicalDriveInstance()
{
return new PPosixPhysicalDrive();
}
#endif
void IPhysicalDrive::DumpDriveInfo( LPCSTR lpszDrive )
{
DISK_GEOMETRY dg;
BYTE bLayout[20240];
printf("\n----- Info on %s ------\n\n", lpszDrive );
DWORD BytesPerSector = 512;
#ifdef SUPPORT_WINDOWS_XP_PARTITIONS
if( GetDriveGeometryEx( (DISK_GEOMETRY_EX*) bLayout, sizeof(bLayout) ) )
{
DISK_GEOMETRY_EX* pDG = (DISK_GEOMETRY_EX*) bLayout;
printf("Drive uses XP-style DISK_GEOMETRY_EX:\n" );
printf(" Cylinders = %" FMT_QWORD "\n", pDG->Geometry.Cylinders.QuadPart );
printf(" MediaType = %hd\n", (USHORT) pDG->Geometry.MediaType );
printf(" TracksPerCylinder = %hd\n", pDG->Geometry.TracksPerCylinder );
printf(" SectorsPerTrack = %hd\n", pDG->Geometry.SectorsPerTrack );
printf(" BytesPerSector = %hd\n", pDG->Geometry.BytesPerSector );
BytesPerSector = pDG->Geometry.BytesPerSector;
printf(" DiskSize = %" FMT_QWORD "\n", pDG->DiskSize.QuadPart );
}
else
#endif
if( GetDriveGeometry(&dg) )
{
printf("Drive uses DISK_GEOMETRY:\n" );
printf(" Cylinders = %" FMT_QWORD "\n", dg.Cylinders.QuadPart );
printf(" MediaType = %hd\n", (USHORT) dg.MediaType );
printf(" TracksPerCylinder = %hd\n", dg.TracksPerCylinder );
printf(" SectorsPerTrack = %hd\n", dg.SectorsPerTrack );
printf(" BytesPerSector = %hd\n", dg.BytesPerSector );
INT64 DiskSize = dg.BytesPerSector;
DiskSize *= dg.SectorsPerTrack;
DiskSize *= dg.TracksPerCylinder;
DiskSize *= dg.Cylinders.QuadPart;
BytesPerSector = dg.BytesPerSector;
printf(" DiskSize (calculated) = %" FMT_QWORD "\n", DiskSize );
}
else
{
printf("ERROR %s, unable to get drive geometry\n", (LPCSTR) GetLastErrorString() );
return;
}
printf("\n");
BYTE* bMemory = new BYTE[BytesPerSector*2];
assert(bMemory != NULL);
memset( bMemory, 0, BytesPerSector*2 );
memset( bLayout, 0, sizeof(bLayout) );
#ifdef SUPPORT_WINDOWS_XP_PARTITIONS
WCHAR wcGuid[256];
if( GetDriveLayoutEx(bLayout, sizeof(bLayout)) )
{
PDRIVE_LAYOUT_INFORMATION_EX pLI = (PDRIVE_LAYOUT_INFORMATION_EX)bLayout;
printf("Got DRIVE_LAYOUT_INFORMATION_EX\n\n" );
printf(" PartitionCount = %d\n", pLI->PartitionCount );
if( pLI->PartitionStyle == PARTITION_STYLE_GPT )
{
printf(" PartitionStyle = %d (GPT)\n", pLI->PartitionStyle );
StringFromGUID2(pLI->Gpt.DiskId, wcGuid, 256);
printf(" DiskId = %ls\n",wcGuid );
printf(" StartingUsableOffset = %" FMT_QWORD "\n", pLI->Gpt.StartingUsableOffset.QuadPart );
printf(" UsableLength = %" FMT_QWORD "\n", pLI->Gpt.UsableLength.QuadPart );
printf(" MaxPartitionCount = %d\n", pLI->Gpt.MaxPartitionCount );
}
else if( pLI->PartitionStyle == PARTITION_STYLE_MBR )
{
printf(" PartitionStyle = %d (MBR)\n", pLI->PartitionStyle );
printf(" Signature = 0x%08lx\n", pLI->Mbr.Signature );
}
else
{
printf(" PartitionStyle = %d (RAW)\n", pLI->PartitionStyle );
}
for( unsigned long ulPartition = 0; ulPartition < pLI->PartitionCount; ulPartition++ )
{
PARTITION_INFORMATION_EX& p = pLI->PartitionEntry[ulPartition];
if( !p.StartingOffset.QuadPart && !p.PartitionLength.QuadPart )
continue;
printf("\n --- PARTITION %d ---\n\n", ulPartition );
printf(" PartitionStart = %" FMT_QWORD "\n", p.StartingOffset.QuadPart );
printf(" PartitionLength = %" FMT_QWORD " (%.2f MB)\n", p.PartitionLength.QuadPart, PBytesInMBytes(p.PartitionLength.QuadPart) );
if( pLI->PartitionStyle == PARTITION_STYLE_GPT )
{
StringFromGUID2(p.Gpt.PartitionType, wcGuid, 256);
printf(" PartitionType = %ls\n", wcGuid );
StringFromGUID2(p.Gpt.PartitionId, wcGuid, 256);
printf(" PartitionId = %ls\n", wcGuid );
printf(" Attributes = %" FMT_QWORD "\n", (DWORD) p.Gpt.Attributes );
printf(" Name = %ls\n", p.Gpt.Name );
}
else if( pLI->PartitionStyle == PARTITION_STYLE_MBR )
{
printf(" PartitionType = %d\n", (DWORD) p.Mbr.PartitionType );
}
INT64 diskoffset = (p.StartingOffset.QuadPart + REISERFS_DISK_OFFSET_IN_BYTES);
if( !ReadAbsolute(bMemory, BytesPerSector, diskoffset ) )
{
printf("Warning %s, unable to read %d bytes from offset %" FMT_QWORD "\n", (LPCSTR) GetLastErrorString(), BytesPerSector, diskoffset );
}
else
{
printf(" Read %d bytes at offset %" FMT_QWORD "\n", (DWORD) BytesPerSector, diskoffset );
LPREISERFS_SUPER_BLOCK p = (LPREISERFS_SUPER_BLOCK) bMemory;
if( stricmp(p->s_magic,REISERFS_SUPER_MAGIC_STRING) )
{
if( stricmp(p->s_magic,REISER2FS_SUPER_MAGIC_STRING) )
{
printf(" Doesn't seem to be a ReiserFS partition (%08lx %08lx %08lx)\n",
*(LPDWORD)&(p->s_magic[0]), *(LPDWORD)&(p->s_magic[4]), *(LPDWORD)&(p->s_magic[8]) );
}
else
{
printf( " Is ReiserFS partition type 2 (%08lx %08lx %08lx)\n",
*(LPDWORD)&(p->s_magic[0]), *(LPDWORD)&(p->s_magic[4]), *(LPDWORD)&(p->s_magic[8]) );
}
}
else
{
printf( " Is ReiserFS partition type 1 (%08lx %08lx %08lx)\n",
*(LPDWORD)&(p->s_magic[0]), *(LPDWORD)&(p->s_magic[4]), *(LPDWORD)&(p->s_magic[8]) );
}
}
}
}
else
#endif
if( GetDriveLayout(bLayout, sizeof(bLayout)) )
{
PDRIVE_LAYOUT_INFORMATION pLI = (PDRIVE_LAYOUT_INFORMATION)bLayout;
printf("Got DRIVE_LAYOUT_INFORMATION\n\n" );
printf(" PartitionCount = %d\n", pLI->PartitionCount );
printf(" Signature = 0x%08lx\n", pLI->Signature );
for( unsigned long ulPartition = 0; ulPartition < pLI->PartitionCount; ulPartition++ )
{
PARTITION_INFORMATION& p = pLI->PartitionEntry[ulPartition];
if( !p.StartingOffset.QuadPart && !p.PartitionLength.QuadPart )
continue;
printf("\n --- PARTITION %d ---\n\n", ulPartition );
printf(" StartingOffset = %" FMT_QWORD "\n", p.StartingOffset.QuadPart );
printf(" PartitionLength = %" FMT_QWORD " (%.2f MB)\n", p.PartitionLength.QuadPart, PBytesInMBytes(p.PartitionLength.QuadPart) );
printf(" PartitionNumber = %ld\n", p.PartitionNumber );
printf(" PartitionType = %ld\n", (long) p.PartitionType );
INT64 diskoffset = (p.StartingOffset.QuadPart + REISERFS_DISK_OFFSET_IN_BYTES);
if( !ReadAbsolute(bMemory, BytesPerSector, diskoffset ) )
{
printf("Warning %s, unable to read %d bytes from offset %" FMT_QWORD "\n", (LPCSTR) GetLastErrorString(), BytesPerSector, diskoffset );
}
else
{
diskoffset /= BytesPerSector;
printf(" Read %d bytes at offset %" FMT_QWORD "\n", (DWORD) BytesPerSector, diskoffset );
LPREISERFS_SUPER_BLOCK p = (LPREISERFS_SUPER_BLOCK) bMemory;
if( stricmp(p->s_magic,REISERFS_SUPER_MAGIC_STRING) )
{
if( stricmp(p->s_magic,REISER2FS_SUPER_MAGIC_STRING) )
{
printf(" Doesn't seem to be a ReiserFS partition (%08lx %08lx %08lx)\n",
*(LPDWORD)&(p->s_magic[0]), *(LPDWORD)&(p->s_magic[4]), *(LPDWORD)&(p->s_magic[8]) );
}
else
{
printf( " Is ReiserFS partition type 2 (%08lx %08lx %08lx)\n",
*(LPDWORD)&(p->s_magic[0]), *(LPDWORD)&(p->s_magic[4]), *(LPDWORD)&(p->s_magic[8]) );
}
}
else
{
printf( " Is ReiserFS partition type 1 (%08lx %08lx %08lx)\n",
*(LPDWORD)&(p->s_magic[0]), *(LPDWORD)&(p->s_magic[4]), *(LPDWORD)&(p->s_magic[8]) );
}
}
}
}
else
{
printf("ERROR %s, unable to get drive layout\n", (LPCSTR) GetLastErrorString() );
return;
}
}
syntax highlighted by Code2HTML, v. 0.9.1