#include #include #include "itsutils.h" #include "kernelmisc.h" #include "WINDEV.H" #include "diskio.h" //-------------------------------- int GetDiskInfo(HANDLE hDsk, DISK_INFO &info) { DWORD nReturned; // various ce versions use all possible combinations, so we try 'm all. if (DeviceIoControl(hDsk, IOCTL_DISK_GETINFO, &info, sizeof(info), NULL, 0, &nReturned, NULL)) return 1; if (DeviceIoControl(hDsk, IOCTL_DISK_GETINFO, NULL, 0, &info, sizeof(info), &nReturned, NULL)) return 2; if (DeviceIoControl(hDsk, DISK_IOCTL_GETINFO, &info, sizeof(info), NULL, 0, &nReturned, NULL)) return 3; if (DeviceIoControl(hDsk, DISK_IOCTL_GETINFO, NULL, 0, &info, sizeof(info), &nReturned, NULL)) return 4; return 0; } HANDLE OpenDisk(int n) { TCHAR diskname[16]; // todo: implement opening volume instead of physical disk when bit31 of disknr is set. if (n>=0 && n<=256) _sntprintf(diskname, 16, L"DSK%u:", n); else _sntprintf(diskname, 16, L"DSK:"); HANDLE hDsk= CreateFile( diskname, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0 ); if (hDsk==NULL || hDsk==INVALID_HANDLE_VALUE) { return NULL; } return hDsk; } /* TCHAR ss[256]; _sntprintf(ss, 256, L"req: %d %08lx %08lx", pbInput->dwDiskNr, pbInput->dwOffset, pbInput->dwSize); MessageBox(0, ss, L"req", 0); _sntprintf(ss, 256, L"reply: %d %08lx %08lx -> %d, %d, %08lx %08lx", pbInput->dwDiskNr, pbInput->dwOffset, pbInput->dwSize, out->dwNumberOfBytesRead, out->start, out->number, outsize); MessageBox(0, ss, L"reply", 0); */ bool DiskReadBlocks(HANDLE hDsk, int nStart, int nBlocks, const DISK_INFO& info, BYTE* buffer, DWORD* pnBytesRead) { SG_REQ req; req.sr_start= nStart; req.sr_num_sec= nBlocks; req.sr_num_sg= 1; req.sr_status= 0; req.sr_callback= NULL; req.sr_sglist[0].sb_len= nBlocks*info.di_bytes_per_sect; req.sr_sglist[0].sb_buf= globalptr(buffer); DWORD nReturned=0; if (!DeviceIoControl(hDsk, DISK_IOCTL_READ, &req, sizeof(req), NULL, NULL, &nReturned, NULL)) return false; *pnBytesRead= nBlocks*info.di_bytes_per_sect; return true; } bool DiskWriteBlocks(HANDLE hDsk, int nStart, int nBlocks, const DISK_INFO& info, const BYTE* buffer, DWORD* pnBytesWritten) { SG_REQ req; req.sr_start= nStart; req.sr_num_sec= nBlocks; req.sr_num_sg= 1; req.sr_status= 0; req.sr_callback= NULL; req.sr_sglist[0].sb_len= nBlocks*info.di_bytes_per_sect; req.sr_sglist[0].sb_buf= globalptr((BYTE*)buffer); DWORD nReturned=0; if (!DeviceIoControl(hDsk, DISK_IOCTL_WRITE, &req, sizeof(req), NULL, NULL, &nReturned, NULL)) return false; *pnBytesWritten= nBlocks*info.di_bytes_per_sect; return true; } bool GetSDCardId(HANDLE hDsk, BYTE *cardid) { HDATA *haDsk= cvHandle2HDataPtr(hDsk); if (haDsk==NULL) { debug("haDsk==NULL\n"); return false; } fsopendev_t *dskdev= (fsopendev_t *)MapPtrProc(haDsk->pvObj, haDsk->pci->pServer); if (dskdev==NULL) { debug("dskdev==NULL\n"); return false; } BYTE *opendata= (BYTE*)MapPtrProc(dskdev->dwOpenData, haDsk->pci->pServer); if (opendata==NULL) { debug("opendata==NULL\n"); return false; } memcpy(cardid, opendata+0x40, 16); return true; } ITSUTILS_API HRESULT STDAPICALLTYPE ITSDCardInfo( DWORD cbInput, SDCardInfoParams *pbInput, DWORD *pcbOutput, SDCardInfoResult **ppbOutput, IRAPIStream *pStream) { HRESULT res= 0; *ppbOutput= NULL; *pcbOutput= 0; HANDLE hDsk= OpenDisk(pbInput->dwDiskNr); if (hDsk==NULL) return GetLastError(); DISK_INFO info; if (!GetDiskInfo(hDsk, info)) { res= GetLastError(); CloseHandle(hDsk); return res; } DWORD outsize= sizeof(SDCardInfoResult); SDCardInfoResult *out= (SDCardInfoResult*)LocalAlloc(LPTR, outsize); out->blockSize= info.di_bytes_per_sect; out->totalBlocks= info.di_total_sectors; KernelMode _km; if (!GetSDCardId(hDsk, out->cardid)) { out->cardidLength= 0; memset(out->cardid, 0, 16); } else { out->cardidLength= 16; } CloseHandle(hDsk); *ppbOutput= out; *pcbOutput= outsize; return 0; } ITSUTILS_API HRESULT STDAPICALLTYPE ITReadSDCard( DWORD cbInput, ReadSDCardParams *pbInput, DWORD *pcbOutput, ReadSDCardResult **ppbOutput, IRAPIStream *pStream) { HRESULT res= 0; *ppbOutput= NULL; *pcbOutput= 0; KernelMode _km; HANDLE hDsk= OpenDisk(pbInput->dwDiskNr); if (hDsk==NULL) return GetLastError(); DISK_INFO info; if (!GetDiskInfo(hDsk, info)) { res= GetLastError(); CloseHandle(hDsk); return res; } if (pbInput->dwOffset % info.di_bytes_per_sect) { debug("ERROR: ITReadSDCard: startoffset not on sector boundary: sector nr %x ofs %04x\n", pbInput->dwOffset / info.di_bytes_per_sect, pbInput->dwOffset % info.di_bytes_per_sect); CloseHandle(hDsk); return ERROR_INVALID_PARAMETER; } if ((pbInput->dwOffset+pbInput->dwSize) % info.di_bytes_per_sect) { debug("ERROR: ITReadSDCard: endoffset not on sector boundary: sector nr %x ofs %04x\n", (pbInput->dwOffset+pbInput->dwSize)/ info.di_bytes_per_sect, (pbInput->dwOffset+pbInput->dwSize)% info.di_bytes_per_sect); CloseHandle(hDsk); return ERROR_INVALID_PARAMETER; } DWORD outsize= sizeof(ReadSDCardResult)+pbInput->dwSize; ReadSDCardResult *out= (ReadSDCardResult *)LocalAlloc(LPTR, outsize); if (!DiskReadBlocks(hDsk, pbInput->dwOffset / info.di_bytes_per_sect, pbInput->dwSize / info.di_bytes_per_sect, info, out->buffer, &out->dwNumberOfBytesRead)) { res= GetLastError(); CloseHandle(hDsk); LocalFree(out); return res; } // out->start= pbInput->dwOffset / info.di_bytes_per_sect; // out->number= pbInput->dwSize / info.di_bytes_per_sect; CloseHandle(hDsk); *ppbOutput= out; *pcbOutput= outsize; return 0; } ITSUTILS_API HRESULT STDAPICALLTYPE ITWriteSDCard( DWORD cbInput, WriteSDCardParams *pbInput, DWORD *pcbOutput, WriteSDCardResult **ppbOutput, IRAPIStream *pStream) { HRESULT res= 0; *ppbOutput= NULL; *pcbOutput= 0; KernelMode _km; HANDLE hDsk= OpenDisk(pbInput->dwDiskNr); if (hDsk==NULL) return GetLastError(); DISK_INFO info; if (!GetDiskInfo(hDsk, info)) { res= GetLastError(); CloseHandle(hDsk); return res; } if (pbInput->dwOffset % info.di_bytes_per_sect) { debug("ERROR: ITWriteSDCard : startoffset not on sector boundary: sector nr %x ofs %04x\n", pbInput->dwOffset / info.di_bytes_per_sect, pbInput->dwOffset % info.di_bytes_per_sect); CloseHandle(hDsk); return ERROR_INVALID_PARAMETER; } if ((pbInput->dwOffset+pbInput->dwSize) % info.di_bytes_per_sect) { debug("ERROR: ITWriteSDCard : endoffset not on sector boundary: sector nr %x ofs %04x\n", (pbInput->dwOffset+pbInput->dwSize)/ info.di_bytes_per_sect, (pbInput->dwOffset+pbInput->dwSize)% info.di_bytes_per_sect); CloseHandle(hDsk); return ERROR_INVALID_PARAMETER; } WriteSDCardResult *out= (WriteSDCardResult *)LocalAlloc(LPTR, sizeof(WriteSDCardResult)); if (!DiskWriteBlocks(hDsk, pbInput->dwOffset / info.di_bytes_per_sect, pbInput->dwSize / info.di_bytes_per_sect, info, pbInput->buffer, &out->dwNumberOfBytesWritten)) { res= GetLastError(); CloseHandle(hDsk); LocalFree(out); return res; } CloseHandle(hDsk); *ppbOutput= out; *pcbOutput= sizeof(WriteSDCardResult); return 0; }