Windows: Fix AFSSetBasicInfo attribute processing
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSFileInfo.cpp
index 18eafc3..43e895b 100644 (file)
@@ -109,6 +109,14 @@ AFSQueryFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
             if ( NT_SUCCESS( ntStatus))
             {
 
+               AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                             AFS_TRACE_LEVEL_VERBOSE,
+                             "AFSQueryFileInfo FID %08lX-%08lX-%08lX-%08lX Clearing Verify Flag\n",
+                             pFcb->ObjectInformation->FileId.Cell,
+                             pFcb->ObjectInformation->FileId.Volume,
+                             pFcb->ObjectInformation->FileId.Vnode,
+                             pFcb->ObjectInformation->FileId.Unique));
+
                 ClearFlag( pFcb->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
             }
             else
@@ -584,7 +592,8 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
             try_return( ntStatus);
         }
 
-        if( BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
+       if( FileInformationClass != FilePositionInformation &&
+           BooleanFlagOn( pFcb->ObjectInformation->VolumeCB->VolumeInformation.FileSystemAttributes, FILE_READ_ONLY_VOLUME))
         {
 
             AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
@@ -638,10 +647,9 @@ AFSSetFileInfo( IN PDEVICE_OBJECT LibDeviceObject,
             case FileBasicInformation:
             {
 
-                bUpdateFileInfo = TRUE;
-
                 ntStatus = AFSSetBasicInfo( Irp,
-                                            pCcb->DirectoryCB);
+                                           pCcb->DirectoryCB,
+                                           &bUpdateFileInfo);
 
                 break;
             }
@@ -1903,7 +1911,8 @@ AFSQueryPhysicalNameInfo( IN PIRP Irp,
 
 NTSTATUS
 AFSSetBasicInfo( IN PIRP Irp,
-                 IN AFSDirectoryCB *DirectoryCB)
+                IN AFSDirectoryCB *DirectoryCB,
+                OUT BOOLEAN *bUpdateFileInfo)
 {
     NTSTATUS ntStatus = STATUS_SUCCESS;
     PFILE_BASIC_INFORMATION pBuffer;
@@ -1923,26 +1932,92 @@ AFSSetBasicInfo( IN PIRP Irp,
         if( pBuffer->FileAttributes != (ULONGLONG)0)
         {
 
-            if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_FILE_FCB &&
-                BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_DIRECTORY))
-            {
+           //
+           // Make sure that the reparse point attribute is not modified.
+           // Fail if the RP attribute is requested but it is not
+           // already a RP.  Otherwise, ignore it.
+           //
 
-                try_return( ntStatus = STATUS_INVALID_PARAMETER);
-            }
+           if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
+                                FILE_ATTRIBUTE_REPARSE_POINT) &&
+                BooleanFlagOn( pBuffer->FileAttributes,
+                               FILE_ATTRIBUTE_REPARSE_POINT))
+           {
 
-            if( DirectoryCB->ObjectInformation->Fcb->Header.NodeTypeCode == AFS_DIRECTORY_FCB)
-            {
+               try_return( ntStatus = STATUS_INVALID_PARAMETER);
+           }
 
-                pBuffer->FileAttributes |= FILE_ATTRIBUTE_DIRECTORY;
-            }
+           //
+           // Make sure that the directory attribute is not modified.
+           // Fail if the D attribute is requested but it is not
+           // already a directory.  Otherwise, ignore it.
+           //
+
+           if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
+                                FILE_ATTRIBUTE_DIRECTORY) &&
+                BooleanFlagOn( pBuffer->FileAttributes,
+                               FILE_ATTRIBUTE_DIRECTORY))
+           {
+
+               try_return( ntStatus = STATUS_INVALID_PARAMETER);
+           }
+
+           //
+           // Save the original value
+           //
+
+           pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
+
+           if( BooleanFlagOn( pBuffer->FileAttributes, FILE_ATTRIBUTE_READONLY))
+           {
+
+               //
+               // Set the readonly flag.
+               //
+
+               if ( !BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
+                                    FILE_ATTRIBUTE_READONLY))
+               {
+
+                   if ( DirectoryCB->ObjectInformation->FileAttributes == FILE_ATTRIBUTE_NORMAL)
+                   {
+
+                       DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_READONLY;
+                   }
+                   else
+                   {
+
+                       DirectoryCB->ObjectInformation->FileAttributes |= FILE_ATTRIBUTE_READONLY;
+                   }
+
+                   ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+
+                   SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
+               }
+           }
+           else
+           {
+               //
+               // Reset the readonly flag.
+               //
 
-            pCcb->FileUnwindInfo.FileAttributes = DirectoryCB->ObjectInformation->FileAttributes;
+               if ( BooleanFlagOn( DirectoryCB->ObjectInformation->FileAttributes,
+                                   FILE_ATTRIBUTE_READONLY))
+               {
 
-            DirectoryCB->ObjectInformation->FileAttributes = pBuffer->FileAttributes;
+                   DirectoryCB->ObjectInformation->FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
 
-            ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+                   if ( DirectoryCB->ObjectInformation->FileAttributes == 0)
+                   {
 
-            SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
+                       DirectoryCB->ObjectInformation->FileAttributes = FILE_ATTRIBUTE_NORMAL;
+                   }
+
+                   ulNotifyFilter |= FILE_NOTIFY_CHANGE_ATTRIBUTES;
+
+                   SetFlag( DirectoryCB->ObjectInformation->Fcb->Flags, AFS_FCB_FLAG_FILE_MODIFIED);
+               }
+           }
         }
 
         pCcb->FileUnwindInfo.CreationTime.QuadPart = (ULONGLONG)-1;
@@ -2008,6 +2083,8 @@ AFSSetBasicInfo( IN PIRP Irp,
         if( ulNotifyFilter > 0)
         {
 
+           *bUpdateFileInfo = TRUE;
+
             if( BooleanFlagOn( DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_PARENT_FID))
             {
 
@@ -2201,7 +2278,16 @@ AFSSetDispositionInfo( IN PIRP Irp,
             {
                 BOOLEAN bMmFlushed;
 
-                AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+               AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                             AFS_TRACE_LEVEL_VERBOSE,
+                             "AFSSetDispositionInfo Acquiring Fcb lock %p EXCL %08lX\n",
+                             &pFcb->NPFcb->Resource,
+                             PsGetCurrentThread()));
+
+               AFSAcquireExcl( &pFcb->NPFcb->Resource,
+                               TRUE);
+
+               AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSSetDispositionInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
                               &pFcb->NPFcb->SectionObjectResource,
@@ -2272,7 +2358,7 @@ AFSSetDispositionInfo( IN PIRP Irp,
                                  ntStatus));
                }
 
-                AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+               AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSSetDispositionInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
                               &pFcb->NPFcb->SectionObjectResource,
@@ -2280,6 +2366,14 @@ AFSSetDispositionInfo( IN PIRP Irp,
 
                 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
 
+               AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+                             AFS_TRACE_LEVEL_VERBOSE,
+                             "AFSSetDispositionInfo Releasing Fcb lock %p EXCL %08lX\n",
+                             &pFcb->NPFcb->Resource,
+                             PsGetCurrentThread()));
+
+               AFSReleaseResource( &pFcb->NPFcb->Resource);
+
                 if ( !bMmFlushed)
                 {
 
@@ -3453,7 +3547,7 @@ AFSSetRenameInfo( IN PIRP Irp)
                 // permit the locks to be obtained out of order risking a deadlock.
                 //
 
-                AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+               AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSSetRenameInfo Acquiring Fcb lock %p EXCL %08lX\n",
                               &pTargetFcb->NPFcb->Resource,
@@ -3462,7 +3556,7 @@ AFSSetRenameInfo( IN PIRP Irp)
                 AFSAcquireExcl( &pTargetFcb->NPFcb->Resource,
                                 TRUE);
 
-                AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+               AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSSetRenameInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
                               &pTargetFcb->NPFcb->SectionObjectResource,
@@ -3488,7 +3582,7 @@ AFSSetRenameInfo( IN PIRP Irp)
                                      &uniTargetName));
                    }
                }
-               __except( EXCEPTION_EXECUTE_HANDLER)
+               __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
                 {
 
                    ntStatus = GetExceptionCode();
@@ -3503,7 +3597,7 @@ AFSSetRenameInfo( IN PIRP Irp)
                                  ntStatus));
                 }
 
-                AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+               AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
                               AFS_TRACE_LEVEL_VERBOSE,
                               "AFSSetRenameInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
                               &pTargetFcb->NPFcb->SectionObjectResource,
@@ -3645,7 +3739,7 @@ AFSSetAllocationInfo( IN PIRP Irp,
     if( pFcb->Header.AllocationSize.QuadPart > pBuffer->AllocationSize.QuadPart)
     {
 
-        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+       AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSSetAllocationInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
                       &pFcb->NPFcb->SectionObjectResource,
@@ -3660,7 +3754,7 @@ AFSSetAllocationInfo( IN PIRP Irp,
            bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
                                                 &pBuffer->AllocationSize);
        }
-       __except( EXCEPTION_EXECUTE_HANDLER)
+       __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
        {
 
            bUserMapped = FALSE;
@@ -3677,7 +3771,7 @@ AFSSetAllocationInfo( IN PIRP Irp,
                          ntStatus));
        }
 
-        AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+       AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
                       AFS_TRACE_LEVEL_VERBOSE,
                       "AFSSetAllocationInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
                       &pFcb->NPFcb->SectionObjectResource,
@@ -3871,7 +3965,7 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
         if( pBuffer->EndOfFile.QuadPart < pFcb->Header.FileSize.QuadPart)
         {
 
-            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+           AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSSetEndOfFileInfo Acquiring Fcb SectionObject lock %p EXCL %08lX\n",
                           &pFcb->NPFcb->SectionObjectResource,
@@ -3886,7 +3980,7 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
                bUserMapped = !MmCanFileBeTruncated( pFileObject->SectionObjectPointer,
                                                     &pBuffer->EndOfFile);
            }
-           __except( EXCEPTION_EXECUTE_HANDLER)
+           __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()))
            {
 
                bUserMapped = FALSE;
@@ -3903,7 +3997,7 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
                              ntStatus));
            }
 
-            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
+           AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING|AFS_SUBSYSTEM_SECTION_OBJECT,
                           AFS_TRACE_LEVEL_VERBOSE,
                           "AFSSetEndOfFileInfo Releasing Fcb SectionObject lock %p EXCL %08lX\n",
                           &pFcb->NPFcb->SectionObjectResource,
@@ -3926,7 +4020,7 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
                 //
                 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE,
-                              "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
+                             "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
                               &pFcb->NPFcb->PagingResource,
                               PsGetCurrentThread()));
 
@@ -3975,7 +4069,7 @@ AFSSetEndOfFileInfo( IN PIRP Irp,
             //
             AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                           AFS_TRACE_LEVEL_VERBOSE,
-                          "AFSSetAllocationInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
+                         "AFSSetEndOfFileInfo Acquiring Fcb PagingIo lock %p EXCL %08lX\n",
                           &pFcb->NPFcb->PagingResource,
                           PsGetCurrentThread()));