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