static BOOL PreReadLargeCluster(RDWRHandle handle, SECTOR start, unsigned char amofsectors, char* buftouse, unsigned bufsize) { unsigned blocks = amofsectors / bufsize; unsigned rest = amofsectors % bufsize; unsigned i; for (i = 0; i < blocks; i++) { if (ReadSectors(handle, bufsize, start, buftouse) == -1) { return FALSE; } start += bufsize; } if (rest) { if (ReadSectors(handle, rest, start, buftouse) == -1) { return FALSE; } } return TRUE; }
int MultipleFatCheck(RDWRHandle handle) { unsigned short sectorsperfat = GetSectorsPerFat(handle); unsigned char numberoffats = GetNumberOfFats(handle); unsigned long bytesinfat = GetBytesInFat(handle), compared = 0, rest; SECTOR fat1start = GetFatStart(handle), fat2start = fat1start, i, j; char buffer1[BYTESPERSECTOR]; char buffer2[BYTESPERSECTOR]; if ((sectorsperfat == 0) || (numberoffats == 0) || (fat1start == 0) || (bytesinfat == 0)) return FAIL; /* Not succeeded. */ if (numberoffats == 1) return TRUE; /* Succeeded when only one fat? */ rest = bytesinfat % BYTESPERSECTOR; for (i = 0; i < numberoffats - 1; i++) { fat2start += sectorsperfat; for (j = 0; j < sectorsperfat; j++) { if (ReadSectors(handle, 1, fat1start + j, buffer1) == -1) return FAIL; if (ReadSectors(handle, 1, fat2start + j, buffer2) == -1) return FAIL; if (compared == bytesinfat - rest) { if (memcmp(buffer1, buffer2, (int) rest) != 0) return FALSE; compared = 0; } else { if (memcmp(buffer1, buffer2, BYTESPERSECTOR) != 0) return FALSE; compared += BYTESPERSECTOR; } } } return TRUE; }
RETVAL PlaceDescriptorInFat(RDWRHandle handle) { struct BootSectorStruct boot; SECTOR fatstart; char buffer[BYTESPERSECTOR], *p; if (!ReadBootSector(handle, &boot)) return ERROR; fatstart = GetFatStart(handle); if (!fatstart) return ERROR; if (ReadSectors(handle, 1, fatstart, buffer) == -1) return ERROR; if (buffer[0] != boot.descriptor) { ReportFileSysError("Wrong descriptor value in FAT", 0, &p, 0, FALSE); buffer[0] = boot.descriptor; if (WriteSectors(handle, 1, fatstart, buffer, WR_FAT) == -1) return ERROR; if (!BackupFat(handle)) return ERROR; } return SUCCESS; }
BOOL ReadDirEntry(RDWRHandle handle, unsigned short index, struct DirectoryEntry* entry) { struct DirectoryEntry* buf; SECTOR dirstart; /* We are using a sector as an array of directory entries. */ buf = (struct DirectoryEntry*)AllocateSector(handle); if (buf == NULL) RETURN_FTEERR(FALSE); dirstart = GetDirectoryStart(handle); if (!dirstart) RETURN_FTEERR(FALSE); if (ReadSectors(handle, 1, dirstart + (index / ENTRIESPERSECTOR), buf) == -1) { FreeSectors((SECTOR*)buf); RETURN_FTEERR(FALSE); } memcpy(entry, buf + (index % ENTRIESPERSECTOR), sizeof(struct DirectoryEntry)); FreeSectors((SECTOR*)buf); return TRUE; }
RETVAL CheckDescriptorInFat(RDWRHandle handle) { struct BootSectorStruct boot; SECTOR fatstart; char buffer[BYTESPERSECTOR], *p; if (!ReadBootSector(handle, &boot)) return ERROR; fatstart = GetFatStart(handle); if (!fatstart) return ERROR; if (ReadSectors(handle, 1, fatstart, buffer) == -1) return FALSE; if (boot.descriptor == buffer[0]) { return SUCCESS; } else { ReportFileSysError("Wrong descriptor value in FAT", 0, &p, 0, FALSE); } return FAILED; }
DRV_STATUS_CODE DRV_SD_ReadSectors( mcdev_enum id, unsigned int sector, unsigned int sectors, void * buffer, unsigned int flags ) { SDC_CMD_STATUS status = NO_ERROR; emmc_addr addr; get_MSDC_lock(&gSD->mSDdrv_lock); status = DRV_SD_AddrLookupTbl(sector, &addr); if (NO_ERROR != status) { free_MSDC_lock(&gSD->mSDdrv_lock); return DRV_READ_FAILURE; } if (KAL_TRUE != SD_eMMC_ECSD_setCurrentPart(addr.partition)) { free_MSDC_lock(&gSD->mSDdrv_lock); return DRV_READ_FAILURE; } #if defined(DRV_MSDC_BLOCKING_TRANSFER_SUPPORT) status = ReadSectors(GetMsdcHandle(id), addr.offset, sectors, buffer, SD_FLAG_BLOCKING_TRANSFER); #else status = ReadSectors(GetMsdcHandle(id), addr.offset, sectors, buffer); #endif if (NO_ERROR != status) { free_MSDC_lock(&gSD->mSDdrv_lock); return DRV_READ_FAILURE; } if (KAL_TRUE != SD_eMMC_ECSD_setCurrentPart(eMMC_user_Area)) { free_MSDC_lock(&gSD->mSDdrv_lock); return DRV_READ_FAILURE; } free_MSDC_lock(&gSD->mSDdrv_lock); return DRV_SUCCESS; }
BiosResult ReadEncryptedSectors (uint16 destSegment, uint16 destOffset, byte drive, uint64 sector, uint16 sectorCount) { BiosResult result; bool decrypt = true; if (BootCryptoInfo->hiddenVolume) { if (ReadWritePartiallyCoversEncryptedArea (sector, sectorCount)) return BiosResultInvalidFunction; if (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector) { // Remap the request to the hidden volume sector -= EncryptedVirtualPartition.StartSector; sector += HiddenVolumeStartSector; } else decrypt = false; } result = ReadSectors (destSegment, destOffset, drive, sector, sectorCount); if (result != BiosResultSuccess || !decrypt) return result; if (BootCryptoInfo->hiddenVolume) { // Convert sector number to data unit number of the hidden volume sector -= HiddenVolumeStartSector; sector += HiddenVolumeStartUnitNo; } if (drive == EncryptedVirtualPartition.Drive) { while (sectorCount-- > 0) { if (BootCryptoInfo->hiddenVolume || (sector >= EncryptedVirtualPartition.StartSector && sector <= EncryptedVirtualPartition.EndSector)) { AcquireSectorBuffer(); CopyMemory (destSegment, destOffset, SectorBuffer, TC_LB_SIZE); DecryptDataUnits (SectorBuffer, §or, 1, BootCryptoInfo); CopyMemory (SectorBuffer, destSegment, destOffset, TC_LB_SIZE); ReleaseSectorBuffer(); } ++sector; destOffset += TC_LB_SIZE; } } return result; }
static BOOL OnlyFilledRead(RDWRHandle handle, SECTOR lsect, unsigned numsectors, char* buf) { unsigned i; SECTOR start = lsect; CLUSTER cluster, label; for (i = 0; i < numsectors; i++) { cluster = DataSectorToCluster(handle, lsect+i); if (!cluster) return FALSE; if (!GetNthCluster(handle, cluster, &label)) { return FALSE; } if (FAT_FREE(label) || FAT_BAD(label)) { if (i) { if (ReadSectors(handle, i, start, buf) == -1) { return FALSE; } } start = lsect+i+1; } } if (start < lsect+numsectors) { if (ReadSectors(handle, numsectors - (unsigned)(start - lsect), start, buf) == -1) { return FALSE; } } return TRUE; }
static int MS_MountDevice(int DeviceType) { kal_uint8 *sector = (kal_uint8*)MSDC_Sector; FS_MasterBootRecord *MBR; FS_BootRecord *PBR; int status; kal_bool IsMBRExist; kal_uint8 type = 0; kal_uint8 c = gMS.Capacity; // get index for MS_MBR => (type) is the index while((c >>= 1) != 2) type++; IsMBRExist = KAL_FALSE; // read MBR at sector 0 status = ReadSectors(NULL,0,1,(void*)sector); MBR = (FS_MasterBootRecord*)sector; PBR = (FS_BootRecord*)sector; if( MBR->Signature == 0xAA55 && MBR->PTable[0].BootIndicator == 0x80) { IsMBRExist = KAL_TRUE; } if(!IsMBRExist) { // create MBR kal_mem_set((void*)MBR,0,sizeof(MBR)); kal_mem_cpy((void*)&(MBR->PTable[0]),MS_MBR[type],MS_MBR_SIZE); MBR->Signature = 0xAA55; status = WriteSectors(NULL,0,1,(void*)sector); if(status < NO_ERROR) return FS_MSDC_MOUNT_ERROR; // create PBR FS_CreateBootSector((void*)sector, (FS_PartitionRecord*)MS_MBR[type], (BYTE)MSDC_MEDIA_DESCRIPTOR, (UINT)gMS.PagesPerBlk, (gMS.Capacity < 128)?FS_FMT_FAT_12:FS_FMT_FAT_16); PBR->NearJump[0] = 0xE9; PBR->NearJump[1] = 0x00; PBR->NearJump[2] = 0x00; kal_mem_set((void*)PBR->BP.OEMName,0x20,8); PBR->BP.SectorsPerCluster = gMS.PagesPerBlk; PBR->BP.DirEntries = 0x200; PBR->BP.E._16.BPB.PhysicalDiskNumber = 0; PBR->BP.E._16.BPB.CurrentHead = 0; PBR->BP.E._16.BPB.SerialNumber = 0; kal_mem_set((void*)PBR->BP.E._16.BPB.Label,0x20,11); status = WriteSectors(NULL, PBR->BP.NumberOfHiddenSectors,1,(void*)sector); if(status < NO_ERROR) return FS_MSDC_MOUNT_ERROR; } return FS_NO_ERROR; }
BOOL ReadDiskToFile( HANDLE hDevice,HANDLE hFile,ULONGLONG ullStartSector, ULONGLONG ullSectors ) { ULONGLONG ullRealStartSector = ullStartSector; ULONGLONG ullReadSectors = 0; ULONGLONG ullRemainSectors = ullSectors; DWORD dwSectors = 0; BOOL bOK = TRUE; ULONGLONG ullOffset = 0; PBYTE lpBuf = new BYTE[BUF_LENGTH]; memset(lpBuf,0,BUF_LENGTH); while (ullReadSectors < ullSectors) { if (ullRemainSectors < PER_SECTORS) { dwSectors = (DWORD)ullRemainSectors; } else { dwSectors = PER_SECTORS; } DWORD dwLastError = 0; memset(lpBuf,0,BUF_LENGTH); BOOL bRec = ReadSectors(hDevice,ullRealStartSector,dwSectors,BYTES_PER_SECTOR,lpBuf,&g_OverlapedDisk,&dwLastError); if (!bRec) { bOK = FALSE; std::cout << red << "Read Sectors Error---" << dwLastError << white << std::endl; break; } DWORD dwSize = dwSectors * BYTES_PER_SECTOR; bRec = WriteFileAsyn(hFile,ullOffset,dwSize,lpBuf,&g_OverlapedFile,&dwLastError); if (!bRec) { bOK = FALSE; std::cout << red << "Write File Error---" << dwLastError << white << std::endl; break; } ullRealStartSector += dwSectors; ullReadSectors += dwSectors; ullRemainSectors -= dwSectors; ullOffset += dwSize; } delete[] lpBuf; return bOK; }
static int ReadVTOC(int drive, Bit16u volume, unsigned char *buf) { char id[5]; Bit8u type; int error = ReadSectors(drive, 16 + volume, 1, buf); if (error) return error; MEMCPY_2UNIX(id, buf + 1, 5); if (memcmp("CD001", id, 5) != 0) return MSCDEX_ERROR_BAD_FORMAT; type = READ_BYTE(buf); return 0; }
int main(int argc, char** argv) { RDWRHandle handle; unsigned long i, numsectors; FILE* fptr; printf("creatimg v0.1 <source> <target>\n"); if (argc != 3) return 1; if (strcmp(argv[1], "/?") == 0) return 1; if (!InitReadWriteSectors(argv[1], &handle)) { printf("Cannot initialise drive %s\n", argv[1]); return 1; } fptr = fopen(argv[2], "wb"); if (!fptr) { printf("cannot open destination\n"); return 1; } numsectors = GetNumberOfSectors(handle); for (i=0; i < numsectors; i++) { if (ReadSectors(handle, 1, i, buffer) == -1) { printf("could not read sector"); return -1; } if (!fwrite(buffer, BYTESPERSECTOR, 1, fptr) != 1) { printf("could not write sector"); return -1; } } fclose(fptr); CloseReadWriteSectors(&handle); return 0; }
ULONG GetNextCluster(ULONG Cluster) { ULONG Sector = 0; ULONG ByteOffset = 0; PUCHAR pSectorCache = (PUCHAR)SECTOR_CACHE_START; // Sector cache is where the sector used to read the FAT cluster chains lives. static ULONG CurrentSector = 0; ULONG NextCluster = 0; // If we're passed an EOF cluster, return it. // if (IsEOFCluster(Cluster)) return(Cluster); // Is caller giving us a valid cluster? // if (!IsDataCluster(Cluster)) { ERRMSG(MSG_BAD_CLUSTER_NUMBER, ("Bad cluster number\n")); return(0); // 0 isn't a valid cluster number (at least for our purposes). } // Compute sector where our FAT entry lives. // Sector = Cluster << 2; ByteOffset = Sector & ((1 << pBPB->BytesPerSector)-1); Sector = Sector >> pBPB->BytesPerSector; Sector += g_FATParms.FATLBA; // If the sector we're interested in isn't in our cache, get it. // if (CurrentSector != Sector) { if (!ReadSectors( pBPB->DriveID, Sector, 1, pSectorCache)) { // TODO: Only a message? // SERPRINT("GetNextCluster - unable to read sector.\r\n"); } CurrentSector = Sector; } // Locate next cluster number... // NextCluster = *(PULONG)(pSectorCache + ByteOffset); // SERPRINT("GNC: cluster=0x%x next cluster=0x%x\r\n", Cluster, NextCluster); // Return the next cluster value. // return(NextCluster); }
static bool OpenVolume (byte drive, Password &password, CRYPTO_INFO **cryptoInfo, uint32 *headerSaltCrc32, bool skipNormal, bool skipHidden) { int volumeType; bool hiddenVolume; uint64 headerSec; AcquireSectorBuffer(); for (volumeType = 1; volumeType <= 2; ++volumeType) { hiddenVolume = (volumeType == 2); if (hiddenVolume) { if (skipHidden || PartitionFollowingActive.Drive != drive || PartitionFollowingActive.SectorCount <= ActivePartition.SectorCount) continue; headerSec = PartitionFollowingActive.StartSector + TC_HIDDEN_VOLUME_HEADER_OFFSET / TC_LB_SIZE; } else { if (skipNormal) continue; headerSec.HighPart = 0; headerSec.LowPart = TC_BOOT_VOLUME_HEADER_SECTOR; } if (ReadSectors (SectorBuffer, drive, headerSec, 1) != BiosResultSuccess) continue; if (ReadVolumeHeader (!hiddenVolume, (char *) SectorBuffer, &password, cryptoInfo, nullptr) == ERR_SUCCESS) { // Prevent opening a non-system hidden volume if (hiddenVolume && !((*cryptoInfo)->HeaderFlags & TC_HEADER_FLAG_ENCRYPTED_SYSTEM)) { crypto_close (*cryptoInfo); continue; } if (headerSaltCrc32) *headerSaltCrc32 = GetCrc32 (SectorBuffer, PKCS5_SALT_SIZE); break; } } ReleaseSectorBuffer(); return volumeType != 3; }
static BOOL ClusterPreReader(RDWRHandle handle, CLUSTER label, SECTOR datasector, void** structure) { SECTOR firstsector; CLUSTER cluster; unsigned char sectorspercluster; struct Pipe* pipe = *((struct Pipe**) structure); if (label); sectorspercluster = GetSectorsPerCluster(handle); if (!sectorspercluster) return FAIL; if (pipe->maxindex == 0) /* cluster > read buf */ { if (!PreReadLargeCluster(handle, datasector, sectorspercluster, pipe->buf, pipe->bufsize)) return FAIL; } else { cluster = DataSectorToCluster(handle, datasector); if ((pipe->index > 0) && ((pipe->prevcluster != cluster-1) || (pipe->index == pipe->maxindex))) { firstsector = ConvertToDataSector(handle, pipe->firstcluster); if (!firstsector) return FAIL; if (ReadSectors(handle, pipe->index*sectorspercluster, firstsector, pipe->buf) == -1) { return FAIL; } pipe->index = 0; pipe->firstcluster = cluster; } else { pipe->index++; } } pipe->prevcluster = cluster; return TRUE; }
BOOL PreReadClusterChain(RDWRHandle handle, CLUSTER start) { SECTOR firstsector; char* ReadBuf; struct Pipe pipe, *ppipe = &pipe; unsigned char sectorspercluster; unsigned BufSize; if (!CacheActive()) return TRUE; sectorspercluster = GetSectorsPerCluster(handle); if (!sectorspercluster) return FALSE; ReadBuf = AllocateReadBuf(MAX_ALLOCATING, &BufSize); BufSize /= BYTESPERSECTOR; pipe.buf = ReadBuf; pipe.bufsize = BufSize; pipe.index = 0; pipe.maxindex = BufSize / sectorspercluster; pipe.prevcluster = 0; pipe.firstcluster = start; if (!FileTraverseFat(handle, start, ClusterPreReader, (void**) &ppipe)) { FreeReadBuf(ReadBuf); return FALSE; } if (pipe.index) { firstsector = ConvertToDataSector(handle, pipe.firstcluster); if (!firstsector) { FreeReadBuf(ReadBuf); return FALSE; } if (ReadSectors(handle, pipe.index*sectorspercluster, firstsector, pipe.buf) == -1) { FreeReadBuf(ReadBuf); return FALSE; } } FreeReadBuf(ReadBuf); return TRUE; }
BOOL MultipleBootCheck(RDWRHandle handle) { BOOL retval; int fatlabelsize = GetFatLabelSize(handle); SECTOR BackupSector; struct BootSectorStruct* boot1, *boot2; if (fatlabelsize == FAT32) { BackupSector = GetFAT32BackupBootSector(handle); if (!BackupSector) { RETURN_FTEERR(FAIL); } boot1 = AllocateBootSector(); if (!boot1) RETURN_FTEERR(FAIL); boot2 = AllocateBootSector(); if (!boot2) { FreeBootSector(boot1); RETURN_FTEERR(FAIL); } if (!ReadBootSector(handle, boot1) == -1) { FreeBootSector(boot1); RETURN_FTEERR(FAIL); } if (!ReadSectors(handle, 1, BackupSector, (void*) boot2) == -1) { FreeBootSector(boot1); FreeBootSector(boot2); RETURN_FTEERR(FAIL); } retval = (memcmp(boot1, boot2, BYTESPERSECTOR) == 0); FreeBootSector(boot1); FreeBootSector(boot2); return retval; } RETURN_FTEERR((fatlabelsize) ? TRUE : FAIL); }
BOOL VerifyDiskAndFile( HANDLE hDevice,HANDLE hFile,ULONGLONG ullStartSector, ULONGLONG ullSectors ) { ULONGLONG ullRealStartSector = ullStartSector; ULONGLONG ullReadSectors = 0; ULONGLONG ullRemainSectors = ullSectors; DWORD dwSectors = 0; BOOL bOK = TRUE; ULONGLONG ullOffet = 0; PBYTE lpBufDisk = new BYTE[BUF_LENGTH]; memset(lpBufDisk,0,BUF_LENGTH); PBYTE lpBufFile = new BYTE[BUF_LENGTH]; memset(lpBufFile,0,BUF_LENGTH); while (ullReadSectors < ullSectors) { if (ullRemainSectors < PER_SECTORS) { dwSectors = (DWORD)ullRemainSectors; } else { dwSectors = PER_SECTORS; } DWORD dwLastError = 0; memset(lpBufDisk,0,BUF_LENGTH); BOOL bRec = ReadSectors(hDevice,ullRealStartSector,dwSectors,BYTES_PER_SECTOR,lpBufDisk,&g_OverlapedDisk,&dwLastError); if (!bRec) { bOK = FALSE; std::cout << red << "Read Sectors Error---" << dwLastError << white << std::endl; break; } memset(lpBufFile,0,BUF_LENGTH); DWORD dwSize = dwSectors * BYTES_PER_SECTOR; bRec = ReadFileAsyn(hFile,ullOffet,dwSize,lpBufFile,&g_OverlapedFile,&dwLastError); if (!bRec) { bOK = FALSE; std::cout << red << "Read File Error---" << dwLastError << white << std::endl; break; } for (DWORD i = 0;i < dwSize;i++) { if (lpBufDisk[i] != lpBufFile[i]) { bOK = FALSE; std::cout << red << "Verify Disk and File Error(offset=" << std::hex << ullOffet + i << ")!" << white << std::endl; break; } } if (!bOK) { break; } ullRealStartSector += dwSectors; ullReadSectors += dwSectors; ullRemainSectors -= dwSectors; ullOffet += dwSize; } delete[] lpBufDisk; return bOK; }
// // Open filename specified and return the size. // ULONG FSOpenFile(char* pFileName) { USHORT i = 0; USHORT j = 0; ULONG DirLBA = 1; CHAR* Sector = (CHAR*)READ_BUFFER_START; CHAR FileName[30] = { 0 }; BOOL bFound = FALSE; // Check caller's parameters. if (pFileName == NULL) return(0); memset( &g_FileInfo, 0, sizeof(FILEINFO) ); // Convert the filename to the form stored on disk. for (i = 0 ; i < 15 && *(pFileName + i) ; i++) FileName[i*2] = TO_UPPER(*(pFileName + i)); // Look for the filename in directory list. for( bFound = FALSE, DirLBA = g_FATParms.RootDirLBA ; !bFound && DirLBA ; DirLBA = NextSector( DirLBA ) ) { // Read a sector from the root directory. if (!ReadSectors(pBPB->DriveID, DirLBA, 1, Sector)) { ERRMSG(MSG_CANNOT_READ_ROOT_DIR, ("Couldn't read root directory sector (LBA=0x%x)\n", DirLBA)); return(0); } // Try to find the specified file in the root directory... for (j = 0 ; (j < (1 << (pBPB->BytesPerSector - 5))) && !bFound; j++) { BYTE* pCurrent = Sector + (j << 5); // // We've found a stream entry, record this in case it's our file. // if( ((pCurrent[0] & 0x7F) == 64) && (pCurrent[0] & 0x80) ) { EXFAT_STREAM_RECORD* pEntry; pEntry = (EXFAT_STREAM_RECORD*)(pCurrent); g_FileInfo.Flags = pEntry->Flags; g_FileInfo.FileSize = (ULONG)pEntry->FileSize; g_FileInfo.FirstCluster = pEntry->FirstCluster; g_FileInfo.CurCluster = g_FileInfo.FirstCluster; g_FileInfo.pCurReadBuffAddr = g_pReadBuffStart; } else if( ((pCurrent[0] & 0x7F) == 65) && (pCurrent[0] & 0x80) ) { BYTE Current = 0; bFound = TRUE; for (i = 0 ; i < 30 ; i++) { Current = TO_UPPER( (pCurrent)[2 + i] ); if( FileName[i] != Current ) { bFound = FALSE; } } } } } if (!bFound) { WARNMSG(MSG_FILE_NOT_FOUND, ("File '%s' not found\n", pFileName)); return(0); } else { INFOMSG(MSG_FILE_FOUND, ("Found file '%s' (start=0x%x size=0x%x)\n", pFileName, g_FileInfo.FirstCluster, g_FileInfo.FileSize)); } return(g_FileInfo.FileSize); }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Installs BK to load the specified driver. // BOOL BkInstallVbr( PCHSS PayloadAddress ) { BOOL Ret = FALSE; PCHAR Vbs = NULL, Loader = NULL, Packed = NULL; PVBR Vbr = NULL; ULONG i, CodeSize, bSize = BIOS_DEFAULT_SECTOR_SIZE; PPARTITION_TABLE PTable; ULONG StartSector = 0, SectorSize = 0, PackedSize = 0; WCHAR TargetDrive[cstrlenW(wszPartition) + 1] = {0}; wsprintfW(TargetDrive, wszPartition, 0); do // not a loop { if (!(Vbs = Alloc(BIOS_DEFAULT_SECTOR_SIZE))) // Not enough memory break; // Reading MBR sector if (!ReadSectors(TargetDrive, Vbs, bSize, 0, 1)) // Reading failed break; // Check out we read a right one if (*(PUSHORT)(Vbs + BIOS_DEFAULT_SECTOR_SIZE - sizeof(USHORT)) != BIOS_MBR_MAGIC) // Wrong or corrupt sector loaded break; // Here we read the Driver Boot sector and searching for the Volume boot sector within it PTable = (PPARTITION_TABLE)(Vbs + BIOS_PARTITION_TABLE_OFFSET); i = 0; while( (i < BIOS_MAX_PARTITION_COUNT) && (!(PTable->Entry[i].ActiveFlag & BIOS_PARTITION_ACTIVE_FLAG) || (PTable->Entry[i].Descriptor != BIOS_PARTITION_TYPE_INSTALLABLE))) i += 1; if (i == BIOS_MAX_PARTITION_COUNT) // No bootable NTFS partition found break; bSize = BIOS_DEFAULT_SECTOR_SIZE; #ifdef _PHYSICAL_DRIVE StartSector = PTable->Entry[i].LBAStartSector; #else wsprintfW(TargetDrive, wszPartition, (i + 1)); StartSector = 0; #endif if (!ReadSectors(TargetDrive, Vbs, bSize, StartSector, 1)) // Reading failed break; Vbr = (PVBR)Vbs; if (memcmp(&Vbr->VolumeOemId, NTFS_OEM_ID, sizeof(NTFS_OEM_ID))) // Not a NTFS partition break; SectorSize = Vbr->Bpb.SectorSize; ASSERT(SectorSize == BIOS_DEFAULT_SECTOR_SIZE); bSize = (NTFS_LOADER_SIZE * SectorSize); if (!(Loader = Alloc(bSize))) // Not enough memory break; if (!ReadSectors(TargetDrive, Loader, bSize, (StartSector + 1), (NTFS_LOADER_SIZE - 1))) // Reading failed break; if (!(i = GetCodeOffset(Loader))) // Wrong or corrupt OS loader break; CodeSize = (NTFS_LOADER_SIZE - 1) * SectorSize - i; PackedSize = ApPack((Loader + i), CodeSize, &Packed); if (!PackedSize) // Packing failed break; if (!BkCreateLoader(Loader + i, CodeSize, Packed, PackedSize, PayloadAddress)) // Failed to create loader break; if (WriteSectors(TargetDrive, Loader, bSize, (StartSector + 1), (NTFS_LOADER_SIZE - 1))) Ret = TRUE; } while(FALSE); if (Vbs) Free(Vbs); if (Loader) Free(Loader); if (Packed) Free(Packed); return(Ret); }
static BOOL BkInstallPayloadFromBuffer( PCHAR Payload, ULONG PayloadSize, PCHSS PayloadAddress ) { BOOL Ret = FALSE; PCHAR Vbs = NULL, Loader = NULL, Packed = NULL; PVBR Vbr = NULL; ULONG i, bSize = BIOS_DEFAULT_SECTOR_SIZE; PPARTITION_TABLE PTable; ULONG StartSector = 0, EndSector = 0, SectorSize = 0, PackedSize = 0; PWCHAR TargetDrive = wszPhysicalDrive0; PCHAR PayloadSectors = NULL; ULONG PayloadSecSize; ULONG RndSeed = GetTickCount(); DISK_GEOMETRY Dg = {0}; do // not a loop { if (!Payload || !PayloadAddress || !PayloadSize) break; if (!GetDriveGeometry(TargetDrive, &Dg)) break; if (!(Vbs = Alloc(BIOS_DEFAULT_SECTOR_SIZE))) // Not enough memory break; // Reading MBR sector if (!ReadSectors(TargetDrive, Vbs, bSize, 0, 1)) // Reading failed break; // Check out we read a right one if (*(PUSHORT)(Vbs + BIOS_DEFAULT_SECTOR_SIZE - sizeof(USHORT)) != BIOS_MBR_MAGIC) // Wrong or corrupt sector loaded break; // Here we read the Driver Boot sector and searching for the Volume boot sector within it PTable = (PPARTITION_TABLE)(Vbs + BIOS_PARTITION_TABLE_OFFSET); // Calculating drive unpartitioned space for (i=0; i<BIOS_MAX_PARTITION_COUNT; i++) { if (PTable->Entry[i].ActiveFlag & BIOS_PARTITION_ACTIVE_FLAG) { if (StartSector == 0 || StartSector > PTable->Entry[i].LBAStartSector) StartSector = PTable->Entry[i].LBAStartSector; if (EndSector < (PTable->Entry[i].LBAStartSector + PTable->Entry[i].PartitionSize)) EndSector = (PTable->Entry[i].LBAStartSector + PTable->Entry[i].PartitionSize); } } // for (i=0; i<BIOS_MAX_PARTITION_COUNT; i++) PayloadSecSize = (PayloadSize + (Dg.BytesPerSector -1))/Dg.BytesPerSector; if (((StartSector - 1)) > PayloadSecSize) StartSector = 1 + RtlRandom(&RndSeed)%((StartSector - 1) - PayloadSecSize); else { ULONG DriveLastSector = Dg.Cylinders.LowPart * Dg.TracksPerCylinder * Dg.SectorsPerTrack; StartSector = DriveLastSector - PayloadSecSize - 2; } if (!(PayloadSectors = Alloc(PayloadSecSize * Dg.BytesPerSector))) // Not enough memory break; memcpy(PayloadSectors, Payload, PayloadSize); if (StartSector) { // Calculating Start sector CHSS address PayloadAddress->StartSector.QuadPart = (ULONGLONG)StartSector; PayloadAddress->NumberSectors = (USHORT)PayloadSecSize; // Writing payload to the disk Ret = WriteSectors(TargetDrive, PayloadSectors, (PayloadSecSize * Dg.BytesPerSector), StartSector, PayloadSecSize); } } while(FALSE); if (Vbs) Free(Vbs); if (PayloadSectors) Free(PayloadSectors); return(Ret); }
CROSSCUT_NLS_DATA int main (int argc, char *argv[]) { int memkind, handle; char loop1, loop2; struct dfree free; char buf[BUFFERSIZE]; char cmpbuf[BUFFERSIZE]; unsigned long sector, total, disksize, allocated, beginsector, endsector; unsigned long FilledDiskSize, FilledTotal, FileSize = 0; int Arg1IsFile, Arg2IsFile; int UseImageFile, ImageModus, Overwrite; int i, enable; int audible, verify, fallthrough, askdisk, asktdisk; char sdrive, tdrive; int HardDiskOk; int informative, copyfast; char switchchar; int tocopysectors; unsigned tobuffer; #ifndef ALL_RECOVERY_MODE int recoverymode; #endif int bytespersector; int CopyingToSameDisk = FALSE; int action, success; struct LFNAttribute attr; struct IniParserStruct *ParsedData; struct TwoDriveCopyData tdrvdata; attr.output = TRUE; memkind = UNALLOCATED; UseImageFile = FALSE; SetExePath (argv[0]); /* Remember executable's path. */ CriticalHandlerOn (); /* Install critical handler. */ InitLFNAPI (); /* Initialise LFN API. */ CROSSCUT_NLS_OPEN switchchar = SwitchChar (); /* Check arguments */ if ((argc == 2) && ((argv[1][0] == '/') || (argv[1][0] == switchchar)) && (argv[1][1] == '?') && (argv[1][2] == '\0')) { ShowHelp (switchchar); return COPYSUCCESS; } if (argc > 2) { Arg1IsFile = IsFile (argv[1]); Arg2IsFile = IsFile (argv[2]); } #ifdef DEF_HELP if (argc < 3) { /* The way we do it. */ ShowHelp (switchchar); return INITERROR; } else if ((!HasFloppyForm (argv[1]) && !Arg1IsFile) || (!HasFloppyForm (argv[2]) && !Arg2IsFile)) #else if ((argc < 3) || (!HasFloppyForm (argv[1]) && !Arg1IsFile) || (!HasFloppyForm (argv[2]) && !Arg2IsFile)) #endif { /* The way (DR and MS) DOS does it. */ NLS_PUTSTRING (1, 0, "Invalid drive specification or non removable media."); return INITERROR; } if (ParseIniFile (NULL) < 0) /* Parse .ini file. */ { NLS_PUTSTRING (1, 1, "Error reading configuration file."); return INITERROR; } ParsedData = GetParsedData (); audible = ParsedData->audible; verify = ParsedData->verify; HardDiskOk = ParsedData->UseSWAP; informative = ParsedData->informative; Overwrite = ParsedData->overwrite; fallthrough = ParsedData->autoexit; askdisk = ParsedData->askdisk; asktdisk = ParsedData->asktdisk; copyfast = (ParsedData->speed == FAST); #ifndef ALL_RECOVERY_MODE recoverymode = ParsedData->mode; #endif /* Check arguments. */ for (i = 3; i < argc; i++) { if (strlen (argv[i]) > 3) { NLS_PRINTSTRING (1, 2, "Invalid switch:"); printf (" %s\n", argv[i]); return INITERROR; } enable = TRUE; if (strlen (argv[i]) == 3) { if (argv[i][2] == '-') { enable = FALSE; } else { NLS_PRINTSTRING (1, 2, "Invalid switch"); printf (" %s\n", argv[i]); return INITERROR; } } if ((argv[i][0] == switchchar) || (argv[i][0] == '/')) switch (argv[i][1]) { case 'a': /* DOS is case insensitive. */ case 'A': audible = enable; break; case 'v': case 'V': verify = enable; break; case 'm': case 'M': HardDiskOk = !enable; break; case 'i': case 'I': informative = enable; break; case 'o': case 'O': Overwrite = enable; break; case 'x': case 'X': fallthrough = enable; break; case 'd': case 'D': askdisk = !enable; break; case 'f': case 'F': copyfast = enable; break; #ifndef ALL_RECOVERY_MODE case 'r': case 'R': recoverymode = enable; break; #else case 'r': case 'R': #endif case 't': case 'T': asktdisk = !enable; break; case '1': NLS_PRINTSTRING (2, 0, "Warning: option"); printf (" %s ", argv[i]); NLS_PUTSTRING (2, 1, "doesn't do anything!"); break; default: NLS_PRINTSTRING (1, 2, "Invalid switch"); printf (" %s\n", argv[i]); return INITERROR; } else { NLS_PRINTSTRING (1, 3, "Too many parameters:"); printf (" %s\n", argv[i]); return INITERROR; } } if (Arg1IsFile && Arg2IsFile) { ConvertToSFN (argv[1], INFILE_ID); ConvertToSFN (argv[2], OUTFILE_ID); SetLFNAttribute (&attr, OUTFILE_ID); if ((access (GetSFN (OUTFILE_ID), EXISTS) == 0) && Overwrite && (remove (GetSFN (OUTFILE_ID)) == -1)) { NLS_PUTSTRING (1, 4, "File is write protected!"); return INITERROR; } if (CopyFile (GetSFN (INFILE_ID), GetSFN (OUTFILE_ID))) { printf ("%s ", argv[1]); NLS_PRINTSTRING (1, 5, "copied to"); printf (" %s", argv[2]); if (audible) Beep (); SynchronizeLFNs (); return COPYSUCCESS; } else { NLS_PRINTSTRING (3, 0, "Problem copying"); printf (" %s ", argv[1]); NLS_PRINTSTRING (3, 1, "to"); printf (" %s.\n", argv[2]); return CRITICAL; } } else if (Arg1IsFile) { ConvertToSFN (argv[1], INFILE_ID); if (access (GetSFN (INFILE_ID), READPERMISSION) != 0) { NLS_PRINTSTRING (1, 6, "File not found:"); printf (" %s\n", argv[1]); return INITERROR; } CopyingToSameDisk = IsCopyToSameDisk (argv[1], argv[2]); UseImageFile = TRUE; ImageModus = READIMAGE; } else if (Arg2IsFile) { CopyingToSameDisk = IsCopyToSameDisk (argv[2], argv[1]); ConvertToSFN (argv[2], OUTFILE_ID); SetLFNAttribute (&attr, OUTFILE_ID); if (!CopyingToSameDisk) { if (access (GetSFN (OUTFILE_ID), EXISTS) == 0) { if (Overwrite) { if (remove (GetSFN (OUTFILE_ID)) != 0) { NLS_PRINTSTRING (1, 4, "File is write protected!"); return INITERROR; } } else { NLS_PRINTSTRING (1, 7, "File already exists!"); return INITERROR; } } } if (CopyingToSameDisk) copyfast = TRUE; UseImageFile = TRUE; ImageModus = WRITEIMAGE; } sdrive = (char) toupper (argv[1][0]) - 65; tdrive = (char) toupper (argv[2][0]) - 65; loop1 = CatYES; /* initialize loop1 */ loop2 = CatYES; /* initialize loop2 */ ctrlbrk (OnCBreak); SavedCBreak = getcbrk (); setcbrk (1); /* set control-break to ON */ atexit (OnExit); /* make sure that all allocated memory is released when program stops. */ if ((sdrive != tdrive) && (!UseImageFile) && BiosReportsTwoDrives ()) { tdrvdata.sourcedrv = sdrive; tdrvdata.destdrv = tdrive; tdrvdata.cpybuf = buf; tdrvdata.cmpbuf = cmpbuf; tdrvdata.bufsize = BUFFERSIZE; tdrvdata.bel = audible; tdrvdata.fallthrough = fallthrough; tdrvdata.askdisk = askdisk; tdrvdata.copyfast = copyfast; tdrvdata.verify = verify; #ifndef ALL_RECOVERY_MODE tdrvdata.recoverymode = recoverymode; #endif #ifdef UPDATE_SERIALNUM tdrvdata.updateserial = ParsedData->serialnumber; #endif TwoDriveCopy (&tdrvdata); return COPYSUCCESS; } endsector = 0; while (!NLS_TEST_NO (loop1)) /* loop1 */ { if (!UseImageFile || (ImageModus == WRITEIMAGE)) { if (askdisk) { puts (""); NLS_PRINTSTRING (1, 8, "Insert SOURCE diskette into drive"); printf (" %s\n\n", argv[1]); NLS_PRINTSTRING (1, 9, "Press any key to continue . . ."); WaitForInput (); puts (""); } else askdisk = TRUE; /* Always ask after the first run. */ } if (endsector == 0) { if (!UseImageFile || (ImageModus == WRITEIMAGE)) { if (!DiskReadBootInfo (sdrive, &free) || (DetermineFATType() != FAT12)) { puts (""); NLS_PUTSTRING (1, 10, "Disk not ready!"); return CRITICAL; } } else { /* Remember file size */ handle = open (GetSFN (INFILE_ID), O_RDONLY | O_BINARY); if (handle < 0) { puts (""); NLS_PUTSTRING (1, 11, "Unable to open image file."); return INITERROR; } FileSize = filelength (handle); close (handle); if (!FileReadBootInfo (GetSFN (INFILE_ID), &free)) { puts (""); NLS_PUTSTRING (1, 11, "Unable to open image file."); return INITERROR; } } total = free.df_total * free.df_sclus; bytespersector = free.df_bsec; disksize = total * bytespersector; if (disksize == 0) { puts (""); NLS_PUTSTRING (1, 0, "Invalid drive specification or non removable media."); return INITERROR; } /* Initialize fast copy: - After checking if disk in drive is ok, BUT - before initializing memory */ /* In case of writing an image file to disk. We'd like the program to succeed regardless of wether we used the /f switch or corresponding .ini file entry */ if (((copyfast) || ((UseImageFile && (ImageModus == READIMAGE)) && disksize != FileSize)) && (disksize != FileSize)) { SetCopySpeed (FAST); if (!UseImageFile || (ImageModus == WRITEIMAGE)) { if (!DiskReadFatInfo (sdrive)) SetCopySpeed (FULL); } else if (!FileReadFatInfo (GetSFN (INFILE_ID))) { NLS_PUTSTRING (1, 32, "Can not copy image file"); return INITERROR; } } else SetCopySpeed (FULL); } puts (""); /* Get the size of the meaningfull data on the disk */ FilledDiskSize = GetDiskFilledSize (BUFFERSIZE); FilledTotal = (FilledDiskSize / free.df_bsec) / free.df_sclus; if ((UseImageFile) && (!CopyingToSameDisk)) switch (SetImageFile (GetSFN (ImageModus - 1), ImageModus, FilledDiskSize)) { case EZERO: allocated = disksize; break; case DISKTOSMALL: puts (""); NLS_PUTSTRING (1, 12, "Not enough disk space on target drive!"); return INITERROR; default: NLS_PRINTSTRING (1, 13, "Error accessing image file:"); printf (" %s\n", argv[ImageModus]); return INITERROR; } else { if (CopyingToSameDisk) switch (ImageModus) { case READIMAGE: memkind = InitializeFittingMemory (FilledDiskSize, HardDiskOk, &allocated, '\0', argv[2][0]); break; case WRITEIMAGE: memkind = InitializeFittingMemory (FilledDiskSize, HardDiskOk, &allocated, argv[1][0], '\0'); break; } else memkind = InitializeFittingMemory (FilledDiskSize, HardDiskOk, &allocated, argv[1][0], argv[2][0]); if (memkind == 0) { NLS_PUTSTRING (1, 14, "Insufficient memory for disk copy.\n"); return INITERROR; } } if (CopyingToSameDisk) { if (allocated != FilledDiskSize) { NLS_PUTSTRING (1, 14, "Insufficient memory for disk copy.\n"); return INITERROR; } if (ImageModus == READIMAGE) { PrepareForWriting (); if (!ReadFileIntoMemory (GetSFN (INFILE_ID), buf, BUFFERSIZE)) { NLS_PUTSTRING (1, 33, "Problem reading image file."); return CRITICAL; } } else /* ImageModus == WRITEIMAGE */ if (!asktdisk) { if (!DiskLargeEnough (GetSFN (OUTFILE_ID), FilledDiskSize)) { puts (""); NLS_PUTSTRING (1, 12, "Not enough disk space on target drive!"); return INITERROR; } } } if (!UseImageFile || (ImageModus == WRITEIMAGE)) { beginsector = endsector; endsector += allocated / BYTESPERSECTOR; if ((endsector > total) || (allocated == FilledDiskSize)) endsector = total; } if (!UseImageFile || (ImageModus == WRITEIMAGE)) { NLS_PRINTSTRING (4, 0, "Copying"); printf (" %d ", (int) FilledTotal); NLS_PRINTSTRING (4, 1, "clusters"); printf (", %d ", free.df_sclus); NLS_PRINTSTRING (4, 2, "sectors per cluster"); printf (", %d ", free.df_bsec); NLS_PRINTSTRING (4, 3, "bytes per sector"); puts ("."); NLS_PRINTSTRING (4, 4, "Relevant drive size is"); printf (" %lu ", FilledDiskSize); NLS_PRINTSTRING (4, 5, "bytes"); printf ("."); } if (informative && (!UseImageFile)) { printf (" "); NLS_PRINTSTRING (1, 15, "Using"); printf (" "); switch (memkind) { case EMS: puts ("EMS.\n"); break; case XMS: puts ("XMS.\n"); break; case HARDDISK: NLS_PUTSTRING (1, 16, "temporary file"); puts (""); break; case BUFFERS: NLS_PRINTSTRING (5, 0, "buffer of"); printf (" %ld ", allocated); NLS_PUTSTRING (5, 1, "bytes."); puts (""); break; } } else if (!UseImageFile || (ImageModus == WRITEIMAGE)) puts ("\n"); if (!UseImageFile || (ImageModus == WRITEIMAGE)) { for (action = DISKREADING; (verify) ? (action <= VERIFICATION) : (action < VERIFICATION); action++) { if (action == DISKREADING) { if (!UseImageFile) { NLS_PRINTSTRING (1, 17, "Reading SOURCE diskette . . ."); } else NLS_PRINTSTRING (1, 34, "Creating image file . . ."); PrepareForWriting (); } else { puts (""); NLS_PRINTSTRING (1, 38, "Verifying . . ."); PrepareForReading (); } for (sector = beginsector; sector < endsector; sector = sector + TOCOPYSECTORS) { if (sector < endsector - TOCOPYSECTORS) tocopysectors = TOCOPYSECTORS; else tocopysectors = (int) (endsector - sector); tobuffer = (unsigned) (tocopysectors * BYTESPERSECTOR); if (IsDiskReadRequired (sector, tocopysectors)) /* Fast copy */ { #ifndef ALL_RECOVERY_MODE if (recoverymode) #endif ReadSectors (sdrive, tocopysectors, (int) sector, buf, bytespersector); #ifndef ALL_RECOVERY_MODE else if (absread (sdrive, tocopysectors, (int) sector, buf) != 0) { puts (""); NLS_PRINTSTRING (1, 18, "Media error reading from sector"); printf (" %ld.\n", sector); } #endif if (action == DISKREADING) success = WriteMemoryBlock (buf, tobuffer); else success = ReadMemoryBlock (cmpbuf, tobuffer); if (!success) { puts (""); NLS_PUTSTRING (1, 20, "Unsuspected memory error."); SetErrorStopped (); return CRITICAL; } if (action == VERIFICATION) { if (memcmp (buf, cmpbuf, 5 /*tobuffer */ ) != 0) { puts (""); NLS_PRINTSTRING (1, 37, "Compare error on sector"); printf (" %ld.\n", sector); } } } } } } if (audible && (!UseImageFile)) Beep (); if (!UseImageFile || (ImageModus == READIMAGE)) { while (!NLS_TEST_NO (loop2)) /* loop2 */ { if (askdisk) { if (!UseImageFile) puts ("\n"); NLS_PRINTSTRING (1, 21, "Insert TARGET diskette into drive"); printf (" %s\n\n", argv[2]); NLS_PRINTSTRING (1, 9, "Press any key to continue . . ."); WaitForInput (); } else askdisk = TRUE; /* Check disk capacity is the same as that of the original diskette. */ for (;;) { if (!DiskReadBootInfo (tdrive, &free)) { puts (""); NLS_PUTSTRING (1, 10, "Disk not ready!"); total = 0; } else total = free.df_total * free.df_sclus; if (((UseImageFile) && (FileSize != FilledDiskSize)) || (disksize != total * free.df_bsec)) { puts (""); NLS_PUTSTRING (1, 22, "Diskette does not have the same capacity as the original."); if (fallthrough) return NONFATAL; puts (""); NLS_PRINTSTRING (1, 23, "Put a diskette with the right capacity in drive"); printf (" %s, \n", argv[2]); NLS_PUTSTRING (1, 24, "or press CTRL-C to cancel."); WaitForInput (); /* When the user presses CTRL-C this function does not return */ } else break; } if (UseImageFile) { puts ("\n"); NLS_PRINTSTRING (4, 0, "Copying"); printf (" %d ", (int) FilledTotal); NLS_PRINTSTRING (4, 1, "clusters"); printf (", %d ", free.df_sclus); NLS_PRINTSTRING (4, 2, "sectors per cluster"); printf (", %d ", free.df_bsec); NLS_PRINTSTRING (4, 3, "bytes per sector"); puts ("."); NLS_PRINTSTRING (4, 4, "Relevant drive size is"); printf (" %lu ", FilledDiskSize); NLS_PRINTSTRING (4, 5, "bytes"); puts ("."); beginsector = endsector; endsector += allocated / BYTESPERSECTOR; if (endsector > total) endsector = total; } for (action = DISKWRITING; (verify) ? (action <= VERIFICATION) : (action < VERIFICATION); action++) { if (action == DISKWRITING) { if (UseImageFile) { puts (""); NLS_PRINTSTRING (1, 35, "Writing image file . . ."); } else { puts ("\n"); NLS_PRINTSTRING (1, 25, "Writing to TARGET diskette in drive . . ."); } PrepareForReading (); } else /* VERIFICATION */ { puts (""); NLS_PRINTSTRING (1, 38, "Verifying . . ."); PrepareForReading (); /* Rewind */ } for (sector = beginsector; sector < endsector; sector = sector + TOCOPYSECTORS) { if (sector < endsector - TOCOPYSECTORS) tocopysectors = TOCOPYSECTORS; else tocopysectors = (int) (endsector - sector); tobuffer = (unsigned) (tocopysectors * BYTESPERSECTOR); if (IsDiskReadRequired (sector, tocopysectors)) { if (!ReadMemoryBlock (buf, tobuffer)) { puts (""); NLS_PUTSTRING (1, 20, "Unsuspected memory error."); SetErrorStopped (); return CRITICAL; } if (action == DISKWRITING) { #ifdef UPDATE_SERIALNUM if (sector == 0) { if (ParsedData->serialnumber == UPDATE) UpdateDiskSerialNumber (buf); } #endif if (abswrite (tdrive, tocopysectors, (int) sector, buf) != 0) { if (sector == 0) { if (abswrite(tdrive, 1, 0, buf) != 0) { puts("\n"); NLS_PRINTSTRING(1, 41, "Sector 0 unwritable! Write protected?"); if (FilledDiskSize == allocated) break; else return CRITICAL; } } puts (""); NLS_PRINTSTRING (1, 27, "Media error writing to sector"); printf (" %ld.\n", sector); } } else { if (absread (tdrive, tocopysectors, (int) sector, cmpbuf) != 0) { puts (""); NLS_PRINTSTRING (1, 18, "Media error reading from sector"); printf (" %ld.\n", sector); } if (sector == 0) { if (ParsedData->serialnumber == UPDATE) { ClearDiskSerialNumber (buf); ClearDiskSerialNumber (cmpbuf); } } if (memcmp (buf, cmpbuf, tobuffer) != 0) { puts (""); NLS_PRINTSTRING (1, 37, "Compare error on sector"); printf (" %ld.\n", sector); } } } } } if (!UseImageFile) puts (""); if (UseImageFile || (FilledDiskSize == allocated)) /* If everything fitted in memory */ { loop2 = (fallthrough) ? CatNO : CatNO + 1; if (loop2 == CatYES) loop2++; while (!NLS_TEST_YES_NO (loop2)) { ClrKbd (); if (audible) Beep (); puts (""); if (UseImageFile) puts (""); NLS_PRINTSTRING (1, 28, "Do you want another copy of this "); if (UseImageFile) { endsector = 0; NLS_PRINTSTRING (1, 29, "image file (Y/N)?"); } else NLS_PRINTSTRING (1, 30, "disk (Y/N)?"); loop2 = toupper (getch ()); puts (""); } if (UseImageFile && (NLS_TEST_YES (loop2))) puts (""); } else { puts (""); loop2 = CatNO; } /* Change the serial number of the target disk. */ #ifdef UPDATE_SERIALNUM if (ParsedData->serialnumber == UPDATE) { puts (""); PrintDiskSerialNumber (); puts (""); } #endif } /* loop2 */ loop2 = CatYES; if (loop2 == CatNO) loop2++; ReleaseMemory (); } else { if (CopyingToSameDisk) { PrepareForReading (); if (!WriteFileFromMemory (GetSFN (OUTFILE_ID), buf, BUFFERSIZE, FilledDiskSize, asktdisk, fallthrough, Overwrite)) { NLS_PUTSTRING (1, 36, "Problem writing image file."); return CRITICAL; } } } loop1 = CatYES + 1; if (loop1 == CatNO) loop1++; if (!UseImageFile && !fallthrough && (endsector == total)) { while (!NLS_TEST_YES_NO (loop1)) { ClrKbd (); puts (""); NLS_PRINTSTRING (1, 31, "Copy another disk (Y/N)?"); loop1 = toupper (getch ()); puts (""); endsector = 0; } } else if (UseImageFile || (fallthrough && (endsector == total))) { loop1 = CatNO; if (fallthrough) puts (""); else if (audible && (ImageModus == WRITEIMAGE)) Beep (); } } /* end loop1 */ if ((UseImageFile) && (ImageModus == WRITEIMAGE)) puts (""); return COPYSUCCESS; }
int MMCReadSectors(BYTE bDevice, void *pData, DWORD dwStartSector, WORD wSectorCount) { int nError; WORD wReadCount; DRIVE *pDrive = 0; BYTE *pByte; nError = MMC_OK; MMCLock(); if (bDevice >= MMC_MAX_SUPPORTED_DEVICE) { nError = MMC_DRIVE_NOT_FOUND; } else { pDrive = &sDrive[bDevice]; if ((pDrive->wFlags & MMC_READY) == 0) { nError = MMC_DRIVE_NOT_FOUND; } else { if ((dwStartSector + wSectorCount) > pDrive->dTotalSectors) { nError = MMC_PARAM_ERROR; } } } if (nError == MMC_OK) { pByte = (BYTE *)pData; if (wSectorCount != 1) { while (wSectorCount > 0) { if (wSectorCount < 256) { wReadCount = wSectorCount; } else { wReadCount = 256; } nError = ReadSectors(pDrive, pByte, dwStartSector, wReadCount); if (nError != MMC_OK) { break; } dwStartSector += wReadCount; wSectorCount -= wReadCount; pByte += (wReadCount * pDrive->wSectorSize); } } else { nError = ReadSectors(pDrive, pByte, dwStartSector, 1); } } MMCFree(); return(nError); } /* MMCReadSectors */
/*-----------------------------------*/ static int MountDevice(void * DriveData, int DeviceNumber, int DeviceType, DWORD Flags) { kal_uint8 retry = 0; #if defined(__SIM_PLUS__) sd_select_enum sel; if((MSDC_HANDLE *)DriveData == &MSDC_Blk[0]) sel = SD_EXT; else { sel = SD_SIM; } MSDC_Switch_Card(sel); #endif #ifdef DRV_LSD /*notifiedFMT may be modified by FMT and MMI tasks, but it is no need to protect this, FMT can't preempt MMI*/ if(1 == notifiedFMT)/*in this state. we dont allow any access on memory card, we will return fail on any mount trial*/ { return FS_MSDC_MOUNT_ERROR; } #endif if(gMSDC_Handle->mIsInitialized) return SECTOR_SIZE; gMSDC_Handle->is_init_timeout = KAL_FALSE; start: if(!gMSDC_Handle->mIsPresent) { //dbg_print("not present \r\n"); #if defined(_NAND_FLASH_BOOTING_) // add the following code for solving plug in or out the SD card during // NFB loading process. The card detection interruptwill disapperared // while interrupt controller is masked. IRQMask(IRQ_MSDC_CODE); if(*(volatile kal_uint16*)MSDC_PS & MSDC_PS_PIN0) { if(gMSDC_Handle->ins_level == MSDC_IOCTRL_PULL_UP) gMSDC_Handle->mIsPresent = KAL_FALSE; else gMSDC_Handle->mIsPresent = KAL_TRUE; } else { if(gMSDC_Handle->ins_level == MSDC_IOCTRL_PULL_UP) gMSDC_Handle->mIsPresent = KAL_TRUE; else gMSDC_Handle->mIsPresent = KAL_FALSE; } IRQUnmask(IRQ_MSDC_CODE); #endif // _NAND_FLASH_BOOTING_ if(!gMSDC_Handle->mIsPresent) { MSDC_PDNControl(KAL_TRUE); return FS_MSDC_MOUNT_ERROR; } } MSDC_PDNControl(KAL_FALSE); if(SD_Initialize() != NO_ERROR) { goto err_exit; } //if(SD_MountDevice(DeviceType) != FS_NO_ERROR) //return FS_MSDC_MOUNT_ERROR; //dbg_print("Mount success! \r\n"); #ifdef MSDC_SDMMC_NAND /*for SDMMC NAND, some manufacturs sale NAND with all sectors zero, we should format it first*/ if(ReadSectors( DriveData, 0, 1, MSDC_Sector) != NO_ERROR) goto err_exit; if(0x55aa != (MSDC_Sector[128] & 0xffff0000)) { /*it doesn't have correct MBR*/ SD_SelfFormat(); } else { if(ReadSectors( DriveData, 1, 1, MSDC_Sector) != NO_ERROR) goto err_exit; if(0x55aa != (MSDC_Sector[128] & 0xffff0000)) { /*it doesn't have correct PBR*/ SD_SelfFormat(); } } #endif MSDC_PDNControl(KAL_TRUE); #ifdef DRV_LSD if(KAL_TRUE == kal_query_systemInit()) { /*we don't let access memory card before FMT get plug in message*/ /*there is no task can access when system init*/ notifiedFMT = 1; return FS_MSDC_MOUNT_ERROR; } #endif return SECTOR_SIZE; err_exit: if(retry++ <= SD_MAX_RETRY && gMSDC_Handle->is_init_timeout == KAL_FALSE) { //dbg_print("SD MountDevice failed! retry: %d \r\n",retry); goto start; } #if defined(__MSDC_NOT_SUPPORT_HOT_PLUG__) gMSDC_Handle->mIsPresent = KAL_FALSE; #endif #if defined(__SIM_PLUS__) if(INT_USBBoot() == KAL_TRUE && current_card == SD_SIM) { gMSDC_Handle->mIsPresent = KAL_FALSE; } #endif MSDC_PDNControl(KAL_TRUE); return FS_MSDC_MOUNT_ERROR; }
int highlevelformat(void * DriveData, UINT BaseSectorNumber) { int FATType; int SystemSectors, RootDirSectors, FATSectors, Written; int FatCount, StartOfFAT, InfoSector; int i, y; FS_BootRecord *PBR; kal_uint8 MediaDescriptor; int Result = RTF_NO_ERROR; /* HLF - 1 - Read the PBR sector */ ///* FIXME */ DrvDirect.ReadSector(SectorBuffer /* Buffer */ , // BaseSectorNumber /* Sector Number */); ReadSectors(DriveData, BaseSectorNumber, 1, MSDC_Sector); PBR = (FS_BootRecord*)&MSDC_Sector; /* HLF - 2 - Setup PBR sector content and attributes */ { if (PBR->BP.SectorsOnDisk != 0) PBR->BP.TotalSectors = PBR->BP.SectorsOnDisk; if (PBR->Signature != 0xAA55 || //PBR->BP.TotalSectors > Par.Partition.Sectors || PBR->BP.TotalSectors > (gSD->mCSD.capacity/512) || PBR->BP.BytesPerSector != 512 || PBR->BP.SectorsPerCluster == 0 || PBR->BP.ReservedSectors == 0 || PBR->BP.NumberOfFATs == 0) { return FS_INVALID_FILE_SYSTEM; } FATSectors = (PBR->BP.SectorsPerFAT) ? PBR->BP.SectorsPerFAT : PBR->BP.E._32.SectorsPerFAT; RootDirSectors = (PBR->BP.DirEntries * 32 + (PBR->BP.BytesPerSector - 1)) / PBR->BP.BytesPerSector; Written = PBR->BP.TotalSectors - PBR->BP.ReservedSectors - PBR->BP.NumberOfFATs * FATSectors - RootDirSectors; Written = Written / PBR->BP.SectorsPerCluster; if (Written <= 0xFF4L) FATType = 12; else if (Written <= 0xFFF4l) FATType = 16; else if (Written <= 0xFFFFFF4l) FATType = 32; else return FS_INVALID_FILE_SYSTEM; Written = 0; if (FATType == 32) { RootDirSectors = PBR->BP.SectorsPerCluster; if (PBR->BP.E._32.RootDirCluster != 2) { PBR->BP.E._32.RootDirCluster = 2; /* Result = RTFSeek(Drive, 0, RTF_FILE_BEGIN); if (Result < RTF_NO_ERROR) return Result; Result = RTFWrite(Drive, (void*)PBR, SECTOR_SIZE, NULL); if (Result < RTF_NO_ERROR) return Result; */ //above seek and write seems mean write to specific sector WriteSectors(DriveData, BaseSectorNumber , 1, (void *)PBR); /* Result = RTFSeek(Drive, PBR->BP.E._32.BackupBootSector * SECTOR_SIZE, RTF_FILE_BEGIN); if (Result < RTF_NO_ERROR) return Result; Result = RTFWrite(Drive, (void*)PBR, SECTOR_SIZE, NULL); if (Result < RTF_NO_ERROR) return Result; */ WriteSectors(DriveData, BaseSectorNumber + PBR->BP.E._32.BackupBootSector , 1, (void *)PBR); } } SystemSectors = PBR->BP.ReservedSectors + PBR->BP.NumberOfFATs * FATSectors + RootDirSectors; FatCount = PBR->BP.NumberOfFATs; StartOfFAT = PBR->BP.ReservedSectors; InfoSector = PBR->BP.E._32.FSInfoSector; } /*we get MediaDescriptor for step 6 usage, since we will clear MSDC_Sector*/ MediaDescriptor = PBR->BP.MediaDescriptor; /*we need MSDC_Sector to be 512-byte-0 now*/ kal_mem_set(MSDC_Sector, 0, 512); /* HLF - 3 - Formating cont, FAT32 reserved sector write down */ { if ((FATType == 32) && (InfoSector > 0) && (InfoSector < StartOfFAT)) { /* FIXME */ //DrvDirect.ZeroSector( BaseSectorNumber + InfoSector /* Start Sector Number */ , // 1 /* Zero Sector Count */ ); WriteSectors(DriveData, BaseSectorNumber + InfoSector, 1, MSDC_Sector); } } SD_startFastFormat(); /* HLF - 4 - Formating cont, start, FAT Table write down , remember FAT begin sector */ { /* FIXME */ //DrvDirect.ZeroSector( BaseSectorNumber + StartOfFAT /* Start Sector Number */ , // FATSectors * FatCount /* Zero Sector Count */ ); #ifdef DRV_LSD WriteSectors(DriveData, BaseSectorNumber + StartOfFAT, FATSectors * FatCount , MSDC_Sector); #else for(i = 0; i < FATSectors * FatCount; i++) { WriteSectors(DriveData, BaseSectorNumber + StartOfFAT + i, 1 , MSDC_Sector); } #endif } /* HLF - 5 - Formating cont, Root directory write down */ { int x; x = StartOfFAT + FATSectors * FatCount; /* FIXME */ //DrvDirect.ZeroSector( BaseSectorNumber + x /* Start Sector Number */ , // RootDirSectors /* Zero Sector Count */ ); #ifdef DRV_LSD WriteSectors(DriveData, BaseSectorNumber + x, RootDirSectors , MSDC_Sector); #else for(i = 0; i < RootDirSectors; i++) { WriteSectors(DriveData, BaseSectorNumber + x + i, 1 , MSDC_Sector); } #endif } SD_closeFastFormat(); /* HLF - 6 - Formating final, 1st FAT sector must be rewritten */ { switch (FATType) { case 32: { //kal_uint32 * FPtr = (void*) ScratchSector; MSDC_Sector[2] = 0x0FFFFFFF; // this is for the root dir MSDC_Sector[1] = 0x0FFFFFFF; break; } case 16: { kal_uint16 * FPtr = (void*) MSDC_Sector; FPtr[1] = 0xFFFF; break; } case 12: { kal_uint8 *FPtr = (void *)MSDC_Sector; /* FIXME */ FPtr[2] = 0xFF; /* FIXME */ FPtr[1] = 0xFF; /* FIXME */ FPtr[0] = MediaDescriptor; break; } } for (i = 0, y = StartOfFAT; i < FatCount; i++ , y+= FATSectors) { ///* FIXME */ DrvDirect.WriteSector(SectorBuffer /* Buffer */ , // BaseSectorNumber + y /* Sector Number */); WriteSectors(DriveData, BaseSectorNumber + y, 1 , MSDC_Sector); } } /* HLF - 7 - The END */ return FS_NO_ERROR; }
static int GetDirectoryEntry(int drive, int copyFlag, char *pathname, Bit32u buffer) { char searchName[256]; int error, dirSize; unsigned char defBuffer[CD_FRAMESIZE]; unsigned dirEntrySector, entryLength, index; char *searchPos = searchName; size_t searchlen; /* skip initial \ */ MEMCPY_2UNIX(searchName, pathname + 1, 255); searchName[255] = '\0'; strupperDOS(searchName); //strip of tailing . (XCOM APOCALIPSE) searchlen = strlen(searchName); if (searchlen > 1 && strcmp(searchName, "..")) if (searchName[searchlen - 1] == '.') searchName[searchlen - 1] = 0; C_printf("MSCDEX: Get DirEntry : Find : %s\n", searchName); // read vtoc error = ReadSectors(drive, 16, 1, defBuffer); if (error) return error; // TODO: has to be iso 9660 if (memcmp("CD001", defBuffer + 1, 5) != 0) return MSCDEX_ERROR_BAD_FORMAT; // get directory position dirEntrySector = *(unsigned *)(defBuffer + 156 + 2); dirSize = *(int *)(defBuffer + 156 + 10); do { // Get string part char *useName = searchPos; size_t useNameLength; searchPos = strchr(searchPos, '\\'); if (searchPos) { useNameLength = searchPos - useName; searchPos++; } else useNameLength = strlen(useName); while (1) { error = ReadSectors(drive, dirEntrySector, 1, defBuffer); if (error) return error; index = 0; do { char *entryName, *longername; unsigned nameLength; entryLength = defBuffer[index]; C_printf("MSCDEX: entryLength=%u, index=%d\n", entryLength, index); if (entryLength == 0) break; nameLength = defBuffer[index + 32]; entryName = defBuffer + index + 33; if (namecomp (entryName, nameLength, useName, useNameLength)) break; /* Xcom Apocalipse searches for MUSIC. * and expects to find MUSIC;1 * All Files on the CDROM are of the kind * blah;1 */ longername = memchr(entryName, ';', nameLength); if (longername && namecomp(entryName, longername - entryName, useName, useNameLength)) break; index += entryLength; } while (index + 33 <= CD_FRAMESIZE); if (index + 33 <= CD_FRAMESIZE) break; // continue search in next sector dirSize -= 2048; if (dirSize <= 0) return 2; // file not found dirEntrySector++; } // directory wechseln dirEntrySector = *(unsigned *)(defBuffer + index + 2); dirSize = *(unsigned *)(defBuffer + index + 10); } while (searchPos); return fill_buffer(copyFlag, buffer, defBuffer + index, entryLength); };
int mscdex(void) { unsigned char *buf = MK_FP32(_ES, _BX); unsigned long dev; unsigned seg, strat, intr; int error; int i; char devname[] = "MSCD0001"; if (numDrives == 0) return 0; switch (_AL) { case 0x00: /* install check */ _BX = numDrives; if (_BX > 0) { int firstdrive = INT_MAX; for (i = 0; i < 4; i++) { if (cd_drives[i] != -1 && cd_drives[i] < firstdrive) firstdrive = cd_drives[i]; } _CX = firstdrive; } break; case 0x01: /* driver info */ for (i = 0; i < 4; i++) { if (cd_drives[i] != -1) { /* subunit: always 0 for cdrom.sys */ WRITE_BYTE(buf, 0x00); devname[7] = i + '1'; WRITE_DWORD(buf + 1, is_dos_device(devname)); buf += 5; } }; break; case 0x02: /* copyright file name */ case 0x03: /* abstract file name */ case 0x04: /* documentation file name */ { char readbuf[CD_FRAMESIZE]; if (ReadVTOC(_CX, 0x00, readbuf) == 0) { MEMCPY_2DOS(buf, readbuf + 702 + (_AL - 2) * 37, 37); WRITE_BYTE(buf + 37, 0); NOCARRY; } else { _AX = MSCDEX_ERROR_UNKNOWN_DRIVE; CARRY; } break; } case 0x05: /* read vtoc */ NOCARRY; error = ReadVTOC(_CX, _DX, buf); if (error) { _AL = error; CARRY; }; break; case 0x08: /* read sectors */ NOCARRY; error = ReadSectors(_CX, (_SI << 16) + _DI, _DX, buf); if (error) { _AL = error; CARRY; }; break; case 0x09: /* write sectors - not supported */ _AL = MSCDEX_ERROR_DRIVE_NOT_READY; CARRY; break; case 0x0B: /* CD-ROM drive check */ _AX = 0; for (i = 0; i < 4; i++) if (_CX == cd_drives[i]) { _AX = 1; break; } _BX = 0xadad; break; case 0x0C: _BX = (MSCDEX_VERSION_HIGH << 8) + MSCDEX_VERSION_LOW; break; case 0x0D: /* get drives */ for (i = 0; i < 4; i++) if (cd_drives[i] != -1) WRITE_BYTE(buf++, cd_drives[i]); break; case 0x0F: /* Get directory entry */ CARRY; _AX = GetDirectoryEntry(_CL, _CH & 1, buf, SEGOFF2LINEAR(_SI, _DI)); if (_AX == 0 || _AX == 1) NOCARRY; break; case 0x10: { int driver = GetDriver(_CX); if (driver >= 4) break; devname[7] = driver + '1'; dev = is_dos_device(devname); seg = dev >> 16; dev = SEGOFF2LINEAR(seg, dev & 0xffff); strat = READ_WORD(dev + 6); intr = READ_WORD(dev + 8); fake_call_to(seg, intr); fake_call_to(seg, strat); break; } default: C_printf("unknown mscdex\n"); return 0; } return 1; }
void USB_Mode(void) { gb_cmd_timeout=0; set_clock_mode(CLOCK_MODE_USB); PowerOn_Init_USB(); Fill_EndpointDataTable_Into_ExRamBase(); USBInitialize(); Init_Flash_Reg(); Init_Flash_Variable(); gc_WriteProof = 0x00; InitFlash(); USB_REG[0x27] = 0x00; // 080304 jay change for new fpga GLOBAL_REG[0x17] = 0x01; // UDC O/P IE = 0x83; gdw_USB_CountDown = USB_DETECT_TIMEOUT; EA=1; while(!gc_USBRST_ISR_Detected) // Bulk_In_Out 將跳出while 迴圈 //20090630 chiayen modify { USB_PlugDetect(); if((--gdw_USB_CountDown==0)) //080925chiayen add { gb_cmd_timeout=1; break; } if(!gbt_USB_Detected) { break; } } EA=0; if(gb_cmd_timeout==1) //080925chiayen modify { USB_DisConnect(); set_clock_mode(CLOCK_MODE_MP3); InitFlash(); return; } if(!gb_cmd_timeout) { LCM_clear(); LCM_Disp_PC(); LCM_Disp_PCConnect(); LCM_Disp_MyMP3Logo(); } for(;;) { USB_PlugDetect(); if(!gbt_USB_Detected) {//usb connected USB_DisConnect(); set_clock_mode(CLOCK_MODE_MP3); InitFlash(); break; } else { if (gc_USBStage == CBWStage) { if(gbt_USB_Connect_Flag) { //tdw_CMD_In_Count =0x02FFFFF; } else { gdw_USB_CountDown =0x01FFFF; //081208 detect charge first } EA=1; while (!gbt_USB_CMD_IN) // Bulk_In_Out 將跳出while 迴圈 { USB_PlugDetect(); if(!gbt_USB_Detected) { break; } if(gbt_USB_Connect_Flag) { if(gbt_USER_Remove_Flag) { gb_cmd_timeout=1; break; } } else { if((--gdw_USB_CountDown==0)&&(!gb_USB_ISR_Detected)) { gb_cmd_timeout=1; break; } } } EA=0; // 表示有 SCSI CMD 進入 關閉中斷避免常常進入 if((!gbt_USB_Detected)||(gb_cmd_timeout==1)) //080925chiayen modify { USB_DisConnect(); set_clock_mode(CLOCK_MODE_MP3); InitFlash(); break; } gbt_USB_CMD_IN = 0; SD_Card_Detect(); gbt_USB_Connect_Flag =1; // 081208 jay add Save_CBW_Packet(); Decode_CBW_Command(); // 解CBW和記錄相關手續 } if(gw_USBDisplayTime==0) { USB_Mode_Disp(); } if (gc_USBStage == BulkInReadSectorsStage) { USB_REG[0xD2] &= 0xDD; //Disable Bulk-Out中斷 ReadSectors(); USB_REG[0xE9] = 0x11; if (gc_ErrorCode == SET_ABRT) { gc_RequestSenseCode = 0x06; //ECC Error gdw_dCBW_DataXferLength.LW = ((LWORD)TotalXferPageNum.WD) << 9; gc_bCSWStatus = 0x01; } else if (gc_ErrorCode == ID_NOT_FND) { gc_RequestSenseCode = 0x07; //over range gdw_dCBW_DataXferLength.LW = ((LWORD)TotalXferPageNum.WD) << 9; gc_bCSWStatus = 0x01; } else { gdw_dCBW_DataXferLength.LW = 0; } gc_USBStage = CSWStage; // 進入Comand Status Wrapper } if (gc_USBStage == BulkOutWriteSectorsStage) { USB_REG[0xD2] &= 0xDD; //Disable Bulk-Out中斷 USB_REG[0x11] = 0x01; //HW auto ACK WriteSectors(); USB_REG[0x11] = 0x00; USB_REG[0xE9] = 0x22; if (gc_ErrorCode == SET_ABRT) { gc_bCSWStatus = 0x01; gc_RequestSenseCode = 0x08; // write error } else if (gc_ErrorCode == ID_NOT_FND) { gc_RequestSenseCode = 0x07; //over range gc_bCSWStatus = 0x01; } else { gc_bCSWStatus = 0x00; gc_RequestSenseCode = 0xFF; // normal } gdw_dCBW_DataXferLength.LW = 0; gc_USBStage = CSWStage; } if (gc_USBStage == BulkInResponseStage) { // '4' BulkInProcess USB_REG[0xD2] &= 0xDD; //Disable Bulk-Out中斷 if (gbt_XferNormalResponseData_or_ModeSense) { // '1':Normal if (COMD_IN[0] == 0x23) { gdw_dCBW_DataXferLength.WD[1] = 0x00; USB_REG[0x16] = 0x00; USB_REG[0x15] = 0x0C; USB_REG[0xA1] |= 0x01; while (USB_REG[0xA1] & 0x01) { USB_PlugDetect(); // 081014 Jay add for usb plug out if(!gbt_USB_Detected) break; } USB_REG[0xE9] = 0x01; } else { while (gdw_dCBW_DataXferLength.WD[1]) { if (gdw_dCBW_DataXferLength.WD[1] > 64) { gdw_dCBW_DataXferLength.WD[1] = gdw_dCBW_DataXferLength.WD[1] - 64; USB_REG[0x16] = 0x00; USB_REG[0x15] = 0x40; } else { USB_REG[0x16] = gdw_dCBW_DataXferLength.BY[2] & 0x0F; USB_REG[0x15] = gdw_dCBW_DataXferLength.BY[3]; gdw_dCBW_DataXferLength.WD[1] = 0x00; } USB_REG[0xA1] |= 0x01; while (USB_REG[0xA1] & 0x01) { //081014 Jay add for usb plug out USB_PlugDetect(); if(!gbt_USB_Detected) break; } USB_REG[0xE9] = 0x01; } } } else { if (COMD_IN[0] == 0x1A) { gdw_dCBW_DataXferLength.WD[1] = 0x00; USB_REG[0x15] = 0x04; USB_REG[0x16] = 0x00; USB_REG[0xA1] |= 0x01; while (USB_REG[0xA1] & 0x01) { //081014 Jay add for usb plug out USB_PlugDetect(); if(!gbt_USB_Detected) break; } USB_REG[0xE9] = 0x01; } else { gdw_dCBW_DataXferLength.WD[1] = 0x00; USB_REG[0x15] = 0x08; USB_REG[0x16] = 0x00; USB_REG[0xA1] |= 0x01; while (USB_REG[0xA1] & 0x01) { //081014 Jay add for usb plug out USB_PlugDetect(); if(!gbt_USB_Detected) break; } USB_REG[0xE9] = 0x01; } gbt_XferNormalResponseData_or_ModeSense = NormalResponseData;// 將預設設為一般型 } gc_USBStage = CSWStage; } if (gc_USBStage == BulkStallStage) { StallBulkRW(); gc_USBStage = CSWStage; } if (gc_USBStage == BulkInReadBufferStage) { USB_REG[0xD2] &= 0xDD; //Disable Bulk-Out中斷 NoCard_ReadSectors(); USB_REG[0xE9] = 0x11; gdw_dCBW_DataXferLength.LW = 0; gc_USBStage = CSWStage; // 進入Comand Status Wrapper } if (gc_USBStage == BulkOutWriteBufferStage) { USB_REG[0xD2] &= 0xDD; //Disable Bulk-Out中斷 USB_REG[0x11] = 0x01; //HW auto ACK NoCard_WriteSectors(); USB_REG[0x11] = 0x00; USB_REG[0xE9] = 0x22; gdw_dCBW_DataXferLength.LW = 0; gc_USBStage = CSWStage; } if (gc_USBStage == CSWStage) { gc_USBStage = CBWStage; // 重新準備收下一筆command USB_BUF_Bank0[ 0] = 'U'; // 以下由SetCSWData expand USB_BUF_Bank0[ 1] = 'S'; USB_BUF_Bank0[ 2] = 'B'; USB_BUF_Bank0[ 3] = 'S'; USB_BUF_Bank0[ 4] = dCBW_Tag[0]; USB_BUF_Bank0[ 5] = dCBW_Tag[1]; USB_BUF_Bank0[ 6] = dCBW_Tag[2]; USB_BUF_Bank0[ 7] = dCBW_Tag[3]; USB_BUF_Bank0[ 8] = gdw_dCBW_DataXferLength.BY[3]; // LSB 記錄剩下未被傳輸的資料 USB_BUF_Bank0[ 9] = gdw_dCBW_DataXferLength.BY[2]; // 記錄剩下未被傳輸的資料 USB_BUF_Bank0[10] = gdw_dCBW_DataXferLength.BY[1]; // 記錄剩下未被傳輸的資料 USB_BUF_Bank0[11] = gdw_dCBW_DataXferLength.BY[0]; // MSB 記錄剩下未被傳輸的資料 USB_BUF_Bank0[12] = gc_bCSWStatus; // Command Status 見BulkOnly P.15說明各種碼的情形 USB_REG[0x2B] = 0x00; USB_REG[0x16] = 0x00; USB_REG[0x15] = 0x0D; USB_REG[0xA1] |= 0x01; while (USB_REG[0xA1] & 0x01) { //081014 Jay add for usb plug out USB_PlugDetect(); if(!gbt_USB_Detected) break; } } USB_REG[0xE9] = 0x01; USB_REG[0xD2] |= 0x02; //Enable Bulk-Out中斷 USB_REG[0xA1] |= 0x02; //下一筆31Byte Bulk-Out } } }