Windows: XP do not mark rdr devices as secure
[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 #if DBG
180
181         if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_FLAG_BREAK_ON_ENTRY))
182         {
183
184             DbgPrint("AFSRedirFs DriverEntry - Break on entry\n");
185
186             AFSBreakPoint();
187
188             if ( bExit)
189             {
190                 //
191                 // Just as above
192                 //
193                 try_return( ntStatus = STATUS_UNSUCCESSFUL);
194             }
195         }
196 #endif
197
198         if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN) &&
199             !BooleanFlagOn( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN))
200         {
201
202             AFSPrint("AFS DriverEntry: Failed to shutdown clean, exiting\n");
203
204             try_return( ntStatus = STATUS_UNSUCCESSFUL);
205         }
206
207         //
208         // Initialize the debug log and dump file interface
209         //
210
211         AFSInitializeDbgLog();
212
213         AFSInitializeDumpFile();
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                                          FILE_DEVICE_SECURE_OPEN | FILE_REMOTE_DEVICE,
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.MdlRead                      = AFSFastIoMdlRead;
397         AFSFastIoDispatch.MdlReadComplete              = AFSFastIoMdlReadComplete;
398         AFSFastIoDispatch.PrepareMdlWrite              = AFSFastIoPrepareMdlWrite;
399         AFSFastIoDispatch.MdlWriteComplete             = AFSFastIoMdlWriteComplete;
400         AFSFastIoDispatch.FastIoReadCompressed         = AFSFastIoReadCompressed;
401         AFSFastIoDispatch.FastIoWriteCompressed        = AFSFastIoWriteCompressed;
402         AFSFastIoDispatch.MdlReadCompleteCompressed    = AFSFastIoMdlReadCompleteCompressed;
403         AFSFastIoDispatch.MdlWriteCompleteCompressed   = AFSFastIoMdlWriteCompleteCompressed;
404         AFSFastIoDispatch.FastIoQueryOpen              = AFSFastIoQueryOpen;
405
406         //
407         //  Cache manager callback routines.
408         //
409
410         AFSCacheManagerCallbacks.AcquireForLazyWrite  = &AFSAcquireFcbForLazyWrite;
411         AFSCacheManagerCallbacks.ReleaseFromLazyWrite = &AFSReleaseFcbFromLazyWrite;
412         AFSCacheManagerCallbacks.AcquireForReadAhead  = &AFSAcquireFcbForReadAhead;
413         AFSCacheManagerCallbacks.ReleaseFromReadAhead = &AFSReleaseFcbFromReadAhead;
414
415         //
416         //  System process.
417         //
418
419         AFSSysProcess = PsGetCurrentProcessId();
420
421         //
422         // Initialize the worker Queues and their syncrhonization structures
423         //
424
425         KeInitializeEvent( &pDeviceExt->Specific.Control.WorkerQueueHasItems,
426                            SynchronizationEvent,
427                            FALSE);
428
429         ExInitializeResourceLite( &pDeviceExt->Specific.Control.QueueLock);
430
431         KeInitializeEvent( &pDeviceExt->Specific.Control.IOWorkerQueueHasItems,
432                            SynchronizationEvent,
433                            FALSE);
434
435         ExInitializeResourceLite( &pDeviceExt->Specific.Control.IOQueueLock);
436
437
438         //
439         // Register for shutdown notification
440         //
441
442         IoRegisterShutdownNotification( AFSDeviceObject);
443
444         //
445         // Initialize the system process cb
446         //
447
448         AFSInitializeProcessCB( 0,
449                                 (ULONGLONG)AFSSysProcess);
450
451         //
452         // Initialize the redirector device
453         //
454
455         ntStatus = AFSInitRDRDevice();
456
457         if( !NT_SUCCESS( ntStatus))
458         {
459
460             DbgPrint("AFS DriverEntry Failed to initialize redirector device Status %08lX\n");
461
462             try_return( ntStatus);
463         }
464
465         //
466         // Initialize some server name based strings
467         //
468
469         AFSInitServerStrings();
470
471         //
472         // Register the call back for process creation and tear down.
473         // On Vista SP1 and above, PsSetCreateProcessNotifyRoutineEx
474         // will be used.  This function returns STATUS_ACCESS_DENIED
475         // if there is a signing error.  In that case, the AFSProcessNotifyEx
476         // routine has not been registered and we can fallback to the
477         // Windows 2000 interface and AFSProcessNotify.
478         //
479
480         RtlInitUnicodeString( &uniPsSetCreateProcessNotifyRoutineEx,
481                               L"PsSetCreateProcessNotifyRoutineEx");
482
483         pPsSetCreateProcessNotifyRoutineEx = (PsSetCreateProcessNotifyRoutineEx_t)MmGetSystemRoutineAddress(&uniPsSetCreateProcessNotifyRoutineEx);
484
485         ntStatus = STATUS_ACCESS_DENIED;
486
487         if ( pPsSetCreateProcessNotifyRoutineEx)
488         {
489
490             ntStatus = pPsSetCreateProcessNotifyRoutineEx( AFSProcessNotifyEx,
491                                                            FALSE);
492         }
493
494         if ( ntStatus == STATUS_ACCESS_DENIED)
495         {
496
497             ntStatus = PsSetCreateProcessNotifyRoutine( AFSProcessNotify,
498                                                         FALSE);
499         }
500
501         ntStatus = STATUS_SUCCESS;
502
503 try_exit:
504
505         if( !NT_SUCCESS( ntStatus))
506         {
507
508             DbgPrint("AFSRedirFs DriverEntry failed to initialize %08lX\n", ntStatus);
509
510             if( AFSRegistryPath.Buffer != NULL)
511             {
512
513                 ExFreePool( AFSRegistryPath.Buffer);
514             }
515
516             if( uniSymLinkName.Buffer != NULL)
517             {
518
519                 IoDeleteSymbolicLink( &uniSymLinkName);
520             }
521
522             if( AFSDeviceObject != NULL)
523             {
524
525                 AFSRemoveControlDevice();
526
527                 FsRtlNotifyUninitializeSync( &pDeviceExt->Specific.Control.NotifySync);
528
529                 IoUnregisterShutdownNotification( AFSDeviceObject);
530
531                 IoDeleteDevice( AFSDeviceObject);
532             }
533
534             AFSTearDownDbgLog();
535
536             ExDeleteResourceLite( &AFSDbgLogLock);
537         }
538     }
539     __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
540     {
541
542         AFSDbgTrace(( 0,
543                       0,
544                       "EXCEPTION - AFSRedirFs DriverEntry\n"));
545
546         AFSDumpTraceFilesFnc();
547     }
548
549     return ntStatus;
550 }