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);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|