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.
 
 
 
 
 
 

644 lines
21 KiB

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
infoset.h
Abstract:
Handles setup API device infosets
Author:
Vlad Sadovsky (vlads) 10-Jan-1999
Environment:
User Mode - Win32
Revision History:
6-Jan-1999 VladS created
--*/
#ifndef _INFOSET_H_
#define _INFOSET_H_
#include <base.h>
#include <buffer.h>
#include <dbt.h>
#include <setupapi.h>
class DEVICE_INFOSET {
public:
DEVICE_INFOSET(IN GUID guidClass)
{
m_DeviceInfoSet = NULL;
m_ClassGuid = guidClass;
Initialize();
m_fValid = TRUE;
}
~DEVICE_INFOSET( VOID )
{
Reset();
}
inline BOOL
IsValid(
VOID
)
{
return(m_fValid);
}
inline void
EnterCrit(VOID)
{
m_dwCritSec.Lock();
}
inline void
LeaveCrit(VOID)
{
m_dwCritSec.Unlock();
}
inline
HDEVINFO
QueryInfoSetHandle(VOID)
{
return(m_DeviceInfoSet);
}
//
// Initialize info set for given class
//
BOOL
Initialize(VOID)
{
HDEVINFO NewDeviceInfoSet;
DWORD dwErr;
m_DeviceInfoSet = SetupDiCreateDeviceInfoList(NULL, NULL);
Refresh();
#ifdef DEBUG
Dump();
#endif
return (TRUE);
}
BOOL
Refresh(VOID)
{
HDEVINFO NewDeviceInfoSet;
DWORD dwErr;
if ( m_DeviceInfoSet && (m_DeviceInfoSet != INVALID_HANDLE_VALUE)) {
#ifdef WINNT
//
// Now we can retrieve the existing list of active device
// interfaces into the device information set we created above.
//
NewDeviceInfoSet = SetupDiGetClassDevsEx(&(m_ClassGuid),
NULL,
NULL,
// DIGCF_PRESENT | DIGCF_DEVICEINTERFACE,
DIGCF_DEVICEINTERFACE,
m_DeviceInfoSet,
NULL,
NULL
);
NewDeviceInfoSet = SetupDiGetClassDevsEx(&(m_ClassGuid),
NULL,
NULL,
// DIGCF_PRESENT | DIGCF_DEVICEINTERFACE,
0,
NewDeviceInfoSet,
NULL,
NULL
);
if (NewDeviceInfoSet == INVALID_HANDLE_VALUE) {
dwErr = ::GetLastError();
DBG_ERR(("SetupDiGetClassDevsEx failed with 0x%lx\n", dwErr));
return (FALSE);
}
#else
//
// BUGBUG
//
#pragma message("Rewrite for Win98")
return (FALSE);
#endif
//
// If SetupDiGetClassDevsEx succeeds and it was passed in an
// existing device information set to be used, then the HDEVINFO
// it returns is the same as the one it was passed in. Thus, we
// can just use the original DeviceInfoSet handle from here on.
//
}
return (TRUE);
}
//
//
//
BOOL
Reset(VOID)
{
SetupDiDestroyDeviceInfoList(m_DeviceInfoSet);
return (TRUE);
}
//
// Look up driver name by interface name
//
BOOL
LookupDriverNameFromInterfaceName(
LPCTSTR pszInterfaceName,
StiCString* pstrDriverName
)
{
BUFFER bufDetailData;
SP_DEVINFO_DATA spDevInfoData;
SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA pspDevInterfaceDetailData;
TCHAR szDevDriver[STI_MAX_INTERNAL_NAME_LENGTH];
DWORD cbData;
DWORD dwErr;
HKEY hkDevice = (HKEY)INVALID_HANDLE_VALUE;
LONG lResult = ERROR_SUCCESS;
DWORD dwType = REG_SZ;
BOOL fRet = FALSE;
BOOL fDataAcquired = FALSE;
bufDetailData.Resize(sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) +
MAX_PATH * sizeof(TCHAR) +
16
);
pspDevInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) bufDetailData.QueryPtr();
if (!pspDevInterfaceDetailData) {
return (CR_OUT_OF_MEMORY);
}
//
// Locate this device interface in our device information set.
//
spDevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if (SetupDiOpenDeviceInterface(m_DeviceInfoSet,
pszInterfaceName,
DIODI_NO_ADD,
&spDevInterfaceData)) {
//
// First try to open interface regkey.
//
hkDevice = SetupDiOpenDeviceInterfaceRegKey(m_DeviceInfoSet,
&spDevInterfaceData,
0,
KEY_READ);
if(INVALID_HANDLE_VALUE != hkDevice){
*szDevDriver = TEXT('\0');
cbData = sizeof(szDevDriver);
lResult = RegQueryValueEx(hkDevice,
REGSTR_VAL_DEVICE_ID,
NULL,
&dwType,
(LPBYTE)szDevDriver,
&cbData);
dwErr = ::GetLastError();
RegCloseKey(hkDevice);
hkDevice = (HKEY)INVALID_HANDLE_VALUE;
if(ERROR_SUCCESS == lResult){
fDataAcquired = TRUE;
} // if(ERROR_SUCCESS == lResult)
} // if(INVALID_HANDLE_VALUE != hkDevice)
if(!fDataAcquired){
//
// Try to open devnode regkey.
//
cbData = 0;
pspDevInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
fRet = SetupDiGetDeviceInterfaceDetail(m_DeviceInfoSet,
&spDevInterfaceData,
pspDevInterfaceDetailData,
bufDetailData.QuerySize(),
&cbData,
&spDevInfoData);
if(fRet){
//
// Get device interface registry key.
//
hkDevice = SetupDiOpenDevRegKey(m_DeviceInfoSet,
&spDevInfoData,
DICS_FLAG_GLOBAL,
0,
DIREG_DRV,
KEY_READ);
dwErr = ::GetLastError();
} else {
DBG_ERR(("SetupDiGetDeviceInterfaceDetail() Failed Err=0x%x",GetLastError()));
}
if (INVALID_HANDLE_VALUE != hkDevice) {
*szDevDriver = TEXT('\0');
cbData = sizeof(szDevDriver);
lResult = RegQueryValueEx(hkDevice,
REGSTR_VAL_DEVICE_ID,
NULL,
&dwType,
(LPBYTE)szDevDriver,
&cbData);
dwErr = ::GetLastError();
RegCloseKey(hkDevice);
hkDevice = (HKEY)INVALID_HANDLE_VALUE;
if(ERROR_SUCCESS == lResult){
fDataAcquired = TRUE;
} // if(ERROR_SUCCESS == lResult)
} else { // if (INVALID_HANDLE_VALUE != hkDevice)
DBG_ERR(("SetupDiOpenDevRegKey() Failed Err=0x%x",GetLastError()));
fRet = FALSE;
} // if (INVALID_HANDLE_VALUE != hkDevice)
} // if(!fDataAcquired)
if (fDataAcquired) {
// Got it
pstrDriverName->CopyString(szDevDriver);
fRet = TRUE;
} // if (fDataAcquired)
} else {
DBG_ERR(("SetupDiOpenDeviceInterface() Failed Err=0x%x",GetLastError()));
fRet = FALSE;
}
return (fRet);
}
//
// Look up device info data by driver name
//
BOOL
LookupDeviceInfoFromDriverName(
LPCTSTR pszDriverName,
StiCString* pstrInterfaceName,
DEVINST*pDeviceInstance = NULL
)
{
SP_DEVINFO_DATA spDevInfoData;
SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA pspDevInterfaceDetailData;
BUFFER bufDetailData;
TCHAR szDevDriver[STI_MAX_INTERNAL_NAME_LENGTH];
ULONG cbData;
CONFIGRET cmRet = CR_NO_SUCH_DEVINST;
DWORD dwRequired;
DWORD Idx;
DWORD dwError;
DWORD dwType;
BOOL fRet = FALSE;
BOOL fFoundMatch = FALSE;
LONG lResult = ERROR_SUCCESS;
HKEY hkDevice = (HKEY)INVALID_HANDLE_VALUE;
Refresh();
dwRequired = 0;
ZeroMemory(&spDevInterfaceData,sizeof(spDevInterfaceData));
bufDetailData.Resize(sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) +
MAX_PATH * sizeof(TCHAR) +
16
);
pspDevInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) bufDetailData.QueryPtr();
if (!pspDevInterfaceDetailData) {
::SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return (FALSE);
}
if (m_DeviceInfoSet != INVALID_HANDLE_VALUE) {
ZeroMemory(&spDevInfoData,sizeof(spDevInfoData));
spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
spDevInfoData.ClassGuid = m_ClassGuid;
pspDevInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) bufDetailData.QueryPtr();
for (Idx = 0; SetupDiEnumDeviceInfo (m_DeviceInfoSet, Idx, &spDevInfoData); Idx++) {
//
// Get driver name property
//
hkDevice = SetupDiOpenDevRegKey(m_DeviceInfoSet,
&spDevInfoData,
DICS_FLAG_GLOBAL,
0,
DIREG_DRV,
KEY_READ);
if(INVALID_HANDLE_VALUE != hkDevice){
*szDevDriver = TEXT('\0');
cbData = sizeof(szDevDriver);
lResult = RegQueryValueEx(hkDevice,
REGSTR_VAL_DEVICE_ID,
NULL,
&dwType,
(LPBYTE)szDevDriver,
&cbData);
RegCloseKey(hkDevice);
hkDevice = (HKEY)INVALID_HANDLE_VALUE;
if(ERROR_SUCCESS == lResult){
if (lstrcmpi(pszDriverName,szDevDriver) == 0 ) {
//
// Get interface.
//
spDevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
spDevInterfaceData.InterfaceClassGuid = m_ClassGuid;
fRet = SetupDiEnumDeviceInterfaces (m_DeviceInfoSet,
&spDevInfoData,
&(m_ClassGuid),
0,
&spDevInterfaceData);
if(!fRet){
DBG_ERR(("SetupDiEnumDeviceInterfaces() Failed Err=0x%x",GetLastError()));
fFoundMatch = FALSE;
continue;
}
//
// Found match ..
//
fFoundMatch = TRUE;
break;
} // if (lstrcmpi(pszDriverName,szDevDriver) == 0 )
} //if(ERROR_SUCCESS == lResult)
} // if(INVALID_HANDLE_VALUE != hkDevice)
} // for (Idx = 0; SetupDiEnumDeviceInfo (m_DeviceInfoSet, Idx, &spDevInfoData); Idx++)
if(!fFoundMatch){
//
// Try to get interface regkey.
//
spDevInterfaceData.InterfaceClassGuid = m_ClassGuid;
spDevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
for(Idx = 0; SetupDiEnumDeviceInterfaces (m_DeviceInfoSet, NULL, &m_ClassGuid, Idx, &spDevInterfaceData); Idx++) {
hkDevice = SetupDiOpenDeviceInterfaceRegKey(m_DeviceInfoSet,
&spDevInterfaceData,
0,
KEY_READ);
if(INVALID_HANDLE_VALUE != hkDevice){
*szDevDriver = TEXT('\0');
cbData = sizeof(szDevDriver);
lResult = RegQueryValueEx(hkDevice,
REGSTR_VAL_DEVICE_ID,
NULL,
&dwType,
(LPBYTE)szDevDriver,
&cbData);
RegCloseKey(hkDevice);
hkDevice = (HKEY)INVALID_HANDLE_VALUE;
if(ERROR_SUCCESS == lResult){
if (lstrcmpi(pszDriverName,szDevDriver) == 0 ) {
//
// Found match ..
//
fFoundMatch = TRUE;
break;
} // if (lstrcmpi(pszDriverName,szDevDriver) == 0 )
} //if(ERROR_SUCCESS == lResult)
} // if(INVALID_HANDLE_VALUE != hkDevice)
} // for(Idx = 0; SetupDiEnumDeviceInterfaces (m_DeviceInfoSet, NULL, &m_ClassGuid, Idx, &spDevInterfaceData); Idx++)
} // if(!fFoundMatch)
if (fFoundMatch) {
dwRequired = 0;
pspDevInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
fRet = SetupDiGetDeviceInterfaceDetail(m_DeviceInfoSet,
&spDevInterfaceData,
pspDevInterfaceDetailData,
bufDetailData.QuerySize(),
&dwRequired,
&spDevInfoData);
dwError = ::GetLastError();
if (fRet) {
pstrInterfaceName -> CopyString(pspDevInterfaceDetailData->DevicePath);
fRet = TRUE;
} else {
// DPRINTF failed to get interface detail
}
} // if (fFoundMatch)
} else {
// DPRINTF - invalid dev info set handle
}
return (fRet);
}
//
// Process refresh message
//
BOOL
ProcessNewDeviceChangeMessage(
IN LPARAM lParam
)
{
DWORD dwErr;
PDEV_BROADCAST_DEVICEINTERFACE pDevBroadcastDeviceInterface;
SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
pDevBroadcastDeviceInterface = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
//
// Open this new device interface into our device information
// set.
//
if (!SetupDiOpenDeviceInterface(m_DeviceInfoSet,
pDevBroadcastDeviceInterface->dbcc_name,
0,
NULL)) {
dwErr = GetLastError();
}
#ifdef DEBUG
Dump();
#endif
return (TRUE);
}
BOOL
ProcessDeleteDeviceChangeMessage(
IN LPARAM lParam
)
{
DBG_FN(ProcessDeleteDeviceChangeMessage);
DWORD dwErr;
PDEV_BROADCAST_DEVICEINTERFACE pDevBroadcastDeviceInterface;
SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
pDevBroadcastDeviceInterface = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
//
// First, locate this device interface in our device information
// set.
//
spDevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if (SetupDiOpenDeviceInterface(m_DeviceInfoSet,
pDevBroadcastDeviceInterface->dbcc_name,
DIODI_NO_ADD,
&spDevInterfaceData)) {
if (!SetupDiDeleteDeviceInterfaceData(m_DeviceInfoSet,
&spDevInterfaceData)) {
dwErr = GetLastError();
}
}
// Do we need to do refresh now ? BUGBUG
Refresh();
#ifdef DEBUG
Dump();
#endif
return (TRUE);
}
VOID
Dump(VOID)
{
SP_DEVINFO_DATA spDevInfoData;
UINT Idx;
ZeroMemory(&spDevInfoData,sizeof(spDevInfoData));
spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
spDevInfoData.ClassGuid = m_ClassGuid;
for (Idx = 0; SetupDiEnumDeviceInfo (m_DeviceInfoSet, Idx, &spDevInfoData); Idx++) {
Idx = Idx;
}
}
//
DWORD m_dwSignature;
private:
BOOL m_fValid;
CRIT_SECT m_dwCritSec;
DWORD m_dwFlags;
GUID m_ClassGuid;
HDEVINFO m_DeviceInfoSet;
};
//
// Take device class
//
class TAKE_DEVICE_INFOSET {
private:
DEVICE_INFOSET* m_pInfoSet;
public:
inline TAKE_DEVICE_INFOSET(DEVICE_INFOSET* pInfoSet) : m_pInfoSet(pInfoSet)
{
m_pInfoSet->EnterCrit();
}
inline ~TAKE_DEVICE_INFOSET()
{
m_pInfoSet->LeaveCrit();
}
};
#endif // _INFOSET_H_