ReactOS 0.4.15-dev-5666-gc548b97
arcname.c File Reference
#include "precomp.h"
#include "filesup.h"
#include "partlist.h"
#include "arcname.h"
#include <debug.h>
Include dependency graph for arcname.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Typedefs

typedef enum _ADAPTER_TYPE ADAPTER_TYPE
 
typedef enum _ADAPTER_TYPEPADAPTER_TYPE
 
typedef enum _CONTROLLER_TYPE CONTROLLER_TYPE
 
typedef enum _CONTROLLER_TYPEPCONTROLLER_TYPE
 
typedef enum _PERIPHERAL_TYPE PERIPHERAL_TYPE
 
typedef enum _PERIPHERAL_TYPEPPERIPHERAL_TYPE
 

Enumerations

enum  _ADAPTER_TYPE {
  EisaAdapter , ScsiAdapter , MultiAdapter , NetAdapter ,
  RamdiskAdapter , AdapterTypeMax
}
 
enum  _CONTROLLER_TYPE { DiskController , CdRomController , ControllerTypeMax }
 
enum  _PERIPHERAL_TYPE { RDiskPeripheral , FDiskPeripheral , CdRomPeripheral , PeripheralTypeMax }
 

Functions

PCSTR ArcGetNextTokenA (IN PCSTR ArcPath, OUT PANSI_STRING TokenSpecifier, OUT PULONG Key)
 
static PCWSTR ArcGetNextTokenU (IN PCWSTR ArcPath, OUT PUNICODE_STRING TokenSpecifier, OUT PULONG Key)
 
ULONG ArcMatchTokenA (IN PCSTR CandidateToken, IN const PCSTR *TokenTable)
 
ULONG ArcMatchTokenU (IN PCWSTR CandidateToken, IN const PCWSTR *TokenTable)
 
static ULONG ArcMatchToken_UStr (IN PCUNICODE_STRING CandidateToken, IN const PCWSTR *TokenTable)
 
BOOLEAN ArcPathNormalize (OUT PUNICODE_STRING NormalizedArcPath, IN PCWSTR ArcPath)
 
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)
 
static NTSTATUS ResolveArcNameNtSymLink (OUT PUNICODE_STRING NtName, IN PUNICODE_STRING ArcName)
 
static NTSTATUS ResolveArcNameManually (OUT PUNICODE_STRING NtName, IN OUT PCWSTR *ArcNamePath, IN PPARTLIST PartList)
 
BOOLEAN ArcPathToNtPath (OUT PUNICODE_STRING NtPath, IN PCWSTR ArcPath, IN PPARTLIST PartList OPTIONAL)
 

Variables

const PCSTR AdapterTypes_A []
 
const PCWSTR AdapterTypes_U []
 
const PCSTR ControllerTypes_A []
 
const PCWSTR ControllerTypes_U []
 
const PCSTR PeripheralTypes_A []
 
const PCWSTR PeripheralTypes_U []
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 30 of file arcname.c.

Typedef Documentation

◆ ADAPTER_TYPE

◆ CONTROLLER_TYPE

◆ PADAPTER_TYPE

◆ PCONTROLLER_TYPE

◆ PERIPHERAL_TYPE

◆ PPERIPHERAL_TYPE

Enumeration Type Documentation

◆ _ADAPTER_TYPE

Enumerator
EisaAdapter 
ScsiAdapter 
MultiAdapter 
NetAdapter 
RamdiskAdapter 
AdapterTypeMax 

Definition at line 37 of file arcname.c.

38{
enum _ADAPTER_TYPE ADAPTER_TYPE
@ AdapterTypeMax
Definition: arcname.c:44
@ RamdiskAdapter
Definition: arcname.c:43
@ ScsiAdapter
Definition: arcname.c:40
@ EisaAdapter
Definition: arcname.c:39
@ MultiAdapter
Definition: arcname.c:41
@ NetAdapter
Definition: arcname.c:42
enum _ADAPTER_TYPE * PADAPTER_TYPE

◆ _CONTROLLER_TYPE

Enumerator
DiskController 
CdRomController 
ControllerTypeMax 

Definition at line 66 of file arcname.c.

67{
enum _CONTROLLER_TYPE CONTROLLER_TYPE
enum _CONTROLLER_TYPE * PCONTROLLER_TYPE
@ CdRomController
Definition: arcname.c:69
@ ControllerTypeMax
Definition: arcname.c:70
@ DiskController
Definition: arcname.c:68

◆ _PERIPHERAL_TYPE

Enumerator
RDiskPeripheral 
FDiskPeripheral 
CdRomPeripheral 
PeripheralTypeMax 

Definition at line 86 of file arcname.c.

87{
88// VDiskPeripheral,
@ PeripheralTypeMax
Definition: arcname.c:92
@ RDiskPeripheral
Definition: arcname.c:89
@ FDiskPeripheral
Definition: arcname.c:90
@ CdRomPeripheral
Definition: arcname.c:91
enum _PERIPHERAL_TYPE PERIPHERAL_TYPE
enum _PERIPHERAL_TYPE * PPERIPHERAL_TYPE

Function Documentation

◆ ArcGetNextTokenA()

PCSTR ArcGetNextTokenA ( IN PCSTR  ArcPath,
OUT PANSI_STRING  TokenSpecifier,
OUT PULONG  Key 
)

Definition at line 115 of file arcname.c.

119{
121 PCSTR p = ArcPath;
122 SIZE_T SpecifierLength;
123 ULONG KeyValue;
124
125 /*
126 * We must have a valid "specifier(key)" string, where 'specifier'
127 * cannot be the empty string, and is followed by '('.
128 */
129 p = strchr(p, '(');
130 if (p == NULL)
131 return NULL; /* No '(' found */
132 if (p == ArcPath)
133 return NULL; /* Path starts with '(' and is thus invalid */
134
135 SpecifierLength = (p - ArcPath) * sizeof(CHAR);
136 if (SpecifierLength > MAXUSHORT)
137 {
138 return NULL;
139 }
140
141 /*
142 * The strtoul function skips any leading whitespace.
143 *
144 * Note that if the token is "specifier()" then strtoul won't perform
145 * any conversion and return 0, therefore effectively making the token
146 * equivalent to "specifier(0)", as it should be.
147 */
148 // KeyValue = atoi(p);
149 KeyValue = strtoul(p, (PSTR*)&p, 10);
150
151 /* Skip any trailing whitespace */
152 while (isspace(*p)) ++p;
153
154 /* The token must terminate with ')' */
155 if (*p != ')')
156 return NULL;
157#if 0
158 p = strchr(p, ')');
159 if (p == NULL)
160 return NULL;
161#endif
162
163 /* We should have succeeded, copy the token specifier in the buffer */
164 Status = RtlStringCbCopyNA(TokenSpecifier->Buffer,
165 TokenSpecifier->MaximumLength,
166 ArcPath, SpecifierLength);
167 if (!NT_SUCCESS(Status))
168 return NULL;
169
170 TokenSpecifier->Length = (USHORT)SpecifierLength;
171
172 /* We succeeded, return the token key value */
173 *Key = KeyValue;
174
175 /* Next token starts just after */
176 return ++p;
177}
#define isspace(c)
Definition: acclib.h:69
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
char * strchr(const char *String, int ch)
Definition: utclib.c:501
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
Status
Definition: gdiplustypes.h:25
GLfloat GLfloat p
Definition: glext.h:8902
signed char * PSTR
Definition: retypes.h:7
unsigned int ULONG
Definition: retypes.h:1
NTSTRSAFEAPI RtlStringCbCopyNA(_Out_writes_bytes_(cbDest) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_reads_bytes_(cbToCopy) STRSAFE_LPCSTR pszSrc, _In_ size_t cbToCopy)
Definition: ntstrsafe.h:395
unsigned short USHORT
Definition: pedump.c:61
ULONG_PTR SIZE_T
Definition: typedefs.h:80
const char * PCSTR
Definition: typedefs.h:52
#define MAXUSHORT
Definition: typedefs.h:83
char CHAR
Definition: xmlstorage.h:175

◆ ArcGetNextTokenU()

static PCWSTR ArcGetNextTokenU ( IN PCWSTR  ArcPath,
OUT PUNICODE_STRING  TokenSpecifier,
OUT PULONG  Key 
)
static

Definition at line 180 of file arcname.c.

184{
186 PCWSTR p = ArcPath;
187 SIZE_T SpecifierLength;
188 ULONG KeyValue;
189
190 /*
191 * We must have a valid "specifier(key)" string, where 'specifier'
192 * cannot be the empty string, and is followed by '('.
193 */
194 p = wcschr(p, L'(');
195 if (p == NULL)
196 return NULL; /* No '(' found */
197 if (p == ArcPath)
198 return NULL; /* Path starts with '(' and is thus invalid */
199
200 SpecifierLength = (p - ArcPath) * sizeof(WCHAR);
201 if (SpecifierLength > UNICODE_STRING_MAX_BYTES)
202 {
203 return NULL;
204 }
205
206 ++p;
207
208 /*
209 * The strtoul function skips any leading whitespace.
210 *
211 * Note that if the token is "specifier()" then strtoul won't perform
212 * any conversion and return 0, therefore effectively making the token
213 * equivalent to "specifier(0)", as it should be.
214 */
215 // KeyValue = _wtoi(p);
216 KeyValue = wcstoul(p, (PWSTR*)&p, 10);
217
218 /* Skip any trailing whitespace */
219 while (iswspace(*p)) ++p;
220
221 /* The token must terminate with ')' */
222 if (*p != L')')
223 return NULL;
224#if 0
225 p = wcschr(p, L')');
226 if (p == NULL)
227 return NULL;
228#endif
229
230 /* We should have succeeded, copy the token specifier in the buffer */
231 Status = RtlStringCbCopyNW(TokenSpecifier->Buffer,
232 TokenSpecifier->MaximumLength,
233 ArcPath, SpecifierLength);
234 if (!NT_SUCCESS(Status))
235 return NULL;
236
237 TokenSpecifier->Length = (USHORT)SpecifierLength;
238
239 /* We succeeded, return the token key value */
240 *Key = KeyValue;
241
242 /* Next token starts just after */
243 return ++p;
244}
#define wcschr
Definition: compat.h:17
#define iswspace(_c)
Definition: ctype.h:669
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define UNICODE_STRING_MAX_BYTES
NTSTRSAFEAPI RtlStringCbCopyNW(_Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc, _In_ size_t cbToCopy)
Definition: ntstrsafe.h:416
#define L(x)
Definition: ntvdm.h:50
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ParseArcName().

◆ ArcMatchToken_UStr()

static ULONG ArcMatchToken_UStr ( IN PCUNICODE_STRING  CandidateToken,
IN const PCWSTR TokenTable 
)
static

Definition at line 278 of file arcname.c.

281{
282 ULONG Index = 0;
283#if 0
285#else
287#endif
288
289 while (TokenTable[Index])
290 {
291#if 0
292 Length = wcslen(TokenTable[Index]);
293 if ((Length == CandidateToken->Length / sizeof(WCHAR)) &&
294 (_wcsnicmp(CandidateToken->Buffer, TokenTable[Index], Length) == 0))
295 {
296 break;
297 }
298#else
299 RtlInitUnicodeString(&Token, TokenTable[Index]);
300 if (RtlEqualUnicodeString(CandidateToken, &Token, TRUE))
301 break;
302#endif
303
304 ++Index;
305 }
306
307 return Index;
308}
#define TRUE
Definition: types.h:120
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by ParseArcName().

◆ ArcMatchTokenA()

ULONG ArcMatchTokenA ( IN PCSTR  CandidateToken,
IN const PCSTR TokenTable 
)

Definition at line 248 of file arcname.c.

251{
252 ULONG Index = 0;
253
254 while (TokenTable[Index] && _stricmp(CandidateToken, TokenTable[Index]) != 0)
255 {
256 ++Index;
257 }
258
259 return Index;
260}
#define _stricmp
Definition: cat.c:22

◆ ArcMatchTokenU()

ULONG ArcMatchTokenU ( IN PCWSTR  CandidateToken,
IN const PCWSTR TokenTable 
)

Definition at line 263 of file arcname.c.

266{
267 ULONG Index = 0;
268
269 while (TokenTable[Index] && _wcsicmp(CandidateToken, TokenTable[Index]) != 0)
270 {
271 ++Index;
272 }
273
274 return Index;
275}
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)

◆ ArcPathNormalize()

BOOLEAN ArcPathNormalize ( OUT PUNICODE_STRING  NormalizedArcPath,
IN PCWSTR  ArcPath 
)

Definition at line 312 of file arcname.c.

315{
317 PCWSTR EndOfArcName;
318 PCWSTR p;
320
321 if (NormalizedArcPath->MaximumLength < sizeof(UNICODE_NULL))
322 return FALSE;
323
324 *NormalizedArcPath->Buffer = UNICODE_NULL;
325 NormalizedArcPath->Length = 0;
326
327 EndOfArcName = wcschr(ArcPath, OBJ_NAME_PATH_SEPARATOR);
328 if (!EndOfArcName)
329 EndOfArcName = ArcPath + wcslen(ArcPath);
330
331 while ((p = wcsstr(ArcPath, L"()")) && (p < EndOfArcName))
332 {
333#if 0
334 Status = RtlStringCbCopyNW(NormalizedArcPath->Buffer,
335 NormalizedArcPath->MaximumLength,
336 ArcPath, (p - ArcPath) * sizeof(WCHAR));
337#else
338 Status = RtlStringCbCatNW(NormalizedArcPath->Buffer,
339 NormalizedArcPath->MaximumLength,
340 ArcPath, (p - ArcPath) * sizeof(WCHAR));
341#endif
342 if (!NT_SUCCESS(Status))
343 return FALSE;
344
345 Status = RtlStringCbCatW(NormalizedArcPath->Buffer,
346 NormalizedArcPath->MaximumLength,
347 L"(0)");
348 if (!NT_SUCCESS(Status))
349 return FALSE;
350#if 0
351 NormalizedArcPath->Buffer += wcslen(NormalizedArcPath->Buffer);
352#endif
353 ArcPath = p + 2;
354 }
355
356 Status = RtlStringCbCatW(NormalizedArcPath->Buffer,
357 NormalizedArcPath->MaximumLength,
358 ArcPath);
359 if (!NT_SUCCESS(Status))
360 return FALSE;
361
362 PathLength = wcslen(NormalizedArcPath->Buffer);
364 {
365 return FALSE;
366 }
367
368 NormalizedArcPath->Length = (USHORT)PathLength * sizeof(WCHAR);
369 return TRUE;
370}
static USHORT PathLength
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define FALSE
Definition: types.h:117
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
#define UNICODE_NULL
#define UNICODE_STRING_MAX_CHARS
NTSTRSAFEAPI RtlStringCbCatW(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:636
NTSTRSAFEAPI RtlStringCbCatNW(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_reads_bytes_(cbToAppend) STRSAFE_LPCWSTR pszSrc, _In_ size_t cbToAppend)
Definition: ntstrsafe.h:832

Referenced by _tmain().

◆ ArcPathToNtPath()

BOOLEAN ArcPathToNtPath ( OUT PUNICODE_STRING  NtPath,
IN PCWSTR  ArcPath,
IN PPARTLIST PartList  OPTIONAL 
)

Definition at line 819 of file arcname.c.

823{
825 PCWSTR BeginOfPath;
826 UNICODE_STRING ArcName;
828
829 /* TODO: We should "normalize" the path, i.e. expand all the xxx() into xxx(0) */
830
831 if (NtPath->MaximumLength < sizeof(UNICODE_NULL))
832 return FALSE;
833
834 *NtPath->Buffer = UNICODE_NULL;
835 NtPath->Length = 0;
836
837 /*
838 * - First, check whether the ARC path is already inside \\ArcName
839 * and if so, map it to the corresponding NT path.
840 * - Only then, if we haven't found any ArcName, try to build a
841 * NT path by deconstructing the ARC path, using its disk and
842 * partition numbers. We may use here our disk/partition list.
843 *
844 * See also freeldr/arcname.c
845 *
846 * Note that it would be nice to maintain a cache of these mappings.
847 */
848
849 /*
850 * Initialize the ARC name to resolve, by cutting the ARC path at the first
851 * NT path separator. The ARC name therefore ends where the NT path part starts.
852 */
853 RtlInitUnicodeString(&ArcName, ArcPath);
854 BeginOfPath = wcschr(ArcName.Buffer, OBJ_NAME_PATH_SEPARATOR);
855 if (BeginOfPath)
856 ArcName.Length = (ULONG_PTR)BeginOfPath - (ULONG_PTR)ArcName.Buffer;
857
858 /* Resolve the ARC name via NT SymLinks. Note that NtPath is returned NULL-terminated. */
859 Status = ResolveArcNameNtSymLink(NtPath, &ArcName);
860 if (!NT_SUCCESS(Status))
861 {
862 /* We failed, attempt a manual resolution */
863 DPRINT1("ResolveArcNameNtSymLink(ArcName = '%wZ') for ArcPath = '%S' failed, Status 0x%08lx\n", &ArcName, ArcPath, Status);
864
865 /*
866 * We failed at directly resolving the ARC path, and we cannot perform
867 * a manual resolution because we don't have any disk/partition list,
868 * we therefore fail here.
869 */
870 if (!PartList)
871 {
872 DPRINT1("PartList == NULL, cannot perform a manual resolution\n");
873 return FALSE;
874 }
875
876 *NtPath->Buffer = UNICODE_NULL;
877 NtPath->Length = 0;
878
879 BeginOfPath = ArcPath;
880 Status = ResolveArcNameManually(NtPath, &BeginOfPath, PartList);
881 if (!NT_SUCCESS(Status))
882 {
883 /* We really failed this time, bail out */
884 DPRINT1("ResolveArcNameManually(ArcPath = '%S') failed, Status 0x%08lx\n", ArcPath, Status);
885 return FALSE;
886 }
887 }
888
889 /*
890 * We succeeded. Concatenate the rest of the system-specific path. We know the path is going
891 * to be inside the NT namespace, therefore we can use the path string concatenation function
892 * that uses '\\' as the path separator.
893 */
894 if (BeginOfPath && *BeginOfPath)
895 {
896 Status = ConcatPaths(NtPath->Buffer, NtPath->MaximumLength / sizeof(WCHAR), 1, BeginOfPath);
897 if (!NT_SUCCESS(Status))
898 {
899 /* Buffer not large enough, or whatever...: just bail out */
900 return FALSE;
901 }
902 }
903
904 PathLength = wcslen(NtPath->Buffer);
906 {
907 return FALSE;
908 }
909
910 NtPath->Length = (USHORT)PathLength * sizeof(WCHAR);
911
912 return TRUE;
913}
#define DPRINT1
Definition: precomp.h:8
static NTSTATUS ResolveArcNameManually(OUT PUNICODE_STRING NtName, IN OUT PCWSTR *ArcNamePath, IN PPARTLIST PartList)
Definition: arcname.c:689
static NTSTATUS ResolveArcNameNtSymLink(OUT PUNICODE_STRING NtName, IN PUNICODE_STRING ArcName)
Definition: arcname.c:599
#define ULONG_PTR
Definition: config.h:101
NTSTATUS ConcatPaths(IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:659
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by _tmain(), and EnumerateInstallations().

◆ ParseArcName()

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 
)
static

Definition at line 381 of file arcname.c.

391{
392 // NTSTATUS Status;
393 WCHAR TokenBuffer[50];
395 PCWSTR p, q;
396 ULONG AdapterKey = 0;
397 ULONG ControllerKey = 0;
398 ULONG PeripheralKey = 0;
401 CONTROLLER_TYPE ControllerType = ControllerTypeMax;
402 PERIPHERAL_TYPE PeripheralType = PeripheralTypeMax;
403 BOOLEAN UseSignature = FALSE;
404
405 /*
406 * The format of ArcName is:
407 * adapter(www)[controller(xxx)peripheral(yyy)[partition(zzz)][filepath]] ,
408 * where the [filepath] part is not being parsed.
409 */
410
411 RtlInitEmptyUnicodeString(&Token, TokenBuffer, sizeof(TokenBuffer));
412
413 p = *ArcNamePath;
414
415 /* Retrieve the adapter */
416 p = ArcGetNextTokenU(p, &Token, &AdapterKey);
417 if (!p)
418 {
419 DPRINT1("No adapter specified!\n");
421 }
422
423 /* Check for the 'signature()' pseudo-adapter, introduced in Windows 2000 */
424 if (_wcsicmp(Token.Buffer, L"signature") == 0)
425 {
426 /*
427 * We've got a signature! Remember this for later, and set the adapter type to SCSI.
428 * We however check that the rest of the ARC path is valid by parsing the other tokens.
429 * AdapterKey stores the disk signature value (that holds in a ULONG).
430 */
431 UseSignature = TRUE;
433 }
434 else
435 {
436 /* Check for regular adapters */
437 // ArcMatchTokenU(Token.Buffer, AdapterTypes_U);
440 {
441 DPRINT1("Invalid adapter type %wZ\n", &Token);
443 }
444
445 /* Check for adapters that don't take any extra controller or peripheral nodes */
447 {
448 // if (*p)
449 // return STATUS_OBJECT_PATH_SYNTAX_BAD;
450
451 if (AdapterType == NetAdapter)
452 {
453 DPRINT1("%S(%lu) path is not supported!\n", AdapterTypes_U[AdapterType], AdapterKey);
455 }
456
457 goto Quit;
458 }
459 }
460
461 /* Here, we have either an 'eisa', a 'scsi/signature', or a 'multi' adapter */
462
463 /* Check for a valid controller */
464 p = ArcGetNextTokenU(p, &Token, &ControllerKey);
465 if (!p)
466 {
467 DPRINT1("%S(%lu) adapter doesn't have a controller!\n", AdapterTypes_U[AdapterType], AdapterKey);
469 }
470 // ArcMatchTokenU(Token.Buffer, ControllerTypes_U);
472 if (ControllerType >= ControllerTypeMax)
473 {
474 DPRINT1("Invalid controller type %wZ\n", &Token);
476 }
477
478 /* Here the controller can only be either a disk or a CDROM */
479
480 /*
481 * Ignore the controller in case we have a 'multi' adapter.
482 * I guess a similar condition holds for the 'eisa' adapter too...
483 *
484 * For SignatureAdapter, as similar for ScsiAdapter, the controller key corresponds
485 * to the disk target ID. Note that actually, the implementation just ignores the
486 * target ID, as well as the LUN, and just loops over all the available disks and
487 * searches for the one having the correct signature.
488 */
489 if ((AdapterType == MultiAdapter /* || AdapterType == EisaAdapter */) && ControllerKey != 0)
490 {
491 DPRINT1("%S(%lu) adapter with %S(%lu non-zero), ignored!\n",
492 AdapterTypes_U[AdapterType], AdapterKey,
493 ControllerTypes_U[ControllerType], ControllerKey);
494 ControllerKey = 0;
495 }
496
497 /*
498 * Only the 'scsi' adapter supports a direct 'cdrom' controller.
499 * For the others, we need a 'disk' controller to which a 'cdrom' peripheral can talk to.
500 */
501 if ((AdapterType != ScsiAdapter) && (ControllerType == CdRomController))
502 {
503 DPRINT1("%S(%lu) adapter cannot have a CDROM controller!\n", AdapterTypes_U[AdapterType], AdapterKey);
505 }
506
507 /* Check for a valid peripheral */
508 p = ArcGetNextTokenU(p, &Token, &PeripheralKey);
509 if (!p)
510 {
511 DPRINT1("%S(%lu)%S(%lu) adapter-controller doesn't have a peripheral!\n",
512 AdapterTypes_U[AdapterType], AdapterKey,
513 ControllerTypes_U[ControllerType], ControllerKey);
515 }
516 // ArcMatchTokenU(Token.Buffer, PeripheralTypes_U);
518 if (PeripheralType >= PeripheralTypeMax)
519 {
520 DPRINT1("Invalid peripheral type %wZ\n", &Token);
522 }
523
524 /*
525 * If we had a 'cdrom' controller already, the corresponding peripheral can only be 'fdisk'
526 * (see for example the ARC syntax for SCSI CD-ROMs: scsi(x)cdrom(y)fdisk(z) where z == 0).
527 */
528 if ((ControllerType == CdRomController) && (PeripheralType != FDiskPeripheral))
529 {
530 DPRINT1("%S(%lu) controller cannot have a %S(%lu) peripheral! (note that we haven't check whether the adapter was SCSI or not)\n",
531 ControllerTypes_U[ControllerType], ControllerKey,
532 PeripheralTypes_U[PeripheralType], PeripheralKey);
534 }
535
536 /* For a 'scsi' adapter, the possible peripherals are only 'rdisk' or 'fdisk' */
537 if (AdapterType == ScsiAdapter && !(PeripheralType == RDiskPeripheral || PeripheralType == FDiskPeripheral))
538 {
539 DPRINT1("%S(%lu)%S(%lu) SCSI adapter-controller has an invalid peripheral %S(%lu) !\n",
540 AdapterTypes_U[AdapterType], AdapterKey,
541 ControllerTypes_U[ControllerType], ControllerKey,
542 PeripheralTypes_U[PeripheralType], PeripheralKey);
544 }
545
546#if 0
547 if (AdapterType == SignatureAdapter && PeripheralKey != 0)
548 {
549 DPRINT1("%S(%lu) adapter with %S(%lu non-zero), ignored!\n",
550 AdapterTypes_U[AdapterType], AdapterKey,
551 PeripheralTypes_U[PeripheralType], PeripheralKey);
552 PeripheralKey = 0;
553 }
554#endif
555
556 /* Check for the optional 'partition' specifier */
558 if (q && _wcsicmp(Token.Buffer, L"partition") == 0)
559 {
560 /* We've got a partition! */
561 p = q;
562 }
563 else
564 {
565 /*
566 * Either no other ARC token was found, or we've got something else
567 * (possibly invalid or not)...
568 */
569 PartitionNumber = 0;
570 }
571
572 // TODO: Check the partition number in case of fdisks and cdroms??
573
574Quit:
575 /* Return the results */
576 *ArcNamePath = p;
577 *pAdapterKey = AdapterKey;
578 *pControllerKey = ControllerKey;
579 *pPeripheralKey = PeripheralKey;
580 *pPartitionNumber = PartitionNumber;
581 *pAdapterType = AdapterType;
582 *pControllerType = ControllerType;
583 *pPeripheralType = PeripheralType;
584 *pUseSignature = UseSignature;
585
586 return STATUS_SUCCESS;
587}
unsigned char BOOLEAN
static ULONG ArcMatchToken_UStr(IN PCUNICODE_STRING CandidateToken, IN const PCWSTR *TokenTable)
Definition: arcname.c:278
const PCWSTR PeripheralTypes_U[]
Definition: arcname.c:102
static PCWSTR ArcGetNextTokenU(IN PCWSTR ArcPath, OUT PUNICODE_STRING TokenSpecifier, OUT PULONG Key)
Definition: arcname.c:180
const PCWSTR AdapterTypes_U[]
Definition: arcname.c:55
const PCWSTR ControllerTypes_U[]
Definition: arcname.c:78
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:295
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:293
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
@ AdapterType
Definition: cmtypes.h:991
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2061

Referenced by ResolveArcNameManually().

◆ ResolveArcNameManually()

static NTSTATUS ResolveArcNameManually ( OUT PUNICODE_STRING  NtName,
IN OUT PCWSTR ArcNamePath,
IN PPARTLIST  PartList 
)
static

Definition at line 689 of file arcname.c.

693{
695 ULONG AdapterKey;
696 ULONG ControllerKey;
697 ULONG PeripheralKey;
700 CONTROLLER_TYPE ControllerType;
701 PERIPHERAL_TYPE PeripheralType;
702 BOOLEAN UseSignature;
703 SIZE_T NameLength;
704
705 PDISKENTRY DiskEntry;
706 PPARTENTRY PartEntry = NULL;
707
708 if (NtName->MaximumLength < sizeof(UNICODE_NULL))
710
711 /* Parse the ARC path */
712 Status = ParseArcName(ArcNamePath,
713 &AdapterKey,
714 &ControllerKey,
715 &PeripheralKey,
718 &ControllerType,
719 &PeripheralType,
720 &UseSignature);
721 if (!NT_SUCCESS(Status))
722 return Status;
723
724 // TODO: Check the partition number in case of fdisks and cdroms??
725
726 /* Check for adapters that don't take any extra controller or peripheral node */
728 {
729 if (AdapterType == NetAdapter)
730 {
731 DPRINT1("%S(%lu) path is not supported!\n", AdapterTypes_U[AdapterType], AdapterKey);
733 }
734
735 Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
736 L"\\Device\\Ramdisk%lu", AdapterKey);
737 }
738 else
739 if (ControllerType == CdRomController) // and so, AdapterType == ScsiAdapter and PeripheralType == FDiskPeripheral
740 {
741 Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
742 L"\\Device\\Scsi\\CdRom%lu", ControllerKey);
743 }
744 else
745 /* Now, ControllerType == DiskController */
746 if (PeripheralType == CdRomPeripheral)
747 {
748 Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
749 L"\\Device\\CdRom%lu", PeripheralKey);
750 }
751 else
752 if (PeripheralType == FDiskPeripheral)
753 {
754 Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
755 L"\\Device\\Floppy%lu", PeripheralKey);
756 }
757 else
758 if (PeripheralType == RDiskPeripheral)
759 {
760 if (UseSignature)
761 {
762 /* The disk signature is stored in AdapterKey */
763 DiskEntry = GetDiskBySignature(PartList, AdapterKey);
764 }
765 else
766 {
767 DiskEntry = GetDiskBySCSI(PartList, AdapterKey,
768 ControllerKey, PeripheralKey);
769 }
770 if (!DiskEntry)
771 return STATUS_OBJECT_PATH_NOT_FOUND; // STATUS_NOT_FOUND;
772
773 if (PartitionNumber != 0)
774 {
775 PartEntry = GetPartition(DiskEntry, PartitionNumber);
776 if (!PartEntry)
777 return STATUS_OBJECT_PATH_NOT_FOUND; // STATUS_DEVICE_NOT_PARTITIONED;
778 ASSERT(PartEntry->DiskEntry == DiskEntry);
779 }
780
781 Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
782 L"\\Device\\Harddisk%lu\\Partition%lu",
783 DiskEntry->DiskNumber, PartitionNumber);
784 }
785#if 0 // FIXME: Not implemented yet!
786 else
787 if (PeripheralType == VDiskPeripheral)
788 {
789 // TODO: Check how Win 7+ deals with virtual disks.
790 Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
791 L"\\Device\\VirtualHarddisk%lu\\Partition%lu",
792 PeripheralKey, PartitionNumber);
793 }
794#endif
795
796 if (!NT_SUCCESS(Status))
797 {
798 /* Returned NtName is invalid, so zero it out */
799 *NtName->Buffer = UNICODE_NULL;
800 NtName->Length = 0;
801
802 return Status;
803 }
804
805 /* Update NtName length */
806 NameLength = wcslen(NtName->Buffer);
807 if (NameLength > UNICODE_STRING_MAX_CHARS)
808 {
810 }
811
812 NtName->Length = (USHORT)NameLength * sizeof(WCHAR);
813
814 return STATUS_SUCCESS;
815}
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)
Definition: arcname.c:381
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
PPARTENTRY GetPartition(IN PDISKENTRY DiskEntry, IN ULONG PartitionNumber)
Definition: partlist.c:2096
PDISKENTRY GetDiskBySignature(IN PPARTLIST List, IN ULONG Signature)
Definition: partlist.c:2070
PDISKENTRY GetDiskBySCSI(IN PPARTLIST List, IN USHORT Port, IN USHORT Bus, IN USHORT Id)
Definition: partlist.c:2040
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
ULONG DiskNumber
Definition: partlist.h:111
struct _DISKENTRY * DiskEntry
Definition: partlist.h:46
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151

Referenced by ArcPathToNtPath().

◆ ResolveArcNameNtSymLink()

static NTSTATUS ResolveArcNameNtSymLink ( OUT PUNICODE_STRING  NtName,
IN PUNICODE_STRING  ArcName 
)
static

Definition at line 599 of file arcname.c.

602{
605 HANDLE DirectoryHandle, LinkHandle;
606 UNICODE_STRING ArcNameDir;
607
608 if (NtName->MaximumLength < sizeof(UNICODE_NULL))
610
611 /* Open the \ArcName object directory */
612 RtlInitUnicodeString(&ArcNameDir, L"\\ArcName");
614 &ArcNameDir,
616 NULL,
617 NULL);
621 if (!NT_SUCCESS(Status))
622 {
623 DPRINT1("NtOpenDirectoryObject(%wZ) failed, Status 0x%08lx\n", &ArcNameDir, Status);
624 return Status;
625 }
626
627 /* Open the ARC name link */
629 ArcName,
632 NULL);
633 Status = NtOpenSymbolicLinkObject(&LinkHandle,
636
637 /* Close the \ArcName object directory handle */
639
640 /* Check for success */
641 if (!NT_SUCCESS(Status))
642 {
643 DPRINT1("NtOpenSymbolicLinkObject(%wZ) failed, Status 0x%08lx\n", ArcName, Status);
644 return Status;
645 }
646
647 /* Reserve one WCHAR for the NULL-termination */
648 NtName->MaximumLength -= sizeof(UNICODE_NULL);
649
650 /* Resolve the link and close its handle */
651 Status = NtQuerySymbolicLinkObject(LinkHandle, NtName, NULL);
652 NtClose(LinkHandle);
653
654 /* Restore the NULL-termination */
655 NtName->MaximumLength += sizeof(UNICODE_NULL);
656
657 /* Check for success */
658 if (!NT_SUCCESS(Status))
659 {
660 /* We failed, don't touch NtName */
661 DPRINT1("NtQuerySymbolicLinkObject(%wZ) failed, Status 0x%08lx\n", ArcName, Status);
662 }
663 else
664 {
665 /* We succeeded, NULL-terminate NtName */
666 NtName->Buffer[NtName->Length / sizeof(WCHAR)] = UNICODE_NULL;
667 }
668
669 return Status;
670}
static HANDLE DirectoryHandle
Definition: ObType.c:48
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define SYMBOLIC_LINK_QUERY
Definition: nt_native.h:1265
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
NTSTATUS NTAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:393

Referenced by ArcPathToNtPath().

Variable Documentation

◆ AdapterTypes_A

const PCSTR AdapterTypes_A[]
Initial value:
=
{
"eisa",
"scsi",
"multi",
"net",
"ramdisk",
}

Definition at line 46 of file arcname.c.

◆ AdapterTypes_U

const PCWSTR AdapterTypes_U[]
Initial value:
=
{
L"eisa",
L"scsi",
L"multi",
L"net",
L"ramdisk",
}

Definition at line 55 of file arcname.c.

Referenced by ParseArcName(), and ResolveArcNameManually().

◆ ControllerTypes_A

const PCSTR ControllerTypes_A[]
Initial value:
=
{
"disk",
"cdrom",
}

Definition at line 72 of file arcname.c.

◆ ControllerTypes_U

const PCWSTR ControllerTypes_U[]
Initial value:
=
{
L"disk",
L"cdrom",
}

Definition at line 78 of file arcname.c.

Referenced by ParseArcName().

◆ PeripheralTypes_A

const PCSTR PeripheralTypes_A[]
Initial value:
=
{
"rdisk",
"fdisk",
"cdrom",
}

Definition at line 94 of file arcname.c.

◆ PeripheralTypes_U

const PCWSTR PeripheralTypes_U[]
Initial value:
=
{
L"rdisk",
L"fdisk",
L"cdrom",
}

Definition at line 102 of file arcname.c.

Referenced by ParseArcName().