Windows: FileStandardInfo Link count
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSFileInfo.cpp
index 2eb6c73..274b043 100644 (file)
@@ -954,10 +954,10 @@ AFSQueryStandardInfo( IN PIRP Irp,
         RtlZeroMemory( Buffer,
                        *Length);
 
-        Buffer->NumberOfLinks = 1;
+       Buffer->NumberOfLinks = DirectoryCB->ObjectInformation->Links;
         Buffer->DeletePending = BooleanFlagOn( pCcb->DirectoryCB->Flags, AFS_DIR_ENTRY_PENDING_DELETE);
 
-        Buffer->AllocationSize.QuadPart = (ULONGLONG)((DirectoryCB->ObjectInformation->AllocationSize.QuadPart/PAGE_SIZE) + 1) * PAGE_SIZE;
+       Buffer->AllocationSize.QuadPart = DirectoryCB->ObjectInformation->AllocationSize.QuadPart;
 
         Buffer->EndOfFile = DirectoryCB->ObjectInformation->EndOfFile;
 
@@ -1121,14 +1121,9 @@ AFSQueryNameInfo( IN PIRP Irp,
 
     UNREFERENCED_PARAMETER(DirectoryCB);
     NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
-    ULONG ulCopyLength = 0;
-    ULONG cchCopied = 0;
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
-    BOOLEAN bAddLeadingSlash = FALSE;
-    BOOLEAN bAddTrailingSlash = FALSE;
-    USHORT usFullNameLength = 0;
 
     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
 
@@ -1137,116 +1132,16 @@ AFSQueryNameInfo( IN PIRP Irp,
     if( *Length >= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName))
     {
 
-        RtlZeroMemory( Buffer,
-                       *Length);
-
-        if( pCcb->FullFileName.Length == 0 ||
-            pCcb->FullFileName.Buffer[ 0] != L'\\')
-        {
-            bAddLeadingSlash = TRUE;
-        }
-
-        if( pFcb->ObjectInformation->FileType == AFS_FILE_TYPE_DIRECTORY &&
-            pCcb->FullFileName.Length > 0 &&
-            pCcb->FullFileName.Buffer[ (pCcb->FullFileName.Length/sizeof( WCHAR)) - 1] != L'\\')
-        {
-            bAddTrailingSlash = TRUE;
-        }
-
-        usFullNameLength = sizeof( WCHAR) +
-                                    AFSServerName.Length +
-                                    pCcb->FullFileName.Length;
-
-        if( bAddLeadingSlash)
-        {
-            usFullNameLength += sizeof( WCHAR);
-        }
-
-        if( bAddTrailingSlash)
-        {
-            usFullNameLength += sizeof( WCHAR);
-        }
-
-        if( *Length >= (LONG)(FIELD_OFFSET( FILE_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
-        {
-
-            ulCopyLength = (LONG)usFullNameLength;
-
-           ntStatus = STATUS_SUCCESS;
-        }
-        else
-        {
-
-            ulCopyLength = *Length - FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
-
-            ntStatus = STATUS_BUFFER_OVERFLOW;
-        }
-
-        Buffer->FileNameLength = (ULONG)usFullNameLength;
-
-        *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
-
-        if( ulCopyLength > 0)
-        {
-
-            Buffer->FileName[ 0] = L'\\';
-            ulCopyLength -= sizeof( WCHAR);
-
-            *Length -= sizeof( WCHAR);
-            cchCopied += 1;
-
-            if( ulCopyLength >= AFSServerName.Length)
-            {
-
-                RtlCopyMemory( &Buffer->FileName[ 1],
-                               AFSServerName.Buffer,
-                               AFSServerName.Length);
-
-                ulCopyLength -= AFSServerName.Length;
-                *Length -= AFSServerName.Length;
-                cchCopied += AFSServerName.Length/sizeof( WCHAR);
-
-                if ( ulCopyLength > 0 &&
-                     bAddLeadingSlash)
-                {
-
-                    Buffer->FileName[ cchCopied] = L'\\';
-
-                    ulCopyLength -= sizeof( WCHAR);
-                    *Length -= sizeof( WCHAR);
-                    cchCopied++;
-                }
-
-                if( ulCopyLength >= pCcb->FullFileName.Length)
-                {
-
-                    RtlCopyMemory( &Buffer->FileName[ cchCopied],
-                                   pCcb->FullFileName.Buffer,
-                                   pCcb->FullFileName.Length);
-
-                    ulCopyLength -= pCcb->FullFileName.Length;
-                    *Length -= pCcb->FullFileName.Length;
-                    cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
-
-                    if( ulCopyLength > 0 &&
-                        bAddTrailingSlash)
-                    {
-                        Buffer->FileName[ cchCopied] = L'\\';
+       RtlZeroMemory( Buffer,
+                      *Length);
 
-                        *Length -= sizeof( WCHAR);
-                    }
-                }
-                else
-                {
+       *Length -= FIELD_OFFSET( FILE_NAME_INFORMATION, FileName);
 
-                    RtlCopyMemory( &Buffer->FileName[ cchCopied],
-                                   pCcb->FullFileName.Buffer,
-                                   ulCopyLength);
-
-                    *Length -= ulCopyLength;
-                }
-            }
-        }
+       ntStatus = AFSGetFullFileName( pFcb,
+                                      pCcb,
+                                      &Buffer->FileNameLength,
+                                      Buffer->FileName,
+                                      Length);
     }
 
     return ntStatus;
@@ -1709,13 +1604,9 @@ AFSQueryPhysicalNameInfo( IN PIRP Irp,
 
     UNREFERENCED_PARAMETER(DirectoryCB);
     NTSTATUS ntStatus = STATUS_INFO_LENGTH_MISMATCH;
-    ULONG ulCopyLength = 0;
-    ULONG cchCopied = 0;
     AFSFcb *pFcb = NULL;
     AFSCcb *pCcb = NULL;
     IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp);
-    BOOLEAN bAddLeadingSlash = FALSE;
-    USHORT usFullNameLength = 0;
 
     pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
 
@@ -1724,74 +1615,16 @@ AFSQueryPhysicalNameInfo( IN PIRP Irp,
     if( *Length >= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName))
     {
 
-        RtlZeroMemory( Buffer,
-                       *Length);
-
-        if( pCcb->FullFileName.Length == 0 ||
-            pCcb->FullFileName.Buffer[ 0] != L'\\')
-        {
-            bAddLeadingSlash = TRUE;
-        }
-
-        usFullNameLength = pCcb->FullFileName.Length;
-
-        if( bAddLeadingSlash)
-        {
-            usFullNameLength += sizeof( WCHAR);
-        }
-
-        if( *Length >= (LONG)(FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName) + (LONG)usFullNameLength))
-        {
-            ulCopyLength = (LONG)usFullNameLength;
-
-           ntStatus = STATUS_SUCCESS;
-        }
-        else
-        {
-
-            ulCopyLength = *Length - FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
-
-            ntStatus = STATUS_BUFFER_OVERFLOW;
-        }
-
-        Buffer->FileNameLength = (ULONG)usFullNameLength;
-
-        *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
-
-        if( ulCopyLength > 0)
-        {
-
-            if( bAddLeadingSlash)
-            {
-
-                Buffer->FileName[ cchCopied] = L'\\';
-
-                ulCopyLength -= sizeof( WCHAR);
-                *Length -= sizeof( WCHAR);
-                cchCopied++;
-            }
-
-            if( ulCopyLength >= pCcb->FullFileName.Length)
-            {
-
-                RtlCopyMemory( &Buffer->FileName[ cchCopied],
-                               pCcb->FullFileName.Buffer,
-                               pCcb->FullFileName.Length);
-
-                ulCopyLength -= pCcb->FullFileName.Length;
-                *Length -= pCcb->FullFileName.Length;
-                cchCopied += pCcb->FullFileName.Length/sizeof( WCHAR);
-            }
-            else
-            {
+       RtlZeroMemory( Buffer,
+                      *Length);
 
-                RtlCopyMemory( &Buffer->FileName[ cchCopied],
-                               pCcb->FullFileName.Buffer,
-                               ulCopyLength);
+       *Length -= FIELD_OFFSET( FILE_NETWORK_PHYSICAL_NAME_INFORMATION, FileName);
 
-                *Length -= ulCopyLength;
-            }
-        }
+       ntStatus = AFSGetFullFileName( pFcb,
+                                      pCcb,
+                                      &Buffer->FileNameLength,
+                                      Buffer->FileName,
+                                      Length);
     }
 
     return ntStatus;
@@ -3043,6 +2876,50 @@ AFSSetRenameInfo( IN PIRP Irp)
 
             ASSERT( lCount >= 0);
 
+           //
+           // Need to acquire the ObjectInfoLock while checking for the Fcb OpenRefCount so we don't race with
+           // a tear down worker thread on the Fcb
+           //
+
+           AFSAcquireShared( &pTargetDirEntry->ObjectInformation->NonPagedInfo->ObjectInfoLock,
+                             TRUE);
+
+           //
+           // Check there are no current opens on the target
+           //
+
+           if( BooleanFlagOn( pTargetDirEntry->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY) ||
+               ( pTargetDirEntry->ObjectInformation->Fcb != NULL &&
+                 pTargetDirEntry->ObjectInformation->Fcb->OpenReferenceCount != 0))
+           {
+
+               //
+               // Return the correct error code
+               //
+
+               if( BooleanFlagOn( pTargetDirEntry->Flags, AFS_DIR_ENTRY_PENDING_DELETE))
+               {
+                   ntStatus = STATUS_DELETE_PENDING;
+               }
+               else
+               {
+                   ntStatus = STATUS_ACCESS_DENIED;
+               }
+
+               AFSReleaseResource( &pTargetDirEntry->ObjectInformation->NonPagedInfo->ObjectInfoLock);
+
+               AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
+                             AFS_TRACE_LEVEL_ERROR,
+                             "AFSSetRenameInfo Attempt to rename %s Target %wZ Status %08lX\n",
+                             BooleanFlagOn( pTargetDirEntry->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_READONLY)?"ReadOnly":"Open",
+                             &pTargetDirEntry->NameInformation.FileName,
+                             ntStatus));
+
+               try_return( ntStatus);
+           }
+
+           AFSReleaseResource( &pTargetDirEntry->ObjectInformation->NonPagedInfo->ObjectInfoLock);
+
             if( !bReplaceIfExists)
             {