395 lines
8.2 KiB
C
395 lines
8.2 KiB
C
|
||
/*++
|
||
|
||
Copyright (c) 1996 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
init.c
|
||
|
||
Abstract:
|
||
|
||
This module performs initialization for the SPUD device driver.
|
||
|
||
Author:
|
||
|
||
John Ballard (jballard) 21-Oct-1996
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "spudp.h"
|
||
|
||
#define REGISTRY_PARAMETERS L"Parameters"
|
||
#define REGISTRY_SPUD_INFORMATION L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Spud"
|
||
|
||
#if DBG
|
||
#define REGISTRY_DEBUG_FLAGS L"DebugFlags"
|
||
#define REGISTRY_BREAK_ON_STARTUP L"BreakOnStartup"
|
||
#define REGISTRY_USE_PRIVATE_ASSERT L"UsePrivateAssert"
|
||
#endif
|
||
#define REGISTRY_DO_NOT_LOAD L"DoNotLoad"
|
||
|
||
// for the time being, don't load spud.sys by default.
|
||
BOOLEAN FailLoad = FALSE;
|
||
|
||
ULONG
|
||
SpudReadSingleParameter(
|
||
IN HANDLE ParametersHandle,
|
||
IN PWCHAR ValueName,
|
||
IN LONG DefaultValue
|
||
);
|
||
|
||
NTSTATUS
|
||
SpudOpenRegistry(
|
||
IN PUNICODE_STRING BaseName,
|
||
OUT PHANDLE ParametersHandle
|
||
);
|
||
|
||
VOID
|
||
SpudReadRegistry (
|
||
VOID
|
||
);
|
||
|
||
NTSTATUS
|
||
DriverEntry (
|
||
IN PDRIVER_OBJECT DriverObject,
|
||
IN PUNICODE_STRING RegistryPath
|
||
);
|
||
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text( INIT, DriverEntry )
|
||
#pragma alloc_text( INIT, SpudReadSingleParameter )
|
||
#pragma alloc_text( INIT, SpudOpenRegistry )
|
||
#pragma alloc_text( INIT, SpudReadRegistry )
|
||
#endif
|
||
|
||
|
||
NTSTATUS
|
||
DriverEntry (
|
||
IN PDRIVER_OBJECT DriverObject,
|
||
IN PUNICODE_STRING RegistryPath
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This is the initialization routine for the SPUD driver.
|
||
|
||
Arguments:
|
||
|
||
DriverObject - Pointer to driver object created by the system.
|
||
|
||
Return Value:
|
||
|
||
The function value is the final status from the initialization operation.
|
||
|
||
--*/
|
||
|
||
{
|
||
NTSTATUS status = STATUS_SUCCESS;
|
||
BOOLEAN success;
|
||
|
||
PAGED_CODE( );
|
||
|
||
success = SpudInitializeData( );
|
||
if ( !success ) {
|
||
return STATUS_INSUFFICIENT_RESOURCES;
|
||
}
|
||
|
||
SpudReadRegistry( );
|
||
|
||
if (FailLoad) {
|
||
return STATUS_INVALID_DEVICE_REQUEST;
|
||
}
|
||
|
||
if (!KeAddSystemServiceTable(
|
||
SPUDpServiceTable,
|
||
NULL,
|
||
SPUDpServiceLimit,
|
||
SPUDpArgumentTable,
|
||
SPUDServiceIndex
|
||
)) {
|
||
return STATUS_INSUFFICIENT_RESOURCES;
|
||
}
|
||
|
||
DriverInitialized = FALSE;
|
||
ATQIoCompletionPort = NULL;
|
||
ATQOplockCompletionPort = NULL;
|
||
|
||
return (status);
|
||
|
||
} // DriverEntry
|
||
|
||
|
||
|
||
VOID
|
||
SpudReadRegistry (
|
||
VOID
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Reads the SPUD section of the registry. Any values listed in the
|
||
registry override defaults.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
None -- if anything fails, the default value is used.
|
||
|
||
--*/
|
||
{
|
||
HANDLE parametersHandle;
|
||
NTSTATUS status;
|
||
UNICODE_STRING registryPath;
|
||
CLONG i;
|
||
|
||
PAGED_CODE( );
|
||
|
||
RtlInitUnicodeString( ®istryPath, REGISTRY_SPUD_INFORMATION );
|
||
|
||
status = SpudOpenRegistry( ®istryPath, ¶metersHandle );
|
||
|
||
if (status != STATUS_SUCCESS) {
|
||
return;
|
||
}
|
||
|
||
#if DBG
|
||
//
|
||
// Read the debug flags from the registry.
|
||
//
|
||
|
||
SpudDebug = SpudReadSingleParameter(
|
||
parametersHandle,
|
||
REGISTRY_DEBUG_FLAGS,
|
||
SpudDebug
|
||
);
|
||
|
||
//
|
||
// Force a breakpoint if so requested.
|
||
//
|
||
|
||
if( SpudReadSingleParameter(
|
||
parametersHandle,
|
||
REGISTRY_BREAK_ON_STARTUP,
|
||
0 ) != 0 ) {
|
||
DbgBreakPoint();
|
||
}
|
||
|
||
//
|
||
// Enable private assert function if requested.
|
||
//
|
||
|
||
SpudUsePrivateAssert = SpudReadSingleParameter(
|
||
parametersHandle,
|
||
REGISTRY_USE_PRIVATE_ASSERT,
|
||
(LONG)SpudUsePrivateAssert
|
||
) != 0;
|
||
#endif
|
||
|
||
//
|
||
// Fail Load if so requested.
|
||
//
|
||
|
||
if( SpudReadSingleParameter(
|
||
parametersHandle,
|
||
REGISTRY_DO_NOT_LOAD,
|
||
0 ) != 0 ) {
|
||
FailLoad = TRUE;
|
||
#if DBG
|
||
DbgPrint("Spud.sys load aborted! DoNotLoad is configured in the registry.\n");
|
||
#endif
|
||
} else {
|
||
FailLoad = FALSE;
|
||
#if DBG
|
||
DbgPrint("Spud.sys load enabled! DoNotLoad is configured in the registry.\n");
|
||
#endif
|
||
}
|
||
|
||
ZwClose( parametersHandle );
|
||
|
||
return;
|
||
|
||
} // SpudReadRegistry
|
||
|
||
|
||
NTSTATUS
|
||
SpudOpenRegistry(
|
||
IN PUNICODE_STRING BaseName,
|
||
OUT PHANDLE ParametersHandle
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called by SPUD to open the registry. If the registry
|
||
tree exists, then it opens it and returns STATUS_SUCCESS.
|
||
|
||
Arguments:
|
||
|
||
BaseName - Where in the registry to start looking for the information.
|
||
|
||
LinkageHandle - Returns the handle used to read linkage information.
|
||
|
||
ParametersHandle - Returns the handle used to read other
|
||
parameters.
|
||
|
||
Return Value:
|
||
|
||
The status of the request.
|
||
|
||
--*/
|
||
{
|
||
|
||
HANDLE configHandle;
|
||
NTSTATUS status;
|
||
PWSTR parametersString = REGISTRY_PARAMETERS;
|
||
UNICODE_STRING parametersKeyName;
|
||
OBJECT_ATTRIBUTES objectAttributes;
|
||
ULONG disposition;
|
||
|
||
PAGED_CODE( );
|
||
|
||
//
|
||
// Open the registry for the initial string.
|
||
//
|
||
|
||
InitializeObjectAttributes(
|
||
&objectAttributes,
|
||
BaseName, // name
|
||
OBJ_CASE_INSENSITIVE, // attributes
|
||
NULL, // root
|
||
NULL // security descriptor
|
||
);
|
||
|
||
status = ZwOpenKey(
|
||
&configHandle,
|
||
KEY_READ,
|
||
&objectAttributes
|
||
);
|
||
|
||
if (!NT_SUCCESS(status)) {
|
||
return STATUS_UNSUCCESSFUL;
|
||
}
|
||
|
||
//
|
||
// Now open the parameters key.
|
||
//
|
||
|
||
RtlInitUnicodeString (¶metersKeyName, parametersString);
|
||
|
||
InitializeObjectAttributes(
|
||
&objectAttributes,
|
||
¶metersKeyName, // name
|
||
OBJ_CASE_INSENSITIVE, // attributes
|
||
configHandle, // root
|
||
NULL // security descriptor
|
||
);
|
||
|
||
status = ZwOpenKey(
|
||
ParametersHandle,
|
||
KEY_READ,
|
||
&objectAttributes
|
||
);
|
||
if (!NT_SUCCESS(status)) {
|
||
|
||
ZwClose( configHandle );
|
||
return status;
|
||
}
|
||
|
||
//
|
||
// All keys successfully opened.
|
||
//
|
||
|
||
ZwClose( configHandle );
|
||
return STATUS_SUCCESS;
|
||
|
||
} // SpudOpenRegistry
|
||
|
||
|
||
ULONG
|
||
SpudReadSingleParameter(
|
||
IN HANDLE ParametersHandle,
|
||
IN PWCHAR ValueName,
|
||
IN LONG DefaultValue
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called by SPUD to read a single parameter
|
||
from the registry. If the parameter is found it is stored
|
||
in Data.
|
||
|
||
Arguments:
|
||
|
||
ParametersHandle - A pointer to the open registry.
|
||
|
||
ValueName - The name of the value to search for.
|
||
|
||
DefaultValue - The default value.
|
||
|
||
Return Value:
|
||
|
||
The value to use; will be the default if the value is not
|
||
found or is not in the correct range.
|
||
|
||
--*/
|
||
|
||
{
|
||
static ULONG informationBuffer[32]; // declare ULONG to get it aligned
|
||
PKEY_VALUE_FULL_INFORMATION information =
|
||
(PKEY_VALUE_FULL_INFORMATION)informationBuffer;
|
||
UNICODE_STRING valueKeyName;
|
||
ULONG informationLength;
|
||
LONG returnValue;
|
||
NTSTATUS status;
|
||
|
||
PAGED_CODE( );
|
||
|
||
RtlInitUnicodeString( &valueKeyName, ValueName );
|
||
|
||
status = ZwQueryValueKey(
|
||
ParametersHandle,
|
||
&valueKeyName,
|
||
KeyValueFullInformation,
|
||
(PVOID)information,
|
||
sizeof (informationBuffer),
|
||
&informationLength
|
||
);
|
||
|
||
if ((status == STATUS_SUCCESS) && (information->DataLength == sizeof(ULONG))) {
|
||
|
||
RtlMoveMemory(
|
||
(PVOID)&returnValue,
|
||
((PUCHAR)information) + information->DataOffset,
|
||
sizeof(ULONG)
|
||
);
|
||
|
||
if (returnValue < 0) {
|
||
|
||
returnValue = DefaultValue;
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
returnValue = DefaultValue;
|
||
}
|
||
|
||
return returnValue;
|
||
|
||
} // SpudReadSingleParameter
|
||
|