|  | 
| 我的 Windows 编译环境建立不起来,没有缘分,已经放弃。目前我的兴趣已经彻底转到 Linux 下了。在 Linux 下可做的事多着呢,根本忙不过来,恐怕以后再也没有机会回到 Windows 下编程了。
 
 我把你提供的代码贴出来,方便有兴趣者查看。
 
 复制代码// mdisk.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <shellapi.h>
//#include <winable.h>
typedef BOOL(WINAPI *INITIALIZEWINTO)(void);
typedef BOOL(WINAPI *SHUTDOWNWINIO)(void);
typedef BOOL(WINAPI *GETPORTVAL)(WORD wPortAddr, PDWORD pdwPortVal, BYTE bSize);
typedef BOOL(WINAPI *SETPORTVAL)(WORD wPortAddr, DWORD dwPortVal, BYTE bSize);
typedef PBYTE(_stdcall *MAPPHYSTOLIN)(PBYTE pbPhysAddr, DWORD dwPhysSize, HANDLE *pPhysicalMemoryHandle);  
typedef BOOL(_stdcall *UNMAPPHYSICALMEMORY)(HANDLE PhysicalMemoryHandle, PBYTE pbLinAddr);  
typedef BOOL(WINAPI *GETPHYSLONG)(PBYTE pbPhysAddr, PDWORD pdwPhysVal);  
typedef BOOL(WINAPI *SETPHYSLONG)(PBYTE pbPhysAddr, DWORD dwPhysVal); 
//typedef BOOL(WINAPI *INSTALLWINIODRIVER)(PWSTR pszWinIoDriverPath, bool IsDemandLoaded = false);   
//typedef BOOL(WINAPI *REMOVEWINIODRIVER)();  
INITIALIZEWINTO   InitializeWinIo = NULL;
SHUTDOWNWINIO        ShutdownWinIo = NULL;
GETPORTVAL  GetPortVal = NULL;
SETPORTVAL  SetPortVal = NULL;
MAPPHYSTOLIN MapPhysToLin = NULL;   
UNMAPPHYSICALMEMORY UnmapPhysicalMemory = NULL;  
GETPHYSLONG GetPhysLong = NULL;
SETPHYSLONG SetPhysLong = NULL;
//INSTALLWINIODRIVER InstallWinIoDriver = NULL; 
//REMOVEWINIODRIVER RemoveWinIoDriver = NULL;
BOOL InitFuncs(void)
{
        HMODULE hMod = LoadLibrary(_T("WinIo32.dll"));
    InitializeWinIo= (INITIALIZEWINTO)GetProcAddress(hMod,"InitializeWinIo");
        ShutdownWinIo= (SHUTDOWNWINIO)GetProcAddress(hMod,"ShutdownWinIo");
    GetPortVal= (GETPORTVAL)GetProcAddress(hMod,"GetPortVal");
        SetPortVal= (SETPORTVAL)GetProcAddress(hMod,"SetPortVal");
        MapPhysToLin=(MAPPHYSTOLIN)GetProcAddress(hMod,"MapPhysToLin");  
        UnmapPhysicalMemory=(UNMAPPHYSICALMEMORY)GetProcAddress(hMod,"UnmapPhysicalMemory");  
        GetPhysLong=(GETPHYSLONG)GetProcAddress(hMod,"GetPhysLong");  
        SetPhysLong=(SETPHYSLONG)GetProcAddress(hMod,"SetPhysLong");  
        //InstallWinIoDriver=(INSTALLWINIODRIVER)GetProcAddress(hMod,"InstallWinIoDriver");        
        //RemoveWinIoDriver=(REMOVEWINIODRIVER)GetProcAddress(hMod,"RemoveWinIoDriver");  
        if(InitializeWinIo==NULL) return FALSE;
        if(ShutdownWinIo==NULL) return FALSE;
        if(GetPortVal==NULL) return FALSE;
        if(SetPortVal==NULL) return FALSE;
        if(MapPhysToLin==NULL) return FALSE;
        if(UnmapPhysicalMemory==NULL) return FALSE;
        if(GetPhysLong==NULL) return FALSE;
        if(SetPhysLong==NULL) return FALSE;
        //if(InstallWinIoDriver==NULL) return FALSE;
        //if(RemoveWinIoDriver==NULL) return FALSE;
        
        return TRUE;
}
BOOL ReadPhysicalMemory(unsigned int phyAddr, DWORD phySize, unsigned char *buf)
{
        unsigned int addr;
        unsigned long data;
        unsigned long *p=(unsigned long *)buf;
        for(unsigned int i=0;i<phySize;i+=4)
        {
                addr=phyAddr+i;
                GetPhysLong((PBYTE)addr,&data);
                *p=data;
                p++;
        }
        return TRUE;
}
void print_buf(unsigned char *p)
{
        for(int k=0;k<200;k++)
        {
                printf("%c",*(p+k));
        }
        printf("\n");
}
void find_g4d_drive(unsigned char* buf, int bufLen);
int _tmain(int argc, _TCHAR* argv[])
{
    if(InitFuncs()!=TRUE)
        {
                printf("Load WinIo.dll failed!\n");
                return 0;
        }
    if(InitializeWinIo()!=TRUE)
        {
                printf("InitializeWinIo failed!\n");
                return 0;
        }
        printf("InitializeWinIo OK!\n");
        printf("\n");
        //printf("DWORD length=%d\n",sizeof(DWORD));
#if 0        
        HANDLE hPhyMem;
        PBYTE pbLinAddr;
        //下面的语句让 0xf0000 地址的 65536 个字节可直接读写
    pbLinAddr = MapPhysToLin((unsigned char *)0xf0000,65536,&hPhyMem);
        printf("pbLinAddr=%x\n",pbLinAddr);
        DWORD ttmp;
        BOOL rtv;
        rtv=GetPhysLong((PBYTE)0xf0000,&ttmp);
        printf("rtv=%d, ttmp=%x\n",rtv, ttmp);
        
#endif        
        // real-mode RAM range 0-640KB
    const int nBytes=0xA0000;
        unsigned char buf[nBytes];
        memset(buf,0,nBytes);
        ReadPhysicalMemory(0,nBytes,buf);
    //print_buf(buf);
    find_g4d_drive(buf,nBytes);
        ShutdownWinIo();
        printf("Done!\n");
        return 0;
}
typedef struct _INTRVECT { 
        UINT16 offset; 
        UINT16 segment; 
} INTRVECT, *PINTRVECT;
typedef struct _GRUB4DOS_DRIVE_MAP_SLOT {
        unsigned char from_drive;
        unsigned char to_drive;                        // 0xFF indicates a memdrive
        unsigned char max_head;
        unsigned char max_sector:6,
                disable_lba:1,                // bit 6: disable lba
                read_only:1;                // bit 7: read only 
        unsigned short to_cylinder:13,        // max cylinder of the TO drive
                from_cdrom:1,                // bit 13: FROM drive is CDROM(with big 2048-byte sector)
                to_cdrom:1,                        // bit 14:  TO  drive is CDROM(with big 2048-byte sector)
                to_support_lba:1;        // bit 15:  TO  drive support LBA
        unsigned char to_head;                        // max head of the TO drive
        unsigned char to_sector:6,                // max sector of the TO drive
                fake_write:1,                // bit 6: fake-write or safe-boot
                in_situ:1;                        // bit 7: in-situ
        UINT64 start_sector;
        UINT64 sector_count;
} GRUB4DOS_DRIVE_MAP_SLOT, *PGRUB4DOS_DRIVE_MAP_SLOT;
void print_drv_map(PGRUB4DOS_DRIVE_MAP_SLOT slot)
{
        int dataLen=sizeof(GRUB4DOS_DRIVE_MAP_SLOT);
        printf("DATA: ");
        for(int k=0;k<dataLen;k++)
        {
                printf("%.2X ", *((unsigned char *)slot+k) );
        }
        printf("\n");
        UINT64 drvlen=slot->sector_count<<9;
        UINT64 address=slot->start_sector<<9;
        printf("Detected GRUB4DOS disk offset=0x%I64x bytes, len=%I64d KB\n",address, drvlen>>10);
        
    printf("   GRUB4DOS SourceDrive: 0x%02x\n", slot->from_drive);
    printf("   GRUB4DOS DestDrive: 0x%02x\n", slot->to_drive);
    printf("   GRUB4DOS MaxHead: %d\n", slot->max_head);
    printf("   GRUB4DOS MaxSector: %d\n", slot->max_sector);
    printf("   GRUB4DOS DestMaxCylinder: %d\n", slot->to_cylinder);
    printf("   GRUB4DOS DestMaxHead: %d\n", slot->to_head);
    printf("   GRUB4DOS DestMaxSector: %d\n", slot->to_sector);
    printf("   GRUB4DOS SectorStart: 0x%08x\n", slot->start_sector);
    printf("   GRUB4DOS SectorCount: %d\n", slot->sector_count);
    printf("\n");
        printf("   GRUB4DOS disable_lba=%d\n", slot->disable_lba);
        printf("   GRUB4DOS read_only=%d\n", slot->read_only);
        printf("   GRUB4DOS from_cdrom=%d\n", slot->from_cdrom);
        printf("   GRUB4DOS to_cdrom=%d\n", slot->to_cdrom);
        printf("   GRUB4DOS to_support_lba=%d\n", slot->to_support_lba);
        printf("   GRUB4DOS fake_write=%d\n", slot->fake_write);
        printf("   GRUB4DOS in_situ=%d\n", slot->in_situ);
}
void print_vector(INTRVECT * pvec)
{
        printf("offset=0x%.4x  ", pvec->offset);
        printf("segment=0x%.4x", pvec->segment);
        printf("\n");
}
void print_string(unsigned char *buf,UINT32 int13entry)
{
        unsigned char tmp_str[9];
    memset(tmp_str,0,9);
        memcpy(tmp_str,buf+int13entry+3,8);
        printf("%s  ",tmp_str);
    memset(tmp_str,0,9);
        memcpy(tmp_str,buf+int13entry+3+8,8);
        printf("%s\n",tmp_str);
}
int check_string(unsigned char *buf,UINT32 int13entry)
{
        int cmp=-1;
        
        unsigned char tmp_str[9];
    memset(tmp_str,0,9);
        memcpy(tmp_str,buf+int13entry+3,8);
        cmp = strcmp((char *)tmp_str,"$INT13SF");
        if(cmp!=0) return 0;
        memset(tmp_str,0,9);
        memcpy(tmp_str,buf+int13entry+3+8,8);
        cmp = strcmp((char *)tmp_str,"GRUB4DOS");
        if(cmp==0)
        {
                //printf("Found GRUB4DOS\n");
                return 1;
        }
        return 0;
}
void find_g4d_drive(unsigned char* buf, int bufLen)
{
        //bufLen=0xA0000;  //640K
        INTRVECT int13vector;
        UINT32 int13entry;
        int found=0;
        /*for(int kk=0;kk<0x40;kk++)
        {
        int13vector = ((PINTRVECT)buf)[kk];        
        int13entry = (((UINT32)int13vector.segment << 4) + int13vector.offset);        
        printf("int13entry=0x%lX [%.4X:%.4X]\n",int13entry,int13vector.segment,int13vector.offset);
        }
        printf("\n");
        return;
        */
        
        int13vector = ((PINTRVECT)buf)[0x13];        
        int13entry = (((UINT32)int13vector.segment << 4) + int13vector.offset);
        while(int13entry<0xA0000-27)
        {
                //if(int13entry==0) continue;
                printf("int13entry=0x%lX [%.4X:%.4X]\n",int13entry,int13vector.segment,int13vector.offset);
                found=check_string(buf,int13entry);
                if(found==1)
                {
                        PGRUB4DOS_DRIVE_MAP_SLOT pdrvmap;
                        //drive map slot starts at offset 0x20 of the same segment as int13 entry
                        pdrvmap = (PGRUB4DOS_DRIVE_MAP_SLOT)(buf+(((UINT32)int13vector.segment << 4) + 0x20));                        
                        printf("Found GRUBDOS drive at offset 0x%lX [%.4X:%.4X], data length=%d bytes\n",
                                (unsigned char *)pdrvmap-buf,int13vector.segment,0x20,
                                sizeof(GRUB4DOS_DRIVE_MAP_SLOT) );
                        printf("\n");
                    print_drv_map(pdrvmap);
                        printf("\n");
                        
                }
                int13vector = *((UNALIGNED INTRVECT *)(buf+int13entry+3+8+8));
                int13entry = (((UINT32)int13vector.segment << 4) + int13vector.offset);
                //printf("==>int13entry=0x%lX [%.4X:%.4X]\n",int13entry,int13vector.segment,int13vector.offset);
        
        }
}
 | 
 |