Windows: AFSProcessUserFsRequest NULL dereference
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSFSControl.cpp
index e9e2bd6..a892166 100644 (file)
@@ -77,12 +77,14 @@ AFSFSControl( IN PDEVICE_OBJECT LibDeviceObject,
                               ntStatus);
 
     }
-    __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
+    __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
     {
 
         AFSDbgLogMsg( 0,
                       0,
                       "EXCEPTION - AFSFSControl\n");
+
+        AFSDumpTraceFilesFnc();
     }
 
     return ntStatus;
@@ -115,7 +117,8 @@ AFSParseMountPointTarget( IN  UNICODE_STRING *Target,
 
     // If a colon is not found, it means there is no cell
 
-    if ( Cell->Buffer[ Cell->Length / sizeof( WCHAR)] == L':')
+    if ( Cell->Length < Target->Length - sizeof( WCHAR) &&
+         Cell->Buffer[ Cell->Length / sizeof( WCHAR)] == L':')
     {
 
         Cell->MaximumLength = Cell->Length;
@@ -169,6 +172,7 @@ AFSProcessUserFsRequest( IN PIRP Irp)
         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
 
         if( pFcb == NULL ||
+            pCcb == NULL ||
             pCcb->DirectoryCB == NULL)
         {
 
@@ -207,7 +211,7 @@ AFSProcessUserFsRequest( IN PIRP Irp)
             case FSCTL_OPLOCK_BREAK_NOTIFY:
             case FSCTL_OPLOCK_BREAK_ACK_NO_2:
             case FSCTL_REQUEST_FILTER_OPLOCK :
-
+            {
                 //
                 // Note that implementing this call will probably need us
                 // to call the server as well as adding code in read and
@@ -219,62 +223,98 @@ AFSProcessUserFsRequest( IN PIRP Irp)
                 ntStatus = STATUS_NOT_IMPLEMENTED;
 
                 break;
+            }
 
             case FSCTL_LOCK_VOLUME:
-
+            {
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
                               "AFSProcessUserFsRequest Processing FSCTL_LOCK_VOLUME request\n");
 
+                ntStatus = STATUS_NOT_IMPLEMENTED;
+
                 break;
+            }
 
             case FSCTL_UNLOCK_VOLUME:
-
+            {
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
                               "AFSProcessUserFsRequest Processing FSCTL_UNLOCK_VOLUME request\n");
 
+                ntStatus = STATUS_NOT_IMPLEMENTED;
+
                 break;
+            }
 
             case FSCTL_DISMOUNT_VOLUME:
-
+            {
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
                               "AFSProcessUserFsRequest Processing FSCTL_DISMOUNT_VOLUME request\n");
 
+                ntStatus = STATUS_NOT_IMPLEMENTED;
+
                 break;
+            }
 
             case FSCTL_MARK_VOLUME_DIRTY:
-
+            {
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
                               "AFSProcessUserFsRequest Processing FSCTL_MARK_VOLUME_DIRTY request\n");
 
+                ntStatus = STATUS_NOT_IMPLEMENTED;
+
                 break;
+            }
 
             case FSCTL_IS_VOLUME_DIRTY:
-
+            {
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
                               "AFSProcessUserFsRequest Processing FSCTL_IS_VOLUME_DIRTY request\n");
 
+                ntStatus = STATUS_NOT_IMPLEMENTED;
+
                 break;
+            }
 
             case FSCTL_IS_VOLUME_MOUNTED:
-
+            {
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
                               "AFSProcessUserFsRequest Processing FSCTL_IS_VOLUME_MOUNTED request\n");
 
+                ntStatus = STATUS_NOT_IMPLEMENTED;
+
                 break;
+            }
 
             case FSCTL_IS_PATHNAME_VALID:
-
+            {
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
                               "AFSProcessUserFsRequest Processing FSCTL_IS_PATHNAME_VALID request\n");
 
+                ntStatus = STATUS_SUCCESS;
+
                 break;
+            }
+
+#ifndef FSCTL_CSC_INTERNAL
+#define FSCTL_CSC_INTERNAL                  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 107, METHOD_NEITHER, FILE_ANY_ACCESS)
+#endif
+            case FSCTL_CSC_INTERNAL:
+            {
+                AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
+                              AFS_TRACE_LEVEL_VERBOSE_2,
+                              "AFSProcessUserFsRequest Processing FSCTL_CSC_INTERNAL request\n");
+
+                ntStatus = STATUS_INVALID_DEVICE_REQUEST;
+
+                break;
+            }
 
             case FSCTL_GET_REPARSE_POINT:
             {
@@ -285,19 +325,10 @@ AFSProcessUserFsRequest( IN PIRP Irp)
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
-                              "AFSProcessUserFsRequest Processing FSCTL_GET_REPARSE_POINT request\n");
-
-                if( ulOutputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
-                {
-
-                    ntStatus = STATUS_BUFFER_TOO_SMALL;
-
-                    Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer);
-
-                    break;
-                }
-
-                ulRemainingLen -= FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer);
+                              "AFSProcessUserFsRequest Processing FSCTL_GET_REPARSE_POINT request %wZ Type 0x%x Attrib 0x%x\n",
+                              &pCcb->DirectoryCB->NameInformation.FileName,
+                              pCcb->DirectoryCB->ObjectInformation->FileType,
+                              pCcb->DirectoryCB->ObjectInformation->FileAttributes);
 
                 //
                 // Check if we have the reparse entry set on the entry
@@ -311,6 +342,18 @@ AFSProcessUserFsRequest( IN PIRP Irp)
                     break;
                 }
 
+                if( ulOutputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
+                {
+
+                    ntStatus = STATUS_BUFFER_TOO_SMALL;
+
+                    Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer);
+
+                    break;
+                }
+
+                ulRemainingLen -= FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer);
+
                 //
                 // Populate the data in the reparse buffer
                 //
@@ -340,7 +383,7 @@ AFSProcessUserFsRequest( IN PIRP Irp)
                                   pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
                                   pCcb->DirectoryCB->ObjectInformation->FileId.Unique);
 
-                    ntStatus = AFSVerifyEntry( &pFcb->AuthGroup,
+                    ntStatus = AFSVerifyEntry( &pCcb->AuthGroup,
                                                pCcb->DirectoryCB);
 
                     if( !NT_SUCCESS( ntStatus))
@@ -373,7 +416,7 @@ AFSProcessUserFsRequest( IN PIRP Irp)
                         if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
                         {
 
-                            ntStatus = STATUS_ACCESS_DENIED;
+                            ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
 
                             break;
                         }
@@ -412,7 +455,7 @@ AFSProcessUserFsRequest( IN PIRP Irp)
 
                         if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
                         {
-                            ntStatus = STATUS_ACCESS_DENIED;
+                            ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
 
                             break;
                         }
@@ -466,7 +509,7 @@ AFSProcessUserFsRequest( IN PIRP Irp)
                         if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
                         {
 
-                            ntStatus = STATUS_ACCESS_DENIED;
+                            ntStatus = STATUS_REPARSE_POINT_NOT_RESOLVED;
 
                             break;
                         }
@@ -508,7 +551,7 @@ AFSProcessUserFsRequest( IN PIRP Irp)
 
                     ulRemainingLen -= pReparseBuffer->ReparseDataLength;
 
-                    pReparseBuffer->ReparseTag = IO_REPARSE_TAG_OPENAFS_DFS;
+                    pReparseBuffer->ReparseTag = IO_REPARSE_TAG_SURROGATE|IO_REPARSE_TAG_OPENAFS_DFS;
 
                     RtlCopyMemory( &pReparseBuffer->ReparseGuid,
                                    &GUID_AFS_REPARSE_GUID,
@@ -530,15 +573,10 @@ AFSProcessUserFsRequest( IN PIRP Irp)
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
-                              "AFSProcessUserFsRequest Processing FSCTL_SET_REPARSE_POINT request\n");
-
-                if( ulInputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
-                {
-
-                    ntStatus = STATUS_INVALID_PARAMETER;
-
-                    break;
-                }
+                              "AFSProcessUserFsRequest Processing FSCTL_SET_REPARSE_POINT request %wZ Type 0x%x Attrib 0x%x\n",
+                              &pCcb->DirectoryCB->NameInformation.FileName,
+                              pCcb->DirectoryCB->ObjectInformation->FileType,
+                              pCcb->DirectoryCB->ObjectInformation->FileAttributes);
 
                 //
                 // Check if we have the reparse entry set on the entry
@@ -552,7 +590,15 @@ AFSProcessUserFsRequest( IN PIRP Irp)
                     break;
                 }
 
-                if( pReparseBuffer->ReparseTag != IO_REPARSE_TAG_OPENAFS_DFS)
+                if( ulInputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
+                {
+
+                    ntStatus = STATUS_IO_REPARSE_DATA_INVALID;
+
+                    break;
+                }
+
+                if( (pReparseBuffer->ReparseTag & 0x0000FFFF) != IO_REPARSE_TAG_OPENAFS_DFS)
                 {
 
                     ntStatus = STATUS_IO_REPARSE_TAG_MISMATCH;
@@ -574,6 +620,8 @@ AFSProcessUserFsRequest( IN PIRP Irp)
                 // For now deny access on this call
                 //
 
+                ntStatus = STATUS_INVALID_PARAMETER;
+
                 break;
             }
 
@@ -584,15 +632,10 @@ AFSProcessUserFsRequest( IN PIRP Irp)
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
-                              "AFSProcessUserFsRequest Processing FSCTL_DELETE_REPARSE_POINT request\n");
-
-                if( ulInputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
-                {
-
-                    ntStatus = STATUS_INVALID_PARAMETER;
-
-                    break;
-                }
+                              "AFSProcessUserFsRequest Processing FSCTL_DELETE_REPARSE_POINT request %wZ Type 0x%x Attrib 0x%x\n",
+                              &pCcb->DirectoryCB->NameInformation.FileName,
+                              pCcb->DirectoryCB->ObjectInformation->FileType,
+                              pCcb->DirectoryCB->ObjectInformation->FileAttributes);
 
                 //
                 // Check if we have the reparse entry set on the entry
@@ -606,7 +649,15 @@ AFSProcessUserFsRequest( IN PIRP Irp)
                     break;
                 }
 
-                if( pReparseBuffer->ReparseTag != IO_REPARSE_TAG_OPENAFS_DFS)
+                if( ulInputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
+                {
+
+                    ntStatus = STATUS_INVALID_PARAMETER;
+
+                    break;
+                }
+
+                if( (pReparseBuffer->ReparseTag & 0x0000FFFF) != IO_REPARSE_TAG_OPENAFS_DFS)
                 {
 
                     ntStatus = STATUS_IO_REPARSE_TAG_MISMATCH;
@@ -633,15 +684,33 @@ AFSProcessUserFsRequest( IN PIRP Irp)
                 break;
             }
 
+#ifndef FSCTL_SET_PURGE_FAILURE_MODE
+#define FSCTL_SET_PURGE_FAILURE_MODE        CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 156, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#endif
+
+            case FSCTL_SET_PURGE_FAILURE_MODE:
+            {
+
+                //
+                // For the time being just succeed this call
+                //
+
+                ntStatus = STATUS_SUCCESS;
+
+                break;
+            }
+
             default :
+            {
 
                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
                               AFS_TRACE_LEVEL_VERBOSE_2,
                               "AFSProcessUserFsRequest Processing default (%08lX) request\n", ulFsControlCode);
 
-                ntStatus = STATUS_INVALID_PARAMETER;
+                ntStatus = STATUS_INVALID_DEVICE_REQUEST;
 
                 break;
+            }
         }
 
 try_exit: