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/CMakeL... ============================================================================== --- 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/diskpa... ============================================================================== --- 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/diskpa... ============================================================================== --- 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/e... ============================================================================== --- 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/r... ============================================================================== --- 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/r... ============================================================================== --- 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/s... ============================================================================== --- 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/t... ============================================================================== --- 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.c... ============================================================================== --- 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/partli... ============================================================================== --- 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/resour... ============================================================================== --- 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/select... ============================================================================== --- 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); }