SDHC卡的讀寫問題 |
答題得分者是:wjhsu
|
poaivy
中階會員 發表:40 回覆:78 積分:53 註冊:2004-08-09 發送簡訊給我 |
請問各位
使用下列方法對SD可以做讀的動作 hDevice = CreateFile("\\\\.\\K:", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); SetFilePointer( hDevice , addr*512, NULL, FILE_BEGIN); 移動到你所想要找的資料位址 ReadFile(hDevice, Buffer, 512, &dwBlockRead, 0); // ㄧ次讀一個BLOCK(512Byte) WriteFile( hDevice , buffer, 512, &dwBytesRead, NULL); // ㄧ次寫一個BLOCK(512Byte) CloseHandle(hDevice); 前提是.......... SD卡的容量 8G以下的 都適用 使用上都OK ^.^ 直到最近買了片16G的............. SetFilePointer( hDevice , addr*512, NULL, FILE_BEGIN); 移動到你所想像不到的資料位址 ReadFile(hDevice, Buffer, 512, &dwBlockRead, 0); // ㄧ次讀一個BLOCK(512Byte)??? 這兩個函式已經失效 SD SPEC看了又看 會出問題的話早該在4跟8G的卡就會有問題了(都很正常)..... 用了16G的卡後就不能對SECTOR的內容作讀寫動作了....... 想請問各位有使用過意見或者有別的方法可以處理嗎?? 因為.......... WinHex....他 讀的到啊 >.< 編輯記錄
poaivy 重新編輯於 2008-09-25 15:45:06, 註解 無‧
|
wjhsu
初階會員 發表:9 回覆:32 積分:48 註冊:2004-06-13 發送簡訊給我 |
|
poaivy
中階會員 發表:40 回覆:78 積分:53 註冊:2004-08-09 發送簡訊給我 |
|
poaivy
中階會員 發表:40 回覆:78 積分:53 註冊:2004-08-09 發送簡訊給我 |
|
wjhsu
初階會員 發表:9 回覆:32 積分:48 註冊:2004-06-13 發送簡訊給我 |
你是想讀寫MBR的資料嗎? 如果是的話, 應該要用CreateFile()開啟"實體磁碟機", 如果用CreateFile("\\\\.\\K:"...)的方式, 開啟的是邏輯磁碟機,
兩種方式用SetFilePointerEx()指向磁區0 所代表的意義不同, 前者表示MBR, 後者則是Boot Sector, (不過, 對SD卡而言, 有時會沒有MBR, 所以用實體磁碟機開啟後, Sector 0, 也是Boot Sector) 底下是我的方式, 請參考..., 主要是用GetPhysicalDiskHandle()取得實體磁碟機的代號後, 其餘SetFilePointerEx & ReadFile用法就相同了... p.s. MBR & BootSector 可以參考 http://home.educities.edu.tw/wanker742126/index.html ... [code cpp] //--------------------------------------------------------------------------- /** 找出邏輯磁碟機對應的實體磁碟機代號 傳入值: DriveLetter: 邏輯磁碟機的符號, 如; C, D, E... DiskNum : 傳回的實體磁碟機代號, 如果要進一步用CreateFile()開啟實體磁碟 機, 可用"\\\\.\\PHYSICALDRIVEn", 做為第一個參數, 其中n就是 DiskNum 傳回值: 成功傳回true, 實體磁碟機的代號放在DiskNum, 否則傳回false Note: 1. 根據MSDN的說明, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS傳回的 VOLUME_DISK_EXTENTS結構裏 , NumberOfDiskExtents表示此邏輯磁碟機"分佈" 的實體磁碟機數量, 一般來說, 此值應該為1, 表示傳入的邏輯磁碟機的磁區均 位於同一顆實體磁碟中, 例如: 一顆硬碟分割成C,D,E三槽, 則用C,D,E傳入此 函式時, 得到的 DiskExtent.Extents[0].DiskNumber應該相同 2. 如果邏輯磁碟機的磁區分佈於不同的實體磁碟機, 則NumberOfDiskExtents的 值不為1, 而DeviceIoControl()失敗後, 呼叫 GetLastError()應該會傳回 ERROR_MORE_DATA, 此時要修正傳入 DeviceIoControl 的Output Buffer大小, 3. 此函式只處理第一種狀況, 第二種狀況就當做fail */ bool GetPhysicalDiskNum(char DriveLetter, DWORD &DiskNum) { VOLUME_DISK_EXTENTS DiskExtent; HANDLE hDrive; DWORD BytesRet; BOOL Success; char DriveStr[]="\\\\.\\X:"; DriveStr[4] = DriveLetter; hDrive = ::CreateFile( DriveStr, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); Success = FALSE; DiskNum = -1; if (hDrive != INVALID_HANDLE_VALUE) { Success = ::DeviceIoControl( hDrive, // handle to device IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, // dwIoControlCode NULL, // lpInBuffer 0, // nInBufferSize &DiskExtent, // output buffer sizeof(DiskExtent), // size of output buffer &BytesRet, // number of bytes returned NULL); // OVERLAPPED structure if (Success) DiskNum = DiskExtent.Extents[0].DiskNumber; ::CloseHandle(hDrive); } return (bool)Success; } /** 取得邏輯磁碟機對應的實體磁碟機的Handle */ HANDLE GetPhysicalDiskHandle(char DriveLetter) { HANDLE hPhysical; DWORD DiskNum; AnsiString PhysStr = "\\\\.\\PHYSICALDRIVE"; if (!GetPhysicalDiskNum(DriveLetter, DiskNum)) hPhysical = INVALID_HANDLE_VALUE; else { PhysStr = IntToStr(DiskNum); hPhysical = CreateFile( PhysStr.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL); } return hPhysical; } //--------------------------------------------------------------------------- #define SECTOR_SIZE 512 void __fastcall TForm1::Button2Click(TObject *Sender) { LARGE_INTEGER NewPtr; LARGE_INTEGER Addr; AnsiString Row; HANDLE DiskHandle; unsigned char Buf[SECTOR_SIZE]; DWORD Temp; DWORD SectorId = 0; //Sector的LBA編號 0 = MBR Addr.QuadPart = SectorId * SECTOR_SIZE; DiskHandle = GetPhysicalDiskHandle('I'); if (DiskHandle != INVALID_HANDLE_VALUE) { if (SetFilePointerEx(DiskHandle, Addr, &NewPtr,FILE_BEGIN)) { if (ReadFile(DiskHandle, Buf, SECTOR_SIZE, &Temp, NULL)) { Row = ""; for (int i=0; i Row = (IntToHex(Buf[i],2) " "); if (((i 1) % 16)==0) { Memo->Lines->Add(Row); Row=""; } } } } CloseHandle(DiskHandle); } } [/code] |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |