fijate esta clase, la saqué no recuerdo de donde... je
#include <windows.h>
#include <stdio.h>
#include <ctype.h>
#define VWIN32_DIOC_DOS_IOCTL 1 // specified MS-DOS device I/O ctl - Interrupt 21h Function 4400h - 4411h
#define VWIN32_DIOC_DOS_INT25 2 // Absolute Disk Read command - Interrupt 25h
#define VWIN32_DIOC_DOS_INT26 3 // Absolute Disk Write command - Interrupt 25h
#define VWIN32_DIOC_DOS_INT13 4 // Interrupt 13h commands
#define VWIN32_DIOC_SIMCTRLC 5 // Simulate Ctrl-C
#define VWIN32_DIOC_DOS_DRIVEINFO 6 // Interrupt 21h Function 730X commands
#define CARRY_FLAG 1
#ifndef INVALID_SET_FILE_POINTER
#define INVALID_SET_FILE_POINTER (DWORD)-1
#endif
typedef struct _DISKIO {
DWORD dwStartSector; // starting logical sector number
WORD wSectors; // number of sectors
DWORD dwBuffer; // address of read/write buffer
} DISKIO, * PDISKIO;
typedef struct _DIOC_REGISTERS
{
DWORD reg_EBX;
DWORD reg_EDX;
DWORD reg_ECX;
DWORD reg_EAX;
DWORD reg_EDI;
DWORD reg_ESI;
DWORD reg_Flags;
} DIOC_REGISTERS, *PDIOC_REGISTERS;
struct partial_boot_sector_info{
LPSTR Fs;
DWORD FsOffs;
DWORD SerialOffs;
};
class DiskSectorRW{
public:
virtual bool Open(char *vol) = 0;
virtual void Close() = 0;
virtual bool ReadSector(DWORD sector, char *Buffer, int sectorSize = 512) = 0;
virtual bool WriteSector(DWORD sector, char *buffer, int sectorSize = 512) = 0;
};
class DiskSectorWinNT : public DiskSectorRW
{
private:
HANDLE m_hDisk;
public:
bool Open(char *vol);
void Close();
bool ReadSector (DWORD sector, char *Buffer, int sectorSize = 512);
bool WriteSector(DWORD sector, char *Buffer, int sectorSize = 512);
};
class DiskSectorWin9x : public DiskSectorRW
{
private:
HANDLE m_hVmm32;
bool m_bOpened;
char m_chDrive;
BYTE m_nDriveNo;
bool m_bW9xOsr2AndAbove;
bool m_bUseLocking;
public:
DiskSectorWin9x() : m_bUseLocking(false) { }
bool Open(char *vol);
void Close();
bool ReadSector (DWORD sector, char *Buffer, int sectorSize = 512);
bool WriteSector(DWORD sector, char *Buffer, int sectorSize = 512);
static bool LockLogicalVolume (HANDLE hVWin32, BYTE bDriveNum, BYTE bLockLevel, WORD wPermissions);
static bool UnlockLogicalVolume(HANDLE hVWin32, BYTE bDriveNum);
static bool ReadLogicalSectors (HANDLE hDev, BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff);
static bool WriteLogicalSectors (HANDLE hDev, BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff);
static bool NewReadSectors(HANDLE hDev, BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff);
static bool NewWriteSectors(HANDLE hDev, BYTE bDrive, DWORD dwStartSector, WORD wSectors, LPBYTE lpSectBuff);
};
class DiskSector
{
private:
DiskSectorRW *util;
public:
DiskSector();
~DiskSector();
bool Open(char *vol);
void Close();
bool ReadSector(DWORD sector, char *Buffer, int sectorSize = 512);
bool WriteSector(DWORD sector, char *buffer, int sectorSize = 512);
};
#include "disk.h"
DiskSector::DiskSector()
{
if (GetVersion() > 0x80000000)
util = new DiskSectorWin9x;
else
util = new DiskSectorWinNT;
}
void DiskSector::Close()
{
util->Close();
}
bool DiskSector::Open(char *vol)
{
return util->Open(vol);
}
bool DiskSector::WriteSector(DWORD sector, char *Buffer, int sectorSize)
{
return util->WriteSector(sector, Buffer, sectorSize);
}
bool DiskSector::ReadSector(DWORD sector, char *Buffer, int sectorSize)
{
return util->ReadSector(sector, Buffer, sectorSize);
}
DiskSector::~DiskSector()
{
delete util;
}
/***********************************************************/
bool DiskSectorWinNT::Open(char *vol)
{
char szDrive[10];
sprintf(szDrive
, "\\\\.\\%c:", vol
[0]); m_hDisk = ::CreateFile(
szDrive,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
return m_hDisk != INVALID_HANDLE_VALUE;
}
void DiskSectorWinNT::Close()
{
if (m_hDisk != INVALID_HANDLE_VALUE)
::CloseHandle(m_hDisk);
}
bool DiskSectorWinNT::ReadSector (DWORD sector, char *Buffer, int sectorSize)
{
DWORD read = 0;
if (::SetFilePointer(m_hDisk, sector, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
return false;
if (!::ReadFile(m_hDisk, Buffer, sectorSize, &read, NULL))
return false;
return true;
}
bool DiskSectorWinNT::WriteSector(DWORD sector, char *Buffer, int sectorSize)
{
DWORD wrote = 0;
if (::SetFilePointer(m_hDisk, sector, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
return false;
if (!::WriteFile(m_hDisk, Buffer, sectorSize, &wrote, NULL))
return false;
return true;
}
/***********************************************************/
bool DiskSectorWin9x::Open(char *vol){
m_bOpened = false;
OSVERSIONINFOEX osvi = {0};
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if (!::GetVersionEx((OSVERSIONINFO *)&osvi)){
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (!::GetVersionEx ((OSVERSIONINFO *)&osvi))
return false;
}
if (osvi.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)
return false;
m_nDriveNo = m_chDrive - 'A' + 1;
char temp[10] = {0};
if (::GetDriveType(temp) != DRIVE_FIXED)
return false;
m_bW9xOsr2AndAbove = (osvi.dwMajorVersion >= 4 && osvi.dwMinorVersion >= 10)
||
(
(osvi.dwBuildNumber == 4 && osvi.dwMinorVersion == 0) &&
(osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B')
);
m_hVmm32 = ::CreateFile(
"\\\\.\\VWIN32", // name
0, // access mode
0, // share mode
NULL, // security descriptor
0, // ho to create
FILE_FLAG_DELETE_ON_CLOSE, // file attributes
NULL); // handle to file with att to copy
m_bOpened = (m_hVmm32 != INVALID_HANDLE_VALUE);
return m_bOpened;
}
void DiskSectorWin9x::Close()
{
if (m_bOpened)
::CloseHandle(m_hVmm32);
m_bOpened = false;
}
bool DiskSectorWin9x::ReadLogicalSectors (HANDLE hDev,
BYTE bDrive,
DWORD dwStartSector,
WORD wSectors,
LPBYTE lpSectBuff)
{
BOOL fResult;
DWORD cb;
DIOC_REGISTERS reg = {0};
DISKIO dio = {0};
dio.dwStartSector = dwStartSector;
dio.wSectors = wSectors;
dio.dwBuffer = (DWORD)lpSectBuff;
reg.reg_EAX = bDrive - 1; // Int 25h drive numbers are 0-based.
reg.reg_EBX = (DWORD)&dio; // Drive letter 0 = A, 1 = B 2 = C ect..
reg.reg_ECX = 0xFFFF; // use DISKIO struct
fResult = ::DeviceIoControl(hDev, VWIN32_DIOC_DOS_INT25,
®, sizeof(reg),
®, sizeof(reg), &cb, 0);
// Determine if the DeviceIoControl call and the read succeeded.
fResult = fResult && !(reg.reg_Flags & CARRY_FLAG);
return fResult == TRUE;
}
bool DiskSectorWin9x::WriteLogicalSectors (HANDLE hDev,
BYTE bDrive,
DWORD dwStartSector,
WORD wSectors,
LPBYTE lpSectBuff)
{
BOOL fResult;
DWORD cb;
DIOC_REGISTERS reg = {0};
DISKIO dio = {0};
dio.dwStartSector = dwStartSector;
dio.wSectors = wSectors;
dio.dwBuffer = (DWORD)lpSectBuff;
reg.reg_EAX = bDrive - 1; // Int 26h drive numbers are 0-based.
reg.reg_EBX = (DWORD)&dio;
reg.reg_ECX = 0xFFFF; // use DISKIO struct
fResult = ::DeviceIoControl(hDev, VWIN32_DIOC_DOS_INT26,
®, sizeof(reg),
®, sizeof(reg), &cb, 0);
// Determine if the DeviceIoControl call and the write succeeded.
fResult = fResult && !(reg.reg_Flags & CARRY_FLAG);
return fResult == TRUE;
}
bool DiskSectorWin9x::NewReadSectors(HANDLE hDev,
BYTE bDrive,
DWORD dwStartSector,
WORD wSectors,
LPBYTE lpSectBuff)
{
BOOL fResult;
DWORD cb;
DIOC_REGISTERS reg = {0};
DISKIO dio;
dio.dwStartSector = dwStartSector;
dio.wSectors = wSectors;
dio.dwBuffer = (DWORD)lpSectBuff;
reg.reg_EAX = 0x7305; // Ext_ABSDiskReadWrite
reg.reg_EBX = (DWORD)&dio;
reg.reg_ECX = (DWORD)-1;
reg.reg_EDX = bDrive; // Int 21h, fn 7305h drive numbers are 1-based
fResult = ::DeviceIoControl(hDev, VWIN32_DIOC_DOS_DRIVEINFO,
®, sizeof(reg),
®, sizeof(reg), &cb, 0);
// Determine if the DeviceIoControl call and the read succeeded.
fResult = fResult && !(reg.reg_Flags & CARRY_FLAG);
return fResult == TRUE;
}
bool DiskSectorWin9x::NewWriteSectors(HANDLE hDev,
BYTE bDrive,
DWORD dwStartSector,
WORD wSectors,
LPBYTE lpSectBuff)
{
BOOL fResult;
DWORD cb;
DIOC_REGISTERS reg = {0};
DISKIO dio;
dio.dwStartSector = dwStartSector;
dio.wSectors = wSectors;
dio.dwBuffer = (DWORD)lpSectBuff;
reg.reg_EAX = 0x7305; // Ext_ABSDiskReadWrite
reg.reg_EBX = (DWORD)&dio;
reg.reg_ECX = (DWORD)-1;
reg.reg_EDX = bDrive; // Int 21h, fn 7305h drive numbers are 1-based
reg.reg_ESI = 0x6001; // Normal file data/write (See function
// documentation for other values)
fResult = ::DeviceIoControl(hDev, VWIN32_DIOC_DOS_DRIVEINFO,
®, sizeof(reg),
®, sizeof(reg), &cb, 0);
// Determine if the DeviceIoControl call and the write succeeded.
fResult = fResult && !(reg.reg_Flags & CARRY_FLAG);
return fResult == TRUE;
}
bool DiskSectorWin9x::LockLogicalVolume (HANDLE hVWin32,
BYTE bDriveNum,
BYTE bLockLevel,
WORD wPermissions)
{
BOOL fResult;
DIOC_REGISTERS regs = {0};
BYTE bDeviceCat; // can be either 0x48 or 0x08
DWORD cb;
bDeviceCat = 0x48;
ATTEMPT_AGAIN:
// Set up the parameters for the call.
regs.reg_EAX = 0x440D;
regs.reg_EBX = MAKEWORD(bDriveNum, bLockLevel);
regs.reg_ECX = MAKEWORD(0x4A, bDeviceCat);
regs.reg_EDX = wPermissions;
fResult = ::DeviceIoControl (hVWin32, VWIN32_DIOC_DOS_IOCTL,
®s, sizeof(regs), ®s, sizeof(regs),
&cb, 0);
fResult = fResult && !(regs.reg_Flags & CARRY_FLAG);
if (!fResult && (bDeviceCat != 0x08)){
bDeviceCat = 0x08;
goto ATTEMPT_AGAIN;
}
return fResult == TRUE;
}
bool DiskSectorWin9x::UnlockLogicalVolume (HANDLE hVWin32, BYTE bDriveNum)
{
BOOL fResult;
DIOC_REGISTERS regs = {0};
BYTE bDeviceCat; // can be either 0x48 or 0x08
DWORD cb;
bDeviceCat = 0x48;
ATTEMPT_AGAIN:
regs.reg_EAX = 0x440D;
regs.reg_EBX = bDriveNum;
regs.reg_ECX = MAKEWORD(0x6A, bDeviceCat);
fResult = ::DeviceIoControl (hVWin32, VWIN32_DIOC_DOS_IOCTL,
®s, sizeof(regs), ®s, sizeof(regs),
&cb, 0);
fResult = fResult && !(regs.reg_Flags & CARRY_FLAG);
if (!fResult && (bDeviceCat != 0x08)){
bDeviceCat = 0x08;
goto ATTEMPT_AGAIN;
}
return fResult == TRUE;
}
bool DiskSectorWin9x::ReadSector (DWORD sector, char *Buffer, int sectorSize)
{
if (!m_bOpened)
return false;
if (m_bUseLocking)
{
if (!LockLogicalVolume(m_hVmm32, m_nDriveNo, 1, 1))
return false;
if (!LockLogicalVolume(m_hVmm32, m_nDriveNo, 2, 0))
{
UnlockLogicalVolume(m_hVmm32, m_nDriveNo);
return false;
}
}
bool bRet;
if (m_bW9xOsr2AndAbove)
bRet = NewReadSectors(m_hVmm32, m_nDriveNo, sector, 1, (LPBYTE)Buffer);
else
bRet = ReadLogicalSectors(m_hVmm32, m_nDriveNo, sector, 1, (LPBYTE)Buffer);
if (m_bUseLocking)
{
UnlockLogicalVolume(m_hVmm32, m_nDriveNo);
UnlockLogicalVolume(m_hVmm32, m_nDriveNo);
}
return bRet;
}
bool DiskSectorWin9x::WriteSector (DWORD sector, char *Buffer, int sectorSize)
{
if (!m_bOpened)
return false;
if (!LockLogicalVolume(m_hVmm32, m_nDriveNo, 1, 1))
return false;
if (!LockLogicalVolume(m_hVmm32, m_nDriveNo, 2, 0))
{
UnlockLogicalVolume(m_hVmm32, m_nDriveNo);
return false;
}
if (!LockLogicalVolume(m_hVmm32, m_nDriveNo, 3, 0))
{
UnlockLogicalVolume(m_hVmm32, m_nDriveNo);
UnlockLogicalVolume(m_hVmm32, m_nDriveNo);
return false;
}
bool bRet;
if (m_bW9xOsr2AndAbove)
bRet = NewWriteSectors(m_hVmm32, m_nDriveNo, sector, 1, (LPBYTE) Buffer);
else
bRet = WriteLogicalSectors(m_hVmm32, m_nDriveNo, sector, 1, (LPBYTE) Buffer);
UnlockLogicalVolume(m_hVmm32, m_nDriveNo);
UnlockLogicalVolume(m_hVmm32, m_nDriveNo);
UnlockLogicalVolume(m_hVmm32, m_nDriveNo);
return bRet;
}
S2
PD: cabe aclarar que tenes que tener permisos administrativos al usar el código.
PD2: con esto solo accedes al los datos raw del disco, luego tenes que analizar la cabecera de las particiones, detectar el tipo (FAT, NTFS) y según eso ver la lista de nodos de archivos... en google había visto algunos ejemplos hace un tiempo.