]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
Windows: Obtain File Attribs for DFS Link target
authorpete scott <pscott@kerneldrivers.com>
Wed, 13 Aug 2014 19:28:49 +0000 (15:28 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Wed, 20 Aug 2014 16:54:09 +0000 (12:54 -0400)
The AFSRetrieveFileAttributes() function is used to acquire the
attributes for an AFS symlink.  The result is either returned directly
to the application or used internally to determine the attributes
to be exposed by reparse points.

If the evaluated symlink crosses a DFS Link the redirector cannot
return the request to IO Manager to evaluate the target.  Instead
the redirector must handle the request internally and attempt to
read the attributes of the target object.

Change-Id: If14df8dc41e13fd59b524fdb575c46abab1dfc2f
Reviewed-on: http://gerrit.openafs.org/11399
Reviewed-by: Peter Scott <pscott@kerneldrivers.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
src/WINNT/afsrdr/kernel/lib/AFSCreate.cpp
src/WINNT/afsrdr/kernel/lib/AFSGeneric.cpp
src/WINNT/afsrdr/kernel/lib/AFSNameSupport.cpp
src/WINNT/afsrdr/kernel/lib/Include/AFSCommon.h

index 71d18fb708dc819f9bbbe739629b6eef2dd11e99..9ce2635e09fdf4072bc744904e498529cb56fe06 100644 (file)
@@ -464,7 +464,8 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                                               &NewVolumeReferenceReason,
                                               &pNewParentDirectoryCB,
                                               &pDirectoryCB,
-                                              &uniComponentName);
+                                              &uniComponentName,
+                                              NULL);
 
                if ( pNewVolumeCB != NULL)
                {
@@ -697,7 +698,8 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                                               &NewVolumeReferenceReason,
                                               &pNewParentDirectoryCB,
                                               &pDirectoryCB,
-                                              &uniComponentName);
+                                              &uniComponentName,
+                                              NULL);
 
                if ( ntStatus == STATUS_SUCCESS ||
                     ntStatus == STATUS_OBJECT_NAME_NOT_FOUND ||
@@ -815,7 +817,8 @@ AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
                                                       &NewVolumeReferenceReason,
                                                       &pNewParentDirectoryCB,
                                                       &pDirectoryCB,
-                                                      &uniComponentName);
+                                                      &uniComponentName,
+                                                      NULL);
                    }
                }
                else
index abf4bfd5947850ef1f18632ec89b37e4f3eb1a2e..ffb96c4fe33140285533a409753a0aac934e67c2 100644 (file)
@@ -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)
         {
@@ -8402,7 +8427,8 @@ AFSGetObjectStatus( IN AFSGetStatusInfoCB *GetStatusInfo,
                                            &NewVolumeReferenceReason,
                                            &pNewParentDirEntry,
                                            &pDirectoryEntry,
-                                           NULL);
+                                           NULL,
+                                          NULL);
 
             if ( pNewVolumeCB != NULL)
             {
@@ -9901,3 +9927,78 @@ 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;
+}
index bf78512419b77a40b065e03decb1e5338110f97f..7a70e1a82caaabb50ddf510e61bc2cac8e78c162 100644 (file)
@@ -65,7 +65,8 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     OUT LONG *OutVolumeReferenceReason,
                     OUT AFSDirectoryCB **OutParentDirectoryCB,
                     OUT AFSDirectoryCB **OutDirectoryCB,
-                    OUT PUNICODE_STRING ComponentName)
+                    OUT PUNICODE_STRING ComponentName,
+                   OUT PUNICODE_STRING TargetName)
 {
 
     NTSTATUS          ntStatus = STATUS_SUCCESS;
@@ -1154,13 +1155,15 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     // system for it to reevaluate it
                     //
 
-                    if( FileObject != NULL)
+                    if( FileObject != NULL ||
+                       TargetName != NULL)
                     {
 
                         ntStatus = AFSProcessDFSLink( pDirEntry,
                                                       FileObject,
                                                       &uniRemainingPath,
-                                                      AuthGroup);
+                                                      AuthGroup,
+                                                     TargetName);
                     }
                     else
                     {
@@ -4992,7 +4995,8 @@ NTSTATUS
 AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
                    IN PFILE_OBJECT FileObject,
                    IN UNICODE_STRING *RemainingPath,
-                   IN GUID *AuthGroup)
+                   IN GUID *AuthGroup,
+                  OUT PUNICODE_STRING TargetName)
 {
 
     NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
@@ -5004,7 +5008,14 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
     __Enter
     {
 
-        //
+       if ( FileObject != NULL && TargetName != NULL ||
+            FileObject == NULL && TargetName == NULL)
+       {
+
+           try_return( ntStatus = STATUS_INVALID_PARAMETER);
+       }
+
+       //
         // Build up the name to reparse
         //
 
@@ -5103,8 +5114,8 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
         }
 
         //
-        // Allocate the reparse buffer
-        //
+       // Allocate the reparse buffer (from FS because might be returned in FileObject)
+       //
 
         uniReparseName.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool,
                                                                    uniReparseName.MaximumLength,
@@ -5188,17 +5199,29 @@ AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
             uniReparseName.Length += RemainingPath->Length;
         }
 
-        //
-        // Update the name in the file object
-        //
-
-        if( FileObject->FileName.Buffer != NULL)
+       if( FileObject != NULL)
         {
+           //
+           // Update the name in the file object
+           //
+
+           if( FileObject->FileName.Buffer != NULL)
+           {
 
-            AFSExFreePoolWithTag( FileObject->FileName.Buffer, 0);
+               //
+               // original FileObject buffer was not allocated by AFS
+               //
+
+               ExFreePoolWithTag( FileObject->FileName.Buffer, 0);
+           }
+
+           FileObject->FileName = uniReparseName;
         }
+       else
+       {
 
-        FileObject->FileName = uniReparseName;
+           *TargetName = uniReparseName;
+       }
 
         AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
                       AFS_TRACE_LEVEL_VERBOSE,
index 07255272e9ae6e7f6d3af1e8f5d5d25ec7feb907..f85396078fecad6659cf4189da3b63b14a813267 100644 (file)
@@ -574,7 +574,8 @@ AFSLocateNameEntry( IN GUID *AuthGroup,
                     OUT LONG *OutVolumeReferenceReason,
                     OUT AFSDirectoryCB **OutParentDirectoryCB,
                     OUT AFSDirectoryCB **OutDirectoryCB,
-                    OUT PUNICODE_STRING ComponentName);
+                    OUT PUNICODE_STRING ComponentName,
+                   OUT PUNICODE_STRING TargetName);
 
 NTSTATUS
 AFSCreateDirEntry( IN GUID            *AuthGroup,
@@ -632,8 +633,9 @@ AFSBuildRootVolume( IN GUID *AuthGroup,
 NTSTATUS
 AFSProcessDFSLink( IN AFSDirectoryCB *DirEntry,
                    IN PFILE_OBJECT FileObject,
-                   IN UNICODE_STRING *RemainingPath,
-                   IN GUID *AuthGroup);
+                   IN PUNICODE_STRING RemainingPath,
+                   IN GUID *AuthGroup,
+                  OUT PUNICODE_STRING TargetName);
 
 //
 // AFSNetworkProviderSupport.cpp
@@ -1456,6 +1458,10 @@ AFSPerformObjectInvalidate( IN AFSObjectInfoCB *ObjectInfo,
 BOOLEAN
 AFSIgnoreReparsePointToFile( void);
 
+NTSTATUS
+AFSRetrieveTargetFileInfo( IN PUNICODE_STRING TargetName,
+                          OUT AFSFileInfoCB *FileInfo);
+
 //
 // AFSNameArray.cpp Prototypes
 //