48889 (588618), страница 6
Текст из файла (страница 6)
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
double GetFreeSpaceEx(PDISC_INFO info)//
{
unsigned long i;
double RET;
double freeclusters = 0;
double clusters = info->sizeFATbytes / 4;
if (clusters == 0) return 0;
for(i=0;i if(!info->pFAT[i])freeclusters++; RET=(freeclusters * info->BytesPerCluster); RET /= (1024*1024); return RET; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //инициализирует структуру DISC_INFO PDISC_INFO Fat32Init(char disc) { char LogicalDiskName[]="\\\\.\\X:"; char RootDir[]="X:"; UCHAR buf[2048]; UCHAR signature1; //66 USHORT signature2; //510 UCHAR signature3; //38 UINT i,n; PDISC_INFO info=(_DISC_INFO*)malloc(sizeof(DISC_INFO)); info->Disc=disc; LogicalDiskName[4]=disc; RootDir[0]=disc; info->hDrive=CreateFile( LogicalDiskName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if(info->hDrive==INVALID_HANDLE_VALUE) { AnalyzeError("# Error at CreateFile: ",GetLastError()); free(info); return NULL; } GetDiskFreeSpace(RootDir,NULL,(unsigned long*)&(info->nBytePerSector),NULL,NULL); if(!Fat32DataRead(info, buf, info->nBytePerSector)) { CloseHandle(info->hDrive); free(info); return NULL; } //bFAT16 signature3=*(UCHAR*)&buf[38]; signature1=*(UCHAR*)&buf[66]; signature2=*(USHORT*)&buf[510]; if(signature2!=0xAA55) { //printf("# 55AA sig n'found"); CloseHandle(info->hDrive); free(info); return NULL; } if((signature3==0x29) && (signature1!=0x29)) { //printf("YAAHO!! FAT16!!!!!!!!!"); info->bFAT16 = TRUE; info->sizeFAT = *(short*)&buf[22]; info->nRootElements = *(short*)&buf[17]; }else{ if(signature1 != 0x29) { //printf("# unknown FS"); free(info); return NULL; } info->bFAT16 = FALSE; info->sizeFAT=*(short*)&buf[36]; } info->nFATCopy=*(short*)&buf[16]; info->sizeReserved=*(short*)&buf[14]; info->SectPerCluster=*(char*)&buf[13]; info->BytesPerCluster=(info->SectPerCluster)*(info->nBytePerSector); info->beginFAT=info->sizeReserved; i=info->nBytePerSector; n=0; while(i=i/2)n++; info->bitsPerSector=n; if(!LoadFAT(info)) { CloseHandle(info->hDrive); free(info); return NULL; } if(info->bFAT16) { info->RootSector = info->beginFAT + info->nFATCopy * info->sizeFAT; info->RootCluster = 0; } else { info->RootCluster=*(int*)&buf[44]; info->RootSector = 0; } info->hRootDir=LoadDirectory(info, info->RootCluster,&(info->dwRootDirSize)); info->prcfree = GetFreeSpaceEx(info); return info; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //возвращает кластер директории расположенной по пути cpPath UINT GotoDir(PDISC_INFO info, char* cpPath) { UINT i,dwLen=strlen(cpPath); char* pStr=(char*)malloc(dwLen+2); char* cpDirName=pStr; UINT DirCluster; ULONG dwDirSize; HDIR hDir; hDir=info->hRootDir; dwDirSize=info->dwRootDirSize; strcpy(pStr,cpPath); if(pStr[dwLen-1]!='\\') { strcat(pStr,"\\"); dwLen++; } for(i=0;i { if(pStr[i]=='\\') { pStr[i]=0; DirCluster=ListDirectory(info, hDir,dwDirSize,cpDirName, NULL); if(hDir!=info->hRootDir)free(hDir); if(!DirCluster) { //printf("# error directory %s not found",cpDirName); free(pStr); return 0; } if(i==(dwLen-1)) { free(pStr); return DirCluster; } hDir=LoadDirectory(info, DirCluster, &dwDirSize); cpDirName=pStr+i+1; } } free(pStr); return 0; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ void Fat32DeInit(PDISC_INFO info) { free(info->pFAT); free(info->hRootDir); CloseHandle(info->hDrive); free(info); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ PFILES PrintRootDirectory(PDISC_INFO info) { PFILES pfirst = NULL; ListDirectory(info, info->hRootDir, info->dwRootDirSize, NULL, &pfirst); return pfirst; } MBRMODULE.CPP #include //#include "mbrmodule.h" #include "err.h" char FAT[]="\x01\x04\x06\x0D\x0E"; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //Узнать диск по серийному номеру char GetDiscBySN(UINT SN) { UINT VolumeSerialNumber; char Drive[4]="X:\\"; int i; for(i=2;i<25;i++) if((GetLogicalDrives()&(1< { Drive[0] = 'A'+i; switch(GetDriveType(Drive)) { case DRIVE_CDROM: break; default: GetVolumeInformation(Drive, NULL,0, (unsigned long*)&VolumeSerialNumber, NULL,0,NULL,0 ); if(VolumeSerialNumber==SN) return Drive[0]; } } return 0; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //Узнать файловую систему диска по коду файловой системы char* GetFileSystem(unsigned char code) { int i; if((code==0x07)||(code==0x17)) return "NTFS "; if(code==0x82) return "ext2 "; if(code==0x83) return "ext3 "; if((code==0x0B)||(code==0x0C)) return "FAT32 "; for(i=0;i if(code==FAT[i]) return "FAT "; return "? "; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //сдвинуть указатель int MovePointer(PHARDINFO inf, UINT secpointer) { UINT iErr; UINT HiPointer=secpointer>>(32-inf->bitsPerSector); UINT LoPointer=secpointer UINT bRetValue=SetFilePointer(inf->hDrive,LoPointer,(long*)&HiPointer,FILE_BEGIN); if(bRetValue==-1) { iErr=GetLastError(); if(iErr!=NO_ERROR) { //printf("# error at SetFilePointer: "); AnalyzeError(NULL,iErr); } } return bRetValue; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //Читать один сектор с жесткого диска void* RawRead(PHARDINFO inf) { UINT iErr, SectorSize, nRead, i, n; void* buf; SectorSize=inf->dwSectorSize; if(!SectorSize)SectorSize=0x200; buf=malloc(SectorSize); while(!ReadFile(inf->hDrive, buf, SectorSize, (unsigned long*)&nRead, NULL)) { iErr=GetLastError(); free(buf); if((iErr==ERROR_INVALID_PARAMETER)&&(SectorSize<0x8000)) { SectorSize=SectorSize*2; buf=malloc(SectorSize); continue; } //printf("# error at ReadFile: "); AnalyzeError(NULL,iErr); return NULL; }; if(inf->dwSectorSize!=SectorSize) { i=SectorSize; n=0; while(i=i/2)n++; inf->bitsPerSector=n; inf->dwSectorSize=SectorSize; } return buf; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*Изъять серийный номер для FAT или NTFS abs_addr - адрес начала логического диска в секторах Serial - адрес 8-байтного буфера для серийного номера id - идентификатор файловой системы */ BOOL GetDiscSerial(PHARDINFO inf, UINT abs_addr, UCHAR* Serial, UCHAR id) { char* buf; int i; if(MovePointer(inf,abs_addr)==-1)return FALSE; if((buf=(char*)RawRead(inf))==NULL)return FALSE; switch(id) { case 0x07: //NTFS memcpy(Serial,buf+72,8); break; case 0x0E: case 0x0C: case 0x0B: //FAT32 memcpy(Serial,buf+67,4); break; default: for(i=0;i if(id==FAT[i]) { memcpy(Serial,buf+39,4); free(buf); return TRUE; } return FALSE; } free(buf); return TRUE; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ void DeInit(PHARDINFO inf) { CloseHandle(inf->hDrive); free(inf); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //Вывести список разделов из Partition Table в MBR PLOGICAL_DISC ListMBR(PHARDINFO inf, UCHAR* pMBR, UINT dwMBRAddr, UINT* pExtended, PPLOGICAL_DISC last) { UCHAR* pPart; UCHAR id,active; UINT ext=0,secBegin,secLength,mbLength=0,gbLength=0; PLOGICAL_DISC first=NULL, pld=NULL, pred=NULL; UINT SectorSize,abs_addr,SN4; UCHAR SN[8]; char* cpFS; int i; SectorSize=inf->dwSectorSize; pPart=pMBR+0x01BE; for(i=0;i<4;i++) { id=pPart[4]; if(!id) { pPart+=0x10; continue; } secBegin=*(UINT*)&pPart[8]; secLength=*(UINT*)&pPart[12]; active=pPart[0]; if(active)active='+'; else active='-'; pPart+=0x10; mbLength=secLength/(2*1024)*SectorSize/512; gbLength=mbLength/1024; abs_addr=dwMBRAddr+secBegin; cpFS=GetFileSystem(id); if((id==0x0F)||(id==0x05)) { ext=secBegin; continue; } memset(SN,0,sizeof(SN)); GetDiscSerial(inf,abs_addr,SN,id); memcpy(&SN4,SN,4); pred = pld; pld =(_LOGICAL_DISC*) malloc(sizeof(LOGICAL_DISC)); memset(pld, 0, sizeof(LOGICAL_DISC)); if(pred!=NULL) pred->next = pld; else first = pld; pld->nHard = inf->nHard; pld->nDisc = SN4?GetDiscBySN(SN4):'?'; pld->active = active; pld->abs_addr = abs_addr; pld->secLength = secLength; pld->id = id; pld->cpFS = cpFS; pld->SN4 = SN4; pld->gbLength = gbLength; pld->mbLength = mbLength; pld->next = NULL; } *pExtended = ext; *last = pld; return first; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //Печатать заголовок void PrintHead() { //printf("HDD Disc Boot Addr Size FS SN mb/gb\n"); //printf("------------------------------------------------------------------------\n"); } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //Проверить сигнатуру BOOL CheckMBR(UCHAR* pMBR) { BOOL bRetValue=*(USHORT*)(pMBR+0x01FE)==0xAA55; // if(!bRetValue)printf("# not valid MBR\n"); return bRetValue; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ //Пройтись по цепочке MBR BOOL WalkOnMBR(PHARDINFO inf, PPLOGICAL_DISC first) { PLOGICAL_DISC pred=NULL, last=NULL; UINT ext,dwNextMBRAddr; void* pMBR; *first = NULL; if((pMBR=RawRead(inf))==NULL)return FALSE; if(!CheckMBR((unsigned char*)pMBR)) { free(pMBR); return FALSE; } if((*first=ListMBR(inf,(unsigned char*)pMBR,0,&ext,&last))&&ext) { inf->dwExtendedAddr=ext; ext=0; while(1) { free(pMBR); dwNextMBRAddr=ext+inf->dwExtendedAddr; if(MovePointer(inf,dwNextMBRAddr)==-1)return FALSE; if((pMBR=RawRead(inf))==NULL)return FALSE; if(!CheckMBR((unsigned char*)pMBR)) { free(pMBR); return FALSE; } pred = last; pred->next = ListMBR(inf,(unsigned char*)pMBR,dwNextMBRAddr,&ext,&last); if(!ext)break; } } free(pMBR); return TRUE; } /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ PHARDINFO Init(char n) { char HardDiskName[]="\\\\.\\PHYSICALDRIVE0"; void* hDrive; UINT iErr, dwSectorSize; PHARDINFO inf; HardDiskName[sizeof(HardDiskName)-2]=n+'0'; hDrive=CreateFile( HardDiskName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); if(hDrive==INVALID_HANDLE_VALUE) { iErr=GetLastError(); if(iErr==ERROR_FILE_NOT_FOUND)return NULL; AnalyzeError("# Error at CreateFile: ",iErr); return NULL; } inf=(_HARDINFO*)malloc(sizeof(HARDINFO)); inf->hDrive=hDrive; inf->nHard=n; inf->dwSectorSize=0; WalkOnMBR(inf, &inf->disklist); return inf;}