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.
873 lines
27 KiB
873 lines
27 KiB
|
|
/*++
|
|
Copyright (c) 1997 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
enum.cpp
|
|
|
|
Abstract:
|
|
|
|
Enumerates WIA device registry.
|
|
|
|
Author:
|
|
|
|
Keisuke Tsuchida (KeisukeT) 01-Jun-2000
|
|
|
|
History:
|
|
|
|
|
|
--*/
|
|
|
|
|
|
//
|
|
// Include Headers
|
|
//
|
|
|
|
#define INIT_GUID
|
|
|
|
#include "cplusinc.h"
|
|
#include "sticomm.h"
|
|
#include <setupapi.h>
|
|
#include <cfg.h>
|
|
#include <cfgmgr32.h>
|
|
#include <devguid.h>
|
|
#include <initguid.h>
|
|
#include <ntddpar.h>
|
|
#include "enum.h"
|
|
|
|
VOID
|
|
DebugOutputDeviceName(
|
|
HDEVINFO hDevInfo,
|
|
PSP_DEVINFO_DATA pspDevInfoData,
|
|
LPCTSTR szKeyName
|
|
);
|
|
|
|
VOID
|
|
DebugOutputInterfaceName(
|
|
HDEVINFO hDevInfo,
|
|
PSP_DEVICE_INTERFACE_DATA pspDevInterfaceData,
|
|
LPCTSTR szKeyName
|
|
);
|
|
|
|
BOOL
|
|
IsStiRegKey(
|
|
HKEY hkDevRegKey
|
|
);
|
|
|
|
//
|
|
// Define
|
|
//
|
|
|
|
// from sti_ci.h
|
|
#define WIA_DEVKEYLIST_INITIAL_SIZE 1024
|
|
#define STILL_IMAGE TEXT("StillImage")
|
|
#define SUBCLASS TEXT("SubClass")
|
|
|
|
|
|
//
|
|
// Functions
|
|
//
|
|
|
|
extern "C"{
|
|
|
|
PWIA_DEVKEYLIST
|
|
WiaCreateDeviceRegistryList(
|
|
BOOL bEnumActiveOnly
|
|
)
|
|
{
|
|
PWIA_DEVKEYLIST pReturn;
|
|
PWIA_DEVKEYLIST pTempBuffer;
|
|
HKEY hkDevRegKey;
|
|
DWORD dwError;
|
|
DWORD dwCurrentSize;
|
|
DWORD dwRequiredSize;
|
|
DWORD dwNumberOfDevices;
|
|
DWORD dwFlags;
|
|
DWORD dwValueSize;
|
|
DWORD dwDetailDataSize;
|
|
BOOL bIsPlugged;
|
|
HANDLE hDevInfo;
|
|
CONFIGRET ConfigRet;
|
|
ULONG ulStatus;
|
|
ULONG ulProblemNumber;
|
|
DWORD Idx;
|
|
GUID Guid;
|
|
SP_DEVINFO_DATA spDevInfoData;
|
|
SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
|
|
|
|
PSP_DEVICE_INTERFACE_DETAIL_DATA pspDevInterfaceDetailData;
|
|
|
|
// DPRINTF(DM_ERROR,TEXT("WiaCreateDeviceRegistryList: Enter... bEnumActiveOnly=%d"), bEnumActiveOnly);
|
|
|
|
//
|
|
// Initialize local.
|
|
//
|
|
|
|
pReturn = NULL;
|
|
pTempBuffer = NULL;
|
|
hkDevRegKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
dwError = ERROR_SUCCESS;
|
|
dwCurrentSize = WIA_DEVKEYLIST_INITIAL_SIZE;
|
|
dwRequiredSize = sizeof(DWORD);
|
|
dwNumberOfDevices = 0;
|
|
dwFlags = (bEnumActiveOnly ? DIGCF_PRESENT : 0) | DIGCF_PROFILE;
|
|
hDevInfo = INVALID_HANDLE_VALUE;
|
|
Idx = 0;
|
|
Guid = GUID_DEVCLASS_IMAGE;
|
|
ConfigRet = CR_SUCCESS;
|
|
ulStatus = 0;
|
|
ulProblemNumber = 0;
|
|
bIsPlugged = FALSE;
|
|
|
|
pspDevInterfaceDetailData = NULL;
|
|
|
|
memset(&spDevInfoData, 0, sizeof(spDevInfoData));
|
|
memset(&spDevInterfaceData, 0, sizeof(spDevInterfaceData));
|
|
|
|
//
|
|
// Allocate buffer.
|
|
//
|
|
|
|
pTempBuffer = (PWIA_DEVKEYLIST)new BYTE[dwCurrentSize];
|
|
if(NULL == pTempBuffer){
|
|
DPRINTF(DM_ERROR,TEXT("WiaCreateDeviceRegistryList: ERROR!! Insufficient system resources. Err=0x%x\n"), GetLastError());
|
|
|
|
pReturn = NULL;
|
|
goto WiaCreateDeviceRegistryList_return;
|
|
} // if(NULL == pTempBuffer)
|
|
|
|
memset(pTempBuffer, 0, dwCurrentSize);
|
|
|
|
//
|
|
// Enumerate "devnode" devices.
|
|
//
|
|
|
|
hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, dwFlags);
|
|
if (hDevInfo == INVALID_HANDLE_VALUE) {
|
|
DPRINTF(DM_ERROR,TEXT("WiaCreateDeviceRegistryList: ERROR!! SetupDiGetClassDevs (devnodes) fails. Err=0x%x\n"), GetLastError());
|
|
|
|
pReturn = NULL;
|
|
goto WiaCreateDeviceRegistryList_return;
|
|
}
|
|
|
|
spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
|
|
for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++) {
|
|
|
|
// DebugOutputDeviceName(hDevInfo, &spDevInfoData, TEXT("DriverDesc"));
|
|
|
|
//
|
|
// Get device regkey.
|
|
//
|
|
|
|
hkDevRegKey = SetupDiOpenDevRegKey(hDevInfo,
|
|
&spDevInfoData,
|
|
DICS_FLAG_GLOBAL,
|
|
0,
|
|
DIREG_DRV,
|
|
KEY_READ | KEY_WRITE);
|
|
|
|
if(INVALID_HANDLE_VALUE == hkDevRegKey){
|
|
|
|
//
|
|
// Attempt to open the key as READ ONLY instead...
|
|
//
|
|
|
|
hkDevRegKey = SetupDiOpenDevRegKey(hDevInfo,
|
|
&spDevInfoData,
|
|
DICS_FLAG_GLOBAL,
|
|
0,
|
|
DIREG_DRV,
|
|
KEY_READ);
|
|
if(INVALID_HANDLE_VALUE == hkDevRegKey){
|
|
DPRINTF(DM_ERROR,TEXT("WiaCreateDeviceRegistryList: ERROR!! SetupDiOpenDevRegKey (devnodes) fails. Err=0x%x\n"), GetLastError());
|
|
continue;
|
|
} // if(INVALID_HANDLE_VALUE == hkDevRegKey)
|
|
} // if(INVALID_HANDLE_VALUE == hkDevRegKey)
|
|
|
|
//
|
|
// See if it has "StillImage" in SubClass key.
|
|
//
|
|
|
|
if(!IsStiRegKey(hkDevRegKey)){
|
|
RegCloseKey(hkDevRegKey);
|
|
hkDevRegKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
continue;
|
|
} // if(!IsStiRegKey(hkDevRegKey))
|
|
|
|
//
|
|
// See if this node is active.
|
|
//
|
|
|
|
bIsPlugged = TRUE;
|
|
ulStatus = 0;
|
|
ulProblemNumber = 0;
|
|
ConfigRet = CM_Get_DevNode_Status(&ulStatus,
|
|
&ulProblemNumber,
|
|
spDevInfoData.DevInst,
|
|
0);
|
|
if(CR_SUCCESS != ConfigRet){
|
|
// DPRINTF(DM_ERROR,TEXT("WiaCreateDeviceRegistryList: Unable to get devnode status. CR=0x%x.\n"), ConfigRet);
|
|
if(bEnumActiveOnly){
|
|
RegCloseKey(hkDevRegKey);
|
|
hkDevRegKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
continue;
|
|
} else {
|
|
bIsPlugged = FALSE;
|
|
}
|
|
} // if(CR_SUCCESS != ConfigRet)
|
|
|
|
// DPRINTF(DM_ERROR,TEXT("WiaCreateDeviceRegistryList: Devnode status=0x%x, Problem=0x%x.\n"), ulStatus, ulProblemNumber);
|
|
|
|
//
|
|
// Skip a node with problem if enumerating only active devices.
|
|
//
|
|
|
|
if(bEnumActiveOnly){
|
|
if(!(ulStatus & DN_STARTED)){
|
|
RegCloseKey(hkDevRegKey);
|
|
hkDevRegKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
continue;
|
|
} // if(!(ulStatus & DN_STARTED))
|
|
} // if(bEnumActiveOnly)
|
|
|
|
//
|
|
// Add acquired regkey handle. If running out of buffer, enlarge.
|
|
//
|
|
|
|
dwRequiredSize += sizeof(WIA_DEVPROP);
|
|
|
|
if(dwCurrentSize < dwRequiredSize){
|
|
PWIA_DEVKEYLIST pTempNew;
|
|
DWORD dwNewSize;
|
|
|
|
dwNewSize = dwCurrentSize + WIA_DEVKEYLIST_INITIAL_SIZE;
|
|
|
|
pTempNew = (PWIA_DEVKEYLIST)new BYTE[dwNewSize];
|
|
|
|
if(NULL == pTempNew){
|
|
pReturn = NULL;
|
|
goto WiaCreateDeviceRegistryList_return;
|
|
} // if(NULL == pTempNew)
|
|
|
|
memset(pTempNew, 0, dwNewSize);
|
|
memcpy(pTempNew, pTempBuffer, dwCurrentSize);
|
|
delete [] pTempBuffer;
|
|
pTempBuffer = pTempNew;
|
|
dwCurrentSize = dwNewSize;
|
|
} // if(dwCurrentSize < dwRequiredSize)
|
|
|
|
//
|
|
// Fill in the structure.
|
|
//
|
|
|
|
pTempBuffer->Dev[dwNumberOfDevices].bIsPlugged = bIsPlugged;
|
|
pTempBuffer->Dev[dwNumberOfDevices].ulProblem = ulProblemNumber;
|
|
pTempBuffer->Dev[dwNumberOfDevices].ulStatus = ulStatus;
|
|
pTempBuffer->Dev[dwNumberOfDevices].hkDeviceRegistry = hkDevRegKey;
|
|
dwNumberOfDevices++;
|
|
|
|
} // for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++)
|
|
|
|
//
|
|
// Free device info set.
|
|
//
|
|
|
|
SetupDiDestroyDeviceInfoList(hDevInfo);
|
|
hDevInfo = INVALID_HANDLE_VALUE;
|
|
|
|
//
|
|
// Enumerate "interface" devices.
|
|
//
|
|
|
|
hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, DIGCF_PROFILE | DIGCF_DEVICEINTERFACE);
|
|
if (hDevInfo == INVALID_HANDLE_VALUE) {
|
|
|
|
pReturn = NULL;
|
|
goto WiaCreateDeviceRegistryList_return;
|
|
}
|
|
|
|
spDevInterfaceData.cbSize = sizeof (spDevInterfaceData);
|
|
for (Idx = 0; SetupDiEnumDeviceInterfaces (hDevInfo, NULL, &Guid, Idx, &spDevInterfaceData); Idx++) {
|
|
|
|
// DebugOutputInterfaceName(hDevInfo, &spDevInterfaceData, TEXT("FriendlyName"));
|
|
|
|
hkDevRegKey = SetupDiOpenDeviceInterfaceRegKey(hDevInfo,
|
|
&spDevInterfaceData,
|
|
0,
|
|
KEY_READ | KEY_WRITE);
|
|
if(INVALID_HANDLE_VALUE == hkDevRegKey){
|
|
|
|
//
|
|
// Attempt to open the key as READ ONLY instead...
|
|
//
|
|
|
|
hkDevRegKey = SetupDiOpenDeviceInterfaceRegKey(hDevInfo,
|
|
&spDevInterfaceData,
|
|
0,
|
|
KEY_READ);
|
|
if(INVALID_HANDLE_VALUE == hkDevRegKey){
|
|
continue;
|
|
} // if(INVALID_HANDLE_VALUE == hkDevRegKey)
|
|
} // if(INVALID_HANDLE_VALUE == hkDevRegKey)
|
|
|
|
//
|
|
// See if it has "StillImage" in SubClass key.
|
|
//
|
|
|
|
if(!IsStiRegKey(hkDevRegKey)){
|
|
RegCloseKey(hkDevRegKey);
|
|
hkDevRegKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
continue;
|
|
} // if(!IsStiRegKey(hkDevRegKey))
|
|
|
|
|
|
bIsPlugged = TRUE;
|
|
ulStatus = 0;
|
|
ulProblemNumber = 0;
|
|
|
|
//
|
|
// Get devnode which this interface is created on.
|
|
//
|
|
|
|
SetupDiGetDeviceInterfaceDetail(hDevInfo,
|
|
&spDevInterfaceData,
|
|
NULL,
|
|
0,
|
|
&dwDetailDataSize,
|
|
NULL);
|
|
if(0 == dwDetailDataSize){
|
|
DPRINTF(DM_ERROR, TEXT("IsInterfaceActive: SetupDiGetDeviceInterfaceDetail() failed. Err=0x%x. ReqSize=0x%x"), GetLastError(), dwDetailDataSize);
|
|
if(bEnumActiveOnly){
|
|
RegCloseKey(hkDevRegKey);
|
|
hkDevRegKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
continue;
|
|
} else {
|
|
bIsPlugged = FALSE;
|
|
}
|
|
} // if(0 == dwDetailDataSize)
|
|
|
|
//
|
|
// Allocate memory for data.
|
|
//
|
|
|
|
pspDevInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)new char[dwDetailDataSize];
|
|
if(NULL == pspDevInterfaceDetailData){
|
|
DPRINTF(DM_ERROR, TEXT("IsInterfaceActive: Insufficient buffer."));
|
|
RegCloseKey(hkDevRegKey);
|
|
hkDevRegKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
continue;
|
|
} // if(NULL == pspDevInterfaceDetailData)
|
|
|
|
//
|
|
// Get the actual data.
|
|
//
|
|
|
|
spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
|
pspDevInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
|
if(!SetupDiGetDeviceInterfaceDetail(hDevInfo,
|
|
&spDevInterfaceData,
|
|
pspDevInterfaceDetailData,
|
|
dwDetailDataSize,
|
|
&dwDetailDataSize,
|
|
&spDevInfoData)){
|
|
DPRINTF(DM_ERROR, TEXT("IsInterfaceActive: SetupDiGetDeviceInterfaceDetail() failed. Err=0x%x. ReqSize=0x%x"), GetLastError(), dwRequiredSize);
|
|
|
|
delete [] pspDevInterfaceDetailData;
|
|
pspDevInterfaceDetailData = NULL;
|
|
|
|
if(bEnumActiveOnly){
|
|
RegCloseKey(hkDevRegKey);
|
|
hkDevRegKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
continue;
|
|
} else {
|
|
bIsPlugged = FALSE;
|
|
}
|
|
}// if(!SetupDiGetDeviceInterfaceDetail()
|
|
|
|
if(NULL != pspDevInterfaceDetailData){
|
|
delete [] pspDevInterfaceDetailData;
|
|
pspDevInterfaceDetailData = NULL;
|
|
} // if(NULL != pspDevInterfaceDetailData)
|
|
|
|
//
|
|
// See its devnode is active.
|
|
//
|
|
|
|
ConfigRet = CM_Get_DevNode_Status(&ulStatus,
|
|
&ulProblemNumber,
|
|
spDevInfoData.DevInst,
|
|
0);
|
|
if(CR_SUCCESS != ConfigRet){
|
|
DPRINTF(DM_ERROR,TEXT("WiaCreateDeviceRegistryList: Unable to get devnode status. CR=0x%x.\n"), ConfigRet);
|
|
if(bEnumActiveOnly){
|
|
RegCloseKey(hkDevRegKey);
|
|
hkDevRegKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
continue;
|
|
} else {
|
|
bIsPlugged = FALSE;
|
|
}
|
|
} // if(CR_SUCCESS != ConfigRet)
|
|
|
|
if(bEnumActiveOnly){
|
|
if(!(ulStatus & DN_STARTED)){
|
|
RegCloseKey(hkDevRegKey);
|
|
hkDevRegKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
continue;
|
|
} // if(!(ulStatus & DN_STARTED))
|
|
} // if(bEnumActiveOnly)
|
|
|
|
//
|
|
// Add acquired regkey handle. If running out of buffer, enlarge.
|
|
//
|
|
|
|
dwRequiredSize += sizeof(WIA_DEVPROP);
|
|
|
|
if(dwCurrentSize < dwRequiredSize){
|
|
PWIA_DEVKEYLIST pTempNew;
|
|
DWORD dwNewSize;
|
|
|
|
dwNewSize = dwCurrentSize + WIA_DEVKEYLIST_INITIAL_SIZE;
|
|
|
|
pTempNew = (PWIA_DEVKEYLIST)new BYTE[dwNewSize];
|
|
if(NULL == pTempNew){
|
|
pReturn = NULL;
|
|
goto WiaCreateDeviceRegistryList_return;
|
|
} // if(NULL == pTempNew)
|
|
|
|
memset(pTempNew, 0, dwNewSize);
|
|
memcpy(pTempNew, pTempBuffer, dwCurrentSize);
|
|
delete [] pTempBuffer;
|
|
pTempBuffer = pTempNew;
|
|
dwCurrentSize = dwNewSize;
|
|
} // if(dwCurrentSize < dwRequiredSize)
|
|
|
|
//
|
|
// Fill in the structure.
|
|
//
|
|
|
|
pTempBuffer->Dev[dwNumberOfDevices].bIsPlugged = bIsPlugged;
|
|
pTempBuffer->Dev[dwNumberOfDevices].ulProblem = ulProblemNumber;
|
|
pTempBuffer->Dev[dwNumberOfDevices].ulStatus = ulStatus;
|
|
pTempBuffer->Dev[dwNumberOfDevices].hkDeviceRegistry = hkDevRegKey;
|
|
dwNumberOfDevices++;
|
|
|
|
} // for (Idx = 0; SetupDiEnumDeviceInterfaces (hDevInfo, NULL, &Guid, Idx, &spDevInterfaceData); Idx++)
|
|
|
|
//
|
|
// Operation succeeded.
|
|
//
|
|
|
|
if(0 != dwNumberOfDevices){
|
|
pTempBuffer->dwNumberOfDevices = dwNumberOfDevices;
|
|
pReturn = pTempBuffer;
|
|
pTempBuffer = NULL;
|
|
} // if(0 != dwNumberOfDevices)
|
|
|
|
WiaCreateDeviceRegistryList_return:
|
|
|
|
//
|
|
// Clean up.
|
|
//
|
|
|
|
if(INVALID_HANDLE_VALUE != hDevInfo){
|
|
SetupDiDestroyDeviceInfoList(hDevInfo);
|
|
} // if(INVALID_HANDLE_VALUE != hDevInfo)
|
|
|
|
if(NULL != pTempBuffer){
|
|
pTempBuffer->dwNumberOfDevices = dwNumberOfDevices;
|
|
WiaDestroyDeviceRegistryList(pTempBuffer);
|
|
} // if(NULL != pTempBuffer)
|
|
|
|
// DPRINTF(DM_ERROR, TEXT("WiaCreateDeviceRegistryList: Leave... %d devices. Ret=0x%p."), dwNumberOfDevices, pReturn);
|
|
|
|
return pReturn;
|
|
} // WiaCreateDeviceRegistryList()
|
|
|
|
|
|
VOID
|
|
WiaDestroyDeviceRegistryList(
|
|
PWIA_DEVKEYLIST pWiaDevKeyList
|
|
)
|
|
{
|
|
DWORD Idx;
|
|
|
|
//
|
|
// Check argument.
|
|
//
|
|
|
|
if(NULL == pWiaDevKeyList){
|
|
goto WiaFreeDeviceRegistryList_return;
|
|
}
|
|
|
|
for(Idx = 0; Idx < pWiaDevKeyList->dwNumberOfDevices; Idx++){
|
|
if(INVALID_HANDLE_VALUE != pWiaDevKeyList->Dev[Idx].hkDeviceRegistry){
|
|
RegCloseKey(pWiaDevKeyList->Dev[Idx].hkDeviceRegistry);
|
|
} // if(INVALID_HANDLE_VALUE != pWiaDevKeyList->Dev[Idx].hkDeviceRegistry)
|
|
} // for(Idx = 0; Idx < pWiaDevKeyList->dwNumberOfDevices; Idx++)
|
|
|
|
delete pWiaDevKeyList;
|
|
|
|
WiaFreeDeviceRegistryList_return:
|
|
return;
|
|
}
|
|
|
|
VOID
|
|
EnumLpt(
|
|
VOID
|
|
)
|
|
{
|
|
|
|
CONFIGRET ConfigRet;
|
|
HDEVINFO hLptDevInfo;
|
|
SP_DEVINFO_DATA spDevInfoData;
|
|
DWORD Idx;
|
|
GUID Guid;
|
|
DWORD dwCurrentTickCount;
|
|
static DWORD s_dwLastTickCount = 0;
|
|
|
|
//
|
|
// Initialize local.
|
|
//
|
|
|
|
ConfigRet = CR_SUCCESS;
|
|
hLptDevInfo = (HDEVINFO) INVALID_HANDLE_VALUE;
|
|
Idx = 0;
|
|
Guid = GUID_PARALLEL_DEVICE;
|
|
dwCurrentTickCount = 0;
|
|
|
|
memset(&spDevInfoData, 0, sizeof(spDevInfoData));
|
|
|
|
//
|
|
// Get current system tick.
|
|
//
|
|
|
|
dwCurrentTickCount = GetTickCount();
|
|
|
|
//
|
|
// Bail out if the function is called within ENUMLPT_HOLDTIME millisec.
|
|
//
|
|
|
|
if( (dwCurrentTickCount - s_dwLastTickCount) < ENUMLPT_HOLDTIME){
|
|
goto EnumLpt_return;
|
|
}
|
|
|
|
//
|
|
// Save current tick
|
|
//
|
|
|
|
s_dwLastTickCount = dwCurrentTickCount;
|
|
|
|
//
|
|
// Enum LPT port as needed.
|
|
//
|
|
|
|
if(IsPnpLptExisting()){
|
|
|
|
//
|
|
// Get LPT devnodes.
|
|
//
|
|
|
|
Guid = GUID_PARALLEL_DEVICE;
|
|
hLptDevInfo = SetupDiGetClassDevs(&Guid, NULL, NULL, DIGCF_INTERFACEDEVICE);
|
|
if(INVALID_HANDLE_VALUE == hLptDevInfo){
|
|
|
|
goto EnumLpt_return;
|
|
}
|
|
|
|
//
|
|
// Re-enumerate LPT port.
|
|
//
|
|
|
|
spDevInfoData.cbSize = sizeof(spDevInfoData);
|
|
for(Idx = 0; SetupDiEnumDeviceInfo(hLptDevInfo, Idx, &spDevInfoData); Idx++){
|
|
ConfigRet = CM_Reenumerate_DevNode(spDevInfoData.DevInst, CM_REENUMERATE_NORMAL);
|
|
if(CR_SUCCESS != ConfigRet){
|
|
DPRINTF(DM_ERROR,TEXT("EnumLpt: ERROR!! CM_Reenumerate_DevNode() fails. Idx=0x%x, ConfigRet=0x%x\n"), Idx, ConfigRet);
|
|
} // if(CR_SUCCESS != ConfigRet)
|
|
} // for(Idx = 0; SetupDiEnumDeviceInfo(hLptDevInfo, Idx, &spDevInfoData); Idx++)
|
|
} // if(IsPnpLptExisting())
|
|
|
|
EnumLpt_return:
|
|
|
|
//
|
|
// Clean up.
|
|
//
|
|
|
|
if(INVALID_HANDLE_VALUE != hLptDevInfo){
|
|
SetupDiDestroyDeviceInfoList(hLptDevInfo);
|
|
} // if(INVALID_HANDLE_HALUE != hLptDevInfo)
|
|
|
|
return;
|
|
} // EnumLpt()
|
|
|
|
BOOL
|
|
IsPnpLptExisting(
|
|
VOID
|
|
)
|
|
{
|
|
|
|
HDEVINFO hDevInfo;
|
|
CONFIGRET ConfigRet;
|
|
DWORD Idx;
|
|
GUID Guid;
|
|
SP_DEVINFO_DATA spDevInfoData;
|
|
HKEY hkDevRegKey;
|
|
DWORD dwHardwareConfig;
|
|
LONG lResult;
|
|
ULONG ulStatus;
|
|
ULONG ulProblemNumber;
|
|
BOOL bRet;
|
|
|
|
//
|
|
// Initialize local.
|
|
//
|
|
|
|
hDevInfo = INVALID_HANDLE_VALUE;
|
|
ConfigRet = CR_SUCCESS;
|
|
Idx = 0;
|
|
Guid = GUID_DEVCLASS_IMAGE;
|
|
hkDevRegKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
ulStatus = 0;
|
|
ulProblemNumber = 0;
|
|
bRet = FALSE;
|
|
|
|
memset(&spDevInfoData, 0, sizeof(spDevInfoData));
|
|
|
|
//
|
|
// Enum Imaging class devnode.
|
|
//
|
|
|
|
hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, DIGCF_PROFILE);
|
|
if(hDevInfo == INVALID_HANDLE_VALUE){
|
|
|
|
goto IsPnpLptExisting_return;
|
|
} // if(hDevInfo == INVALID_HANDLE_VALUE)}
|
|
|
|
spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
|
|
for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++) {
|
|
|
|
hkDevRegKey = SetupDiOpenDevRegKey(hDevInfo,
|
|
&spDevInfoData,
|
|
DICS_FLAG_GLOBAL,
|
|
0,
|
|
DIREG_DRV,
|
|
KEY_READ);
|
|
|
|
if(INVALID_HANDLE_VALUE == hkDevRegKey){
|
|
DPRINTF(DM_ERROR,TEXT("WiaCreateDeviceRegistryList: ERROR!! SetupDiOpenDevRegKey (devnodes) fails. Err=0x%x\n"), GetLastError());
|
|
continue;
|
|
} // if(INVALID_HANDLE_VALUE == hkDevRegKey)
|
|
|
|
//
|
|
// Make sure it's STI/WIA device.
|
|
//
|
|
|
|
if(!IsStiRegKey(hkDevRegKey)){
|
|
RegCloseKey(hkDevRegKey);
|
|
hkDevRegKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
continue;
|
|
} // if(!IsStiRegKey(hkDevRegKey))
|
|
|
|
//
|
|
// Get "Hardware config" key.
|
|
//
|
|
|
|
dwHardwareConfig = ReadRegistryDwordW(hkDevRegKey, REGSTR_VAL_HARDWARE_W, 0);
|
|
|
|
RegCloseKey(hkDevRegKey);
|
|
hkDevRegKey = (HKEY)INVALID_HANDLE_VALUE;
|
|
|
|
if(!(dwHardwareConfig & STI_HW_CONFIG_PARALLEL)){
|
|
|
|
//
|
|
// This is not a parallel device.
|
|
//
|
|
|
|
continue;
|
|
} // if(!IsStiRegKey(hkDevRegKey))
|
|
|
|
//
|
|
// See if device is detected by system.
|
|
//
|
|
|
|
ulStatus = 0;
|
|
ulProblemNumber = 0;
|
|
ConfigRet = CM_Get_DevNode_Status(&ulStatus,
|
|
&ulProblemNumber,
|
|
spDevInfoData.DevInst,
|
|
0);
|
|
if(CR_SUCCESS != ConfigRet){
|
|
|
|
//
|
|
// There is a Pnp LPT device installed but not been detected on boot. Let enum LPT.
|
|
//
|
|
|
|
bRet = TRUE;
|
|
break;
|
|
} // if(CR_SUCCESS != ConfigRet)
|
|
|
|
} // for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++)
|
|
|
|
IsPnpLptExisting_return:
|
|
|
|
//
|
|
// Clean up.
|
|
//
|
|
|
|
if(INVALID_HANDLE_VALUE != hDevInfo){
|
|
SetupDiDestroyDeviceInfoList(hDevInfo);
|
|
} // if(INVALID_HANDLE_VALUE != hDevInfo)
|
|
|
|
return bRet;
|
|
|
|
} // IsPnpLptExisting()
|
|
|
|
|
|
} // extern "C"
|
|
|
|
|
|
VOID
|
|
DebugOutputDeviceName(
|
|
HDEVINFO hDevInfo,
|
|
PSP_DEVINFO_DATA pspDevInfoData,
|
|
LPCTSTR szKeyName
|
|
)
|
|
{
|
|
HKEY hkDev = NULL;
|
|
TCHAR szBuffer[1024];
|
|
DWORD dwSize;
|
|
LONG lResult;
|
|
DWORD dwType;
|
|
|
|
hkDev = SetupDiOpenDevRegKey(hDevInfo,
|
|
pspDevInfoData,
|
|
DICS_FLAG_GLOBAL,
|
|
0,
|
|
DIREG_DRV,
|
|
KEY_READ);
|
|
|
|
if(INVALID_HANDLE_VALUE == hkDev){
|
|
DPRINTF(DM_ERROR, TEXT("DebugOutputDeviceName: SetupDiOpenDevRegKey() failed. Err=0x%x"), GetLastError());
|
|
goto DebugOutputDeviceName_return;
|
|
} // if(INVALID_HANDLE_VALUE == hkDev)
|
|
|
|
dwSize = sizeof(szBuffer);
|
|
lResult = RegQueryValueEx(hkDev,
|
|
szKeyName,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)szBuffer,
|
|
&dwSize);
|
|
if(ERROR_SUCCESS != lResult){
|
|
DPRINTF(DM_ERROR, TEXT("DebugOutputDeviceName: RegQueryValueEx() failed. Err=0x%x"), lResult);
|
|
goto DebugOutputDeviceName_return;
|
|
}
|
|
|
|
switch(dwType){
|
|
case REG_DWORD:
|
|
DPRINTF(DM_ERROR, TEXT("DebugOutputDeviceName: Value: %s, Data: 0x%x"), szKeyName, szBuffer);
|
|
break;
|
|
|
|
case REG_SZ:
|
|
DPRINTF(DM_ERROR, TEXT("DebugOutputDeviceName: Value: %s, Data: %s"), szKeyName, szBuffer);
|
|
}
|
|
|
|
DebugOutputDeviceName_return:
|
|
|
|
// Close opened key
|
|
if(hkDev && (INVALID_HANDLE_VALUE != hkDev) ){
|
|
RegCloseKey(hkDev);
|
|
hkDev = (HKEY)INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
return;
|
|
} // DebugOutputDeviceRegistry(
|
|
|
|
VOID
|
|
DebugOutputInterfaceName(
|
|
HDEVINFO hDevInfo,
|
|
PSP_DEVICE_INTERFACE_DATA pspDevInterfaceData,
|
|
LPCTSTR szKeyName
|
|
)
|
|
{
|
|
HKEY hkDev = NULL;
|
|
TCHAR szBuffer[1024];
|
|
DWORD dwSize;
|
|
LONG lResult;
|
|
DWORD dwType;
|
|
|
|
hkDev = SetupDiOpenDeviceInterfaceRegKey(hDevInfo,
|
|
pspDevInterfaceData,
|
|
0,
|
|
KEY_READ);
|
|
|
|
if(INVALID_HANDLE_VALUE == hkDev){
|
|
// DPRINTF(DM_ERROR, TEXT("DebugOutputInterfaceName: SetupDiOpenDeviceInterfaceRegKey() failed. Err=0x%x"), GetLastError());
|
|
goto DebugOutputInterfaceName_return;
|
|
} // if(INVALID_HANDLE_VALUE == hkDev)
|
|
|
|
dwSize = sizeof(szBuffer);
|
|
lResult = RegQueryValueEx(hkDev,
|
|
szKeyName,
|
|
NULL,
|
|
&dwType,
|
|
(LPBYTE)szBuffer,
|
|
&dwSize);
|
|
if(ERROR_SUCCESS != lResult){
|
|
// DPRINTF(DM_ERROR, TEXT("DebugOutputInterfaceName: RegQueryValueEx() failed. Err=0x%x"), lResult);
|
|
goto DebugOutputInterfaceName_return;
|
|
}
|
|
|
|
switch(dwType){
|
|
case REG_DWORD:
|
|
DPRINTF(DM_ERROR, TEXT("DebugOutputInterfaceName: Value: %s, Data: 0x%x"), szKeyName, szBuffer);
|
|
break;
|
|
|
|
case REG_SZ:
|
|
DPRINTF(DM_ERROR, TEXT("DebugOutputInterfaceName: Value: %s, Data: %s"), szKeyName, szBuffer);
|
|
}
|
|
|
|
DebugOutputInterfaceName_return:
|
|
// Close opened key
|
|
if(hkDev && (INVALID_HANDLE_VALUE != hkDev) ){
|
|
RegCloseKey(hkDev);
|
|
hkDev = (HKEY)INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
return;
|
|
} // DebugOutputInterfaceName()
|
|
|
|
BOOL
|
|
IsStiRegKey(
|
|
HKEY hkDevRegKey
|
|
)
|
|
{
|
|
DWORD dwValueSize;
|
|
TCHAR szSubClass[MAX_PATH];
|
|
BOOL bRet;
|
|
|
|
bRet = TRUE;
|
|
dwValueSize = sizeof(szSubClass);
|
|
|
|
memset(szSubClass, 0, sizeof(szSubClass));
|
|
|
|
RegQueryValueEx(hkDevRegKey,
|
|
SUBCLASS,
|
|
NULL,
|
|
NULL,
|
|
(LPBYTE)szSubClass,
|
|
&dwValueSize);
|
|
|
|
if( (0 == lstrlen(szSubClass))
|
|
|| (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, szSubClass, -1, STILL_IMAGE, -1) != CSTR_EQUAL) )
|
|
{
|
|
bRet = FALSE;
|
|
}
|
|
|
|
return bRet;
|
|
} // IsStiRegKey()
|
|
|
|
|
|
/********************************* End of File ***************************/
|
|
|