Windows: Redirector opens must set a valid FsContext
[openafs.git] / src / WINNT / afsrdr / kernel / fs / AFSCreate.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: AFSCreate.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 //
42 // Function: AFSCreate
43 //
44 // Description:
45 //
46 //      This function is the dispatch handler for the IRP_MJ_CREATE requests. It makes the determination to
47 //      which interface this request is destined.
48 //
49 // Return:
50 //
51 //      A status is returned for the function. The Irp completion processing is handled in the specific
52 //      interface handler.
53 //
54
55 NTSTATUS
56 AFSCreate( IN PDEVICE_OBJECT DeviceObject,
57            IN PIRP Irp)
58 {
59
60     NTSTATUS ntStatus = STATUS_SUCCESS;
61
62     __try
63     {
64
65         if( DeviceObject == AFSDeviceObject)
66         {
67
68             ntStatus = AFSControlDeviceCreate( Irp);
69
70             try_return( ntStatus);
71         }
72
73         ntStatus = AFSCommonCreate( DeviceObject,
74                                     Irp);
75
76 try_exit:
77
78         NOTHING;
79     }
80     __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
81     {
82
83         AFSDbgLogMsg( 0,
84                       0,
85                       "EXCEPTION - AFSCreate\n");
86
87         ntStatus = STATUS_ACCESS_DENIED;
88     }
89
90     return ntStatus;
91 }
92
93 NTSTATUS
94 AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject,
95                  IN PIRP Irp)
96 {
97
98     NTSTATUS            ntStatus = STATUS_SUCCESS;
99     FILE_OBJECT        *pFileObject = NULL;
100     IO_STACK_LOCATION  *pIrpSp;
101     AFSDeviceExt       *pDeviceExt = NULL;
102     AFSDeviceExt       *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
103     GUID               *pAuthGroup = NULL;
104     UNICODE_STRING uniGUIDString;
105
106     __Enter
107     {
108
109         pIrpSp = IoGetCurrentIrpStackLocation( Irp);
110         pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension;
111         pFileObject = pIrpSp->FileObject;
112
113         uniGUIDString.Buffer = NULL;
114         uniGUIDString.Length = 0;
115         uniGUIDString.MaximumLength = 0;
116
117         //
118         // Validate the process entry
119         //
120
121         pAuthGroup = AFSValidateProcessEntry();
122
123         if( pAuthGroup != NULL)
124         {
125
126             RtlStringFromGUID( *pAuthGroup,
127                                &uniGUIDString);
128
129             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
130                           AFS_TRACE_LEVEL_VERBOSE,
131                           "%s (%08lX) Located AuthGroup %wZ after validation\n",
132                           __FUNCTION__,
133                           Irp,
134                           &uniGUIDString);
135
136         }
137         else
138         {
139             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
140                           AFS_TRACE_LEVEL_VERBOSE,
141                           "%s (%08lX) Failed to locate AuthGroup\n",
142                           __FUNCTION__,
143                           Irp);
144         }
145
146         //
147         // Root open?
148         //
149
150         if( pFileObject == NULL ||
151             pFileObject->FileName.Buffer == NULL)
152         {
153
154             AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
155                           AFS_TRACE_LEVEL_VERBOSE,
156                           "AFSCommonCreate (%08lX) Processing volume open request\n",
157                           Irp);
158
159             ntStatus = AFSOpenRedirector( Irp);
160
161             AFSCompleteRequest( Irp,
162                                 ntStatus);
163
164             try_return( ntStatus);
165         }
166
167
168         //
169         // Check the state of the library
170         //
171
172         ntStatus = AFSCheckLibraryState( Irp);
173
174         if( !NT_SUCCESS( ntStatus) ||
175             ntStatus == STATUS_PENDING)
176         {
177
178             if( ntStatus != STATUS_PENDING)
179             {
180                 AFSCompleteRequest( Irp, ntStatus);
181             }
182
183             try_return( ntStatus);
184         }
185
186         IoSkipCurrentIrpStackLocation( Irp);
187
188         ntStatus = IoCallDriver( pControlDevExt->Specific.Control.LibraryDeviceObject,
189                                  Irp);
190
191         //
192         // Indicate the library is done with the request
193         //
194
195         AFSClearLibraryRequest();
196
197 try_exit:
198
199         if ( pFileObject) {
200             AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
201                           AFS_TRACE_LEVEL_VERBOSE,
202                           "%s (%08lX) File \"%wZ\" AuthGroup '%wZ' ntStatus %08lX\n",
203                           __FUNCTION__,
204                           Irp,
205                           &pFileObject->FileName,
206                           &uniGUIDString,
207                           ntStatus);
208         }
209
210         if( uniGUIDString.Buffer != NULL)
211         {
212             RtlFreeUnicodeString( &uniGUIDString);
213         }
214     }
215
216     return ntStatus;
217 }
218
219 NTSTATUS
220 AFSControlDeviceCreate( IN PIRP Irp)
221 {
222
223     NTSTATUS ntStatus = STATUS_SUCCESS;
224
225     __Enter
226     {
227
228         //
229         // For now, jsut let the open happen
230         //
231
232         Irp->IoStatus.Information = FILE_OPENED;
233
234         AFSCompleteRequest( Irp, ntStatus);
235     }
236
237     return ntStatus;
238 }
239
240 NTSTATUS
241 AFSOpenRedirector( IN PIRP Irp)
242 {
243
244     NTSTATUS ntStatus = STATUS_SUCCESS;
245     FILE_OBJECT        *pFileObject = NULL;
246     IO_STACK_LOCATION  *pIrpSp;
247     AFSDeviceExt* pDeviceExt =
248         (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
249
250     __Enter
251     {
252
253         pIrpSp = IoGetCurrentIrpStackLocation( Irp);
254
255         pFileObject = pIrpSp->FileObject;
256
257         pFileObject->FsContext = (PVOID) pDeviceExt->Fcb;
258
259         ASSERT(pFileObject->FsContext != NULL);
260
261         //
262         // Return the open result for this file
263         //
264
265         Irp->IoStatus.Information = FILE_OPENED;
266
267         Irp->IoStatus.Status = ntStatus;
268     }
269
270     return ntStatus;
271 }