4 #pragma alloc_text(PAGE, NcComparePath) 5 #pragma alloc_text(PAGE, NcConstructPath) 6 #pragma alloc_text(PAGE, NcParseFinalComponent) 9 #define NcIsCharComponentTerminator( C ) \ 10 ((C) == L'\\' || (C) == L':') 14 _In_ PCUNICODE_STRING Name,
16 _Out_opt_ PUNICODE_STRING Remainder,
17 _In_ BOOLEAN IgnoreCase,
18 _In_ BOOLEAN ContainsDevice,
57 PUNICODE_STRING LongName;
58 PUNICODE_STRING ShortName;
69 USHORT NameMatchIndex = 0;
84 USHORT ComponentMatches = 0;
85 USHORT MappingComponents;
86 USHORT VolumeComponents;
91 LongName = &Mapping->LongNamePath.FullPath;
92 ShortName = &Mapping->ShortNamePath.FullPath;
94 MappingComponents = Mapping->LongNamePath.NumberComponentsInFullPath;
95 VolumeComponents = Mapping->LongNamePath.NumberComponentsInVolumePath;
97 LongName = &Mapping->LongNamePath.VolumelessName;
98 ShortName = &Mapping->ShortNamePath.VolumelessName;
100 MappingComponents = Mapping->LongNamePath.NumberComponentsInFullPath - Mapping->LongNamePath.NumberComponentsInVolumePath;
101 VolumeComponents = 0;
104 NameBuff = Name->Buffer;
105 LongBuff = LongName->Buffer;
106 ShortBuff = ShortName->Buffer;
108 NameLength = Name->Length/
sizeof(WCHAR);
109 LongLength = LongName->Length/
sizeof(WCHAR);
110 ShortLength = ShortName->Length/
sizeof(WCHAR);
117 FLT_ASSERT( Name->Length %
sizeof(WCHAR) == 0 );
118 FLT_ASSERT( LongName->Length %
sizeof(WCHAR) == 0 );
119 FLT_ASSERT( ShortName->Length %
sizeof(WCHAR) == 0 );
120 FLT_ASSERT( Mapping->LongNamePath.NumberComponentsInFullPath == Mapping->ShortNamePath.NumberComponentsInFullPath );
156 LongDone = (BOOLEAN)(LongIndex >= LongLength || LongBuff[LongIndex] ==
'\\');
157 ShortDone = (BOOLEAN)(ShortIndex >= ShortLength || ShortBuff[ShortIndex] ==
'\\');
169 if(LongDone && ShortDone) {
186 NameBuffCur = RtlUpcaseUnicodeChar( NameBuff[NameIndex] );
188 LongBuffCur = RtlUpcaseUnicodeChar( LongBuff[LongIndex] );
192 ShortBuffCur = RtlUpcaseUnicodeChar( ShortBuff[ShortIndex] );
197 NameBuffCur = NameBuff[NameIndex];
199 LongBuffCur = LongBuff[LongIndex];
203 ShortBuffCur = ShortBuff[ShortIndex];
212 if (NameBuffCur != LongBuffCur) {
220 if (NameBuffCur != ShortBuffCur) {
243 }
while(LongMatch || ShortMatch);
267 while (NameIndex < NameLength && NameBuff[NameIndex] !=
'\\') {
282 while( LongIndex < LongLength && LongBuff[LongIndex] !=
'\\' ) {
294 while( ShortIndex < ShortLength && ShortBuff[ShortIndex] !=
'\\' ) {
306 if ((LongMatch || ShortMatch) && NameIndex != 0) {
314 FLT_ASSERT( NameIndex == NameLength || NameBuff[NameIndex] ==
'\\' );
315 FLT_ASSERT( LongIndex == LongLength || LongBuff[LongIndex] ==
'\\' );
316 FLT_ASSERT( ShortIndex == ShortLength || ShortBuff[ShortIndex] ==
'\\' );
322 if (NameIndex < NameLength) {
326 if (LongIndex < LongLength) {
330 if (ShortIndex < ShortLength) {
334 if (LongMatch || ShortMatch) {
335 NameMatchIndex = NameIndex;
347 FLT_ASSERT( (LongIndex < LongLength) ? (ShortIndex < ShortLength) :
TRUE );
349 }
while( (LongMatch || ShortMatch) && NameIndex < NameLength && LongIndex < LongLength );
356 Overlap->EntireFlags = 0;
361 FLT_ASSERT( ComponentMatches <= MappingComponents );
363 if (ComponentMatches >= MappingComponents &&
364 NameLength > NameMatchIndex) {
371 Overlap->InMapping =
TRUE;
373 if (Remainder !=
NULL) {
375 Remainder->Buffer = &NameBuff[NameMatchIndex];
376 Remainder->Length = (NameLength - NameMatchIndex) *
sizeof(WCHAR);
377 Remainder->MaximumLength = Remainder->Length;
380 }
else if (ComponentMatches == MappingComponents) {
387 Overlap->Match =
TRUE;
388 Overlap->InMapping =
TRUE;
390 if (Remainder !=
NULL) {
392 Remainder->Buffer = &NameBuff[NameIndex];
393 Remainder->MaximumLength = Remainder->Length = 0;
396 }
else if (ComponentMatches == MappingComponents - 1 &&
397 NameLength > NameMatchIndex) {
405 Overlap->Peer =
TRUE;
407 for (;NameIndex < NameLength;NameIndex++) {
408 if (NameBuff[NameIndex] == L
'\\') {
409 Overlap->Peer = FALSE;
415 }
else if (ComponentMatches == MappingComponents - 1) {
422 Overlap->Parent =
TRUE;
423 Overlap->Ancestor =
TRUE;
425 }
else if (ComponentMatches >= VolumeComponents &&
426 NameLength == NameMatchIndex) {
433 Overlap->Ancestor =
TRUE;
436 return (BOOLEAN)Overlap->InMapping;
441 _Must_inspect_result_
445 _In_ PUNICODE_STRING Remainder,
446 _In_ BOOLEAN IncludeVolume,
447 _Out_
_At_(NewName->
Buffer, __drv_allocatesMem(Mem)) PUNICODE_STRING NewName
471 NTSTATUS
Status = STATUS_SUCCESS;
474 USHORT SeparatorLength;
482 SeparatorLength = (Remainder->Length == 0 ? 0 :
sizeof(WCHAR));
483 NameLength = RealPath->LongNamePath.VolumelessName.Length + SeparatorLength + Remainder->Length;
484 if( IncludeVolume ) {
486 NameLength = NameLength + RealPath->LongNamePath.VolumePath.Length;
498 if (NameLength >= MAXUSHORT) {
500 Status = STATUS_OBJECT_PATH_INVALID;
501 goto NcConstructPathCleanup;
508 NameBuffer = ExAllocatePoolWithTag( PagedPool,
512 if (NameBuffer ==
NULL) {
514 Status = STATUS_INSUFFICIENT_RESOURCES;
515 goto NcConstructPathCleanup;
522 NewName->Buffer = NameBuffer;
524 NewName->MaximumLength = NameLength;
532 Status = RtlAppendUnicodeStringToString( NewName, &RealPath->LongNamePath.VolumePath );
541 Status = RtlAppendUnicodeStringToString( NewName,
542 &RealPath->LongNamePath.VolumelessName );
550 if (SeparatorLength > 0) {
552 NewName->Buffer[NewName->Length/
sizeof(WCHAR)] =
NC_SEPARATOR;
553 NewName->Length +=
sizeof(WCHAR);
555 FLT_ASSERT( NewName->Length <= NewName->MaximumLength );
562 Status = RtlAppendUnicodeStringToString( NewName, Remainder );
566 NcConstructPathCleanup:
573 _In_ PUNICODE_STRING EntirePath,
574 _Out_ PUNICODE_STRING ParentPath,
575 _Out_ PUNICODE_STRING FinalComponent
578 USHORT Index = EntirePath->Length /
sizeof(WCHAR);
580 USHORT FinalComponentLength;
581 BOOLEAN FoundFinalComponent = FALSE;
582 NTSTATUS
Status = STATUS_SUCCESS;
583 PWSTR ParentStringBuffer =
NULL;
584 PWSTR FinalStringBuffer =
NULL;
590 if (EntirePath->Buffer[Index] == L
'\\') {
591 FoundFinalComponent =
TRUE;
601 if (!FoundFinalComponent) {
602 return STATUS_INVALID_PARAMETER;
611 ParentLength = Index *
sizeof(WCHAR);
613 ParentLength = (Index + 1) *
sizeof(WCHAR);
621 FinalComponentLength = EntirePath->Length - (Index + 1) *
sizeof(WCHAR);
622 if (FinalComponentLength == 0) {
623 return STATUS_INVALID_PARAMETER;
626 ParentStringBuffer = ExAllocatePoolWithTag( NonPagedPool,
630 if (ParentStringBuffer ==
NULL) {
631 Status = STATUS_INSUFFICIENT_RESOURCES;
632 goto NcParseFinalComponentCleanup;
635 FinalStringBuffer = ExAllocatePoolWithTag( NonPagedPool,
636 FinalComponentLength,
639 if (FinalStringBuffer ==
NULL) {
640 Status = STATUS_INSUFFICIENT_RESOURCES;
641 goto NcParseFinalComponentCleanup;
644 RtlCopyMemory( ParentStringBuffer, EntirePath->Buffer, ParentLength );
646 ParentPath->Buffer = ParentStringBuffer;
647 ParentPath->MaximumLength =
648 ParentPath->Length = ParentLength;
650 RtlCopyMemory( FinalStringBuffer, &EntirePath->Buffer[Index + 1], FinalComponentLength );
652 FinalComponent->Buffer = FinalStringBuffer;
653 FinalComponent->MaximumLength =
654 FinalComponent->Length = FinalComponentLength;
660 ParentStringBuffer =
NULL;
661 FinalStringBuffer =
NULL;
663 NcParseFinalComponentCleanup:
665 if (ParentStringBuffer) {
666 ExFreePoolWithTag( ParentStringBuffer,
NC_TAG );
669 if (FinalStringBuffer) {
670 ExFreePoolWithTag( FinalStringBuffer,
NC_TAG );
RtlCopyMemory(OutputStringBuffer, TempMappingBuffer->Data, OutputString->MaximumLength)
FLT_ASSERT(IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject))
_At_(String->Length, _Out_range_(==, 0)) _At_(String -> MaximumLength, _In_) _At_(String->Buffer, _Pre_maybenull_ _Post_notnull_ _Post_writable_byte_size_(String->MaximumLength)) NTSTATUS CtxAllocateUnicodeString(_Out_ PUNICODE_STRING String)
#define NcIsCharComponentTerminator(C)
BOOLEAN NcComparePath(_In_ PCUNICODE_STRING Name, _In_ PNC_MAPPING_ENTRY Mapping, _Out_opt_ PUNICODE_STRING Remainder, _In_ BOOLEAN IgnoreCase, _In_ BOOLEAN ContainsDevice, _Out_ PNC_PATH_OVERLAP Overlap)
_In_ BOOLEAN _Out_ PFILE_BASIC_INFORMATION Buffer
NcLoadRegistryStringRetry NULL
NTSTATUS NcParseFinalComponent(_In_ PUNICODE_STRING EntirePath, _Out_ PUNICODE_STRING ParentPath, _Out_ PUNICODE_STRING FinalComponent)
NcLoadRegistryStringCleanup NC_TAG
#define NC_GENERATE_NAME_TAG