Author: ekohl
Date: Mon Jul 20 19:17:06 2015
New Revision: 68473
URL:
http://svn.reactos.org/svn/reactos?rev=68473&view=rev
Log:
[DISKPART]
- Use the partition list code from usetup. Scan all harddisks at startup and keep the list
alive as long as diskpart is running.
- Use the partiton list in the 'select disk' and 'list disk' commands.
- Implement the 'list disk' and 'list partition' commmands.
- Add required strings.
Added:
trunk/reactos/base/system/diskpart/partlist.c (with props)
Modified:
trunk/reactos/base/system/diskpart/CMakeLists.txt
trunk/reactos/base/system/diskpart/diskpart.c
trunk/reactos/base/system/diskpart/diskpart.h
trunk/reactos/base/system/diskpart/lang/en-US.rc
trunk/reactos/base/system/diskpart/lang/ro-RO.rc
trunk/reactos/base/system/diskpart/lang/ru-RU.rc
trunk/reactos/base/system/diskpart/lang/sq-AL.rc
trunk/reactos/base/system/diskpart/lang/tr-TR.rc
trunk/reactos/base/system/diskpart/list.c
trunk/reactos/base/system/diskpart/resource.h
trunk/reactos/base/system/diskpart/select.c
Modified: trunk/reactos/base/system/diskpart/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/diskpart/CMake…
==============================================================================
--- trunk/reactos/base/system/diskpart/CMakeLists.txt [iso-8859-1] (original)
+++ trunk/reactos/base/system/diskpart/CMakeLists.txt [iso-8859-1] Mon Jul 20 19:17:06
2015
@@ -28,6 +28,7 @@
merge.c
offline.c
online.c
+ partlist.c
recover.c
remove.c
repair.c
Modified: trunk/reactos/base/system/diskpart/diskpart.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/diskpart/diskp…
==============================================================================
--- trunk/reactos/base/system/diskpart/diskpart.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/diskpart/diskpart.c [iso-8859-1] Mon Jul 20 19:17:06 2015
@@ -17,6 +17,7 @@
#include <winuser.h>
/* FUNCTIONS ******************************************************************/
+
VOID
PrintResourceString(INT resID, ...)
{
@@ -95,17 +96,20 @@
LPCWSTR tmpBuffer = NULL;
WCHAR appTitle[50];
int index, timeout;
+ int result = EXIT_SUCCESS;
/* Sets the title of the program so the user will have an easier time
determining the current program, especially if diskpart is running a
script */
LoadStringW(GetModuleHandle(NULL), IDS_APP_HEADER, (LPWSTR)appTitle, 50);
SetConsoleTitleW(appTitle);
-
+
/* Sets the timeout value to 0 just in case the user doesn't
specify a value */
timeout = 0;
+ CreatePartitionList();
+
/* If there are no command arguments, then go straight to the interpreter */
if (argc < 2)
{
@@ -127,7 +131,8 @@
{
/* If there is no flag, then return an error */
PrintResourceString(IDS_ERROR_MSG_BAD_ARG, argv[index]);
- return EXIT_FAILURE;
+ result = EXIT_FAILURE;
+ goto done;
}
/* Checks for the /? flag first since the program
@@ -135,7 +140,8 @@
if (_wcsicmp(tmpBuffer, L"?") == 0)
{
PrintResourceString(IDS_APP_USAGE);
- return EXIT_SUCCESS;
+ result = EXIT_SUCCESS;
+ goto done;
}
/* Checks for the script flag */
else if (_wcsicmp(tmpBuffer, L"s") == 0)
@@ -164,7 +170,8 @@
{
/* Assume that the flag doesn't exist. */
PrintResourceString(IDS_ERROR_MSG_BAD_ARG, tmpBuffer);
- return EXIT_FAILURE;
+ result = EXIT_FAILURE;
+ goto done;
}
}
@@ -180,18 +187,25 @@
Sleep(timeout * 1000);
if (RunScript(script) == FALSE)
- return EXIT_FAILURE;
+ {
+ result = EXIT_FAILURE;
+ goto done;
+ }
}
else
{
/* Exit failure since the user wanted to run a script */
PrintResourceString(IDS_ERROR_MSG_NO_SCRIPT, script);
- return EXIT_FAILURE;
+ result = EXIT_FAILURE;
+ goto done;
}
}
/* Let the user know the program is exiting */
PrintResourceString(IDS_APP_LEAVING);
- return EXIT_SUCCESS;
-}
+done:
+ DestroyPartitionList();
+
+ return result;
+}
Modified: trunk/reactos/base/system/diskpart/diskpart.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/diskpart/diskp…
==============================================================================
--- trunk/reactos/base/system/diskpart/diskpart.h [iso-8859-1] (original)
+++ trunk/reactos/base/system/diskpart/diskpart.h [iso-8859-1] Mon Jul 20 19:17:06 2015
@@ -17,6 +17,11 @@
#define WIN32_NO_STATUS
#include <windef.h>
#include <winbase.h>
+#include <winreg.h>
+#include <winuser.h>
+#include <wincon.h>
+
+/*
#define NTOS_MODE_USER
#include <ndk/exfuncs.h>
#include <ndk/iofuncs.h>
@@ -24,6 +29,19 @@
#include <ndk/psfuncs.h>
#include <ndk/rtlfuncs.h>
#include <ndk/umfuncs.h>
+*/
+
+#define NTOS_MODE_USER
+#include <ndk/cmfuncs.h>
+#include <ndk/exfuncs.h>
+#include <ndk/iofuncs.h>
+#include <ndk/kefuncs.h>
+#include <ndk/mmfuncs.h>
+#include <ndk/obfuncs.h>
+#include <ndk/psfuncs.h>
+#include <ndk/rtlfuncs.h>
+#include <ndk/setypes.h>
+#include <ndk/umfuncs.h>
#include "resource.h"
@@ -50,10 +68,115 @@
#define MAX_STRING_SIZE 1024
#define MAX_ARGS_COUNT 256
+
+typedef enum _FORMATSTATE
+{
+ Unformatted,
+ UnformattedOrDamaged,
+ UnknownFormat,
+ Preformatted,
+ Formatted
+} FORMATSTATE, *PFORMATSTATE;
+
+typedef struct _PARTENTRY
+{
+ LIST_ENTRY ListEntry;
+
+ struct _DISKENTRY *DiskEntry;
+
+ ULARGE_INTEGER StartSector;
+ ULARGE_INTEGER SectorCount;
+
+ BOOLEAN BootIndicator;
+ UCHAR PartitionType;
+ ULONG HiddenSectors;
+ ULONG PartitionNumber;
+ ULONG PartitionIndex;
+
+ CHAR DriveLetter;
+ CHAR VolumeLabel[17];
+ CHAR FileSystemName[9];
+
+ BOOLEAN LogicalPartition;
+
+ /* Partition is partitioned disk space */
+ BOOLEAN IsPartitioned;
+
+ /* Partition is new. Table does not exist on disk yet */
+ BOOLEAN New;
+
+ /* Partition was created automatically. */
+ BOOLEAN AutoCreate;
+
+ FORMATSTATE FormatState;
+
+ /* Partition must be checked */
+ BOOLEAN NeedsCheck;
+
+ struct _FILE_SYSTEM_ITEM *FileSystem;
+} PARTENTRY, *PPARTENTRY;
+
+
+typedef struct _BIOSDISKENTRY
+{
+ LIST_ENTRY ListEntry;
+ ULONG DiskNumber;
+ ULONG Signature;
+ ULONG Checksum;
+ BOOLEAN Recognized;
+ CM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
+ CM_INT13_DRIVE_PARAMETER Int13DiskData;
+} BIOSDISKENTRY, *PBIOSDISKENTRY;
+
+
+typedef struct _DISKENTRY
+{
+ LIST_ENTRY ListEntry;
+
+ ULONGLONG Cylinders;
+ ULONG TracksPerCylinder;
+ ULONG SectorsPerTrack;
+ ULONG BytesPerSector;
+
+ ULARGE_INTEGER SectorCount;
+ ULONG SectorAlignment;
+ ULONG CylinderAlignment;
+
+ BOOLEAN BiosFound;
+ ULONG BiosDiskNumber;
+// ULONG Signature;
+// ULONG Checksum;
+
+ ULONG DiskNumber;
+ USHORT Port;
+ USHORT Bus;
+ USHORT Id;
+
+ /* Has the partition list been modified? */
+ BOOLEAN Dirty;
+
+ BOOLEAN NewDisk;
+ BOOLEAN NoMbr; /* MBR is absent */
+
+ UNICODE_STRING DriverName;
+
+ PDRIVE_LAYOUT_INFORMATION LayoutBuffer;
+
+ PPARTENTRY ExtendedPartition;
+
+ LIST_ENTRY PrimaryPartListHead;
+ LIST_ENTRY LogicalPartListHead;
+
+} DISKENTRY, *PDISKENTRY;
+
+
/* GLOBAL VARIABLES ***********************************************************/
-ULONG CurrentDisk;
-ULONG CurrentPartition;
+extern LIST_ENTRY DiskListHead;
+extern LIST_ENTRY BiosDiskListHead;
+
+extern PDISKENTRY CurrentDisk;
+extern PPARTENTRY CurrentPartition;
/* PROTOTYPES *****************************************************************/
@@ -144,6 +267,13 @@
/* online.c */
BOOL online_main(INT argc, LPWSTR *argv);
+/* partlist.c */
+NTSTATUS
+CreatePartitionList(VOID);
+
+VOID
+DestroyPartitionList(VOID);
+
/* recover.c */
BOOL recover_main(INT argc, LPWSTR *argv);
Modified: trunk/reactos/base/system/diskpart/lang/en-US.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/diskpart/lang/…
==============================================================================
--- trunk/reactos/base/system/diskpart/lang/en-US.rc [iso-8859-1] (original)
+++ trunk/reactos/base/system/diskpart/lang/en-US.rc [iso-8859-1] Mon Jul 20 19:17:06
2015
@@ -40,6 +40,10 @@
IDS_LIST_DISK_HEAD "\n Disk ### Status Size Free Dyn
Gpt\n"
IDS_LIST_DISK_LINE " -------- ---------- ------- ------- --- ---\n"
IDS_LIST_DISK_FORMAT "%c %7lu %-10s %4I64u %-2s %4I64u %-2s %1s
%1s\n"
+ IDS_LIST_PARTITION_HEAD "\n Partition Type Size
Offset\n"
+ IDS_LIST_PARTITION_LINE " ------------- ---------------- -------
-------\n"
+ IDS_LIST_PARTITION_FORMAT "%c Partition %2lu %-16s %4I64u %-2s %4I64u
%-2s\n"
+ IDS_LIST_PARTITION_NO_DISK "\nThere is no disk for listing partitions.\nPlease
select a disk and try again.\n\n"
IDS_LIST_VOLUME_HEAD " Volume ### Ltr Label\n"
END
@@ -48,10 +52,13 @@
BEGIN
IDS_SELECT_NO_DISK "\nThere is no disk currently selected.\nPlease select a disk
and try again.\n\n"
IDS_SELECT_DISK "\nDisk %lu is now the selected disk.\n\n"
+ IDS_SELECT_DISK_INVALID "\nInvalid disk.\n\n"
+ IDS_SELECT_NO_PARTITION "\nThere is no partition currently selected.\nPlease
select a disk and try again.\n\n"
+ IDS_SELECT_PARTITION "\nPartition %lu is now the selected partition.\n\n"
+ IDS_SELECT_PARTITION_NO_DISK "\nThere is no disk for selecting a
partition.\nPlease select a disk and try again.\n\n"
+ IDS_SELECT_PARTITION_INVALID "\nInvalid partition.\n\n"
IDS_SELECT_NO_VOLUME "\nThere is no volume currently selected.\nPlease select a
disk and try again.\n\n"
IDS_SELECT_VOLUME "\nVolume %lu is now the selected volume.\n\n"
- IDS_SELECT_NO_PARTITION "\nThere is no partition currently selected.\nPlease
select a disk and try again.\n\n"
- IDS_SELECT_PARTITION "\nPartition %lu is now the selected partition.\n\n"
END
/* Disk Status */
@@ -122,7 +129,6 @@
IDS_ERROR_MSG_NO_SCRIPT "Error opening script: %s\n"
IDS_ERROR_MSG_BAD_ARG "Error processing argument: %s\n"
IDS_ERROR_INVALID_ARGS "Invalid arguments\n"
- IDS_ERROR_INVALID_DISK "Invalid disk\n"
END
/* Active help descriptions */
Modified: trunk/reactos/base/system/diskpart/lang/ro-RO.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/diskpart/lang/…
==============================================================================
--- trunk/reactos/base/system/diskpart/lang/ro-RO.rc [iso-8859-1] (original)
+++ trunk/reactos/base/system/diskpart/lang/ro-RO.rc [iso-8859-1] Mon Jul 20 19:17:06
2015
@@ -41,6 +41,10 @@
IDS_LIST_DISK_HEAD "\n Disc ### Stare Dimensiune Liber Dyn
Gpt\n"
IDS_LIST_DISK_LINE " -------- ---------- ---------- ------- ---
---\n"
IDS_LIST_DISK_FORMAT "%c %7lu %-10s %4I64u %-2s %4I64u %-2s %1s
%1s\n"
+ IDS_LIST_PARTITION_HEAD "\n Partition Type Size
Offset\n"
+ IDS_LIST_PARTITION_LINE " ------------- ---------------- -------
-------\n"
+ IDS_LIST_PARTITION_FORMAT "%c Partition %2lu %-16s %4I64u %-2s %4I64u
%-2s\n"
+ IDS_LIST_PARTITION_NO_DISK "\nThere is no disk for listing partitions.\nPlease
select a disk and try again.\n\n"
IDS_LIST_VOLUME_HEAD "Volum ###\tLtr\tEtichetÄ\n"
END
@@ -49,10 +53,13 @@
BEGIN
IDS_SELECT_NO_DISK "\nThere is no disk currently selected.\nPlease select a disk
and try again.\n\n"
IDS_SELECT_DISK "\nDisk %lu is now the selected disk.\n\n"
+ IDS_SELECT_DISK_INVALID "\nInvalid disk.\n\n"
+ IDS_SELECT_NO_PARTITION "\nThere is no partition currently selected.\nPlease
select a disk and try again.\n\n"
+ IDS_SELECT_PARTITION "\nPartition %lu is now the selected partition.\n\n"
+ IDS_SELECT_PARTITION_NO_DISK "\nThere is no disk for selecting a
partition.\nPlease select a disk and try again.\n\n"
+ IDS_SELECT_PARTITION_INVALID "\nInvalid partition.\n\n"
IDS_SELECT_NO_VOLUME "\nThere is no volume currently selected.\nPlease select a
disk and try again.\n\n"
IDS_SELECT_VOLUME "\nVolume %lu is now the selected volume.\n\n"
- IDS_SELECT_NO_PARTITION "\nThere is no partition currently selected.\nPlease
select a disk and try again.\n\n"
- IDS_SELECT_PARTITION "\nPartition %lu is now the selected partition.\n\n"
END
/* Disk Status */
@@ -123,7 +130,6 @@
IDS_ERROR_MSG_NO_SCRIPT "Eroare la deschiderea fiÈierului script: %s\n"
IDS_ERROR_MSG_BAD_ARG "Eroare la prelucrarea argumentului: %s\n"
IDS_ERROR_INVALID_ARGS "Invalid arguments\n"
- IDS_ERROR_INVALID_DISK "Invalid disk\n"
END
/* Active help descriptions */
Modified: trunk/reactos/base/system/diskpart/lang/ru-RU.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/diskpart/lang/…
==============================================================================
--- trunk/reactos/base/system/diskpart/lang/ru-RU.rc [iso-8859-1] (original)
+++ trunk/reactos/base/system/diskpart/lang/ru-RU.rc [iso-8859-1] Mon Jul 20 19:17:06
2015
@@ -42,6 +42,10 @@
IDS_LIST_DISK_HEAD "\n ÐиÑк ### СоÑÑоÑние РазмеÑ
Свободно Ðин GPT\n"
IDS_LIST_DISK_LINE " -------- ---------- ------- -------- --- ---\n"
IDS_LIST_DISK_FORMAT "%c %7lu %-10s %4I64u %-2s %4I64u %-2s %1s
%1s\n"
+ IDS_LIST_PARTITION_HEAD "\n Partition Type Size
Offset\n"
+ IDS_LIST_PARTITION_LINE " ------------- ---------------- -------
-------\n"
+ IDS_LIST_PARTITION_FORMAT "%c Partition %2lu %-16s %4I64u %-2s %4I64u
%-2s\n"
+ IDS_LIST_PARTITION_NO_DISK "\nThere is no disk for listing partitions.\nPlease
select a disk and try again.\n\n"
IDS_LIST_VOLUME_HEAD "Том ###\tÐмÑ\tÐеÑка\n"
END
@@ -50,10 +54,13 @@
BEGIN
IDS_SELECT_NO_DISK "\nThere is no disk currently selected.\nPlease select a disk
and try again.\n\n"
IDS_SELECT_DISK "\nDisk %lu is now the selected disk.\n\n"
+ IDS_SELECT_DISK_INVALID "\nInvalid disk.\n\n"
+ IDS_SELECT_NO_PARTITION "\nThere is no partition currently selected.\nPlease
select a disk and try again.\n\n"
+ IDS_SELECT_PARTITION "\nPartition %lu is now the selected partition.\n\n"
+ IDS_SELECT_PARTITION_NO_DISK "\nThere is no disk for selecting a
partition.\nPlease select a disk and try again.\n\n"
+ IDS_SELECT_PARTITION_INVALID "\nInvalid partition.\n\n"
IDS_SELECT_NO_VOLUME "\nThere is no volume currently selected.\nPlease select a
disk and try again.\n\n"
IDS_SELECT_VOLUME "\nVolume %lu is now the selected volume.\n\n"
- IDS_SELECT_NO_PARTITION "\nThere is no partition currently selected.\nPlease
select a disk and try again.\n\n"
- IDS_SELECT_PARTITION "\nPartition %lu is now the selected partition.\n\n"
END
/* Disk Status */
@@ -124,7 +131,6 @@
IDS_ERROR_MSG_NO_SCRIPT "ÐÑибка оÑкÑÑÑÐ¸Ñ ÑкÑипÑа:
%s\n"
IDS_ERROR_MSG_BAD_ARG "ÐÑибка обÑабоÑки паÑамеÑÑов:
%s\n"
IDS_ERROR_INVALID_ARGS "Invalid arguments\n"
- IDS_ERROR_INVALID_DISK "Invalid disk\n"
END
/* Active help descriptions */
Modified: trunk/reactos/base/system/diskpart/lang/sq-AL.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/diskpart/lang/…
==============================================================================
--- trunk/reactos/base/system/diskpart/lang/sq-AL.rc [iso-8859-1] (original)
+++ trunk/reactos/base/system/diskpart/lang/sq-AL.rc [iso-8859-1] Mon Jul 20 19:17:06
2015
@@ -44,6 +44,10 @@
IDS_LIST_DISK_HEAD "\n Disk ### Status Size Free Dyn
Gpt\n"
IDS_LIST_DISK_LINE " -------- ---------- ------- ------- --- ---\n"
IDS_LIST_DISK_FORMAT "%c %7lu %-10s %4I64u %-2s %4I64u %-2s %1s
%1s\n"
+ IDS_LIST_PARTITION_HEAD "\n Partition Type Size
Offset\n"
+ IDS_LIST_PARTITION_LINE "%c ------------- ---------------- -------
-------\n"
+ IDS_LIST_PARTITION_FORMAT " Partition %2lu %-16s %4I64u %-2s %4I64u
%-2s\n"
+ IDS_LIST_PARTITION_NO_DISK "\nThere is no disk for listing partitions.\nPlease
select a disk and try again.\n\n"
IDS_LIST_VOLUME_HEAD "Volume ###\tLtr\tLabel\n"
END
@@ -52,10 +56,13 @@
BEGIN
IDS_SELECT_NO_DISK "\nThere is no disk currently selected.\nPlease select a disk
and try again.\n\n"
IDS_SELECT_DISK "\nDisk %lu is now the selected disk.\n\n"
+ IDS_SELECT_DISK_INVALID "\nInvalid disk.\n\n"
+ IDS_SELECT_NO_PARTITION "\nThere is no partition currently selected.\nPlease
select a disk and try again.\n\n"
+ IDS_SELECT_PARTITION "\nPartition %lu is now the selected partition.\n\n"
+ IDS_SELECT_PARTITION_NO_DISK "\nThere is no disk for selecting a
partition.\nPlease select a disk and try again.\n\n"
+ IDS_SELECT_PARTITION_INVALID "\nInvalid partition.\n\n"
IDS_SELECT_NO_VOLUME "\nThere is no volume currently selected.\nPlease select a
disk and try again.\n\n"
IDS_SELECT_VOLUME "\nVolume %lu is now the selected volume.\n\n"
- IDS_SELECT_NO_PARTITION "\nThere is no partition currently selected.\nPlease
select a disk and try again.\n\n"
- IDS_SELECT_PARTITION "\nPartition %lu is now the selected partition.\n\n"
END
/* Disk Status */
@@ -126,7 +133,6 @@
IDS_ERROR_MSG_NO_SCRIPT "Error në hapjen e skriptes: %s\n"
IDS_ERROR_MSG_BAD_ARG "Error argumenti i procesimit: %s\n"
IDS_ERROR_INVALID_ARGS "Invalid arguments\n"
- IDS_ERROR_INVALID_DISK "Invalid disk\n"
END
/* Active help descriptions */
Modified: trunk/reactos/base/system/diskpart/lang/tr-TR.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/diskpart/lang/…
==============================================================================
--- trunk/reactos/base/system/diskpart/lang/tr-TR.rc [iso-8859-1] (original)
+++ trunk/reactos/base/system/diskpart/lang/tr-TR.rc [iso-8859-1] Mon Jul 20 19:17:06
2015
@@ -42,6 +42,10 @@
IDS_LIST_DISK_HEAD "\n Disk ### Durum Boyut BoÅ Dev
Gpt\n"
IDS_LIST_DISK_LINE " -------- ---------- ------- ------- --- ---\n"
IDS_LIST_DISK_FORMAT "%c %7lu %-10s %4I64u %-2s %4I64u %-2s %1s
%1s\n"
+ IDS_LIST_PARTITION_HEAD "\n Partition Type Size
Offset\n"
+ IDS_LIST_PARTITION_LINE " ------------- ---------------- -------
-------\n"
+ IDS_LIST_PARTITION_FORMAT "%c Partition %2lu %-16s %4I64u %-2s %4I64u
%-2s\n"
+ IDS_LIST_PARTITION_NO_DISK "\nThere is no disk for listing partitions.\nPlease
select a disk and try again.\n\n"
IDS_LIST_VOLUME_HEAD "Birim ###\tHarf\tEtiket\n"
END
@@ -50,10 +54,13 @@
BEGIN
IDS_SELECT_NO_DISK "\nThere is no disk currently selected.\nPlease select a disk
and try again.\n\n"
IDS_SELECT_DISK "\nDisk %lu is now the selected disk.\n\n"
+ IDS_SELECT_DISK_INVALID "\nInvalid disk.\n\n"
+ IDS_SELECT_NO_PARTITION "\nThere is no partition currently selected.\nPlease
select a disk and try again.\n\n"
+ IDS_SELECT_PARTITION "\nPartition %lu is now the selected partition.\n\n"
+ IDS_SELECT_PARTITION_NO_DISK "\nThere is no disk for selecting a
partition.\nPlease select a disk and try again.\n\n"
+ IDS_SELECT_PARTITION_INVALID "\nInvalid partition.\n\n"
IDS_SELECT_NO_VOLUME "\nThere is no volume currently selected.\nPlease select a
disk and try again.\n\n"
IDS_SELECT_VOLUME "\nVolume %lu is now the selected volume.\n\n"
- IDS_SELECT_NO_PARTITION "\nThere is no partition currently selected.\nPlease
select a disk and try again.\n\n"
- IDS_SELECT_PARTITION "\nPartition %lu is now the selected partition.\n\n"
END
/* Disk Status */
@@ -124,7 +131,6 @@
IDS_ERROR_MSG_NO_SCRIPT "Betik açmada yanlıÅlık: %s\n"
IDS_ERROR_MSG_BAD_ARG "DeÄiÅtirgen iÅlemede yanlıÅlık: %s\n"
IDS_ERROR_INVALID_ARGS "Invalid arguments\n"
- IDS_ERROR_INVALID_DISK "Invalid disk\n"
END
/* Active help descriptions */
Modified: trunk/reactos/base/system/diskpart/list.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/diskpart/list.…
==============================================================================
--- trunk/reactos/base/system/diskpart/list.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/diskpart/list.c [iso-8859-1] Mon Jul 20 19:17:06 2015
@@ -11,6 +11,8 @@
#define NDEBUG
#include <debug.h>
+/* FUNCTIONS ******************************************************************/
+
static
ULONGLONG
RoundingDivide(
@@ -25,115 +27,54 @@
VOID
ListDisk(VOID)
{
- WCHAR Buffer[MAX_PATH];
- OBJECT_ATTRIBUTES ObjectAttributes;
- SYSTEM_DEVICE_INFORMATION Sdi;
- IO_STATUS_BLOCK Iosb;
- DISK_GEOMETRY DiskGeometry;
- ULONG ReturnSize;
- ULONG DiskNumber;
- UNICODE_STRING Name;
- HANDLE FileHandle;
- NTSTATUS Status;
-
- ULARGE_INTEGER DiskSize;
- ULARGE_INTEGER FreeSize;
+ PLIST_ENTRY Entry;
+ PDISKENTRY DiskEntry;
+ ULONGLONG DiskSize;
+ ULONGLONG FreeSize;
LPWSTR lpSizeUnit;
LPWSTR lpFreeUnit;
-
-
- Status = NtQuerySystemInformation(SystemDeviceInformation,
- &Sdi,
- sizeof(SYSTEM_DEVICE_INFORMATION),
- &ReturnSize);
- if (!NT_SUCCESS(Status))
- {
- return;
- }
/* Header labels */
PrintResourceString(IDS_LIST_DISK_HEAD);
PrintResourceString(IDS_LIST_DISK_LINE);
- for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
- {
- swprintf(Buffer,
- L"\\Device\\Harddisk%d\\Partition0",
- DiskNumber);
- RtlInitUnicodeString(&Name,
- Buffer);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- 0,
- NULL,
- NULL);
-
- Status = NtOpenFile(&FileHandle,
- FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
- &ObjectAttributes,
- &Iosb,
- FILE_SHARE_READ,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (NT_SUCCESS(Status))
- {
- Status = NtDeviceIoControlFile(FileHandle,
- NULL,
- NULL,
- NULL,
- &Iosb,
- IOCTL_DISK_GET_DRIVE_GEOMETRY,
- NULL,
- 0,
- &DiskGeometry,
- sizeof(DISK_GEOMETRY));
- if (NT_SUCCESS(Status))
- {
- DiskSize.QuadPart = DiskGeometry.Cylinders.QuadPart *
- (ULONGLONG)DiskGeometry.TracksPerCylinder *
- (ULONGLONG)DiskGeometry.SectorsPerTrack *
- (ULONGLONG)DiskGeometry.BytesPerSector;
- if (DiskSize.QuadPart >= 10737418240) /* 10 GB */
- {
- DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, 1073741824);
- lpSizeUnit = L"GB";
- }
- else
- {
- DiskSize.QuadPart = RoundingDivide(DiskSize.QuadPart, 1048576);
- if (DiskSize.QuadPart == 0)
- DiskSize.QuadPart = 1;
- lpSizeUnit = L"MB";
- }
-
- /* FIXME */
- FreeSize.QuadPart = 0;
- lpFreeUnit = L"B";
-
- PrintResourceString(IDS_LIST_DISK_FORMAT,
- (CurrentDisk == DiskNumber) ? L'*': '
',
- DiskNumber,
- L"Online",
- DiskSize.QuadPart,
- lpSizeUnit,
- FreeSize.QuadPart,
- lpFreeUnit,
- L" ",
- L" ");
- }
- else
- {
- printf("Status 0x%lx\n", Status);
-
- }
-
- NtClose(FileHandle);
+ Entry = DiskListHead.Flink;
+ while (Entry != &DiskListHead)
+ {
+ DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+
+ DiskSize = DiskEntry->SectorCount.QuadPart *
+ (ULONGLONG)DiskEntry->BytesPerSector;
+
+ if (DiskSize >= 10737418240) /* 10 GB */
+ {
+ DiskSize = RoundingDivide(DiskSize, 1073741824);
+ lpSizeUnit = L"GB";
}
else
{
- printf("Status 0x%lx\n", Status);
-
- }
+ DiskSize = RoundingDivide(DiskSize, 1048576);
+ if (DiskSize == 0)
+ DiskSize = 1;
+ lpSizeUnit = L"MB";
+ }
+
+ /* FIXME */
+ FreeSize = 0;
+ lpFreeUnit = L"B";
+
+ PrintResourceString(IDS_LIST_DISK_FORMAT,
+ (CurrentDisk == DiskEntry) ? L'*': ' ',
+ DiskEntry->DiskNumber,
+ L"Online",
+ DiskSize,
+ lpSizeUnit,
+ FreeSize,
+ lpFreeUnit,
+ L" ",
+ L" ");
+
+ Entry = Entry->Flink;
}
wprintf(L"\n\n");
@@ -143,7 +84,137 @@
VOID
ListPartition(VOID)
{
- printf("List Partition!!\n");
+ PLIST_ENTRY Entry;
+ PPARTENTRY PartEntry;
+ ULONGLONG PartSize;
+ ULONGLONG PartOffset;
+ LPWSTR lpSizeUnit;
+ LPWSTR lpOffsetUnit;
+ ULONG PartNumber = 1;
+
+ if (CurrentDisk == NULL)
+ {
+ PrintResourceString(IDS_LIST_PARTITION_NO_DISK);
+ return;
+ }
+
+ /* Header labels */
+ PrintResourceString(IDS_LIST_PARTITION_HEAD);
+ PrintResourceString(IDS_LIST_PARTITION_LINE);
+
+ Entry = CurrentDisk->PrimaryPartListHead.Flink;
+ while (Entry != &CurrentDisk->PrimaryPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+
+ if (PartEntry->PartitionType != 0)
+ {
+ PartSize = PartEntry->SectorCount.QuadPart *
CurrentDisk->BytesPerSector;
+
+ if (PartSize >= 10737418240) /* 10 GB */
+ {
+ PartSize = RoundingDivide(PartSize, 1073741824);
+ lpSizeUnit = L"GB";
+ }
+ else if (PartSize >= 10485760) /* 10 MB */
+ {
+ PartSize = RoundingDivide(PartSize, 1048576);
+ lpSizeUnit = L"MB";
+ }
+ else
+ {
+ PartSize = RoundingDivide(PartSize, 1024);
+ lpSizeUnit = L"KB";
+ }
+
+ PartOffset = PartEntry->StartSector.QuadPart *
CurrentDisk->BytesPerSector;
+
+ if (PartOffset >= 10737418240) /* 10 GB */
+ {
+ PartOffset = RoundingDivide(PartOffset, 1073741824);
+ lpOffsetUnit = L"GB";
+ }
+ else if (PartOffset >= 10485760) /* 10 MB */
+ {
+ PartOffset = RoundingDivide(PartOffset, 1048576);
+ lpOffsetUnit = L"MB";
+ }
+ else
+ {
+ PartOffset = RoundingDivide(PartOffset, 1024);
+ lpOffsetUnit = L"KB";
+ }
+
+ PrintResourceString(IDS_LIST_PARTITION_FORMAT,
+ (CurrentPartition == PartEntry) ? L'*': '
',
+ PartNumber++,
+ IsContainerPartition(PartEntry->PartitionType) ?
L"Extended" : L"Primary",
+ PartSize,
+ lpSizeUnit,
+ PartOffset,
+ lpOffsetUnit);
+ }
+
+ Entry = Entry->Flink;
+ }
+
+ Entry = CurrentDisk->LogicalPartListHead.Flink;
+ while (Entry != &CurrentDisk->LogicalPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+
+ if (PartEntry->PartitionType != 0)
+ {
+ PartSize = PartEntry->SectorCount.QuadPart *
CurrentDisk->BytesPerSector;
+
+ if (PartSize >= 10737418240) /* 10 GB */
+ {
+ PartSize = RoundingDivide(PartSize, 1073741824);
+ lpSizeUnit = L"GB";
+ }
+ else if (PartSize >= 10485760) /* 10 MB */
+ {
+ PartSize = RoundingDivide(PartSize, 1048576);
+ lpSizeUnit = L"MB";
+ }
+ else
+ {
+ PartSize = RoundingDivide(PartSize, 1024);
+ lpSizeUnit = L"KB";
+ }
+
+ PartOffset = PartEntry->StartSector.QuadPart *
CurrentDisk->BytesPerSector;
+
+ if (PartOffset >= 10737418240) /* 10 GB */
+ {
+ PartOffset = RoundingDivide(PartOffset, 1073741824);
+ lpOffsetUnit = L"GB";
+ }
+ else if (PartOffset >= 10485760) /* 10 MB */
+ {
+ PartOffset = RoundingDivide(PartOffset, 1048576);
+ lpOffsetUnit = L"MB";
+ }
+ else
+ {
+ PartOffset = RoundingDivide(PartOffset, 1024);
+ lpOffsetUnit = L"KB";
+ }
+
+ PrintResourceString(IDS_LIST_PARTITION_FORMAT,
+ (CurrentPartition == PartEntry) ? L'*': '
',
+ PartNumber++,
+ L"Logical",
+ PartSize,
+ lpSizeUnit,
+ PartOffset,
+ lpOffsetUnit);
+ }
+
+ Entry = Entry->Flink;
+ }
+
+ wprintf(L"\n");
}
static
Added: trunk/reactos/base/system/diskpart/partlist.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/diskpart/partl…
==============================================================================
--- trunk/reactos/base/system/diskpart/partlist.c (added)
+++ trunk/reactos/base/system/diskpart/partlist.c [iso-8859-1] Mon Jul 20 19:17:06 2015
@@ -0,0 +1,1186 @@
+/*
+ * PROJECT: ReactOS DiskPart
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: base/system/diskpart/diskpart.c
+ * PURPOSE: Manages all the partitions of the OS in an interactive way
+ * PROGRAMMERS: Eric Kohl
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "diskpart.h"
+
+#include <stdlib.h>
+#include <winbase.h>
+#include <wincon.h>
+#include <winuser.h>
+
+#include <ntddscsi.h>
+
+#define NDEBUG
+#include <debug.h>
+
+#define InsertAscendingList(ListHead, NewEntry, Type, ListEntryField, SortField)\
+{\
+ PLIST_ENTRY current;\
+\
+ current = (ListHead)->Flink;\
+ while (current != (ListHead))\
+ {\
+ if (CONTAINING_RECORD(current, Type, ListEntryField)->SortField >=\
+ (NewEntry)->SortField)\
+ {\
+ break;\
+ }\
+ current = current->Flink;\
+ }\
+\
+ InsertTailList(current, &((NewEntry)->ListEntryField));\
+}
+
+/* We have to define it there, because it is not in the MS DDK */
+#define PARTITION_EXT2 0x83
+
+#define PARTITION_TBL_SIZE 4
+
+#include <pshpack1.h>
+
+typedef struct _PARTITION
+{
+ unsigned char BootFlags; /* bootable? 0=no, 128=yes */
+ unsigned char StartingHead; /* beginning head number */
+ unsigned char StartingSector; /* beginning sector number */
+ unsigned char StartingCylinder; /* 10 bit nmbr, with high 2 bits put in begsect */
+ unsigned char PartitionType; /* Operating System type indicator code */
+ unsigned char EndingHead; /* ending head number */
+ unsigned char EndingSector; /* ending sector number */
+ unsigned char EndingCylinder; /* also a 10 bit nmbr, with same high 2 bit trick
*/
+ unsigned int StartingBlock; /* first sector relative to start of disk */
+ unsigned int SectorCount; /* number of sectors in partition */
+} PARTITION, *PPARTITION;
+
+typedef struct _PARTITION_SECTOR
+{
+ UCHAR BootCode[440]; /* 0x000 */
+ ULONG Signature; /* 0x1B8 */
+ UCHAR Reserved[2]; /* 0x1BC */
+ PARTITION Partition[PARTITION_TBL_SIZE]; /* 0x1BE */
+ USHORT Magic; /* 0x1FE */
+} PARTITION_SECTOR, *PPARTITION_SECTOR;
+
+#include <poppack.h>
+
+
+/* GLOBALS ********************************************************************/
+
+LIST_ENTRY DiskListHead;
+LIST_ENTRY BiosDiskListHead;
+
+PDISKENTRY CurrentDisk = NULL;
+PPARTENTRY CurrentPartition = NULL;
+
+
+/* FUNCTIONS ******************************************************************/
+
+ULONGLONG
+AlignDown(
+ IN ULONGLONG Value,
+ IN ULONG Alignment)
+{
+ ULONGLONG Temp;
+
+ Temp = Value / Alignment;
+
+ return Temp * Alignment;
+}
+
+static
+VOID
+GetDriverName(
+ PDISKENTRY DiskEntry)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[2];
+ WCHAR KeyName[32];
+ NTSTATUS Status;
+
+ RtlInitUnicodeString(&DiskEntry->DriverName,
+ NULL);
+
+ swprintf(KeyName,
+ L"\\Scsi\\Scsi Port %lu",
+ DiskEntry->Port);
+
+ RtlZeroMemory(&QueryTable,
+ sizeof(QueryTable));
+
+ QueryTable[0].Name = L"Driver";
+ QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
+ QueryTable[0].EntryContext = &DiskEntry->DriverName;
+
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_DEVICEMAP,
+ KeyName,
+ QueryTable,
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status);
+ }
+}
+
+static
+NTSTATUS
+NTAPI
+DiskIdentifierQueryRoutine(
+ PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
+ UNICODE_STRING NameU;
+
+ if (ValueType == REG_SZ &&
+ ValueLength == 20 * sizeof(WCHAR))
+ {
+ NameU.Buffer = (PWCHAR)ValueData;
+ NameU.Length = NameU.MaximumLength = 8 * sizeof(WCHAR);
+ RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Checksum);
+
+ NameU.Buffer = (PWCHAR)ValueData + 9;
+ RtlUnicodeStringToInteger(&NameU, 16, &BiosDiskEntry->Signature);
+
+ return STATUS_SUCCESS;
+ }
+
+ return STATUS_UNSUCCESSFUL;
+}
+
+static
+NTSTATUS
+NTAPI
+DiskConfigurationDataQueryRoutine(
+ PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ PBIOSDISKENTRY BiosDiskEntry = (PBIOSDISKENTRY)Context;
+ PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
+ PCM_DISK_GEOMETRY_DEVICE_DATA DiskGeometry;
+ ULONG i;
+
+ if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
+ ValueLength < sizeof(CM_FULL_RESOURCE_DESCRIPTOR))
+ return STATUS_UNSUCCESSFUL;
+
+ FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
+
+ /* Hm. Version and Revision are not set on Microsoft Windows XP... */
+#if 0
+ if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
+ FullResourceDescriptor->PartialResourceList.Revision != 1)
+ return STATUS_UNSUCCESSFUL;
+#endif
+
+ for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
+ {
+ if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type !=
CmResourceTypeDeviceSpecific ||
+
FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize
!= sizeof(CM_DISK_GEOMETRY_DEVICE_DATA))
+ continue;
+
+ DiskGeometry =
(PCM_DISK_GEOMETRY_DEVICE_DATA)&FullResourceDescriptor->PartialResourceList.PartialDescriptors[i
+ 1];
+ BiosDiskEntry->DiskGeometry = *DiskGeometry;
+
+ return STATUS_SUCCESS;
+ }
+
+ return STATUS_UNSUCCESSFUL;
+}
+
+static
+NTSTATUS
+NTAPI
+SystemConfigurationDataQueryRoutine(
+ PWSTR ValueName,
+ ULONG ValueType,
+ PVOID ValueData,
+ ULONG ValueLength,
+ PVOID Context,
+ PVOID EntryContext)
+{
+ PCM_FULL_RESOURCE_DESCRIPTOR FullResourceDescriptor;
+ PCM_INT13_DRIVE_PARAMETER* Int13Drives = (PCM_INT13_DRIVE_PARAMETER*)Context;
+ ULONG i;
+
+ if (ValueType != REG_FULL_RESOURCE_DESCRIPTOR ||
+ ValueLength < sizeof (CM_FULL_RESOURCE_DESCRIPTOR))
+ return STATUS_UNSUCCESSFUL;
+
+ FullResourceDescriptor = (PCM_FULL_RESOURCE_DESCRIPTOR)ValueData;
+
+ /* Hm. Version and Revision are not set on Microsoft Windows XP... */
+#if 0
+ if (FullResourceDescriptor->PartialResourceList.Version != 1 ||
+ FullResourceDescriptor->PartialResourceList.Revision != 1)
+ return STATUS_UNSUCCESSFUL;
+#endif
+
+ for (i = 0; i < FullResourceDescriptor->PartialResourceList.Count; i++)
+ {
+ if (FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].Type !=
CmResourceTypeDeviceSpecific ||
+
FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize
% sizeof(CM_INT13_DRIVE_PARAMETER) != 0)
+ continue;
+
+ *Int13Drives = (CM_INT13_DRIVE_PARAMETER*)RtlAllocateHeap(RtlGetProcessHeap(),
0,
+
FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
+ if (*Int13Drives == NULL)
+ return STATUS_NO_MEMORY;
+
+ memcpy(*Int13Drives,
+ &FullResourceDescriptor->PartialResourceList.PartialDescriptors[i +
1],
+
FullResourceDescriptor->PartialResourceList.PartialDescriptors[i].u.DeviceSpecificData.DataSize);
+ return STATUS_SUCCESS;
+ }
+
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+#define ROOT_NAME
L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\MultifunctionAdapter"
+
+static
+VOID
+EnumerateBiosDiskEntries(VOID)
+{
+ RTL_QUERY_REGISTRY_TABLE QueryTable[3];
+ WCHAR Name[120];
+ ULONG AdapterCount;
+ ULONG DiskCount;
+ NTSTATUS Status;
+ PCM_INT13_DRIVE_PARAMETER Int13Drives;
+ PBIOSDISKENTRY BiosDiskEntry;
+
+ memset(QueryTable, 0, sizeof(QueryTable));
+
+ QueryTable[1].Name = L"Configuration Data";
+ QueryTable[1].QueryRoutine = SystemConfigurationDataQueryRoutine;
+ Int13Drives = NULL;
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+
L"\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System",
+ &QueryTable[1],
+ (PVOID)&Int13Drives,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Unable to query the 'Configuration Data' key in
'\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System', status=%lx\n",
Status);
+ return;
+ }
+
+ AdapterCount = 0;
+ while (1)
+ {
+ swprintf(Name, L"%s\\%lu", ROOT_NAME, AdapterCount);
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ Name,
+ &QueryTable[2],
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ break;
+ }
+
+ swprintf(Name, L"%s\\%lu\\DiskController", ROOT_NAME, AdapterCount);
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ Name,
+ &QueryTable[2],
+ NULL,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ while (1)
+ {
+ swprintf(Name, L"%s\\%lu\\DiskController\\0", ROOT_NAME,
AdapterCount);
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ Name,
+ &QueryTable[2],
+ NULL,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
+ return;
+ }
+
+ swprintf(Name, L"%s\\%lu\\DiskController\\0\\DiskPeripheral",
ROOT_NAME, AdapterCount);
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ Name,
+ &QueryTable[2],
+ NULL,
+ NULL);
+ if (NT_SUCCESS(Status))
+ {
+ QueryTable[0].Name = L"Identifier";
+ QueryTable[0].QueryRoutine = DiskIdentifierQueryRoutine;
+ QueryTable[1].Name = L"Configuration Data";
+ QueryTable[1].QueryRoutine = DiskConfigurationDataQueryRoutine;
+
+ DiskCount = 0;
+ while (1)
+ {
+ BiosDiskEntry =
(BIOSDISKENTRY*)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(BIOSDISKENTRY));
+ if (BiosDiskEntry == NULL)
+ {
+ break;
+ }
+
+ swprintf(Name,
L"%s\\%lu\\DiskController\\0\\DiskPeripheral\\%lu", ROOT_NAME, AdapterCount,
DiskCount);
+ Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
+ Name,
+ QueryTable,
+ (PVOID)BiosDiskEntry,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
+ break;
+ }
+
+ BiosDiskEntry->DiskNumber = DiskCount;
+ BiosDiskEntry->Recognized = FALSE;
+
+ if (DiskCount < Int13Drives[0].NumberDrives)
+ {
+ BiosDiskEntry->Int13DiskData = Int13Drives[DiskCount];
+ }
+ else
+ {
+ DPRINT1("Didn't find int13 drive datas for disk
%u\n", DiskCount);
+ }
+
+ InsertTailList(&BiosDiskListHead,
&BiosDiskEntry->ListEntry);
+
+ DPRINT("DiskNumber: %lu\n",
BiosDiskEntry->DiskNumber);
+ DPRINT("Signature: %08lx\n",
BiosDiskEntry->Signature);
+ DPRINT("Checksum: %08lx\n",
BiosDiskEntry->Checksum);
+ DPRINT("BytesPerSector: %lu\n",
BiosDiskEntry->DiskGeometry.BytesPerSector);
+ DPRINT("NumberOfCylinders: %lu\n",
BiosDiskEntry->DiskGeometry.NumberOfCylinders);
+ DPRINT("NumberOfHeads: %lu\n",
BiosDiskEntry->DiskGeometry.NumberOfHeads);
+ DPRINT("DriveSelect: %02x\n",
BiosDiskEntry->Int13DiskData.DriveSelect);
+ DPRINT("MaxCylinders: %lu\n",
BiosDiskEntry->Int13DiskData.MaxCylinders);
+ DPRINT("SectorsPerTrack: %d\n",
BiosDiskEntry->Int13DiskData.SectorsPerTrack);
+ DPRINT("MaxHeads: %d\n",
BiosDiskEntry->Int13DiskData.MaxHeads);
+ DPRINT("NumberDrives: %d\n",
BiosDiskEntry->Int13DiskData.NumberDrives);
+
+ DiskCount++;
+ }
+ }
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
+ return;
+ }
+ }
+
+ AdapterCount++;
+ }
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Int13Drives);
+}
+
+
+static
+VOID
+AddPartitionToDisk(
+ ULONG DiskNumber,
+ PDISKENTRY DiskEntry,
+ ULONG PartitionIndex,
+ BOOLEAN LogicalPartition)
+{
+ PPARTITION_INFORMATION PartitionInfo;
+ PPARTENTRY PartEntry;
+
+ PartitionInfo = &DiskEntry->LayoutBuffer->PartitionEntry[PartitionIndex];
+ if (PartitionInfo->PartitionType == 0 ||
+ (LogicalPartition == TRUE &&
IsContainerPartition(PartitionInfo->PartitionType)))
+ return;
+
+ PartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(PARTENTRY));
+ if (PartEntry == NULL)
+ {
+ return;
+ }
+
+ PartEntry->DiskEntry = DiskEntry;
+
+ PartEntry->StartSector.QuadPart =
(ULONGLONG)PartitionInfo->StartingOffset.QuadPart / DiskEntry->BytesPerSector;
+ PartEntry->SectorCount.QuadPart =
(ULONGLONG)PartitionInfo->PartitionLength.QuadPart / DiskEntry->BytesPerSector;
+
+ PartEntry->BootIndicator = PartitionInfo->BootIndicator;
+ PartEntry->PartitionType = PartitionInfo->PartitionType;
+ PartEntry->HiddenSectors = PartitionInfo->HiddenSectors;
+
+ PartEntry->LogicalPartition = LogicalPartition;
+ PartEntry->IsPartitioned = TRUE;
+ PartEntry->PartitionNumber = PartitionInfo->PartitionNumber;
+ PartEntry->PartitionIndex = PartitionIndex;
+
+ if (IsContainerPartition(PartEntry->PartitionType))
+ {
+ PartEntry->FormatState = Unformatted;
+
+ if (LogicalPartition == FALSE && DiskEntry->ExtendedPartition ==
NULL)
+ DiskEntry->ExtendedPartition = PartEntry;
+ }
+ else if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
+ (PartEntry->PartitionType == PARTITION_FAT_16) ||
+ (PartEntry->PartitionType == PARTITION_HUGE) ||
+ (PartEntry->PartitionType == PARTITION_XINT13) ||
+ (PartEntry->PartitionType == PARTITION_FAT32) ||
+ (PartEntry->PartitionType == PARTITION_FAT32_XINT13))
+ {
+#if 0
+ if (CheckFatFormat())
+ {
+ PartEntry->FormatState = Preformatted;
+ }
+ else
+ {
+ PartEntry->FormatState = Unformatted;
+ }
+#endif
+ PartEntry->FormatState = Preformatted;
+ }
+ else if (PartEntry->PartitionType == PARTITION_EXT2)
+ {
+#if 0
+ if (CheckExt2Format())
+ {
+ PartEntry->FormatState = Preformatted;
+ }
+ else
+ {
+ PartEntry->FormatState = Unformatted;
+ }
+#endif
+ PartEntry->FormatState = Preformatted;
+ }
+ else if (PartEntry->PartitionType == PARTITION_IFS)
+ {
+#if 0
+ if (CheckNtfsFormat())
+ {
+ PartEntry->FormatState = Preformatted;
+ }
+ else if (CheckHpfsFormat())
+ {
+ PartEntry->FormatState = Preformatted;
+ }
+ else
+ {
+ PartEntry->FormatState = Unformatted;
+ }
+#endif
+ PartEntry->FormatState = Preformatted;
+ }
+ else
+ {
+ PartEntry->FormatState = UnknownFormat;
+ }
+
+ if (LogicalPartition)
+ InsertTailList(&DiskEntry->LogicalPartListHead,
+ &PartEntry->ListEntry);
+ else
+ InsertTailList(&DiskEntry->PrimaryPartListHead,
+ &PartEntry->ListEntry);
+}
+
+
+static
+VOID
+ScanForUnpartitionedDiskSpace(
+ PDISKENTRY DiskEntry)
+{
+ ULONGLONG LastStartSector;
+ ULONGLONG LastSectorCount;
+ ULONGLONG LastUnusedSectorCount;
+ PPARTENTRY PartEntry;
+ PPARTENTRY NewPartEntry;
+ PLIST_ENTRY Entry;
+
+ DPRINT("ScanForUnpartitionedDiskSpace()\n");
+
+ if (IsListEmpty(&DiskEntry->PrimaryPartListHead))
+ {
+ DPRINT1("No primary partition!\n");
+
+ /* Create a partition table that represents the empty disk */
+ NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(PARTENTRY));
+ if (NewPartEntry == NULL)
+ return;
+
+ NewPartEntry->DiskEntry = DiskEntry;
+
+ NewPartEntry->IsPartitioned = FALSE;
+ NewPartEntry->StartSector.QuadPart =
(ULONGLONG)DiskEntry->SectorAlignment;
+ NewPartEntry->SectorCount.QuadPart =
AlignDown(DiskEntry->SectorCount.QuadPart, DiskEntry->SectorAlignment) -
+ NewPartEntry->StartSector.QuadPart;
+
+ DPRINT1("First Sector: %I64u\n",
NewPartEntry->StartSector.QuadPart);
+ DPRINT1("Last Sector: %I64u\n", NewPartEntry->StartSector.QuadPart +
NewPartEntry->SectorCount.QuadPart - 1);
+ DPRINT1("Total Sectors: %I64u\n",
NewPartEntry->SectorCount.QuadPart);
+
+ NewPartEntry->FormatState = Unformatted;
+
+ InsertTailList(&DiskEntry->PrimaryPartListHead,
+ &NewPartEntry->ListEntry);
+
+ return;
+ }
+
+ /* Start partition at head 1, cylinder 0 */
+ LastStartSector = DiskEntry->SectorAlignment;
+ LastSectorCount = 0ULL;
+ LastUnusedSectorCount = 0ULL;
+
+ Entry = DiskEntry->PrimaryPartListHead.Flink;
+ while (Entry != &DiskEntry->PrimaryPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+
+ if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
+ PartEntry->SectorCount.QuadPart != 0ULL)
+ {
+ LastUnusedSectorCount =
+ PartEntry->StartSector.QuadPart - (LastStartSector +
LastSectorCount);
+
+ if (PartEntry->StartSector.QuadPart > (LastStartSector +
LastSectorCount) &&
+ LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
+ {
+ DPRINT("Unpartitioned disk space %I64u sectors\n",
LastUnusedSectorCount);
+
+ NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(PARTENTRY));
+ if (NewPartEntry == NULL)
+ return;
+
+ NewPartEntry->DiskEntry = DiskEntry;
+
+ NewPartEntry->IsPartitioned = FALSE;
+ NewPartEntry->StartSector.QuadPart = LastStartSector +
LastSectorCount;
+ NewPartEntry->SectorCount.QuadPart =
AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount,
DiskEntry->SectorAlignment) -
+
NewPartEntry->StartSector.QuadPart;
+
+ DPRINT1("First Sector: %I64u\n",
NewPartEntry->StartSector.QuadPart);
+ DPRINT1("Last Sector: %I64u\n",
NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
+ DPRINT1("Total Sectors: %I64u\n",
NewPartEntry->SectorCount.QuadPart);
+
+ NewPartEntry->FormatState = Unformatted;
+
+ /* Insert the table into the list */
+ InsertTailList(&PartEntry->ListEntry,
+ &NewPartEntry->ListEntry);
+ }
+
+ LastStartSector = PartEntry->StartSector.QuadPart;
+ LastSectorCount = PartEntry->SectorCount.QuadPart;
+ }
+
+ Entry = Entry->Flink;
+ }
+
+ /* Check for trailing unpartitioned disk space */
+ if ((LastStartSector + LastSectorCount) < DiskEntry->SectorCount.QuadPart)
+ {
+ LastUnusedSectorCount = AlignDown(DiskEntry->SectorCount.QuadPart -
(LastStartSector + LastSectorCount), DiskEntry->SectorAlignment);
+
+ if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->CylinderAlignment)
+ {
+ DPRINT1("Unpartitioned disk space: %I64u sectors\n",
LastUnusedSectorCount);
+
+ NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(PARTENTRY));
+ if (NewPartEntry == NULL)
+ return;
+
+ NewPartEntry->DiskEntry = DiskEntry;
+
+ NewPartEntry->IsPartitioned = FALSE;
+ NewPartEntry->StartSector.QuadPart = LastStartSector + LastSectorCount;
+ NewPartEntry->SectorCount.QuadPart =
AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount,
DiskEntry->SectorAlignment) -
+ NewPartEntry->StartSector.QuadPart;
+
+ DPRINT1("First Sector: %I64u\n",
NewPartEntry->StartSector.QuadPart);
+ DPRINT1("Last Sector: %I64u\n",
NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
+ DPRINT1("Total Sectors: %I64u\n",
NewPartEntry->SectorCount.QuadPart);
+
+ NewPartEntry->FormatState = Unformatted;
+
+ /* Append the table to the list */
+ InsertTailList(&DiskEntry->PrimaryPartListHead,
+ &NewPartEntry->ListEntry);
+ }
+ }
+
+ if (DiskEntry->ExtendedPartition != NULL)
+ {
+ if (IsListEmpty(&DiskEntry->LogicalPartListHead))
+ {
+ DPRINT1("No logical partition!\n");
+
+ /* Create a partition table entry that represents the empty extended
partition */
+ NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(PARTENTRY));
+ if (NewPartEntry == NULL)
+ return;
+
+ NewPartEntry->DiskEntry = DiskEntry;
+ NewPartEntry->LogicalPartition = TRUE;
+
+ NewPartEntry->IsPartitioned = FALSE;
+ NewPartEntry->StartSector.QuadPart =
DiskEntry->ExtendedPartition->StartSector.QuadPart +
(ULONGLONG)DiskEntry->SectorAlignment;
+ NewPartEntry->SectorCount.QuadPart =
DiskEntry->ExtendedPartition->SectorCount.QuadPart -
(ULONGLONG)DiskEntry->SectorAlignment;
+
+ DPRINT1("First Sector: %I64u\n",
NewPartEntry->StartSector.QuadPart);
+ DPRINT1("Last Sector: %I64u\n",
NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
+ DPRINT1("Total Sectors: %I64u\n",
NewPartEntry->SectorCount.QuadPart);
+
+ NewPartEntry->FormatState = Unformatted;
+
+ InsertTailList(&DiskEntry->LogicalPartListHead,
+ &NewPartEntry->ListEntry);
+
+ return;
+ }
+
+ /* Start partition at head 1, cylinder 0 */
+ LastStartSector = DiskEntry->ExtendedPartition->StartSector.QuadPart +
(ULONGLONG)DiskEntry->SectorAlignment;
+ LastSectorCount = 0ULL;
+ LastUnusedSectorCount = 0ULL;
+
+ Entry = DiskEntry->LogicalPartListHead.Flink;
+ while (Entry != &DiskEntry->LogicalPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+
+ if (PartEntry->PartitionType != PARTITION_ENTRY_UNUSED ||
+ PartEntry->SectorCount.QuadPart != 0ULL)
+ {
+ LastUnusedSectorCount =
+ PartEntry->StartSector.QuadPart -
(ULONGLONG)DiskEntry->SectorAlignment - (LastStartSector + LastSectorCount);
+
+ if ((PartEntry->StartSector.QuadPart -
(ULONGLONG)DiskEntry->SectorAlignment) > (LastStartSector + LastSectorCount)
&&
+ LastUnusedSectorCount >=
(ULONGLONG)DiskEntry->SectorAlignment)
+ {
+ DPRINT("Unpartitioned disk space %I64u sectors\n",
LastUnusedSectorCount);
+
+ NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(PARTENTRY));
+ if (NewPartEntry == NULL)
+ return;
+
+ NewPartEntry->DiskEntry = DiskEntry;
+ NewPartEntry->LogicalPartition = TRUE;
+
+ NewPartEntry->IsPartitioned = FALSE;
+ NewPartEntry->StartSector.QuadPart = LastStartSector +
LastSectorCount;
+ NewPartEntry->SectorCount.QuadPart =
AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount,
DiskEntry->SectorAlignment) -
+
NewPartEntry->StartSector.QuadPart;
+
+ DPRINT("First Sector: %I64u\n",
NewPartEntry->StartSector.QuadPart);
+ DPRINT("Last Sector: %I64u\n",
NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
+ DPRINT("Total Sectors: %I64u\n",
NewPartEntry->SectorCount.QuadPart);
+
+ NewPartEntry->FormatState = Unformatted;
+
+ /* Insert the table into the list */
+ InsertTailList(&PartEntry->ListEntry,
+ &NewPartEntry->ListEntry);
+ }
+
+ LastStartSector = PartEntry->StartSector.QuadPart;
+ LastSectorCount = PartEntry->SectorCount.QuadPart;
+ }
+
+ Entry = Entry->Flink;
+ }
+
+ /* Check for trailing unpartitioned disk space */
+ if ((LastStartSector + LastSectorCount) <
DiskEntry->ExtendedPartition->StartSector.QuadPart +
DiskEntry->ExtendedPartition->SectorCount.QuadPart)
+ {
+ LastUnusedSectorCount =
AlignDown(DiskEntry->ExtendedPartition->StartSector.QuadPart +
DiskEntry->ExtendedPartition->SectorCount.QuadPart - (LastStartSector +
LastSectorCount),
+ DiskEntry->SectorAlignment);
+
+ if (LastUnusedSectorCount >= (ULONGLONG)DiskEntry->SectorAlignment)
+ {
+ DPRINT("Unpartitioned disk space: %I64u sectors\n",
LastUnusedSectorCount);
+
+ NewPartEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(PARTENTRY));
+ if (NewPartEntry == NULL)
+ return;
+
+ NewPartEntry->DiskEntry = DiskEntry;
+ NewPartEntry->LogicalPartition = TRUE;
+
+ NewPartEntry->IsPartitioned = FALSE;
+ NewPartEntry->StartSector.QuadPart = LastStartSector +
LastSectorCount;
+ NewPartEntry->SectorCount.QuadPart =
AlignDown(NewPartEntry->StartSector.QuadPart + LastUnusedSectorCount,
DiskEntry->SectorAlignment) -
+
NewPartEntry->StartSector.QuadPart;
+
+ DPRINT("First Sector: %I64u\n",
NewPartEntry->StartSector.QuadPart);
+ DPRINT("Last Sector: %I64u\n",
NewPartEntry->StartSector.QuadPart + NewPartEntry->SectorCount.QuadPart - 1);
+ DPRINT("Total Sectors: %I64u\n",
NewPartEntry->SectorCount.QuadPart);
+
+ NewPartEntry->FormatState = Unformatted;
+
+ /* Append the table to the list */
+ InsertTailList(&DiskEntry->LogicalPartListHead,
+ &NewPartEntry->ListEntry);
+ }
+ }
+ }
+
+ DPRINT("ScanForUnpartitionedDiskSpace() done\n");
+}
+
+
+static
+VOID
+AddDiskToList(
+ HANDLE FileHandle,
+ ULONG DiskNumber)
+{
+ DISK_GEOMETRY DiskGeometry;
+ SCSI_ADDRESS ScsiAddress;
+ PDISKENTRY DiskEntry;
+ IO_STATUS_BLOCK Iosb;
+ NTSTATUS Status;
+ PPARTITION_SECTOR Mbr;
+ PULONG Buffer;
+ LARGE_INTEGER FileOffset;
+ WCHAR Identifier[20];
+ ULONG Checksum;
+ ULONG Signature;
+ ULONG i;
+ PLIST_ENTRY ListEntry;
+ PBIOSDISKENTRY BiosDiskEntry;
+ ULONG LayoutBufferSize;
+ PDRIVE_LAYOUT_INFORMATION NewLayoutBuffer;
+
+ Status = NtDeviceIoControlFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ IOCTL_DISK_GET_DRIVE_GEOMETRY,
+ NULL,
+ 0,
+ &DiskGeometry,
+ sizeof(DISK_GEOMETRY));
+ if (!NT_SUCCESS(Status))
+ {
+ return;
+ }
+
+ if (DiskGeometry.MediaType != FixedMedia &&
+ DiskGeometry.MediaType != RemovableMedia)
+ {
+ return;
+ }
+
+ Status = NtDeviceIoControlFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ IOCTL_SCSI_GET_ADDRESS,
+ NULL,
+ 0,
+ &ScsiAddress,
+ sizeof(SCSI_ADDRESS));
+ if (!NT_SUCCESS(Status))
+ {
+ return;
+ }
+
+ Mbr = (PARTITION_SECTOR*)RtlAllocateHeap(RtlGetProcessHeap(),
+ 0,
+ DiskGeometry.BytesPerSector);
+ if (Mbr == NULL)
+ {
+ return;
+ }
+
+ FileOffset.QuadPart = 0;
+ Status = NtReadFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ (PVOID)Mbr,
+ DiskGeometry.BytesPerSector,
+ &FileOffset,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
+ DPRINT1("NtReadFile failed, status=%x\n", Status);
+ return;
+ }
+ Signature = Mbr->Signature;
+
+ /* Calculate the MBR checksum */
+ Checksum = 0;
+ Buffer = (PULONG)Mbr;
+ for (i = 0; i < 128; i++)
+ {
+ Checksum += Buffer[i];
+ }
+ Checksum = ~Checksum + 1;
+
+ swprintf(Identifier, L"%08x-%08x-A", Checksum, Signature);
+ DPRINT("Identifier: %S\n", Identifier);
+
+ DiskEntry = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(DISKENTRY));
+ if (DiskEntry == NULL)
+ {
+ return;
+ }
+
+// DiskEntry->Checksum = Checksum;
+// DiskEntry->Signature = Signature;
+ DiskEntry->BiosFound = FALSE;
+
+ /* Check if this disk has a valid MBR */
+ if (Mbr->BootCode[0] == 0 && Mbr->BootCode[1] == 0)
+ DiskEntry->NoMbr = TRUE;
+ else
+ DiskEntry->NoMbr = FALSE;
+
+ /* Free Mbr sector buffer */
+ RtlFreeHeap(RtlGetProcessHeap(), 0, Mbr);
+
+ ListEntry = BiosDiskListHead.Flink;
+ while (ListEntry != &BiosDiskListHead)
+ {
+ BiosDiskEntry = CONTAINING_RECORD(ListEntry, BIOSDISKENTRY, ListEntry);
+ /* FIXME:
+ * Compare the size from bios and the reported size from driver.
+ * If we have more than one disk with a zero or with the same signatur
+ * we must create new signatures and reboot. After the reboot,
+ * it is possible to identify the disks.
+ */
+ if (BiosDiskEntry->Signature == Signature &&
+ BiosDiskEntry->Checksum == Checksum &&
+ !BiosDiskEntry->Recognized)
+ {
+ if (!DiskEntry->BiosFound)
+ {
+ DiskEntry->BiosDiskNumber = BiosDiskEntry->DiskNumber;
+ DiskEntry->BiosFound = TRUE;
+ BiosDiskEntry->Recognized = TRUE;
+ }
+ else
+ {
+ }
+ }
+ ListEntry = ListEntry->Flink;
+ }
+
+ if (!DiskEntry->BiosFound)
+ {
+#if 0
+ RtlFreeHeap(ProcessHeap, 0, DiskEntry);
+ return;
+#else
+ DPRINT1("WARNING: Setup could not find a matching BIOS disk entry. Disk %d
is not be bootable by the BIOS!\n", DiskNumber);
+#endif
+ }
+
+ InitializeListHead(&DiskEntry->PrimaryPartListHead);
+ InitializeListHead(&DiskEntry->LogicalPartListHead);
+
+ DiskEntry->Cylinders = DiskGeometry.Cylinders.QuadPart;
+ DiskEntry->TracksPerCylinder = DiskGeometry.TracksPerCylinder;
+ DiskEntry->SectorsPerTrack = DiskGeometry.SectorsPerTrack;
+ DiskEntry->BytesPerSector = DiskGeometry.BytesPerSector;
+
+ DPRINT("Cylinders %I64u\n", DiskEntry->Cylinders);
+ DPRINT("TracksPerCylinder %I64u\n", DiskEntry->TracksPerCylinder);
+ DPRINT("SectorsPerTrack %I64u\n", DiskEntry->SectorsPerTrack);
+ DPRINT("BytesPerSector %I64u\n", DiskEntry->BytesPerSector);
+
+ DiskEntry->SectorCount.QuadPart = DiskGeometry.Cylinders.QuadPart *
+ (ULONGLONG)DiskGeometry.TracksPerCylinder *
+ (ULONGLONG)DiskGeometry.SectorsPerTrack;
+
+ DiskEntry->SectorAlignment = DiskGeometry.SectorsPerTrack;
+ DiskEntry->CylinderAlignment = DiskGeometry.SectorsPerTrack *
DiskGeometry.TracksPerCylinder;
+
+ DPRINT1("SectorCount: %I64u\n", DiskEntry->SectorCount);
+ DPRINT1("SectorAlignment: %lu\n", DiskEntry->SectorAlignment);
+ DPRINT1("CylinderAlignment: %lu\n", DiskEntry->CylinderAlignment);
+
+ DiskEntry->DiskNumber = DiskNumber;
+ DiskEntry->Port = ScsiAddress.PortNumber;
+ DiskEntry->Bus = ScsiAddress.PathId;
+ DiskEntry->Id = ScsiAddress.TargetId;
+
+ GetDriverName(DiskEntry);
+
+ InsertAscendingList(&DiskListHead, DiskEntry, DISKENTRY, ListEntry, DiskNumber);
+
+ /* Allocate a layout buffer with 4 partition entries first */
+ LayoutBufferSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
+ ((4 - ANYSIZE_ARRAY) * sizeof(PARTITION_INFORMATION));
+ DiskEntry->LayoutBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ LayoutBufferSize);
+ if (DiskEntry->LayoutBuffer == NULL)
+ {
+ DPRINT1("Failed to allocate the disk layout buffer!\n");
+ return;
+ }
+
+ for (;;)
+ {
+ DPRINT1("Buffer size: %lu\n", LayoutBufferSize);
+ Status = NtDeviceIoControlFile(FileHandle,
+ NULL,
+ NULL,
+ NULL,
+ &Iosb,
+ IOCTL_DISK_GET_DRIVE_LAYOUT,
+ NULL,
+ 0,
+ DiskEntry->LayoutBuffer,
+ LayoutBufferSize);
+ if (NT_SUCCESS(Status))
+ break;
+
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ {
+ DPRINT1("NtDeviceIoControlFile() failed (Status: 0x%08lx)\n",
Status);
+ return;
+ }
+
+ LayoutBufferSize += 4 * sizeof(PARTITION_INFORMATION);
+ NewLayoutBuffer = RtlReAllocateHeap(RtlGetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ DiskEntry->LayoutBuffer,
+ LayoutBufferSize);
+ if (NewLayoutBuffer == NULL)
+ {
+ DPRINT1("Failed to reallocate the disk layout buffer!\n");
+ return;
+ }
+
+ DiskEntry->LayoutBuffer = NewLayoutBuffer;
+ }
+
+ DPRINT1("PartitionCount: %lu\n",
DiskEntry->LayoutBuffer->PartitionCount);
+
+#ifdef DUMP_PARTITION_TABLE
+ DumpPartitionTable(DiskEntry);
+#endif
+
+ if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart != 0
&&
+ DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionLength.QuadPart != 0
&&
+ DiskEntry->LayoutBuffer->PartitionEntry[0].PartitionType != 0)
+ {
+ if ((DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart /
DiskEntry->BytesPerSector) % DiskEntry->SectorsPerTrack == 0)
+ {
+ DPRINT("Use %lu Sector alignment!\n",
DiskEntry->SectorsPerTrack);
+ }
+ else if (DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart
% (1024 * 1024) == 0)
+ {
+ DPRINT1("Use megabyte (%lu Sectors) alignment!\n", (1024 * 1024) /
DiskEntry->BytesPerSector);
+ }
+ else
+ {
+ DPRINT1("No matching aligment found! Partiton 1 starts at %I64u\n",
DiskEntry->LayoutBuffer->PartitionEntry[0].StartingOffset.QuadPart);
+ }
+ }
+ else
+ {
+ DPRINT1("No valid partiton table found! Use megabyte (%lu Sectors)
alignment!\n", (1024 * 1024) / DiskEntry->BytesPerSector);
+ }
+
+
+ if (DiskEntry->LayoutBuffer->PartitionCount == 0)
+ {
+ DiskEntry->NewDisk = TRUE;
+ DiskEntry->LayoutBuffer->PartitionCount = 4;
+
+ for (i = 0; i < 4; i++)
+ DiskEntry->LayoutBuffer->PartitionEntry[i].RewritePartition = TRUE;
+ }
+ else
+ {
+ for (i = 0; i < 4; i++)
+ {
+ AddPartitionToDisk(DiskNumber,
+ DiskEntry,
+ i,
+ FALSE);
+ }
+
+ for (i = 4; i < DiskEntry->LayoutBuffer->PartitionCount; i += 4)
+ {
+ AddPartitionToDisk(DiskNumber,
+ DiskEntry,
+ i,
+ TRUE);
+ }
+ }
+
+ ScanForUnpartitionedDiskSpace(DiskEntry);
+}
+
+
+NTSTATUS
+CreatePartitionList(VOID)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ SYSTEM_DEVICE_INFORMATION Sdi;
+ IO_STATUS_BLOCK Iosb;
+ ULONG ReturnSize;
+ NTSTATUS Status;
+ ULONG DiskNumber;
+ WCHAR Buffer[MAX_PATH];
+ UNICODE_STRING Name;
+ HANDLE FileHandle;
+
+ CurrentDisk = NULL;
+ CurrentPartition = NULL;
+
+// BootDisk = NULL;
+// BootPartition = NULL;
+
+// TempDisk = NULL;
+// TempPartition = NULL;
+// FormatState = Start;
+
+ InitializeListHead(&DiskListHead);
+ InitializeListHead(&BiosDiskListHead);
+
+ EnumerateBiosDiskEntries();
+
+ Status = NtQuerySystemInformation(SystemDeviceInformation,
+ &Sdi,
+ sizeof(SYSTEM_DEVICE_INFORMATION),
+ &ReturnSize);
+ if (!NT_SUCCESS(Status))
+ {
+ return Status;
+ }
+
+ for (DiskNumber = 0; DiskNumber < Sdi.NumberOfDisks; DiskNumber++)
+ {
+ swprintf(Buffer,
+ L"\\Device\\Harddisk%d\\Partition0",
+ DiskNumber);
+ RtlInitUnicodeString(&Name,
+ Buffer);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ 0,
+ NULL,
+ NULL);
+
+ Status = NtOpenFile(&FileHandle,
+ FILE_READ_DATA | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
+ &ObjectAttributes,
+ &Iosb,
+ FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT);
+ if (NT_SUCCESS(Status))
+ {
+ AddDiskToList(FileHandle,
+ DiskNumber);
+
+ NtClose(FileHandle);
+ }
+ }
+
+// UpdateDiskSignatures(List);
+
+// AssignDriveLetters(List);
+
+ return STATUS_SUCCESS;
+}
+
+
+VOID
+DestroyPartitionList(VOID)
+{
+ PDISKENTRY DiskEntry;
+ PBIOSDISKENTRY BiosDiskEntry;
+ PPARTENTRY PartEntry;
+ PLIST_ENTRY Entry;
+
+ /* Release disk and partition info */
+ while (!IsListEmpty(&DiskListHead))
+ {
+ Entry = RemoveHeadList(&DiskListHead);
+ DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+
+ /* Release driver name */
+ RtlFreeUnicodeString(&DiskEntry->DriverName);
+
+ /* Release primary partition list */
+ while (!IsListEmpty(&DiskEntry->PrimaryPartListHead))
+ {
+ Entry = RemoveHeadList(&DiskEntry->PrimaryPartListHead);
+ PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
+ }
+
+ /* Release logical partition list */
+ while (!IsListEmpty(&DiskEntry->LogicalPartListHead))
+ {
+ Entry = RemoveHeadList(&DiskEntry->LogicalPartListHead);
+ PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, PartEntry);
+ }
+
+ /* Release layout buffer */
+ if (DiskEntry->LayoutBuffer != NULL)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry->LayoutBuffer);
+
+
+ /* Release disk entry */
+ RtlFreeHeap(RtlGetProcessHeap(), 0, DiskEntry);
+ }
+
+ /* Release the bios disk info */
+ while(!IsListEmpty(&BiosDiskListHead))
+ {
+ Entry = RemoveHeadList(&BiosDiskListHead);
+ BiosDiskEntry = CONTAINING_RECORD(Entry, BIOSDISKENTRY, ListEntry);
+
+ RtlFreeHeap(RtlGetProcessHeap(), 0, BiosDiskEntry);
+ }
+}
+
+/* EOF */
Propchange: trunk/reactos/base/system/diskpart/partlist.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/base/system/diskpart/resource.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/diskpart/resou…
==============================================================================
--- trunk/reactos/base/system/diskpart/resource.h [iso-8859-1] (original)
+++ trunk/reactos/base/system/diskpart/resource.h [iso-8859-1] Mon Jul 20 19:17:06 2015
@@ -35,14 +35,21 @@
#define IDS_LIST_DISK_HEAD 3300
#define IDS_LIST_DISK_LINE 3301
#define IDS_LIST_DISK_FORMAT 3302
-#define IDS_LIST_VOLUME_HEAD 3303
+#define IDS_LIST_PARTITION_HEAD 3303
+#define IDS_LIST_PARTITION_LINE 3304
+#define IDS_LIST_PARTITION_FORMAT 3305
+#define IDS_LIST_PARTITION_NO_DISK 3306
+#define IDS_LIST_VOLUME_HEAD 3307
#define IDS_SELECT_NO_DISK 4400
#define IDS_SELECT_DISK 4401
-#define IDS_SELECT_NO_VOLUME 4402
-#define IDS_SELECT_VOLUME 4403
-#define IDS_SELECT_NO_PARTITION 4404
-#define IDS_SELECT_PARTITION 4405
+#define IDS_SELECT_DISK_INVALID 4402
+#define IDS_SELECT_NO_PARTITION 4403
+#define IDS_SELECT_PARTITION 4404
+#define IDS_SELECT_PARTITION_NO_DISK 4405
+#define IDS_SELECT_PARTITION_INVALID 4406
+#define IDS_SELECT_NO_VOLUME 4407
+#define IDS_SELECT_VOLUME 4408
#define IDS_STATUS_YES 31
#define IDS_STATUS_NO 32
@@ -135,4 +142,3 @@
#define IDS_HELP_CMD_UNIQUEID 140
#define IDS_ERROR_INVALID_ARGS 211
-#define IDS_ERROR_INVALID_DISK 212
Modified: trunk/reactos/base/system/diskpart/select.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/system/diskpart/selec…
==============================================================================
--- trunk/reactos/base/system/diskpart/select.c [iso-8859-1] (original)
+++ trunk/reactos/base/system/diskpart/select.c [iso-8859-1] Mon Jul 20 19:17:06 2015
@@ -11,10 +11,7 @@
#define NDEBUG
#include <debug.h>
-
-ULONG CurrentDisk = (ULONG)-1;
-ULONG CurrentPartition = (ULONG)-1;
-
+/* FUNCTIONS ******************************************************************/
static
VOID
@@ -22,10 +19,9 @@
INT argc,
LPWSTR *argv)
{
- SYSTEM_DEVICE_INFORMATION Sdi;
- ULONG ReturnSize;
- NTSTATUS Status;
- LONG value;
+ PLIST_ENTRY Entry;
+ PDISKENTRY DiskEntry;
+ LONG lValue;
LPWSTR endptr = NULL;
DPRINT("Select Disk()\n");
@@ -38,40 +34,40 @@
if (argc == 2)
{
- if (CurrentDisk == (ULONG)-1)
+ if (CurrentDisk == NULL)
PrintResourceString(IDS_SELECT_NO_DISK);
else
- PrintResourceString(IDS_SELECT_DISK, CurrentDisk);
+ PrintResourceString(IDS_SELECT_DISK, CurrentDisk->DiskNumber);
return;
}
- value = wcstol(argv[2], &endptr, 10);
- if (((value == 0) && (endptr == argv[2])) ||
- (value < 0))
+ lValue = wcstol(argv[2], &endptr, 10);
+ if (((lValue == 0) && (endptr == argv[2])) ||
+ (lValue < 0))
{
PrintResourceString(IDS_ERROR_INVALID_ARGS);
return;
}
- Status = NtQuerySystemInformation(SystemDeviceInformation,
- &Sdi,
- sizeof(SYSTEM_DEVICE_INFORMATION),
- &ReturnSize);
- if (!NT_SUCCESS(Status))
+ CurrentDisk = NULL;
+
+ Entry = DiskListHead.Flink;
+ while (Entry != &DiskListHead)
{
- return;
+ DiskEntry = CONTAINING_RECORD(Entry, DISKENTRY, ListEntry);
+
+ if (DiskEntry->DiskNumber == (ULONG)lValue)
+ {
+ CurrentDisk = DiskEntry;
+ CurrentPartition = NULL;
+ PrintResourceString(IDS_SELECT_DISK, CurrentDisk->DiskNumber);
+ return;
+ }
+
+ Entry = Entry->Flink;
}
- if ((ULONG)value >= Sdi.NumberOfDisks)
- {
- PrintResourceString(IDS_ERROR_INVALID_DISK);
- return;
- }
-
- CurrentDisk = (ULONG)value;
- CurrentPartition = (ULONG)-1;
-
- PrintResourceString(IDS_SELECT_DISK, CurrentDisk);
+ PrintResourceString(IDS_SELECT_DISK_INVALID);
}
@@ -81,8 +77,11 @@
INT argc,
LPWSTR *argv)
{
- LONG value;
+ PLIST_ENTRY Entry;
+ PPARTENTRY PartEntry;
+ LONG lValue;
LPWSTR endptr = NULL;
+ ULONG PartNumber = 1;
DPRINT("Select Partition()\n");
@@ -92,28 +91,69 @@
return;
}
+ if (CurrentDisk == NULL)
+ {
+ PrintResourceString(IDS_SELECT_PARTITION_NO_DISK);
+ return;
+ }
+
if (argc == 2)
{
- if (CurrentPartition == (ULONG)-1)
+ if (CurrentPartition == NULL)
PrintResourceString(IDS_SELECT_NO_PARTITION);
else
PrintResourceString(IDS_SELECT_PARTITION, CurrentPartition);
return;
}
- value = wcstol(argv[2], &endptr, 10);
- if (((value == 0) && (endptr == argv[2])) ||
- (value < 0))
+ lValue = wcstol(argv[2], &endptr, 10);
+ if (((lValue == 0) && (endptr == argv[2])) ||
+ (lValue < 0))
{
PrintResourceString(IDS_ERROR_INVALID_ARGS);
return;
}
- /* FIXME: Check the new partition number */
+ Entry = CurrentDisk->PrimaryPartListHead.Flink;
+ while (Entry != &CurrentDisk->PrimaryPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
- CurrentPartition = (ULONG)value;
+ if (PartEntry->PartitionType != 0)
+ {
+ if (PartNumber == (ULONG)lValue)
+ {
+ CurrentPartition = PartEntry;
+ PrintResourceString(IDS_SELECT_PARTITION, PartNumber);
+ return;
+ }
- PrintResourceString(IDS_SELECT_PARTITION, CurrentPartition);
+ PartNumber++;
+ }
+
+ Entry = Entry->Flink;
+ }
+
+ Entry = CurrentDisk->LogicalPartListHead.Flink;
+ while (Entry != &CurrentDisk->LogicalPartListHead)
+ {
+ PartEntry = CONTAINING_RECORD(Entry, PARTENTRY, ListEntry);
+
+ if (PartEntry->PartitionType != 0)
+ {
+ if (PartNumber == (ULONG)lValue)
+ {
+ CurrentPartition = PartEntry;
+ PrintResourceString(IDS_SELECT_PARTITION, PartNumber);
+ return;
+ }
+
+ PartNumber++;
+ }
+ Entry = Entry->Flink;
+ }
+
+ PrintResourceString(IDS_SELECT_PARTITION_INVALID);
}