pDirNode->ObjectInformation = pObjectInfoCB;
//
- // Set valid entry
+ // Set valid entry and NOT_IN_PARENT flag
//
- SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID);
+ SetFlag( pDirNode->Flags, AFS_DIR_ENTRY_VALID | AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
pDirNode->FileIndex = FileIndex;
pObjectInfoCB->FileAttributes = DirEnumEntry->FileAttributes;
- if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
- pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
+ if( pObjectInfoCB->FileType == AFS_FILE_TYPE_MOUNTPOINT)
+ {
+
+ pObjectInfoCB->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+ }
+
+ if (pObjectInfoCB->FileType == AFS_FILE_TYPE_SYMLINK ||
pObjectInfoCB->FileType == AFS_FILE_TYPE_DFSLINK)
{
- pObjectInfoCB->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+ pObjectInfoCB->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
}
pObjectInfoCB->EaSize = DirEnumEntry->EaSize;
DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
- if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
- pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
+ if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
+ {
+
+ DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+ }
+
+ if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
{
- DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+ DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
}
DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
DirEntry->ObjectInformation->FileAttributes = pDirEntry->FileAttributes;
- if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
- pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
+ if( pDirEntry->FileType == AFS_FILE_TYPE_MOUNTPOINT)
+ {
+
+ DirEntry->ObjectInformation->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+ }
+
+ if( pDirEntry->FileType == AFS_FILE_TYPE_SYMLINK ||
pDirEntry->FileType == AFS_FILE_TYPE_DFSLINK)
{
- DirEntry->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+ DirEntry->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
}
DirEntry->ObjectInformation->EaSize = pDirEntry->EaSize;
AFSFsRtlNotifyFullReportChange( &pVolumeCB->ObjectInformation,
NULL,
FILE_NOTIFY_CHANGE_FILE_NAME |
- FILE_NOTIFY_CHANGE_DIR_NAME |
- FILE_NOTIFY_CHANGE_NAME |
- FILE_NOTIFY_CHANGE_ATTRIBUTES |
- FILE_NOTIFY_CHANGE_SIZE,
+ FILE_NOTIFY_CHANGE_DIR_NAME |
+ FILE_NOTIFY_CHANGE_NAME |
+ FILE_NOTIFY_CHANGE_ATTRIBUTES |
+ FILE_NOTIFY_CHANGE_SIZE,
FILE_ACTION_MODIFIED);
InterlockedDecrement( &pVolumeCB->VolumeReferenceCount);
else
{
- if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
- InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
+ if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED)
{
+
pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+
+ SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
}
pObjectInfo->Expiration.QuadPart = 0;
ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
}
- if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
+ if( InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION ||
+ InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED)
{
ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
}
(VOID) AFSTearDownFcbExtents( pObjectInfo->Fcb);
}
+ pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
+
+
+ if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSInvalidateCache Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
+ pObjectInfo->FileId.Cell,
+ pObjectInfo->FileId.Volume,
+ pObjectInfo->FileId.Vnode,
+ pObjectInfo->FileId.Unique);
+
+ SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
+ }
+
// Fall through to the default processing
}
SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY);
- if( InvalidateCB->Reason == AFS_INVALIDATE_FLUSHED ||
- InvalidateCB->Reason == AFS_INVALIDATE_DATA_VERSION)
- {
- pObjectInfo->DataVersion.QuadPart = (ULONGLONG)-1;
-
- if( pObjectInfo->FileType == AFS_FILE_TYPE_FILE)
- {
-
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSInvalidateCache Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
- pObjectInfo->FileId.Cell,
- pObjectInfo->FileId.Volume,
- pObjectInfo->FileId.Vnode,
- pObjectInfo->FileId.Unique);
-
- SetFlag( pObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
- }
- }
-
break;
}
}
SetFlag( VolumeCB->ObjectInformation.Flags, AFS_OBJECT_FLAGS_VERIFY);
- if( Reason == AFS_INVALIDATE_FLUSHED ||
- Reason == AFS_INVALIDATE_DATA_VERSION)
+ if( Reason == AFS_INVALIDATE_FLUSHED)
{
VolumeCB->ObjectInformation.DataVersion.QuadPart = (ULONGLONG)-1;
ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
}
- if( Reason == AFS_INVALIDATE_DATA_VERSION)
+ if( Reason == AFS_INVALIDATE_DATA_VERSION ||
+ Reason == AFS_INVALIDATE_FLUSHED)
{
ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
}
SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY);
- if( Reason == AFS_INVALIDATE_FLUSHED ||
- Reason == AFS_INVALIDATE_DATA_VERSION)
+ if( Reason == AFS_INVALIDATE_FLUSHED)
{
pCurrentObject->DataVersion.QuadPart = (ULONGLONG)-1;
+ }
- if( pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
- {
+ if( Reason == AFS_INVALIDATE_FLUSHED &&
+ pCurrentObject->FileType == AFS_FILE_TYPE_FILE)
+ {
- AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
- AFS_TRACE_LEVEL_VERBOSE,
- "AFSInvalidateVolume Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
- pCurrentObject->FileId.Cell,
- pCurrentObject->FileId.Volume,
- pCurrentObject->FileId.Vnode,
- pCurrentObject->FileId.Unique);
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSInvalidateVolume Setting VERIFY_DATA flag on fid %08lX-%08lX-%08lX-%08lX\n",
+ pCurrentObject->FileId.Cell,
+ pCurrentObject->FileId.Volume,
+ pCurrentObject->FileId.Vnode,
+ pCurrentObject->FileId.Unique);
- SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
- }
+ SetFlag( pCurrentObject->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
}
if( pCurrentObject->FileType == AFS_FILE_TYPE_DIRECTORY)
ulFilter |= FILE_NOTIFY_CHANGE_SECURITY;
}
- if( Reason == AFS_INVALIDATE_DATA_VERSION)
+ if( Reason == AFS_INVALIDATE_DATA_VERSION ||
+ Reason == AFS_INVALIDATE_FLUSHED)
{
ulFilter |= FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE;
}
AFSAcquireExcl( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock,
TRUE);
- AFSValidateDirectoryCache( pObjectInfo,
- AuthGroup);
+ ntStatus = AFSValidateDirectoryCache( pObjectInfo,
+ AuthGroup);
AFSReleaseResource( pObjectInfo->Specific.Directory.DirectoryNodeHdr.TreeLock);
+
+ if ( !NT_SUCCESS( ntStatus))
+ {
+
+ try_return( ntStatus);
+ }
}
//
while( pCurrentDirEntry != NULL)
{
+ pNextDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
+
if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
{
- ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
+ //
+ // If this entry has been deleted then process it here
+ //
+
+ if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_DELETED) &&
+ pCurrentDirEntry->OpenReferenceCount == 0)
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Deleting dir entry %p name %wZ\n",
+ pCurrentDirEntry,
+ &pCurrentDirEntry->NameInformation.FileName);
+
+ AFSDeleteDirEntry( ObjectInfo,
+ pCurrentDirEntry);
+ }
+ else
+ {
+
+ ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Clear VALID flag on DE %p Reference count %08lX\n",
+ pCurrentDirEntry,
+ pCurrentDirEntry->OpenReferenceCount);
+
+ //
+ // We pull the short name from the parent tree since it could change below
+ //
+
+ if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
+ {
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Removing DE %p (%08lX) from shortname tree for %wZ\n",
+ pCurrentDirEntry,
+ pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
+ &pCurrentDirEntry->NameInformation.FileName);
+
+ AFSRemoveShortNameDirEntry( &ObjectInfo->Specific.Directory.ShortNameTree,
+ pCurrentDirEntry);
+
+ ClearFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
+ }
+ }
}
- pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
+ pCurrentDirEntry = pNextDirEntry;
}
//
// Reget the directory contents
//
- AFSVerifyDirectoryContent( ObjectInfo,
- AuthGroup);
+ ntStatus = AFSVerifyDirectoryContent( ObjectInfo,
+ AuthGroup);
+
+ if ( !NT_SUCCESS( ntStatus))
+ {
+ try_return( ntStatus);
+ }
//
// Now start again and tear down any entries not valid
if( BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_VALID))
{
+ if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME) &&
+ pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex > 0)
+ {
+
+ if( ObjectInfo->Specific.Directory.ShortNameTree == NULL)
+ {
+
+ ObjectInfo->Specific.Directory.ShortNameTree = pCurrentDirEntry;
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Insert DE %p to head of shortname tree for %wZ\n",
+ pCurrentDirEntry,
+ &pCurrentDirEntry->NameInformation.FileName);
+
+ SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
+ }
+ else
+ {
+
+ if( !NT_SUCCESS( AFSInsertShortNameDirEntry( ObjectInfo->Specific.Directory.ShortNameTree,
+ pCurrentDirEntry)))
+ {
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Failed to insert DE %p (%08lX) to shortname tree for %wZ\n",
+ pCurrentDirEntry,
+ pCurrentDirEntry->Type.Data.ShortNameTreeEntry.HashIndex,
+ &pCurrentDirEntry->NameInformation.FileName);
+ }
+ else
+ {
+ SetFlag( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
+
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Insert DE %p to shortname tree for %wZ\n",
+ pCurrentDirEntry,
+ &pCurrentDirEntry->NameInformation.FileName);
+ }
+ }
+ }
+
pCurrentDirEntry = pNextDirEntry;
continue;
}
+ AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+ AFS_TRACE_LEVEL_VERBOSE,
+ "AFSValidateDirectoryCache Processing INVALID DE %p Reference count %08lX\n",
+ pCurrentDirEntry,
+ pCurrentDirEntry->OpenReferenceCount);
+
if( pCurrentDirEntry->OpenReferenceCount == 0)
{
}
#endif
+try_exit:
+
if( bAcquiredLock)
{
pObjectInfo->FileAttributes = DirEnumEntry->FileAttributes;
- if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT ||
- pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
+ if( pObjectInfo->FileType == AFS_FILE_TYPE_MOUNTPOINT)
+ {
+
+ pObjectInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+ }
+
+ if( pObjectInfo->FileType == AFS_FILE_TYPE_SYMLINK ||
pObjectInfo->FileType == AFS_FILE_TYPE_DFSLINK)
{
- pObjectInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+ pObjectInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
}
pObjectInfo->EaSize = DirEnumEntry->EaSize;
if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_MOUNTPOINT)
{
- FileInfo->FileAttributes |= (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
+ FileInfo->FileAttributes = (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT);
}
else if( pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_SYMLINK ||
pDirectoryEntry->ObjectInformation->FileType == AFS_FILE_TYPE_DFSLINK)
{
- FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+ if ( FileInfo->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+ {
+
+ FileInfo->FileAttributes = FILE_ATTRIBUTE_REPARSE_POINT;
+ }
+ else
+ {
+
+ FileInfo->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
+ }
}
FileInfo->AllocationSize = pDirectoryEntry->ObjectInformation->AllocationSize;
AFSRemoveCaseInsensitiveDirEntry( &ParentObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseInsensitiveTreeHead,
DirEntry);
- if( ParentObjectInfo->Specific.Directory.ShortNameTree &&
- DirEntry->Type.Data.ShortNameTreeEntry.HashIndex != 0)
+ if( BooleanFlagOn( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME))
{
//
AFSRemoveShortNameDirEntry( &ParentObjectInfo->Specific.Directory.ShortNameTree,
DirEntry);
+
+ ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_INSERTED_SHORT_NAME);
}
AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
SetFlag( DirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE);
+ ClearFlag( DirEntry->Flags, AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD);
+
try_exit:
NOTHING;
BOOLEAN bIsValid = TRUE;
ULONG ulCount = 0;
- AFSDirectoryCB *pCurrentDirEntry = NULL;
+ AFSDirectoryCB *pCurrentDirEntry = NULL, *pDirEntry = NULL;
pCurrentDirEntry = ObjectInfo->Specific.Directory.DirectoryNodeListHead;
if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_FAKE))
{
ulCount++;
+
+ if( !BooleanFlagOn( pCurrentDirEntry->Flags, AFS_DIR_ENTRY_NOT_IN_PARENT_TREE))
+ {
+
+ pDirEntry = NULL;
+
+ AFSLocateCaseSensitiveDirEntry( ObjectInfo->Specific.Directory.DirectoryNodeHdr.CaseSensitiveTreeHead,
+ (ULONG)pCurrentDirEntry->CaseSensitiveTreeEntry.HashIndex,
+ &pDirEntry);
+
+ if( pDirEntry == NULL)
+ {
+ DbgBreakPoint();
+ }
+ }
}
pCurrentDirEntry = (AFSDirectoryCB *)pCurrentDirEntry->ListEntry.fLink;
SECURITY_DESCRIPTOR *pSecurityDescr = NULL;
ULONG ulSDLength = 0;
SECURITY_DESCRIPTOR *pRelativeSecurityDescr = NULL;
+ PSID pWorldSID = NULL;
+ ULONG *pulSubAuthority = NULL;
+ ULONG ulWorldSIDLEngth = 0;
__Enter
{
+ ulWorldSIDLEngth = RtlLengthRequiredSid( 1);
+
+ pWorldSID = (PSID)ExAllocatePoolWithTag( PagedPool,
+ ulWorldSIDLEngth,
+ AFS_GENERIC_MEMORY_29_TAG);
+
+ if( pWorldSID == NULL)
+ {
+ AFSPrint( "AFSCreateDefaultSecurityDescriptor unable to allocate World SID\n");
+ try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
+ }
+
+ RtlZeroMemory( pWorldSID,
+ ulWorldSIDLEngth);
+
+ RtlInitializeSid( pWorldSID,
+ &SeWorldSidAuthority,
+ 1);
+
+ pulSubAuthority = RtlSubAuthoritySid(pWorldSID, 0);
+ *pulSubAuthority = SECURITY_WORLD_RID;
+
if( AFSRtlSetSaclSecurityDescriptor == NULL)
{
}
}
+ //
+ // Add in the group and owner to the SD
+ //
+
+ if( AFSRtlSetGroupSecurityDescriptor != NULL)
+ {
+ ntStatus = AFSRtlSetGroupSecurityDescriptor( pSecurityDescr,
+ pWorldSID,
+ FALSE);
+
+ if( !NT_SUCCESS( ntStatus))
+ {
+
+ AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetGroupSecurityDescriptor failed ntStatus %08lX\n",
+ ntStatus);
+
+ try_return( ntStatus);
+ }
+ }
+
+ ntStatus = RtlSetOwnerSecurityDescriptor( pSecurityDescr,
+ pWorldSID,
+ FALSE);
+
+ if( !NT_SUCCESS( ntStatus))
+ {
+
+ AFSPrint( "AFSCreateDefaultSecurityDescriptor RtlSetOwnerSecurityDescriptor failed ntStatus %08lX\n",
+ ntStatus);
+
+ try_return( ntStatus);
+ }
+
if( !RtlValidSecurityDescriptor( pSecurityDescr))
{
{
ExFreePool( pACE);
}
+
+ if( pWorldSID != NULL)
+ {
+ ExFreePool( pWorldSID);
+ }
}
return ntStatus;
}
+
+void
+AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
+ OUT UNICODE_STRING *ParentPath)
+{
+
+ USHORT usIndex = 0;
+
+ *ParentPath = *FullFileName;
+
+ //
+ // If the final character is a \, jump over it
+ //
+
+ if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
+ {
+ ParentPath->Length -= sizeof( WCHAR);
+ }
+
+ while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
+ {
+ ParentPath->Length -= sizeof( WCHAR);
+ }
+
+ //
+ // And the separator
+ //
+
+ ParentPath->Length -= sizeof( WCHAR);
+
+ return;
+}
+