Windows: RDR File System Framework driver
[openafs.git] / src / WINNT / afsrdr / kernel / fs / AFSInit.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: AFSInit.cpp
37 //
38
39 #include "AFSCommon.h"
40
41 #ifndef AMD64
42 extern "C"
43 {
44 extern void                   *KeServiceDescriptorTable;
45 };
46 #endif
47
48 //
49 // DriverEntry
50 //
51 // This is the initial entry point for the driver.
52 //
53 // Inputs:
54 //  DriverObject        Pointer to Driver Object created by I/O manager
55 //  RegistryPath        Pointer to registry path representing this Driver
56 //
57 // Returns:
58 //  Success             To indicate Driver's inituaialization processing
59 //                      was successful
60 //  NT ERROR STATUS     Otherwise -- Driver does not remain loaded
61 //
62
63 NTSTATUS
64 DriverEntry( PDRIVER_OBJECT DriverObject,
65              PUNICODE_STRING RegistryPath)
66 {
67
68     NTSTATUS ntStatus = STATUS_SUCCESS;
69     AFSDeviceExt    *pDeviceExt;
70     ULONG ulTimeIncrement = 0;
71     UNICODE_STRING uniSymLinkName;
72     UNICODE_STRING uniDeviceName;
73     ULONG ulIndex = 0;
74     ULONG ulValue = 0;
75     UNICODE_STRING uniValueName;
76     BOOLEAN bExit = FALSE;
77     UNICODE_STRING uniRoutine;
78     RTL_OSVERSIONINFOW sysVersion;
79
80     __try
81     {
82
83         DbgPrint("AFSRedirFs DriverEntry Initialization build %s:%s\n", __DATE__, __TIME__);
84
85         //
86         // Initialize some local variables for easier processing
87         //
88
89         uniSymLinkName.Buffer = NULL;
90
91         AFSDumpFileLocation.Length = 0;
92         AFSDumpFileLocation.MaximumLength = 0;
93         AFSDumpFileLocation.Buffer = NULL;
94
95         AFSDumpFileName.Length = 0;
96         AFSDumpFileName.Buffer = NULL;
97         AFSDumpFileName.MaximumLength = 0;
98
99         ExInitializeResourceLite( &AFSDbgLogLock);
100
101         //
102         // Initialize the server name
103         //
104
105         AFSReadServerName();
106
107         RtlZeroMemory( &sysVersion,
108                        sizeof( RTL_OSVERSIONINFOW));
109
110         sysVersion.dwOSVersionInfoSize = sizeof( RTL_OSVERSIONINFOW);
111
112         RtlGetVersion( &sysVersion);
113
114         RtlInitUnicodeString( &uniRoutine,
115                               L"ZwSetInformationToken");
116
117         AFSSetInformationToken = (PAFSSetInformationToken)MmGetSystemRoutineAddress( &uniRoutine);
118
119         if( AFSSetInformationToken == NULL)
120         {
121 #ifndef AMD64
122             AFSSrvcTableEntry *pServiceTable = NULL;
123
124             pServiceTable = (AFSSrvcTableEntry *)KeServiceDescriptorTable;
125
126             //
127             // Only perform this lookup for Windows XP.
128             //
129
130             if( pServiceTable != NULL &&
131                 sysVersion.dwMajorVersion == 5 &&
132                 sysVersion.dwMinorVersion == 1)
133             {
134                 AFSSetInformationToken = (PAFSSetInformationToken)pServiceTable->ServiceTable[ 0xE6];
135             }
136 #endif
137         }
138
139         //
140         // And the global root share name
141         //
142
143         RtlInitUnicodeString( &AFSGlobalRootName,
144                               AFS_GLOBAL_ROOT_SHARE_NAME);
145
146         RtlZeroMemory( &AFSNoPAGAuthGroup,
147                        sizeof( GUID));
148
149         //
150         // Our backdoor to not let the driver load
151         //
152
153         if( bExit)
154         {
155             try_return( ntStatus);
156         }
157
158         //
159         // Perform some initialization
160         //
161
162         AFSDriverObject = DriverObject;
163
164         ntStatus = AFSReadRegistry( RegistryPath);
165
166         if( !NT_SUCCESS( ntStatus))
167         {
168
169             DbgPrint("AFS DriverEntry: Failed to read registry Status %08lX\n", ntStatus);
170
171             ntStatus = STATUS_SUCCESS;
172         }
173
174         //
175         // Initialize the debug log and dump file interface
176         //
177
178         AFSInitializeDbgLog();
179
180         AFSInitializeDumpFile();
181
182 #if DBG
183
184         if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_FLAG_BREAK_ON_ENTRY))
185         {
186
187             DbgPrint("AFSRedirFs DriverEntry - Break on entry\n");
188
189             AFSBreakPoint();
190
191             if ( bExit)
192             {
193                 //
194                 // Just as above
195                 //
196                 try_return( ntStatus = STATUS_UNSUCCESSFUL);
197             }
198         }
199 #endif
200
201         if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN) &&
202             !BooleanFlagOn( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN))
203         {
204
205             AFSPrint("AFS DriverEntry: Failed to shutdown clean, exiting\n");
206
207             try_return( ntStatus = STATUS_UNSUCCESSFUL);
208         }
209
210         //
211         // Setup the registry string
212         //
213
214         AFSRegistryPath.MaximumLength = RegistryPath->MaximumLength;
215         AFSRegistryPath.Length        = RegistryPath->Length;
216
217         AFSRegistryPath.Buffer = (PWSTR)ExAllocatePoolWithTag( PagedPool,
218                                                                AFSRegistryPath.Length,
219                                                                AFS_GENERIC_MEMORY_18_TAG);
220
221         if( AFSRegistryPath.Buffer == NULL)
222         {
223
224             DbgPrint("AFSRedirFs DriverEntry Failed to allocate registry path buffer\n");
225
226             try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
227         }
228
229         RtlCopyMemory( AFSRegistryPath.Buffer,
230                        RegistryPath->Buffer,
231                        RegistryPath->Length);
232
233         if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN))
234         {
235
236             //
237             // Update the shutdown flag
238             //
239
240             ulValue = (ULONG)-1;
241
242             RtlInitUnicodeString( &uniValueName,
243                                   AFS_REG_SHUTDOWN_STATUS);
244
245             AFSUpdateRegistryParameter( &uniValueName,
246                                         REG_DWORD,
247                                         &ulValue,
248                                         sizeof( ULONG));
249         }
250
251         RtlInitUnicodeString( &uniDeviceName,
252                               AFS_CONTROL_DEVICE_NAME);
253
254         ntStatus = IoCreateDeviceSecure( DriverObject,
255                                          sizeof( AFSDeviceExt),
256                                          &uniDeviceName,
257                                          FILE_DEVICE_NETWORK_FILE_SYSTEM,
258                                          0,
259                                          FALSE,
260                                          &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX,
261                                          (LPCGUID)&GUID_SD_AFS_REDIRECTOR_CONTROL_OBJECT,
262                                          &AFSDeviceObject);
263
264         if( !NT_SUCCESS( ntStatus))
265         {
266
267             DbgPrint("AFS DriverEntry - Failed to allocate device control object Status %08lX\n", ntStatus);
268
269             try_return( ntStatus);
270         }
271
272         //
273         // Setup the device extension
274         //
275
276         pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
277
278         InitializeListHead( &pDeviceExt->Specific.Control.DirNotifyList);
279         FsRtlNotifyInitializeSync( &pDeviceExt->Specific.Control.NotifySync);
280
281         //
282         // Now initialize the control device
283         //
284
285         ntStatus = AFSInitializeControlDevice();
286
287         if( !NT_SUCCESS( ntStatus))
288         {
289
290             try_return( ntStatus);
291         }
292
293         //
294         // Allocate our symbolic link for service communication
295         //
296
297         RtlInitUnicodeString( &uniSymLinkName,
298                               AFS_SYMLINK_NAME);
299
300         ntStatus = IoCreateSymbolicLink( &uniSymLinkName,
301                                          &uniDeviceName);
302
303         if( !NT_SUCCESS( ntStatus))
304         {
305
306             DbgPrint("AFS DriverEntry - Failed to create symbolic link Status %08lX\n", ntStatus);
307
308             //
309             // OK, no one can communicate with us so fail
310             //
311
312             try_return( ntStatus);
313         }
314
315         //
316         // Fill in the dispatch table
317         //
318
319         for( ulIndex = 0; ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; ulIndex++)
320         {
321
322             DriverObject->MajorFunction[ ulIndex] = AFSDefaultDispatch;
323         }
324
325         DriverObject->MajorFunction[IRP_MJ_CREATE] =                    AFSCreate;
326         DriverObject->MajorFunction[IRP_MJ_CLOSE] =                     AFSClose;
327         DriverObject->MajorFunction[IRP_MJ_READ] =                      AFSRead;
328         DriverObject->MajorFunction[IRP_MJ_WRITE] =                     AFSWrite;
329         DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =         AFSQueryFileInfo;
330         DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =           AFSSetFileInfo;
331         DriverObject->MajorFunction[IRP_MJ_QUERY_EA] =                  AFSQueryEA;
332         DriverObject->MajorFunction[IRP_MJ_SET_EA] =                    AFSSetEA;
333         DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] =             AFSFlushBuffers;
334         DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =  AFSQueryVolumeInfo;
335         DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] =    AFSSetVolumeInfo;
336         DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =         AFSDirControl;
337         DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =       AFSFSControl;
338         DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =            AFSDevControl;
339         DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =   AFSInternalDevControl;
340         DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =                  AFSShutdown;
341         DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] =              AFSLockControl;
342         DriverObject->MajorFunction[IRP_MJ_CLEANUP] =                   AFSCleanup;
343         DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] =            AFSQuerySecurity;
344         DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] =              AFSSetSecurity;
345         DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =            AFSSystemControl;
346         //DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] =               AFSQueryQuota;
347         //DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] =                 AFSSetQuota;
348
349         //
350         // Since we are not a true FSD then we are not controlling a device and hence these will not be needed
351         //
352
353 #ifdef FSD_NOT_USED
354
355         DriverObject->MajorFunction[IRP_MJ_POWER] =                     AFSPower;
356         DriverObject->MajorFunction[IRP_MJ_PNP] =                       AFSPnP;
357
358 #endif
359
360         //
361         // Fast IO Dispatch table
362         //
363
364         DriverObject->FastIoDispatch = &AFSFastIoDispatch;
365
366         RtlZeroMemory( &AFSFastIoDispatch,
367                        sizeof( AFSFastIoDispatch));
368
369         //
370         // Again, since we are not a registered FSD many of these are not going to be called. They are here
371         // for completeness.
372         //
373
374         AFSFastIoDispatch.SizeOfFastIoDispatch         = sizeof(FAST_IO_DISPATCH);
375         AFSFastIoDispatch.FastIoCheckIfPossible        = AFSFastIoCheckIfPossible;  //  CheckForFastIo
376         AFSFastIoDispatch.FastIoRead                   = AFSFastIoRead;             //  Read
377         AFSFastIoDispatch.FastIoWrite                  = AFSFastIoWrite;            //  Write
378         AFSFastIoDispatch.FastIoQueryBasicInfo         = AFSFastIoQueryBasicInfo;     //  QueryBasicInfo
379         AFSFastIoDispatch.FastIoQueryStandardInfo      = AFSFastIoQueryStandardInfo;       //  QueryStandardInfo
380         AFSFastIoDispatch.FastIoLock                   = AFSFastIoLock;               //  Lock
381         AFSFastIoDispatch.FastIoUnlockSingle           = AFSFastIoUnlockSingle;       //  UnlockSingle
382         AFSFastIoDispatch.FastIoUnlockAll              = AFSFastIoUnlockAll;          //  UnlockAll
383         AFSFastIoDispatch.FastIoUnlockAllByKey         = AFSFastIoUnlockAllByKey;     //  UnlockAllByKey
384         AFSFastIoDispatch.FastIoQueryNetworkOpenInfo   = AFSFastIoQueryNetworkOpenInfo;
385         AFSFastIoDispatch.AcquireForCcFlush            = AFSFastIoAcquireForCCFlush;
386         AFSFastIoDispatch.ReleaseForCcFlush            = AFSFastIoReleaseForCCFlush;
387         AFSFastIoDispatch.FastIoDeviceControl          = AFSFastIoDevCtrl;
388         AFSFastIoDispatch.AcquireFileForNtCreateSection = AFSFastIoAcquireFile;
389         AFSFastIoDispatch.ReleaseFileForNtCreateSection = AFSFastIoReleaseFile;
390         AFSFastIoDispatch.FastIoDetachDevice           = AFSFastIoDetachDevice;
391         //AFSFastIoDispatch.AcquireForModWrite           = AFSFastIoAcquireForModWrite;
392         //AFSFastIoDispatch.ReleaseForModWrite           = AFSFastIoReleaseForModWrite;
393         AFSFastIoDispatch.MdlRead                      = AFSFastIoMdlRead;
394         AFSFastIoDispatch.MdlReadComplete              = AFSFastIoMdlReadComplete;
395         AFSFastIoDispatch.PrepareMdlWrite              = AFSFastIoPrepareMdlWrite;
396         AFSFastIoDispatch.MdlWriteComplete             = AFSFastIoMdlWriteComplete;
397         AFSFastIoDispatch.FastIoReadCompressed         = AFSFastIoReadCompressed;
398         AFSFastIoDispatch.FastIoWriteCompressed        = AFSFastIoWriteCompressed;
399         AFSFastIoDispatch.MdlReadCompleteCompressed    = AFSFastIoMdlReadCompleteCompressed;
400         AFSFastIoDispatch.MdlWriteCompleteCompressed   = AFSFastIoMdlWriteCompleteCompressed;
401         AFSFastIoDispatch.FastIoQueryOpen              = AFSFastIoQueryOpen;
402
403         //
404         //  Cache manager callback routines.
405         //
406
407         AFSCacheManagerCallbacks.AcquireForLazyWrite  = &AFSAcquireFcbForLazyWrite;
408         AFSCacheManagerCallbacks.ReleaseFromLazyWrite = &AFSReleaseFcbFromLazyWrite;
409         AFSCacheManagerCallbacks.AcquireForReadAhead  = &AFSAcquireFcbForReadAhead;
410         AFSCacheManagerCallbacks.ReleaseFromReadAhead = &AFSReleaseFcbFromReadAhead;
411
412         //
413         //  System process.
414         //
415
416         AFSSysProcess = PsGetCurrentProcessId();
417
418         //
419         // Register for shutdown notification
420         //
421
422         IoRegisterShutdownNotification( AFSDeviceObject);
423
424         //
425         // Initialize the system process cb
426         //
427
428         AFSInitializeProcessCB( 0,
429                                 (ULONGLONG)AFSSysProcess);
430
431         //
432         // Initialize the redirector device
433         //
434
435         ntStatus = AFSInitRDRDevice();
436
437         if( !NT_SUCCESS( ntStatus))
438         {
439
440             DbgPrint("AFS DriverEntry Failed to initialize redirector device Status %08lX\n");
441
442             try_return( ntStatus);
443         }
444
445         //
446         // Initialize some server name based strings
447         //
448
449         AFSInitServerStrings();
450
451         //
452         // Register the call back for process creation and tear down
453         //
454
455         PsSetCreateProcessNotifyRoutine( AFSProcessNotify,
456                                          FALSE);
457
458 try_exit:
459
460         if( !NT_SUCCESS( ntStatus))
461         {
462
463             DbgPrint("AFSRedirFs DriverEntry failed to initialize %08lX\n", ntStatus);
464
465             if( AFSRegistryPath.Buffer != NULL)
466             {
467
468                 ExFreePool( AFSRegistryPath.Buffer);
469             }
470
471             if( uniSymLinkName.Buffer != NULL)
472             {
473
474                 IoDeleteSymbolicLink( &uniSymLinkName);
475             }
476
477             if( AFSDeviceObject != NULL)
478             {
479
480                 AFSRemoveControlDevice();
481
482                 FsRtlNotifyUninitializeSync( &pDeviceExt->Specific.Control.NotifySync);
483
484                 IoUnregisterShutdownNotification( AFSDeviceObject);
485
486                 IoDeleteDevice( AFSDeviceObject);
487             }
488
489             AFSTearDownDbgLog();
490
491             ExDeleteResourceLite( &AFSDbgLogLock);
492         }
493     }
494     __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) )
495     {
496
497         AFSDbgLogMsg( 0,
498                       0,
499                       "EXCEPTION - AFSRedirFs DriverEntry\n");
500     }
501
502     return ntStatus;
503 }