2003-04-28 Casper S. Hornstrup <chorns@users.sourceforge.net>

* lib/fslib/vfatlib/vfatlib.h: New file.
	* subsys/system/usetup/format.c: Ditto.
	* subsys/system/usetup/format.h: Ditto.
	* lib/fslib/vfatlib/vfatlib.c (GetShiftCount): Define.
	(VfatWriteBootSector, VfatWriteFsInfo, VfatWriteFAT,
	VfatWriteRootDirectory): New function.
	(VfatFormat): Implement.
	* subsys/system/usetup/bootsup.c: (InstallFat32BootCodeToFile): Use
	0x0000 as marker to disable backup boot sector.
	(InstallFat32BootCodeToDisk): Add lower 8-bit to BackupBootSector.
	Also treat 0x0000 as no backup boot sector is available.
	* subsys/system/usetup/makefile (TARGET_SDKLIBS): Define.
	(TARGET_OBJECTS): Add format.o.
	* subsys/system/usetup/partlist.c (AddPartitionList): Initialize
	PartNumber field.
	(GetSelectedPartition): Set PartEntryNumber correctly.
	(CreateSelectedPartition): Write partition information to disk.
	(DeleteSelectedPartition): New function.
	* subsys/system/usetup/partlist.h (PARTDATA): Add field CreatePartition.
	(DeleteSelectedPartition): Prototype.
	* subsys/system/usetup/usetup.c (ConfirmDeletePartition): New function.
	(SelectPartitionPage): Support deletion of partition.
	(FormatPartitionPage): Support formatting of partition.

svn path=/trunk/; revision=4612
This commit is contained in:
Casper Hornstrup 2003-04-28 19:44:13 +00:00
parent 55300ebbf2
commit 37f29ead4b
10 changed files with 852 additions and 23 deletions

View file

@ -1,3 +1,29 @@
2003-04-28 Casper S. Hornstrup <chorns@users.sourceforge.net>
* lib/fslib/vfatlib/vfatlib.h: New file.
* subsys/system/usetup/format.c: Ditto.
* subsys/system/usetup/format.h: Ditto.
* lib/fslib/vfatlib/vfatlib.c (GetShiftCount): Define.
(VfatWriteBootSector, VfatWriteFsInfo, VfatWriteFAT,
VfatWriteRootDirectory): New function.
(VfatFormat): Implement.
* subsys/system/usetup/bootsup.c: (InstallFat32BootCodeToFile): Use
0x0000 as marker to disable backup boot sector.
(InstallFat32BootCodeToDisk): Add lower 8-bit to BackupBootSector.
Also treat 0x0000 as no backup boot sector is available.
* subsys/system/usetup/makefile (TARGET_SDKLIBS): Define.
(TARGET_OBJECTS): Add format.o.
* subsys/system/usetup/partlist.c (AddPartitionList): Initialize
PartNumber field.
(GetSelectedPartition): Set PartEntryNumber correctly.
(CreateSelectedPartition): Write partition information to disk.
(DeleteSelectedPartition): New function.
* subsys/system/usetup/partlist.h (PARTDATA): Add field CreatePartition.
(DeleteSelectedPartition): Prototype.
* subsys/system/usetup/usetup.c (ConfirmDeletePartition): New function.
(SelectPartitionPage): Support deletion of partition.
(FormatPartitionPage): Support formatting of partition.
2003-04-27 Casper S. Hornstrup <chorns@users.sourceforge.net>
* tools/helper.mk (TARGET_ASFLAGS): Add -march and define MK_ARCH_ID.

View file

@ -11,7 +11,22 @@
#include <debug.h>
#define NTOS_MODE_USER
#include <ntos.h>
#include <ddk/ntddscsi.h>
#include <fslib/vfatlib.h>
#include "vfatlib.h"
static ULONG
GetShiftCount(ULONG Value)
{
ULONG i = 1;
while (Value > 0)
{
i++;
Value /= 2;
}
return i - 2;
}
NTSTATUS
@ -22,6 +37,279 @@ VfatInitialize()
return STATUS_SUCCESS;
}
static NTSTATUS
VfatWriteBootSector(IN HANDLE FileHandle,
IN PFAT32_BOOT_SECTOR BootSector)
{
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING Name;
NTSTATUS Status;
PUCHAR NewBootSector;
LARGE_INTEGER FileOffset;
/* Allocate buffer for new bootsector */
NewBootSector = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
0,
SECTORSIZE);
if (NewBootSector == NULL)
return(STATUS_INSUFFICIENT_RESOURCES);
/* Zero the new bootsector */
memset(NewBootSector, 0, SECTORSIZE);
/* Copy FAT32 BPB to new bootsector */
memcpy((NewBootSector + 3),
&BootSector->OEMName[0],
87); /* FAT32 BPB length (up to (not including) Res2) */
/* Write sector 0 */
FileOffset.QuadPart = 0ULL;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
NewBootSector,
SECTORSIZE,
&FileOffset,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
return(Status);
}
/* Write backup boot sector */
if (BootSector->BootBackup != 0x0000)
{
FileOffset.QuadPart = (ULONGLONG)((ULONG) BootSector->BootBackup * SECTORSIZE);
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
NewBootSector,
SECTORSIZE,
&FileOffset,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
return(Status);
}
}
/* Free the new boot sector */
RtlFreeHeap(RtlGetProcessHeap(), 0, NewBootSector);
return(Status);
}
static NTSTATUS
VfatWriteFsInfo(IN HANDLE FileHandle,
IN PFAT32_BOOT_SECTOR BootSector)
{
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING Name;
NTSTATUS Status;
PFAT32_FSINFO FsInfo;
LARGE_INTEGER FileOffset;
/* Allocate buffer for new sector */
FsInfo = (PFAT32_FSINFO)RtlAllocateHeap(RtlGetProcessHeap(),
0,
BootSector->BytesPerSector);
if (FsInfo == NULL)
return(STATUS_INSUFFICIENT_RESOURCES);
/* Zero the new sector */
memset(FsInfo, 0, BootSector->BytesPerSector);
FsInfo->LeadSig = 0x41615252;
FsInfo->StrucSig = 0x61417272;
FsInfo->FreeCount = 0xffffffff;
FsInfo->NextFree = 0xffffffff;
/* Write sector */
FileOffset.QuadPart = BootSector->FSInfoSector * BootSector->BytesPerSector;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
FsInfo,
BootSector->BytesPerSector,
&FileOffset,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
RtlFreeHeap(RtlGetProcessHeap(), 0, FsInfo);
return(Status);
}
/* Free the new sector buffer */
RtlFreeHeap(RtlGetProcessHeap(), 0, FsInfo);
return(Status);
}
static NTSTATUS
VfatWriteFAT(IN HANDLE FileHandle,
ULONG SectorOffset,
IN PFAT32_BOOT_SECTOR BootSector)
{
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING Name;
NTSTATUS Status;
PUCHAR Buffer;
LARGE_INTEGER FileOffset;
ULONG i;
/* Allocate buffer */
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
0,
BootSector->BytesPerSector);
if (Buffer == NULL)
return(STATUS_INSUFFICIENT_RESOURCES);
/* Zero the buffer */
memset(Buffer, 0, BootSector->BytesPerSector);
/* FAT cluster 0 */
Buffer[0] = 0xf8; /* Media type */
Buffer[1] = 0xff;
Buffer[2] = 0xff;
Buffer[3] = 0xff;
/* FAT cluster 1 */
Buffer[4] = 0xcf; /* Clean shutdown, no disk read/write errors, end-of-cluster (EOC) mark */
Buffer[5] = 0xff;
Buffer[6] = 0xff;
Buffer[7] = 0xf7;
/* FAT cluster 2 */
Buffer[8] = 0xff; /* End of root directory */
Buffer[9] = 0xff;
Buffer[10] = 0xff;
Buffer[11] = 0x0f;
/* Write first sector of the FAT */
FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors) * BootSector->BytesPerSector;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
Buffer,
BootSector->BytesPerSector,
&FileOffset,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
return(Status);
}
/* Zero the buffer */
memset(Buffer, 0, BootSector->BytesPerSector);
/* Zero the rest of the FAT */
for (i = 1; i < BootSector->FATSectors32 - 1; i++)
{
/* Zero one sector of the FAT */
FileOffset.QuadPart = (SectorOffset + BootSector->ReservedSectors + i) * BootSector->BytesPerSector;
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
Buffer,
BootSector->BytesPerSector,
&FileOffset,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
return(Status);
}
}
/* Free the buffer */
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
return(Status);
}
static NTSTATUS
VfatWriteRootDirectory(IN HANDLE FileHandle,
IN PFAT32_BOOT_SECTOR BootSector)
{
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
NTSTATUS Status;
PUCHAR Buffer;
LARGE_INTEGER FileOffset;
ULONGLONG FirstDataSector;
ULONGLONG FirstRootDirSector;
/* Allocate buffer for the cluster */
Buffer = (PUCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
0,
BootSector->SectorsPerCluster * BootSector->BytesPerSector);
if (Buffer == NULL)
return(STATUS_INSUFFICIENT_RESOURCES);
/* Zero the buffer */
memset(Buffer, 0, BootSector->SectorsPerCluster * BootSector->BytesPerSector);
DPRINT("BootSector->ReservedSectors = %lu\n", BootSector->ReservedSectors);
DPRINT("BootSector->FATSectors32 = %lu\n", BootSector->FATSectors32);
DPRINT("BootSector->RootCluster = %lu\n", BootSector->RootCluster);
DPRINT("BootSector->SectorsPerCluster = %lu\n", BootSector->SectorsPerCluster);
/* Write cluster */
FirstDataSector = BootSector->ReservedSectors +
(BootSector->FATCount * BootSector->FATSectors32) + 0 /* RootDirSectors */;
DPRINT("FirstDataSector = %lu\n", FirstDataSector);
FirstRootDirSector = ((BootSector->RootCluster - 2) * BootSector->SectorsPerCluster) + FirstDataSector;
FileOffset.QuadPart = FirstRootDirSector * BootSector->BytesPerSector;
DPRINT("FirstRootDirSector = %lu\n", FirstRootDirSector);
DPRINT("FileOffset = %lu\n", FileOffset.QuadPart);
Status = NtWriteFile(FileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock,
Buffer,
BootSector->SectorsPerCluster * BootSector->BytesPerSector,
&FileOffset,
NULL);
if (!NT_SUCCESS(Status))
{
DPRINT("NtWriteFile() failed (Status %lx)\n", Status);
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
return(Status);
}
/* Free the buffer */
RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
return(Status);
}
NTSTATUS
VfatFormat(
@ -32,9 +320,204 @@ VfatFormat(
DWORD ClusterSize,
PFMIFSCALLBACK Callback)
{
DPRINT1("VfatFormat()\n");
OBJECT_ATTRIBUTES ObjectAttributes;
DISK_GEOMETRY DiskGeometry;
IO_STATUS_BLOCK Iosb;
HANDLE FileHandle;
SCSI_ADDRESS ScsiAddress;
PARTITION_INFORMATION PartitionInfo;
FAT32_BOOT_SECTOR BootSector;
ANSI_STRING VolumeLabel;
NTSTATUS Status;
ULONG RootDirSectors;
ULONG TmpVal1;
ULONG TmpVal2;
return STATUS_SUCCESS;
DPRINT("VfatFormat(DriveRoot '%S')\n", DriveRoot->Buffer);
InitializeObjectAttributes(&ObjectAttributes,
DriveRoot,
0,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
FILE_WRITE_ACCESS | FILE_WRITE_ATTRIBUTES,
&ObjectAttributes,
&Iosb,
1,
FILE_SYNCHRONOUS_IO_ALERT);
if (!NT_SUCCESS(Status))
{
DPRINT("NtOpenFile() failed with status 0x%.08x\n", Status);
return Status;
}
Status = NtDeviceIoControlFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&DiskGeometry,
sizeof(DISK_GEOMETRY));
if (!NT_SUCCESS(Status))
{
DPRINT("IOCTL_DISK_GET_DRIVE_GEOMETRY failed with status 0x%.08x\n", Status);
NtClose(FileHandle);
return Status;
}
if (DiskGeometry.MediaType == FixedMedia)
{
DPRINT("Cylinders %d\n", DiskGeometry.Cylinders.QuadPart);
DPRINT("TracksPerCylinder %d\n", DiskGeometry.TracksPerCylinder);
DPRINT("SectorsPerTrack %d\n", DiskGeometry.SectorsPerTrack);
DPRINT("BytesPerSector %d\n", DiskGeometry.BytesPerSector);
DPRINT("DiskSize %d\n",
DiskGeometry.Cylinders.QuadPart *
(ULONGLONG)DiskGeometry.TracksPerCylinder *
(ULONGLONG)DiskGeometry.SectorsPerTrack *
(ULONGLONG)DiskGeometry.BytesPerSector);
Status = NtDeviceIoControlFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_DISK_GET_PARTITION_INFO,
NULL,
0,
&PartitionInfo,
sizeof(PARTITION_INFORMATION));
if (!NT_SUCCESS(Status))
{
DPRINT("IOCTL_DISK_GET_PARTITION_INFO failed with status 0x%.08x\n", Status);
NtClose(FileHandle);
return Status;
}
DPRINT("PartitionType 0x%x\n", PartitionInfo.PartitionType);
DPRINT("StartingOffset %d\n", PartitionInfo.StartingOffset);
DPRINT("PartitionLength %d\n", PartitionInfo.PartitionLength);
DPRINT("HiddenSectors %d\n", PartitionInfo.HiddenSectors);
DPRINT("PartitionNumber %d\n", PartitionInfo.PartitionNumber);
DPRINT("BootIndicator 0x%x\n", PartitionInfo.BootIndicator);
DPRINT("RewritePartition %d\n", PartitionInfo.RewritePartition);
DPRINT("RecognizedPartition %d\n", PartitionInfo.RecognizedPartition);
}
else
{
DPRINT1("FIXME: Removable media is not supported\n");
NtClose(FileHandle);
return Status;
}
memset(&BootSector, 0, sizeof(FAT32_BOOT_SECTOR));
memcpy(&BootSector.OEMName[0], "MSWIN4.1", 8);
BootSector.BytesPerSector = DiskGeometry.BytesPerSector;
BootSector.SectorsPerCluster = 4096 / BootSector.BytesPerSector; // 4KB clusters /* FIXME: */
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 = 63; /* FIXME: */
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 = 0xff; /* No BIOS boot drive available */ //0x80; /* FIXME: */
BootSector.ExtBootSignature = 0x29;
BootSector.VolumeID = 0x45768798; /* FIXME: */
if ((Label == NULL) || (Label->Buffer == NULL))
{
memcpy(&BootSector.VolumeLabel[0], "NO NAME ", 11);
}
else
{
RtlUnicodeStringToAnsiString(&VolumeLabel, Label, TRUE);
memset(&BootSector.VolumeLabel[0], ' ', 11);
memcpy(&BootSector.VolumeLabel[0], VolumeLabel.Buffer,
VolumeLabel.Length < 11 ? VolumeLabel.Length : 11);
RtlFreeAnsiString(&VolumeLabel);
}
memcpy(&BootSector.SysType[0], "FAT32 ", 8);
RootDirSectors = ((BootSector.RootEntries * 32) +
(BootSector.BytesPerSector - 1)) / BootSector.BytesPerSector;
TmpVal1 = BootSector.SectorsHuge - (BootSector.ReservedSectors + RootDirSectors);
TmpVal2 = (256 * BootSector.SectorsPerCluster) + BootSector.FATCount;
if (TRUE /* FAT32 */)
{
TmpVal2 /= 2;
BootSector.FATSectors = 0;
BootSector.FATSectors32 = (TmpVal1 + (TmpVal2 - 1)) / TmpVal2;
}
Status = VfatWriteBootSector(FileHandle,
&BootSector);
if (!NT_SUCCESS(Status))
{
DPRINT("VfatWriteBootSector() failed with status 0x%.08x\n", Status);
NtClose(FileHandle);
return Status;
}
Status = VfatWriteFsInfo(FileHandle,
&BootSector);
if (!NT_SUCCESS(Status))
{
DPRINT("VfatWriteFsInfo() failed with status 0x%.08x\n", Status);
NtClose(FileHandle);
return Status;
}
/* Write first FAT copy */
Status = VfatWriteFAT(FileHandle,
0,
&BootSector);
if (!NT_SUCCESS(Status))
{
DPRINT("VfatWriteFAT() failed with status 0x%.08x\n", Status);
NtClose(FileHandle);
return Status;
}
/* Write second FAT copy */
Status = VfatWriteFAT(FileHandle,
BootSector.FATSectors32,
&BootSector);
if (!NT_SUCCESS(Status))
{
DPRINT("VfatWriteFAT() failed with status 0x%.08x.\n", Status);
NtClose(FileHandle);
return Status;
}
Status = VfatWriteRootDirectory(FileHandle,
&BootSector);
if (!NT_SUCCESS(Status))
{
DPRINT("VfatWriteRootDirectory() failed with status 0x%.08x\n", Status);
NtClose(FileHandle);
return Status;
}
NtClose(FileHandle);
DPRINT("VfatFormat() done. Status 0x%.08x\n", Status);
return Status;
}

View file

@ -0,0 +1,57 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS VFAT filesystem library
* FILE: vfatlib.h
*/
#define NDEBUG
#include <debug.h>
#define NTOS_MODE_USER
#include <ntos.h>
#include <fslib/vfatlib.h>
#define SECTORSIZE 512
typedef struct _FAT32_BOOT_SECTOR
{
unsigned char magic0; // 0
unsigned char res0; // 1
unsigned char magic1; // 2
unsigned char OEMName[8]; // 3
unsigned short BytesPerSector; // 11
unsigned char SectorsPerCluster; // 13
unsigned short ReservedSectors; // 14
unsigned char FATCount; // 16
unsigned short RootEntries; // 17
unsigned short Sectors; // 19
unsigned char Media; // 21
unsigned short FATSectors; // 22
unsigned short SectorsPerTrack; // 24
unsigned short Heads; // 22
unsigned long HiddenSectors; // 24
unsigned long SectorsHuge; // 28
unsigned long FATSectors32; // 36
unsigned short ExtFlag; // 40
unsigned short FSVersion; // 42
unsigned long RootCluster; // 44
unsigned short FSInfoSector; // 48
unsigned short BootBackup; // 50
unsigned char Res3[12]; // 52
unsigned char Drive; // 64
unsigned char Res4; // 65
unsigned char ExtBootSignature; // 66
unsigned long VolumeID; // 67
unsigned char VolumeLabel[11]; // 71
unsigned char SysType[8]; // 82
unsigned char Res2[418]; // 90
unsigned long Signature1; // 508
} __attribute__((packed)) FAT32_BOOT_SECTOR, *PFAT32_BOOT_SECTOR;
typedef struct _FAT32_FSINFO
{
unsigned int LeadSig; // 0
unsigned char Res1[480]; // 4
unsigned int StrucSig; // 484
unsigned int FreeCount; // 488
unsigned int NextFree; // 492
unsigned int Res2; // 496
} __attribute__((packed)) FAT32_FSINFO, *PFAT32_FSINFO;

View file

@ -828,8 +828,8 @@ CHECKPOINT1;
87); /* FAT32 BPB length */
/* Disable the backup boot sector */
NewBootSector[0x32] = 0xFF;
NewBootSector[0x33] = 0xFF;
NewBootSector[0x32] = 0x00;
NewBootSector[0x33] = 0x00;
/* Free the original boot sector */
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
@ -1358,7 +1358,7 @@ InstallFat32BootCodeToDisk(PWSTR SrcPath,
87); /* FAT32 BPB length */
/* Get the location of the backup boot sector */
BackupBootSector = (OrigBootSector[0x33] << 8) + OrigBootSector[0x33];
BackupBootSector = (OrigBootSector[0x33] << 8) + OrigBootSector[0x32];
/* Free the original boot sector */
RtlFreeHeap(ProcessHeap, 0, OrigBootSector);
@ -1406,7 +1406,7 @@ InstallFat32BootCodeToDisk(PWSTR SrcPath,
}
/* Write backup boot sector */
if (BackupBootSector != 0xFFFF)
if ((BackupBootSector != 0x0000) && (BackupBootSector != 0xFFFF))
{
FileOffset.QuadPart = (ULONGLONG)((ULONG)BackupBootSector * SECTORSIZE);
Status = NtWriteFile(FileHandle,

View file

@ -0,0 +1,57 @@
/*
* ReactOS kernel
* Copyright (C) 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: format.c,v 1.1 2003/04/28 19:44:13 chorns Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/format.c
* PURPOSE: Filesystem format support functions
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <ntdll/rtl.h>
#define NDEBUG
#include <debug.h>
#include <fslib/vfatlib.h>
/* FUNCTIONS ****************************************************************/
NTSTATUS
FormatPartition(PUNICODE_STRING DriveRoot)
{
NTSTATUS Status;
VfatInitialize();
Status = VfatFormat(DriveRoot,
0, // MediaFlag
NULL, // Label
TRUE, // QuickFormat
0, // ClusterSize
NULL); // Callback
DPRINT("VfatFormat() status 0x%.08x\n", Status);
VfatCleanup();
return Status;
}
/* EOF */

View file

@ -0,0 +1,35 @@
/*
* ReactOS kernel
* Copyright (C) 2003 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: format.h,v 1.1 2003/04/28 19:44:13 chorns Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/format.h
* PURPOSE: Filesystem format support functions
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
#ifndef __FORMAT_H__
#define __FORMAT_H__
NTSTATUS
FormatPartition(PUNICODE_STRING DriveRoot);
#endif /* __FILESUP_H__ */
/* EOF */

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.10 2003/04/05 09:37:44 chorns Exp $
# $Id: makefile,v 1.11 2003/04/28 19:44:13 chorns Exp $
PATH_TO_TOP = ../../..
@ -12,12 +12,15 @@ TARGET_APPTYPE = native
TARGET_NAME = usetup
TARGET_SDKLIBS = vfatlib.a ntdll.a
TARGET_INSTALLDIR = system32
TARGET_CFLAGS = -D__NTAPP__
TARGET_OBJECTS = $(TARGET_NAME).o bootsup.o console.o drivesup.o filequeue.o \
filesup.o infcache.o inicache.o partlist.o progress.o registry.o
filesup.o format.o infcache.o inicache.o partlist.o progress.o \
registry.o
include $(PATH_TO_TOP)/rules.mak

View file

@ -16,12 +16,13 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: partlist.c,v 1.8 2003/04/18 14:00:17 chorns Exp $
/* $Id: partlist.c,v 1.9 2003/04/28 19:44:13 chorns Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/partlist.c
* PURPOSE: Partition list functions
* PROGRAMMER: Eric Kohl
* Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
#include <ddk/ntddk.h>
@ -89,6 +90,7 @@ AddPartitionList(ULONG DiskNumber,
PartEntry->PartSize = DiskEntry->DiskSize - PartEntry->StartingOffset;
PartEntry->Used = FALSE;
PartEntry->HidePartEntry = FALSE;
PartEntry->PartNumber = 1;
}
else
{
@ -111,6 +113,7 @@ AddPartitionList(ULONG DiskNumber,
{
DiskEntry->PartArray[LastUnusedEntry].StartingOffset = LastStartingOffset + LastPartitionSize;
DiskEntry->PartArray[LastUnusedEntry].PartSize = LastUnusedPartitionSize;
DiskEntry->PartArray[LastUnusedEntry].PartNumber = LastUnusedEntry + 1; /* FIXME: Is this always correct? */
}
LastStartingOffset = LayoutBuffer->PartitionEntry[i].StartingOffset.QuadPart;
LastPartitionSize = LayoutBuffer->PartitionEntry[i].PartitionLength.QuadPart;
@ -156,6 +159,7 @@ AddPartitionList(ULONG DiskNumber,
{
DiskEntry->PartArray[LastUnusedEntry].StartingOffset = LastStartingOffset + LastPartitionSize;
DiskEntry->PartArray[LastUnusedEntry].PartSize = LastUnusedPartitionSize;
DiskEntry->PartArray[LastUnusedEntry].PartNumber = LastUnusedEntry + 1; /* FIXME: Is this always correct? */
}
}
}
@ -1093,6 +1097,8 @@ GetSelectedPartition(PPARTLIST List,
}
/* Copy partition-specific data */
Data->CreatePartition = FALSE;
Data->NewPartSize = 0;
Data->PartSize = PartEntry->PartSize;
Data->PartNumber = PartEntry->PartNumber;
Data->PartType = PartEntry->PartType;
@ -1189,7 +1195,7 @@ CreateSelectedPartition(PPARTLIST List,
DiskEntry = &List->DiskArray[List->CurrentDisk];
PartEntry = &DiskEntry->PartArray[List->CurrentPartition];
PartEntry->PartType = PartType;
PartEntryNumber = PartEntry->PartNumber;
PartEntryNumber = List->CurrentPartition;
DPRINT("NewPartSize %d (%d MB)\n", NewPartSize, NewPartSize / (1024 * 1024));
DPRINT("PartEntry->StartingOffset %d\n", PartEntry->StartingOffset);
@ -1278,4 +1284,112 @@ CreateSelectedPartition(PPARTLIST List,
return TRUE;
}
BOOL
DeleteSelectedPartition(PPARTLIST List)
{
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry;
ULONG PartEntryNumber;
OBJECT_ATTRIBUTES ObjectAttributes;
DRIVE_LAYOUT_INFORMATION *LayoutBuffer;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
WCHAR Buffer[MAX_PATH];
UNICODE_STRING Name;
HANDLE FileHandle;
LARGE_INTEGER li;
DiskEntry = &List->DiskArray[List->CurrentDisk];
PartEntry = &DiskEntry->PartArray[List->CurrentPartition];
PartEntry->PartType = PARTITION_ENTRY_UNUSED;
PartEntryNumber = List->CurrentPartition;
DPRINT1("DeleteSelectedPartition(PartEntryNumber = %d)\n", PartEntryNumber);
DPRINT1("PartEntry->StartingOffset %d\n", PartEntry->StartingOffset);
DPRINT1("PartEntry->PartSize %d\n", PartEntry->PartSize);
DPRINT1("PartEntry->PartNumber %d\n", PartEntry->PartNumber);
DPRINT1("PartEntry->PartType 0x%x\n", PartEntry->PartType);
DPRINT1("PartEntry->FileSystemName %s\n", PartEntry->FileSystemName);
swprintf(Buffer,
L"\\Device\\Harddisk%d\\Partition0",
DiskEntry->DiskNumber);
RtlInitUnicodeString(&Name, Buffer);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
0,
NULL,
NULL);
Status = NtOpenFile(&FileHandle,
0x10001,
&ObjectAttributes,
&Iosb,
1,
FILE_SYNCHRONOUS_IO_NONALERT);
if (NT_SUCCESS(Status))
{
LayoutBuffer = (DRIVE_LAYOUT_INFORMATION*)RtlAllocateHeap(ProcessHeap, 0, 8192);
Status = NtDeviceIoControlFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_DISK_GET_DRIVE_LAYOUT,
NULL,
0,
LayoutBuffer,
8192);
if (!NT_SUCCESS(Status))
{
DPRINT("IOCTL_DISK_GET_DRIVE_LAYOUT failed() 0x%.08x\n", Status);
NtClose(FileHandle);
RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
return FALSE;
}
li.QuadPart = 0;
LayoutBuffer->PartitionEntry[PartEntryNumber].StartingOffset = li;
li.QuadPart = 0;
LayoutBuffer->PartitionEntry[PartEntryNumber].PartitionLength = li;
LayoutBuffer->PartitionEntry[PartEntryNumber].HiddenSectors = 0;
LayoutBuffer->PartitionEntry[PartEntryNumber].PartitionType = 0;
LayoutBuffer->PartitionEntry[PartEntryNumber].RecognizedPartition = FALSE;
LayoutBuffer->PartitionEntry[PartEntryNumber].RewritePartition = TRUE;
Status = NtDeviceIoControlFile(FileHandle,
NULL,
NULL,
NULL,
&Iosb,
IOCTL_DISK_SET_DRIVE_LAYOUT,
LayoutBuffer,
8192,
NULL,
0);
if (!NT_SUCCESS(Status))
{
DPRINT("IOCTL_DISK_SET_DRIVE_LAYOUT failed() 0x%.08x\n", Status);
NtClose(FileHandle);
RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
return FALSE;
}
}
else
{
DPRINT("NtOpenFile failed() 0x%.08x\n", Status);
NtClose(FileHandle);
RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
return FALSE;
}
NtClose(FileHandle);
RtlFreeHeap(ProcessHeap, 0, LayoutBuffer);
return TRUE;
}
/* EOF */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: partlist.h,v 1.9 2003/04/18 14:00:17 chorns Exp $
/* $Id: partlist.h,v 1.10 2003/04/28 19:44:13 chorns Exp $
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS text-mode setup
* FILE: subsys/system/usetup/partlist.h
@ -35,6 +35,7 @@ typedef struct _PARTDATA
USHORT Bus;
USHORT Id;
BOOLEAN CreatePartition;
ULONGLONG PartSize;
ULONGLONG NewPartSize;
ULONG PartNumber;
@ -145,6 +146,9 @@ CreateSelectedPartition(PPARTLIST List,
ULONG PartType,
ULONGLONG NewPartSize);
BOOL
DeleteSelectedPartition(PPARTLIST List);
#endif /* __PARTLIST_H__ */
/* EOF */

View file

@ -22,6 +22,7 @@
* FILE: subsys/system/usetup/usetup.c
* PURPOSE: Text-mode setup
* PROGRAMMER: Eric Kohl
* Casper S. Hornstrup (chorns@users.sourceforge.net)
*/
#include <ddk/ntddk.h>
@ -39,6 +40,7 @@
#include "progress.h"
#include "bootsup.h"
#include "registry.h"
#include "format.h"
#define NDEBUG
#include <debug.h>
@ -623,6 +625,43 @@ InstallIntroPage(PINPUT_RECORD Ir)
}
/*
* Confirm delete partition
* RETURNS
* TRUE: Delete currently selected partition.
* FALSE: Don't delete currently selected partition.
*/
static BOOL
ConfirmDeletePartition(PINPUT_RECORD Ir)
{
BOOL Result = FALSE;
PopupError("Are you sure you want to delete this partition?\n"
"\n"
" * Press ENTER to delete the partition.\n"
" * Press ESC to NOT delete the partition.",
"ESC = Cancel ENTER = Delete partition");
while(TRUE)
{
ConInKey(Ir);
if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) /* ESC */
{
Result = FALSE;
break;
}
else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_RETURN) /* ENTER */
{
Result = TRUE;
break;
}
}
return(Result);
}
static PAGE_NUMBER
SelectPartitionPage(PINPUT_RECORD Ir)
{
@ -735,6 +774,16 @@ SelectPartitionPage(PINPUT_RECORD Ir)
#ifdef ENABLE_FORMAT
/* Don't destroy the parition list here */;
return(CREATE_PARTITION_PAGE);
#endif
}
else if (Ir->Event.KeyEvent.wVirtualKeyCode == VK_D) /* D */
{
#ifdef ENABLE_FORMAT
if (ConfirmDeletePartition(Ir) == TRUE)
{
(BOOLEAN) DeleteSelectedPartition(CurrentPartitionList);
}
return(SELECT_PARTITION_PAGE);
#endif
}
@ -998,6 +1047,7 @@ CreatePartitionPage(PINPUT_RECORD Ir)
&PartData);
if (PartDataValid)
{
PartData.CreatePartition = TRUE;
PartData.NewPartSize = PartSize;
ActivePartitionValid = GetActiveBootPartition(PartList,
@ -1060,7 +1110,7 @@ CreateFileSystemList(SHORT Left,
List->Left = Left;
List->Top = Top;
#if ENABLE_FORMAT
#ifdef ENABLE_FORMAT
List->FileSystemCount = 1;
#else
List->FileSystemCount = 0;
@ -1308,7 +1358,7 @@ SelectFileSystemPage(PINPUT_RECORD Ir)
static ULONG
FormatPartitionPage(PINPUT_RECORD Ir)
{
BOOLEAN CreatePartition;
NTSTATUS Status;
ULONG PartType;
BOOLEAN Valid;
@ -1335,30 +1385,23 @@ FormatPartitionPage(PINPUT_RECORD Ir)
{
SetStatusText(" Please wait ...");
CreatePartition = FALSE;
switch (CurrentFileSystemList->CurrentFileSystem)
{
#ifdef ENABLE_FORMAT
case FsFat:
PartType = PARTITION_FAT32_XINT13;
CreatePartition = TRUE;
break;
#endif
case FsKeep:
CreatePartition = FALSE;
break;
default:
return QUIT_PAGE;
}
if (CreatePartition)
if (PartData.CreatePartition)
{
Valid = CreateSelectedPartition(CurrentPartitionList, PartType, PartData.NewPartSize);
if (Valid)
{
return(INSTALL_DIRECTORY_PAGE);
}
else
if (!Valid)
{
DPRINT("CreateSelectedPartition() failed\n");
/* FIXME: show an error dialog */
@ -1370,6 +1413,13 @@ FormatPartitionPage(PINPUT_RECORD Ir)
{
#ifdef ENABLE_FORMAT
case FsFat:
Status = FormatPartition(&DestinationRootPath);
if (!NT_SUCCESS(Status))
{
DPRINT1("FormatPartition() failed with status 0x%.08x\n", Status);
/* FIXME: show an error dialog */
return(QUIT_PAGE);
}
break;
#endif
case FsKeep:
@ -1377,6 +1427,7 @@ FormatPartitionPage(PINPUT_RECORD Ir)
default:
return QUIT_PAGE;
}
return(INSTALL_DIRECTORY_PAGE);
}
}
@ -1560,7 +1611,6 @@ PrepareCopyPage(PINPUT_RECORD Ir)
// SetStatusText(" Please wait...");
/*
* Build the file copy list
*/