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.
 
 
 
 
 
 

1062 lines
25 KiB

#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#include <string.h>
#include <regstr.h>
#include <cfgmgr32.h>
#include "netinfo.h"
// Globals
DEV_INFO *g_pdiDevList; // Head of device list
/*++
Routine Description: (21) GetDevNodeInfoAndCreateNewDevInfoNode
Creates new list node, then gets registry and resource information for
a specific device and copies it into that node. Finally, adds new node
to beginning of linked list
Arguments:
dnDevNode: the device to find information about
szDevNodeID: the registry path name of the device
szEnumBuffer: name of enumerator this device is under
Return Value:
BOOL: TRUE if function succeeds, FALSE if not
--*/
BOOL GetDevNodeInfoAndCreateNewDevInfoNode(IN DEVNODE dnDevNode,
IN PTCHAR szDevNodeID,
IN PTCHAR szEnumBuffer)
{
LOG_CONF lcLogConf = 0, lcLogConfNew;
CONFIGRET cmret, cmret2;
PDEV_INFO pdiDevInfo=(PDEV_INFO)malloc(sizeof(DEV_INFO));
int i;
BOOL boolForcedFound = FALSE, boolAllocFound = FALSE;
USHORT ushLogConfType[4] = {BOOT_LOG_CONF, ALLOC_LOG_CONF, BASIC_LOG_CONF, FORCED_LOG_CONF};
if (pdiDevInfo == NULL)
goto RetFALSE;
// If this is not a PnP device, skip it
if (!lstrcmpi(szEnumBuffer, TEXT("Root"))) {
free(pdiDevInfo);
goto RetTRUE;
}
//
// Initialize fields inside the node
//
if (!InitializeInfoNode(pdiDevInfo, szDevNodeID, dnDevNode)) {
// This is a device we don't want to list. Skip it
free(pdiDevInfo);
goto RetTRUE;
}
for (i = 0; i < NUM_LOG_CONF_TYPES; i++) {
// Get logical configuration information
cmret = CM_Get_First_Log_Conf(&lcLogConfNew,
dnDevNode,
ushLogConfType[i]);
while (CR_SUCCESS == cmret) {
lcLogConf = lcLogConfNew;
if (ALLOC_LOG_CONF == ushLogConfType[i]) {
boolAllocFound = TRUE;
}
if (!(GetResDesList(pdiDevInfo, lcLogConf, ushLogConfType[i]))) {
goto RetFALSE;
}
cmret = CM_Get_Next_Log_Conf(&lcLogConfNew,
lcLogConf,
0);
cmret2 = CM_Free_Log_Conf_Handle(lcLogConf);
}
}
//
// If device has no Alloc configurations, skip
// to the next device
//
if (!boolAllocFound) {
//free(pdiDevInfo);
//goto RetTRUE;
}
//
// Insert new pdiDevInfo into Linked List of DevNodes
//
if (g_pdiDevList == NULL) {
//
// DevList is empty
//
g_pdiDevList = pdiDevInfo;
} else {
//
// Add new pdiDevInfo to beginning of linked list
//
pdiDevInfo->Next = g_pdiDevList;
g_pdiDevList->Prev = pdiDevInfo;
g_pdiDevList = pdiDevInfo;
}
RetTRUE:
return TRUE;
RetFALSE:
return FALSE;
}
/*++
Routine Description: (20) ParseEnumerator
Gets devices listed under enumerator name in registry
Arguments:
szEnumBuffer: the enumerator name
Return Value:
BOOL: TRUE if function succeeds, FALSE if not
--*/
BOOL
ParseEnumerator(IN PTCHAR szEnumBuffer)
{
PTCHAR szDevIDBuffer = NULL;
PTCHAR szDevNodeID = NULL;
ULONG ulDevIDBufferLen = 0, ulCount = 0, ulStart = 0;
CONFIGRET cmret = CR_SUCCESS;
DEVNODE dnDevNode;
BOOL bReturn = TRUE;
//
// Get buffer length
//
cmret = CM_Get_Device_ID_List_Size(&ulDevIDBufferLen,
szEnumBuffer,
CM_GETIDLIST_FILTER_ENUMERATOR);
if (CR_SUCCESS != cmret) {
//ErrorLog(20, TEXT("CM_Get_Device_ID_List_Size"), cmret, NULL);
bReturn = FALSE;
goto RetFALSE;
}
if ((szDevIDBuffer =(PTCHAR) malloc(sizeof(TCHAR) * ulDevIDBufferLen)) == NULL ||
(szDevNodeID =(PTCHAR) malloc(sizeof(TCHAR) * ulDevIDBufferLen)) == NULL) {
bReturn = FALSE;
goto RetFALSE;
}
//
// Get the Device ID List
//
cmret = CM_Get_Device_ID_List(szEnumBuffer,
szDevIDBuffer,
ulDevIDBufferLen,
CM_GETIDLIST_FILTER_ENUMERATOR);
if (CR_SUCCESS != cmret) {
//ErrorLog(20, TEXT("CM_Get_Device_ID_List"), cmret, NULL);
bReturn = FALSE;
goto RetFALSE;
}
//
// Note that ulDevIDBufferLen is a loose upper bound. The API may have
// returned a size greater than the actual size of the list of strings.
//
for (ulCount = 0; ulCount < ulDevIDBufferLen; ulCount++) {
ulStart = ulCount;
if (szDevIDBuffer[ulCount] != '\0') {
cmret = CM_Locate_DevNode(&dnDevNode,
szDevIDBuffer + ulCount,
CM_LOCATE_DEVNODE_NORMAL);
//
// Go to the next substring
//
while (szDevIDBuffer[ulCount] != TEXT('\0')) {
ulCount++;
}
// Stop when we reach the double-NULL terminator
if (szDevIDBuffer[ulCount+1] == TEXT('\0')) {
ulCount=ulDevIDBufferLen;
continue;
}
if (cmret == CR_SUCCESS) {
_tcsncpy(szDevNodeID, szDevIDBuffer + ulStart, ulDevIDBufferLen);
// Found the DevNode, so add its information to the device list
if (!(GetDevNodeInfoAndCreateNewDevInfoNode(dnDevNode,
szDevNodeID,
szEnumBuffer))) {
bReturn = FALSE;
goto RetFALSE;
}
}
}
}
bReturn = TRUE;
RetFALSE:
// fix to rajeshm old code. Selective free bug number 137987
if (NULL != szDevIDBuffer)
free (szDevIDBuffer);
if (NULL != szDevNodeID)
free (szDevNodeID);
return bReturn;
}
void
CollectDevData() {
CONFIGRET cmret = CR_SUCCESS;
ULONG ulIndexNum = 0;
ULONG ulEnumBufferLen = 0;
PTCHAR szEnumBuffer;
szEnumBuffer = (PTCHAR) malloc(sizeof(TCHAR) * MAX_DEVNODE_ID_LEN);
if (NULL == szEnumBuffer)
return;
for (ulIndexNum = 0; cmret == CR_SUCCESS; ulIndexNum++) {
ulEnumBufferLen = MAX_DEVNODE_ID_LEN;
cmret = CM_Enumerate_Enumerators( ulIndexNum,
szEnumBuffer,
&ulEnumBufferLen,
0);
if (cmret == CR_SUCCESS)
ParseEnumerator(szEnumBuffer);
}
free (szEnumBuffer);
}
BOOL CopyRegistryLine(IN DEVNODE dnDevNode,
IN ULONG ulPropertyType,
IN PDEV_INFO pdiDevInfo)
/*++
Routine Description: (22) CopyRegistryLine
Copies one specific string of registry data to new list node
Arguments:
dnDevNode: the device to get information about
ulpropertyType: which registry string to get
pdiDevInfo: the new list node
Return Value:
BOOL: TRUE if function succeeds, FALSE if not
--*/
{
ULONG ulRegDataLen = 0, ulRegDataType = 0;
CONFIGRET cmret = CR_SUCCESS;
PTCHAR szRegData = NULL;
//
// Get the length of the buffer don't bother checking return value
// If RegProperty doesn't exist, we'll just move on
//
CM_Get_DevNode_Registry_Property(dnDevNode,
ulPropertyType,
NULL,
NULL,
&ulRegDataLen,
0);
if (!ulRegDataLen ||
(szRegData = (PTCHAR) malloc(sizeof(TCHAR) * ulRegDataLen)) == NULL) {
goto RetFALSE;
}
//
// Now get the registry information
//
cmret = CM_Get_DevNode_Registry_Property( dnDevNode,
ulPropertyType,
&ulRegDataType,
szRegData,
&ulRegDataLen,
0);
if (CR_SUCCESS == cmret) {
if (!(CopyRegDataToDevInfoNode(pdiDevInfo,
ulPropertyType,
szRegData))) {
goto RetFALSE;
}
}
if (szRegData == NULL)
free (szRegData);
return TRUE;
RetFALSE:
return FALSE;
} /* CopyRegistryLine */
/*++
Routine Description: (23) CopyRegDataToDevInfoNode
Copies a registry string to a list node
Arguments:
pdiDevInfo: the new list node
ulPropertyType: which registry string to copy
szRegData: the data to be copied
Return Value:
BOOL: TRUE if function succeeds, FALSE if not
--*/
BOOL CopyRegDataToDevInfoNode(IN OUT PDEV_INFO pdiDevInfo,
IN ULONG ulPropertyType,
IN PTCHAR szRegData)
{
if (pdiDevInfo == NULL) {
goto RetFALSE;
}
switch (ulPropertyType) {
case CM_DRP_DEVICEDESC:
_tcsncpy(pdiDevInfo->szDescription, szRegData, MAX_PATH );
break;
case CM_DRP_HARDWAREID:
_tcsncpy(pdiDevInfo->szHardwareID, szRegData, MAX_PATH );
break;
case CM_DRP_SERVICE:
_tcsncpy(pdiDevInfo->szService, szRegData, MAX_PATH );
break;
case CM_DRP_CLASS:
_tcsncpy(pdiDevInfo->szClass, szRegData, MAX_PATH );
break;
case CM_DRP_MFG:
_tcsncpy(pdiDevInfo->szManufacturer, szRegData, MAX_PATH );
break;
case CM_DRP_CONFIGFLAGS:
_tcsncpy(pdiDevInfo->szConfigFlags, szRegData, MAX_PATH );
break;
}
return TRUE;
RetFALSE:
return FALSE;
} /* CopyRegDataToDevInfoNode */
/*++
Routine Description: (58) InitializeInfoNode
Initialized fields inside the new node
Arguments:
pdiDevInfo: the node
szDevNodeID: used to find the dnDevNode in the future
dnDevNode: the device we're storing information about
Return Value:
BOOL: TRUE if we should keep this node, FALSE if we should throw it away
--*/
BOOL InitializeInfoNode(IN PDEV_INFO pdiDevInfo,
IN PTCHAR szDevNodeID,
IN DEVNODE dnDevNode)
{
if (pdiDevInfo) {
pdiDevInfo->Next = NULL;
pdiDevInfo->Prev = NULL;
pdiDevInfo->szDevNodeID[0] = TEXT('\0');
pdiDevInfo->szDescription[0] = TEXT('\0');
pdiDevInfo->szHardwareID[0] = TEXT('\0');
pdiDevInfo->szService[0] = TEXT('\0');
pdiDevInfo->szClass[0] = TEXT('\0');
pdiDevInfo->szManufacturer[0] = TEXT('\0');
pdiDevInfo->szConfigFlags[0] = TEXT('\0');
pdiDevInfo->szFriendlyName[0] = TEXT('\0');
pdiDevInfo->boolSavedOrigConfiguration = FALSE;
pdiDevInfo->boolDisabled = FALSE;
pdiDevInfo->prddForcedResDesData = NULL;
pdiDevInfo->prddAllocResDesData = NULL;
pdiDevInfo->prddBasicResDesData = NULL;
pdiDevInfo->prddBootResDesData = NULL;
//
// Store devNodeID in pdiDevInfo to get handles to devnode in future
//
_tcsncpy(pdiDevInfo->szDevNodeID, szDevNodeID, MAX_PATH);
// Extract information from the registry about this DevNode
CopyRegistryLine(dnDevNode, CM_DRP_DEVICEDESC, pdiDevInfo);
CopyRegistryLine(dnDevNode, CM_DRP_HARDWAREID, pdiDevInfo);
CopyRegistryLine(dnDevNode, CM_DRP_SERVICE, pdiDevInfo);
CopyRegistryLine(dnDevNode, CM_DRP_CLASS, pdiDevInfo);
CopyRegistryLine(dnDevNode, CM_DRP_MFG, pdiDevInfo);
CopyRegistryLine(dnDevNode, CM_DRP_CONFIGFLAGS, pdiDevInfo);
RecordFriendlyName(pdiDevInfo);
}
//
// Check the friendly name to see if we want to throw this node away
//
if (strcmp(pdiDevInfo->szFriendlyName, "STORAGE/Volume") == 0 ||
strcmp(pdiDevInfo->szFriendlyName, "Unknown Device") == 0) {
return FALSE;
}
return TRUE;
} /* InitializeInfoNode */
/*++
Routine Description: (57) RecordFriendlyName
Finds the best user friendly name for this device
Arguments:
pdiDevInfo: node containing all possible names
Return Value:
void
--*/
void
RecordFriendlyName(IN PDEV_INFO pdiDevInfo)
{
if (pdiDevInfo) {
if (pdiDevInfo->szDescription && pdiDevInfo->szDescription[0] != TEXT('\0'))
_tcsncpy(pdiDevInfo->szFriendlyName, pdiDevInfo->szDescription, MAX_PATH );
else if (pdiDevInfo->szHardwareID && pdiDevInfo->szHardwareID[0] != TEXT('\0'))
_tcsncpy(pdiDevInfo->szFriendlyName, pdiDevInfo->szHardwareID, MAX_PATH);
else if (pdiDevInfo->szManufacturer && pdiDevInfo->szManufacturer[0] != TEXT('\0'))
_tcsncpy(pdiDevInfo->szFriendlyName, pdiDevInfo->szHardwareID, MAX_PATH);
else if (pdiDevInfo->szService && pdiDevInfo->szService[0] != TEXT('\0'))
_tcsncpy(pdiDevInfo->szFriendlyName, pdiDevInfo->szService, MAX_PATH);
else if (pdiDevInfo->szClass && pdiDevInfo->szClass[0] != TEXT('\0'))
_tcsncpy(pdiDevInfo->szFriendlyName, pdiDevInfo->szClass, MAX_PATH);
else
_tcscpy(pdiDevInfo->szFriendlyName, TEXT("Unknown Device"));
}
} /* RecordFriendlyName */
/*++
Routine Description: (24) GetResDesList
Creates new resource data node and copies resource information to that node
Arguments:
pdiDevInfo: the list node which will contain the new resource node
lcLogConf: the logical configuration information
ulLogConfType: FORCED, ALLOC, BOOT, or BASIC logical configuration
Return Value:
BOOL: TRUE if function succeeds, FALSE if not
--*/
BOOL
GetResDesList(IN OUT PDEV_INFO pdiDevInfo,
IN LOG_CONF lcLogConf,
IN ULONG ulLogConfType)
{
CONFIGRET cmret, cmret2;
RES_DES rdResDes = 0, rdResDesNew;
RESOURCEID ridResourceID = 0;
PRES_DES_DATA prddResDesData;
prddResDesData = (PRES_DES_DATA)malloc(sizeof(RES_DES_DATA));
if (prddResDesData == NULL)
goto c0;
prddResDesData->Next = NULL;
prddResDesData->Prev = NULL;
prddResDesData->pmresMEMResource = NULL;
prddResDesData->piresIOResource = NULL;
prddResDesData->pdresDMAResource = NULL;
prddResDesData->pqresIRQResource = NULL;
cmret = CM_Get_Next_Res_Des(&rdResDesNew,
lcLogConf,
ResType_All,
&ridResourceID,
0);
//
// Go through each resource type and copy data to new node
//
while (CR_SUCCESS == cmret) {
rdResDes = rdResDesNew;
if (ridResourceID >= ResType_Mem && ridResourceID <= ResType_IRQ) {
if (!(ProcessResDesInfo(prddResDesData,
rdResDes,
ridResourceID))) {
goto c1;
}
}
cmret = CM_Get_Next_Res_Des(&rdResDesNew,
rdResDes,
ResType_All,
&ridResourceID,
0);
cmret2 = CM_Free_Res_Des_Handle(rdResDes);
if (cmret2 != CR_SUCCESS) {
//ErrorLog(24, TEXT("CM_Free_Res_Des_Handle"), cmret2, NULL);
}
}
// Add the new node to the linked list
switch (ulLogConfType) {
case FORCED_LOG_CONF:
if (!pdiDevInfo->prddForcedResDesData) {
//
// This is the first entry into the linked list
//
pdiDevInfo->prddForcedResDesData = prddResDesData;
} else {
//
// Add new node to beginning of linked list
//
prddResDesData->Next = pdiDevInfo->prddForcedResDesData;
pdiDevInfo->prddForcedResDesData->Prev = prddResDesData;
pdiDevInfo->prddForcedResDesData = prddResDesData;
}
break;
case ALLOC_LOG_CONF:
if (!pdiDevInfo->prddAllocResDesData) {
//
// This is the first entry into the linked list
//
pdiDevInfo->prddAllocResDesData = prddResDesData;
} else {
//
// Add new node to beginning of linked list
//
prddResDesData->Next = pdiDevInfo->prddAllocResDesData;
pdiDevInfo->prddAllocResDesData->Prev = prddResDesData;
pdiDevInfo->prddAllocResDesData = prddResDesData;
}
break;
case BASIC_LOG_CONF:
if (!pdiDevInfo->prddBasicResDesData) {
//
// This is the first entry into the linked list
//
pdiDevInfo->prddBasicResDesData = prddResDesData;
} else {
//
// Add new node to beginning of linked list
//
prddResDesData->Next = pdiDevInfo->prddBasicResDesData;
pdiDevInfo->prddBasicResDesData->Prev = prddResDesData;
pdiDevInfo->prddBasicResDesData = prddResDesData;
}
break;
case BOOT_LOG_CONF:
if (!pdiDevInfo->prddBootResDesData) {
//
// This is the first entry into the linked list
//
pdiDevInfo->prddBootResDesData = prddResDesData;
} else {
//
// Add new node to beginning of linked list
//
prddResDesData->Next = pdiDevInfo->prddBootResDesData;
pdiDevInfo->prddBootResDesData->Prev = prddResDesData;
pdiDevInfo->prddBootResDesData = prddResDesData;
}
break;
default:
goto c1;
}
return TRUE;
c1:
free(prddResDesData);
c0:
return FALSE;
}
/* GetResDestList */
/*++
Routine Description: (25) ProcessResDesInfo
Gets information for one resource descriptor
Arguments:
prddResDesData: the new resource data node receiving the info
rdResDes: the resource descriptor containing the info
ridResourceID: tells the resource type (DMA, IO, MEM, IRQ, or CS)
Return Value:
BOOL: TRUE if function succeeds, FALSE if not
--*/
BOOL
ProcessResDesInfo(IN OUT PRES_DES_DATA prddResDesData,
IN RES_DES rdResDes,
IN RESOURCEID ridResourceID)
{
PVOID pvResDesDataBuffer = NULL;
ULONG ulResDesDataBufferLen;
CONFIGRET cmret;
cmret = CM_Get_Res_Des_Data_Size(&ulResDesDataBufferLen,
rdResDes,
0);
if (CR_SUCCESS != cmret) {
//ErrorLog(25, TEXT("CM_Get_Res_Des_Data_Size"), cmret, NULL);
goto RetFALSE;
}
if ((pvResDesDataBuffer = malloc(sizeof(PVOID) * ulResDesDataBufferLen))
== NULL) {
// Log(25, SEV2, TEXT("resDesDataBuffer malloc size of %d failed."),
// ulResDesDataBufferLen);
goto RetFALSE;
}
//
// Get the data
//
cmret = CM_Get_Res_Des_Data(rdResDes,
pvResDesDataBuffer,
ulResDesDataBufferLen,
0);
if (CR_SUCCESS != cmret) {
//ErrorLog(25, TEXT("CM_Get_Res_Des_Data"), cmret, NULL);
goto RetFALSE;
}
//
// Copy data into ResDesData node
//
switch (ridResourceID) {
case ResType_Mem:
prddResDesData->pmresMEMResource = (PMEM_RESOURCE)pvResDesDataBuffer;
break;
case ResType_IO:
prddResDesData->piresIOResource = (PIO_RESOURCE)pvResDesDataBuffer;
break;
case ResType_DMA:
prddResDesData->pdresDMAResource = (PDMA_RESOURCE)pvResDesDataBuffer;
break;
case ResType_IRQ:
prddResDesData->pqresIRQResource = (PIRQ_RESOURCE)pvResDesDataBuffer;
break;
default:
// Log(25, SEV2, TEXT("Illegal ResourceID - %ul"), ridResourceID);
goto RetFALSE;
}
return TRUE;
RetFALSE:
return FALSE;
} /* ProcessResDesInfo */
/*++
Routine Description: (26) UpdateDeviceList
Frees resource information for all devices and then collects the
information again
Arguments:
none (g_pdiDevList is global head of device list)
Return Value:
BOOL: TRUE if function succeeds, FALSE if not
--*/
BOOL UpdateDeviceList()
{
PDEV_INFO pdiTmpDevInfo;
pdiTmpDevInfo = g_pdiDevList;
//
// Go through linked list and delete each node's ResDes lists
//
while (pdiTmpDevInfo) {
if (pdiTmpDevInfo->prddForcedResDesData) {
DeleteResDesDataNode(pdiTmpDevInfo->prddForcedResDesData);
pdiTmpDevInfo->prddForcedResDesData = NULL;
}
if (pdiTmpDevInfo->prddAllocResDesData) {
DeleteResDesDataNode(pdiTmpDevInfo->prddAllocResDesData);
pdiTmpDevInfo->prddAllocResDesData = NULL;
}
if (pdiTmpDevInfo->prddBasicResDesData) {
DeleteResDesDataNode(pdiTmpDevInfo->prddBasicResDesData);
pdiTmpDevInfo->prddBasicResDesData = NULL;
}
if (pdiTmpDevInfo->prddBootResDesData) {
DeleteResDesDataNode(pdiTmpDevInfo->prddBootResDesData);
pdiTmpDevInfo->prddBootResDesData = NULL;
}
pdiTmpDevInfo = pdiTmpDevInfo->Next;
}
pdiTmpDevInfo = g_pdiDevList;
//
// Recreate the ResDesLists for each node
//
while (pdiTmpDevInfo) {
if (!(RecreateResDesList(pdiTmpDevInfo, FORCED_LOG_CONF)))
goto RetFALSE;
if (!(RecreateResDesList(pdiTmpDevInfo, ALLOC_LOG_CONF)))
goto RetFALSE;
if (!(RecreateResDesList(pdiTmpDevInfo, BASIC_LOG_CONF)))
goto RetFALSE;
if (!(RecreateResDesList(pdiTmpDevInfo, BOOT_LOG_CONF)))
goto RetFALSE;
pdiTmpDevInfo = pdiTmpDevInfo->Next;
}
return TRUE;
RetFALSE:
return FALSE;
} /* UpdateDeviceList */
/*++
Routine Description: (27) DeleteResDesDataNode
Deletes a string of RES_DES_DATA structures
Arguments:
prddTmpResDes: the head of the linked list
Return Value:
void
--*/
void
DeleteResDesDataNode(IN PRES_DES_DATA prddTmpResDes)
{
PRES_DES_DATA prddNextResDes;
while (prddTmpResDes) {
prddNextResDes = prddTmpResDes->Next;
free (prddTmpResDes);
prddTmpResDes = prddNextResDes;
}
} /* DeleteResDesDataNode */
/*++
Routine Description: (56) CopyDataToLogConf
Calls CM_Add_Res_Des to add a resDes to a lcLogConf
Arguments:
lcLogConf: the lcLogConf receiving the resDes
ridResType: ResType_Mem, IO, DMA or IRQ
pvResData: the new data
ulResourceLen: size of the data
Return Value:
BOOL: TRUE if the CM call succeeds, FALSE if not
--*/
BOOL
CopyDataToLogConf(IN LOG_CONF lcLogConf,
IN RESOURCEID ridResType,
IN PVOID pvResData,
IN ULONG ulResourceLen)
{
CONFIGRET cmret;
RES_DES rdResDes;
//
// Copy the data to the logConf
//
cmret = CM_Add_Res_Des(&rdResDes,
lcLogConf,
ridResType,
pvResData,
ulResourceLen,
0);
if (CR_SUCCESS != cmret) {
goto RetFALSE;
}
return TRUE;
RetFALSE:
return FALSE;
} /* CopyDataToLogConf */
/*++
Routine Description: (28) RecreateResDesList
Uses CM calls to find ResDes information and creates linked list
of this information inside of given DEV_INFO
Arguments:
pdiTmpDevInfo: the node receiving the information
ulLogConfType: the LogConf type (FORCED_LOG_CONF,
ALLOC_LOG_CONF,
BASIC_LOG_CONF,
BOOT_LOG_CONF)
Return Value:
BOOL: TRUE if function succeeds, FALSE if not
--*/
BOOL
RecreateResDesList(IN OUT PDEV_INFO pdiTmpDevInfo,
IN ULONG ulLogConfType)
{
CONFIGRET cmret, cmret2;
DEVNODE dnDevNode;
LOG_CONF lcLogConf, lcLogConfNew;
//
// Get handle to the devnode
//
cmret = CM_Locate_DevNode(&dnDevNode,
pdiTmpDevInfo->szDevNodeID,
CM_LOCATE_DEVNODE_NORMAL);
if (CR_SUCCESS != cmret) {
//ErrorLog(28, TEXT("CM_Locate_DevNode"), cmret, NULL);
goto RetFALSE;
}
//
// Get logical configuration information
//
cmret = CM_Get_First_Log_Conf(&lcLogConfNew,
dnDevNode,
ulLogConfType);
while (CR_SUCCESS == cmret) {
lcLogConf = lcLogConfNew;
if (!(GetResDesList(pdiTmpDevInfo, lcLogConf, ulLogConfType))) {
goto RetFALSE;
}
cmret = CM_Get_Next_Log_Conf(&lcLogConfNew,
lcLogConf,
0);
cmret2 = CM_Free_Log_Conf_Handle(lcLogConf);
if (CR_SUCCESS != cmret2) {
//ErrorLog(28, TEXT("CM_Free_Log_Conf"), cmret2, NULL);
}
}
return TRUE;
RetFALSE:
return FALSE;
} /* RecreateResDesList */
void Cleanup()
{
PDEV_INFO pdiDevInfo = g_pdiDevList;
PDEV_INFO pdiNextInfoNode;
while (pdiDevInfo) {
pdiNextInfoNode = pdiDevInfo->Next;
DeleteResDesDataNode(pdiDevInfo->prddForcedResDesData);
DeleteResDesDataNode(pdiDevInfo->prddAllocResDesData);
DeleteResDesDataNode(pdiDevInfo->prddBasicResDesData);
DeleteResDesDataNode(pdiDevInfo->prddBootResDesData);
free(pdiDevInfo);
pdiDevInfo = pdiNextInfoNode;
}
} /* Cleanup */