Windows: AFSRetrieveParentPath handle no parent
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSGeneric.cpp
index c889513..2594416 100644 (file)
@@ -1941,7 +1941,7 @@ AFSInvalidateObject( IN OUT AFSObjectInfoCB **ppObjectInfo,
                         }
                     }
                 }
-               __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+               __except( EXCEPTION_EXECUTE_HANDLER)
                 {
 
                     ntStatus = GetExceptionCode();
@@ -2474,7 +2474,7 @@ AFSSubstituteSysName( IN UNICODE_STRING *ComponentName,
             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE_2,
                           "AFSSubstituteSysName No sysname %wZ Status %08lX\n",
-                          &ComponentName,
+                         ComponentName,
                           STATUS_OBJECT_NAME_NOT_FOUND));
 
             try_return( ntStatus = STATUS_OBJECT_NAME_NOT_FOUND);
@@ -3160,7 +3160,7 @@ AFSVerifyEntry( IN GUID *AuthGroup,
                             }
                         }
                     }
-                   __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+                   __except( EXCEPTION_EXECUTE_HANDLER)
                     {
                         ntStatus = GetExceptionCode();
 
@@ -4371,7 +4371,7 @@ AFSValidateEntry( IN AFSDirectoryCB *DirEntry,
                                }
                            }
                        }
-                       __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+                       __except( EXCEPTION_EXECUTE_HANDLER)
                        {
                            ntStatus = GetExceptionCode();
 
@@ -5683,11 +5683,16 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
     UNICODE_STRING uniComponentName, uniRemainingPath, uniParsedName;
     ULONG ulNameDifference = 0;
     LONG lCount;
+    UNICODE_STRING uniDFSTargetName;
 
     __Enter
     {
 
-        //
+       uniDFSTargetName.Length = 0;
+       uniDFSTargetName.MaximumLength = 0;
+       uniDFSTargetName.Buffer = NULL;
+
+       //
         // Retrieve a target name for the entry
         //
 
@@ -5964,7 +5969,8 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
                                        &NewVolumeReferenceReason,
                                        &pNewParentDirEntry,
                                        &pDirectoryEntry,
-                                       NULL);
+                                       NULL,
+                                      &uniDFSTargetName);
 
         if ( pNewVolumeCB != NULL)
         {
@@ -6014,10 +6020,21 @@ AFSRetrieveFileAttributes( IN AFSDirectoryCB *ParentDirectoryCB,
 
         pNewParentDirEntry = NULL;
 
-        if( !NT_SUCCESS( ntStatus) ||
-            ntStatus == STATUS_REPARSE)
+       if( !NT_SUCCESS( ntStatus))
+       {
+           try_return( ntStatus);
+       }
+
+       //
+       // If the status is STATUS_REPARSE then attempt to retrieve the attributes from the target name returned
+       //
+
+       if( ntStatus == STATUS_REPARSE)
         {
 
+           ntStatus = AFSRetrieveTargetFileInfo( &uniDFSTargetName,
+                                                 FileInfo);
+
             try_return( ntStatus);
         }
 
@@ -6144,6 +6161,13 @@ try_exit:
 
             AFSExFreePoolWithTag( pwchBuffer, 0);
         }
+
+       if ( uniDFSTargetName.Buffer != NULL)
+       {
+
+           AFSExFreePoolWithTag( uniDFSTargetName.Buffer,
+                                 AFS_REPARSE_NAME_TAG);
+       }
     }
 
     return ntStatus;
@@ -6808,7 +6832,8 @@ AFSEvaluateRootEntry( IN AFSDirectoryCB *DirectoryCB,
                                        &VolumeReferenceReason,
                                        &pNewParentDirEntry,
                                        &pDirectoryEntry,
-                                       NULL);
+                                       NULL,
+                                      NULL);
 
         if ( pNewVolumeCB != NULL)
         {
@@ -7051,7 +7076,7 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                             }
                         }
                     }
-                   __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+                   __except( EXCEPTION_EXECUTE_HANDLER)
                     {
 
                         ntStatus = GetExceptionCode();
@@ -7247,7 +7272,7 @@ AFSCleanupFcb( IN AFSFcb *Fcb,
                         }
                     }
                 }
-               __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+               __except( EXCEPTION_EXECUTE_HANDLER)
                 {
 
                     ntStatus = GetExceptionCode();
@@ -8402,7 +8427,8 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                                            &NewVolumeReferenceReason,
                                            &pNewParentDirEntry,
                                            &pDirectoryEntry,
-                                           NULL);
+                                           NULL,
+                                          NULL);
 
             if ( pNewVolumeCB != NULL)
             {
@@ -9091,12 +9117,14 @@ AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
     // If the final character is a \, jump over it
     //
 
-    if( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
+    if( ParentPath->Length >= sizeof( WCHAR)
+       && ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] == L'\\')
     {
         ParentPath->Length -= sizeof( WCHAR);
     }
 
-    while( ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
+    while( ParentPath->Length >= sizeof( WCHAR)
+          && ParentPath->Buffer[ (ParentPath->Length/sizeof( WCHAR)) - 1] != L'\\')
     {
         ParentPath->Length -= sizeof( WCHAR);
     }
@@ -9105,7 +9133,10 @@ AFSRetrieveParentPath( IN UNICODE_STRING *FullFileName,
     // And the separator
     //
 
-    ParentPath->Length -= sizeof( WCHAR);
+    if ( ParentPath->Length >= sizeof( WCHAR))
+    {
+       ParentPath->Length -= sizeof( WCHAR);
+    }
 
     return;
 }
@@ -9335,7 +9366,7 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                                SetFlag( ObjectInfo->Flags, AFS_OBJECT_FLAGS_VERIFY_DATA);
                             }
                         }
-                       __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+                       __except( EXCEPTION_EXECUTE_HANDLER)
                         {
 
                             ntStatus = GetExceptionCode();
@@ -9483,7 +9514,7 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                                             bCleanExtents = TRUE;
                                         }
                                     }
-                                   __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
+                                   __except( EXCEPTION_EXECUTE_HANDLER)
                                     {
 
                                         ntStatus = GetExceptionCode();
@@ -9564,28 +9595,46 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
 
                                                 ulSize = ByteRangeList[ulIndex].Length.QuadPart > DWORD_MAX ? DWORD_MAX : ByteRangeList[ulIndex].Length.LowPart;
 
-                                                if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
-                                                    !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                                          &ByteRangeList[ulIndex].FileOffset,
-                                                                          ulSize,
-                                                                          FALSE))
-                                                {
-
-                                                    AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
-                                                                  AFS_TRACE_LEVEL_WARNING,
-                                                                  "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
-                                                                  ObjectInfo->FileId.Cell,
-                                                                  ObjectInfo->FileId.Volume,
-                                                                  ObjectInfo->FileId.Vnode,
-                                                                  ObjectInfo->FileId.Unique));
-
-                                                    bPurgeOnClose = TRUE;
-                                                }
-                                                else
-                                                {
-
-                                                    bCleanExtents = TRUE;
-                                                }
+                                               __try
+                                               {
+
+                                                   if( ObjectInfo->Fcb->NPFcb->SectionObjectPointers.DataSectionObject != NULL &&
+                                                       !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                             &ByteRangeList[ulIndex].FileOffset,
+                                                                             ulSize,
+                                                                             FALSE))
+                                                   {
+
+                                                       AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+                                                                     AFS_TRACE_LEVEL_WARNING,
+                                                                     "AFSPerformObjectInvalidation [1] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                                                     ObjectInfo->FileId.Cell,
+                                                                     ObjectInfo->FileId.Volume,
+                                                                     ObjectInfo->FileId.Vnode,
+                                                                     ObjectInfo->FileId.Unique));
+
+                                                       bPurgeOnClose = TRUE;
+                                                   }
+                                                   else
+                                                   {
+
+                                                       bCleanExtents = TRUE;
+                                                   }
+                                               }
+                                               __except( EXCEPTION_EXECUTE_HANDLER)
+                                               {
+
+                                                   ntStatus = GetExceptionCode();
+
+                                                   AFSDbgTrace(( 0,
+                                                                 0,
+                                                                 "EXCEPTION - AFSPerformObjectInvalidation CcPurgeCacheSection (1) FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                                                                 ObjectInfo->FileId.Cell,
+                                                                 ObjectInfo->FileId.Volume,
+                                                                 ObjectInfo->FileId.Vnode,
+                                                                 ObjectInfo->FileId.Unique,
+                                                                 ntStatus));
+                                               }
 
                                                 ByteRangeList[ulIndex].Length.QuadPart -= ulSize;
 
@@ -9623,27 +9672,44 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
 
                                                 if( !BooleanFlagOn( pEntry->Flags, AFS_EXTENT_DIRTY))
                                                 {
-                                                    if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                                              &pEntry->FileOffset,
-                                                                              pEntry->Size,
-                                                                              FALSE))
-                                                    {
-
-                                                        AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
-                                                                      AFS_TRACE_LEVEL_WARNING,
-                                                                      "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
-                                                                      ObjectInfo->FileId.Cell,
-                                                                      ObjectInfo->FileId.Volume,
-                                                                      ObjectInfo->FileId.Vnode,
-                                                                      ObjectInfo->FileId.Unique));
-
-                                                        bPurgeOnClose = TRUE;
-                                                    }
-                                                    else
-                                                    {
-
-                                                        bCleanExtents = TRUE;
-                                                    }
+                                                   __try
+                                                   {
+                                                       if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                                 &pEntry->FileOffset,
+                                                                                 pEntry->Size,
+                                                                                 FALSE))
+                                                       {
+
+                                                           AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+                                                                         AFS_TRACE_LEVEL_WARNING,
+                                                                         "AFSPerformObjectInvalidation [2] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                                                         ObjectInfo->FileId.Cell,
+                                                                         ObjectInfo->FileId.Volume,
+                                                                         ObjectInfo->FileId.Vnode,
+                                                                         ObjectInfo->FileId.Unique));
+
+                                                           bPurgeOnClose = TRUE;
+                                                       }
+                                                       else
+                                                       {
+
+                                                           bCleanExtents = TRUE;
+                                                       }
+                                                   }
+                                                   __except( EXCEPTION_EXECUTE_HANDLER)
+                                                   {
+
+                                                       ntStatus = GetExceptionCode();
+
+                                                       AFSDbgTrace(( 0,
+                                                                     0,
+                                                                     "EXCEPTION - AFSPerformObjectInvalidation CcPurgeCacheSection (2) FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                                                                     ObjectInfo->FileId.Cell,
+                                                                     ObjectInfo->FileId.Volume,
+                                                                     ObjectInfo->FileId.Vnode,
+                                                                     ObjectInfo->FileId.Unique,
+                                                                     ntStatus));
+                                                   }
                                                 }
 
                                                 if( liCurrentOffset.QuadPart < pEntry->FileOffset.QuadPart)
@@ -9663,27 +9729,44 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                                                             ulFlushLength = liFlushLength.LowPart;
                                                         }
 
-                                                        if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                                                  &liCurrentOffset,
-                                                                                  ulFlushLength,
-                                                                                  FALSE))
-                                                        {
-
-                                                            AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
-                                                                          AFS_TRACE_LEVEL_WARNING,
-                                                                          "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
-                                                                          ObjectInfo->FileId.Cell,
-                                                                          ObjectInfo->FileId.Volume,
-                                                                          ObjectInfo->FileId.Vnode,
-                                                                          ObjectInfo->FileId.Unique));
-
-                                                            bPurgeOnClose = TRUE;
-                                                        }
-                                                        else
-                                                        {
-
-                                                            bCleanExtents = TRUE;
-                                                        }
+                                                       __try
+                                                       {
+                                                           if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                                     &liCurrentOffset,
+                                                                                     ulFlushLength,
+                                                                                     FALSE))
+                                                           {
+
+                                                               AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+                                                                             AFS_TRACE_LEVEL_WARNING,
+                                                                             "AFSPerformObjectInvalidation [3] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                                                             ObjectInfo->FileId.Cell,
+                                                                             ObjectInfo->FileId.Volume,
+                                                                             ObjectInfo->FileId.Vnode,
+                                                                             ObjectInfo->FileId.Unique));
+
+                                                               bPurgeOnClose = TRUE;
+                                                           }
+                                                           else
+                                                           {
+
+                                                               bCleanExtents = TRUE;
+                                                           }
+                                                       }
+                                                       __except( EXCEPTION_EXECUTE_HANDLER)
+                                                       {
+
+                                                           ntStatus = GetExceptionCode();
+
+                                                           AFSDbgTrace(( 0,
+                                                                         0,
+                                                                         "EXCEPTION - AFSPerformObjectInvalidation CcPurgeCacheSection (3) FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                                                                         ObjectInfo->FileId.Cell,
+                                                                         ObjectInfo->FileId.Volume,
+                                                                         ObjectInfo->FileId.Vnode,
+                                                                         ObjectInfo->FileId.Unique,
+                                                                         ntStatus));
+                                                       }
 
                                                         liFlushLength.QuadPart -= ulFlushLength;
                                                     }
@@ -9697,27 +9780,44 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
                                         }
                                         else
                                         {
-                                            if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
-                                                                      NULL,
-                                                                      0,
-                                                                      FALSE))
-                                            {
-
-                                                AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
-                                                              AFS_TRACE_LEVEL_WARNING,
-                                                              "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
-                                                              ObjectInfo->FileId.Cell,
-                                                              ObjectInfo->FileId.Volume,
-                                                              ObjectInfo->FileId.Vnode,
-                                                              ObjectInfo->FileId.Unique));
-
-                                                bPurgeOnClose = TRUE;
-                                            }
-                                            else
-                                            {
-
-                                                bCleanExtents = TRUE;
-                                            }
+                                           __try
+                                           {
+                                               if( !CcPurgeCacheSection( &ObjectInfo->Fcb->NPFcb->SectionObjectPointers,
+                                                                         NULL,
+                                                                         0,
+                                                                         FALSE))
+                                               {
+
+                                                   AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
+                                                                 AFS_TRACE_LEVEL_WARNING,
+                                                                 "AFSPerformObjectInvalidation [4] CcPurgeCacheSection failure FID %08lX-%08lX-%08lX-%08lX\n",
+                                                                 ObjectInfo->FileId.Cell,
+                                                                 ObjectInfo->FileId.Volume,
+                                                                 ObjectInfo->FileId.Vnode,
+                                                                 ObjectInfo->FileId.Unique));
+
+                                                   bPurgeOnClose = TRUE;
+                                               }
+                                               else
+                                               {
+
+                                                   bCleanExtents = TRUE;
+                                               }
+                                           }
+                                           __except( EXCEPTION_EXECUTE_HANDLER)
+                                           {
+
+                                               ntStatus = GetExceptionCode();
+
+                                               AFSDbgTrace(( 0,
+                                                             0,
+                                                             "EXCEPTION - AFSPerformObjectInvalidation CcPurgeCacheSection (4) FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
+                                                             ObjectInfo->FileId.Cell,
+                                                             ObjectInfo->FileId.Volume,
+                                                             ObjectInfo->FileId.Vnode,
+                                                             ObjectInfo->FileId.Unique,
+                                                             ntStatus));
+                                           }
                                         }
 
                                         if ( bPurgeOnClose)
@@ -9832,3 +9932,104 @@ AFSIgnoreReparsePointToFile( void)
 
     return bIgnoreReparsePoint;
 }
+
+NTSTATUS
+AFSRetrieveTargetFileInfo( IN PUNICODE_STRING TargetName,
+                          OUT AFSFileInfoCB *FileInfo)
+{
+
+    NTSTATUS ntStatus = STATUS_SUCCESS;
+    OBJECT_ATTRIBUTES stObjectAttribs;
+    HANDLE hFile = NULL;
+    IO_STATUS_BLOCK stIoStatus;
+    FILE_NETWORK_OPEN_INFORMATION stFileInfo;
+
+    __Enter
+    {
+
+       InitializeObjectAttributes( &stObjectAttribs,
+                                   TargetName,
+                                   OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
+                                   NULL,
+                                   NULL);
+
+       ntStatus = ZwCreateFile( &hFile,
+                                FILE_READ_ATTRIBUTES,
+                                &stObjectAttribs,
+                                &stIoStatus,
+                                NULL,
+                                0,
+                                FILE_SHARE_READ | FILE_SHARE_WRITE,
+                                FILE_OPEN,
+                                FILE_SYNCHRONOUS_IO_NONALERT,
+                                NULL,
+                                0);
+
+       if( !NT_SUCCESS( ntStatus))
+       {
+
+           try_return( ntStatus);
+       }
+
+       ntStatus = ZwQueryInformationFile( hFile,
+                                          &stIoStatus,
+                                          &stFileInfo,
+                                          sizeof( FILE_NETWORK_OPEN_INFORMATION),
+                                          FileNetworkOpenInformation);
+
+       if( !NT_SUCCESS( ntStatus))
+       {
+
+           try_return( ntStatus);
+       }
+
+       FileInfo->FileAttributes = stFileInfo.FileAttributes;
+
+       FileInfo->AllocationSize = stFileInfo.AllocationSize;
+
+       FileInfo->EndOfFile = stFileInfo.EndOfFile;
+
+       FileInfo->CreationTime = stFileInfo.CreationTime;
+
+       FileInfo->LastAccessTime = stFileInfo.LastAccessTime;
+
+       FileInfo->LastWriteTime = stFileInfo.LastWriteTime;
+
+       FileInfo->ChangeTime = stFileInfo.ChangeTime;
+
+try_exit:
+
+       if( hFile != NULL)
+       {
+           ZwClose( hFile);
+       }
+    }
+
+    return ntStatus;
+}
+
+BOOLEAN
+AFSIsShareName( IN UNICODE_STRING *FileName)
+{
+
+    BOOLEAN     bIsShareName = TRUE;
+    USHORT      usIndex = 1; // Skip the first \
+
+    //
+    // A share name will be of the form \Share so only a single \ at the beginning
+    //
+
+    while( usIndex < FileName->Length/sizeof( WCHAR))
+    {
+
+       if( FileName->Buffer[ usIndex] == L'\\')
+       {
+           bIsShareName = FALSE;
+           break;
+       }
+
+       usIndex++;
+    }
+
+    return bIsShareName;
+}
\ No newline at end of file