Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

226 lines
5.4 KiB

/****************************************************************************
*
* reslist.c
*
* Copyright (c) 1994 Microsoft Corporation. All Rights Reserved.
*
* This file contains code for querying the registry so that drivers
* can grey invalid resource options prior to loading drivers
*
****************************************************************************/
#include <windows.h>
#include "reslist.h"
#include <registry.h>
#include <stdio.h>
typedef BOOL ENUMKEYSCALLBACK(PVOID, HKEY, LPTSTR);
typedef BOOL ENUMKEYVALUESCALLBACK(PVOID, LPTSTR, DWORD, PVOID, DWORD);
/*
**
**
**
*/
BOOL EnumKeys(HKEY hKey,
LPTSTR KeyName,
ENUMKEYSCALLBACK *Callback,
PVOID Context
)
{
HKEY SubKey;
DWORD Index;
TCHAR SubKeyName[MAX_PATH];
if (ERROR_SUCCESS != RegOpenKey(hKey, KeyName, &SubKey)) {
return FALSE;
}
for (Index = 0; ;Index++) {
DWORD Rc;
Rc = RegEnumKey(SubKey,
Index,
SubKeyName,
MAX_PATH);
if (Rc == ERROR_SUCCESS) {
if (!(*Callback)(Context, SubKey, SubKeyName)) {
RegCloseKey(SubKey);
return FALSE;
}
} else {
RegCloseKey(SubKey);
return Rc == ERROR_NO_MORE_ITEMS;
}
}
}
BOOL EnumKeyValues(HKEY hKey,
LPTSTR KeyName,
ENUMKEYVALUESCALLBACK *Callback,
PVOID Context
)
{
HKEY SubKey;
DWORD Index;
TCHAR ValueName[MAX_PATH];
if (ERROR_SUCCESS != RegOpenKey(hKey, KeyName, &SubKey)) {
return FALSE;
}
for (Index = 0; ;Index++) {
DWORD Rc;
DWORD Type;
DWORD cchName;
DWORD ccbData;
cchName = MAX_PATH;
Rc = RegEnumValue(SubKey,
Index,
ValueName,
&cchName,
NULL,
&Type,
NULL,
&ccbData);
if (Rc == ERROR_SUCCESS) {
PBYTE pData;
pData = (PBYTE)LocalAlloc(LPTR, ccbData);
if (pData == NULL) {
RegCloseKey(SubKey);
return FALSE;
}
Rc = RegQueryValueEx(SubKey,
ValueName,
NULL,
&Type,
pData,
&ccbData);
if (ERROR_SUCCESS != Rc ||
!(*Callback)(Context, ValueName, Type, pData, ccbData)) {
LocalFree((HLOCAL)pData);
RegCloseKey(SubKey);
return FALSE;
}
LocalFree((HLOCAL)pData);
} else {
RegCloseKey(SubKey);
return Rc == ERROR_NO_MORE_ITEMS;
}
}
}
BOOL EnumerateDrivers(PVOID Context, HKEY hKey, LPTSTR SubKeyName)
{
PRESOURCE_INFO ResInfo = (PRESOURCE_INFO)Context;
if (ResInfo->IgnoreDriver != NULL &&
lstrcmpi(SubKeyName, ResInfo->IgnoreDriver) == 0) {
return TRUE;
}
ResInfo->DriverName = SubKeyName;
return EnumKeyValues(hKey, SubKeyName, EnumerateDevices, Context);
}
BOOL EnumerateDriverTypes(PVOID Context, HKEY hKey, LPTSTR SubKeyName)
{
PRESOURCE_INFO ResInfo = (PRESOURCE_INFO)Context;
ResInfo->DriverType = SubKeyName;
return EnumKeys(hKey, SubKeyName, EnumerateDrivers, Context);
}
BOOL EnumResources(ENUMRESOURCECALLBACK Callback, PVOID Context, LPCTSTR IgnoreDriver)
{
HKEY hKey;
RESOURCE_INFO ResInfo;
ResInfo.AppContext = Context;
ResInfo.AppCallback = Callback;
ResInfo.IgnoreDriver = IgnoreDriver;
/*
** Open the resources registry key then recursively enumerate
** all resource lists
*/
return EnumKeys(HKEY_LOCAL_MACHINE,
TEXT("HARDWARE\\RESOURCEMAP"),
EnumerateDriverTypes,
(PVOID)&ResInfo);
}
/*
** Build a simple routine to find what interrupts and DMA channels
** are in use
*/
typedef struct {
DD_BUS_TYPE MinBusType;
DWORD Interrupts[DD_NumberOfBusTypes];
DWORD DmaChannels[DD_NumberOfBusTypes];
} INTERRUPTS_AND_DMA, *PINTERRUPTS_AND_DMA;
BOOL GetInterruptsAndDMACallback(
PVOID Context,
DD_BUS_TYPE BusType,
DD_RESOURCE_TYPE ResourceType,
PDD_CONFIG_DATA ConfigData
)
{
PINTERRUPTS_AND_DMA pData;
pData = Context;
if (pData->MinBusType > BusType) {
pData->MinBusType = BusType;
}
switch (ResourceType) {
case DD_Interrupt:
pData->Interrupts[BusType] |= 1 << ConfigData->Interrupt;
break;
case DD_DmaChannel:
pData->DmaChannels[BusType] |= 1 << ConfigData->DmaChannel;
break;
break;
}
return TRUE;
}
BOOL GetInterruptsAndDMA(
LPDWORD InterruptsInUse,
LPDWORD DmaChannelsInUse,
LPCTSTR IgnoreDriver
)
{
INTERRUPTS_AND_DMA Data;
ZeroMemory((PVOID)&Data, sizeof(Data));
Data.MinBusType = DD_NumberOfBusTypes;
EnumResources(GetInterruptsAndDMACallback, &Data, IgnoreDriver);
if (Data.MinBusType == DD_NumberOfBusTypes) {
return FALSE;
}
*InterruptsInUse = Data.Interrupts[Data.MinBusType];
*DmaChannelsInUse = Data.DmaChannels[Data.MinBusType];
return TRUE;
}