int Partition::Mount() { EXT2_SUPER_BLOCK sblock; int gSizes, gSizeb; char *tmpbuf; ReadDisk(handle, &sblock, relative_sect + 2, 2, sect_size); if(sblock.s_magic != EXT2_SUPER_MAGIC) { LOG("Bad Super Block. The drive %s is not ext2 formatted.\n", linux_name.c_str()); return -1; } if(sblock.s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION) { LOG("File system compression is used which is not supported.\n"); } blocksize = EXT2_BLOCK_SIZE(&sblock); inodes_per_group = EXT2_INODES_PER_GROUP(&sblock); inode_size = EXT2_INODE_SIZE(&sblock); LOG(" Розмір блоку: %d\n", blocksize); totalGroups = (sblock.s_blocks_count)/EXT2_BLOCKS_PER_GROUP(&sblock); gSizeb = (sizeof(EXT2_GROUP_DESC) * totalGroups); gSizes = (gSizeb / sect_size)+1; desc = (EXT2_GROUP_DESC *) calloc(totalGroups, sizeof(EXT2_GROUP_DESC)); if(desc == NULL) { LOG("Not enough Memory: mount: desc: Exiting\n"); exit(1); } if((tmpbuf = (char *) malloc(gSizes * sect_size)) == NULL) { LOG("Not enough Memory: mount: tmpbuf: Exiting\n"); exit(1); } if((blocksize/sect_size) <= 2) ReadDisk(handle, tmpbuf, relative_sect + ((blocksize/sect_size) + 2), gSizes, sect_size); else ReadDisk(handle, tmpbuf, relative_sect + (blocksize/sect_size), gSizes, sect_size); memcpy(desc, tmpbuf, gSizeb); free(tmpbuf); return 0; }
/** * Find UFS super block, start from LBA address dwOffset. * * @param[in] hDisk Disk handle. * @param[in] dwOffset LBA of start finding. * * @return NULL if superblock not found or other error, or a pointer to MyFs. */ PMyFs FindSblock(HANDLE hDisk, DWORD dwOffset) { int i; static int sblock_try[] = SBLOCKSEARCH; /* places for search */ BYTE pSblock[SBLOCKSIZE]; for (i = 0; sblock_try[i] != - 1; i++) { struct fs *fs; ReadDisk(hDisk, pSblock, (((DWORD64)dwOffset) << 9) + ((DWORD64)sblock_try[i]), SBLOCKSIZE); fs = (struct fs*)pSblock; if (fs->fs_magic == FS_BAD_MAGIC) { break; } if ((fs->fs_magic == FS_UFS1_MAGIC || (fs->fs_magic == FS_UFS2_MAGIC && fs->fs_sblockloc == sblock_try[i])) && fs->fs_ncg >= 1 && fs->fs_bsize >= MINBSIZE && fs->fs_bsize >= SBLOCKSIZE) { /* check superblock */ PMyFs my_fs = (PMyFs)HeapAlloc(g_hProcessHeap, 0, sizeof(MyFs)); if (my_fs) { return MakeMyFs((struct fs*)pSblock, my_fs); } } } return NULL; }
int Partition::ReadBlock(uint64_t blocknum, void *buffer) { char *newbuffer; int nsects = blocksize/sect_size; int ret; uint64_t sectno; newbuffer = buffercache.take(blocknum); if(!newbuffer) { newbuffer = new char[blocksize]; if(!newbuffer) return -1; else { sectno = (uint64_t)((uint64_t)nsects * blocknum) + relative_sect; } ret = ReadDisk(handle, newbuffer, sectno, nsects, sect_size); if(ret < 0) { delete [] newbuffer; return ret; } } memcpy(buffer, newbuffer, blocksize); buffercache.insert(blocknum, newbuffer, 1); return 0; }
/*static*/ VOID WINAPI BiosDiskService(LPWORD Stack) { BYTE Drive; PDISK_IMAGE DiskImage; switch (getAH()) { /* Disk -- Reset Disk System */ case 0x00: { Drive = getDL(); if (Drive & 0x80) { AllDisksReset(); /* Return success */ setAH(0x00); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; break; } Drive &= ~0x80; if (Drive >= ARRAYSIZE(FloppyDrive)) { DPRINT1("BiosDiskService(0x00): Drive number 0x%02X invalid\n", Drive); /* Return error */ setAH(0x01); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; break; } // TODO: Reset drive /* Return success */ setAH(0x00); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; break; } /* Disk -- Get Status of Last Operation */ case 0x01: { BYTE LastOperationStatus = 0x00; Drive = getDL(); DiskImage = GetDisk(Drive); if (!DiskImage || !IsDiskPresent(DiskImage)) { DPRINT1("BiosDiskService(0x01): Disk number 0x%02X invalid\n", Drive); /* Return error */ setAH(0x01); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; break; } LastOperationStatus = DiskImage->LastOperationStatus; if (Drive & 0x80) Bda->LastDiskOperation = LastOperationStatus; else Bda->LastDisketteOperation = LastOperationStatus; /* Return last error */ setAH(LastOperationStatus); if (LastOperationStatus == 0x00) Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; else Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; break; } /* Disk -- Read Sectors into Memory */ case 0x02: { BYTE Status; BYTE Head = getDH(); BYTE NumSectors = getAL(); // CH: Low eight bits of cylinder number // CL: High two bits of cylinder (bits 6-7, hard disk only) WORD Cylinder = MAKEWORD(getCH(), (getCL() >> 6) & 0x02); // CL: Sector number 1-63 (bits 0-5) BYTE Sector = (getCL() & 0x3F); // 1-based Drive = getDL(); DiskImage = GetDisk(Drive); if (!DiskImage || !IsDiskPresent(DiskImage)) { DPRINT1("BiosDiskService(0x02): Disk number 0x%02X invalid\n", Drive); /* Return error */ setAH(0x01); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; break; } /* Read the sectors */ Status = ReadDisk(DiskImage, Cylinder, Head, Sector, NumSectors); if (Status == 0x00) { /* Return success */ setAH(0x00); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; } else { DPRINT1("BiosDiskService(0x02): Error when reading from disk number 0x%02X (0x%02X)\n", Drive, Status); /* Return error */ setAH(Status); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; } break; } /* Disk -- Write Disk Sectors */ case 0x03: { BYTE Status; BYTE Head = getDH(); BYTE NumSectors = getAL(); // CH: Low eight bits of cylinder number // CL: High two bits of cylinder (bits 6-7, hard disk only) WORD Cylinder = MAKEWORD(getCH(), (getCL() >> 6) & 0x02); // CL: Sector number 1-63 (bits 0-5) BYTE Sector = (getCL() & 0x3F); // 1-based Drive = getDL(); DiskImage = GetDisk(Drive); if (!DiskImage || !IsDiskPresent(DiskImage)) { DPRINT1("BiosDiskService(0x03): Disk number 0x%02X invalid\n", Drive); /* Return error */ setAH(0x01); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; break; } /* Write the sectors */ Status = WriteDisk(DiskImage, Cylinder, Head, Sector, NumSectors); if (Status == 0x00) { /* Return success */ setAH(0x00); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; } else { DPRINT1("BiosDiskService(0x03): Error when writing to disk number 0x%02X (0x%02X)\n", Drive, Status); /* Return error */ setAH(Status); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; } break; } /* Disk -- Verify Disk Sectors */ case 0x04: /* Floppy/Fixed Disk -- Format Track */ case 0x05: /* Fixed Disk -- Format Track and Set Bad Sector Flags */ case 0x06: /* Fixed Disk -- Format Drive starting at Given Track */ case 0x07: goto Default; /* Disk -- Get Drive Parameters */ case 0x08: { WORD MaxCylinders; BYTE MaxHeads; BYTE PresentDrives = 0; BYTE i; Drive = getDL(); DiskImage = GetDisk(Drive); if (!DiskImage || !IsDiskPresent(DiskImage)) { DPRINT1("BiosDiskService(0x08): Disk number 0x%02X invalid\n", Drive); /* Return error */ setAH(0x01); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; break; } // Minus 2 because it's the maximum cylinder number (not count), // and the last cylinder is reserved (for compatibility with BIOSes // which reserve it for testing purposes). MaxCylinders = DiskImage->DiskInfo.Cylinders - 2; // Minus 1 because it's the maximum head number (not count). MaxHeads = DiskImage->DiskInfo.Heads - 1; // CL: Sector number 1-63 (bits 0-5) // High two bits of cylinder (bits 6-7, hard disk only) setCL((DiskImage->DiskInfo.Sectors & 0x3F) | ((HIBYTE(MaxCylinders) & 0x02) << 6)); // CH: Low eight bits of cylinder number setCH(LOBYTE(MaxCylinders)); setDH(MaxHeads); if (Drive & 0x80) { /* Count the number of active HDDs */ for (i = 0; i < ARRAYSIZE(HardDrive); ++i) { if (IsDiskPresent(HardDrive[i])) ++PresentDrives; } /* Reset ES:DI to NULL */ // FIXME: NONONO!! Apps expect (for example, MS-DOS kernel) // that this function does not modify ES:DI if it was called // for a HDD. // setES(0x0000); // setDI(0x0000); } else { /* Count the number of active floppies */ for (i = 0; i < ARRAYSIZE(FloppyDrive); ++i) { if (IsDiskPresent(FloppyDrive[i])) ++PresentDrives; } /* ES:DI points to the floppy parameter table */ setES(HIWORD(((PULONG)BaseAddress)[0x1E])); setDI(LOWORD(((PULONG)BaseAddress)[0x1E])); } setDL(PresentDrives); setBL(DiskImage->DiskType); // DiskGeometryList[DiskImage->DiskType].biosval setAL(0x00); /* Return success */ setAH(0x00); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; break; } /* Hard Disk -- Initialize Controller with Drive Parameters */ case 0x09: /* Hard Disk -- Read Long Sectors */ case 0x0A: /* Hard Disk -- Write Long Sectors */ case 0x0B: goto Default; /* Hard Disk -- Seek to Cylinder */ case 0x0C: { BYTE Status; BYTE Head = getDH(); // CH: Low eight bits of cylinder number // CL: High two bits of cylinder (bits 6-7, hard disk only) WORD Cylinder = MAKEWORD(getCH(), (getCL() >> 6) & 0x02); // CL: Sector number 1-63 (bits 0-5) BYTE Sector = (getCL() & 0x3F); // 1-based Drive = getDL(); if (!(Drive & 0x80)) { DPRINT1("BiosDiskService(0x0C): Disk number 0x%02X is not a HDD\n", Drive); /* Return error */ setAH(0x01); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; break; } DiskImage = GetDisk(Drive); if (!DiskImage || !IsDiskPresent(DiskImage)) { DPRINT1("BiosDiskService(0x0C): Disk number 0x%02X invalid\n", Drive); /* Return error */ setAH(0x01); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; break; } /* Set position */ Status = SeekDisk(DiskImage, Cylinder, Head, Sector); if (Status == 0x00) { /* Return success */ setAH(0x00); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; } else { DPRINT1("BiosDiskService(0x0C): Error when seeking in disk number 0x%02X (0x%02X)\n", Drive, Status); /* Return error */ setAH(Status); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; } break; } /* Hard Disk -- Reset Hard Disks */ case 0x0D: { // FIXME: Should do what 0x11 does. UNIMPLEMENTED; } /* Hard Disk -- Read Sector Buffer (XT only) */ case 0x0E: /* Hard Disk -- Write Sector Buffer (XT only) */ case 0x0F: goto Default; /* Hard Disk -- Check if Drive is ready */ case 0x10: { Drive = getDL(); if (!(Drive & 0x80)) { DPRINT1("BiosDiskService(0x10): Disk number 0x%02X is not a HDD\n", Drive); /* Return error */ setAH(0x01); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; break; } DiskImage = GetDisk(Drive); if (!DiskImage || !IsDiskPresent(DiskImage)) { DPRINT1("BiosDiskService(0x10): Disk number 0x%02X invalid\n", Drive); /* Return error */ setAH(0x01); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; break; } /* Return success */ setAH(0x00); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; break; } /* Hard Disk -- Recalibrate Drive */ case 0x11: { BYTE Status; Drive = getDL(); if (!(Drive & 0x80)) { DPRINT1("BiosDiskService(0x11): Disk number 0x%02X is not a HDD\n", Drive); /* Return error */ setAH(0x01); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; break; } DiskImage = GetDisk(Drive); if (!DiskImage || !IsDiskPresent(DiskImage)) { DPRINT1("BiosDiskService(0x11): Disk number 0x%02X invalid\n", Drive); /* Return error */ setAH(0x01); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; break; } /* Set position to zero */ Status = SeekDisk(DiskImage, /*Cylinder*/ 0, /*Head*/ 0, /*Sector*/ 1); if (Status == 0x00) { /* Return success */ setAH(0x00); Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; } else { DPRINT1("BiosDiskService(0x11): Error when recalibrating disk number 0x%02X (0x%02X)\n", Drive, Status); /* Return error */ setAH(Status); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; } break; } /* Hard Disk -- Controller RAM Diagnostic */ case 0x12: /* Hard Disk -- Drive Diagnostic */ case 0x13: /* Hard Disk -- Controller Internal Diagnostic */ case 0x14: goto Default; /* Disk -- Get Disk Type */ case 0x15: { Drive = getDL(); DiskImage = GetDisk(Drive); if (!DiskImage || !IsDiskPresent(DiskImage)) { DPRINT1("BiosDiskService(0x15): Disk number 0x%02X invalid\n", Drive); /* Return error */ setAH(0x01); Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF; break; } if (Drive & 0x80) { ULONG NumSectors; /* Hard disk */ setAH(0x03); /* Number of 512-byte sectors in CX:DX */ NumSectors = (ULONG)((ULONG)DiskImage->DiskInfo.Cylinders * DiskImage->DiskInfo.Heads) * DiskImage->DiskInfo.Sectors; setCX(HIWORD(NumSectors)); setDX(LOWORD(NumSectors)); } else { /* Floppy */ setAH(0x01); } /* Return success */ Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF; break; } /* Floppy Disk -- Detect Disk Change */ case 0x16: /* Floppy Disk -- Set Disk Type for Format */ case 0x17: /* Disk -- Set Media Type for Format */ case 0x18: goto Default; default: Default: { DPRINT1("BIOS Function INT 13h, AH = 0x%02X, AL = 0x%02X, BH = 0x%02X NOT IMPLEMENTED\n", getAH(), getAL(), getBH()); } } }