Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1148 lines
27 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 "pnpstuff.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;
BOOL boolForced;
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;
} /* GetDevNodeInfoAndCreateNewDevInfoNode */
/*++
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;
//
// 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);
goto RetFALSE;
}
if ((szDevIDBuffer = malloc(sizeof(TCHAR) * ulDevIDBufferLen)) == NULL ||
(szDevNodeID = malloc(sizeof(TCHAR) * ulDevIDBufferLen)) == NULL)
{
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);
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)
{
wsprintf(szDevNodeID, TEXT("%s"), szDevIDBuffer + ulStart);
//
// Found the DevNode, so add its information to the device list
//
if (!(GetDevNodeInfoAndCreateNewDevInfoNode(dnDevNode,
szDevNodeID,
szEnumBuffer)))
{
goto RetFALSE;
}
}
}
}
return TRUE;
RetFALSE:
return FALSE;
} /* Parse Enumerator */
void CollectDevData()
{
CONFIGRET cmret = CR_SUCCESS;
ULONG ulIndexNum = 0;
ULONG ulEnumBufferLen = 0;
PTCHAR szEnumBuffer;
szEnumBuffer = malloc(sizeof(TCHAR) * MAX_DEVNODE_ID_LEN);
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);
}
}
} /* CollectDevData */
/*++
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
--*/
BOOL CopyRegistryLine(IN DEVNODE dnDevNode,
IN ULONG ulPropertyType,
IN PDEV_INFO pdiDevInfo)
{
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 = 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;
}
}
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:
wsprintf(pdiDevInfo->szDescription, TEXT("%s"), szRegData);
break;
case CM_DRP_HARDWAREID:
wsprintf(pdiDevInfo->szHardwareID, TEXT("%s"), szRegData);
break;
case CM_DRP_SERVICE:
wsprintf(pdiDevInfo->szService, TEXT("%s"), szRegData);
break;
case CM_DRP_CLASS:
wsprintf(pdiDevInfo->szClass, TEXT("%s"), szRegData);
break;
case CM_DRP_MFG:
wsprintf(pdiDevInfo->szManufacturer, TEXT("%s"), szRegData);
break;
case CM_DRP_CONFIGFLAGS:
wsprintf(pdiDevInfo->szConfigFlags, TEXT("%s"), szRegData);
break;
// Log(23, SEV2, TEXT("Invalid property type"));
}
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] = '\0';
pdiDevInfo->szDescription[0] = '\0';
pdiDevInfo->szHardwareID[0] = '\0';
pdiDevInfo->szService[0] = '\0';
pdiDevInfo->szClass[0] = '\0';
pdiDevInfo->szManufacturer[0] = '\0';
pdiDevInfo->szConfigFlags[0] = '\0';
pdiDevInfo->szFriendlyName[0] = '\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
//
wsprintf(pdiDevInfo->szDevNodeID, TEXT("%s"), szDevNodeID);
//
// 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] != '\0')
{
wsprintf(pdiDevInfo->szFriendlyName, TEXT("%s"),
pdiDevInfo->szDescription);
}
else if (pdiDevInfo->szHardwareID &&
pdiDevInfo->szHardwareID[0] != '\0')
{
wsprintf(pdiDevInfo->szFriendlyName, TEXT("%s"),
pdiDevInfo->szHardwareID);
}
else if (pdiDevInfo->szManufacturer &&
pdiDevInfo->szManufacturer[0] != '\0')
{
wsprintf(pdiDevInfo->szFriendlyName, TEXT("%s"),
pdiDevInfo->szHardwareID);
}
else if (pdiDevInfo->szService &&
pdiDevInfo->szService[0] != '\0')
{
wsprintf(pdiDevInfo->szFriendlyName, TEXT("%s"),
pdiDevInfo->szService);
}
else if (pdiDevInfo->szClass &&
pdiDevInfo->szClass[0] != '\0')
{
wsprintf(pdiDevInfo->szFriendlyName, TEXT("%s"),
pdiDevInfo->szClass);
}
else
{
wsprintf(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)
{
// Log(24, SEV2, TEXT("ResDesData malloc failed."));
goto RetFALSE;
}
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 RetFALSE;
}
}
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);
}
}
//
// **** change this by making resDesData = pdiDevInfo->----ResDesDAta
// and merging into one code
//
//
// 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:
// Log(24, SEV2, TEXT("Illegal LogConfType\n - %ul"), ulLogConfType);
goto RetFALSE;
}
return TRUE;
RetFALSE:
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 */