523 lines
12 KiB
C
523 lines
12 KiB
C
/*++
|
||
|
||
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);
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|