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