Пример #1
0
NTSTATUS
Fat16Format(IN HANDLE FileHandle,
            IN PPARTITION_INFORMATION PartitionInfo,
            IN PDISK_GEOMETRY DiskGeometry,
            IN PUNICODE_STRING Label,
            IN BOOLEAN QuickFormat,
            IN ULONG ClusterSize,
            IN OUT PFORMAT_CONTEXT Context)
{
    FAT16_BOOT_SECTOR BootSector;
    OEM_STRING VolumeLabel;
    ULONG SectorCount;
    ULONG RootDirSectors;
    ULONG TmpVal1;
    ULONG TmpVal2;
    ULONG TmpVal3;
    NTSTATUS Status;

    /* Calculate cluster size */
    if (ClusterSize == 0)
    {
        if (PartitionInfo->PartitionLength.QuadPart < 16LL * 1024LL * 1024LL)
        {
            /* Partition < 16MB ==> 1KB Cluster */
            ClusterSize = 1024;
        }
        else if (PartitionInfo->PartitionLength.QuadPart < 128LL * 1024LL * 1024LL)
        {
            /* Partition < 128MB ==> 2KB Cluster */
            ClusterSize = 2048;
        }
        else if (PartitionInfo->PartitionLength.QuadPart < 256LL * 1024LL * 1024LL)
        {
            /* Partition < 256MB ==> 4KB Cluster */
            ClusterSize = 4096;
        }
        else
        {
            /* Partition >= 256MB (< 512MB) ==> 8KB Cluster */
            ClusterSize = 8192;
        }
    }

    SectorCount = PartitionInfo->PartitionLength.QuadPart >>
        GetShiftCount(DiskGeometry->BytesPerSector); /* Use shifting to avoid 64-bit division */

    RtlZeroMemory(&BootSector, sizeof(FAT16_BOOT_SECTOR));
    memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8);
    /* FIXME: Add dummy bootloader for real */
    BootSector.Jump[0] = 0xeb;
    BootSector.Jump[1] = 0x3c;
    BootSector.Jump[2] = 0x90;
    BootSector.BytesPerSector = DiskGeometry->BytesPerSector;
    BootSector.SectorsPerCluster = ClusterSize / BootSector.BytesPerSector;
    BootSector.ReservedSectors = 1;
    BootSector.FATCount = 2;
    BootSector.RootEntries = 512;
    BootSector.Sectors = (SectorCount < 0x10000) ? (unsigned short)SectorCount : 0;
    BootSector.Media = 0xf8;
    BootSector.FATSectors = 0;  /* Set later. See below. */
    BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
    BootSector.Heads = DiskGeometry->TracksPerCylinder;
    BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
    BootSector.SectorsHuge = (SectorCount >= 0x10000) ? (unsigned long)SectorCount : 0;
    BootSector.Drive = (DiskGeometry->MediaType == FixedMedia) ? 0x80 : 0x00;
    BootSector.ExtBootSignature = 0x29;
    BootSector.VolumeID = CalcVolumeSerialNumber();
    if ((Label == NULL) || (Label->Buffer == NULL))
    {
        memcpy(&BootSector.VolumeLabel[0], "NO NAME    ", 11);
    }
    else
    {
        RtlUnicodeStringToOemString(&VolumeLabel, Label, TRUE);
        RtlFillMemory(&BootSector.VolumeLabel[0], 11, ' ');
        memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
               VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
        RtlFreeOemString(&VolumeLabel);
    }

    memcpy(&BootSector.SysType[0], "FAT16   ", 8);

    DPRINT("BootSector.SectorsHuge = %lx\n", BootSector.SectorsHuge);

    RootDirSectors = ((BootSector.RootEntries * 32) +
        (BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector;

    /* Calculate number of FAT sectors */
    /* (BootSector.BytesPerSector / 2) FAT entries (16bit) fit into one sector */
    TmpVal1 = SectorCount - (BootSector.ReservedSectors + RootDirSectors);
    TmpVal2 = ((BootSector.BytesPerSector / 2) * BootSector.SectorsPerCluster) + BootSector.FATCount;
    TmpVal3 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
    BootSector.FATSectors = (unsigned short)(TmpVal3 & 0xffff);
    DPRINT("BootSector.FATSectors = %hu\n", BootSector.FATSectors);

    /* Init context data */
    Context->TotalSectorCount =
        1 + (BootSector.FATSectors * 2) + RootDirSectors;

    if (!QuickFormat)
    {
        Context->TotalSectorCount += SectorCount;

        Status = FatWipeSectors(FileHandle,
                                SectorCount,
                                (ULONG)BootSector.SectorsPerCluster,
                                (ULONG)BootSector.BytesPerSector,
                                Context);
        if (!NT_SUCCESS(Status))
        {
            DPRINT("FatWipeSectors() failed with status 0x%.08x\n", Status);
            return Status;
        }
    }

    Status = Fat16WriteBootSector(FileHandle,
                                  &BootSector,
                                  Context);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Fat16WriteBootSector() failed with status 0x%.08x\n", Status);
        return Status;
    }

    /* Write first FAT copy */
    Status = Fat16WriteFAT(FileHandle,
                           0,
                           &BootSector,
                           Context);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Fat16WriteFAT() failed with status 0x%.08x\n", Status);
        return Status;
    }

    /* Write second FAT copy */
    Status = Fat16WriteFAT(FileHandle,
                           (ULONG)BootSector.FATSectors,
                           &BootSector,
                           Context);
    if (!NT_SUCCESS(Status))
    {
       DPRINT("Fat16WriteFAT() failed with status 0x%.08x.\n", Status);
        return Status;
    }

    Status = Fat16WriteRootDirectory(FileHandle,
                                     &BootSector,
                                     Context);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Fat16WriteRootDirectory() failed with status 0x%.08x\n", Status);
    }

    return Status;
}
Пример #2
0
NTSTATUS
Fat32Format(IN HANDLE FileHandle,
            IN PPARTITION_INFORMATION PartitionInfo,
            IN PDISK_GEOMETRY DiskGeometry,
            IN PUNICODE_STRING Label,
            IN BOOLEAN QuickFormat,
            IN ULONG ClusterSize,
            IN OUT PFORMAT_CONTEXT Context)
{
    FAT32_BOOT_SECTOR BootSector;
    OEM_STRING VolumeLabel;
    ULONG TmpVal1;
    ULONG TmpVal2;
    NTSTATUS Status;

    /* Calculate cluster size */
    if (ClusterSize == 0)
    {
        if (PartitionInfo->PartitionLength.QuadPart < 8LL * 1024LL * 1024LL * 1024LL)
        {
            /* Partition < 8GB ==> 4KB Cluster */
            ClusterSize = 4096;
        }
        else if (PartitionInfo->PartitionLength.QuadPart < 16LL * 1024LL * 1024LL * 1024LL)
        {
            /* Partition 8GB - 16GB ==> 8KB Cluster */
            ClusterSize = 8192;
        }
        else if (PartitionInfo->PartitionLength.QuadPart < 32LL * 1024LL * 1024LL * 1024LL)
        {
            /* Partition 16GB - 32GB ==> 16KB Cluster */
            ClusterSize = 16384;
        }
        else
        {
            /* Partition >= 32GB ==> 32KB Cluster */
            ClusterSize = 32768;
        }
    }

    memset(&BootSector, 0, sizeof(FAT32_BOOT_SECTOR));
    memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8);
    BootSector.BytesPerSector = DiskGeometry->BytesPerSector;
    BootSector.SectorsPerCluster = ClusterSize / BootSector.BytesPerSector;
    BootSector.ReservedSectors = 32;
    BootSector.FATCount = 2;
    BootSector.RootEntries = 0;
    BootSector.Sectors = 0;
    BootSector.Media = 0xf8;
    BootSector.FATSectors = 0;
    BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
    BootSector.Heads = DiskGeometry->TracksPerCylinder;
    BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
    BootSector.SectorsHuge = PartitionInfo->PartitionLength.QuadPart >>
        GetShiftCount(BootSector.BytesPerSector); /* Use shifting to avoid 64-bit division */
    BootSector.FATSectors32 = 0; /* Set later */
    BootSector.ExtFlag = 0; /* Mirror all FATs */
    BootSector.FSVersion = 0x0000; /* 0:0 */
    BootSector.RootCluster = 2;
    BootSector.FSInfoSector = 1;
    BootSector.BootBackup = 6;
    BootSector.Drive = (DiskGeometry->MediaType == FixedMedia) ? 0x80 : 0x00;
    BootSector.ExtBootSignature = 0x29;
    BootSector.VolumeID = CalcVolumeSerialNumber ();
    if ((Label == NULL) || (Label->Buffer == NULL))
    {
        memcpy(&BootSector.VolumeLabel[0], "NO NAME    ", 11);
    }
    else
    {
        RtlUnicodeStringToOemString(&VolumeLabel, Label, TRUE);
        memset(&BootSector.VolumeLabel[0], ' ', 11);
        memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
               VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
        RtlFreeOemString(&VolumeLabel);
    }

    memcpy(&BootSector.SysType[0], "FAT32   ", 8);

    /* Calculate number of FAT sectors */
    /* (BytesPerSector / 4) FAT entries (32bit) fit into one sector */
    TmpVal1 = BootSector.SectorsHuge - BootSector.ReservedSectors;
    TmpVal2 = ((BootSector.BytesPerSector / 4) * BootSector.SectorsPerCluster) + BootSector.FATCount;
    BootSector.FATSectors32 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
    DPRINT("FATSectors32 = %lu\n", BootSector.FATSectors32);

    /* Init context data */
    Context->TotalSectorCount =
        2 + (BootSector.FATSectors32 * BootSector.FATCount) + BootSector.SectorsPerCluster;

    if (!QuickFormat)
    {
        Context->TotalSectorCount += BootSector.SectorsHuge;

        Status = Fat32WipeSectors(FileHandle,
                                  &BootSector,
                                  Context);
        if (!NT_SUCCESS(Status))
        {
            DPRINT("Fat32WipeSectors() failed with status 0x%.08x\n", Status);
            return Status;
        }
    }

    Status = Fat32WriteBootSector(FileHandle,
                                  &BootSector,
                                  Context);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Fat32WriteBootSector() failed with status 0x%.08x\n", Status);
        return Status;
    }

    Status = Fat32WriteFsInfo(FileHandle,
                              &BootSector,
                              Context);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Fat32WriteFsInfo() failed with status 0x%.08x\n", Status);
        return Status;
    }

    /* Write first FAT copy */
    Status = Fat32WriteFAT(FileHandle,
                           0,
                           &BootSector,
                           Context);
    if (!NT_SUCCESS(Status))
    {
      DPRINT("Fat32WriteFAT() failed with status 0x%.08x\n", Status);
      return Status;
    }

    /* Write second FAT copy */
    Status = Fat32WriteFAT(FileHandle,
                           BootSector.FATSectors32,
                           &BootSector,
                           Context);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Fat32WriteFAT() failed with status 0x%.08x.\n", Status);
        return Status;
    }

    Status = Fat32WriteRootDirectory(FileHandle,
                                     &BootSector,
                                     Context);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Fat32WriteRootDirectory() failed with status 0x%.08x\n", Status);
    }

    return Status;
}
Пример #3
0
NTSTATUS
Fat12Format(IN HANDLE FileHandle,
            IN PPARTITION_INFORMATION PartitionInfo,
            IN PDISK_GEOMETRY DiskGeometry,
            IN PUNICODE_STRING Label,
            IN BOOLEAN QuickFormat,
            IN ULONG ClusterSize,
            IN OUT PFORMAT_CONTEXT Context)
{
    FAT16_BOOT_SECTOR BootSector;
    OEM_STRING VolumeLabel;
    ULONG SectorCount;
    ULONG RootDirSectors;
    ULONG TmpVal1;
    ULONG TmpVal2;
    ULONG TmpVal3;
    NTSTATUS Status;

    /* Calculate cluster size */
    if (ClusterSize == 0)
    {
        if (DiskGeometry->MediaType == FixedMedia)
        {
            /* 4KB Cluster (Harddisk only) */
            ClusterSize = 4096;
        }
        else
        {
            /* 512 byte cluster (floppy) */
            ClusterSize = 512;
        }
    }

    SectorCount = PartitionInfo->PartitionLength.QuadPart >>
        GetShiftCount(DiskGeometry->BytesPerSector); /* Use shifting to avoid 64-bit division */

    DPRINT("SectorCount = %lu\n", SectorCount);

    memset(&BootSector, 0, sizeof(FAT16_BOOT_SECTOR));
    memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8);
    BootSector.BytesPerSector = DiskGeometry->BytesPerSector;
    BootSector.SectorsPerCluster = ClusterSize / BootSector.BytesPerSector;
    BootSector.ReservedSectors = 1;
    BootSector.FATCount = 2;
    BootSector.RootEntries = 512;
    BootSector.Sectors = (SectorCount < 0x10000) ? (unsigned short)SectorCount : 0;
    BootSector.Media = 0xf8;
    BootSector.FATSectors = 0;  /* Set later. See below. */
    BootSector.SectorsPerTrack = DiskGeometry->SectorsPerTrack;
    BootSector.Heads = DiskGeometry->TracksPerCylinder;
    BootSector.HiddenSectors = PartitionInfo->HiddenSectors;
    BootSector.SectorsHuge = (SectorCount >= 0x10000) ? (unsigned long)SectorCount : 0;
    BootSector.Drive = DiskGeometry->MediaType == FixedMedia ? 0x80 : 0x00;
    BootSector.ExtBootSignature = 0x29;
    BootSector.VolumeID = CalcVolumeSerialNumber();
    if ((Label == NULL) || (Label->Buffer == NULL))
    {
        memcpy(&BootSector.VolumeLabel[0], "NO NAME    ", 11);
    }
    else
    {
        RtlUnicodeStringToOemString(&VolumeLabel, Label, TRUE);
        memset(&BootSector.VolumeLabel[0], ' ', 11);
        memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
               VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
        RtlFreeOemString(&VolumeLabel);
    }

    memcpy(&BootSector.SysType[0], "FAT12   ", 8);

    RootDirSectors = ((BootSector.RootEntries * 32) +
        (BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector;

    /* Calculate number of FAT sectors */
    /* ((BootSector.BytesPerSector * 2) / 3) FAT entries (12bit) fit into one sector */
    TmpVal1 = SectorCount - (BootSector.ReservedSectors + RootDirSectors);
    TmpVal2 = (((BootSector.BytesPerSector * 2) / 3) * BootSector.SectorsPerCluster) + BootSector.FATCount;
    TmpVal3 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
    BootSector.FATSectors = (unsigned short)(TmpVal3 & 0xffff);

    DPRINT("BootSector.FATSectors = %hx\n", BootSector.FATSectors);

    /* Init context data */
    Context->TotalSectorCount =
        1 + (BootSector.FATSectors * 2) + RootDirSectors;

    Status = Fat12WriteBootSector(FileHandle,
                                  &BootSector,
                                  Context);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Fat12WriteBootSector() failed with status 0x%.08x\n", Status);
        return Status;
    }

    /* Write first FAT copy */
    Status = Fat12WriteFAT(FileHandle,
                           0,
                           &BootSector,
                           Context);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Fat12WriteFAT() failed with status 0x%.08x\n", Status);
        return Status;
    }

    /* Write second FAT copy */
    Status = Fat12WriteFAT(FileHandle,
                           (ULONG)BootSector.FATSectors,
                           &BootSector,
                           Context);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Fat12WriteFAT() failed with status 0x%.08x.\n", Status);
        return Status;
    }

    Status = Fat12WriteRootDirectory(FileHandle,
                                     &BootSector,
                                     Context);
    if (!NT_SUCCESS(Status))
    {
        DPRINT("Fat12WriteRootDirectory() failed with status 0x%.08x\n", Status);
    }

    if (!QuickFormat)
    {
        /* FIXME: Fill remaining sectors */
    }

    return Status;
}