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