Author: hbelusca
Date: Sun Aug 20 21:30:13 2017
New Revision: 75632
URL:
http://svn.reactos.org/svn/reactos?rev=75632&view=rev
Log:
[SETUPLIB]: Factor out and introduce a ParseArcName() helper function that does its job.
Used in exiting code and in later code in this file.
Modified:
branches/setup_improvements/base/setup/lib/arcname.c
Modified: branches/setup_improvements/base/setup/lib/arcname.c
URL:
http://svn.reactos.org/svn/reactos/branches/setup_improvements/base/setup/l…
==============================================================================
--- branches/setup_improvements/base/setup/lib/arcname.c [iso-8859-1] (original)
+++ branches/setup_improvements/base/setup/lib/arcname.c [iso-8859-1] Sun Aug 20 21:30:13
2017
@@ -345,6 +345,218 @@
/*
+ * ArcNamePath:
+ * In input, pointer to an ARC path (NULL-terminated) starting by an
+ * ARC name to be parsed into its different components.
+ * In output, ArcNamePath points to the beginning of the path after
+ * the ARC name part.
+ */
+static NTSTATUS
+ParseArcName(
+ IN OUT PCWSTR* ArcNamePath,
+ OUT PULONG pAdapterKey,
+ OUT PULONG pControllerKey,
+ OUT PULONG pPeripheralKey,
+ OUT PULONG pPartitionNumber,
+ OUT PADAPTER_TYPE pAdapterType,
+ OUT PCONTROLLER_TYPE pControllerType,
+ OUT PPERIPHERAL_TYPE pPeripheralType,
+ OUT PBOOLEAN pUseSignature)
+{
+ WCHAR TokenBuffer[50];
+ UNICODE_STRING Token;
+ PCWSTR p, q;
+ ULONG AdapterKey;
+ ULONG ControllerKey;
+ ULONG PeripheralKey;
+ ULONG PartitionNumber;
+ ADAPTER_TYPE AdapterType;
+ CONTROLLER_TYPE ControllerType;
+ PERIPHERAL_TYPE PeripheralType;
+ BOOLEAN UseSignature = FALSE;
+
+ /*
+ * The format of ArcName is:
+ * adapter(www)[controller(xxx)peripheral(yyy)[partition(zzz)][filepath]] ,
+ * where the [filepath] part is not being parsed.
+ */
+
+ RtlInitEmptyUnicodeString(&Token, TokenBuffer, sizeof(TokenBuffer));
+
+ p = *ArcNamePath;
+
+ /* Retrieve the adapter */
+ p = ArcGetNextTokenU(p, &Token, &AdapterKey);
+ if (!p)
+ {
+ DPRINT1("No adapter specified!\n");
+ return STATUS_OBJECT_PATH_SYNTAX_BAD;
+ }
+
+ /* Check for the 'signature()' pseudo-adapter, introduced in Windows 2000 */
+ if (_wcsicmp(Token.Buffer, L"signature") == 0)
+ {
+ /*
+ * We've got a signature! Remember this for later, and set the adapter type
to SCSI.
+ * We however check that the rest of the ARC path is valid by parsing the other
tokens.
+ * AdapterKey stores the disk signature value (that holds in a ULONG).
+ */
+ UseSignature = TRUE;
+ AdapterType = ScsiAdapter;
+ }
+ else
+ {
+ /* Check for regular adapters */
+ AdapterType =
(ADAPTER_TYPE)/*ArcMatchTokenU*/ArcMatchToken_UStr(/*Token.Buffer*/&Token,
AdapterTypes_U);
+ if (AdapterType >= AdapterTypeMax)
+ {
+ DPRINT1("Invalid adapter type %wZ\n", &Token);
+ return STATUS_OBJECT_NAME_INVALID;
+ }
+
+ /* Check for adapters that don't take any extra controller or peripheral
nodes */
+ if (AdapterType == NetAdapter || AdapterType == RamdiskAdapter)
+ {
+ // if (*p)
+ // return STATUS_OBJECT_PATH_SYNTAX_BAD;
+
+ if (AdapterType == NetAdapter)
+ {
+ DPRINT1("%S(%lu) path is not supported!\n",
AdapterTypes_U[AdapterType], AdapterKey);
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ goto Quit;
+ }
+ }
+
+ /* Here, we have either an 'eisa', a 'scsi/signature', or a
'multi' adapter */
+
+ /* Check for a valid controller */
+ p = ArcGetNextTokenU(p, &Token, &ControllerKey);
+ if (!p)
+ {
+ DPRINT1("%S(%lu) adapter doesn't have a controller!\n",
AdapterTypes_U[AdapterType], AdapterKey);
+ return STATUS_OBJECT_PATH_SYNTAX_BAD;
+ }
+ ControllerType =
(CONTROLLER_TYPE)/*ArcMatchTokenU*/ArcMatchToken_UStr(/*Token.Buffer*/&Token,
ControllerTypes_U);
+ if (ControllerType >= ControllerTypeMax)
+ {
+ DPRINT1("Invalid controller type %wZ\n", &Token);
+ return STATUS_OBJECT_NAME_INVALID;
+ }
+
+ /* Here the controller can only be either a disk or a CDROM */
+
+ /*
+ * Ignore the controller in case we have a 'multi' adapter.
+ * I guess a similar condition holds for the 'eisa' adapter too...
+ *
+ * For SignatureAdapter, as similar for ScsiAdapter, the controller key corresponds
+ * to the disk target ID. Note that actually, the implementation just ignores the
+ * target ID, as well as the LUN, and just loops over all the available disks and
+ * searches for the one having the correct signature.
+ */
+ if ((AdapterType == MultiAdapter /* || AdapterType == EisaAdapter */) &&
ControllerKey != 0)
+ {
+ DPRINT1("%S(%lu) adapter with %S(%lu non-zero), ignored!\n",
+ AdapterTypes_U[AdapterType], AdapterKey,
+ ControllerTypes_U[ControllerType], ControllerKey);
+ ControllerKey = 0;
+ }
+
+ /*
+ * Only the 'scsi' adapter supports a direct 'cdrom' controller.
+ * For the others, we need a 'disk' controller to which a 'cdrom'
peripheral can talk to.
+ */
+ if ((AdapterType != ScsiAdapter) && (ControllerType == CdRomController))
+ {
+ DPRINT1("%S(%lu) adapter cannot have a CDROM controller!\n",
AdapterTypes_U[AdapterType], AdapterKey);
+ return STATUS_OBJECT_PATH_INVALID;
+ }
+
+ /* Check for a valid peripheral */
+ p = ArcGetNextTokenU(p, &Token, &PeripheralKey);
+ if (!p)
+ {
+ DPRINT1("%S(%lu)%S(%lu) adapter-controller doesn't have a
peripheral!\n",
+ AdapterTypes_U[AdapterType], AdapterKey,
+ ControllerTypes_U[ControllerType], ControllerKey);
+ return STATUS_OBJECT_PATH_SYNTAX_BAD;
+ }
+ PeripheralType =
(PERIPHERAL_TYPE)/*ArcMatchTokenU*/ArcMatchToken_UStr(/*Token.Buffer*/&Token,
PeripheralTypes_U);
+ if (PeripheralType >= PeripheralTypeMax)
+ {
+ DPRINT1("Invalid peripheral type %wZ\n", &Token);
+ return STATUS_OBJECT_NAME_INVALID;
+ }
+
+ /*
+ * If we had a 'cdrom' controller already, the corresponding peripheral can
only be 'fdisk'
+ * (see for example the ARC syntax for SCSI CD-ROMs: scsi(x)cdrom(y)fdisk(z) where z
== 0).
+ */
+ if ((ControllerType == CdRomController) && (PeripheralType !=
FDiskPeripheral))
+ {
+ DPRINT1("%S(%lu) controller cannot have a %S(%lu) peripheral! (note that we
haven't check whether the adapter was SCSI or not)\n",
+ ControllerTypes_U[ControllerType], ControllerKey,
+ PeripheralTypes_U[PeripheralType], PeripheralKey);
+ return STATUS_OBJECT_PATH_INVALID;
+ }
+
+ /* For a 'scsi' adapter, the possible peripherals are only 'rdisk' or
'fdisk' */
+ if (AdapterType == ScsiAdapter && !(PeripheralType == RDiskPeripheral ||
PeripheralType == FDiskPeripheral))
+ {
+ DPRINT1("%S(%lu)%S(%lu) SCSI adapter-controller has an invalid peripheral
%S(%lu) !\n",
+ AdapterTypes_U[AdapterType], AdapterKey,
+ ControllerTypes_U[ControllerType], ControllerKey,
+ PeripheralTypes_U[PeripheralType], PeripheralKey);
+ return STATUS_OBJECT_PATH_INVALID;
+ }
+
+#if 0
+ if (AdapterType == SignatureAdapter && PeripheralKey != 0)
+ {
+ DPRINT1("%S(%lu) adapter with %S(%lu non-zero), ignored!\n",
+ AdapterTypes_U[AdapterType], AdapterKey,
+ PeripheralTypes_U[PeripheralType], PeripheralKey);
+ PeripheralKey = 0;
+ }
+#endif
+
+ /* Check for the optional 'partition' specifier */
+ q = ArcGetNextTokenU(p, &Token, &PartitionNumber);
+ if (q && _wcsicmp(Token.Buffer, L"partition") == 0)
+ {
+ /* We've got a partition! */
+ p = q;
+ }
+ else
+ {
+ /*
+ * Either no other ARC token was found, or we've got something else
+ * (possibly invalid or not)...
+ */
+ PartitionNumber = 0;
+ }
+
+ // TODO: Check the partition number in case of fdisks and cdroms??
+
+Quit:
+ /* Return the results */
+ *ArcNamePath = p;
+ *pAdapterKey = AdapterKey;
+ *pControllerKey = ControllerKey;
+ *pPeripheralKey = PeripheralKey;
+ *pPartitionNumber = PartitionNumber;
+ *pAdapterType = AdapterType;
+ *pControllerType = ControllerType;
+ *pPeripheralType = PeripheralType;
+ *pUseSignature = UseSignature;
+
+ return STATUS_SUCCESS;
+}
+
+/*
* ArcName:
* ARC name (counted string) to be resolved into a NT device name.
* The caller should have already delimited it from within an ARC path
@@ -434,12 +646,12 @@
/*
* ArcNamePath:
- * In input, pointer to an ARC path (NULL-terminated) starting by an ARC name
- * to be resolved into a NT device name.
- * In opposition to ResolveArcNameNtSymLink(), the caller does not have to
- * delimit the ARC name from within an ARC path. The real ARC name is deduced
- * after parsing the ARC path, and, in output, ArcNamePath points to the
- * beginning of the path after the ARC name part.
+ * In input, pointer to an ARC path (NULL-terminated) starting by an
+ * ARC name to be resolved into a NT device name.
+ * In opposition to ResolveArcNameNtSymLink(), the caller does not have
+ * to delimit the ARC name from within an ARC path. The real ARC name is
+ * deduced after parsing the ARC path, and, in output, ArcNamePath points
+ * to the beginning of the path after the ARC name part.
*
* NtName:
* Receives the resolved NT name. The buffer is NULL-terminated.
@@ -452,12 +664,10 @@
ResolveArcNameManually(
OUT PUNICODE_STRING NtName,
IN OUT PCWSTR* ArcNamePath,
- IN PPARTLIST PartList OPTIONAL)
-{
+ IN PPARTLIST PartList)
+{
+ NTSTATUS Status;
HRESULT hr;
- WCHAR TokenBuffer[50];
- UNICODE_STRING Token;
- PCWSTR p, q;
ULONG AdapterKey;
ULONG ControllerKey;
ULONG PeripheralKey;
@@ -465,7 +675,7 @@
ADAPTER_TYPE AdapterType;
CONTROLLER_TYPE ControllerType;
PERIPHERAL_TYPE PeripheralType;
- BOOLEAN UseSignature = FALSE;
+ BOOLEAN UseSignature;
PDISKENTRY DiskEntry;
PPARTENTRY PartEntry = NULL;
@@ -478,176 +688,34 @@
NtName->Length = 0;
#endif
- /*
- * The format of ArcName is:
- * adapter(www)[controller(xxx)peripheral(yyy)[partition(zzz)][filepath]] ,
- * where the [filepath] part is not being parsed.
- */
-
- RtlInitEmptyUnicodeString(&Token, TokenBuffer, sizeof(TokenBuffer));
-
- p = *ArcNamePath;
-
- /* Retrieve the adapter */
- p = ArcGetNextTokenU(p, &Token, &AdapterKey);
- if (!p)
- {
- DPRINT1("No adapter specified!\n");
- return STATUS_OBJECT_PATH_SYNTAX_BAD;
- }
-
- /* Check for the 'signature()' pseudo-adapter, introduced in Windows 2000 */
- if (_wcsicmp(Token.Buffer, L"signature") == 0)
- {
- /*
- * We've got a signature! Remember this for later, and set the adapter type
to SCSI.
- * We however check that the rest of the ARC path is valid by parsing the other
tokens.
- * AdapterKey stores the disk signature value (that holds in a ULONG).
- */
- UseSignature = TRUE;
- AdapterType = ScsiAdapter;
+ /* Parse the ARC path */
+ Status = ParseArcName(ArcNamePath,
+ &AdapterKey,
+ &ControllerKey,
+ &PeripheralKey,
+ &PartitionNumber,
+ &AdapterType,
+ &ControllerType,
+ &PeripheralType,
+ &UseSignature);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ // TODO: Check the partition number in case of fdisks and cdroms??
+
+ /* Check for adapters that don't take any extra controller or peripheral nodes
*/
+ if (AdapterType == NetAdapter || AdapterType == RamdiskAdapter)
+ {
+ if (AdapterType == NetAdapter)
+ {
+ DPRINT1("%S(%lu) path is not supported!\n",
AdapterTypes_U[AdapterType], AdapterKey);
+ return STATUS_NOT_SUPPORTED;
+ }
+
+ hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
+ L"\\Device\\Ramdisk%lu", AdapterKey);
}
else
- {
- /* Check for regular adapters */
- AdapterType =
(ADAPTER_TYPE)/*ArcMatchTokenU*/ArcMatchToken_UStr(/*Token.Buffer*/&Token,
AdapterTypes_U);
- if (AdapterType >= AdapterTypeMax)
- {
- DPRINT1("Invalid adapter type %wZ\n", &Token);
- return STATUS_OBJECT_NAME_INVALID;
- }
-
- /* Check for adapters that don't take any extra controller or peripheral
nodes */
- if (AdapterType == NetAdapter || AdapterType == RamdiskAdapter)
- {
- // if (*p)
- // return STATUS_OBJECT_PATH_SYNTAX_BAD;
-
- if (AdapterType == NetAdapter)
- {
- DPRINT1("%S(%lu) path is not supported!\n",
AdapterTypes_U[AdapterType], AdapterKey);
- return STATUS_NOT_SUPPORTED;
- }
-
- hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
- L"\\Device\\Ramdisk%lu", AdapterKey);
- goto Quit;
- }
- }
-
- /* Here, we have either an 'eisa', a 'scsi/signature', or a
'multi' adapter */
-
- /* Check for a valid controller */
- p = ArcGetNextTokenU(p, &Token, &ControllerKey);
- if (!p)
- {
- DPRINT1("%S(%lu) adapter doesn't have a controller!\n",
AdapterTypes_U[AdapterType], AdapterKey);
- return STATUS_OBJECT_PATH_SYNTAX_BAD;
- }
- ControllerType =
(CONTROLLER_TYPE)/*ArcMatchTokenU*/ArcMatchToken_UStr(/*Token.Buffer*/&Token,
ControllerTypes_U);
- if (ControllerType >= ControllerTypeMax)
- {
- DPRINT1("Invalid controller type %wZ\n", &Token);
- return STATUS_OBJECT_NAME_INVALID;
- }
-
- /* Here the controller can only be either a disk or a CDROM */
-
- /*
- * Ignore the controller in case we have a 'multi' adapter.
- * I guess a similar condition holds for the 'eisa' adapter too...
- *
- * For SignatureAdapter, as similar for ScsiAdapter, the controller key corresponds
- * to the disk target ID. Note that actually, the implementation just ignores the
- * target ID, as well as the LUN, and just loops over all the available disks and
- * searches for the one having the correct signature.
- */
- if ((AdapterType == MultiAdapter /* || AdapterType == EisaAdapter */) &&
ControllerKey != 0)
- {
- DPRINT1("%S(%lu) adapter with %S(%lu non-zero), ignored!\n",
- AdapterTypes_U[AdapterType], AdapterKey,
- ControllerTypes_U[ControllerType], ControllerKey);
- ControllerKey = 0;
- }
-
- /*
- * Only the 'scsi' adapter supports a direct 'cdrom' controller.
- * For the others, we need a 'disk' controller to which a 'cdrom'
peripheral can talk to.
- */
- if ((AdapterType != ScsiAdapter) && (ControllerType == CdRomController))
- {
- DPRINT1("%S(%lu) adapter cannot have a CDROM controller!\n",
AdapterTypes_U[AdapterType], AdapterKey);
- return STATUS_OBJECT_PATH_INVALID;
- }
-
- /* Check for a valid peripheral */
- p = ArcGetNextTokenU(p, &Token, &PeripheralKey);
- if (!p)
- {
- DPRINT1("%S(%lu)%S(%lu) adapter-controller doesn't have a
peripheral!\n",
- AdapterTypes_U[AdapterType], AdapterKey,
- ControllerTypes_U[ControllerType], ControllerKey);
- return STATUS_OBJECT_PATH_SYNTAX_BAD;
- }
- PeripheralType =
(PERIPHERAL_TYPE)/*ArcMatchTokenU*/ArcMatchToken_UStr(/*Token.Buffer*/&Token,
PeripheralTypes_U);
- if (PeripheralType >= PeripheralTypeMax)
- {
- DPRINT1("Invalid peripheral type %wZ\n", &Token);
- return STATUS_OBJECT_NAME_INVALID;
- }
-
- /*
- * If we had a 'cdrom' controller already, the corresponding peripheral can
only be 'fdisk'
- * (see for example the ARC syntax for SCSI CD-ROMs: scsi(x)cdrom(y)fdisk(z) where z
== 0).
- */
- if ((ControllerType == CdRomController) && (PeripheralType !=
FDiskPeripheral))
- {
- DPRINT1("%S(%lu) controller cannot have a %S(%lu) peripheral! (note that we
haven't check whether the adapter was SCSI or not)\n",
- ControllerTypes_U[ControllerType], ControllerKey,
- PeripheralTypes_U[PeripheralType], PeripheralKey);
- return STATUS_OBJECT_PATH_INVALID;
- }
-
- /* For a 'scsi' adapter, the possible peripherals are only 'rdisk' or
'fdisk' */
- if (AdapterType == ScsiAdapter && !(PeripheralType == RDiskPeripheral ||
PeripheralType == FDiskPeripheral))
- {
- DPRINT1("%S(%lu)%S(%lu) SCSI adapter-controller has an invalid peripheral
%S(%lu) !\n",
- AdapterTypes_U[AdapterType], AdapterKey,
- ControllerTypes_U[ControllerType], ControllerKey,
- PeripheralTypes_U[PeripheralType], PeripheralKey);
- return STATUS_OBJECT_PATH_INVALID;
- }
-
-#if 0
- if (AdapterType == SignatureAdapter && PeripheralKey != 0)
- {
- DPRINT1("%S(%lu) adapter with %S(%lu non-zero), ignored!\n",
- AdapterTypes_U[AdapterType], AdapterKey,
- PeripheralTypes_U[PeripheralType], PeripheralKey);
- PeripheralKey = 0;
- }
-#endif
-
- /* Check for the optional 'partition' specifier */
- q = ArcGetNextTokenU(p, &Token, &PartitionNumber);
- if (q && _wcsicmp(Token.Buffer, L"partition") == 0)
- {
- /* We've got a partition! */
- p = q;
- }
- else
- {
- /*
- * Either no other ARC token was found, or we've got something else
- * (possibly invalid or not)...
- */
- PartitionNumber = 0;
- }
-
-
- // TODO: Check the partition number in case of fdisks and cdroms??
-
-
if (ControllerType == CdRomController) // and so, AdapterType == ScsiAdapter and
PeripheralType == FDiskPeripheral
{
hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
@@ -718,7 +786,6 @@
return (NTSTATUS)hr;
}
- *ArcNamePath = p;
return STATUS_SUCCESS;
}