Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

249 lines
6.5 KiB

/*++
Copyright (c) 1996 Microsoft Corporation
Module Name:
driverex.c
Abstract
Driver extension list management.
Authors:
Ervin P.
Environment:
Kernel mode only
Revision History:
--*/
#include "pch.h"
/*
* Including initguid.h defines the INITGUID symbol, which causes
* GUID_CLASS_INPUT (in hidclass.h and poclass.h)
* and GUID_DEVICE_SYS_BUTTON (in poclass.h) to get defined.
*/
#include <initguid.h>
#include <hidclass.h> // hidclass.h only defines GUID_CLASS_INPUT
#include <wdmguid.h>
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, DllInitialize)
#pragma alloc_text(PAGE, DllUnload)
#pragma alloc_text(PAGE, DriverEntry)
#endif
LIST_ENTRY driverExtList;
FAST_MUTEX driverExtListMutex;
//
// Global counter of HID FDOs used for device object naming, destined to go
// away once the device object naming issues are ironed out
//
ULONG HidpNextHidNumber = 0;
#define MAKEULONG(low, high) ((ULONG)(((USHORT)(low)) | (((ULONG)((USHORT)(high))) << 16)))
/*
********************************************************************************
* EnqueueDriverExt
********************************************************************************
*
*
*/
BOOLEAN EnqueueDriverExt(PHIDCLASS_DRIVER_EXTENSION driverExt)
{
PLIST_ENTRY listEntry;
BOOLEAN result = TRUE;
DBGVERBOSE(("Enqueue driver extension..."));
ExAcquireFastMutex(&driverExtListMutex);
/*
* Make sure this driver entry is not already in our list.
*/
listEntry = &driverExtList;
while ((listEntry = listEntry->Flink) != &driverExtList){
PHIDCLASS_DRIVER_EXTENSION thisDriverExt;
thisDriverExt = CONTAINING_RECORD( listEntry,
HIDCLASS_DRIVER_EXTENSION,
ListEntry);
if (thisDriverExt == driverExt){
/*
* This driver extension is already in our list!
*/
ASSERT(thisDriverExt != driverExt);
result = FALSE;
break;
}
}
if (result){
InsertHeadList(&driverExtList, &driverExt->ListEntry);
}
ExReleaseFastMutex(&driverExtListMutex);
return result;
}
/*
********************************************************************************
* RefDriverExt
********************************************************************************
*
*
*/
PHIDCLASS_DRIVER_EXTENSION RefDriverExt(IN PDRIVER_OBJECT MinidriverObject)
{
PLIST_ENTRY listEntry;
PHIDCLASS_DRIVER_EXTENSION hidDriverExtension, result = NULL;
DBGVERBOSE(("Ref driver extension..."));
ExAcquireFastMutex(&driverExtListMutex);
listEntry = &driverExtList;
while ((listEntry = listEntry->Flink) != &driverExtList){
hidDriverExtension = CONTAINING_RECORD( listEntry,
HIDCLASS_DRIVER_EXTENSION,
ListEntry );
ASSERT(ISPTR(hidDriverExtension));
if (hidDriverExtension->MinidriverObject == MinidriverObject){
hidDriverExtension->ReferenceCount++;
result = hidDriverExtension;
break;
}
}
ExReleaseFastMutex(&driverExtListMutex);
ASSERT(result);
return result;
}
/*
********************************************************************************
* DerefDriverExt
********************************************************************************
*
*/
PHIDCLASS_DRIVER_EXTENSION DerefDriverExt(IN PDRIVER_OBJECT MinidriverObject)
{
PLIST_ENTRY listEntry;
PHIDCLASS_DRIVER_EXTENSION result = NULL;
DBGVERBOSE(("Deref driver extension..."));
ExAcquireFastMutex(&driverExtListMutex);
listEntry = &driverExtList;
while ((listEntry = listEntry->Flink) != &driverExtList){
PHIDCLASS_DRIVER_EXTENSION hidDriverExtension =
CONTAINING_RECORD( listEntry,
HIDCLASS_DRIVER_EXTENSION,
ListEntry);
ASSERT(ISPTR(hidDriverExtension));
if (hidDriverExtension->MinidriverObject == MinidriverObject){
hidDriverExtension->ReferenceCount--;
/*
* The extra dereference in HidpDriverUnload should
* cause this ReferenceCount to eventually go to -1;
* at that time, we can dequeue it.
*/
if (hidDriverExtension->ReferenceCount < 0){
/*
* No need to free hidDriverExtension;
* it gets freed when the driver object is freed.
*/
ASSERT(hidDriverExtension->ReferenceCount == -1);
RemoveEntryList(listEntry);
if (hidDriverExtension->RegistryPath.Buffer) {
ExFreePool(hidDriverExtension->RegistryPath.Buffer);
}
}
result = hidDriverExtension;
break;
}
}
ExReleaseFastMutex(&driverExtListMutex);
ASSERT(result);
return result;
}
/*
********************************************************************************
* DllUnload
********************************************************************************
*
* We need this routine so that the driver can get unloaded when all
* references have been dropped by the minidriver.
*
*/
NTSTATUS
DllUnload (VOID)
{
PAGED_CODE();
DBGVERBOSE(("Unloading..."));
return STATUS_SUCCESS;
}
/*
********************************************************************************
* DllInitialize
********************************************************************************
*
* This routine called instead of DriverEntry since we're loaded as a DLL.
*
*/
NTSTATUS
DllInitialize (PUNICODE_STRING RegistryPath)
{
PAGED_CODE();
DBGVERBOSE(("Initializing hidclass dll..."));
InitializeListHead(&driverExtList);
ExInitializeFastMutex(&driverExtListMutex);
HidpNextHidNumber = 0;
return STATUS_SUCCESS;
}
/*
********************************************************************************
* DriverEntry
********************************************************************************
*
* This routine is required by the linker,
* but SHOULD NEVER BE CALLED since we're loaded as a DLL.
*
*/
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
UNREFERENCED_PARAMETER(DriverObject);
UNREFERENCED_PARAMETER(RegistryPath);
PAGED_CODE();
ASSERT(!(PVOID)"DriverEntry should never get called!");
return STATUS_SUCCESS;
}