866 lines
22 KiB
C++
866 lines
22 KiB
C++
|
|
// devnode.cpp0
|
|
#include "stdafx.h"
|
|
#include "devnode.h"
|
|
|
|
// globals from alcclass
|
|
AutoListClass *pALCHead = NULL;
|
|
AutoListClass *pALCTail = NULL;
|
|
int AutoListClassCount = NULL;
|
|
|
|
|
|
/*******************************************************************
|
|
Constructiors
|
|
*******************************************************************/
|
|
|
|
|
|
DevnodeClass::DevnodeClass(DEVNODE hDevice, DEVNODE l_hParent)
|
|
{
|
|
pDeviceID = NULL;
|
|
hDevnode = hDevice;
|
|
hParent = l_hParent;
|
|
pszDescription = NULL;
|
|
ulProblemCode = (ULONG) -1;
|
|
ulStatus = 0;
|
|
pszClass = NULL;
|
|
bDNHasMark = (BOOL)-1;
|
|
bCanDisable = FALSE;
|
|
bCanTest = FALSE;
|
|
bDidPass = FALSE;
|
|
pHardwareID = NULL;
|
|
pCompatID = NULL;
|
|
pszGUID = NULL;
|
|
pszLocation = NULL;
|
|
pszPDO = NULL;
|
|
pszFriendlyName = NULL;
|
|
pszMFG = NULL;
|
|
InterfaceBusType = InterfaceTypeUndefined;
|
|
GetDeviceInformation();
|
|
|
|
}
|
|
|
|
DevnodeClass::DevnodeClass(void)
|
|
{
|
|
pDeviceID = NULL;
|
|
hDevnode = 0;
|
|
hParent = 0;
|
|
pszDescription = NULL;
|
|
ulProblemCode = (ULONG) -1;
|
|
ulStatus = 0;
|
|
pszClass = NULL;
|
|
bDNHasMark = (BOOL)-1;
|
|
bCanDisable = FALSE;
|
|
bCanTest = FALSE;
|
|
bDidPass = FALSE;
|
|
pHardwareID = NULL;
|
|
pCompatID = NULL;
|
|
pszGUID = NULL;
|
|
pszLocation = NULL;
|
|
pszPDO = NULL;
|
|
pszFriendlyName = NULL;
|
|
pszMFG = NULL;
|
|
InterfaceBusType = InterfaceTypeUndefined;
|
|
|
|
}
|
|
|
|
DevnodeClass::~DevnodeClass()
|
|
{
|
|
hDevnode = -1;
|
|
ulProblemCode = (ULONG) -1;
|
|
ulStatus = (ULONG)-1;
|
|
bDNHasMark = (BOOL)-1;
|
|
InterfaceBusType = InterfaceTypeUndefined;
|
|
bCanDisable = FALSE;
|
|
bCanTest = FALSE;
|
|
bDidPass = FALSE;
|
|
|
|
|
|
if ( pDeviceID )
|
|
{
|
|
delete pDeviceID;
|
|
pDeviceID = NULL;
|
|
}
|
|
if ( pszClass )
|
|
{
|
|
delete pszClass;
|
|
pszClass = NULL;
|
|
}
|
|
if ( pszDescription )
|
|
{
|
|
delete pszDescription;
|
|
pszDescription = NULL;
|
|
}
|
|
if ( pszFriendlyName )
|
|
{
|
|
delete pszFriendlyName;
|
|
pszFriendlyName = NULL;
|
|
}
|
|
if ( pszGUID )
|
|
{
|
|
delete pszGUID;
|
|
pszGUID = NULL;
|
|
}
|
|
if ( pszLocation )
|
|
{
|
|
delete pszLocation;
|
|
pszLocation = NULL;
|
|
}
|
|
if ( pszPDO )
|
|
{
|
|
delete pszPDO;
|
|
pszPDO = NULL;
|
|
}
|
|
if ( pszMFG )
|
|
{
|
|
delete pszMFG;
|
|
pszMFG = NULL;
|
|
}
|
|
if ( pHardwareID )
|
|
{
|
|
delete pHardwareID;
|
|
pHardwareID = NULL;
|
|
}
|
|
|
|
if ( pCompatID )
|
|
{
|
|
delete pCompatID;
|
|
pCompatID = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
/*******************************************************************
|
|
Member Functions
|
|
*******************************************************************/
|
|
|
|
BOOL DevnodeClass::SetHandle(DEVNODE Devnode, DEVNODE Parent)
|
|
{
|
|
hDevnode = -1;
|
|
ulProblemCode = (ULONG) -1;
|
|
ulStatus = (ULONG)-1;
|
|
bDNHasMark = (BOOL)-1;
|
|
InterfaceBusType = InterfaceTypeUndefined;
|
|
bCanDisable = FALSE;
|
|
bCanTest = FALSE;
|
|
bDidPass = FALSE;
|
|
|
|
|
|
if ( pDeviceID )
|
|
{
|
|
delete pDeviceID;
|
|
pDeviceID = NULL;
|
|
}
|
|
if ( pszClass )
|
|
{
|
|
delete pszClass;
|
|
pszClass = NULL;
|
|
}
|
|
if ( pszDescription )
|
|
{
|
|
delete pszDescription;
|
|
pszDescription = NULL;
|
|
}
|
|
if ( pszFriendlyName )
|
|
{
|
|
delete pszFriendlyName;
|
|
pszFriendlyName = NULL;
|
|
}
|
|
if ( pszGUID )
|
|
{
|
|
delete pszGUID;
|
|
pszGUID = NULL;
|
|
}
|
|
if ( pszLocation )
|
|
{
|
|
delete pszLocation;
|
|
pszLocation = NULL;
|
|
}
|
|
if ( pszPDO )
|
|
{
|
|
delete pszPDO;
|
|
pszPDO = NULL;
|
|
}
|
|
if ( pszMFG )
|
|
{
|
|
delete pszMFG;
|
|
pszMFG = NULL;
|
|
}
|
|
if ( pHardwareID )
|
|
{
|
|
delete pHardwareID;
|
|
pHardwareID = NULL;
|
|
}
|
|
|
|
if ( pCompatID )
|
|
{
|
|
delete pCompatID;
|
|
pCompatID = NULL;
|
|
}
|
|
|
|
|
|
hDevnode = Devnode;
|
|
hParent = Parent;
|
|
return (GetDeviceInformation());
|
|
}
|
|
|
|
/****************************************************************************
|
|
GetDeviceInformation
|
|
|
|
find information about devnode
|
|
modifies this, members in DevnodeClass
|
|
*****************************************************************************/
|
|
CONFIGRET DevnodeClass::GetDeviceInformation (void)
|
|
{
|
|
CONFIGRET retval;
|
|
ULONG ulSize;
|
|
|
|
// check to see that we have a devnode handle
|
|
|
|
if ( !hDevnode )
|
|
{
|
|
return (CR_NO_SUCH_DEVNODE);
|
|
}
|
|
if ( !hParent )
|
|
{
|
|
DEVNODE hParentDevnode;
|
|
if ( !GetParent(&hParentDevnode) )
|
|
{
|
|
hParent = hParentDevnode;
|
|
}
|
|
}
|
|
|
|
/**********
|
|
Get Device ID
|
|
***********/
|
|
retval = CM_Get_Device_ID_Size (&ulSize, hDevnode, 0L);
|
|
if ( retval ) return(retval);
|
|
|
|
pDeviceID = new TCHAR [++ulSize]; // add one for terminating NULL
|
|
if ( !pDeviceID ) return(CR_OUT_OF_MEMORY);
|
|
|
|
retval = CM_Get_Device_ID (hDevnode,
|
|
pDeviceID,
|
|
ulSize, //is null terminated?!?
|
|
0L);
|
|
if ( retval ) return(retval);
|
|
|
|
|
|
|
|
|
|
/**********
|
|
Get device description/friendly name
|
|
***********/
|
|
|
|
ulSize = 0;
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_DEVICEDESC,
|
|
NULL,
|
|
NULL,
|
|
&ulSize,
|
|
0);
|
|
|
|
if ( retval )
|
|
if ( (retval == CR_BUFFER_SMALL) )
|
|
{
|
|
//if ( bVerbose )
|
|
// logprintf ("Still Having trouble with CM_Get_DevNode_Registry_Property returning CR_BUFFER_TOO_SMALL\r\n"
|
|
// "When trying to get the size of the Device description\r\n");
|
|
ulSize = 511;
|
|
}
|
|
else
|
|
return(retval);
|
|
|
|
pszDescription = new TCHAR [ulSize+1];
|
|
if ( !pszDescription ) return(CR_OUT_OF_MEMORY);
|
|
|
|
//Now get value
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_DEVICEDESC,
|
|
NULL,
|
|
pszDescription,
|
|
&ulSize,
|
|
0);
|
|
if ( retval )
|
|
return(retval);
|
|
|
|
/**********
|
|
Get device description/friendly name
|
|
***********/
|
|
|
|
ulSize = 0;
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_FRIENDLYNAME,
|
|
NULL,
|
|
NULL,
|
|
&ulSize,
|
|
0);
|
|
|
|
|
|
if ( ulSize )
|
|
{
|
|
pszFriendlyName = new TCHAR [ulSize+1];
|
|
if ( !pszFriendlyName ) return(CR_OUT_OF_MEMORY);
|
|
|
|
//Now get value
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_FRIENDLYNAME,
|
|
NULL,
|
|
pszFriendlyName,
|
|
&ulSize,
|
|
0);
|
|
if ( retval )
|
|
return(retval);
|
|
}
|
|
|
|
/**********
|
|
Get device class
|
|
***********/
|
|
ulSize = 0;
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_CLASS,
|
|
NULL,
|
|
NULL,
|
|
&ulSize,
|
|
0);
|
|
|
|
if ( retval )
|
|
{
|
|
if ( (retval == CR_BUFFER_SMALL) )
|
|
{
|
|
//if ( bVerbose )
|
|
// logprintf ("Still Having trouble with CM_Get_DevNode_Registry_Property returning CR_BUFFER_TOO_SMALL\r\n"
|
|
// "When trying to get the size of the class\r\n");
|
|
ulSize = 511;
|
|
}
|
|
else if ( retval == CR_NO_SUCH_VALUE )
|
|
{
|
|
//if ( bVerbose )
|
|
//{
|
|
// logprintf("This device does not have a class associated with it\r\n");
|
|
//}
|
|
ulSize = 511;
|
|
}
|
|
else
|
|
ulSize = 0;
|
|
}
|
|
|
|
|
|
if (ulSize)
|
|
{
|
|
|
|
pszClass = new TCHAR [ulSize+1];
|
|
if ( !pszClass )
|
|
return(CR_OUT_OF_MEMORY);
|
|
|
|
//Now get value
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_CLASS,
|
|
NULL,
|
|
pszClass,
|
|
&ulSize,
|
|
0);
|
|
if ( retval )
|
|
{
|
|
if (pszClass)
|
|
delete pszClass;
|
|
pszClass = NULL;
|
|
}
|
|
else
|
|
_strupr(pszClass);
|
|
}
|
|
|
|
|
|
/**********
|
|
Get Hardware ID information
|
|
***********/
|
|
|
|
ulSize = 0;
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_HARDWAREID,
|
|
NULL,
|
|
NULL,
|
|
&ulSize,
|
|
0);
|
|
|
|
if ( retval && !ulSize )
|
|
if ( (retval == CR_BUFFER_SMALL) )
|
|
{
|
|
//if ( bVerbose )
|
|
// logprintf ("Still Having trouble with CM_Get_DevNode_Registry_Property returning CR_BUFFER_TOO_SMALL\r\n"
|
|
// "When trying to get the size of the Device description\r\n");
|
|
ulSize = 511;
|
|
}
|
|
else
|
|
return(retval);
|
|
|
|
pHardwareID = new TCHAR [++ulSize+1];
|
|
if ( !pHardwareID ) return(CR_OUT_OF_MEMORY);
|
|
|
|
//Now get value
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_HARDWAREID,
|
|
NULL,
|
|
pHardwareID,
|
|
&ulSize,
|
|
0);
|
|
if ( retval )
|
|
return(retval);
|
|
|
|
/**********
|
|
Get Compat ID information
|
|
***********/
|
|
|
|
ulSize = 0;
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_COMPATIBLEIDS,
|
|
NULL,
|
|
NULL,
|
|
&ulSize,
|
|
0);
|
|
|
|
if ( retval && !ulSize )
|
|
if ( (retval == CR_BUFFER_SMALL) )
|
|
{
|
|
//if ( bVerbose )
|
|
// logprintf ("Still Having trouble with CM_Get_DevNode_Registry_Property returning CR_BUFFER_TOO_SMALL\r\n"
|
|
// "When trying to get the size of the Device description\r\n");
|
|
ulSize = 511;
|
|
}
|
|
else
|
|
ulSize = 0;
|
|
|
|
if (ulSize)
|
|
{
|
|
|
|
pCompatID = new TCHAR [++ulSize+1];
|
|
if ( !pCompatID ) return(CR_OUT_OF_MEMORY);
|
|
|
|
//Now get value
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_COMPATIBLEIDS,
|
|
NULL,
|
|
pCompatID,
|
|
&ulSize,
|
|
0);
|
|
if ( retval )
|
|
return(retval);
|
|
}
|
|
|
|
|
|
/**********
|
|
Get ClassGUID
|
|
***********/
|
|
|
|
ulSize = 0;
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_CLASSGUID,
|
|
NULL,
|
|
NULL,
|
|
&ulSize,
|
|
0);
|
|
|
|
if ( ulSize )
|
|
{
|
|
|
|
pszGUID = new TCHAR [ulSize+1];
|
|
if ( !pszGUID ) return(CR_OUT_OF_MEMORY);
|
|
|
|
//Now get value
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_CLASSGUID,
|
|
NULL,
|
|
pszGUID,
|
|
&ulSize,
|
|
0);
|
|
}
|
|
|
|
/**********
|
|
Get PDO Name
|
|
***********/
|
|
|
|
ulSize = 0;
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME,
|
|
NULL,
|
|
NULL,
|
|
&ulSize,
|
|
0);
|
|
|
|
if ( ulSize )
|
|
{
|
|
|
|
pszPDO = new TCHAR [ulSize+1];
|
|
if ( !pszPDO ) return(CR_OUT_OF_MEMORY);
|
|
|
|
//Now get value
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_PHYSICAL_DEVICE_OBJECT_NAME,
|
|
NULL,
|
|
pszPDO,
|
|
&ulSize,
|
|
0);
|
|
}
|
|
|
|
/**********
|
|
Get MFG Name
|
|
***********/
|
|
|
|
ulSize = 0;
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_MFG,
|
|
NULL,
|
|
NULL,
|
|
&ulSize,
|
|
0);
|
|
|
|
if ( ulSize )
|
|
{
|
|
|
|
pszMFG = new TCHAR [ulSize+1];
|
|
if ( !pszMFG ) return(CR_OUT_OF_MEMORY);
|
|
|
|
//Now get value
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_MFG,
|
|
NULL,
|
|
pszMFG,
|
|
&ulSize,
|
|
0);
|
|
}
|
|
|
|
|
|
|
|
/**********
|
|
Get LocationInformation
|
|
***********/
|
|
|
|
ulSize = 0;
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_LOCATION_INFORMATION,
|
|
NULL,
|
|
NULL,
|
|
&ulSize,
|
|
0);
|
|
|
|
if ( ulSize )
|
|
{
|
|
pszLocation = new TCHAR [ulSize+1];
|
|
if ( !pszLocation ) return(CR_OUT_OF_MEMORY);
|
|
|
|
//Now get value
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_LOCATION_INFORMATION,
|
|
NULL,
|
|
pszLocation,
|
|
&ulSize,
|
|
0);
|
|
}
|
|
|
|
|
|
/**********
|
|
Get interface/bus type
|
|
***********/
|
|
|
|
//Now get value
|
|
ulSize = sizeof(INTERFACE_TYPE);
|
|
retval = CM_Get_DevNode_Registry_Property (hDevnode,
|
|
CM_DRP_LEGACYBUSTYPE,
|
|
NULL,
|
|
&InterfaceBusType,
|
|
&ulSize,
|
|
0);
|
|
// if (!retval)
|
|
// {
|
|
// InterfaceBusType= InterfaceTypeUndefined;
|
|
// }
|
|
|
|
/**********
|
|
Get Problem and status code
|
|
***********/
|
|
retval = CM_Get_DevNode_Status (&ulStatus,
|
|
&ulProblemCode,
|
|
hDevnode,
|
|
0L);
|
|
if ( retval ) return(retval);
|
|
|
|
/**********
|
|
set bCanDisable
|
|
***********/
|
|
// If we get here, let's assume that the device is testable, and filter from there
|
|
bCanDisable = TRUE;
|
|
bCanTest = TRUE;
|
|
|
|
|
|
return(CR_SUCCESS);
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
GetXxxx fuctions
|
|
*****************************************************************************/
|
|
|
|
CONFIGRET DevnodeClass::GetChild(DEVNODE *pChildDevnode)
|
|
{
|
|
return (CM_Get_Child(pChildDevnode, hDevnode, 0l));
|
|
}
|
|
|
|
CONFIGRET DevnodeClass::GetParent(DEVNODE *pParentDevnode)
|
|
{
|
|
return (CM_Get_Parent(pParentDevnode, hDevnode, 0l));
|
|
}
|
|
|
|
CONFIGRET DevnodeClass::GetSibling(DEVNODE *pSiblingDevnode)
|
|
{
|
|
return (CM_Get_Sibling(pSiblingDevnode, hDevnode, 0l));
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
Disabler Funcitons
|
|
*****************************************************************************/
|
|
|
|
|
|
/*
|
|
CONFIGRET DevnodeClass::Remove(ULONG uFlags)
|
|
{
|
|
//return (CM_Query_And_Remove_SubTree(hDevnode, NULL, NULL, 0, uFlags));
|
|
return (CM_Remove_SubTree(hDevnode, uFlags));
|
|
} */
|
|
|
|
typedef CONFIGRET (WINAPI *pCM_Query_And_Remove_SubTree)(DEVNODE, PPNP_VETO_TYPE, LPSTR, ULONG, ULONG);
|
|
|
|
CONFIGRET DevnodeClass::Remove(ULONG uFlags)
|
|
{
|
|
static pCM_Query_And_Remove_SubTree fpCM_Query_And_Remove_SubTree = NULL;
|
|
|
|
if (!fpCM_Query_And_Remove_SubTree)
|
|
{
|
|
OSVERSIONINFO ver;
|
|
memset(&ver, 0, sizeof(OSVERSIONINFO));
|
|
ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
|
|
|
GetVersionEx(&ver);
|
|
|
|
if (ver.dwPlatformId == VER_PLATFORM_WIN32_NT)
|
|
{
|
|
// is windows NT
|
|
HINSTANCE hinst;
|
|
hinst = LoadLibrary(_T("cfgmgr32.dll"));
|
|
fpCM_Query_And_Remove_SubTree = (pCM_Query_And_Remove_SubTree)GetProcAddress(hinst, "CM_Query_And_Remove_SubTreeA");
|
|
//a-kjaw to fix prefix bug 259378.
|
|
if(NULL == fpCM_Query_And_Remove_SubTree)
|
|
return CR_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
//else is not winnt
|
|
fpCM_Query_And_Remove_SubTree = (pCM_Query_And_Remove_SubTree)-1;
|
|
}
|
|
}
|
|
|
|
if (fpCM_Query_And_Remove_SubTree == (pCM_Query_And_Remove_SubTree)-1)
|
|
{
|
|
// is win9x
|
|
return (CM_Remove_SubTree(hDevnode, uFlags));
|
|
}
|
|
else
|
|
{
|
|
return (fpCM_Query_And_Remove_SubTree(hDevnode, NULL, NULL, 0, uFlags));
|
|
}
|
|
}
|
|
|
|
CONFIGRET DevnodeClass::Refresh(ULONG uFlags)
|
|
{
|
|
CONFIGRET retval;
|
|
|
|
retval = CM_Reenumerate_DevNode(hParent, uFlags);
|
|
|
|
if ( retval ) return (retval);
|
|
|
|
retval = FindDevnode();
|
|
|
|
GetProblemCode();
|
|
return(retval);
|
|
}
|
|
|
|
|
|
CONFIGRET DevnodeClass::Disable(ULONG uFlags)
|
|
{
|
|
return (CM_Disable_DevNode(hDevnode, uFlags));
|
|
}
|
|
|
|
CONFIGRET DevnodeClass::Enable(ULONG uFlags)
|
|
{
|
|
CONFIGRET retval;
|
|
|
|
retval = CM_Enable_DevNode(hDevnode, uFlags);
|
|
|
|
if ( retval ) return (retval);
|
|
|
|
return (FindDevnode());
|
|
}
|
|
|
|
CONFIGRET DevnodeClass::GetProblemCode(ULONG *Status, ULONG *Problem)
|
|
{
|
|
CONFIGRET retval;
|
|
|
|
retval = CM_Get_DevNode_Status (&ulStatus,
|
|
&ulProblemCode,
|
|
hDevnode,
|
|
0L);
|
|
if ( retval ) return(retval);
|
|
|
|
if (Status) *Status = ulStatus;
|
|
if (Problem) *Problem = ulProblemCode;
|
|
|
|
return (retval);
|
|
}
|
|
|
|
/**************
|
|
FindDevnode
|
|
|
|
This function just updates the hDevnode, refreshed the device,
|
|
and updates the status and problem code
|
|
|
|
**************/
|
|
|
|
CONFIGRET DevnodeClass::FindDevnode(void)
|
|
{
|
|
CONFIGRET retval;
|
|
|
|
retval = CM_Locate_DevNode (&hDevnode, pDeviceID, CM_LOCATE_DEVNODE_NORMAL);
|
|
|
|
if ( retval )
|
|
{
|
|
hDevnode = NULL;
|
|
ulProblemCode = (ULONG)-1;
|
|
ulStatus = (ULONG)-1;
|
|
return (retval);
|
|
}
|
|
|
|
return (CM_Reenumerate_DevNode (hDevnode, CM_REENUMERATE_SYNCHRONOUS));
|
|
}
|
|
|
|
|
|
/***************
|
|
|
|
operator==
|
|
|
|
*************/
|
|
|
|
int DevnodeClass::operator==(const DevnodeClass &OtherDevnode)
|
|
{
|
|
|
|
if ( strcmp(pDeviceID, OtherDevnode.pDeviceID) )
|
|
return (FALSE);
|
|
|
|
if ( ulProblemCode != OtherDevnode.ulProblemCode )
|
|
{
|
|
return (FALSE);
|
|
}
|
|
if ( (ulStatus ^ OtherDevnode.ulStatus) & ~IGNORE_ME_BITS )
|
|
{
|
|
return (FALSE);
|
|
}
|
|
return (TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
ULONG ReadRegKeyInformationSZ (HKEY RootKey, TCHAR *KeyName, TCHAR **Value)
|
|
{
|
|
TCHAR * szBuffer;
|
|
LONG retval;
|
|
DWORD dwSize = 0;
|
|
DWORD dwType = 0;
|
|
|
|
// make sure the buffer is clear
|
|
|
|
//assert (Value); // make sure that we actually got a value
|
|
//assert (!*Value); // and also make sure that the buffer is already empty
|
|
|
|
// for non debug versions
|
|
*Value = NULL;
|
|
|
|
//a-kjaw. Prefix bug no. 259379. if dwSize if not NULL &lpData is Null
|
|
// func returns the size reqd to store the string which helps string allocation.
|
|
retval = RegQueryValueEx(RootKey,
|
|
KeyName,
|
|
0, // reserved
|
|
&dwType,
|
|
NULL,
|
|
&dwSize);
|
|
|
|
if ( retval != ERROR_SUCCESS )
|
|
{
|
|
return (retval); // cant continue
|
|
}
|
|
|
|
if ( (dwType != REG_SZ) || !dwSize )
|
|
{
|
|
return (ERROR_FILE_NOT_FOUND);
|
|
}
|
|
|
|
szBuffer = new TCHAR[++dwSize];
|
|
|
|
if ( !szBuffer )
|
|
{
|
|
return (ERROR_NOT_ENOUGH_MEMORY);
|
|
}
|
|
|
|
retval = RegQueryValueEx(RootKey,
|
|
KeyName,
|
|
0, // reserved
|
|
&dwType,
|
|
(UCHAR *)szBuffer,
|
|
&dwSize);
|
|
|
|
if ( retval )
|
|
{
|
|
delete szBuffer;
|
|
return (retval);
|
|
}
|
|
|
|
*Value = szBuffer;
|
|
return (ERROR_SUCCESS);
|
|
|
|
}
|
|
|
|
BOOL Enumerate_WalkTree_Devnode(DEVNODE hDevnode, DEVNODE hParent)
|
|
{
|
|
CONFIGRET retval;
|
|
DevnodeClass *pNewDevice;
|
|
DEVNODE hSib;
|
|
|
|
pNewDevice = new DevnodeClass(hDevnode, hParent);
|
|
|
|
retval = pNewDevice->GetChild(&hSib);
|
|
if ( !retval )
|
|
{
|
|
Enumerate_WalkTree_Devnode(hSib, hDevnode);
|
|
}
|
|
retval = pNewDevice->GetSibling(&hSib);
|
|
if ( !retval )
|
|
{
|
|
Enumerate_WalkTree_Devnode(hSib, hParent);
|
|
}
|
|
|
|
return (retval);
|
|
|
|
|
|
}
|
|
|
|
|
|
ULONG EnumerateTree_Devnode(void)
|
|
{
|
|
|
|
DEVNODE hDevnode;
|
|
|
|
CM_Locate_DevNode(&hDevnode, NULL, CM_LOCATE_DEVNODE_NORMAL);
|
|
Enumerate_WalkTree_Devnode(hDevnode, NULL);
|
|
|
|
return (DevnodeClass::ALCCount());
|
|
|
|
}
|