Windows: Additional trace logging
[openafs.git] / src / WINNT / afsrdr / kernel / lib / AFSFSControl.cpp
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3  * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * - Redistributions of source code must retain the above copyright notice,
11  *   this list of conditions and the following disclaimer.
12  * - Redistributions in binary form must reproduce the above copyright
13  *   notice,
14  *   this list of conditions and the following disclaimer in the
15  *   documentation
16  *   and/or other materials provided with the distribution.
17  * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18  *   nor the names of their contributors may be used to endorse or promote
19  *   products derived from this software without specific prior written
20  *   permission from Kernel Drivers, LLC and Your File System, Inc.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34
35 //
36 // File: AFSFSControl.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 NTSTATUS
42 AFSFSControl( IN PDEVICE_OBJECT LibDeviceObject,
43               IN PIRP Irp)
44 {
45
46     NTSTATUS ntStatus = STATUS_SUCCESS;
47     IO_STACK_LOCATION *pIrpSp;
48
49     pIrpSp = IoGetCurrentIrpStackLocation( Irp);
50
51     __try
52     {
53
54         switch( pIrpSp->MinorFunction)
55         {
56
57             case IRP_MN_USER_FS_REQUEST:
58
59                 ntStatus = AFSProcessUserFsRequest( Irp);
60
61                 break;
62
63             case IRP_MN_MOUNT_VOLUME:
64
65                 break;
66
67             case IRP_MN_VERIFY_VOLUME:
68
69                 break;
70
71             default:
72
73                 break;
74         }
75
76         AFSCompleteRequest( Irp,
77                               ntStatus);
78
79     }
80     __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
81     {
82
83         AFSDbgLogMsg( 0,
84                       0,
85                       "EXCEPTION - AFSFSControl\n");
86     }
87
88     return ntStatus;
89 }
90
91 static BOOLEAN
92 AFSParseMountPointTarget( IN  UNICODE_STRING *Target,
93                           OUT USHORT         *Type,
94                           OUT UNICODE_STRING *Volume,
95                           OUT UNICODE_STRING *Cell)
96 {
97     // Targets are of the form <type>[<cell>:]<volume>
98
99     *Type = Target->Buffer[ 0];
100
101     // Extract the cell name (if any)
102
103     Cell->Buffer = &Target->Buffer[ 1];
104
105     // Search for colon separator or end of counted string
106
107     for ( Cell->Length = 0; Cell->Length < Target->Length - sizeof( WCHAR); Cell->Length += sizeof( WCHAR))
108     {
109
110         if ( Cell->Buffer[ Cell->Length / sizeof( WCHAR)] == L':')
111         {
112             break;
113         }
114     }
115
116     // If a colon is not found, it means there is no cell
117
118     if ( Cell->Buffer[ Cell->Length / sizeof( WCHAR)] == L':')
119     {
120
121         Cell->MaximumLength = Cell->Length;
122
123         if ( Cell->Length > Target->Length - 2 * sizeof( WCHAR))
124         {
125             // Invalid target string if there is no room for
126             // the volume name.
127
128             return FALSE;
129         }
130
131         Volume->Length = Volume->MaximumLength = (Target->Length - Cell->Length - 2 * sizeof( WCHAR));
132
133         Volume->Buffer = &Target->Buffer[ Cell->Length / sizeof( WCHAR) + 2];
134     }
135     else
136     {
137         // There is no cell
138
139         Volume->Length = Volume->MaximumLength = Cell->Length;
140
141         Volume->Buffer = Cell->Buffer;
142
143         Cell->Length = Cell->MaximumLength = 0;
144
145         Cell->Buffer = NULL;
146     }
147
148     return TRUE;
149 }
150
151 NTSTATUS
152 AFSProcessUserFsRequest( IN PIRP Irp)
153 {
154
155     NTSTATUS ntStatus = STATUS_SUCCESS;
156     ULONG ulFsControlCode;
157     AFSFcb *pFcb = NULL;
158     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp );
159     AFSCcb *pCcb = NULL;
160     ULONG ulOutputBufferLen, ulInputBufferLen;
161
162     __Enter
163     {
164
165         ulFsControlCode = pIrpSp->Parameters.FileSystemControl.FsControlCode;
166
167         pFcb = (AFSFcb *)pIrpSp->FileObject->FsContext;
168
169         pCcb = (AFSCcb *)pIrpSp->FileObject->FsContext2;
170
171         if( pFcb == NULL ||
172             pCcb->DirectoryCB == NULL)
173         {
174
175             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
176                           AFS_TRACE_LEVEL_VERBOSE_2,
177                           "AFSProcessUserFsRequest Invalid Fcb\n");
178
179             try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
180         }
181
182         if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
183         {
184
185             ntStatus = AFSProcessShareFsCtrl( Irp,
186                                               pFcb,
187                                               pCcb);
188
189             try_return( ntStatus);
190         }
191
192         ulOutputBufferLen = pIrpSp->Parameters.FileSystemControl.OutputBufferLength;
193         ulInputBufferLen = pIrpSp->Parameters.FileSystemControl.InputBufferLength;
194
195         //
196         // Process the request
197         //
198
199         switch( ulFsControlCode )
200         {
201
202             case FSCTL_REQUEST_OPLOCK_LEVEL_1:
203             case FSCTL_REQUEST_OPLOCK_LEVEL_2:
204             case FSCTL_REQUEST_BATCH_OPLOCK:
205             case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE:
206             case FSCTL_OPBATCH_ACK_CLOSE_PENDING:
207             case FSCTL_OPLOCK_BREAK_NOTIFY:
208             case FSCTL_OPLOCK_BREAK_ACK_NO_2:
209             case FSCTL_REQUEST_FILTER_OPLOCK :
210             {
211                 //
212                 // Note that implementing this call will probably need us
213                 // to call the server as well as adding code in read and
214                 // write and caching.  Also that it is unlikely that
215                 // anyone will ever call us at this point - RDR doesn't
216                 // allow it
217                 //
218
219                 ntStatus = STATUS_NOT_IMPLEMENTED;
220
221                 break;
222             }
223
224             case FSCTL_LOCK_VOLUME:
225             {
226                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
227                               AFS_TRACE_LEVEL_VERBOSE_2,
228                               "AFSProcessUserFsRequest Processing FSCTL_LOCK_VOLUME request\n");
229
230                 break;
231             }
232
233             case FSCTL_UNLOCK_VOLUME:
234             {
235                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
236                               AFS_TRACE_LEVEL_VERBOSE_2,
237                               "AFSProcessUserFsRequest Processing FSCTL_UNLOCK_VOLUME request\n");
238
239                 break;
240             }
241
242             case FSCTL_DISMOUNT_VOLUME:
243             {
244                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
245                               AFS_TRACE_LEVEL_VERBOSE_2,
246                               "AFSProcessUserFsRequest Processing FSCTL_DISMOUNT_VOLUME request\n");
247
248                 break;
249             }
250
251             case FSCTL_MARK_VOLUME_DIRTY:
252             {
253                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
254                               AFS_TRACE_LEVEL_VERBOSE_2,
255                               "AFSProcessUserFsRequest Processing FSCTL_MARK_VOLUME_DIRTY request\n");
256
257                 break;
258             }
259
260             case FSCTL_IS_VOLUME_DIRTY:
261             {
262                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
263                               AFS_TRACE_LEVEL_VERBOSE_2,
264                               "AFSProcessUserFsRequest Processing FSCTL_IS_VOLUME_DIRTY request\n");
265
266                 break;
267             }
268
269             case FSCTL_IS_VOLUME_MOUNTED:
270             {
271                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
272                               AFS_TRACE_LEVEL_VERBOSE_2,
273                               "AFSProcessUserFsRequest Processing FSCTL_IS_VOLUME_MOUNTED request\n");
274
275                 break;
276             }
277
278             case FSCTL_IS_PATHNAME_VALID:
279             {
280                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
281                               AFS_TRACE_LEVEL_VERBOSE_2,
282                               "AFSProcessUserFsRequest Processing FSCTL_IS_PATHNAME_VALID request\n");
283
284                 break;
285             }
286
287 #ifndef FSCTL_CSC_INTERNAL
288 #define FSCTL_CSC_INTERNAL                  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 107, METHOD_NEITHER, FILE_ANY_ACCESS)
289 #endif
290             case FSCTL_CSC_INTERNAL:
291             {
292                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
293                               AFS_TRACE_LEVEL_VERBOSE_2,
294                               "AFSProcessUserFsRequest Processing FSCTL_CSC_INTERNAL request\n");
295
296                 ntStatus = STATUS_INVALID_DEVICE_REQUEST;
297
298                 break;
299             }
300
301             case FSCTL_GET_REPARSE_POINT:
302             {
303
304                 REPARSE_GUID_DATA_BUFFER *pReparseBuffer = (REPARSE_GUID_DATA_BUFFER *)Irp->AssociatedIrp.SystemBuffer;
305                 ULONG ulRemainingLen = ulOutputBufferLen;
306                 AFSReparseTagInfo *pReparseInfo = NULL;
307
308                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
309                               AFS_TRACE_LEVEL_VERBOSE_2,
310                               "AFSProcessUserFsRequest Processing FSCTL_GET_REPARSE_POINT request %wZ Type 0x%x Attrib 0x%x\n",
311                               &pCcb->DirectoryCB->NameInformation.FileName,
312                               pCcb->DirectoryCB->ObjectInformation->FileType,
313                               pCcb->DirectoryCB->ObjectInformation->FileAttributes);
314
315                 //
316                 // Check if we have the reparse entry set on the entry
317                 //
318
319                 if( !BooleanFlagOn( pCcb->DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
320                 {
321
322                     ntStatus = STATUS_NOT_A_REPARSE_POINT;
323
324                     break;
325                 }
326
327                 if( ulOutputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
328                 {
329
330                     ntStatus = STATUS_BUFFER_TOO_SMALL;
331
332                     Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer);
333
334                     break;
335                 }
336
337                 ulRemainingLen -= FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer);
338
339                 //
340                 // Populate the data in the reparse buffer
341                 //
342
343                 pReparseBuffer->ReparseDataLength  = 0;
344
345                 AFSAcquireExcl( &pCcb->DirectoryCB->NonPaged->Lock,
346                                 TRUE);
347
348                 if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
349                 {
350
351                     //
352                     // We'll reset the DV to ensure we validate the metadata content
353                     //
354
355                     pCcb->DirectoryCB->ObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
356
357                     SetFlag( pCcb->DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
358
359                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
360                                   AFS_TRACE_LEVEL_VERBOSE,
361                                   "AFSProcessUserFsRequest Verifying symlink %wZ FID %08lX-%08lX-%08lX-%08lX\n",
362                                   &pCcb->DirectoryCB->NameInformation.FileName,
363                                   pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
364                                   pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
365                                   pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
366                                   pCcb->DirectoryCB->ObjectInformation->FileId.Unique);
367
368                     ntStatus = AFSVerifyEntry( &pFcb->AuthGroup,
369                                                pCcb->DirectoryCB);
370
371                     if( !NT_SUCCESS( ntStatus))
372                     {
373
374                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
375                                       AFS_TRACE_LEVEL_ERROR,
376                                       "AFSProcessUserFsRequest Failed to verify symlink %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
377                                       &pCcb->DirectoryCB->NameInformation.FileName,
378                                       pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
379                                       pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
380                                       pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
381                                       pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
382                                       ntStatus);
383
384                         AFSReleaseResource( &pCcb->DirectoryCB->NonPaged->Lock);
385
386                         break;
387                     }
388                 }
389
390                 pReparseInfo = (AFSReparseTagInfo *)&pReparseBuffer->GenericReparseBuffer.DataBuffer[ 0];
391
392                 switch( pCcb->DirectoryCB->ObjectInformation->FileType)
393                 {
394
395                     case AFS_FILE_TYPE_SYMLINK:
396                     {
397
398                         if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
399                         {
400
401                             ntStatus = STATUS_ACCESS_DENIED;
402
403                             break;
404                         }
405
406                         if( ulRemainingLen < (ULONG) FIELD_OFFSET( AFSReparseTagInfo, AFSSymLink.Buffer) + pCcb->DirectoryCB->NameInformation.TargetName.Length)
407                         {
408
409                             ntStatus = STATUS_BUFFER_TOO_SMALL;
410
411                             Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
412                                                         FIELD_OFFSET( AFSReparseTagInfo, AFSSymLink.Buffer) +
413                                                         pCcb->DirectoryCB->NameInformation.TargetName.Length;
414
415                             break;
416                         }
417
418                         pReparseInfo->SubTag = OPENAFS_SUBTAG_SYMLINK;
419
420                         pReparseInfo->AFSSymLink.RelativeLink = AFSIsRelativeName( &pCcb->DirectoryCB->NameInformation.TargetName);
421
422                         pReparseInfo->AFSSymLink.SymLinkTargetLength = pCcb->DirectoryCB->NameInformation.TargetName.Length;
423
424                         RtlCopyMemory( pReparseInfo->AFSSymLink.Buffer,
425                                        pCcb->DirectoryCB->NameInformation.TargetName.Buffer,
426                                        pCcb->DirectoryCB->NameInformation.TargetName.Length);
427
428                         pReparseBuffer->ReparseDataLength = (FIELD_OFFSET( AFSReparseTagInfo, AFSSymLink.Buffer) + pCcb->DirectoryCB->NameInformation.TargetName.Length);
429
430                         break;
431                     }
432
433                     case AFS_FILE_TYPE_MOUNTPOINT:
434                     {
435                         UNICODE_STRING Cell, Volume;
436                         USHORT Type;
437
438                         if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
439                         {
440                             ntStatus = STATUS_ACCESS_DENIED;
441
442                             break;
443                         }
444
445                         if ( !AFSParseMountPointTarget( &pCcb->DirectoryCB->NameInformation.TargetName,
446                                                         &Type,
447                                                         &Volume,
448                                                         &Cell))
449                         {
450                             ntStatus = STATUS_INVALID_PARAMETER;
451
452                             break;
453                         }
454
455                         if( ulRemainingLen < (ULONG) FIELD_OFFSET( AFSReparseTagInfo, AFSMountPoint.Buffer) + Volume.Length + Cell.Length)
456                         {
457
458                             ntStatus = STATUS_BUFFER_TOO_SMALL;
459
460                             Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
461                                                         FIELD_OFFSET( AFSReparseTagInfo, AFSMountPoint.Buffer) +
462                                                         Volume.Length + Cell.Length;
463
464                             break;
465                         }
466
467                         pReparseInfo->SubTag = OPENAFS_SUBTAG_MOUNTPOINT;
468
469                         pReparseInfo->AFSMountPoint.Type = Type;
470
471                         pReparseInfo->AFSMountPoint.MountPointCellLength = Cell.Length;
472
473                         pReparseInfo->AFSMountPoint.MountPointVolumeLength = Volume.Length;
474
475                         RtlCopyMemory( pReparseInfo->AFSMountPoint.Buffer,
476                                        Cell.Buffer,
477                                        Cell.Length);
478
479                         RtlCopyMemory( &pReparseInfo->AFSMountPoint.Buffer[ Cell.Length / sizeof( WCHAR)],
480                                        Volume.Buffer,
481                                        Volume.Length);
482
483                         pReparseBuffer->ReparseDataLength = (FIELD_OFFSET( AFSReparseTagInfo, AFSMountPoint.Buffer) + Volume.Length + Cell.Length);
484
485                         break;
486                     }
487
488                     case AFS_FILE_TYPE_DFSLINK:
489                     {
490
491                         if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
492                         {
493
494                             ntStatus = STATUS_ACCESS_DENIED;
495
496                             break;
497                         }
498
499                         if( ulRemainingLen < (ULONG) FIELD_OFFSET( AFSReparseTagInfo, UNCReferral.Buffer) + pCcb->DirectoryCB->NameInformation.TargetName.Length)
500                         {
501
502                             ntStatus = STATUS_BUFFER_TOO_SMALL;
503
504                             Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
505                                                         FIELD_OFFSET( AFSReparseTagInfo, UNCReferral.Buffer) +
506                                                         pCcb->DirectoryCB->NameInformation.TargetName.Length;
507
508                             break;
509                         }
510
511                         pReparseInfo->SubTag = OPENAFS_SUBTAG_UNC;
512
513                         pReparseInfo->UNCReferral.UNCTargetLength = pCcb->DirectoryCB->NameInformation.TargetName.Length;
514
515                         RtlCopyMemory( pReparseInfo->UNCReferral.Buffer,
516                                        pCcb->DirectoryCB->NameInformation.TargetName.Buffer,
517                                        pCcb->DirectoryCB->NameInformation.TargetName.Length);
518
519                         pReparseBuffer->ReparseDataLength = (FIELD_OFFSET( AFSReparseTagInfo, UNCReferral.Buffer) + pCcb->DirectoryCB->NameInformation.TargetName.Length);
520
521                         break;
522                     }
523
524                     default:
525
526                         ntStatus = STATUS_NOT_A_REPARSE_POINT;
527
528                         break;
529                 }
530
531                 if ( ntStatus == STATUS_SUCCESS)
532                 {
533
534                     ulRemainingLen -= pReparseBuffer->ReparseDataLength;
535
536                     pReparseBuffer->ReparseTag = IO_REPARSE_TAG_OPENAFS_DFS;
537
538                     RtlCopyMemory( &pReparseBuffer->ReparseGuid,
539                                    &GUID_AFS_REPARSE_GUID,
540                                    sizeof( GUID));
541
542                     Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
543                                                               pReparseBuffer->ReparseDataLength;
544                 }
545
546                 AFSReleaseResource( &pCcb->DirectoryCB->NonPaged->Lock);
547
548                 break;
549             }
550
551             case FSCTL_SET_REPARSE_POINT:
552             {
553
554                 REPARSE_GUID_DATA_BUFFER *pReparseBuffer = (REPARSE_GUID_DATA_BUFFER *)Irp->AssociatedIrp.SystemBuffer;
555
556                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
557                               AFS_TRACE_LEVEL_VERBOSE_2,
558                               "AFSProcessUserFsRequest Processing FSCTL_SET_REPARSE_POINT request %wZ Type 0x%x Attrib 0x%x\n",
559                               &pCcb->DirectoryCB->NameInformation.FileName,
560                               pCcb->DirectoryCB->ObjectInformation->FileType,
561                               pCcb->DirectoryCB->ObjectInformation->FileAttributes);
562
563                 //
564                 // Check if we have the reparse entry set on the entry
565                 //
566
567                 if( !BooleanFlagOn( pCcb->DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
568                 {
569
570                     ntStatus = STATUS_NOT_A_REPARSE_POINT;
571
572                     break;
573                 }
574
575                 if( ulInputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
576                 {
577
578                     ntStatus = STATUS_INVALID_PARAMETER;
579
580                     break;
581                 }
582
583                 if( pReparseBuffer->ReparseTag != IO_REPARSE_TAG_OPENAFS_DFS)
584                 {
585
586                     ntStatus = STATUS_IO_REPARSE_TAG_MISMATCH;
587
588                     break;
589                 }
590
591                 if( RtlCompareMemory( &pReparseBuffer->ReparseGuid,
592                                       &GUID_AFS_REPARSE_GUID,
593                                       sizeof( GUID)) != sizeof( GUID))
594                 {
595
596                     ntStatus = STATUS_REPARSE_ATTRIBUTE_CONFLICT;
597
598                     break;
599                 }
600
601                 //
602                 // For now deny access on this call
603                 //
604
605                 break;
606             }
607
608             case FSCTL_DELETE_REPARSE_POINT:
609             {
610
611                 REPARSE_GUID_DATA_BUFFER *pReparseBuffer = (REPARSE_GUID_DATA_BUFFER *)Irp->AssociatedIrp.SystemBuffer;
612
613                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
614                               AFS_TRACE_LEVEL_VERBOSE_2,
615                               "AFSProcessUserFsRequest Processing FSCTL_DELETE_REPARSE_POINT request %wZ Type 0x%x Attrib 0x%x\n",
616                               &pCcb->DirectoryCB->NameInformation.FileName,
617                               pCcb->DirectoryCB->ObjectInformation->FileType,
618                               pCcb->DirectoryCB->ObjectInformation->FileAttributes);
619
620                 //
621                 // Check if we have the reparse entry set on the entry
622                 //
623
624                 if( !BooleanFlagOn( pCcb->DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
625                 {
626
627                     ntStatus = STATUS_NOT_A_REPARSE_POINT;
628
629                     break;
630                 }
631
632                 if( ulInputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
633                 {
634
635                     ntStatus = STATUS_INVALID_PARAMETER;
636
637                     break;
638                 }
639
640                 if( pReparseBuffer->ReparseTag != IO_REPARSE_TAG_OPENAFS_DFS)
641                 {
642
643                     ntStatus = STATUS_IO_REPARSE_TAG_MISMATCH;
644
645                     break;
646                 }
647
648                 if( RtlCompareMemory( &pReparseBuffer->ReparseGuid,
649                                       &GUID_AFS_REPARSE_GUID,
650                                       sizeof( GUID)) != sizeof( GUID))
651                 {
652
653                     ntStatus = STATUS_REPARSE_ATTRIBUTE_CONFLICT;
654
655                     break;
656                 }
657
658                 //
659                 // For now deny access on this call
660                 //
661
662                 ntStatus = STATUS_ACCESS_DENIED;
663
664                 break;
665             }
666
667             default :
668
669                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
670                               AFS_TRACE_LEVEL_VERBOSE_2,
671                               "AFSProcessUserFsRequest Processing default (%08lX) request\n", ulFsControlCode);
672
673                 ntStatus = STATUS_INVALID_DEVICE_REQUEST;
674
675                 break;
676         }
677
678 try_exit:
679
680         NOTHING;
681     }
682
683     return ntStatus;
684 }
685
686 NTSTATUS
687 AFSProcessShareFsCtrl( IN IRP *Irp,
688                        IN AFSFcb *Fcb,
689                        IN AFSCcb *Ccb)
690 {
691
692     NTSTATUS ntStatus = STATUS_SUCCESS;
693     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
694     ULONG ulOutputBufferLen = 0, ulInputBufferLen;
695     ULONG ulFsControlCode;
696
697     __Enter
698     {
699
700         ulFsControlCode = pIrpSp->Parameters.FileSystemControl.FsControlCode;
701
702         ulOutputBufferLen = pIrpSp->Parameters.FileSystemControl.OutputBufferLength;
703         ulInputBufferLen = pIrpSp->Parameters.FileSystemControl.InputBufferLength;
704
705         switch( ulFsControlCode)
706         {
707
708             case FSCTL_PIPE_TRANSCEIVE:
709             {
710
711                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
712                               AFS_TRACE_LEVEL_VERBOSE,
713                               "AFSProcessShareFsCtrl On pipe %wZ Class FSCTL_PIPE_TRANSCEIVE\n",
714                               &Ccb->DirectoryCB->NameInformation.FileName);
715
716                 ntStatus = AFSNotifyPipeTransceive( Ccb,
717                                                     ulInputBufferLen,
718                                                     ulOutputBufferLen,
719                                                     pIrpSp->Parameters.FileSystemControl.Type3InputBuffer,
720                                                     Irp->UserBuffer,
721                                                     (ULONG *)&Irp->IoStatus.Information);
722
723                 if( !NT_SUCCESS( ntStatus))
724                 {
725
726                     AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
727                                   AFS_TRACE_LEVEL_VERBOSE,
728                                   "AFSProcessShareFsCtrl Failure on pipe %wZ Class FSCTL_PIPE_TRANSCEIVE Status %08lX\n",
729                                   &Ccb->DirectoryCB->NameInformation.FileName,
730                                   ntStatus);
731                 }
732
733                 break;
734             }
735
736             default:
737             {
738
739                 if( BooleanFlagOn( Ccb->DirectoryCB->Flags, AFS_DIR_ENTRY_SERVER_SERVICE))
740                 {
741
742                     //AFSPrint("AFSProcessShareFsCtrl (%08lX) For srvsvc input %08lX output %08lX\n",
743                     //                                                            ulFsControlCode,
744                     //                                                            ulInputBufferLen,
745                     //                                                            ulOutputBufferLen);
746                 }
747                 else if( BooleanFlagOn( Ccb->DirectoryCB->Flags, AFS_DIR_ENTRY_WORKSTATION_SERVICE))
748                 {
749
750                     //AFSPrint("AFSProcessShareFsCtrl (%08lX) For wkssvc input %08lX output %08lX\n",
751                     //                                                            ulFsControlCode,
752                     //                                                            ulInputBufferLen,
753                     //                                                            ulOutputBufferLen);
754                 }
755                 else
756                 {
757
758                     //AFSPrint("AFSProcessShareFsCtrl (%08lX) For IPC$ input %08lX output %08lX\n",
759                     //                                                            ulFsControlCode,
760                     //                                                            ulInputBufferLen,
761                     //                                                            ulOutputBufferLen);
762                 }
763
764                 break;
765             }
766         }
767     }
768
769     return ntStatus;
770 }