|
|
/******************************************************************************
* * (C) COPYRIGHT MICROSOFT CORP., 2000 * * TITLE: Device.cpp * * VERSION: 1.0 * * AUTHOR: KeisukeT * * DATE: 27 Mar, 2000 * * DESCRIPTION: * Device class for WIA class installer. * * *******************************************************************************/
//
// Precompiled header
//
#include "precomp.h"
#pragma hdrstop
#define INITGUID
#include "device.h"
#include "sti.h"
#include "stiregi.h"
#include <stisvc.h>
#include <devguid.h>
#include <regstr.h>
#include <icm.h>
#include <ks.h>
//
// Parsinc character used to separate field type from value in registry data section
//
#define FIELD_DELIMETER TEXT(',')
BOOL CDevice::CollectNames( VOID ) {
BOOL bRet; HANDLE hDevInfo; GUID Guid; DWORD dwRequired; DWORD Idx; SP_DEVINFO_DATA spDevInfoData; SP_DEVICE_INTERFACE_DATA spDevInterfaceData; TCHAR szTempBuffer[MAX_DESCRIPTION]; HKEY hKeyInterface; HKEY hKeyDevice;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::CollectNames: Enter...\r\n")));
//
// Initialize local.
//
bRet = FALSE; hDevInfo = INVALID_HANDLE_VALUE; Guid = GUID_DEVCLASS_IMAGE; dwRequired = 0; Idx = 0; hKeyInterface = (HKEY)INVALID_HANDLE_VALUE; hKeyDevice = (HKEY)INVALID_HANDLE_VALUE;
memset(szTempBuffer, 0, sizeof(szTempBuffer)); memset(&spDevInfoData, 0, sizeof(spDevInfoData)); memset(&spDevInterfaceData, 0, sizeof(spDevInterfaceData));
//
// Reset device name/ID array.
//
m_csaAllNames.Cleanup(); m_csaAllId.Cleanup();
//
// Get all of installed WIA "devnode" device info set.
//
hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, DIGCF_PROFILE); if (hDevInfo == INVALID_HANDLE_VALUE) { DebugTrace(TRACE_ERROR,(("CDevice::CollectNames: ERROR!! SetupDiGetClassDevs (devnodes) fails. Err=0x%x\n"), GetLastError()));
bRet = FALSE; goto CollectNames_return; }
//
// Enum WIA devnode device friendly name and add them to array.
//
DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Looking for DevNodes.\r\n")));
spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA); for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++) {
//
// Open device registry key.
//
hKeyDevice = SetupDiOpenDevRegKey(hDevInfo, &spDevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ);
if (INVALID_HANDLE_VALUE != hKeyDevice) {
//
// Get FriendlyName.
//
dwRequired = (sizeof(szTempBuffer)-sizeof(TEXT('\0'))); if (RegQueryValueEx(hKeyDevice, REGSTR_VAL_FRIENDLY_NAME, NULL, NULL, (LPBYTE)szTempBuffer, &dwRequired) == ERROR_SUCCESS) {
//
// FriendlyName is found in this device regisgry. Add to the list if valid.
//
if(0 != lstrlen(szTempBuffer)) { DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Found %ws as installed device name.\r\n"), szTempBuffer)); m_csaAllNames.Add((LPCTSTR)szTempBuffer); } else { // if(0 != lstrlen(szTempBuffer))
DebugTrace(TRACE_ERROR,(("CDevice::CollectNames: ERROR!! Invalid FriendleName (length=0).\r\n"))); } // if(0 != lstrlen(szTempBuffer))
} else { // if (RegQueryValueEx()
DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: can't get FriendlyName. Err=0x%x\r\n"), GetLastError())); } // if (RegQueryValueEx()
//
// Get DeviceID.
//
dwRequired = (sizeof(szTempBuffer)-sizeof(TEXT('\0'))); if (RegQueryValueEx(hKeyDevice, REGSTR_VAL_DEVICE_ID, NULL, NULL, (LPBYTE)szTempBuffer, &dwRequired) == ERROR_SUCCESS) {
//
// DeviceID is found in this device regisgry. Add to the list if valid.
//
if(0 != lstrlen(szTempBuffer)) { DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Found %ws as installed device ID.\r\n"), szTempBuffer)); m_csaAllId.Add((LPCTSTR)szTempBuffer); } else { // if(0 != lstrlen(szTempBuffer))
DebugTrace(TRACE_ERROR,(("CDevice::CollectNames: ERROR!! Invalid DeviceID (length=0).\r\n"))); } // if(0 != lstrlen(szTempBuffer))
} else { // if (RegQueryValueEx()
DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: can't get DeviceID. Err=0x%x\r\n"), GetLastError())); } // if (RegQueryValueEx()
//
// Close regkey and continue.
//
RegCloseKey(hKeyDevice); hKeyInterface = (HKEY)INVALID_HANDLE_VALUE; szTempBuffer[0] = TEXT('\0');
} else { // if (hKeyDevice != INVALID_HANDLE_VALUE)
DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Unable to open Device(%d) RegKey. Err=0x%x\r\n"), Idx, GetLastError())); } // if (hKeyDevice != INVALID_HANDLE_VALUE)
} // for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++)
//
// Free "devnode" device info set.
//
SetupDiDestroyDeviceInfoList(hDevInfo); hDevInfo = INVALID_HANDLE_VALUE;
//
// Enum WIA interface-only device friendly name and add them to array.
//
DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Looking for Interfaces.\r\n")));
hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PROFILE); if (hDevInfo == INVALID_HANDLE_VALUE) { DebugTrace(TRACE_ERROR,(("CDevice::CollectNames: ERROR!! SetupDiGetClassDevs (inferfase) fails. Err=0x%x\n"), GetLastError()));
bRet = FALSE; goto CollectNames_return; }
spDevInterfaceData.cbSize = sizeof (spDevInterfaceData); for (Idx = 0; SetupDiEnumDeviceInterfaces (hDevInfo, NULL, &Guid, Idx, &spDevInterfaceData); Idx++) {
hKeyInterface = SetupDiOpenDeviceInterfaceRegKey(hDevInfo, &spDevInterfaceData, 0, KEY_READ); if (hKeyInterface != INVALID_HANDLE_VALUE) {
//
// Get FriendlyName.
//
dwRequired = (sizeof(szTempBuffer)-sizeof(TEXT('\0'))); if (RegQueryValueEx(hKeyInterface, REGSTR_VAL_FRIENDLY_NAME, NULL, NULL, (LPBYTE)szTempBuffer, &dwRequired) == ERROR_SUCCESS) {
//
// FriendlyName is found in this interface. Add to the list if valid.
//
if(0 != lstrlen(szTempBuffer)) { DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Found %ws as installed device name (interface).\r\n"), szTempBuffer)); m_csaAllNames.Add((LPCTSTR)szTempBuffer); } else { // if(0 != lstrlen(szTempBuffer))
DebugTrace(TRACE_ERROR,(("CDevice::CollectNames: ERROR!! Invalid FriendleName (length=0).\r\n"))); } // if(0 != lstrlen(szTempBuffer))
} else { // if (RegQueryValueEx()
DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: can't get FriendlyName. Err=0x%x\r\n"), GetLastError())); } // if (RegQueryValueEx()
//
// Get DeviceID.
//
dwRequired = (sizeof(szTempBuffer)-sizeof(TEXT('\0'))); if (RegQueryValueEx(hKeyInterface, REGSTR_VAL_DEVICE_ID, NULL, NULL, (LPBYTE)szTempBuffer, &dwRequired) == ERROR_SUCCESS) {
//
// DeviceID is found in this interface. Add to the list if valid.
//
if(0 != lstrlen(szTempBuffer)) { DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Found %ws as installed device ID (interface).\r\n"), szTempBuffer)); m_csaAllId.Add((LPCTSTR)szTempBuffer); } else { // if(0 != lstrlen(szTempBuffer))
DebugTrace(TRACE_ERROR,(("CDevice::CollectNames: ERROR!! Invalid DeviceID (length=0).\r\n"))); } // if(0 != lstrlen(szTempBuffer))
} else { // if (RegQueryValueEx()
DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: can't get DeviceID. Err=0x%x\r\n"), GetLastError())); } // if (RegQueryValueEx()
//
// Close registry key and continue.
//
RegCloseKey(hKeyInterface); hKeyInterface = (HKEY)INVALID_HANDLE_VALUE; szTempBuffer[0] = TEXT('\0');
} else { // if (hKeyInterface != INVALID_HANDLE_VALUE)
DebugTrace(TRACE_STATUS,(("CDevice::CollectNames: Unable to open Interface(%d) RegKey. Err=0x%x\r\n"), Idx, GetLastError())); } // if (hKeyInterface != INVALID_HANDLE_VALUE)
} // for (Idx = 0; SetupDiEnumDeviceInterfaces (hDevInfo, NULL, &Guid, Idx, &spDevInterfaceData); Idx++)
//
// Operation succeeded.
//
bRet = TRUE;
CollectNames_return:
//
// Clean up.
//
if(INVALID_HANDLE_VALUE != hDevInfo){ SetupDiDestroyDeviceInfoList(hDevInfo); }
if(INVALID_HANDLE_VALUE != hKeyInterface){ RegCloseKey(hKeyInterface); }
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::CollectNames: Leaving... Ret=0x%x\n"), bRet)); return bRet; } // CDevice::CollectNames()
// For a device w/ devnode.
CDevice::CDevice( HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData, BOOL bIsPnP ) { HKEY hkDevice; //
// Initizlize local.
//
hkDevice = (HKEY)INVALID_HANDLE_VALUE;
//
// Initialize member.
//
m_hMutex = (HANDLE)NULL; m_hDevInfo = hDevInfo; m_pspDevInfoData = pspDevInfoData;
m_bIsPnP = bIsPnP; m_bDefaultDevice = FALSE; m_bVideoDevice = FALSE; m_bInfProceeded = FALSE; m_bInterfaceOnly = FALSE; m_bIsMigration = FALSE;
m_hkInterfaceRegistry = (HKEY)INVALID_HANDLE_VALUE;
m_dwCapabilities = 0; m_dwInterfaceIndex = INVALID_DEVICE_INDEX;
m_pfnDevnodeSelCallback = (DEVNODESELCALLBACK) NULL; m_pExtraDeviceData = NULL;
m_csFriendlyName.Empty(); m_csInf.Empty(); m_csInstallSection.Empty(); m_csDriverDescription.Empty(); m_csPort.Empty(); m_csDeviceID.Empty(); //
// In case of upgrade, use original FriendlyName.
//
hkDevice = SetupDiOpenDevRegKey(m_hDevInfo, m_pspDevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ); if(INVALID_HANDLE_VALUE != hkDevice){
//
// Device registry found. Read its FriendlyName.
//
m_csDriverDescription.Load(hkDevice, FRIENDLYNAME); m_csDeviceID.Load(hkDevice, REGSTR_VAL_DEVICE_ID); m_csFriendlyName.Load(hkDevice, FRIENDLYNAME);
RegCloseKey(hkDevice); hkDevice = (HKEY)INVALID_HANDLE_VALUE;
} // if(INVALID_HANDLE_VALUE != hkDevice)
//
// Get the number of installed devices.
//
GetDeviceCount(&m_dwNumberOfWiaDevice, &m_dwNumberOfStiDevice);
} // CDevice::CDevice()
// For a interface-only device.
CDevice::CDevice( HDEVINFO hDevInfo, DWORD dwDeviceIndex ) { //
// Initialize member.
//
m_hMutex = (HANDLE)NULL; m_hDevInfo = hDevInfo; m_pspDevInfoData = NULL;
m_bIsPnP = FALSE; m_bDefaultDevice = FALSE; m_bVideoDevice = FALSE; m_bInfProceeded = FALSE; m_bInterfaceOnly = TRUE; m_bIsMigration = FALSE;
m_hkInterfaceRegistry = (HKEY)INVALID_HANDLE_VALUE;
m_dwCapabilities = 0; m_dwInterfaceIndex = dwDeviceIndex;
m_pfnDevnodeSelCallback = (DEVNODESELCALLBACK) NULL; m_pExtraDeviceData = NULL;
m_csFriendlyName.Empty(); m_csInf.Empty(); m_csInstallSection.Empty(); m_csDriverDescription.Empty(); m_csPort.Empty(); m_csDeviceID.Empty();
//
// Get the number of installed devices.
//
GetDeviceCount(&m_dwNumberOfWiaDevice, &m_dwNumberOfStiDevice);
} // CDevice::CDevice()
// For a interface-only device.
CDevice::CDevice( PDEVICE_INFO pMigratingDevice ) { TCHAR StringBuffer[MAX_PATH+1]; TCHAR WindowsDir[MAX_PATH+1];
//
// Initialize local.
//
memset(StringBuffer, 0, sizeof(StringBuffer)); memset(WindowsDir, 0, sizeof(WindowsDir));
//
// Initialize member.
//
m_hMutex = (HANDLE)NULL; m_hDevInfo = NULL; m_pspDevInfoData = NULL;
m_bIsPnP = FALSE; m_bDefaultDevice = FALSE; m_bVideoDevice = FALSE; m_bInfProceeded = FALSE; m_bInterfaceOnly = TRUE; m_bIsMigration = TRUE;
m_hkInterfaceRegistry = (HKEY)INVALID_HANDLE_VALUE;
m_dwCapabilities = 0; m_dwInterfaceIndex = INVALID_DEVICE_INDEX;
m_pfnDevnodeSelCallback = (DEVNODESELCALLBACK) NULL;
//
// Copy migration data.
//
AtoT(StringBuffer, pMigratingDevice->pszInfPath); m_csInf = StringBuffer; if(0 != GetWindowsDirectory(WindowsDir, MAX_PATH)){ _sntprintf(StringBuffer, ARRAYSIZE(StringBuffer)-1, TEXT("%ws\\inf\\%ws"), WindowsDir, (LPTSTR)m_csInf); m_csInf = StringBuffer; } // if(0 != GetWindowsDirectory(WindowsDir, MAX_PATH))
AtoT(StringBuffer, pMigratingDevice->pszInfSection); m_csInstallSection = StringBuffer; AtoT(StringBuffer, pMigratingDevice->pszFriendlyName); m_csDriverDescription = StringBuffer; AtoT(StringBuffer, pMigratingDevice->pszFriendlyName); m_csFriendlyName = StringBuffer; AtoT(StringBuffer, pMigratingDevice->pszCreateFileName); m_csPort = StringBuffer; m_pExtraDeviceData = pMigratingDevice->pDeviceDataParam; m_csDeviceID.Empty();
//
// Get the number of installed devices.
//
GetDeviceCount(&m_dwNumberOfWiaDevice, &m_dwNumberOfStiDevice);
} // CDevice::CDevice()
CDevice::~CDevice( ) { HKEY hkNameStore;
if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore)){ //
// Delete FriendlyName and DeviceId in name store.
//
RegDeleteKey(hkNameStore, m_csFriendlyName); RegDeleteKey(hkNameStore, m_csDeviceID); RegCloseKey(hkNameStore);
} // if(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore))
//
// Make sure Mutex is released.
//
ReleaseInstallerMutex();
} // CDevice::~CDevice()
BOOL CDevice::IsSameDevice( HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoSet ) { BOOL bRet; SP_DRVINFO_DATA spDrvInfoData;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::IsSameDevice: Enter...\r\n")));
//
// Initialize local.
//
bRet = FALSE;
memset(&spDrvInfoData, 0, sizeof(spDrvInfoData));
//
// Get default FriendlyName. It's used to check if it's same device or not.
//
spDrvInfoData.cbSize = sizeof (SP_DRVINFO_DATA); if (!SetupDiGetSelectedDriver (hDevInfo, pspDevInfoSet, &spDrvInfoData)){
bRet = FALSE; goto IsSameDevice_return; } // if (SetupDiGetSelectedDriver (m_hDevInfo, m_pspDevInfoData, &spDevInfoData))
//
// See if it has same description of current device. (TRUE=same)
//
bRet = (0 == lstrcmp((LPCTSTR)spDrvInfoData.Description, (LPCTSTR)m_csPdoDescription));
IsSameDevice_return: DebugTrace(TRACE_PROC_LEAVE,(("CDevice::IsSameDevice: Leaving... Ret=0x%x\n"), bRet)); return bRet; } // CDevice::IsSameDevice()
BOOL CDevice::IsFriendlyNameUnique( LPTSTR szFriendlyName ) //
// Note:
// Before calling this function, caller has to make sure mutex is acquired.
//
{ BOOL bRet; DWORD Idx; DWORD dwNumberOfName;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::IsFriendlyNameUnique: Enter... \r\n")));
//
// Initialize local.
//
bRet = FALSE; Idx = 0; dwNumberOfName = m_csaAllNames.Count();
//
// If given name is same as generated one, it's unique.
//
if(0 == lstrcmp(szFriendlyName, (LPTSTR)(m_csFriendlyName))){ bRet = TRUE; goto IsFriendlyNameUnique_return; } // if(0 == lstrcmp(szFriendlyName, (LPTSTR)(m_csFriendlyName)))
//
// Check any existing name matches given name.
//
for (Idx = 0; Idx < dwNumberOfName; Idx++) {
DebugTrace(TRACE_STATUS,(("CDevice::IsFriendlyNameUnique: Name compare %ws and %ws.\r\n"),m_csaAllNames[Idx], szFriendlyName));
if (0 == lstrcmpi(m_csaAllNames[Idx], szFriendlyName)){ bRet = FALSE; goto IsFriendlyNameUnique_return; } } // for (Idx = 0; Idx < dwNumberOfName; Idx)
//
// Look in name store.
//
if(IsNameAlreadyStored(szFriendlyName)){ bRet = FALSE; goto IsFriendlyNameUnique_return; } // if(IsNameAlreadyStored(szFriendlyName))
//
// This device name is unique.
//
bRet = TRUE;
IsFriendlyNameUnique_return: DebugTrace(TRACE_PROC_LEAVE,(("CDevice::IsFriendlyNameUnique: Leaving... Ret=0x%x\n"), bRet)); return bRet;
} // CDevice::IsFriendlyNameUnique()
BOOL CDevice::IsDeviceIdUnique( LPTSTR szDeviceId ) { BOOL bRet; DWORD Idx; DWORD dwNumberOfId;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::IsDeviceIdUnique: Enter... \r\n")));
//
// Initialize local.
//
bRet = FALSE; Idx = 0; dwNumberOfId = m_csaAllId.Count();
//
// If given ID is same as generated one, it's unique.
//
if(0 == lstrcmp(szDeviceId, (LPTSTR)(m_csDeviceID))){ bRet = TRUE; goto IsDeviceIdUnique_return; } // if(0 == lstrcmp(szFriendlyName, (LPTSTR)(m_csFriendlyName)))
//
// Check any existing name matches given name.
//
for (Idx = 0; Idx < dwNumberOfId; Idx++) {
DebugTrace(TRACE_STATUS,(("CDevice::IsDeviceIdUnique: DeviceId compare %ws and %ws.\r\n"),m_csaAllId[Idx], szDeviceId));
if (0 == lstrcmpi(m_csaAllId[Idx], szDeviceId)){ bRet = FALSE; goto IsDeviceIdUnique_return; } // if (0 == lstrcmpi(m_csaAllId[Idx], szFriendlyName))
} // for (Idx = 0; Idx < dwNumberOfName; Idx)
//
// Look in name store.
//
if(IsNameAlreadyStored(szDeviceId)){ bRet = FALSE; goto IsDeviceIdUnique_return; } // if(IsNameAlreadyStored(szFriendlyName))
//
// This device name is unique.
//
bRet = TRUE;
IsDeviceIdUnique_return: DebugTrace(TRACE_PROC_LEAVE,(("CDevice::IsDeviceIdUnique: Leaving... Ret=0x%x\n"), bRet)); return bRet;
} // CDevice::IsDeviceIdUnique()
BOOL CDevice::NameDefaultUniqueName( VOID ) { SP_DRVINFO_DATA spDrvInfoData; TCHAR szFriendly[MAX_DESCRIPTION]; TCHAR szDescription[MAX_DESCRIPTION]; UINT i; BOOL bRet; HKEY hkNameStore; DWORD dwError;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::NameDefaultUniqueName: Enter... \r\n")));
//
// Initialize local.
//
bRet = FALSE; hkNameStore = (HKEY)INVALID_HANDLE_VALUE;
memset(szFriendly, 0, sizeof(szFriendly)); memset(szDescription, 0, sizeof(szDescription)); memset(&spDrvInfoData, 0, sizeof(spDrvInfoData));
//
// Acquire mutex to make sure not duplicating FriendlyName/DeviceId.
//
dwError = AcquireInstallerMutex(MAX_MUTEXTIMEOUT); if(ERROR_SUCCESS != dwError){ // it must be done at least in 60 sec.
if(WAIT_ABANDONED == dwError){ DebugTrace(TRACE_ERROR,("CDevice::NameDefaultUniqueName: ERROR!! Mutex abandoned. Continue...\r\n")); } else if(WAIT_TIMEOUT == dwError){ DebugTrace(TRACE_ERROR,("CDevice::NameDefaultUniqueName: ERROR!! Unable to acquire mutex in 60 sec. Bail out.\r\n")); bRet = FALSE; goto NameDefaultUniqueName_return; } // else if(WAIT_TIMEOUT == dwError)
} // if(ERROR_SUCCESS != AcquireInstallerMutex(60000))
//
// Get all installed WIA device friendly name.
//
CollectNames();
//
// Generate unique device ID.
//
if(m_csDeviceID.IsEmpty()){ GenerateUniqueDeviceId(); } // if(m_csDeviceID.IsEmpty())
if(m_csFriendlyName.IsEmpty()){
//
// Get default FriendlyName. It's used to check if it's same device or not.
//
spDrvInfoData.cbSize = sizeof (SP_DRVINFO_DATA); if (!SetupDiGetSelectedDriver (m_hDevInfo, m_pspDevInfoData, &spDrvInfoData)){
bRet = FALSE; goto NameDefaultUniqueName_return; } // if (SetupDiGetSelectedDriver (m_hDevInfo, m_pspDevInfoData, &spDevInfoData))
//
// Copy default Device description. (= default FriendlyName)
// Also set Vnedor name.
//
m_csVendor = (LPCTSTR)spDrvInfoData.MfgName; m_csPdoDescription = (LPCTSTR)spDrvInfoData.Description;
//
// Find unique name for this device.
//
if(m_csDriverDescription.IsEmpty()){ lstrcpyn(szDescription, m_csPdoDescription, ARRAYSIZE(szDescription)-1); m_csDriverDescription = szDescription; } else { lstrcpyn(szDescription, m_csDriverDescription, ARRAYSIZE(szDescription)-1); }
lstrcpyn(szFriendly, szDescription, ARRAYSIZE(szFriendly)-1); for (i = 2; !IsFriendlyNameUnique(szFriendly); i++) { _sntprintf(szFriendly, ARRAYSIZE(szFriendly)-1, TEXT("%ws #%d"), szDescription, i); }
//
// Set created FriendlyName.
//
m_csFriendlyName = szFriendly;
} // if(m_csFriendlyName.IsEmpty())
//
// Save FriendlyName and DeviceId in registry. It'll be deleted when installation is completed.
//
if(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore)){ HKEY hkTemp;
hkTemp = (HKEY)INVALID_HANDLE_VALUE;
//
// Create FriendlyName key.
//
if(ERROR_SUCCESS == RegCreateKey(hkNameStore, (LPTSTR)m_csFriendlyName, &hkTemp)){ RegCloseKey(hkTemp); hkTemp = (HKEY)INVALID_HANDLE_VALUE; } else { DebugTrace(TRACE_ERROR,("CDevice::NameDefaultUniqueName: ERROR!! Unable to create %s key.\r\n", (LPTSTR)m_csFriendlyName)); } // if(ERROR_SUCCESS != RegCreateKey(hkNameStore, (LPTSTR)m_csFriendlyName, &hkTemp))
//
// Create DeviceId key.
//
if(ERROR_SUCCESS == RegCreateKey(hkNameStore, (LPTSTR)m_csDeviceID, &hkTemp)){ RegCloseKey(hkTemp); hkTemp = (HKEY)INVALID_HANDLE_VALUE; } else { DebugTrace(TRACE_ERROR,("CDevice::NameDefaultUniqueName: ERROR!! Unable to create %s key.\r\n", (LPTSTR)m_csDeviceID)); } // if(ERROR_SUCCESS != RegCreateKey(hkNameStore, (LPTSTR)m_csFriendlyName, &hkTemp))
RegCloseKey(hkNameStore);
} else { // if(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore))
DebugTrace(TRACE_ERROR,("CDevice::NameDefaultUniqueName: ERROR!! Unable to create NameStore key.\r\n")); } // else(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore))
//
// Operation succeeded.
//
DebugTrace(TRACE_STATUS,(("CDevice::NameDefaultUniqueName: Device default name=%ws.\r\n"), (LPTSTR)m_csFriendlyName)); bRet = TRUE;
NameDefaultUniqueName_return:
//
// Release mutex. ReleaseInstallerMutex() will handle invalid handle also, so we can call anyway.
//
ReleaseInstallerMutex();
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::NameDefaultUniqueName: Leaving... Ret=0x%x\n"), bRet)); return bRet; } // CDevice::NameDefaultUniqueName()
BOOL CDevice::GenerateUniqueDeviceId( VOID ) { DWORD Idx; BOOL bRet; TCHAR szDeviceId[MAX_DESCRIPTION];
DebugTrace(TRACE_PROC_ENTER,(("CDevice::GenerateUniqueDeviceId: Enter... \r\n")));
//
// Initialize local.
//
bRet = FALSE; memset(szDeviceId, 0, sizeof(szDeviceId));
//
// Find unique name for this device.
//
_sntprintf(szDeviceId, ARRAYSIZE(szDeviceId)-1, TEXT("%ws\\%04d"), WIA_GUIDSTRING, 0);
for (Idx = 1; !IsDeviceIdUnique(szDeviceId); Idx++) { _sntprintf(szDeviceId, ARRAYSIZE(szDeviceId)-1, TEXT("%ws\\%04d"), WIA_GUIDSTRING, Idx); }
//
// Set created hardwareId.
//
m_csDeviceID = szDeviceId;
//
// Operation succeeded.
//
DebugTrace(TRACE_STATUS,(("CDevice::GenerateUniqueDeviceId: DeviceID=%ws.\r\n"), (LPTSTR)m_csDeviceID)); bRet = TRUE;
// GenerateUniqueDeviceId_return:
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::GenerateUniqueDeviceId: Leaving... Ret=0x%x\n"), bRet)); return bRet; } // CDevice::GenerateUniqueDeviceId()
BOOL CDevice::Install( ) /*++
Routine Description:
Worker function for DIF_INSTALL setup message
Arguments:
none
Return Value:
TRUE - successful FALSE - non successful
--*/ {
BOOL bRet;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::Install: Enter... \r\n")));
//
// Initialize local.
//
bRet = FALSE;
//
// Class installer only handles file copy.
//
if(IsMigration()){ CreateDeviceInterfaceAndInstall(); } else { // if(IsMigration())
if ( !HandleFilesInstallation()){ DebugTrace(TRACE_ERROR, (("CDevice::Install: HandleFilesInstallation Failed. Err=0x%x"), GetLastError()));
bRet = FALSE; goto Install_return; } // if ( !HandleFilesInstallation())
} // else(IsMigration())
//
// We are successfully finished
//
bRet = TRUE;
Install_return:
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::Install: Leaving... Ret=0x%x\n"), bRet)); return bRet; }
DWORD CDevice::Remove( PSP_REMOVEDEVICE_PARAMS lprdp ) /*++
Routine Description:
Remove
method which is called when device is being removed
Arguments:
Return Value:
Side effects:
--*/ {
CString csUninstallSection; CString csInf; CString csSubClass; DWORD dwCapabilities; PVOID pvContext; HKEY hkDrv; HKEY hkRun; GUID Guid; BOOL bIsServiceStopped; BOOL bIsSti;
BOOL bSetParamRet; PSP_FILE_CALLBACK SavedCallback;
SP_DEVICE_INTERFACE_DATA spDevInterfaceData; SP_DEVINSTALL_PARAMS DeviceInstallParams; DWORD dwReturn; LPTSTR pSec;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::Remove: Enter... \r\n")));
//
// Initialize local.
//
pvContext = NULL; hkDrv = NULL; hkRun = NULL;
bSetParamRet = FALSE; SavedCallback = NULL; dwReturn = NO_ERROR; Guid = GUID_DEVCLASS_IMAGE;
bIsServiceStopped = FALSE; bIsSti = FALSE;
memset(&DeviceInstallParams, 0, sizeof(DeviceInstallParams)); memset(&spDevInterfaceData, 0, sizeof(spDevInterfaceData));
//
// NT setup inconsistently set this bit , disable for now
//
#if SETUP_PROBLEM
if (!(lprdp->Scope & DI_REMOVEDEVICE_GLOBAL)) {
goto Remove_return; } #endif
//
// The name of the uninstall section was stored during installation
//
if(IsInterfaceOnlyDevice()){
DebugTrace(TRACE_STATUS,(("CDevice::Remove: This is Interface-only device.\r\n")));
//
// Get interface from index.
//
spDevInterfaceData.cbSize = sizeof(spDevInterfaceData); if(!SetupDiEnumDeviceInterfaces(m_hDevInfo, NULL, &Guid, m_dwInterfaceIndex, &spDevInterfaceData)){ DebugTrace(TRACE_ERROR,(("CDevice::Remove: SetupDiEnumDeviceInterfaces() failed. Err=0x%x \r\n"), GetLastError()));
dwReturn = ERROR_NO_DEFAULT_DEVICE_INTERFACE; goto Remove_return; }
//
// Create interface reg-key.
//
hkDrv = SetupDiOpenDeviceInterfaceRegKey(m_hDevInfo, &spDevInterfaceData, 0, KEY_READ); } else { // if(IsInterfaceOnlyDevice())
DebugTrace(TRACE_STATUS,(("CDevice::Remove: This is devnode device.\r\n")));
hkDrv = SetupDiOpenDevRegKey(m_hDevInfo, m_pspDevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ); } // if(IsInterfaceOnlyDevice())
if (hkDrv == INVALID_HANDLE_VALUE) { DebugTrace(TRACE_ERROR,(("CDevice::Remove: Invalid device/interface regkey handle. Err=0x%x \r\n"), GetLastError()));
dwReturn = ERROR_KEY_DOES_NOT_EXIST; goto Remove_return; }
//
// Retrieve the name of the .INF File
//
csUninstallSection.Load (hkDrv, UNINSTALLSECTION); csInf.Load (hkDrv, INFPATH); csSubClass.Load(hkDrv, SUBCLASS); GetDwordFromRegistry(hkDrv, CAPABILITIES, &dwCapabilities);
//
// See if we need STI/WIA specific operation.
//
if( (!csSubClass.IsEmpty()) && (0 == MyStrCmpi(csSubClass, STILL_IMAGE)) ) { //
// This is STI/WIA device.
//
bIsSti = TRUE; //
// Delete "Scanner and Camera Wizard" menu.
//
if( (dwCapabilities & STI_GENCAP_WIA) && (m_dwNumberOfWiaDevice <= 1) ) { DeleteWiaShortcut();
//
// remove following key for performance improvement.
//
if(ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, REGKEY_WIASHEXT)){ DebugTrace(TRACE_ERROR,(("CDevice::Remove: RegDeleteKey() failed. Err=0x%x. \r\n"), GetLastError())); } // if(ERROR_SUCCESS != RegDeleteKey(HKEY_LOCAL_MACHINE, REGKEY_WIASHEXT))
} // if( (dwCapabilities & STI_GENCAP_WIA)
//
// If this is the last STI/WIA device, set WIA service as Manual.
//
if(m_dwNumberOfStiDevice <= 1){
HKEY hkeyTemp;
DebugTrace(TRACE_STATUS,(("CDevice::Remove: Last WIA device being removed. Set WIA service as MANUAL.\r\n")));
//
// No more still image devices -- change service to Manual start
//
// StopWiaService();
SetServiceStart(STI_SERVICE_NAME, SERVICE_DEMAND_START); bIsServiceStopped = TRUE;
//
//
// Also remove shell's flag about WIA device presence, this should be portable
// to NT
//
if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SOFT_STI, &hkRun) == 0) { RegDeleteValue (hkRun, REGSTR_VAL_WIA_PRESENT); RegCloseKey(hkRun); hkRun = NULL; } // if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SOFT_STI, &hkRun) == 0)
} // if(m_dwNumberOfStiDevice <= 1)
} // if (m_dwNumberOfDevice <= 1)
//
// Operaion succeeded.
//
dwReturn = NO_ERROR;
Remove_return:
if(IsInterfaceOnlyDevice()){
//
// Delete interface resigtry key.
//
if(!SetupDiDeleteDeviceInterfaceRegKey(m_hDevInfo, &spDevInterfaceData, 0)){ DebugTrace(TRACE_ERROR,(("CDevice::Remove: SetupDiDeleteDeviceInterfaceRegKey failed. Err=0x%x \r\n"), GetLastError())); } // if(!SetupDiDeleteDeviceInterfaceRegKey(m_hDevInfo, &spDevInterfaceData, 0))
//
// Remove the interface.
//
if(!SetupDiRemoveDeviceInterface(m_hDevInfo, &spDevInterfaceData)){ DebugTrace(TRACE_ERROR,(("CDevice::Remove: SetupDiRemoveDeviceInterface failed. Err=0x%x \r\n"), GetLastError())); } // if(!SetupDiRemoveDeviceInterface(m_hDevInfo, &spDevInterfaceData))
} else { // if(IsInterfaceOnlyDevice())
//
// Delete device resigtry key.
//
SetupDiDeleteDevRegKey (m_hDevInfo, m_pspDevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_BOTH);
if(NO_ERROR == dwReturn){
//
// Remove the device node anyway.
//
if(!SetupDiRemoveDevice(m_hDevInfo, m_pspDevInfoData)){ DebugTrace(TRACE_ERROR,(("CDevice::Remove: SetupDiRemoveDevice failed. Err=0x%x \r\n"), GetLastError()));
//
// Failed to remove device instance from system. Let default installer do that.
//
dwReturn = ERROR_DI_DO_DEFAULT; } // if(!SetupDiRemoveDevice(m_hDevInfo, m_pspDevInfoData))
} // if(ERROR_DI_DO_DEFAULT != dwReturn)
} // else (IsInterfaceOnlyDevice())
//
// Notify WIA service device removal
//
if(bIsSti){ WiaDeviceEnum(); } // if(TRUE == bIsSti)
//
// Clean up.
//
if(IS_VALID_HANDLE(hkDrv)){ RegCloseKey (hkDrv); hkDrv = NULL; }
if(IS_VALID_HANDLE(hkRun)){ RegCloseKey (hkRun); hkRun = NULL; }
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::Remove: Leaving... Ret=0x%x\n"), dwReturn)); return dwReturn; }
BOOL CDevice::PreprocessInf( VOID ) {
BOOL bRet; HINF hInf;
CString csCapabilities; CString csDeviceType; CString csDeviceSubType; CString csDriverDescription;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::PreprocessInf: Enter... \r\n")));
//
// Initialize local.
//
bRet = FALSE; hInf = INVALID_HANDLE_VALUE;
//
// Check if INF has already been proceeded.
//
if(m_bInfProceeded){ DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: INF is already processed. \r\n"))); bRet = TRUE; goto ProcessInf_return; }
//
// Get Inf file/section name.
//
if( m_csInf.IsEmpty() || m_csInstallSection.IsEmpty()){ GetInfInforamtion(); } // if( m_csInf.IsEmpty() || m_csInstallSection.IsEmpty())
//
// Open INF file.
//
hInf = SetupOpenInfFile(m_csInf, NULL, INF_STYLE_WIN4, NULL);
if(!IS_VALID_HANDLE(hInf)){ DebugTrace(TRACE_ERROR, (("CDevice::PreprocessInf: Unable to open INF(%ws). Error = 0x%x.\r\n"),m_csInf, GetLastError()));
bRet = FALSE; goto ProcessInf_return; } // if(!IS_VALID_HANDLE(hInf))
//
// Check if WiaSection entry exists.
//
m_csWiaSection.Load (hInf, m_csInstallSection, WIASECTION); if(!m_csWiaSection.IsEmpty()){ DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: WiaSection exists. Acquire all informaiton from WiaSection..\r\n")));
//
// Install interface from WiaSection for MFP device.
//
m_csInstallSection = m_csWiaSection; m_bInterfaceOnly = TRUE;
} // if(!m_csWiaSection.IsEmpty())
//
// Get all information required for installation from inf file.
//
m_csSubClass.Load (hInf, m_csInstallSection, SUBCLASS); m_csUSDClass.Load (hInf, m_csInstallSection, USDCLASS); m_csEventSection.Load (hInf, m_csInstallSection, EVENTS); m_csConnection.Load (hInf, m_csInstallSection, CONNECTION); m_csIcmProfile.Load (hInf, m_csInstallSection, ICMPROFILES); m_csPropPages.Load (hInf, m_csInstallSection, PROPERTYPAGES); m_csDataSection.Load (hInf, m_csInstallSection, DEVICESECTION); m_csUninstallSection.Load (hInf, m_csInstallSection, UNINSTALLSECTION); m_csPortSelect.Load (hInf, m_csInstallSection, PORTSELECT);
if(!IsMigration()){ csDriverDescription.Load(hInf, m_csInstallSection, DESCRIPTION); if(!csDriverDescription.IsEmpty()){ m_csDriverDescription = csDriverDescription; if(TRUE != NameDefaultUniqueName()){ //
// Unable to generate FriendlyName.
//
bRet = FALSE; goto ProcessInf_return; } // if(TRUE != NameDefaultUniqueName())
} // if(!m_csDriverDescription.IsEmpty())
} // if(!IsMigration())
csCapabilities.Load (hInf, m_csInstallSection, CAPABILITIES); csDeviceType.Load (hInf, m_csInstallSection, DEVICETYPE); csDeviceSubType.Load (hInf, m_csInstallSection, DEVICESUBTYPE);
m_dwCapabilities = csCapabilities.Decode(); m_dwDeviceType = csDeviceType.Decode(); m_dwDeviceSubType = csDeviceSubType.Decode();
DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: --------------- INF parameters --------------- \r\n"))); DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: Description : %ws\n"), (LPTSTR)m_csDriverDescription)); DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: SubClass : %ws\n"), (LPTSTR)m_csSubClass)); DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: USDClass : %ws\n"), (LPTSTR)m_csUSDClass)); DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: EventSection : %ws\n"), (LPTSTR)m_csEventSection)); DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: Connection : %ws\n"), (LPTSTR)m_csConnection)); DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: IcmProfile : %ws\n"), (LPTSTR)m_csIcmProfile)); DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: PropPages : %ws\n"), (LPTSTR)m_csPropPages)); DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: DataSection : %ws\n"), (LPTSTR)m_csDataSection)); DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: UninstallSection : %ws\n"), (LPTSTR)m_csUninstallSection)); DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: Capabilities : 0x%x\n"), m_dwCapabilities)); DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: DeviceType : 0x%x\n"), m_dwDeviceType)); DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: DeviceSubType : 0x%x\n"), m_dwDeviceSubType));
//
// Set video device flag if applicable.
//
if(StiDeviceTypeStreamingVideo == m_dwDeviceType){ DebugTrace(TRACE_STATUS,(("CDevice::PreprocessInf: This is video device.\r\n"))); m_bVideoDevice = TRUE; } else { m_bVideoDevice = FALSE; }
//
// Operation succeeded.
//
bRet = TRUE; m_bInfProceeded = TRUE;
ProcessInf_return:
if(IS_VALID_HANDLE(hInf)){ SetupCloseInfFile(hInf); hInf = INVALID_HANDLE_VALUE; } // if(IS_VALID_HANDLE(hInf))
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::PreprocessInf: Leaving... Ret=0x%x \r\n"), bRet)); return bRet; } // CDevice::PreprocessInf()
BOOL CDevice::PreInstall( VOID ) { BOOL bRet; HKEY hkDrv; GUID Guid; HDEVINFO hDevInfo; SP_DEVINFO_DATA spDevInfoData; SP_DEVICE_INTERFACE_DATA spDevInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA pspDevInterfaceDetailData; BOOL bUseDefaultDevInfoSet; DWORD dwRequiredSize;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::PreInstall: Enter... \r\n")));
//
// Initialize local.
//
bRet = FALSE;
//
// Get all INF parameter.
//
if(!PreprocessInf()){ DebugTrace(TRACE_ERROR,(("CDevice::PreInstall: ERROR!! Unable to process INF.\r\n")));
bRet = FALSE; goto PreInstall_return; }
/**************************************
if(!IsInterfaceOnlyDevice()){
//
// Register device if it's getting manually installed and not "interface-only" device..
//
if(!IsPnpDevice()){ if (!SetupDiRegisterDeviceInfo(m_hDevInfo, m_pspDevInfoData, 0, NULL, NULL, NULL)) { DebugTrace(TRACE_ERROR,(("CDevice::PreInstall: SetupDiRegisterDeviceInfo failed. Err=0x%x.\r\n"),GetLastError()));
bRet = FALSE; goto PreInstall_return; } } // if(!IsPnpDevice())
} // if(IsInterfaceOnlyDevice())
**************************************/
//
// Clean up.
//
//
// Operation succeeded.
//
bRet = TRUE;
PreInstall_return: DebugTrace(TRACE_PROC_LEAVE,(("CDevice::PreInstall: Leaving... Ret=0x%x.\r\n"), bRet)); return bRet; }
BOOL CDevice::PostInstall( BOOL bSucceeded ) { BOOL bRet; HKEY hkRun; HKEY hkDrv; DWORD dwFlagPresent; CString csInfFilename; CString csInfSection; GUID Guid; HKEY hkNameStore;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::PostInstall: Enter... \r\n")));
//
// Initialize local.
//
bRet = FALSE; hkRun = NULL; dwFlagPresent = 1; Guid = GUID_DEVCLASS_IMAGE; hkNameStore = (HKEY)INVALID_HANDLE_VALUE;
if(IsFeatureInstallation()){
//
// This is a "feature" added to other class devnode and being installed by co-isntaller.
// Need to do actual installation here only for "feature", manual installed device would
// be installed through wizard. (final.cpp)
//
bRet = Install(); if(FALSE == bRet){ DebugTrace(TRACE_ERROR,(("CDevice::PostInstall: device interface registry key creation failed. \r\n"))); bSucceeded = FALSE; } //if(FALSE == bRet)
} // if(IsFeatureInstallation())
if(!bSucceeded){
HDEVINFO hDevInfo; SP_DEVICE_INTERFACE_DATA spDevInterfaceData; DWORD dwIndex;
//
// Installation failed. Do clean up.
//
DebugTrace(TRACE_STATUS,(("CDevice::PostInstall: Installation failed. Do clean up.\r\n")));
//
// Delete craeted interface if any.
//
if(IsInterfaceOnlyDevice()){ hDevInfo = GetDeviceInterfaceIndex(m_csDeviceID, &dwIndex); if(IS_VALID_HANDLE(hDevInfo)){ spDevInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); if(SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &Guid, dwIndex, &spDevInterfaceData)){
//
// Created Interface is found. Delete it...
//
DebugTrace(TRACE_STATUS,(("CDevice::PostInstall: Deleting created interface for %ws.\r\n"), (LPTSTR)m_csFriendlyName));
if(!SetupDiRemoveDeviceInterface(hDevInfo, &spDevInterfaceData)){ DebugTrace(TRACE_ERROR,(("CDevice::PostInstall: ERROR!! Unable to delete interface for %ws. Err=0x%x\n"), m_csFriendlyName, GetLastError())); } } // if(SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &Guid, dwIndex, &spDevInterfaceData))
//
// Destroy created DevInfoSet.
//
SetupDiDestroyDeviceInfoList(hDevInfo); } // if(NULL != hDevInfo)
} // if(IsInterfaceOnlyDevice())
bRet = TRUE; goto PostInstall_return;
} // if(!bSucceeded)
//
// Save all Inf parameters to registry.
//
if(!UpdateDeviceRegistry()){ DebugTrace(TRACE_ERROR,(("CDevice::PostInstall: ERROR!! UpdateDeviceRegistry() failed. \r\n"))); }
//
// Do WIA/STI device only process.
//
if( (!m_csSubClass.IsEmpty()) && (0 == MyStrCmpi(m_csSubClass, STILL_IMAGE)) ) {
HKEY hkeyTemp;
//
// Change service to AUTO start.
//
SetServiceStart(STI_SERVICE_NAME, SERVICE_AUTO_START);
//
// Start WIA service.
//
if(!StartWiaService()){ // DebugTrace(TRACE_ERROR,(("CDevice::PostInstall: ERROR!! Unable to start WIA service.\r\n")));
}
//
// Create "Scanner and Camera Wizard" menu if WIA.
//
if(m_dwCapabilities & STI_GENCAP_WIA){
CreateWiaShortcut();
//
// Add following value upon device arrival for performance improvement.
//
if (ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGKEY_WIASHEXT, &hkeyTemp)) { RegSetValue (hkeyTemp, NULL, REG_SZ, REGSTR_VAL_WIASHEXT, lstrlen(REGSTR_VAL_WIASHEXT) * sizeof(TCHAR)); RegCloseKey(hkeyTemp); hkeyTemp = NULL; } else { DebugTrace(TRACE_ERROR,(("CDevice::PostInstall: ERROR!! RegOpenKey(WIASHEXT) failed. Err=0x%x \r\n"), GetLastError())); } // if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SOFT_STI, &hkRun))
} // if(m_dwCapabilities & STI_GENCAP_WIA)
//
// Also add shell's flag about WIA device presence, this should be portable
// to NT
//
if (ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SOFT_STI, &hkRun)) { RegDeleteValue (hkRun, REGSTR_VAL_WIA_PRESENT); RegSetValueEx (hkRun, REGSTR_VAL_WIA_PRESENT, 0, REG_DWORD, (LPBYTE)&dwFlagPresent, sizeof(DWORD)); } else { DebugTrace(TRACE_ERROR,(("CDevice::PostInstall: ERROR!! RegOpenKey() failed. Err=0x%x \r\n"), GetLastError())); } // if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_SOFT_STI, &hkRun))
//
// Notify WIA service device arrival
//
WiaDeviceEnum(); } // if(!lstrcmpi(m_csSubClass, STILL_IMAGE))
//
// ICM support
//
ProcessICMProfiles();
//
// Register interface name of Videoo device.
//
bRet = TRUE;
PostInstall_return:
//
// Clean up.
//
if(NULL != hkRun){ RegCloseKey(hkRun); }
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::PostInstall: Leaving... Ret=0x%x.\r\n"), bRet)); return bRet; } // CDevice::PostInstall()
BOOL CDevice::HandleFilesInstallation( VOID ) /*++
Routine Description:
Arguments:
Return Value:
Side effects:
--*/ {
BOOL bRet; BOOL bSetParamRet; PSP_FILE_CALLBACK pSavedCallback; PVOID pvContext; SP_DEVINSTALL_PARAMS spDeviceInstallParams;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::HandleFilesInstallation: Enter... \r\n")));
//
// Initialize local.
//
bRet = FALSE; bSetParamRet = FALSE; pvContext = NULL; pSavedCallback = NULL;
memset(&spDeviceInstallParams, 0, sizeof(spDeviceInstallParams));
//
// Get device install parameter.
//
spDeviceInstallParams.cbSize = sizeof (SP_DEVINSTALL_PARAMS); if (!SetupDiGetDeviceInstallParams (m_hDevInfo, m_pspDevInfoData, &spDeviceInstallParams)) { DebugTrace(TRACE_ERROR,(("CDevice::HandleFilesInstallation: ERROR!! SetupDiGetDeviceInstallParams() failed. Err=0x%x.\r\n"), GetLastError()));
bRet = FALSE; goto HandleFilesInstallation_return; }
//
// Modify device installation parameters to have custom callback
//
pvContext = SetupInitDefaultQueueCallbackEx(NULL, (HWND)((spDeviceInstallParams.Flags & DI_QUIETINSTALL) ?INVALID_HANDLE_VALUE : NULL), 0, 0, NULL); if(NULL == pvContext){
DebugTrace(TRACE_ERROR,(("CDevice::HandleFilesInstallation: ERROR!! SetupInitDefaultQueueCallbackEx() failed. Err=0x%x.\r\n"), GetLastError()));
bRet = FALSE; goto HandleFilesInstallation_return; } // if(NULL == pvContext)
pSavedCallback = spDeviceInstallParams.InstallMsgHandler; spDeviceInstallParams.InstallMsgHandler = StiInstallCallback; spDeviceInstallParams.InstallMsgHandlerContext = pvContext;
bSetParamRet = SetupDiSetDeviceInstallParams (m_hDevInfo, m_pspDevInfoData, &spDeviceInstallParams);
if(FALSE == bSetParamRet){ DebugTrace(TRACE_ERROR,(("CDevice::HandleFilesInstallation: ERROR!! SetupDiSetDeviceInstallParams() failed. Err=0x%x.\r\n"), GetLastError()));
bRet = FALSE; goto HandleFilesInstallation_return; } // if(FALSE == bSetParamRet)
//
// Let the default installer do its job.
//
if(IsInterfaceOnlyDevice()){ bRet = CreateDeviceInterfaceAndInstall(); } else { bRet = SetupDiInstallDevice(m_hDevInfo, m_pspDevInfoData); } if(FALSE == bRet){ DebugTrace(TRACE_ERROR,(("CDevice::HandleFilesInstallation: ERROR!! SetupDiInstallDevice() failed. Err=0x%x.\r\n"), GetLastError()));
bRet = FALSE; goto HandleFilesInstallation_return; } // if(FALSE == bSetParamRet)
//
// Terminate defaule queue callback
//
SetupTermDefaultQueueCallback(pvContext);
//
// Cleanup.
//
if (bSetParamRet) { spDeviceInstallParams.InstallMsgHandler = pSavedCallback; SetupDiSetDeviceInstallParams (m_hDevInfo, m_pspDevInfoData, &spDeviceInstallParams); }
HandleFilesInstallation_return:
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::HandleFilesInstallation: Leaving... Ret=0x%x.\r\n"), bRet)); return bRet;
} // CDevice::HandleFilesInstallation()
BOOL CDevice::UpdateDeviceRegistry( VOID ) { BOOL bRet; HKEY hkDrv; DWORD dwConnectionType; HINF hInf;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::UpdateDeviceRegistry: Enter... \r\n")));
//
// Initialize Local.
//
bRet = FALSE; hkDrv = NULL; dwConnectionType = STI_HW_CONFIG_UNKNOWN;
//
// Open INF.
//
hInf = SetupOpenInfFile(m_csInf, NULL, INF_STYLE_WIN4, NULL);
if (hInf == INVALID_HANDLE_VALUE) { DebugTrace(TRACE_ERROR, (("CDevice::UpdateDeviceRegistry: Unable to open INF(%ws). Error = 0x%x.\r\n"),m_csInf, GetLastError()));
bRet = FALSE; goto UpdateDeviceRegistry_return; } // if (hInf == INVALID_HANDLE_VALUE)
//
// Create device registry key.
//
if(IsInterfaceOnlyDevice()){
DebugTrace(TRACE_STATUS,(("CDevice::UpdateDeviceRegistry: This is Interface-only device.\r\n")));
//
// Create interface reg-key.
//
hkDrv = m_hkInterfaceRegistry;
} else { // if(IsInterfaceOnlyDevice())
DebugTrace(TRACE_STATUS,(("CDevice::UpdateDeviceRegistry: This is devnode device.\r\n")));
hkDrv = SetupDiCreateDevRegKey(m_hDevInfo, m_pspDevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, NULL, NULL); } // if(IsInterfaceOnlyDevice())
if(hkDrv == INVALID_HANDLE_VALUE) { DebugTrace(TRACE_ERROR,(("CDevice::UpdateDeviceRegistry: ERROR!! SetupDiCreateDevRegKey() failed. Err=0x%x.\r\n"), GetLastError()));
bRet = FALSE; goto UpdateDeviceRegistry_return; } //if(hkDrv == INVALID_HANDLE_VALUE)
//
// Save INF parameters to registry.
//
if(m_csPort.IsEmpty()){ if(m_bInterfaceOnly){
//
// If PortName doesn't exist for interface-only device, then use symbolic link as CraeteFile name.
//
m_csSymbolicLink.Store(hkDrv, CREATEFILENAME); } //if(m_bInterfaceOnly)
} else { // if(m_csPort.IsEmpty())
m_csPort.Store(hkDrv, CREATEFILENAME); } // if(m_csPort.IsEmpty())
m_csSubClass.Store(hkDrv, SUBCLASS); m_csUSDClass.Store(hkDrv, USDCLASS); m_csVendor.Store(hkDrv, VENDOR); m_csFriendlyName.Store(hkDrv, FRIENDLYNAME); m_csUninstallSection.Store(hkDrv, UNINSTALLSECTION); m_csPropPages.Store(hkDrv, PROPERTYPAGES); m_csIcmProfile.Store(hkDrv, ICMPROFILES); m_csDeviceID.Store(hkDrv, REGSTR_VAL_DEVICE_ID); m_csPortSelect.Store (hkDrv, PORTSELECT);
if(IsInterfaceOnlyDevice()){ m_csInf.Store(hkDrv, INFPATH); m_csInstallSection.Store(hkDrv, INFSECTION); m_csDriverDescription.Store(hkDrv, DRIVERDESC); } // if(IsInterfaceOnlyDevice())
//
// Save DWORD values.
//
RegSetValueEx(hkDrv, CAPABILITIES, 0, REG_DWORD, (LPBYTE) &m_dwCapabilities, sizeof(m_dwCapabilities));
RegSetValueEx(hkDrv, DEVICETYPE, 0, REG_DWORD, (LPBYTE) &m_dwDeviceType, sizeof(m_dwDeviceType));
RegSetValueEx(hkDrv, DEVICESUBTYPE, 0, REG_DWORD, (LPBYTE) &m_dwDeviceSubType, sizeof(m_dwDeviceSubType));
RegSetValueEx(hkDrv, ISPNP, 0, REG_DWORD, (LPBYTE) &m_bIsPnP, sizeof(m_bIsPnP));
//
// Set HardwareConfig. (= Connection)
//
if(!m_csConnection.IsEmpty()){
m_csConnection.Store (hkDrv, CONNECTION);
if(_tcsicmp(m_csConnection, SERIAL) == 0 ){ dwConnectionType = STI_HW_CONFIG_SERIAL; } else if(_tcsicmp(m_csConnection, PARALLEL) == 0 ){ dwConnectionType = STI_HW_CONFIG_PARALLEL; }
if (dwConnectionType != STI_HW_CONFIG_UNKNOWN) { RegSetValueEx(hkDrv, REGSTR_VAL_HARDWARE, 0, REG_DWORD, (LPBYTE) &dwConnectionType, sizeof(dwConnectionType)); } } // if(!m_csConneciton.IsEmpty())
//
// Process DeviceData section.
//
ProcessDataSection(hInf, hkDrv);
//
// Process Event section.
//
ProcessEventsSection(hInf, hkDrv);
//
// Create registry key for video key if applicable.
//
ProcessVideoDevice(hkDrv);
//
// Operation succeeded.
//
bRet = TRUE;
UpdateDeviceRegistry_return:
//
// Cleanup.
//
if(hkDrv != INVALID_HANDLE_VALUE){ RegCloseKey(hkDrv); m_hkInterfaceRegistry = NULL; }
if(hInf != INVALID_HANDLE_VALUE){ SetupCloseInfFile(hInf); }
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::UpdateDeviceRegistry: Leaving... Ret=0x%x.\r\n"), bRet)); return bRet; } // CDevice::UpdateDeviceRegistry()
VOID CDevice::ProcessVideoDevice( HKEY hkDrv ) {
GUID Guid; HKEY hkDeviceData; TCHAR Buffer[1024]; SP_DEVICE_INTERFACE_DATA spDevInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA pspDevInterfaceDetail;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::ProcessVideoDevice: Enter... \r\n")));
//
// Initialize local.
//
Guid = KSCATEGORY_CAPTURE; pspDevInterfaceDetail = NULL; hkDeviceData = NULL;
memset(&spDevInterfaceData, 0, sizeof(spDevInterfaceData)); memset(Buffer, 0, sizeof(Buffer));
//
// This is only for video devices.
//
if (!m_bVideoDevice) { DebugTrace(TRACE_STATUS,(("CDevice::ProcessVideoDevice: This is not a video device. Do nothing.\r\n"))); goto ProcessVideoDevice_return; }
//
// Use "AUTO" as dummy CreatFile name for Video devices.
//
RegSetValueEx( hkDrv, CREATEFILENAME, 0, REG_SZ, (LPBYTE)AUTO, (lstrlen(AUTO)+1)*sizeof(TCHAR) );
//
// Get device interface data of installing Video device.
//
spDevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if (!SetupDiEnumDeviceInterfaces (m_hDevInfo, m_pspDevInfoData, &Guid, 0, &spDevInterfaceData ) ) { DebugTrace(TRACE_ERROR,(("ProcessVideoDevice: ERROR!!SetupDiEnumDeviceInterfaces failed. Err=0x%x \r\n"), GetLastError())); goto ProcessVideoDevice_return; }
//
// Get detailed data of acquired interface.
//
pspDevInterfaceDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)Buffer; pspDevInterfaceDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail (m_hDevInfo, &spDevInterfaceData, pspDevInterfaceDetail, sizeof(Buffer) - sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA), NULL, NULL) ) { DebugTrace(TRACE_ERROR,(("ProcessVideoDevice: ERROR!!SetupDiGetDeviceInterfaceDetail failed. Err=0x%x \r\n"), GetLastError())); goto ProcessVideoDevice_return; }
//
// We got the device path, now write it to registry
//
if (ERROR_SUCCESS != RegOpenKey(hkDrv, DEVICESECTION, &hkDeviceData)) { DebugTrace(TRACE_ERROR,(("ProcessVideoDevice: ERROR!! Unable to open DeviceData key. Err=0x%x \r\n"), GetLastError())); goto ProcessVideoDevice_return; }
RegSetValueEx(hkDeviceData, VIDEO_PATH_ID, 0, REG_SZ, (LPBYTE)pspDevInterfaceDetail->DevicePath, (lstrlen(pspDevInterfaceDetail->DevicePath)+1)*sizeof(TCHAR) );
ProcessVideoDevice_return:
//
// Cleanup.
//
if(NULL != hkDeviceData){ RegCloseKey(hkDeviceData); }
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::ProcessVideoDevice: Leaving... Ret=VOID.\r\n"))); return; } // CDevice::ProcessVideoDevice()
VOID CDevice::ProcessEventsSection( HINF hInf, HKEY hkDrv ) /*++
Routine Description:
Arguments:
Return Value:
Side effects:
--*/ {
CString csFriendlyName; CString csRegisteredApp; CString csGuid;
HKEY hkEvents; HKEY hkEventPod;
INFCONTEXT InfContext; UINT uiLineIndex = 0;
BOOL fRet = TRUE; BOOL fLooping = TRUE;
TCHAR pKeyName[LINE_LEN ]; TCHAR pField [MAX_INF_STRING_LENGTH]; TCHAR pTypeField[LINE_LEN];
DWORD dwKeySize = LINE_LEN; DWORD dwFieldSize = MAX_INF_STRING_LENGTH;
DWORD dwError = 0; DWORD dwFieldIndex = 0;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::ProcessEventsSection: Enter... \r\n")));
if (!m_csEventSection.IsEmpty()) {
// First create device data subkey
dwError = RegCreateKey(hkDrv, EVENTS, &hkEvents);
if ( NOERROR == dwError ) {
fLooping = SetupFindFirstLine(hInf, (LPCTSTR) m_csEventSection, NULL, &InfContext ); while (fLooping) {
::ZeroMemory(pKeyName, sizeof(pKeyName)); ::ZeroMemory(pField, sizeof(pField)); ::ZeroMemory(pTypeField, sizeof(pTypeField) );
// Get key name as zero-based indexed field
dwFieldIndex = 0; dwKeySize = sizeof(pKeyName) / sizeof(TCHAR);
fRet = SetupGetStringField(&InfContext, dwFieldIndex, pKeyName, dwKeySize, NULL);
dwError = ::GetLastError(); if (!fRet) { // Didn't get key name - move to the next
DebugTrace(TRACE_ERROR,(("CDevice::ProcessEventsSection: ERROR!! Failed to get key name. Error=0x%x. \r\n"), dwError)); fLooping = SetupFindNextLine(&InfContext,&InfContext); continue; }
// Get friendly name field
dwFieldIndex = 1; dwFieldSize = sizeof(pField) / sizeof(TCHAR);
fRet = SetupGetStringField(&InfContext, dwFieldIndex, pField, dwFieldSize, NULL);
dwError = ::GetLastError(); if (!fRet ) { // Didn't get name - move to the next
DebugTrace(TRACE_ERROR,(("CDevice::ProcessEventsSection: ERROR!! Failed to get field [%d]. Error=0x%x. \r\n"), dwFieldIndex, dwError)); fLooping = SetupFindNextLine(&InfContext,&InfContext); continue; }
csFriendlyName = pField;
// Get GUID field
dwFieldIndex = 2; dwFieldSize = sizeof(pField) / sizeof(TCHAR);
fRet = SetupGetStringField(&InfContext, dwFieldIndex, pField, dwFieldSize, NULL);
dwError = ::GetLastError(); if (!fRet ) { // Didn't get GUID - move to the next line
DebugTrace(TRACE_ERROR,(("CDevice::ProcessEventsSection: ERROR!! Failed to get field [%d]. Error=0x%x. \r\n"), dwFieldIndex, dwError)); fLooping = SetupFindNextLine(&InfContext,&InfContext); continue; }
csGuid = pField;
// Get registered app field
dwFieldIndex = 3; dwFieldSize = sizeof(pField) / sizeof(TCHAR);
fRet = SetupGetStringField(&InfContext, 3, pField, dwFieldSize, NULL);
dwError = ::GetLastError(); if (fRet ) { DebugTrace(TRACE_ERROR,(("CDevice::ProcessEventsSection: ERROR!! Failed to get field [%d]. Error=0x%x. \r\n"), dwFieldIndex, dwError)); csRegisteredApp = pField; } else { // Didn't get key type - use widlcard by default
csRegisteredApp = TEXT("*"); }
// Now only if we have all needed values - save to the registry
if (RegCreateKey(hkEvents, pKeyName, &hkEventPod) == NO_ERROR) {
// Event friendly name store as default value
csFriendlyName.Store (hkEventPod, TEXT(""));
csGuid.Store (hkEventPod, SZ_GUID);
csRegisteredApp.Store (hkEventPod, LAUNCH_APP);
RegCloseKey (hkEventPod); } else { // Couldn't create event key - bad
DebugTrace(TRACE_ERROR,(("CDevice::ProcessEventsSection: ERROR!! Unable to create RegKey. Error=0x%x.\r\n"), GetLastError())); }
// Move to the next line finally
fLooping = SetupFindNextLine(&InfContext,&InfContext); }
RegCloseKey (hkEvents);
} else { DebugTrace(TRACE_ERROR,(("CDevice::ProcessEventsSection: ERROR!! Unable to create event RegKey. Error=0x%x.\r\n"), GetLastError())); } } // ProcessEventsSection_return:
//
// Cleanup.
//
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::ProcessEventsSection: Leaving... Ret=VOID.\r\n"))); return; } // CDevice::ProcessEventsSection()
VOID CDevice::ProcessDataSection( HINF hInf, HKEY hkDrv ) /*++
Routine Description:
Arguments:
Return Value:
Side effects:
--*/ { CString csTempValue; HKEY hkDeviceData;
INFCONTEXT InfContext;
UINT uiLineIndex = 0;
BOOL fRet = TRUE; BOOL fLooping = TRUE;
TCHAR pKeyName[LINE_LEN ]; TCHAR pField [MAX_INF_STRING_LENGTH]; TCHAR pTypeField[LINE_LEN];
// Sizes are in characters
DWORD dwKeySize = LINE_LEN; DWORD dwFieldSize = MAX_INF_STRING_LENGTH;
DWORD dwError = 0; DWORD dwFieldIndex = 0;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::ProcessDataSection: Enter... \r\n")));
if (!m_csDataSection.IsEmpty()) {
// First create device data subkey
dwError = RegCreateKey(hkDrv, DEVICESECTION, &hkDeviceData);
if ( NOERROR == dwError ) {
// Seek to the first line of the section
fLooping = SetupFindFirstLine(hInf, (LPCTSTR) m_csDataSection, NULL, &InfContext);
while (fLooping) {
dwKeySize = sizeof(pKeyName) / sizeof(TCHAR);
::ZeroMemory(pKeyName, sizeof(pKeyName)); ::ZeroMemory(pField, sizeof(pField)); ::ZeroMemory(pTypeField, sizeof(pTypeField) );
dwFieldIndex = 0;
// Get key name as zero-indexed field
fRet = SetupGetStringField(&InfContext, dwFieldIndex, pKeyName, dwKeySize, &dwKeySize);
dwError = ::GetLastError(); if (!fRet) { // Didn't get key name - move to the next
DebugTrace(TRACE_ERROR, (("CDevice::ProcessDataSection: Failed to get key name. Error = 0x%x.\r\n"),dwError)); fLooping = SetupFindNextLine(&InfContext,&InfContext); continue; }
// Get value field
dwFieldIndex = 1; dwFieldSize = sizeof(pField) / sizeof(TCHAR);
fRet = SetupGetStringField(&InfContext, dwFieldIndex, pField, dwFieldSize, NULL);
dwError = ::GetLastError(); if (!fRet ) { // Didn't get key name - move to the next
DebugTrace(TRACE_ERROR, (("CDevice::ProcessDataSection: Failed to get field [%d]. Error = 0x%x.\r\n"),dwFieldIndex, dwError)); fLooping = SetupFindNextLine(&InfContext,&InfContext); continue; }
csTempValue = pField; // Get value field
*pTypeField = TEXT('\0'); dwFieldIndex = 2; dwFieldSize = sizeof(pTypeField) / sizeof(TCHAR);
fRet = SetupGetStringField(&InfContext, dwFieldIndex, pTypeField, dwFieldSize, NULL);
dwError = ::GetLastError(); if (!fRet ) { // Didn't get key type - assume string
*pTypeField = TEXT('\0'); }
// Now we have both type and value - save it in the registry
csTempValue.Store (hkDeviceData, pKeyName,pTypeField );
// Move to the next line finally
fLooping = SetupFindNextLine(&InfContext,&InfContext); }
//
// Process migrating DeviceData section.
//
MigrateDeviceData(hkDeviceData, m_pExtraDeviceData, "");
// Now clean up
RegCloseKey (hkDeviceData);
} else { // if ( NOERROR == dwError )
DebugTrace(TRACE_ERROR, (("CDevice::ProcessDataSection: ERROR!! Unable to create DataSection RegKey. Error = 0x%x.\r\n"), dwError)); } // if ( NOERROR == dwError )
} // if (!m_csDataSection.IsEmpty())
// ProcessDataSection_return:
//
// Cleanup.
//
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::ProcessDataSection: Leaving... Ret=VOID.\r\n"))); return; } // CDevice::ProcessDataSection()
VOID CDevice::ProcessICMProfiles( VOID ) /*++
Routine Description:
Arguments:
Return Value:
Side effects:
--*/ {
DWORD Idx; CStringArray csaICMProfiles; TCHAR szAnsiName[STI_MAX_INTERNAL_NAME_LENGTH];
DebugTrace(TRACE_PROC_ENTER,(("CDevice::ProcessICMProfiles: Enter... \r\n")));
//
// Initialize Local.
//
Idx = 0;
memset(szAnsiName, 0, sizeof(szAnsiName));
//
// If section doesn't exist, just return.
//
if(m_csIcmProfile.IsEmpty()){ goto ProcessICMProfiles_return; }
//
// Split a line to each token.
//
csaICMProfiles.Tokenize ((LPTSTR)m_csIcmProfile, FIELD_DELIMETER);
//
// Process all ICM profiles.
//
while ((LPTSTR)csaICMProfiles[Idx] != NULL) {
DebugTrace(TRACE_STATUS,(("ProcessICMProfiles: Installing ICM profile%d(%ws) for %ws.\r\n"), Idx, (LPTSTR)csaICMProfiles[Idx], (LPTSTR)m_csDeviceID));
//
// Install color profile.
//
if (!InstallColorProfile (NULL, csaICMProfiles[Idx])) { DebugTrace(TRACE_ERROR,(("ProcessICMProfiles: ERROR!! InstallColorProfile failed. Err=0x%x \r\n"), GetLastError())); } // if (!InstallColorProfile (NULL, csaICMProfiles[Idx]))
//
// Register color profile with installing device.
//
if (!AssociateColorProfileWithDevice (NULL, csaICMProfiles[Idx], (LPTSTR)m_csDeviceID)) { DebugTrace(TRACE_ERROR,(("ProcessICMProfiles: ERROR!! AssociateColorProfileWithDevice failed. Err=0x%x \r\n"), GetLastError())); }
//
// Process next device.
//
Idx++;
} // while ((LPTSTR)csaICMProfiles[Idx] != NULL)
ProcessICMProfiles_return: return;
} // CDevice::ProcessICMProfiles()
BOOL CDevice::GetInfInforamtion( VOID ) { BOOL bRet;
HINF hInf; SP_DRVINFO_DATA DriverInfoData; PSP_DRVINFO_DETAIL_DATA pDriverInfoDetailData; TCHAR szInfSectionName[MAX_DESCRIPTION]; DWORD dwSize; DWORD dwLastError;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::GetInfInforamtion: Enter... \r\n")));
//
// Initialize locals.
//
dwSize = 0; bRet = FALSE; hInf = INVALID_HANDLE_VALUE; dwLastError = ERROR_SUCCESS; pDriverInfoDetailData = NULL;
memset (szInfSectionName, 0, sizeof(szInfSectionName)); memset (&DriverInfoData, 0, sizeof(SP_DRVINFO_DATA));
//
// Get selected device driver information.
//
DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA); if (!SetupDiGetSelectedDriver(m_hDevInfo, m_pspDevInfoData, &DriverInfoData)) { DebugTrace(TRACE_ERROR,(("CDevice::GetInfInforamtion: ERROR!! SetupDiGetSelectedDriver Failed. Err=0x%x\r\n"), GetLastError()));
bRet = FALSE; goto GetInfInforamtion_return; }
//
// See required buffer size for driver detailed data.
//
SetupDiGetDriverInfoDetail(m_hDevInfo, m_pspDevInfoData, &DriverInfoData, NULL, 0, &dwSize); dwLastError = GetLastError(); if(ERROR_INSUFFICIENT_BUFFER != dwLastError){ DebugTrace(TRACE_ERROR,(("CDevice::GetInfInforamtion: ERROR!! SetupDiGetDriverInfoDetail doesn't return required size.Er=0x%x\r\n"),dwLastError));
bRet = FALSE; goto GetInfInforamtion_return; }
//
// Allocate required size of buffer for driver detailed data.
//
pDriverInfoDetailData = (PSP_DRVINFO_DETAIL_DATA)new char[dwSize]; if(NULL == pDriverInfoDetailData){ DebugTrace(TRACE_ERROR,(("CDevice::GetInfInforamtion: ERROR!! Unable to allocate driver detailed info buffer.\r\n")));
bRet = FALSE; goto GetInfInforamtion_return; }
//
// Initialize allocated buffer.
//
memset(pDriverInfoDetailData, 0, dwSize); pDriverInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
//
// Get detailed data of selected device driver.
//
if(!SetupDiGetDriverInfoDetail(m_hDevInfo, m_pspDevInfoData, &DriverInfoData, pDriverInfoDetailData, dwSize, NULL) ) { DebugTrace(TRACE_ERROR,(("CDevice::GetInfInforamtion: ERROR!! SetupDiGetDriverInfoDetail Failed.Er=0x%x\r\n"),GetLastError()));
bRet = FALSE; goto GetInfInforamtion_return; }
//
// Open INF file of selected driver.
//
hInf = SetupOpenInfFile(pDriverInfoDetailData->InfFileName, NULL, INF_STYLE_WIN4, NULL); if (hInf == INVALID_HANDLE_VALUE) { DebugTrace(TRACE_ERROR,(("CDevice::GetInfInforamtion: ERROR!! SetupOpenInfFile Failed.Er=0x%x\r\n"),GetLastError()));
bRet = FALSE; goto GetInfInforamtion_return; }
//
// Get actual INF section name to be installed.
//
if (!SetupDiGetActualSectionToInstall(hInf, pDriverInfoDetailData->SectionName, szInfSectionName, sizeof(szInfSectionName)/sizeof(TCHAR), NULL, NULL) ) { DebugTrace(TRACE_ERROR,(("CDevice::GetInfInforamtion: ERROR!! SetupDiGetActualSectionToInstall Failed.Er=0x%x\r\n"),GetLastError()));
bRet = FALSE; goto GetInfInforamtion_return; }
//
// Set Inf section/file name.
//
m_csInf = pDriverInfoDetailData->InfFileName; m_csInstallSection = szInfSectionName;
DebugTrace(TRACE_STATUS,(("CDevice::GetInfInforamtion: INF Filename : %ws\n"),(LPTSTR)m_csInf)); DebugTrace(TRACE_STATUS,(("CDevice::GetInfInforamtion: INF Section name: %ws\n"),(LPTSTR)m_csInstallSection));
//
// Operation succeeded.
//
bRet = TRUE;
GetInfInforamtion_return:
//
// Clean up.
//
if(INVALID_HANDLE_VALUE != hInf){ SetupCloseInfFile(hInf); }
if(NULL != pDriverInfoDetailData){ delete[] pDriverInfoDetailData; }
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::GetInfInforamtion: Leaving... Ret=0x%x\n"), bRet)); return bRet; } // CDevice::GetInfInforamtion()
VOID CDevice::SetPort( LPTSTR szPortName ) { DebugTrace(TRACE_STATUS,(("CDevice::SetPort: Current Portname=%ws\n"), szPortName));
//
// Set PortName.
//
m_csPort = szPortName;
} // CDevice::SetPort()
VOID CDevice::SetFriendlyName( LPTSTR szFriendlyName ) //
// Note:
// Before calling this function, caller has to make sure mutex is acquired.
//
{ HKEY hkNameStore;
//
// Mutex must have been acquired before this call.
//
DebugTrace(TRACE_STATUS,(("CDevice::SetFriendlyName: Current CreateFileName=%ws\n"), szFriendlyName));
//
// Delete stored entry, create new one.
//
if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore)){ HKEY hkTemp;
hkTemp = (HKEY)INVALID_HANDLE_VALUE; //
// Delete FriendlyName and DeviceId in name store.
//
RegDeleteKey(hkNameStore, m_csFriendlyName); if(ERROR_SUCCESS == RegCreateKey(hkNameStore, szFriendlyName, &hkTemp)){ RegCloseKey(hkTemp); } // if(ERROR_SUCCESS == RegCreateKey(hkNameStore, szFriendlyName, &hkTemp))
RegCloseKey(hkNameStore); } // if(ERROR_SUCCESS == RegCreateKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore))
//
// Set PortName.
//
m_csFriendlyName = szFriendlyName;
} // CDevice::SetPort()
VOID CDevice::SetDevnodeSelectCallback( DEVNODESELCALLBACK pfnDevnodeSelCallback ) { DebugTrace(TRACE_STATUS,(("CDevice::SetDevnodeSelectCallback: Current PortselCallback=0x%x\n"), pfnDevnodeSelCallback));
//
// Set SetPortselCallBack.
//
m_pfnDevnodeSelCallback = pfnDevnodeSelCallback;
//
// This is "interface-only" device.
//
m_bInterfaceOnly = TRUE;
} // CDevice::SetDevnodeSelectCallback()
BOOL CDevice::CreateDeviceInterfaceAndInstall( VOID ) { BOOL bRet; HKEY hkDrv; GUID Guid; HDEVINFO hDevInfo; SP_DEVINFO_DATA spDevInfoData; SP_DEVICE_INTERFACE_DATA spDevInterfaceData; PSP_DEVICE_INTERFACE_DETAIL_DATA pspDevInterfaceDetailData; HINF hInf; BOOL bUseDefaultDevInfoSet; DWORD dwRequiredSize;
DebugTrace(TRACE_PROC_ENTER,(("CDevice::CreateDeviceInterfaceAndInstall: Enter....\r\n")));
//
// Initialize local.
//
bRet = FALSE; hInf = INVALID_HANDLE_VALUE; hDevInfo = INVALID_HANDLE_VALUE; Guid = GUID_DEVCLASS_IMAGE; bUseDefaultDevInfoSet = TRUE; dwRequiredSize = 0; pspDevInterfaceDetailData = NULL;
//
// Get devnode to create interface on.
//
if(NULL != m_pfnDevnodeSelCallback){ if( (FALSE == m_pfnDevnodeSelCallback(m_csPort, &hDevInfo, &spDevInfoData)) || (INVALID_HANDLE_VALUE == hDevInfo) ) { DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: m_pfnDevnodeSelCallback failed. Err=0x%x.\r\n"),GetLastError()));
bRet = FALSE; goto CreateDeviceInterfaceAndInstall_return; }
//
// Devnode selector functions.
//
bUseDefaultDevInfoSet = FALSE;
} else { // if(NULL != m_pfnDevnodeSelCallback)
//
// Use default device info set if available.
//
if( (INVALID_HANDLE_VALUE == m_hDevInfo) || (NULL == m_pspDevInfoData) ) { DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: Invalid Device info and no m_pfnDevnodeSelCallback.\r\n")));
bRet = FALSE; goto CreateDeviceInterfaceAndInstall_return; } else { hDevInfo = m_hDevInfo; spDevInfoData = *m_pspDevInfoData; } } // if(NULL != m_pfnDevnodeSelCallback)
//
// Create Interface (SoftDevice). Use FriendlyName ad ref-string.
//
DebugTrace(TRACE_STATUS,(("CDevice::CreateDeviceInterfaceAndInstall: Creating interface for %ws.\r\n"), (LPTSTR)m_csFriendlyName));
spDevInterfaceData.cbSize = sizeof(spDevInterfaceData); if(!SetupDiCreateDeviceInterface(hDevInfo, &spDevInfoData, &Guid, m_csFriendlyName, 0, &spDevInterfaceData)) { DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: SetupDiCreateInterface failed. Err=0x%x.\r\n"),GetLastError()));
bRet = FALSE; goto CreateDeviceInterfaceAndInstall_return; }
//
// Get symbolic link of created interface.
//
SetupDiGetDeviceInterfaceDetail(hDevInfo, &spDevInterfaceData, NULL, 0, &dwRequiredSize, NULL); if(0 == dwRequiredSize){ DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: Unable to get required size for InterfaceDetailedData. Err=0x%x.\r\n"),GetLastError()));
bRet = FALSE; goto CreateDeviceInterfaceAndInstall_return; } // if(0 == dwRequiredSize)
pspDevInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)new BYTE[dwRequiredSize]; if(NULL == pspDevInterfaceDetailData){ DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: Unable to allocate buffer.\r\n")));
bRet = FALSE; goto CreateDeviceInterfaceAndInstall_return; } // if(NULL == pspDevInterfaceDetailData)
pspDevInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if(!SetupDiGetDeviceInterfaceDetail(hDevInfo, &spDevInterfaceData, pspDevInterfaceDetailData, dwRequiredSize, &dwRequiredSize, NULL)) { DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: SetupDiGetDeviceInterfaceDetail() failed. Err=0x%x.\r\n"),GetLastError()));
bRet = FALSE; goto CreateDeviceInterfaceAndInstall_return;
} // if(!SetupDiGetDeviceInterfaceDetail(
m_csSymbolicLink = pspDevInterfaceDetailData->DevicePath;
//
// Open INF file handle for registry creation.
//
hInf = SetupOpenInfFile(m_csInf, NULL, INF_STYLE_WIN4, NULL);
if(INVALID_HANDLE_VALUE == hInf){ DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: SetupOpenInfFile failed. Err=0x%x.\r\n"),GetLastError()));
bRet = FALSE; goto CreateDeviceInterfaceAndInstall_return; } // if(INVALID_HANDLE_VALUE == hInf)
if(!SetupOpenAppendInfFile(NULL, hInf, NULL)){ DebugTrace(TRACE_WARNING,(("CDevice::CreateDeviceInterfaceAndInstall: SetupOpenAppendInfFile() failed. Err=0x%x.\r\n"),GetLastError())); } // if(!SetupOpenAppendInfFile(NULL, hInf, NULL))
//
// Create Interface Registry and keep its handle, it's hard to find it later.
//
m_hkInterfaceRegistry = SetupDiCreateDeviceInterfaceRegKey(hDevInfo, &spDevInterfaceData, 0, KEY_ALL_ACCESS, // NULL,
// NULL);
hInf, (LPCTSTR)m_csInstallSection); if(INVALID_HANDLE_VALUE == m_hkInterfaceRegistry){ DebugTrace(TRACE_ERROR,(("CDevice::CreateDeviceInterfaceAndInstall: SetupDiCreateDeviceInterfaceRegKey failed. Err=0x%x.\r\n"),GetLastError())); bRet = FALSE; goto CreateDeviceInterfaceAndInstall_return; } // if(INVALID_HANDLE_VALUE == m_hkInterfaceRegistry)
//
// Operation succeeded.
//
bRet = TRUE;
CreateDeviceInterfaceAndInstall_return:
//
// Clean up.
//
if(INVALID_HANDLE_VALUE != hDevInfo){ if(FALSE == bUseDefaultDevInfoSet){
//
// Destroy created DevInfoSet.
//
SetupDiDestroyDeviceInfoList(hDevInfo); } // if(FALSE == bUseDefaultDevInfoSet)
} // if(INVALID_HANDLE_VALUE != hDevInfo)
if(INVALID_HANDLE_VALUE != hInf){ SetupCloseInfFile(hInf); } // if(INVALID_HANDLE_VALUE != hInf)
if(NULL != pspDevInterfaceDetailData){ delete[] pspDevInterfaceDetailData; } // if(NULL != pspDevInterfaceDetailData)
DebugTrace(TRACE_PROC_LEAVE,(("CDevice::CreateDeviceInterfaceAndInstall: Leaving... Ret=0x%x.\r\n"), bRet));
return bRet; } // CDevice::CreateDeviceInterfaceAndInstall()
DWORD CDevice::GetPortSelectMode( VOID ) { DWORD dwRet; //
// Initialize local.
//
dwRet = PORTSELMODE_NORMAL; //
// Make sure INF is processed.
//
if(!PreprocessInf()){ DebugTrace(TRACE_ERROR,(("CDevice::GetPortSelectMode: ERROR!! Unable to process INF.\r\n")));
dwRet = PORTSELMODE_NORMAL; goto GetPortSelectMode_return; }
//
// If "PortSelect" is empty, use default.
//
if(m_csPortSelect.IsEmpty()){ dwRet = PORTSELMODE_NORMAL; goto GetPortSelectMode_return; } // if(m_csPortSelect.IsEmpty())
//
// See if "PortSelect" directive is "no".
//
if(0 == MyStrCmpi(m_csPortSelect, NO)){
//
// Port Selection page should be skipped.
//
dwRet = PORTSELMODE_SKIP; } else if(0 == MyStrCmpi(m_csPortSelect, MESSAGE1)){
//
// System supplied message should be shown.
//
dwRet = PORTSELMODE_MESSAGE1; } else {
//
// Unsupported PortSel option.
//
dwRet = PORTSELMODE_NORMAL; }
GetPortSelectMode_return:
return dwRet; } // CDevice::GetPortSelectMode()
DWORD CDevice::AcquireInstallerMutex( DWORD dwTimeout ) { DWORD dwReturn; //
// Initialize local.
//
dwReturn = ERROR_SUCCESS; if(NULL != m_hMutex){
//
// Mutex is already acquired.
//
DebugTrace(TRACE_WARNING,("WARNING!! AcquireInstallerMutex: Mutex acquired twice.\r\n")); dwReturn = ERROR_SUCCESS; goto AcquireInstallerMutex_return;
} // if(INVALID_HANDLE_VALUE != m_hMutex)
//
// Acquire Mutex.
//
m_hMutex = CreateMutex(NULL, FALSE, WIAINSTALLERMUTEX); dwReturn = GetLastError();
if(NULL == m_hMutex){
//
// CreteMutex() failed.
//
DebugTrace(TRACE_ERROR,("ERROR!! AcquireInstallerMutex: CraeteMutex() failed. Err=0x%x.\r\n", dwReturn)); goto AcquireInstallerMutex_return;
} // if(NULL == hMutex)
//
// Wait until ownership is acquired.
//
dwReturn = WaitForSingleObject(m_hMutex, dwTimeout); switch(dwReturn){ case WAIT_ABANDONED: DebugTrace(TRACE_ERROR, ("CDevice::AcquireInstallerMutex: ERROR!! Wait abandoned.\r\n")); break;
case WAIT_OBJECT_0: DebugTrace(TRACE_STATUS, ("CDevice::AcquireInstallerMutex: Mutex acquired.\r\n")); dwReturn = ERROR_SUCCESS; break;
case WAIT_TIMEOUT: DebugTrace(TRACE_WARNING, ("CDevice::AcquireInstallerMutex: WARNING!! Mutex acquisition timeout.\r\n")); break;
default: DebugTrace(TRACE_ERROR, ("CDevice::AcquireInstallerMutex: ERROR!! Unexpected error from WaitForSingleObjecct(). Err=0x%x.\r\n", dwReturn)); break; } // switch(dwReturn)
AcquireInstallerMutex_return:
DebugTrace(TRACE_PROC_LEAVE,("CDevice::AcquireInstallerMutex: Leaving... Ret=0x%x\n", dwReturn)); return dwReturn;
} // CDevice::AcquireInstallerMutex()
VOID CDevice::ReleaseInstallerMutex( ) { if(NULL != m_hMutex){
if(!ReleaseMutex(m_hMutex)){ DebugTrace(TRACE_ERROR, ("CDevice::ReleaseInstallerMutex: ERROR!! Releasing mutex which not owned..\r\n")); } // if(!ReleaseMutex(m_hMutex))
CloseHandle(m_hMutex); m_hMutex = NULL; DebugTrace(TRACE_STATUS, ("CDevice::ReleaseInstallerMutex: Mutex released.\r\n")); } // if(NULL != m_hMutex)
} // CDevice::ReleaseInstallerMutex()
UINT CALLBACK StiInstallCallback ( PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2 )
/*++
Routine Description:
StiInstallCallback
Callback routine used when calling SetupAPI file copying/installation functions
Arguments:
Context - our context Notification - notification message
Return Value:
SetupAPI return code
Side effects:
None
--*/ {
UINT uRet = FILEOP_COPY;
DebugTrace(TRACE_PROC_ENTER,(("StiInstallCallback: Enter... \r\n")));
//
// Initialize local.
//
uRet = FILEOP_COPY;
//
// Dispatch notification code.
//
switch(Notification){
case SPFILENOTIFY_ENDCOPY: { PFILEPATHS pFilePathInfo; HKEY hKey; DWORD dwDisposition; DWORD dwRefCount; DWORD dwType; UINT uSize; LONG Status;
uSize = sizeof(dwRefCount); pFilePathInfo = (PFILEPATHS)Param1;
DebugTrace(TRACE_STATUS,(("StiInstallCallback:ENDCOPY FileTarget %ws\r\n"), pFilePathInfo->Target));
//
// Open HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\SharedDlls
//
Status = RegCreateKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_SHAREDDLL, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition); if(ERROR_SUCCESS != Status) { DebugTrace(TRACE_ERROR,(("StiInstallCallback: RegCreateKeyEx failed. Err=0x%x\r\n"), Status)); break; }
//
// Retrieve reference count of this file
//
Status = RegQueryValueEx(hKey, pFilePathInfo->Target, NULL, &dwType, (LPBYTE)&dwRefCount, (LPDWORD)&uSize); if(ERROR_SUCCESS != Status) { //
// Value for this file hasn't been created, or error
//
DebugTrace(TRACE_ERROR,(("StiInstallCallback: Value for Ref-count doesn't exist\r\n"))); dwRefCount = 0; }
//
// Increment reference count and set value
//
dwRefCount++; uSize = sizeof(dwRefCount); Status = RegSetValueEx(hKey, pFilePathInfo->Target, NULL, REG_DWORD, (CONST BYTE *)&dwRefCount, uSize); if(ERROR_SUCCESS != Status) { DebugTrace(TRACE_ERROR,(("StiInstallCallback: RegSetValueEx. Err=0x%x.\r\n"), Status)); }
DebugTrace(TRACE_STATUS,(("StiInstallCallback: ref-count of %ws is now 0x%x.\r\n"), pFilePathInfo->Target, dwRefCount));
//
// Close Registry key
//
RegCloseKey(hKey);
Report(( TEXT("StiInstallCallback:%ws copied.\r\n"), pFilePathInfo->Target)); } // case SPFILENOTIFY_ENDCOPY
default: ; }
uRet = SetupDefaultQueueCallback(Context, Notification, Param1, Param2);
DebugTrace(TRACE_PROC_LEAVE,(("StiInstallCallback: Leaving... Ret=0x%x\n"), uRet)); return uRet; }
VOID GetDeviceCount( DWORD *pdwWiaCount, DWORD *pdwStiCount ) /*++
Routine Description:
GetDeviceCount
Verifes if there is at least one STI device installed in a system
Arguments:
bWia - TRUE: Count WIA device
Return Value:
Number of WIA device FALSE
--*/ { DWORD dwWiaCount; DWORD dwStiCount; BOOL fRet; CString csSubClass; DWORD dwCapabilities; GUID Guid; UINT Idx; DWORD dwRequired; DWORD dwError; HKEY hkThis; HKEY hkRun; HANDLE hDevInfo; SP_DEVINFO_DATA spDevInfoData; SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
DebugTrace(TRACE_PROC_ENTER,(("GetDeviceCount: Enter... \r\n")));
//
// Initialize local.
//
dwWiaCount = 0; dwStiCount = 0; fRet = FALSE; Idx = 0; dwRequired = 0; dwError = 0; hkThis = NULL; hkRun = NULL; hDevInfo = NULL; dwCapabilities = 0;
memset(&spDevInfoData, 0, sizeof(spDevInfoData)); memset(&spDevInterfaceData, 0, sizeof(spDevInterfaceData));
//
// Get WIA class guid.
//
SetupDiClassGuidsFromName (CLASSNAME, &Guid, sizeof(GUID), &dwRequired);
//
// Get device info set of all WIA devices (devnode).
//
hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, DIGCF_PROFILE );
if (hDevInfo != INVALID_HANDLE_VALUE) {
spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++) {
#if DEBUG
CHAR szDevDriver[STI_MAX_INTERNAL_NAME_LENGTH]; ULONG cbData;
fRet = SetupDiGetDeviceRegistryProperty (hDevInfo, &spDevInfoData, SPDRP_DRIVER, NULL, (UCHAR *)szDevDriver, sizeof (szDevDriver), &cbData); DebugTrace(TRACE_STATUS,(("GetDeviceCount: Checking device No%d(%ws)\r\n"), Idx, szDevDriver)); #endif
//
// Verify device is not being removed
//
spDevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); spDevInterfaceData.InterfaceClassGuid = GUID_DEVCLASS_IMAGE;
fRet = SetupDiEnumDeviceInterfaces (hDevInfo, NULL, &Guid, Idx, &spDevInterfaceData);
dwError = GetLastError();
if (fRet) { if (spDevInterfaceData.Flags & SPINT_REMOVED) { continue; } }
hkThis = SetupDiOpenDevRegKey(hDevInfo, &spDevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ );
if (hkThis != INVALID_HANDLE_VALUE) {
csSubClass.Load(hkThis, SUBCLASS); GetDwordFromRegistry(hkThis, CAPABILITIES, &dwCapabilities);
DebugTrace(TRACE_STATUS,(("GetDeviceCount: Capabilities=0x%x\n"), dwCapabilities));
RegCloseKey(hkThis);
if( (!csSubClass.IsEmpty()) && (0 == MyStrCmpi(csSubClass, STILL_IMAGE)) ) {
//
// STI device found. Increse the counter.
//
dwStiCount++;
if(dwCapabilities & STI_GENCAP_WIA){
//
// WIA device found.
//
dwWiaCount++;
} // if(dwCapabilities & STI_GENCAP_WIA){
} // if (!csSubClass.IsEmpty() && !lstrcmpi(csSubClass, STILL_IMAGE))
} // if (hkThis != INVALID_HANDLE_VALUE)
} // for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++)
SetupDiDestroyDeviceInfoList(hDevInfo); } else { DebugTrace(TRACE_ERROR,(("GetDeviceCount: ERROR!! Unable to get device info set.\r\n"))); } // if (hDevInfo != INVALID_HANDLE_VALUE)
//
// Get device info set of all WIA devices (interface).
//
hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, DIGCF_PROFILE | DIGCF_DEVICEINTERFACE );
if (hDevInfo != INVALID_HANDLE_VALUE) {
spDevInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); for (Idx = 0; SetupDiEnumDeviceInterfaces (hDevInfo, NULL, &Guid, Idx, &spDevInterfaceData); Idx++) {
DebugTrace(TRACE_STATUS,(("GetDeviceCount: Checking interface No%d.\r\n"), Idx));
//
// Verify device is not being removed
//
if (spDevInterfaceData.Flags & SPINT_REMOVED) { continue; }
hkThis = SetupDiOpenDeviceInterfaceRegKey(hDevInfo, &spDevInterfaceData, 0, KEY_READ );
if (hkThis != INVALID_HANDLE_VALUE) { csSubClass.Load(hkThis, SUBCLASS); GetDwordFromRegistry(hkThis, CAPABILITIES, &dwCapabilities); RegCloseKey(hkThis);
if( (!csSubClass.IsEmpty()) && (0 == MyStrCmpi(csSubClass, STILL_IMAGE)) ) {
//
// STI device found. Increse the counter.
//
dwStiCount++;
if(dwCapabilities & STI_GENCAP_WIA){
//
// WIA device found.
//
dwWiaCount++;
} // if(dwCapabilities & STI_GENCAP_WIA){
} // if (!csSubClass.IsEmpty() && !lstrcmpi(csSubClass, STILL_IMAGE))
} // if (hkThis != INVALID_HANDLE_VALUE)
} // for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++)
SetupDiDestroyDeviceInfoList(hDevInfo); } else { // if (hDevInfo != INVALID_HANDLE_VALUE)
DebugTrace(TRACE_ERROR,(("GetDeviceCount: ERROR!! Unable to get device info set.\r\n"))); } // if (hDevInfo != INVALID_HANDLE_VALUE)
//
// Copy the result.
//
*pdwWiaCount = dwWiaCount; *pdwStiCount = dwStiCount;
DebugTrace(TRACE_PROC_LEAVE,(("GetDeviceCount: Leaving... STI=0x%x, WIA=0x%x.\r\n"), dwStiCount, dwWiaCount)); return; } // GetDeviceCount()
BOOL ExecCommandLine( LPTSTR szCommandLine ) { BOOL bRet; CString csCommandLine; PROCESS_INFORMATION pi; STARTUPINFO si = { sizeof(si), // cb
NULL, // lpReserved;
NULL, // lpDesktop;
NULL, // lpTitle;
0, // dwX;
0, // dwY;
0, // dwXSize;
0, // dwYSize;
0, // dwXCountChars;
0, // dwYCountChars;
0, // dwFillAttribute;
STARTF_FORCEONFEEDBACK, // dwFlags;
SW_SHOWNORMAL, // wShowWindow;
0, // cbReserved2;
NULL, // lpReserved2;
NULL, // hStdInput;
NULL, // hStdOutput;
NULL // hStdError;
};
csCommandLine = szCommandLine; bRet = CreateProcess(NULL, // Application name
(LPTSTR)csCommandLine, // Command line
NULL, // Process attributes
NULL, // Thread attributes
FALSE, // Handle inheritance
NORMAL_PRIORITY_CLASS, // Creation flags
NULL, // Environment
NULL, // Current directory
&si, &pi);
if (bRet) { CloseHandle(pi.hProcess); CloseHandle(pi.hThread); } else { DebugTrace(TRACE_ERROR,(("ExecCommandLine: CreateProcess failed. Err=0x%x.\r\n"), GetLastError())); }
return bRet; }
PPARAM_LIST MigrateDeviceData( HKEY hkDeviceData, PPARAM_LIST pExtraDeviceData, LPSTR pszKeyName ) {
BOOL bDone; PPARAM_LIST pCurrent; PPARAM_LIST pReturn; DWORD dwType; DWORD dwSize; PCHAR pOrginalBuffer; CHAR pCopyBuffer[MAX_PATH*3]; CHAR pDataBuffer[MAX_PATH]; DWORD Idx;
//
// Initialize local.
//
bDone = FALSE; pCurrent = pExtraDeviceData; pReturn = NULL; //
// Loop until it gets "END".
//
while(!bDone){
if(NULL == pCurrent){ //
// Hit the end of list.
//
bDone = TRUE; pReturn =NULL; continue;
} // if(NULL == pTemp)
//
// If "KeyName = END" is found, return.
//
if( (CSTR_EQUAL == CompareStringA(LOCALE_INVARIANT,NORM_IGNORECASE, pCurrent->pParam1, -1,pszKeyName,-1)) && (CSTR_EQUAL == CompareStringA(LOCALE_INVARIANT,NORM_IGNORECASE, pCurrent->pParam2, -1,NAME_END_A,-1)) ) { bDone = TRUE; pReturn = (PPARAM_LIST)pCurrent->pNext; continue; }
//
// If 2nd parameter is "BEGIN", create subkey and call this function recursively.
//
if(CSTR_EQUAL == CompareStringA(LOCALE_INVARIANT,NORM_IGNORECASE, pCurrent->pParam2, -1,NAME_BEGIN_A,-1)){ HKEY hkSubKey; LONG lError; lError = RegCreateKeyA(hkDeviceData, pCurrent->pParam1, &hkSubKey); if(ERROR_SUCCESS != lError){ //
// Unable to create subkey.
//
DebugTrace(TRACE_ERROR,(("MigrateDeviceData: ERROR!! Unable to create subkey..\r\n"))); pReturn = NULL; goto MigrateDeviceData_return; } // if(ERROR_SUCCESS != lError)
pCurrent = MigrateDeviceData(hkSubKey, (PPARAM_LIST)pCurrent->pNext, pCurrent->pParam1); RegCloseKey(hkSubKey); continue; } // if(0 == lstrcmpiA(pCurrent->pParam2, NAME_BEGIN_A))
//
// This is a set of value and data.
//
lstrcpyA(pCopyBuffer, pCurrent->pParam2); pOrginalBuffer = pCopyBuffer; //
// Get key type.
//
pOrginalBuffer[8] = '\0'; dwType = DecodeHexA(pOrginalBuffer);
//
// Get data.
//
Idx = 0; pOrginalBuffer+=9;
while('\0' != *pOrginalBuffer){ if('\0' != pOrginalBuffer[2]){ pOrginalBuffer[2] = '\0'; pDataBuffer[Idx++] = (CHAR)DecodeHexA(pOrginalBuffer); pOrginalBuffer+=3; } else { pDataBuffer[Idx++] = (CHAR)DecodeHexA(pOrginalBuffer); break; } } // while('\0' != pCurrent->pParam2[Idx])
//
// Create this value.
//
RegSetValueExA(hkDeviceData, pCurrent->pParam1, 0, dwType, (PBYTE)pDataBuffer, Idx);
//
// Process next line.
//
pCurrent = (PPARAM_LIST)pCurrent->pNext;
} // while(!bDone)
MigrateDeviceData_return: return pReturn; } // MigrateDeviceData()
DWORD DecodeHexA( LPSTR lpstr ) {
DWORD dwReturn;
//
// Initialize local.
//
dwReturn = 0;
if(NULL == lpstr){ dwReturn = 0; goto DecodeHexA_return; } // if(NULL == lpstr)
//
// Skip spaces.
//
for (LPSTR lpstrThis = lpstr; *lpstrThis && *lpstrThis == TEXT(' '); lpstrThis++) ;
while (*lpstrThis) { switch (*lpstrThis) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': dwReturn <<= 4; dwReturn += ((*lpstrThis) - '0'); break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': dwReturn <<= 4; dwReturn += 10 + (*lpstrThis - 'a'); break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': dwReturn <<= 4; dwReturn += 10 + (*lpstrThis - 'A'); break;
default: return dwReturn; } lpstrThis++; } // while (*lpstrThis)
DecodeHexA_return: return dwReturn; } // DWORD CString::DecodeHex()
BOOL IsNameAlreadyStored( LPTSTR szName ) { BOOL bRet; HKEY hkNameStore;
DebugTrace(TRACE_PROC_ENTER,(("IsNameAlreadyStored: Enter... \r\n")));
//
// Initialize local.
//
bRet = FALSE; hkNameStore = (HKEY)INVALID_HANDLE_VALUE;
//
// Open name store regkey.
//
if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore)){ HKEY hkTemp; hkTemp = (HKEY)INVALID_HANDLE_VALUE;
//
// See if specified name exists in name store.
//
if(ERROR_SUCCESS == RegOpenKey(hkNameStore, szName, &hkTemp)){
//
// Specified name already exists in name store.
//
bRet = TRUE; RegCloseKey(hkTemp);
} // if(ERROR_SUCCESS == RegOpenKey(hkNameStore, szName, &hkTemp))
RegCloseKey(hkNameStore); } // if(ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY_INSTALL_NAMESTORE, &hkNameStore))
// IsNameAlreadyStored_return:
DebugTrace(TRACE_PROC_LEAVE,(("IsNameAlreadyStored: Leaving... Ret=0x%x\n"), bRet)); return bRet; } // IsFriendlyNameUnique()
#if DEAD_CODE
#ifdef USE_STIMON
//
// For the time being always load and start the monitor
//
HKEY hkRun;
if (RegOpenKey(HKEY_LOCAL_MACHINE, REGSTR_PATH_RUN, &hkRun) == NO_ERROR) {
CString csCmdLine; csCmdLine.MakeSystemPath(MONITOR_NAME); csCmdLine.Store (hkRun, REGSTR_VAL_MONITOR);
Report(( TEXT("Monitor Command Line %ws\r\n"), (LPCTSTR)csCmdLine));
// Launch it...
WinExec(csCmdLine, SW_SHOWNOACTIVATE); RegCloseKey(hkRun); } #endif
#endif
|