線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1672
推到 Plurk!
推到 Facebook!

讀取FAT12,16根源程式

 
jackkcg
站務副站長


發表:891
回覆:1050
積分:848
註冊:2002-03-23

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-04-09 15:27:01 IP:61.221.xxx.xxx 未訂閱
此為轉貼資料 http://depos.patching.net/showart.asp?art_id=72&cat_id=2 讀取FAT12,16根源程式<1> // //檔案名稱: fat.c //版本: 00.00.01 // //FAT文件系統. // 蔡軍生 // 20021218 --- 20021222 // #include <_krnl.h> //bool定義. #include // 調試巨集定義. #include //硬碟 #include // FAT文件系統. #include /* memcpy(), memsetw() */ //來自: MM.C void* kmalloc(size_t size); // //邏輯驅器鏈表. // static CDosDriver g_DosDriver; // //邏輯磁區到物理磁區轉換(C,H,S). // // C柱面號 = 邏輯磁區號 /( 每磁軌磁區數 * 磁頭數) // H磁頭號 = (邏輯磁區號 / 每磁軌磁區數) % 磁頭數 // S磁軌記憶體磁區號 = 邏輯磁區號 % 每磁軌磁區數 1 void FAT_RelSecToCHS(int nSec,int* pCylinder,int* pHead,int* pSect); // //讀取C盤分區. // void FAT_ReadDiskC(void); // //識別FAT12,FAT16,FAT32. // int IsFatType(unsigned char* pBuf); // //讀取FAT到記憶體. // void FAT_ReadFatToBuf(void); // //取得根目錄表. // void FAT_ReadRootDirToBuf(void); // //格式化目錄項輸出 // void FAT_FormatRootEnt(CRootEnt* pRootEnt,char* pBuf); // //格式化目錄項日期和時間字串. // char* FAT_FormatDatetime(CRootEnt* pRootEnt); /////////////////////////////////////////////////////////////////////////// // //初始化文件系統. // void FAT_Init(void) { //取得硬碟分區表. HD_PartTableFour* pPartTable = HD_GetPartTable(); KTRACE("BootID = 0xX\n",pPartTable->ptTable1.byteBootID); // FAT_ReadDiskC(); } // //讀取WINDOWS分區表.可以從MicroSoft的文件文檔得到. // //讀取C:分區. // void FAT_ReadDiskC(void) { unsigned char nBuf[512];//C:分區第一個引導磁區. //取得主驅動器參數. HD_Info* pIDE0 = HD_GetIDE0(); //取得硬碟分區表. HD_PartTableFour* pPartTable = HD_GetPartTable(); //設置C:分區資訊. g_DosDriver.nSizeSelf = sizeof(CDosDriver); memcpy(g_DosDriver.cName,"C:",3); g_DosDriver.nStartSec = pPartTable->ptTable1.byteSectorStart;//開始磁區 g_DosDriver.nStartHead = pPartTable->ptTable1.byteHeadStart;//開始磁頭 g_DosDriver.nStartCylinder = (pPartTable->ptTable1.byteSectorStart & 0xC0) << 2 | pPartTable->ptTable1.byteCylinderStart;//開始柱面. //保存本驅動器參數. g_DosDriver.nHead = pIDE0->wHead;//磁頭數. g_DosDriver.nSecPerTrk = pIDE0->wSectPerTrack;//每道多少磁區數. KTRACE("pIDE0->wSectPerTrack=%d\t",pIDE0->wSectPerTrack); //讀C:分區第一個引導磁區.其中包含有Boot sector和 //BPB結構. HD_ReadWrite( CMD_READ,//讀取命令. 0,//0,主硬碟驅動器, 1,//讀取一個磁區. g_DosDriver.nStartSec,//開始磁區 g_DosDriver.nStartHead,//開始磁頭 g_DosDriver.nStartCylinder,//開始柱面. nBuf);//保存讀取的資料. // g_DosDriver.iFatType = IsFatType(nBuf); KTRACE("FAT%d\n",g_DosDriver.iFatType); //邏輯磁區開始位置. //邏輯磁區號 = (物理磁區號-1) 物理磁頭號*每道磁區數 物理磁頭號*每道磁區數*磁頭數. g_DosDriver.nStartSecRel = (g_DosDriver.nStartSec -1) g_DosDriver.nStartHead*g_DosDriver.nSecPerTrk g_DosDriver.nStartCylinder*g_DosDriver.nSecPerTrk*g_DosDriver.nHead; KTRACE("g_DosDriver.nStartSecRel=%d\n",g_DosDriver.nStartSecRel); //讀FAT. FAT_ReadFatToBuf(); //讀取根目錄. FAT_ReadRootDirToBuf(); // while(1);//for test. } // //識別FAT12,FAT16,FAT32. // int IsFatType(unsigned char* pBuf) { DWORD dwRootDirSectors;//根目錄所占磁區數. DWORD dwFatsz;// DWORD dwTotSec;//總磁區. DWORD dwCountOfClusters;//資料區有多少簇. CBootSecBPB1216* pBs = (CBootSecBPB1216*) pBuf; CBootSecBPB32* pBs32 = (CBootSecBPB32*) pBuf; //計算根目錄佔用的磁區數. dwRootDirSectors = ( *((WORD*)pBs->bpb.BPB_RootEntCnt) * 32 *((WORD*)pBs->bpb.BPB_BytePerSec)-1 )/ *((WORD*)pBs->bpb.BPB_BytePerSec); KTRACE("RootDirSectors:%d\n",dwRootDirSectors); //取得每個FAT磁區數 if( *((WORD*)pBs->bpb.BPB_FatSz16) != 0)//FAT12,FAT16 { dwFatsz = *((WORD*)pBs->bpb.BPB_FatSz16); } else//FAT32 { dwFatsz = *((DWORD*)pBs32->bs.BPB_FATSz32); } //取得總共磁區數. if( *((WORD*)pBs->bpb.BPB_TotSec16) != 0)//FAT12,FAT16 { dwTotSec = *((WORD*)pBs->bpb.BPB_TotSec16); } else//FAT32 { dwTotSec = *((DWORD*)pBs32->bpb.BPB_TotSec32); } //保存FAT g_DosDriver.nFatSize = dwFatsz; g_DosDriver.nFatStartSec = *((WORD*)pBs->bpb.BPB_RsvdSecCnt); //保存根目錄. g_DosDriver.nRootEntCnt = *((WORD*)pBs->bpb.BPB_RootEntCnt); g_DosDriver.nRootDirSize = dwRootDirSectors; g_DosDriver.nRootDirStartSec = g_DosDriver.nFatStartSec pBs->bpb.BPB_NumFATs * dwFatsz; //保存文件資料區. g_DosDriver.nFileStartSec = g_DosDriver.nRootDirStartSec dwRootDirSectors; //資料區佔用的磁區數. g_DosDriver.nFileSize = dwTotSec - ( *((WORD*)pBs->bpb.BPB_RsvdSecCnt) pBs->bpb.BPB_NumFATs * dwFatsz dwRootDirSectors); KTRACE("dwFatsz:%d\n",dwFatsz); //計算有多少簇. dwCountOfClusters = g_DosDriver.nFileSize/pBs->bpb.BPB_SecPerClus; KTRACE("dwCountOfClusters:%d\n",dwCountOfClusters); // g_DosDriver.nSecPerTrk = *((WORD*)pBs->bpb.BPB_SecPerTrk); // if(dwCountOfClusters < 4085)//FAT12 { return FAT12; } else if(dwCountOfClusters < 65525)//FAT16 { return FAT16; } else //FAT32 { return FAT32; }//end } // //讀取FAT到記憶體. // void FAT_ReadFatToBuf(void) { int i; //物理磁區開始. int nFatSec = g_DosDriver.nFatStartSec g_DosDriver.nStartSecRel; KTRACE("nFatSec =%d\t",nFatSec); //分配保存FAT的記憶體. g_DosDriver.pFatStart = kmalloc(g_DosDriver.nFatSize * 512); KTRACE("nFatSize=%d\n",g_DosDriver.nFatSize * 512); //讀取所有FAT資料磁區. for(i = 0; i < g_DosDriver.nFatSize; i ) { FAT_ReadOneRelSec(nFatSec i,(g_DosDriver.pFatStart i*512)); } // KTRACE("i=%d\n",i); } // //用邏輯磁區號讀取一個磁區. // bool FAT_ReadOneRelSec(int nRelSec,char* pBuf) { int nCylinder; int nHead; int nSect; //邏輯磁區到物理磁區轉換(C,H,S). FAT_RelSecToCHS(nRelSec,&nCylinder,&nHead,&nSect); HD_ReadWrite( CMD_READ,//讀取命令. 0,//0,主硬碟驅動器, 1,//讀取一個磁區. nSect,//開始磁區 nHead,//開始磁頭 nCylinder,//開始柱面. pBuf);//保存讀取的資料. } // //邏輯磁區到物理磁區轉換,nSec->(C,H,S). // // C柱面號 = 邏輯磁區號 /( 每磁軌磁區數 * 磁頭數) // H磁頭號 = (邏輯磁區號 / 每磁軌磁區數) % 磁頭數 // S磁軌記憶體磁區號 = 邏輯磁區號 % 每磁軌磁區數 1 void FAT_RelSecToCHS(int nSec,int* pCylinder,int* pHead,int* pSect) { *pCylinder = nSec/( g_DosDriver.nSecPerTrk * g_DosDriver.nHead ); *pHead = ( nSec/g_DosDriver.nSecPerTrk ) % g_DosDriver.nHead; *pSect = nSec % g_DosDriver.nSecPerTrk 1; } // //取得根目錄表. // void FAT_ReadRootDirToBuf(void) { int i; char TempBuf[1024]; CRootEnt* pRootEnt = (CRootEnt* ) g_DosDriver.pRootDirStart; char* pCharRootEnt = (char*) g_DosDriver.pRootDirStart; //磁區開始. int nFatSec = g_DosDriver.nRootDirStartSec g_DosDriver.nStartSecRel; KTRACE("nFatSec =%d\t",nFatSec); //分配保存Root DIR的記憶體. g_DosDriver.pFatStart = kmalloc(g_DosDriver.nRootDirSize * 512); KTRACE("nRootDirSize=%d\n",g_DosDriver.nRootDirSize * 512); //讀取所有Root DIR資料磁區. for(i = 0; i < g_DosDriver.nRootDirSize; i ) { FAT_ReadOneRelSec(nFatSec i,(g_DosDriver.pRootDirStart i*512)); } //顯示根目錄. for(i=0; i < g_DosDriver.nRootEntCnt; i ) { if(*pCharRootEnt == 0x00 || *pCharRootEnt == 0xE5 || *pCharRootEnt == 0x05 || *pCharRootEnt == 0x2E ) { continue; } // FAT_FormatRootEnt(pRootEnt,TempBuf); pCharRootEnt = sizeof(CRootEnt); pRootEnt = (CRootEnt*) pCharRootEnt; } // } // //格式化目錄項輸出 // void FAT_FormatRootEnt(CRootEnt* pRootEnt,char* pBuf) { int i; char* pTemp = pBuf; //格式化時間. // for(i=0; i<8; i ) { if(pRootEnt->Name == ) break; pBuf = pRootEnt->Name; } memcpy(pBuf i,".",1); memcpy(pBuf i 1,pRootEnt->Exte,3); *(pBuf i 4) = \0; // FAT_FormatDatetime(pRootEnt); if( pRootEnt->Attr & 0x10 ) { KTRACE(" d ",pRootEnt->Length); } else { KTRACE(" d ",pRootEnt->Length); } // KTRACE("%s\n",pBuf); } // //格式化目錄項日期和時間字串. // char* FAT_FormatDatetime(CRootEnt* pRootEnt) { int nYear = 1980; int nMonth = 1; int nDate = 1; int nHour = 0; int nMinute = 0; // nDate = 0x1F & pRootEnt->Date; nMonth = 0xF & (pRootEnt->Date >> 5); nYear = 0x7F & (pRootEnt->Date >> 9); KTRACE("d-d-d ",nYear,nMonth,nDate); nHour = pRootEnt->Time >> 12 & 0x1F; nMinute = pRootEnt->Time >> 5 & 0x3F; KTRACE("d:d ",nHour,nMinute); } -------------------------------------------------------------------------------- ********************************************************* 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind to make knowledge together! 希望能大家敞開心胸,將知識寶庫結合一起
------
**********************************************************
哈哈&兵燹
最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好

Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知
K.表Knowlege 知識,就是本站的標語:Open our mind
系統時間:2024-05-03 3:34:17
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!