ReactOS  0.4.11-dev-195-gef016bf
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)
 
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)
 
ULONG ArcMatchToken_UStr (IN PCUNICODE_STRING CandidateToken, IN const PCWSTR *TokenTable)
 
BOOLEAN ArcPathNormalize (OUT PUNICODE_STRING NormalizedArcPath, IN PCWSTR ArcPath)
 
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 OPTIONAL)
 
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

#define NDEBUG

Definition at line 30 of file arcname.c.

Typedef Documentation

Enumeration Type Documentation

Enumerator
EisaAdapter 
ScsiAdapter 
MultiAdapter 
NetAdapter 
RamdiskAdapter 
AdapterTypeMax 

Definition at line 35 of file arcname.c.

36 {
40  NetAdapter,
enum _ADAPTER_TYPE ADAPTER_TYPE
enum _ADAPTER_TYPE * PADAPTER_TYPE
Enumerator
DiskController 
CdRomController 
ControllerTypeMax 

Definition at line 64 of file arcname.c.

65 {
enum _CONTROLLER_TYPE * PCONTROLLER_TYPE
enum _CONTROLLER_TYPE CONTROLLER_TYPE
Enumerator
RDiskPeripheral 
FDiskPeripheral 
CdRomPeripheral 
PeripheralTypeMax 

Definition at line 84 of file arcname.c.

85 {
86 // VDiskPeripheral,
enum _PERIPHERAL_TYPE * PPERIPHERAL_TYPE
enum _PERIPHERAL_TYPE PERIPHERAL_TYPE

Function Documentation

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

Definition at line 113 of file arcname.c.

117 {
119  PCSTR p = ArcPath;
120  ULONG SpecifierLength;
121  ULONG KeyValue;
122 
123  /*
124  * We must have a valid "specifier(key)" string, where 'specifier'
125  * cannot be the empty string, and is followed by '('.
126  */
127  p = strchr(p, '(');
128  if (p == NULL)
129  return NULL; /* No '(' found */
130  if (p == ArcPath)
131  return NULL; /* Path starts with '(' and is thus invalid */
132 
133  SpecifierLength = (p - ArcPath) * sizeof(CHAR);
134 
135  /*
136  * The strtoul function skips any leading whitespace.
137  *
138  * Note that if the token is "specifier()" then strtoul won't perform
139  * any conversion and return 0, therefore effectively making the token
140  * equivalent to "specifier(0)", as it should be.
141  */
142  // KeyValue = atoi(p);
143  KeyValue = strtoul(p, (PSTR*)&p, 10);
144 
145  /* Skip any trailing whitespace */
146  while (isspace(*p)) ++p;
147 
148  /* The token must terminate with ')' */
149  if (*p != ')')
150  return NULL;
151 #if 0
152  p = strchr(p, ')');
153  if (p == NULL)
154  return NULL;
155 #endif
156 
157  /* We should have succeeded, copy the token specifier in the buffer */
158  Status = RtlStringCbCopyNA(TokenSpecifier->Buffer,
159  TokenSpecifier->MaximumLength,
160  ArcPath, SpecifierLength);
161  if (!NT_SUCCESS(Status))
162  return NULL;
163 
164  TokenSpecifier->Length = strlen(TokenSpecifier->Buffer) * sizeof(CHAR);
165 
166  /* We succeeded, return the token key value */
167  *Key = KeyValue;
168 
169  /* Next token starts just after */
170  return ++p;
171 }
#define isspace(c)
Definition: acclib.h:69
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:391
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
const char * PCSTR
Definition: typedefs.h:51
char CHAR
Definition: xmlstorage.h:175
smooth NULL
Definition: ftsmooth.c:416
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
Status
Definition: gdiplustypes.h:24
signed char * PSTR
Definition: retypes.h:7
char * strchr(const char *String, int ch)
Definition: utclib.c:501
unsigned int ULONG
Definition: retypes.h:1
GLfloat GLfloat p
Definition: glext.h:8902
#define CHAR(Char)
PCWSTR ArcGetNextTokenU ( IN PCWSTR  ArcPath,
OUT PUNICODE_STRING  TokenSpecifier,
OUT PULONG  Key 
)

Definition at line 174 of file arcname.c.

Referenced by ResolveArcNameManually().

178 {
180  PCWSTR p = ArcPath;
181  ULONG SpecifierLength;
182  ULONG KeyValue;
183 
184  /*
185  * We must have a valid "specifier(key)" string, where 'specifier'
186  * cannot be the empty string, and is followed by '('.
187  */
188  p = wcschr(p, L'(');
189  if (p == NULL)
190  return NULL; /* No '(' found */
191  if (p == ArcPath)
192  return NULL; /* Path starts with '(' and is thus invalid */
193 
194  SpecifierLength = (p - ArcPath) * sizeof(WCHAR);
195 
196  ++p;
197 
198  /*
199  * The strtoul function skips any leading whitespace.
200  *
201  * Note that if the token is "specifier()" then strtoul won't perform
202  * any conversion and return 0, therefore effectively making the token
203  * equivalent to "specifier(0)", as it should be.
204  */
205  // KeyValue = _wtoi(p);
206  KeyValue = wcstoul(p, (PWSTR*)&p, 10);
207 
208  /* Skip any trailing whitespace */
209  while (iswspace(*p)) ++p;
210 
211  /* The token must terminate with ')' */
212  if (*p != L')')
213  return NULL;
214 #if 0
215  p = wcschr(p, L')');
216  if (p == NULL)
217  return NULL;
218 #endif
219 
220  /* We should have succeeded, copy the token specifier in the buffer */
221  Status = RtlStringCbCopyNW(TokenSpecifier->Buffer,
222  TokenSpecifier->MaximumLength,
223  ArcPath, SpecifierLength);
224  if (!NT_SUCCESS(Status))
225  return NULL;
226 
227  TokenSpecifier->Length = wcslen(TokenSpecifier->Buffer) * sizeof(WCHAR);
228 
229  /* We succeeded, return the token key value */
230  *Key = KeyValue;
231 
232  /* Next token starts just after */
233  return ++p;
234 }
__wchar_t WCHAR
Definition: xmlstorage.h:180
PVOID *typedef PWSTR
Definition: winlogon.h:66
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define WCHAR
Definition: msvc.h:43
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:411
smooth NULL
Definition: ftsmooth.c:416
LONG NTSTATUS
Definition: precomp.h:26
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define iswspace(_c)
Definition: ctype.h:669
static const WCHAR L[]
Definition: oid.c:1087
Status
Definition: gdiplustypes.h:24
unsigned int ULONG
Definition: retypes.h:1
const uint16_t * PCWSTR
Definition: typedefs.h:55
GLfloat GLfloat p
Definition: glext.h:8902
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
ULONG ArcMatchToken_UStr ( IN PCUNICODE_STRING  CandidateToken,
IN const PCWSTR TokenTable 
)

Definition at line 268 of file arcname.c.

Referenced by ResolveArcNameManually().

271 {
272  ULONG Index = 0;
273 #if 0
274  SIZE_T Length;
275 #else
277 #endif
278 
279  while (TokenTable[Index])
280  {
281 #if 0
282  Length = wcslen(TokenTable[Index])*sizeof(WCHAR);
283  if (RtlCompareMemory(CandidateToken->Buffer, TokenTable[Index], Length) == Length)
284  break;
285 #else
286  RtlInitUnicodeString(&Token, TokenTable[Index]);
287  // if (RtlCompareUnicodeString(CandidateToken, &Token, TRUE) == 0)
288  if (RtlEqualUnicodeString(CandidateToken, &Token, TRUE))
289  break;
290 #endif
291 
292  ++Index;
293  }
294 
295  return Index;
296 }
#define TRUE
Definition: types.h:120
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
#define WCHAR
Definition: msvc.h:43
static const UCHAR Index[8]
Definition: usbohci.c:18
VOID UINTN Length
Definition: acefiex.h:744
ULONG_PTR SIZE_T
Definition: typedefs.h:78
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
ULONG ArcMatchTokenA ( IN PCSTR  CandidateToken,
IN const PCSTR TokenTable 
)

Definition at line 238 of file arcname.c.

241 {
242  ULONG Index = 0;
243 
244  while (TokenTable[Index] && _stricmp(CandidateToken, TokenTable[Index]) != 0)
245  {
246  ++Index;
247  }
248 
249  return Index;
250 }
#define _stricmp
Definition: cat.c:22
static const UCHAR Index[8]
Definition: usbohci.c:18
unsigned int ULONG
Definition: retypes.h:1
ULONG ArcMatchTokenU ( IN PCWSTR  CandidateToken,
IN const PCWSTR TokenTable 
)

Definition at line 253 of file arcname.c.

256 {
257  ULONG Index = 0;
258 
259  while (TokenTable[Index] && _wcsicmp(CandidateToken, TokenTable[Index]) != 0)
260  {
261  ++Index;
262  }
263 
264  return Index;
265 }
static const UCHAR Index[8]
Definition: usbohci.c:18
unsigned int ULONG
Definition: retypes.h:1
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
BOOLEAN ArcPathNormalize ( OUT PUNICODE_STRING  NormalizedArcPath,
IN PCWSTR  ArcPath 
)

Definition at line 300 of file arcname.c.

Referenced by _tmain().

303 {
305  PCWSTR EndOfArcName;
306  PCWSTR p;
307 
308  if (NormalizedArcPath->MaximumLength < sizeof(UNICODE_NULL))
309  return FALSE;
310 
311  *NormalizedArcPath->Buffer = UNICODE_NULL;
312  NormalizedArcPath->Length = 0;
313 
314  EndOfArcName = wcschr(ArcPath, OBJ_NAME_PATH_SEPARATOR);
315  if (!EndOfArcName)
316  EndOfArcName = ArcPath + wcslen(ArcPath);
317 
318  while ((p = wcsstr(ArcPath, L"()")) && (p < EndOfArcName))
319  {
320 #if 0
321  Status = RtlStringCbCopyNW(NormalizedArcPath->Buffer,
322  NormalizedArcPath->MaximumLength,
323  ArcPath, (p - ArcPath) * sizeof(WCHAR));
324 #else
325  Status = RtlStringCbCatNW(NormalizedArcPath->Buffer,
326  NormalizedArcPath->MaximumLength,
327  ArcPath, (p - ArcPath) * sizeof(WCHAR));
328 #endif
329  if (!NT_SUCCESS(Status))
330  return FALSE;
331 
332  Status = RtlStringCbCatW(NormalizedArcPath->Buffer,
333  NormalizedArcPath->MaximumLength,
334  L"(0)");
335  if (!NT_SUCCESS(Status))
336  return FALSE;
337 #if 0
338  NormalizedArcPath->Buffer += wcslen(NormalizedArcPath->Buffer);
339 #endif
340  ArcPath = p + 2;
341  }
342 
343  Status = RtlStringCbCatW(NormalizedArcPath->Buffer,
344  NormalizedArcPath->MaximumLength,
345  ArcPath);
346  if (!NT_SUCCESS(Status))
347  return FALSE;
348 
349  NormalizedArcPath->Length = wcslen(NormalizedArcPath->Buffer) * sizeof(WCHAR);
350  return TRUE;
351 }
#define TRUE
Definition: types.h:120
__wchar_t WCHAR
Definition: xmlstorage.h:180
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
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:806
#define WCHAR
Definition: msvc.h:43
NTSTRSAFEAPI RtlStringCbCatW(_Inout_updates_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:623
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:27
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:411
LONG NTSTATUS
Definition: precomp.h:26
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
static const WCHAR L[]
Definition: oid.c:1087
Status
Definition: gdiplustypes.h:24
const uint16_t * PCWSTR
Definition: typedefs.h:55
GLfloat GLfloat p
Definition: glext.h:8902
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
BOOLEAN ArcPathToNtPath ( OUT PUNICODE_STRING  NtPath,
IN PCWSTR  ArcPath,
IN PPARTLIST PartList  OPTIONAL 
)

Definition at line 725 of file arcname.c.

Referenced by _tmain(), and EnumerateInstallations().

729 {
731  PCWSTR BeginOfPath;
732  UNICODE_STRING ArcName;
733 
734  /* TODO: We should "normalize" the path, i.e. expand all the xxx() into xxx(0) */
735 
736  if (NtPath->MaximumLength < sizeof(UNICODE_NULL))
737  return FALSE;
738 
739  *NtPath->Buffer = UNICODE_NULL;
740  NtPath->Length = 0;
741 
742  /*
743  * - First, check whether the ARC path is already inside \\ArcName
744  * and if so, map it to the corresponding NT path.
745  * - Only then, if we haven't found any ArcName, try to build a
746  * NT path by deconstructing the ARC path, using its disk and
747  * partition numbers. We may use here our disk/partition list.
748  *
749  * See also freeldr/arcname.c
750  *
751  * Note that it would be nice to maintain a cache of these mappings.
752  */
753 
754  /*
755  * Initialize the ARC name to resolve, by cutting the ARC path at the first
756  * NT path separator. The ARC name therefore ends where the NT path part starts.
757  */
758  RtlInitUnicodeString(&ArcName, ArcPath);
759  BeginOfPath = wcschr(ArcName.Buffer, OBJ_NAME_PATH_SEPARATOR);
760  if (BeginOfPath)
761  ArcName.Length = (ULONG_PTR)BeginOfPath - (ULONG_PTR)ArcName.Buffer;
762 
763  /* Resolve the ARC name via NT SymLinks. Note that NtPath is returned NULL-terminated. */
764  Status = ResolveArcNameNtSymLink(NtPath, &ArcName);
765  if (!NT_SUCCESS(Status))
766  {
767  /* We failed, attempt a manual resolution */
768  DPRINT1("ResolveArcNameNtSymLink(ArcName = '%wZ') for ArcPath = '%S' failed, Status 0x%08lx\n", &ArcName, ArcPath, Status);
769 
770  /*
771  * We failed at directly resolving the ARC path, and we cannot perform
772  * a manual resolution because we don't have any disk/partition list,
773  * we therefore fail here.
774  */
775  if (!PartList)
776  {
777  DPRINT1("PartList == NULL, cannot perform a manual resolution\n");
778  return FALSE;
779  }
780 
781  *NtPath->Buffer = UNICODE_NULL;
782  NtPath->Length = 0;
783 
784  BeginOfPath = ArcPath;
785  Status = ResolveArcNameManually(NtPath, &BeginOfPath, PartList);
786  if (!NT_SUCCESS(Status))
787  {
788  /* We really failed this time, bail out */
789  DPRINT1("ResolveArcNameManually(ArcPath = '%S') failed, Status 0x%08lx\n", ArcPath, Status);
790  return FALSE;
791  }
792  }
793 
794  /*
795  * We succeeded. Concatenate the rest of the system-specific path. We know the path is going
796  * to be inside the NT namespace, therefore we can use the path string concatenation function
797  * that uses '\\' as the path separator.
798  */
799  if (BeginOfPath && *BeginOfPath)
800  {
801  Status = ConcatPaths(NtPath->Buffer, NtPath->MaximumLength / sizeof(WCHAR), 1, BeginOfPath);
802  if (!NT_SUCCESS(Status))
803  {
804  /* Buffer not large enough, or whatever...: just bail out */
805  return FALSE;
806  }
807  }
808  NtPath->Length = wcslen(NtPath->Buffer) * sizeof(WCHAR);
809  return TRUE;
810 }
static NTSTATUS ResolveArcNameNtSymLink(OUT PUNICODE_STRING NtName, IN PUNICODE_STRING ArcName)
Definition: arcname.c:364
#define TRUE
Definition: types.h:120
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define WCHAR
Definition: msvc.h:43
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:27
LONG NTSTATUS
Definition: precomp.h:26
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
Status
Definition: gdiplustypes.h:24
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define ULONG_PTR
Definition: config.h:101
const uint16_t * PCWSTR
Definition: typedefs.h:55
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
static NTSTATUS ResolveArcNameManually(OUT PUNICODE_STRING NtName, IN OUT PCWSTR *ArcNamePath, IN PPARTLIST PartList OPTIONAL)
Definition: arcname.c:459
NTSTATUS ConcatPaths(IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN...)
Definition: filesup.c:81
static NTSTATUS ResolveArcNameManually ( OUT PUNICODE_STRING  NtName,
IN OUT PCWSTR ArcNamePath,
IN PPARTLIST PartList  OPTIONAL 
)
static

Definition at line 459 of file arcname.c.

Referenced by ArcPathToNtPath().

463 {
465  WCHAR TokenBuffer[50];
467  PCWSTR p, q;
468  ULONG AdapterKey;
469  ULONG ControllerKey;
470  ULONG PeripheralKey;
473  CONTROLLER_TYPE ControllerType;
474  PERIPHERAL_TYPE PeripheralType;
475  BOOLEAN UseSignature = FALSE;
476 
477  PDISKENTRY DiskEntry;
478  PPARTENTRY PartEntry = NULL;
479 
480  if (NtName->MaximumLength < sizeof(UNICODE_NULL))
482 
483 #if 0
484  *NtName->Buffer = UNICODE_NULL;
485  NtName->Length = 0;
486 #endif
487 
488  /*
489  * The format of ArcName is:
490  * adapter(www)[controller(xxx)peripheral(yyy)[partition(zzz)][filepath]] ,
491  * where the [filepath] part is not being parsed.
492  */
493 
494  RtlInitEmptyUnicodeString(&Token, TokenBuffer, sizeof(TokenBuffer));
495 
496  p = *ArcNamePath;
497 
498  /* Retrieve the adapter */
499  p = ArcGetNextTokenU(p, &Token, &AdapterKey);
500  if (!p)
501  {
502  DPRINT1("No adapter specified!\n");
504  }
505 
506  /* Check for the 'signature()' pseudo-adapter, introduced in Windows 2000 */
507  if (_wcsicmp(Token.Buffer, L"signature") == 0)
508  {
509  /*
510  * We've got a signature! Remember this for later, and set the adapter type to SCSI.
511  * We however check that the rest of the ARC path is valid by parsing the other tokens.
512  * AdapterKey stores the disk signature value (that holds in a ULONG).
513  */
514  UseSignature = TRUE;
515  AdapterType = ScsiAdapter;
516  }
517  else
518  {
519  /* Check for regular adapters */
520  AdapterType = (ADAPTER_TYPE)/*ArcMatchTokenU*/ArcMatchToken_UStr(/*Token.Buffer*/&Token, AdapterTypes_U);
521  if (AdapterType >= AdapterTypeMax)
522  {
523  DPRINT1("Invalid adapter type %wZ\n", &Token);
525  }
526 
527  /* Check for adapters that don't take any extra controller or peripheral nodes */
528  if (AdapterType == NetAdapter || AdapterType == RamdiskAdapter)
529  {
530  // if (*p)
531  // return STATUS_OBJECT_PATH_SYNTAX_BAD;
532 
533  if (AdapterType == NetAdapter)
534  {
535  DPRINT1("%S(%lu) path is not supported!\n", AdapterTypes_U[AdapterType], AdapterKey);
536  return STATUS_NOT_SUPPORTED;
537  }
538 
539  Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
540  L"\\Device\\Ramdisk%lu", AdapterKey);
541  goto Quit;
542  }
543  }
544 
545  /* Here, we have either an 'eisa', a 'scsi/signature', or a 'multi' adapter */
546 
547  /* Check for a valid controller */
548  p = ArcGetNextTokenU(p, &Token, &ControllerKey);
549  if (!p)
550  {
551  DPRINT1("%S(%lu) adapter doesn't have a controller!\n", AdapterTypes_U[AdapterType], AdapterKey);
553  }
554  ControllerType = (CONTROLLER_TYPE)/*ArcMatchTokenU*/ArcMatchToken_UStr(/*Token.Buffer*/&Token, ControllerTypes_U);
555  if (ControllerType >= ControllerTypeMax)
556  {
557  DPRINT1("Invalid controller type %wZ\n", &Token);
559  }
560 
561  /* Here the controller can only be either a disk or a CDROM */
562 
563  /*
564  * Ignore the controller in case we have a 'multi' adapter.
565  * I guess a similar condition holds for the 'eisa' adapter too...
566  *
567  * For SignatureAdapter, as similar for ScsiAdapter, the controller key corresponds
568  * to the disk target ID. Note that actually, the implementation just ignores the
569  * target ID, as well as the LUN, and just loops over all the available disks and
570  * searches for the one having the correct signature.
571  */
572  if ((AdapterType == MultiAdapter /* || AdapterType == EisaAdapter */) && ControllerKey != 0)
573  {
574  DPRINT1("%S(%lu) adapter with %S(%lu non-zero), ignored!\n",
575  AdapterTypes_U[AdapterType], AdapterKey,
576  ControllerTypes_U[ControllerType], ControllerKey);
577  ControllerKey = 0;
578  }
579 
580  /*
581  * Only the 'scsi' adapter supports a direct 'cdrom' controller.
582  * For the others, we need a 'disk' controller to which a 'cdrom' peripheral can talk to.
583  */
584  if ((AdapterType != ScsiAdapter) && (ControllerType == CdRomController))
585  {
586  DPRINT1("%S(%lu) adapter cannot have a CDROM controller!\n", AdapterTypes_U[AdapterType], AdapterKey);
588  }
589 
590  /* Check for a valid peripheral */
591  p = ArcGetNextTokenU(p, &Token, &PeripheralKey);
592  if (!p)
593  {
594  DPRINT1("%S(%lu)%S(%lu) adapter-controller doesn't have a peripheral!\n",
595  AdapterTypes_U[AdapterType], AdapterKey,
596  ControllerTypes_U[ControllerType], ControllerKey);
598  }
599  PeripheralType = (PERIPHERAL_TYPE)/*ArcMatchTokenU*/ArcMatchToken_UStr(/*Token.Buffer*/&Token, PeripheralTypes_U);
600  if (PeripheralType >= PeripheralTypeMax)
601  {
602  DPRINT1("Invalid peripheral type %wZ\n", &Token);
604  }
605 
606  /*
607  * If we had a 'cdrom' controller already, the corresponding peripheral can only be 'fdisk'
608  * (see for example the ARC syntax for SCSI CD-ROMs: scsi(x)cdrom(y)fdisk(z) where z == 0).
609  */
610  if ((ControllerType == CdRomController) && (PeripheralType != FDiskPeripheral))
611  {
612  DPRINT1("%S(%lu) controller cannot have a %S(%lu) peripheral! (note that we haven't check whether the adapter was SCSI or not)\n",
613  ControllerTypes_U[ControllerType], ControllerKey,
614  PeripheralTypes_U[PeripheralType], PeripheralKey);
616  }
617 
618  /* For a 'scsi' adapter, the possible peripherals are only 'rdisk' or 'fdisk' */
619  if (AdapterType == ScsiAdapter && !(PeripheralType == RDiskPeripheral || PeripheralType == FDiskPeripheral))
620  {
621  DPRINT1("%S(%lu)%S(%lu) SCSI adapter-controller has an invalid peripheral %S(%lu) !\n",
622  AdapterTypes_U[AdapterType], AdapterKey,
623  ControllerTypes_U[ControllerType], ControllerKey,
624  PeripheralTypes_U[PeripheralType], PeripheralKey);
626  }
627 
628 #if 0
629  if (AdapterType == SignatureAdapter && PeripheralKey != 0)
630  {
631  DPRINT1("%S(%lu) adapter with %S(%lu non-zero), ignored!\n",
632  AdapterTypes_U[AdapterType], AdapterKey,
633  PeripheralTypes_U[PeripheralType], PeripheralKey);
634  PeripheralKey = 0;
635  }
636 #endif
637 
638  /* Check for the optional 'partition' specifier */
639  q = ArcGetNextTokenU(p, &Token, &PartitionNumber);
640  if (q && _wcsicmp(Token.Buffer, L"partition") == 0)
641  {
642  /* We've got a partition! */
643  p = q;
644  }
645  else
646  {
647  /*
648  * Either no other ARC token was found, or we've got something else
649  * (possibly invalid or not)...
650  */
651  PartitionNumber = 0;
652  }
653 
654 
655  // TODO: Check the partition number in case of fdisks and cdroms??
656 
657 
658  if (ControllerType == CdRomController) // and so, AdapterType == ScsiAdapter and PeripheralType == FDiskPeripheral
659  {
660  Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
661  L"\\Device\\Scsi\\CdRom%lu", ControllerKey);
662  }
663  else
664  /* Now, ControllerType == DiskController */
665  if (PeripheralType == CdRomPeripheral)
666  {
667  Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
668  L"\\Device\\CdRom%lu", PeripheralKey);
669  }
670  else
671  if (PeripheralType == FDiskPeripheral)
672  {
673  Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
674  L"\\Device\\Floppy%lu", PeripheralKey);
675  }
676  else
677  if (PeripheralType == RDiskPeripheral)
678  {
679  if (UseSignature)
680  {
681  /* The disk signature is stored in AdapterKey */
682  DiskEntry = GetDiskBySignature(PartList, AdapterKey);
683  }
684  else
685  {
686  DiskEntry = GetDiskBySCSI(PartList, AdapterKey,
687  ControllerKey, PeripheralKey);
688  }
689  if (!DiskEntry)
690  return STATUS_OBJECT_PATH_NOT_FOUND; // STATUS_NOT_FOUND;
691 
692  if (PartitionNumber != 0)
693  {
694  PartEntry = GetPartition(DiskEntry, PartitionNumber);
695  if (!PartEntry)
696  return STATUS_OBJECT_PATH_NOT_FOUND; // STATUS_DEVICE_NOT_PARTITIONED;
697  ASSERT(PartEntry->DiskEntry == DiskEntry);
698  }
699 
700  Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
701  L"\\Device\\Harddisk%lu\\Partition%lu",
702  DiskEntry->DiskNumber, PartitionNumber);
703  }
704 #if 0
705  else
706  if (PeripheralType == VDiskPeripheral)
707  {
708  // TODO: Check how Win 7+ deals with virtual disks.
709  Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
710  L"\\Device\\VirtualHarddisk%lu\\Partition%lu",
711  PeripheralKey, PartitionNumber);
712  }
713 #endif
714 
715 Quit:
716  if (!NT_SUCCESS(Status))
717  return Status;
718 
719  *ArcNamePath = p;
720  return STATUS_SUCCESS;
721 }
#define TRUE
Definition: types.h:120
enum _ADAPTER_TYPE ADAPTER_TYPE
PPARTENTRY GetPartition(IN PDISKENTRY DiskEntry, IN ULONG PartitionNumber)
Definition: partlist.c:1469
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
__wchar_t WCHAR
Definition: xmlstorage.h:180
const PCWSTR ControllerTypes_U[]
Definition: arcname.c:76
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID _Out_ PHANDLE Token
ULONG DiskNumber
Definition: partlist.h:94
ULONG ArcMatchToken_UStr(IN PCUNICODE_STRING CandidateToken, IN const PCWSTR *TokenTable)
Definition: arcname.c:268
_In_ ULONG _In_ ULONG PartitionNumber
Definition: iofuncs.h:2056
enum _CONTROLLER_TYPE CONTROLLER_TYPE
const PCWSTR PeripheralTypes_U[]
Definition: arcname.c:100
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:52
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
struct _DISKENTRY * DiskEntry
Definition: partlist.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
PDISKENTRY GetDiskBySignature(IN PPARTLIST List, IN ULONG Signature)
Definition: partlist.c:1443
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
static const WCHAR L[]
Definition: oid.c:1087
static __inline NTSTATUS 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:1120
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:279
PDISKENTRY GetDiskBySCSI(IN PPARTLIST List, IN USHORT Port, IN USHORT Bus, IN USHORT Id)
Definition: partlist.c:1413
#define DPRINT1
Definition: precomp.h:8
const PCWSTR AdapterTypes_U[]
Definition: arcname.c:53
PCWSTR ArcGetNextTokenU(IN PCWSTR ArcPath, OUT PUNICODE_STRING TokenSpecifier, OUT PULONG Key)
Definition: arcname.c:174
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
const uint16_t * PCWSTR
Definition: typedefs.h:55
GLfloat GLfloat p
Definition: glext.h:8902
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:281
return STATUS_SUCCESS
Definition: btrfs.c:2710
enum _PERIPHERAL_TYPE PERIPHERAL_TYPE
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static NTSTATUS ResolveArcNameNtSymLink ( OUT PUNICODE_STRING  NtName,
IN PUNICODE_STRING  ArcName 
)
static

Definition at line 364 of file arcname.c.

Referenced by ArcPathToNtPath().

367 {
370  HANDLE DirectoryHandle, LinkHandle;
371  UNICODE_STRING ArcNameDir;
372 
373  if (NtName->MaximumLength < sizeof(UNICODE_NULL))
375 
376 #if 0
377  *NtName->Buffer = UNICODE_NULL;
378  NtName->Length = 0;
379 #endif
380 
381  /* Open the \ArcName object directory */
382  RtlInitUnicodeString(&ArcNameDir, L"\\ArcName");
383  InitializeObjectAttributes(&ObjectAttributes,
384  &ArcNameDir,
386  NULL,
387  NULL);
388  Status = NtOpenDirectoryObject(&DirectoryHandle,
390  &ObjectAttributes);
391  if (!NT_SUCCESS(Status))
392  {
393  DPRINT1("NtOpenDirectoryObject(%wZ) failed, Status 0x%08lx\n", &ArcNameDir, Status);
394  return Status;
395  }
396 
397  /* Open the ARC name link */
398  InitializeObjectAttributes(&ObjectAttributes,
399  ArcName,
401  DirectoryHandle,
402  NULL);
403  Status = NtOpenSymbolicLinkObject(&LinkHandle,
405  &ObjectAttributes);
406 
407  /* Close the \ArcName object directory handle */
408  NtClose(DirectoryHandle);
409 
410  /* Check for success */
411  if (!NT_SUCCESS(Status))
412  {
413  DPRINT1("NtOpenSymbolicLinkObject(%wZ) failed, Status 0x%08lx\n", ArcName, Status);
414  return Status;
415  }
416 
417  /* Reserve one WCHAR for the NULL-termination */
418  NtName->MaximumLength -= sizeof(UNICODE_NULL);
419 
420  /* Resolve the link */
421  Status = NtQuerySymbolicLinkObject(LinkHandle, NtName, NULL);
422 
423  /* Restore the NULL-termination */
424  NtName->MaximumLength += sizeof(UNICODE_NULL);
425 
426  /* Check for success */
427  if (!NT_SUCCESS(Status))
428  {
429  /* We failed, don't touch NtName */
430  DPRINT1("NtQuerySymbolicLinkObject(%wZ) failed, Status 0x%08lx\n", ArcName, Status);
431  }
432  else
433  {
434  /* We succeeded, NULL-terminate NtName */
435  NtName->Buffer[NtName->Length / sizeof(WCHAR)] = UNICODE_NULL;
436  }
437 
438  NtClose(LinkHandle);
439  return Status;
440 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
NTSTATUS NTAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:359
static HANDLE DirectoryHandle
Definition: ObType.c:48
#define WCHAR
Definition: msvc.h:43
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:52
#define UNICODE_NULL
smooth NULL
Definition: ftsmooth.c:416
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3393
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const WCHAR L[]
Definition: oid.c:1087
Status
Definition: gdiplustypes.h:24
DWORD *typedef HANDLE
Definition: winlogon.h:61
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
#define DPRINT1
Definition: precomp.h:8
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106

Variable Documentation

const PCSTR AdapterTypes_A[]
Initial value:
=
{
"eisa",
"scsi",
"multi",
"net",
"ramdisk",
}
smooth NULL
Definition: ftsmooth.c:416

Definition at line 44 of file arcname.c.

const PCWSTR AdapterTypes_U[]
Initial value:
=
{
L"eisa",
L"scsi",
L"multi",
L"net",
L"ramdisk",
}
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR L[]
Definition: oid.c:1087

Definition at line 53 of file arcname.c.

Referenced by ResolveArcNameManually().

const PCSTR ControllerTypes_A[]
Initial value:
=
{
"disk",
"cdrom",
}
smooth NULL
Definition: ftsmooth.c:416

Definition at line 70 of file arcname.c.

const PCWSTR ControllerTypes_U[]
Initial value:
=
{
L"disk",
L"cdrom",
}
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR L[]
Definition: oid.c:1087

Definition at line 76 of file arcname.c.

Referenced by ResolveArcNameManually().

const PCSTR PeripheralTypes_A[]
Initial value:
=
{
"rdisk",
"fdisk",
"cdrom",
}
smooth NULL
Definition: ftsmooth.c:416

Definition at line 92 of file arcname.c.

const PCWSTR PeripheralTypes_U[]
Initial value:
=
{
L"rdisk",
L"fdisk",
L"cdrom",
}
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR L[]
Definition: oid.c:1087

Definition at line 100 of file arcname.c.

Referenced by ResolveArcNameManually().