05cda83a5350a13db21e6eff5b61b0f8ac39ba67
[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             case FSCTL_GET_REPARSE_POINT:
288             {
289
290                 REPARSE_GUID_DATA_BUFFER *pReparseBuffer = (REPARSE_GUID_DATA_BUFFER *)Irp->AssociatedIrp.SystemBuffer;
291                 ULONG ulRemainingLen = ulOutputBufferLen;
292                 AFSReparseTagInfo *pReparseInfo = NULL;
293
294                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
295                               AFS_TRACE_LEVEL_VERBOSE_2,
296                               "AFSProcessUserFsRequest Processing FSCTL_GET_REPARSE_POINT request\n");
297
298                 if( ulOutputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
299                 {
300
301                     ntStatus = STATUS_BUFFER_TOO_SMALL;
302
303                     Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer);
304
305                     break;
306                 }
307
308                 ulRemainingLen -= FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer);
309
310                 //
311                 // Check if we have the reparse entry set on the entry
312                 //
313
314                 if( !BooleanFlagOn( pCcb->DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
315                 {
316
317                     ntStatus = STATUS_NOT_A_REPARSE_POINT;
318
319                     break;
320                 }
321
322                 //
323                 // Populate the data in the reparse buffer
324                 //
325
326                 pReparseBuffer->ReparseDataLength  = 0;
327
328                 AFSAcquireExcl( &pCcb->DirectoryCB->NonPaged->Lock,
329                                 TRUE);
330
331                 if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
332                 {
333
334                     //
335                     // We'll reset the DV to ensure we validate the metadata content
336                     //
337
338                     pCcb->DirectoryCB->ObjectInformation->DataVersion.QuadPart = (ULONGLONG)-1;
339
340                     SetFlag( pCcb->DirectoryCB->ObjectInformation->Flags, AFS_OBJECT_FLAGS_VERIFY);
341
342                     AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
343                                   AFS_TRACE_LEVEL_VERBOSE,
344                                   "AFSProcessUserFsRequest Verifying symlink %wZ FID %08lX-%08lX-%08lX-%08lX\n",
345                                   &pCcb->DirectoryCB->NameInformation.FileName,
346                                   pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
347                                   pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
348                                   pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
349                                   pCcb->DirectoryCB->ObjectInformation->FileId.Unique);
350
351                     ntStatus = AFSVerifyEntry( &pFcb->AuthGroup,
352                                                pCcb->DirectoryCB);
353
354                     if( !NT_SUCCESS( ntStatus))
355                     {
356
357                         AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
358                                       AFS_TRACE_LEVEL_ERROR,
359                                       "AFSProcessUserFsRequest Failed to verify symlink %wZ FID %08lX-%08lX-%08lX-%08lX Status %08lX\n",
360                                       &pCcb->DirectoryCB->NameInformation.FileName,
361                                       pCcb->DirectoryCB->ObjectInformation->FileId.Cell,
362                                       pCcb->DirectoryCB->ObjectInformation->FileId.Volume,
363                                       pCcb->DirectoryCB->ObjectInformation->FileId.Vnode,
364                                       pCcb->DirectoryCB->ObjectInformation->FileId.Unique,
365                                       ntStatus);
366
367                         AFSReleaseResource( &pCcb->DirectoryCB->NonPaged->Lock);
368
369                         break;
370                     }
371                 }
372
373                 pReparseInfo = (AFSReparseTagInfo *)&pReparseBuffer->GenericReparseBuffer.DataBuffer[ 0];
374
375                 switch( pCcb->DirectoryCB->ObjectInformation->FileType)
376                 {
377
378                     case AFS_FILE_TYPE_SYMLINK:
379                     {
380
381                         if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
382                         {
383
384                             ntStatus = STATUS_ACCESS_DENIED;
385
386                             break;
387                         }
388
389                         if( ulRemainingLen < (ULONG) FIELD_OFFSET( AFSReparseTagInfo, AFSSymLink.Buffer) + pCcb->DirectoryCB->NameInformation.TargetName.Length)
390                         {
391
392                             ntStatus = STATUS_BUFFER_TOO_SMALL;
393
394                             Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
395                                                         FIELD_OFFSET( AFSReparseTagInfo, AFSSymLink.Buffer) +
396                                                         pCcb->DirectoryCB->NameInformation.TargetName.Length;
397
398                             break;
399                         }
400
401                         pReparseInfo->SubTag = OPENAFS_SUBTAG_SYMLINK;
402
403                         pReparseInfo->AFSSymLink.RelativeLink = AFSIsRelativeName( &pCcb->DirectoryCB->NameInformation.TargetName);
404
405                         pReparseInfo->AFSSymLink.SymLinkTargetLength = pCcb->DirectoryCB->NameInformation.TargetName.Length;
406
407                         RtlCopyMemory( pReparseInfo->AFSSymLink.Buffer,
408                                        pCcb->DirectoryCB->NameInformation.TargetName.Buffer,
409                                        pCcb->DirectoryCB->NameInformation.TargetName.Length);
410
411                         pReparseBuffer->ReparseDataLength = (FIELD_OFFSET( AFSReparseTagInfo, AFSSymLink.Buffer) + pCcb->DirectoryCB->NameInformation.TargetName.Length);
412
413                         break;
414                     }
415
416                     case AFS_FILE_TYPE_MOUNTPOINT:
417                     {
418                         UNICODE_STRING Cell, Volume;
419                         USHORT Type;
420
421                         if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
422                         {
423                             ntStatus = STATUS_ACCESS_DENIED;
424
425                             break;
426                         }
427
428                         if ( !AFSParseMountPointTarget( &pCcb->DirectoryCB->NameInformation.TargetName,
429                                                         &Type,
430                                                         &Volume,
431                                                         &Cell))
432                         {
433                             ntStatus = STATUS_INVALID_PARAMETER;
434
435                             break;
436                         }
437
438                         if( ulRemainingLen < (ULONG) FIELD_OFFSET( AFSReparseTagInfo, AFSMountPoint.Buffer) + Volume.Length + Cell.Length)
439                         {
440
441                             ntStatus = STATUS_BUFFER_TOO_SMALL;
442
443                             Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
444                                                         FIELD_OFFSET( AFSReparseTagInfo, AFSMountPoint.Buffer) +
445                                                         Volume.Length + Cell.Length;
446
447                             break;
448                         }
449
450                         pReparseInfo->SubTag = OPENAFS_SUBTAG_MOUNTPOINT;
451
452                         pReparseInfo->AFSMountPoint.Type = Type;
453
454                         pReparseInfo->AFSMountPoint.MountPointCellLength = Cell.Length;
455
456                         pReparseInfo->AFSMountPoint.MountPointVolumeLength = Volume.Length;
457
458                         RtlCopyMemory( pReparseInfo->AFSMountPoint.Buffer,
459                                        Cell.Buffer,
460                                        Cell.Length);
461
462                         RtlCopyMemory( &pReparseInfo->AFSMountPoint.Buffer[ Cell.Length / sizeof( WCHAR)],
463                                        Volume.Buffer,
464                                        Volume.Length);
465
466                         pReparseBuffer->ReparseDataLength = (FIELD_OFFSET( AFSReparseTagInfo, AFSMountPoint.Buffer) + Volume.Length + Cell.Length);
467
468                         break;
469                     }
470
471                     case AFS_FILE_TYPE_DFSLINK:
472                     {
473
474                         if( pCcb->DirectoryCB->NameInformation.TargetName.Length == 0)
475                         {
476
477                             ntStatus = STATUS_ACCESS_DENIED;
478
479                             break;
480                         }
481
482                         if( ulRemainingLen < (ULONG) FIELD_OFFSET( AFSReparseTagInfo, UNCReferral.Buffer) + pCcb->DirectoryCB->NameInformation.TargetName.Length)
483                         {
484
485                             ntStatus = STATUS_BUFFER_TOO_SMALL;
486
487                             Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
488                                                         FIELD_OFFSET( AFSReparseTagInfo, UNCReferral.Buffer) +
489                                                         pCcb->DirectoryCB->NameInformation.TargetName.Length;
490
491                             break;
492                         }
493
494                         pReparseInfo->SubTag = OPENAFS_SUBTAG_UNC;
495
496                         pReparseInfo->UNCReferral.UNCTargetLength = pCcb->DirectoryCB->NameInformation.TargetName.Length;
497
498                         RtlCopyMemory( pReparseInfo->UNCReferral.Buffer,
499                                        pCcb->DirectoryCB->NameInformation.TargetName.Buffer,
500                                        pCcb->DirectoryCB->NameInformation.TargetName.Length);
501
502                         pReparseBuffer->ReparseDataLength = (FIELD_OFFSET( AFSReparseTagInfo, UNCReferral.Buffer) + pCcb->DirectoryCB->NameInformation.TargetName.Length);
503
504                         break;
505                     }
506
507                     default:
508
509                         ntStatus = STATUS_NOT_A_REPARSE_POINT;
510
511                         break;
512                 }
513
514                 if ( ntStatus == STATUS_SUCCESS)
515                 {
516
517                     ulRemainingLen -= pReparseBuffer->ReparseDataLength;
518
519                     pReparseBuffer->ReparseTag = IO_REPARSE_TAG_OPENAFS_DFS;
520
521                     RtlCopyMemory( &pReparseBuffer->ReparseGuid,
522                                    &GUID_AFS_REPARSE_GUID,
523                                    sizeof( GUID));
524
525                     Irp->IoStatus.Information = FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer) +
526                                                               pReparseBuffer->ReparseDataLength;
527                 }
528
529                 AFSReleaseResource( &pCcb->DirectoryCB->NonPaged->Lock);
530
531                 break;
532             }
533
534             case FSCTL_SET_REPARSE_POINT:
535             {
536
537                 REPARSE_GUID_DATA_BUFFER *pReparseBuffer = (REPARSE_GUID_DATA_BUFFER *)Irp->AssociatedIrp.SystemBuffer;
538
539                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
540                               AFS_TRACE_LEVEL_VERBOSE_2,
541                               "AFSProcessUserFsRequest Processing FSCTL_SET_REPARSE_POINT request\n");
542
543                 if( ulInputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
544                 {
545
546                     ntStatus = STATUS_INVALID_PARAMETER;
547
548                     break;
549                 }
550
551                 //
552                 // Check if we have the reparse entry set on the entry
553                 //
554
555                 if( !BooleanFlagOn( pCcb->DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
556                 {
557
558                     ntStatus = STATUS_NOT_A_REPARSE_POINT;
559
560                     break;
561                 }
562
563                 if( pReparseBuffer->ReparseTag != IO_REPARSE_TAG_OPENAFS_DFS)
564                 {
565
566                     ntStatus = STATUS_IO_REPARSE_TAG_MISMATCH;
567
568                     break;
569                 }
570
571                 if( RtlCompareMemory( &pReparseBuffer->ReparseGuid,
572                                       &GUID_AFS_REPARSE_GUID,
573                                       sizeof( GUID)) != sizeof( GUID))
574                 {
575
576                     ntStatus = STATUS_REPARSE_ATTRIBUTE_CONFLICT;
577
578                     break;
579                 }
580
581                 //
582                 // For now deny access on this call
583                 //
584
585                 break;
586             }
587
588             case FSCTL_DELETE_REPARSE_POINT:
589             {
590
591                 REPARSE_GUID_DATA_BUFFER *pReparseBuffer = (REPARSE_GUID_DATA_BUFFER *)Irp->AssociatedIrp.SystemBuffer;
592
593                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
594                               AFS_TRACE_LEVEL_VERBOSE_2,
595                               "AFSProcessUserFsRequest Processing FSCTL_DELETE_REPARSE_POINT request\n");
596
597                 if( ulInputBufferLen < FIELD_OFFSET( REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer.DataBuffer))
598                 {
599
600                     ntStatus = STATUS_INVALID_PARAMETER;
601
602                     break;
603                 }
604
605                 //
606                 // Check if we have the reparse entry set on the entry
607                 //
608
609                 if( !BooleanFlagOn( pCcb->DirectoryCB->ObjectInformation->FileAttributes, FILE_ATTRIBUTE_REPARSE_POINT))
610                 {
611
612                     ntStatus = STATUS_NOT_A_REPARSE_POINT;
613
614                     break;
615                 }
616
617                 if( pReparseBuffer->ReparseTag != IO_REPARSE_TAG_OPENAFS_DFS)
618                 {
619
620                     ntStatus = STATUS_IO_REPARSE_TAG_MISMATCH;
621
622                     break;
623                 }
624
625                 if( RtlCompareMemory( &pReparseBuffer->ReparseGuid,
626                                       &GUID_AFS_REPARSE_GUID,
627                                       sizeof( GUID)) != sizeof( GUID))
628                 {
629
630                     ntStatus = STATUS_REPARSE_ATTRIBUTE_CONFLICT;
631
632                     break;
633                 }
634
635                 //
636                 // For now deny access on this call
637                 //
638
639                 ntStatus = STATUS_ACCESS_DENIED;
640
641                 break;
642             }
643
644             default :
645
646                 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
647                               AFS_TRACE_LEVEL_VERBOSE_2,
648                               "AFSProcessUserFsRequest Processing default (%08lX) request\n", ulFsControlCode);
649
650                 ntStatus = STATUS_INVALID_PARAMETER;
651
652                 break;
653         }
654
655 try_exit:
656
657         NOTHING;
658     }
659
660     return ntStatus;
661 }
662
663 NTSTATUS
664 AFSProcessShareFsCtrl( IN IRP *Irp,
665                        IN AFSFcb *Fcb,
666                        IN AFSCcb *Ccb)
667 {
668
669     NTSTATUS ntStatus = STATUS_SUCCESS;
670     PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
671     ULONG ulOutputBufferLen = 0, ulInputBufferLen;
672     ULONG ulFsControlCode;
673
674     __Enter
675     {
676
677         ulFsControlCode = pIrpSp->Parameters.FileSystemControl.FsControlCode;
678
679         ulOutputBufferLen = pIrpSp->Parameters.FileSystemControl.OutputBufferLength;
680         ulInputBufferLen = pIrpSp->Parameters.FileSystemControl.InputBufferLength;
681
682         switch( ulFsControlCode)
683         {
684
685             case FSCTL_PIPE_TRANSCEIVE:
686             {
687
688                 AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
689                               AFS_TRACE_LEVEL_VERBOSE,
690                               "AFSProcessShareFsCtrl On pipe %wZ Class FSCTL_PIPE_TRANSCEIVE\n",
691                               &Ccb->DirectoryCB->NameInformation.FileName);
692
693                 ntStatus = AFSNotifyPipeTransceive( Ccb,
694                                                     ulInputBufferLen,
695                                                     ulOutputBufferLen,
696                                                     pIrpSp->Parameters.FileSystemControl.Type3InputBuffer,
697                                                     Irp->UserBuffer,
698                                                     (ULONG *)&Irp->IoStatus.Information);
699
700                 if( !NT_SUCCESS( ntStatus))
701                 {
702
703                     AFSDbgLogMsg( AFS_SUBSYSTEM_PIPE_PROCESSING,
704                                   AFS_TRACE_LEVEL_VERBOSE,
705                                   "AFSProcessShareFsCtrl Failure on pipe %wZ Class FSCTL_PIPE_TRANSCEIVE Status %08lX\n",
706                                   &Ccb->DirectoryCB->NameInformation.FileName,
707                                   ntStatus);
708                 }
709
710                 break;
711             }
712
713             default:
714             {
715
716                 if( BooleanFlagOn( Ccb->DirectoryCB->Flags, AFS_DIR_ENTRY_SERVER_SERVICE))
717                 {
718
719                     //AFSPrint("AFSProcessShareFsCtrl (%08lX) For srvsvc input %08lX output %08lX\n",
720                     //                                                            ulFsControlCode,
721                     //                                                            ulInputBufferLen,
722                     //                                                            ulOutputBufferLen);
723                 }
724                 else if( BooleanFlagOn( Ccb->DirectoryCB->Flags, AFS_DIR_ENTRY_WORKSTATION_SERVICE))
725                 {
726
727                     //AFSPrint("AFSProcessShareFsCtrl (%08lX) For wkssvc input %08lX output %08lX\n",
728                     //                                                            ulFsControlCode,
729                     //                                                            ulInputBufferLen,
730                     //                                                            ulOutputBufferLen);
731                 }
732                 else
733                 {
734
735                     //AFSPrint("AFSProcessShareFsCtrl (%08lX) For IPC$ input %08lX output %08lX\n",
736                     //                                                            ulFsControlCode,
737                     //                                                            ulInputBufferLen,
738                     //                                                            ulOutputBufferLen);
739                 }
740
741                 break;
742             }
743         }
744     }
745
746     return ntStatus;
747 }