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