/*++ Copyright (c) 1989 Microsoft Corporation Module Name: init.c Abstract: This module contains the initialization code of the NT browser File System Driver (FSD) and File System Process (FSP). Author: Larry Osterman (larryo) 24-May-1990 Environment: Kernel mode, FSD, and FSP Revision History: 30-May-1990 LarryO Created --*/ // // Include modules // #include "precomp.h" #pragma hdrstop HANDLE BowserServerAnnouncementEventHandle = {0}; PKEVENT BowserServerAnnouncementEvent = {0}; PDOMAIN_INFO BowserPrimaryDomainInfo = NULL; // External functions //(fsctl.c) NTSTATUS StopBowser ( IN BOOLEAN Wait, IN BOOLEAN InFsd, IN PBOWSER_FS_DEVICE_OBJECT DeviceObject, IN PLMDR_REQUEST_PACKET InputBuffer, IN ULONG InputBufferLength ); // Local functions VOID BowserReadBowserConfiguration( PUNICODE_STRING RegistryPath ); #ifdef ALLOC_PRAGMA #pragma alloc_text(INIT, BowserDriverEntry) #pragma alloc_text(PAGE, BowserUnload) #pragma alloc_text(INIT, BowserReadBowserConfiguration) #endif NTSTATUS BowserDriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) /*++ Routine Description: This is the initialization routine for the file system. It is invoked once when the driver is loaded into the system. Its job is to initialize all the structures which will be used by the FSD and the FSP. It also creates the process from which all of the file system threads will be executed. It then registers the file system with the I/O system as a valid file system resident in the system. Arguments: DriverObject - Pointer to driver object created by the system. Return Value: None. --*/ { NTSTATUS Status; UNICODE_STRING unicodeEventName; UNICODE_STRING DummyDomain; PDEVICE_OBJECT DeviceObject; OBJECT_ATTRIBUTES obja; PAGED_CODE(); #if DBG BowserInitializeTraceLog(); #endif // // Create the device object for this file system. // RtlInitUnicodeString( &BowserNameString, DD_BROWSER_DEVICE_NAME_U ); dlog(DPRT_INIT, ("Creating device %wZ\n", &BowserNameString)); #if DBG #define BOWSER_LOAD_BP 0 #if BOWSER_LOAD_BP dlog(DPRT_INIT, ("DebugBreakPoint...\n")); DbgBreakPoint(); #endif #endif dlog(DPRT_INIT, ("DriverObject at %08lx\n", DriverObject)); Status = IoCreateDevice( DriverObject, sizeof(BOWSER_FS_DEVICE_OBJECT) - sizeof(DEVICE_OBJECT), &BowserNameString, FILE_DEVICE_NETWORK_BROWSER, 0, FALSE, &DeviceObject ); if (!NT_SUCCESS(Status)) { InternalError(("Unable to create redirector device")); } dlog(DPRT_INIT, ("Device created at %08lx\n", DeviceObject)); Status = BowserInitializeSecurity(DeviceObject); if (!NT_SUCCESS(Status)) { InternalError(("Unable to initialize security.")); } dlog(DPRT_INIT, ("Initialized Browser security at %p\n", g_pBowSecurityDescriptor)); ExInitializeResourceLite( &BowserDataResource ); // // Save the device object address for this file system driver. // BowserDeviceObject = (PBOWSER_FS_DEVICE_OBJECT )DeviceObject; BowserReadBowserConfiguration(RegistryPath); DeviceObject->StackSize = (CCHAR)BowserIrpStackSize; dlog(DPRT_INIT, ("Stacksize is %d\n",DeviceObject->StackSize)); // // Initialize the TDI package // BowserpInitializeTdi(); // // Initialize the datagram buffer structures // BowserpInitializeMailslot(); BowserInitializeFsd(); BowserpInitializeIrpQueue(); // // Initialize the code to receive a browser server list. // BowserpInitializeGetBrowserServerList(); // // Initialize the bowser FSP. // if (!NT_SUCCESS(Status = BowserpInitializeFsp(DriverObject))) { return Status; } if (!NT_SUCCESS(Status = BowserpInitializeNames())) { return Status; } #if DBG // // If we have a preconfigured trace level, open the browser trace log // right away. // if (BowserDebugLogLevel != 0) { BowserOpenTraceLogFile(L"\\SystemRoot\\Bowser.Log"); } #endif // // // // Set up the browsers unload routine. // // // // DriverObject->DriverUnload = BowserUnload; BowserInitializeDiscardableCode(); // // Set the timer up for the idle timer. // IoInitializeTimer((PDEVICE_OBJECT )BowserDeviceObject, BowserIdleTimer, NULL); RtlInitUnicodeString( &unicodeEventName, SERVER_ANNOUNCE_EVENT_W ); InitializeObjectAttributes( &obja, &unicodeEventName, OBJ_OPENIF, NULL, NULL ); Status = ZwCreateEvent( &BowserServerAnnouncementEventHandle, SYNCHRONIZE | EVENT_QUERY_STATE | EVENT_MODIFY_STATE, &obja, SynchronizationEvent, FALSE ); if (NT_SUCCESS(Status)) { Status = ObReferenceObjectByHandle(BowserServerAnnouncementEventHandle, EVENT_MODIFY_STATE, NULL, KernelMode, &BowserServerAnnouncementEvent, NULL); } // // Always create a domain structure for the primary domain. // RtlInitUnicodeString( &DummyDomain, NULL ); BowserPrimaryDomainInfo = BowserCreateDomain( &DummyDomain, &DummyDomain ); return Status; } VOID BowserUnload( IN PDRIVER_OBJECT DriverObject ) /*++ Routine Description: This is the unload routine for the bowser device. Arguments: DriverObject - pointer to the driver object for the browser driver Return Value: None --*/ { PAGED_CODE(); if ( BowserData.Initialized ){ // // StopBowser was never called (mem cleanup skipped etc). // Call it before exiting (see bug 359407). // // Fake (unused) paramters BOWSER_FS_DEVICE_OBJECT fsDevice; LMDR_REQUEST_PACKET InputBuffer; fsDevice.DeviceObject = *DriverObject->DeviceObject; // set fake input buffer. It is unused (except param check) in // StopBowser InputBuffer.Version = LMDR_REQUEST_PACKET_VERSION_DOM; ASSERT ((IoGetCurrentProcess() == BowserFspProcess)); (VOID) StopBowser( TRUE, TRUE, &fsDevice, &InputBuffer, sizeof(LMDR_REQUEST_PACKET) ); } // // Ditch the global reference to the primary domain. // if ( BowserPrimaryDomainInfo != NULL ) { // break if we're leaking memory. StopBowser should // have cleaned all references. ASSERT ( BowserPrimaryDomainInfo->ReferenceCount == 1 ); BowserDereferenceDomain( BowserPrimaryDomainInfo ); } // // Uninitialize the bowser name structures. // BowserpUninitializeNames(); // // Uninitialize the bowser FSP. // BowserpUninitializeFsp(); // // Uninitialize the routines involved in retrieving browser server lists. // BowserpUninitializeGetBrowserServerList(); // // Uninitialize the mailslot related functions. // BowserpUninitializeMailslot(); // // Uninitialize the TDI related functions. // BowserpUninitializeTdi(); // // Delete the resource protecting the bowser global data. // ExDeleteResourceLite(&BowserDataResource); ObDereferenceObject(BowserServerAnnouncementEvent); ZwClose(BowserServerAnnouncementEventHandle); #if DBG BowserUninitializeTraceLog(); #endif // // Delete the browser device object. // IoDeleteDevice((PDEVICE_OBJECT)BowserDeviceObject); BowserUninitializeDiscardableCode(); return; } VOID BowserReadBowserConfiguration( PUNICODE_STRING RegistryPath ) { ULONG Storage[256]; UNICODE_STRING UnicodeString; HANDLE RedirConfigHandle; HANDLE ParametersHandle; NTSTATUS Status; ULONG BytesRead; OBJECT_ATTRIBUTES ObjectAttributes; PBOWSER_CONFIG_INFO ConfigEntry; PKEY_VALUE_FULL_INFORMATION Value = (PKEY_VALUE_FULL_INFORMATION)Storage; PAGED_CODE(); InitializeObjectAttributes( &ObjectAttributes, RegistryPath, // name OBJ_CASE_INSENSITIVE, // attributes NULL, // root NULL // security descriptor ); Status = ZwOpenKey (&RedirConfigHandle, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { BowserWriteErrorLogEntry ( EVENT_BOWSER_CANT_READ_REGISTRY, Status, NULL, 0, 0 ); return; } RtlInitUnicodeString(&UnicodeString, BOWSER_CONFIG_PARAMETERS); InitializeObjectAttributes( &ObjectAttributes, &UnicodeString, OBJ_CASE_INSENSITIVE, RedirConfigHandle, NULL ); Status = ZwOpenKey (&ParametersHandle, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { BowserWriteErrorLogEntry ( EVENT_BOWSER_CANT_READ_REGISTRY, Status, NULL, 0, 0 ); ZwClose(RedirConfigHandle); return; } for (ConfigEntry = BowserConfigEntries; ConfigEntry->ConfigParameterName != NULL; ConfigEntry += 1) { RtlInitUnicodeString(&UnicodeString, ConfigEntry->ConfigParameterName); Status = ZwQueryValueKey(ParametersHandle, &UnicodeString, KeyValueFullInformation, Value, sizeof(Storage), &BytesRead); if (NT_SUCCESS(Status)) { if (Value->DataLength != 0) { if (ConfigEntry->ConfigValueType == REG_BOOLEAN) { if (Value->Type != REG_DWORD || Value->DataLength != REG_BOOLEAN_SIZE) { BowserWriteErrorLogEntry ( EVENT_BOWSER_CANT_READ_REGISTRY, STATUS_INVALID_PARAMETER, ConfigEntry->ConfigParameterName, (USHORT)(wcslen(ConfigEntry->ConfigParameterName)*sizeof(WCHAR)), 0 ); } else { ULONG_PTR ConfigValue = (ULONG_PTR)((PCHAR)Value)+Value->DataOffset; *(PBOOLEAN)(ConfigEntry->ConfigValue) = (BOOLEAN)(*((PULONG)ConfigValue) != 0); } } else if (Value->Type != ConfigEntry->ConfigValueType || Value->DataLength != ConfigEntry->ConfigValueSize) { BowserWriteErrorLogEntry ( EVENT_BOWSER_CANT_READ_REGISTRY, STATUS_INVALID_PARAMETER, ConfigEntry->ConfigParameterName, (USHORT)(wcslen(ConfigEntry->ConfigParameterName)*sizeof(WCHAR)), 0 ); } else { RtlCopyMemory(ConfigEntry->ConfigValue, ((PCHAR)Value)+Value->DataOffset, Value->DataLength); } } else { BowserWriteErrorLogEntry ( EVENT_BOWSER_CANT_READ_REGISTRY, STATUS_INVALID_PARAMETER, ConfigEntry->ConfigParameterName, (USHORT)(wcslen(ConfigEntry->ConfigParameterName)*sizeof(WCHAR)), 0 ); } } } ZwClose(ParametersHandle); ZwClose(RedirConfigHandle); }