|
|
/******************************************************************************
* * (C) COPYRIGHT MICROSOFT CORP., 2000 * * TITLE: Exports.cpp * * VERSION: 1.0 * * AUTHOR: KeisukeT * * DATE: 27 Mar, 2000 * * DESCRIPTION: * Exported functions. * * *******************************************************************************/
//
// Precompiled header
//
#include "precomp.h"
#pragma hdrstop
//
// Include
//
#include "sti_ci.h"
#include "exports.h"
#include "device.h"
#include "portsel.h"
#include <devguid.h>
#include <stdio.h>
#include <shlobj.h>
#include <objbase.h>
#include <icm.h>
#include <stiregi.h>
#include <stisvc.h>
//
// Global
//
extern HINSTANCE g_hDllInstance;
//
// Function
//
DLLEXPORT HANDLE WINAPI WiaAddDevice( VOID ) { return ExecCommandLine(STR_ADD_DEVICE, EXECDIR_SYSTEM32); } // WiaAddDevice()
DLLEXPORT BOOL WINAPI WiaRemoveDevice( PSTI_DEVICE_INFORMATION pStiDeviceInformation ) { if(NULL == pStiDeviceInformation){ DebugTrace(TRACE_ERROR,(("WiaRemoveDevice: ERROR!! Invalid argument.\r\n"))); return FALSE; } // if(NULL == pStiDeviceInformation)
return (RemoveDevice(NULL, g_hDllInstance, pStiDeviceInformation->szDeviceInternalName, 0)); } // WiaRemoveDevice(
HANDLE WiaInstallerProcess( LPTSTR lpCommandLine ) { BOOL bRet = FALSE; HANDLE hProcess = NULL; PROCESS_INFORMATION ProcessInfo; STARTUPINFO SetupInfo = {sizeof SetupInfo, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, STARTF_FORCEONFEEDBACK, SW_SHOWNORMAL, 0, NULL, NULL, NULL, NULL};
//
// Create install wizard process.
//
DebugTrace(TRACE_STATUS,(("WiaInstallerProcess: Executing \"%ws\".\r\n"), lpCommandLine)); bRet = CreateProcess(NULL, lpCommandLine, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &SetupInfo, &ProcessInfo);
if(bRet){ DebugTrace(TRACE_STATUS,(("WiaInstallerProcess: Installer process successfully created.\r\n"))); CloseHandle(ProcessInfo.hThread); hProcess = ProcessInfo.hProcess; } else { DebugTrace(TRACE_ERROR,(("WiaInstallerProcess: ERROR!! Unable to create a process. Err=0x%x.\r\n"), GetLastError())); hProcess = NULL; }
return hProcess; }
BOOL WINAPI CreateWiaShortcut( VOID ) {
HRESULT hres; IShellLink *psl; LONG err; HKEY khWindowsCurrentVersion; DWORD dwType; DWORD dwSize;
TCHAR pszSystemPath[MAX_PATH+1]; // path to system32 folder.
TCHAR pszShortcutPath[MAX_PATH+1]; // path to creating shortcut.
TCHAR pszProgramPath[MAX_PATH+1]; // path to ProgramFiles folder.
TCHAR pszAccessoriesPath[MAX_PATH+1]; // path to Accessories folder.
TCHAR pszWizardPath[MAX_PATH+1]; // path to wiaacmgr.exe.
TCHAR pszSticiPath[MAX_PATH+1]; // path to sti_ci.dll.
TCHAR pszWizardName[MAX_PATH+1]; // Menu name ofcreating shortcut.
TCHAR pszWizardLinkName[MAX_PATH+1]; // filename ofcreating shortcut.
TCHAR pszWizardDesc[MAX_PATH+1]; // description of creating shortcut.
TCHAR pszAccessoriesName[MAX_PATH+1]; // localized "Accessories" folder name.
BOOL bRet;
//
// Init locals.
//
bRet = FALSE; psl = NULL; err = 0; khWindowsCurrentVersion = NULL;
memset(pszSystemPath, 0, sizeof(pszSystemPath)); memset(pszShortcutPath, 0, sizeof(pszShortcutPath)); memset(pszProgramPath, 0, sizeof(pszProgramPath)); memset(pszAccessoriesPath, 0, sizeof(pszAccessoriesPath)); memset(pszWizardPath, 0, sizeof(pszWizardPath)); memset(pszSticiPath, 0, sizeof(pszSticiPath)); memset(pszWizardName, 0, sizeof(pszWizardName)); memset(pszWizardLinkName, 0, sizeof(pszWizardLinkName)); memset(pszWizardDesc, 0, sizeof(pszWizardDesc)); memset(pszAccessoriesName, 0, sizeof(pszAccessoriesName));
//
// Get path to the "ProgramFiles" folder.
//
hres = SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS | CSIDL_FLAG_CREATE, NULL, 0, pszProgramPath); if(!SUCCEEDED(hres)){ DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: ERROR!! Can't get ProgramFiles folder.\r\n"))); bRet = FALSE; goto CreateWiaShortcut_return;
}
//
// Get localized "Accessoies" folder name from reistry.
//
err = RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY_WINDOWS_CURRENTVERSION, &khWindowsCurrentVersion); if(ERROR_SUCCESS != err){ DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: ERROR!! Can't open Windows\\CurrentVersion.Err=0x%x \r\n"), err)); bRet = FALSE; goto CreateWiaShortcut_return; }
dwSize = sizeof(pszAccessoriesName); err = RegQueryValueEx(khWindowsCurrentVersion, REGSTR_VAL_ACCESSORIES_NAME, NULL, &dwType, (LPBYTE)pszAccessoriesName, &dwSize); if(err){ DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: ERROR!! Can't get %ws value.Err=0x%x\r\n"), REGSTR_VAL_ACCESSORIES_NAME, err));
//
// Unable to get "Accessories" name from registry. Let's take it from resource.
//
if( (NULL == g_hDllInstance) || (0 == LoadString(g_hDllInstance, LocalAccessoriesFolderName, pszAccessoriesName, MAX_PATH)) ) { bRet = FALSE; goto CreateWiaShortcut_return; } // if(0 == LoadString(g_hDllInstance, AccessoriesFolderName, pszAccessoriesName, MAX_PATH))
} // if(err)
//
// Load localizable string from resource.
//
if(NULL != g_hDllInstance){ LoadString(g_hDllInstance, WiaWizardName, pszWizardName, MAX_PATH); } else { DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: ERROR!! No DLL instance\r\n")));
bRet = FALSE; goto CreateWiaShortcut_return; }
//
// Get System path.
//
if( 0== GetSystemDirectory(pszSystemPath, MAX_PATH)){ DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: ERROR!! GetSystemDirectory failed. Err=0x%x\r\n"), GetLastError()));
bRet = FALSE; goto CreateWiaShortcut_return; }
//
// Create shortcut/program name.
//
_sntprintf(pszAccessoriesPath, ARRAYSIZE(pszAccessoriesPath)-1, TEXT("%ws\\%ws"), pszProgramPath, pszAccessoriesName); _sntprintf(pszWizardLinkName, ARRAYSIZE(pszWizardLinkName)-1, TEXT("%ws.lnk"), WIAWIZARDCHORCUTNAME); _sntprintf(pszShortcutPath, ARRAYSIZE(pszShortcutPath)-1, TEXT("%ws\\%ws"), pszAccessoriesPath, pszWizardLinkName); _sntprintf(pszWizardPath, ARRAYSIZE(pszWizardPath)-1, TEXT("%ws\\%ws"), pszSystemPath, WIAACMGR_PATH); _sntprintf(pszSticiPath, ARRAYSIZE(pszSticiPath)-1, TEXT("%ws\\%ws"), pszSystemPath, WIAINSTALLERFILENAME); _sntprintf(pszWizardDesc, ARRAYSIZE(pszWizardDesc)-1, TEXT("@%ws,-%d"), pszSticiPath, WiaWizardDescription);
//
// Create an IShellLink object and get a pointer to the IShellLink
// interface (returned from CoCreateInstance).
//
hres = CoInitialize(NULL); if(!SUCCEEDED(hres)){ DebugTrace(TRACE_ERROR,(("CoInitialize failed. hres=0x%x\r\n"), hres)); bRet = FALSE; goto CreateWiaShortcut_return; }
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID *)&psl); if (SUCCEEDED(hres)){
IPersistFile *ppf;
//
// Query IShellLink for the IPersistFile interface for
// saving the shortcut in persistent storage.
//
hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf); if (SUCCEEDED(hres)){
// Set the path to the shortcut target.
hres = psl->SetPath(pszWizardPath);
if (SUCCEEDED(hres)){ // Set the argument to the shortcut target.
hres = psl->SetArguments(WIAACMGR_ARG);
if (SUCCEEDED(hres)){ // Set the description of the shortcut.
hres = psl->SetDescription(pszWizardDesc);
if (SUCCEEDED(hres)){ // Save the shortcut via the IPersistFile::Save member function.
hres = ppf->Save(pszShortcutPath, TRUE);
if (SUCCEEDED(hres)){ //
// Shortcut created. Set MUI name.
//
hres = SHSetLocalizedName(pszShortcutPath, pszSticiPath, WiaWizardName); if (SUCCEEDED(hres)){ //
// Operation succeeded.
//
bRet = TRUE; } else { DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: ERROR!! SHSetLocalizedName failed. hRes=0x%x\r\n"), hres)); } } else { DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: ERROR!! Save failed. hRes=0x%x\r\n"), hres)); } } else { DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: ERROR!! SetDescription failed. hRes=0x%x\r\n"), hres)); } } else { DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: ERROR!! SetArguments failed. hRes=0x%x\r\n"), hres)); } } else { DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: ERROR!! SetPath failed. hRes=0x%x\r\n"), hres)); }
// Release the pointer to IPersistFile.
ppf->Release(); } else { DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: ERROR!! QueryInterface(IID_IPersistFile) failed.\r\n"))); }
// Release the pointer to IShellLink.
psl->Release();
CoUninitialize();
} else { // if (SUCCEEDED(hres))
DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: ERROR!! CoCreateInstance(IID_IShellLink) failed.\r\n")));
switch(hres){
case REGDB_E_CLASSNOTREG : DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: REGDB_E_CLASSNOTREG.\r\n"))); break; case CLASS_E_NOAGGREGATION : DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: CLASS_E_NOAGGREGATION.\r\n"))); break; case E_NOINTERFACE : DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: E_NOINTERFACE.\r\n"))); break;
default: DebugTrace(TRACE_ERROR,(("CreateWiaShortcut: default.(hres=0x%x).\r\n hres=0x%x"), hres)); break; }
bRet = FALSE; goto CreateWiaShortcut_return; } // if (SUCCEEDED(hres))
CreateWiaShortcut_return:
if(FALSE == bRet){ CString csCmdLine;
//
// Try it again after next reboot.
//
csCmdLine.MakeSystemPath(STI_CI32_ENTRY_WIZMANU); csCmdLine = TEXT(" ") + csCmdLine; csCmdLine = RUNDLL32 + csCmdLine;
SetRunonceKey(REGSTR_VAL_WIZMENU, csCmdLine); } // if(FALSE == bRet)
//
// Clean up
//
if(NULL != khWindowsCurrentVersion){ RegCloseKey(khWindowsCurrentVersion); }
return bRet; }
BOOL WINAPI DeleteWiaShortcut( VOID ) {
HRESULT hres; IShellLink *psl; LONG err; HKEY khWindowsCurrentVersion; DWORD dwType; DWORD dwSize;
TCHAR pszShortcutPath[MAX_PATH]; TCHAR pszAccessoriesName[MAX_PATH]; // localized "Accessories" folder name.
TCHAR pszProgramPath[MAX_PATH]; // path to ProgramFiles folder.
BOOL bRet;
//
// Init locals.
//
bRet = FALSE; psl = NULL; err = 0; khWindowsCurrentVersion = NULL;
memset(pszShortcutPath, 0, sizeof(pszShortcutPath)); memset(pszAccessoriesName, 0, sizeof(pszAccessoriesName)); memset(pszProgramPath, 0, sizeof(pszProgramPath));
//
// Get path to the "ProgramFiles" folder.
//
hres = SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS | CSIDL_FLAG_CREATE, NULL, 0, pszProgramPath); if(!SUCCEEDED(hres)){ DebugTrace(TRACE_ERROR,(("DeleteWiaShortcut: ERROR!! Can't get ProgramFiles folder.\r\n"), hres));
bRet = FALSE; goto DeleteWiaShortcut_return;
}
//
// Get localized "Accessoies" folder name from reistry.
//
err = RegOpenKey(HKEY_LOCAL_MACHINE, REGKEY_WINDOWS_CURRENTVERSION, &khWindowsCurrentVersion); if(err){ DebugTrace(TRACE_ERROR,(("DeleteWiaShortcut: ERROR!! Can't open Windows\\CurrentVersion key.Err=0x%x\r\n"), err));
bRet = FALSE; goto DeleteWiaShortcut_return; }
dwSize = sizeof(pszAccessoriesName)-sizeof(TCHAR); err = RegQueryValueEx(khWindowsCurrentVersion, REGSTR_VAL_ACCESSORIES_NAME, NULL, &dwType, (LPBYTE)pszAccessoriesName, &dwSize); if(err){ DebugTrace(TRACE_ERROR,(("DeleteWiaShortcut: ERROR!! Can't get %ws value.Err=0x%x\r\n"), REGSTR_VAL_ACCESSORIES_NAME, err));
//
// Unable to get "Accessories" name from registry. Let's take it from resource.
//
if( (NULL == g_hDllInstance) || (0 == LoadString(g_hDllInstance, LocalAccessoriesFolderName, pszAccessoriesName, MAX_PATH)) ) { bRet = FALSE; goto DeleteWiaShortcut_return; } // if(0 == LoadString(g_hDllInstance, AccessoriesFolderName, pszAccessoriesName, MAX_PATH))
}
//
// Create shortcut/program name.
//
_sntprintf(pszShortcutPath, ARRAYSIZE(pszShortcutPath)-1, TEXT("%ws\\%ws\\%ws.lnk"), pszProgramPath, pszAccessoriesName, WIAWIZARDCHORCUTNAME);
if(!DeleteFile((LPCTSTR)pszShortcutPath)){ DebugTrace(TRACE_ERROR,(("ERROR!! DeleteFile failed. Err=0x%x\r\n"), GetLastError()));
bRet = FALSE; goto DeleteWiaShortcut_return; }
//
// Operation succeeded.
//
bRet = TRUE;
DeleteWiaShortcut_return:
//
// Clean up
//
if(NULL != khWindowsCurrentVersion){ RegCloseKey(khWindowsCurrentVersion); }
return bRet; }
DLLEXPORT VOID CALLBACK WiaCreateWizardMenu( HWND hwnd, HINSTANCE hinst, LPTSTR lpszCmdLine, int nCmdShow ) { CreateWiaShortcut(); }
DLLEXPORT VOID CALLBACK AddDevice( HWND hWnd, HINSTANCE hInst, LPSTR lpszCmdLine, int nCmdShow ) {
HANDLE hDevInfo; HWND hDlg; GUID Guid; SP_DEVINFO_DATA spDevInfoData; SP_INSTALLWIZARD_DATA InstallWizard; SP_DEVINSTALL_PARAMS spDevInstallParams; TCHAR ClassName[LINE_LEN]; DWORD err; DWORD dwRequired; HANDLE hMutex;
CString csTitle; CString csSubTitle; CString csInstruction; CString csListLabel;
DebugTrace(TRACE_PROC_ENTER,(("AddDevice: Enter...\r\n")));
//
// Initialize locals.
//
hDevInfo = INVALID_HANDLE_VALUE; hDlg = hWnd; Guid = GUID_DEVCLASS_IMAGE; err = ERROR_SUCCESS; dwRequired = 0; hMutex = NULL;
memset(&spDevInfoData, 0, sizeof(spDevInfoData)); memset(&InstallWizard, 0, sizeof(InstallWizard)); memset(&spDevInstallParams, 0, sizeof(spDevInstallParams)); memset(ClassName, 0, sizeof(ClassName));
//
// Acquire Mutex.
//
CInstallerMutex CMutex(&hMutex, WIAINSTALLWIZMUTEX, 0); if(!CMutex.Succeeded()){
HWND hwndAnotherWizard; CString csWindowTitle;
hwndAnotherWizard = NULL;
//
// Other instance is running. Just activate that window and quit.
//
csWindowTitle.FromTable (MessageTitle); hwndAnotherWizard = FindWindow(NULL, (LPTSTR)csWindowTitle); if(NULL != hwndAnotherWizard){ if(!SetForegroundWindow(hwndAnotherWizard)){ DebugTrace(TRACE_ERROR, ("AddDevice: ERROR!! SetForegroundWindow() failed. Err=0x%x.\r\n", GetLastError())); } // if(!SetForegroundWindow(hwndAnotherWizard))
} else { // if(NULL != hwndAnotherWizard)
//
// Mutex acquisition was failed but didn't find Window.
// Continue.
//
DebugTrace(TRACE_WARNING, ("AddDevice: WARNING!! Mutex acquisition was failed but didn't find Window.\r\n")); } // else (NULL != hwndAnotherWizard)
goto AddDevice_Err; } // if(!CMutex.Succeeded())
//
// Create Device Information Set from guid.
//
hDevInfo = SetupDiCreateDeviceInfoList(&Guid, hDlg);
if (hDevInfo == INVALID_HANDLE_VALUE) { err=GetLastError(); goto AddDevice_Err; }
// //
// // Get class install parameter.
// //
//
// if(!SetupDiGetClassInstallParams(hDevInfo,
// NULL,
// &spSelectDeviceParams.ClassInstallHeader,
// sizeof(spSelectDeviceParams),
// &dwRequired)){
// err=GetLastError();
// goto AddDevice_Err;
// }
//
// Get class name from Guid.
//
if(!SetupDiClassNameFromGuid(&Guid, ClassName, sizeof(ClassName)/sizeof(TCHAR), NULL )){ err=GetLastError(); goto AddDevice_Err; }
//
// Create a new device information element to install
//
spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); if(!SetupDiCreateDeviceInfo(hDevInfo, ClassName, &Guid, NULL, hDlg, DICD_GENERATE_ID, &spDevInfoData )){ err=GetLastError(); goto AddDevice_Err; }
//
// Set new element as selected device
//
if(!SetupDiSetSelectedDevice(hDevInfo, &spDevInfoData )){ err=GetLastError(); goto AddDevice_Err; }
//
// Get device install parameters
//
spDevInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS); if(!SetupDiGetDeviceInstallParams(hDevInfo, &spDevInfoData, &spDevInstallParams )){ err=GetLastError(); goto AddDevice_Err; }
//
// Set device install parameters
//
spDevInstallParams.Flags |= DI_SHOWOEM ; spDevInstallParams.Flags |= DI_USECI_SELECTSTRINGS;
spDevInstallParams.hwndParent = hDlg;
if(!SetupDiSetDeviceInstallParams(hDevInfo, &spDevInfoData, &spDevInstallParams )){ err=GetLastError(); goto AddDevice_Err; }
//
// Set class install parameter.
//
InstallWizard.ClassInstallHeader.InstallFunction = DIF_INSTALLWIZARD; InstallWizard.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); InstallWizard.hwndWizardDlg = hDlg;
//
// TRUE = Show first page
//
InstallWizard.PrivateFlags = SCIW_PRIV_CALLED_FROMCPL | SCIW_PRIV_SHOW_FIRST;
if(!SetupDiSetClassInstallParams(hDevInfo, &spDevInfoData, &InstallWizard.ClassInstallHeader, sizeof(SP_INSTALLWIZARD_DATA) )) { err=GetLastError(); goto AddDevice_Err; }
//
// Call class installer to retrieve wizard pages
//
if(!SetupDiCallClassInstaller(DIF_INSTALLWIZARD, hDevInfo, &spDevInfoData )){ err=GetLastError(); goto AddDevice_Err; }
//
// Get result from class installer
//
if(!SetupDiGetClassInstallParams(hDevInfo, &spDevInfoData, &InstallWizard.ClassInstallHeader, sizeof(SP_INSTALLWIZARD_DATA), NULL )) { err=GetLastError(); goto AddDevice_Err; }
//
// Prepare UI parameters to be used by DevSelect page,
//
csTitle.FromTable(SelDevTitle); csSubTitle.FromTable(SelDevSubTitle); csInstruction.FromTable(SelDevInstructions); csListLabel.FromTable(SelDevListLabel);
if(!SetSelectDevTitleAndInstructions(hDevInfo, &spDevInfoData, (LPTSTR)csTitle, (LPTSTR)csSubTitle, (LPTSTR)csInstruction, (LPTSTR)csListLabel)) { err=GetLastError(); goto AddDevice_Err; }
//
// Get device selection page
//
InstallWizard.DynamicPageFlags = DYNAWIZ_FLAG_PAGESADDED; InstallWizard.DynamicPages[InstallWizard.NumDynamicPages++] = SetupDiGetWizardPage(hDevInfo, &spDevInfoData, &InstallWizard, SPWPT_SELECTDEVICE, 0);
//
// Create installer property sheet
//
{ PROPSHEETHEADER PropSheetHeader; DWORD Pages; HPROPSHEETPAGE SelectDevicePage;
PropSheetHeader.dwSize = sizeof(PropSheetHeader); PropSheetHeader.dwFlags = PSH_WIZARD | PSH_USECALLBACK | PSH_WIZARD97 | PSH_STRETCHWATERMARK | PSH_WATERMARK | PSH_HEADER; PropSheetHeader.pszbmWatermark = MAKEINTRESOURCE(WizardBitmap); PropSheetHeader.pszbmHeader = MAKEINTRESOURCE(IDB_BANNERBMP); PropSheetHeader.hwndParent = hDlg; PropSheetHeader.hInstance = g_hDllInstance; PropSheetHeader.pszIcon = NULL; //MAKEINTRESOURCE(IDI_NEWDEVICEICON);
PropSheetHeader.pszCaption = MAKEINTRESOURCE(MessageTitle); PropSheetHeader.nStartPage = 0; PropSheetHeader.nPages = InstallWizard.NumDynamicPages; PropSheetHeader.phpage = InstallWizard.DynamicPages; PropSheetHeader.pfnCallback = iHdwWizardDlgCallback;
if(PropertySheet(&PropSheetHeader) < 0){ err=GetLastError(); }
}
AddDevice_Err:
//
// Free allocated memory
//
if(IS_VALID_HANDLE(hDevInfo)){
//
// Set install parameter.
//
InstallWizard.ClassInstallHeader.InstallFunction = DIF_DESTROYWIZARDDATA; InstallWizard.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); if(!SetupDiSetClassInstallParams(hDevInfo, &spDevInfoData, &InstallWizard.ClassInstallHeader, sizeof(SP_INSTALLWIZARD_DATA)) ) { DebugTrace(TRACE_ERROR,(("AddDevice: ERROR!! SetupDiSetClassInstallParams() failed with active hDevInfo.\r\n"))); }
//
// Let isntaller free context data.
//
SetupDiCallClassInstaller(DIF_DESTROYWIZARDDATA, hDevInfo, &spDevInfoData );
//
// Destroy infoset.
//
SetupDiDestroyDeviceInfoList(hDevInfo); }
DebugTrace(TRACE_PROC_LEAVE,(("AddDevice: Leaving... Ret=VOID.\r\n"))); return; }
BOOL CALLBACK RemoveDevice( HWND hWnd, HINSTANCE hInst, LPTSTR lpszCmdLine, int nCmdShow ) {
HANDLE hDevInfo; SP_DEVINFO_DATA spDevInfoData; SP_REMOVEDEVICE_PARAMS spRemoveDeviceParams; BOOL bStatus; BOOL bIsInterfaceOnly; DWORD err; DWORD dwDeviceIndex; TCHAR szTemp[MAX_FRIENDLYNAME+1];
DebugTrace(TRACE_PROC_ENTER,(("RemoveDevice: Enter...\r\n")));
//
// Initialize local.
//
hDevInfo = INVALID_HANDLE_VALUE; bStatus = FALSE; err = ERROR_SUCCESS; bIsInterfaceOnly = FALSE; dwDeviceIndex = INVALID_DEVICE_INDEX;
memset (&spDevInfoData, 0, sizeof(SP_DEVINFO_DATA)); memset((void *)&spRemoveDeviceParams, 0, sizeof(SP_REMOVEDEVICE_PARAMS)); memset(szTemp, 0, sizeof(szTemp));
//
// Check the argument.
//
if(NULL == lpszCmdLine){ DebugTrace(TRACE_ERROR,(("RemoveDevice: ERROR!! Invalid argumet.\r\n"))); goto RemoveDevice_Err; } // if(NULL == lpszCmdLine)
lstrcpyn(szTemp, lpszCmdLine, ARRAYSIZE(szTemp)-1); DebugTrace(TRACE_STATUS,(("RemoveDevice: Removing \"%ws\".\r\n"), szTemp));
//
// Get removing device element.
//
hDevInfo = SelectDevInfoFromDeviceId(szTemp);
if(INVALID_HANDLE_VALUE != hDevInfo){ spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); SetupDiGetSelectedDevice(hDevInfo, &spDevInfoData); } else {
//
// See if it's "Interface-only" device.
//
hDevInfo = GetDeviceInterfaceIndex(szTemp, &dwDeviceIndex); if( (INVALID_HANDLE_VALUE == hDevInfo) || (INVALID_DEVICE_INDEX == dwDeviceIndex) ) { DebugTrace(TRACE_ERROR,(("RemoveDevice: ERROR!! Can't find \"%ws\".\r\n"), szTemp)); goto RemoveDevice_Err; }
//
// This is "Interface-only" device.
//
bIsInterfaceOnly = TRUE;
} // if(INVALID_HANDLE_VALUE != hDevInfo)
if(bIsInterfaceOnly){ DebugTrace(TRACE_STATUS,(("RemoveDevice: Uninstalling interface-only device.\r\n")));
//
// Uninstalling "Interface-only" device.
//
CDevice cdThis(hDevInfo, dwDeviceIndex); bStatus = (NO_ERROR == cdThis.Remove(NULL));
} else { // if(bIsInterfaceOnly)
DebugTrace(TRACE_STATUS,(("RemoveDevice: Uninstalling a device w/ devnode.\r\n")));
//
// Uninstalling device w/ devnode.
//
if(!SetupDiSetSelectedDevice(hDevInfo, &spDevInfoData )){ err=GetLastError(); goto RemoveDevice_Err; }
//
// Call class installer to remove selected device.
//
spRemoveDeviceParams.ClassInstallHeader.InstallFunction = DIF_REMOVE; spRemoveDeviceParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); spRemoveDeviceParams.Scope = DI_REMOVEDEVICE_GLOBAL;
if(!SetupDiSetClassInstallParams(hDevInfo, &spDevInfoData, &spRemoveDeviceParams.ClassInstallHeader, sizeof(SP_REMOVEDEVICE_PARAMS) )){ err=GetLastError(); goto RemoveDevice_Err; }
if(!SetupDiCallClassInstaller(DIF_REMOVE, hDevInfo, &spDevInfoData )){ err=GetLastError(); goto RemoveDevice_Err; }
//
// Removal succeeded.
//
bStatus = TRUE;
} // if(bIsInterfaceOnly)
RemoveDevice_Err:
if(IS_VALID_HANDLE(hDevInfo)){ SetupDiDestroyDeviceInfoList(hDevInfo); } DebugTrace(TRACE_PROC_LEAVE,(("RemoveDevice... Ret=0x%x Err=0x%x.\r\n"), bStatus, err)); return bStatus; } // RemoveDevice()
DLLEXPORT VOID CALLBACK InstallWiaService( HWND hwnd, HINSTANCE hinst, LPTSTR lpszCmdLine, int nCmdShow ) { DWORD dwError; DWORD dwStiCount; DWORD dwWiaCount; HANDLE hProcess;
DebugTrace(TRACE_PROC_ENTER,(("InstallWiaService: Enter...\r\n")));
//
// Remove old service entry.
//
GetDeviceCount(&dwWiaCount, &dwStiCount);
//
// Install WIA service. This will install only if the service failed to install during processing of STI.INF, else
// it will simply change the StartType.
//
dwError = StiServiceInstall(FALSE, TRUE, // Disable by default
TEXT("NT AUTHORITY\\LocalService"), TEXT("")); if(NOERROR != dwError){ DebugTrace(TRACE_ERROR,(("InstallWiaService: ERROR!! Unable to install service. Err=0x%x\n"), dwError)); } // if(NOERROR != dwError)
//
// Register WIA DLLs.
//
hProcess = ExecCommandLine(TEXT("regsvr32.exe /s wiaservc.dll"), EXECDIR_SYSTEM32); if(IS_VALID_HANDLE(hProcess)){ CloseHandle(hProcess); }
hProcess = ExecCommandLine(TEXT("regsvr32.exe /s sti.dll"), EXECDIR_SYSTEM32); if(IS_VALID_HANDLE(hProcess)){ CloseHandle(hProcess); }
hProcess = ExecCommandLine(TEXT("regsvr32.exe /s wiascr.dll"), EXECDIR_SYSTEM32); if(IS_VALID_HANDLE(hProcess)){ CloseHandle(hProcess); }
hProcess = ExecCommandLine(TEXT("regsvr32.exe /s wiashext.dll"), EXECDIR_SYSTEM32); if(IS_VALID_HANDLE(hProcess)){ CloseHandle(hProcess); }
hProcess = ExecCommandLine(TEXT("regsvr32.exe /s camocx.dll"), EXECDIR_SYSTEM32); if(IS_VALID_HANDLE(hProcess)){ CloseHandle(hProcess); }
hProcess = ExecCommandLine(TEXT("regsvr32.exe /s wiadefui.dll"), EXECDIR_SYSTEM32); if(IS_VALID_HANDLE(hProcess)){ CloseHandle(hProcess); }
hProcess = ExecCommandLine(TEXT("wiaacmgr.exe /RegServer"), EXECDIR_SYSTEM32); if(IS_VALID_HANDLE(hProcess)){ CloseHandle(hProcess); }
hProcess = ExecCommandLine(TEXT("regsvr32.exe /s wiavusd.dll"), EXECDIR_SYSTEM32); if(IS_VALID_HANDLE(hProcess)){ CloseHandle(hProcess); }
hProcess = ExecCommandLine(TEXT("regsvr32.exe /s wiasf.ax"), EXECDIR_SYSTEM32); if(IS_VALID_HANDLE(hProcess)){ CloseHandle(hProcess); }
hProcess = ExecCommandLine(TEXT("rundll32.exe sti.dll,MigrateRegisteredSTIAppsForWIAEvents %%l"), EXECDIR_SYSTEM32); if(IS_VALID_HANDLE(hProcess)){ CloseHandle(hProcess); }
DebugTrace(TRACE_PROC_LEAVE,(("InstallWiaService: Leaving... Ret=VOID.\r\n")));
} // InstallWiaService()
HANDLE SelectDevInfoFromDeviceId( LPTSTR pszDeviceId ) { TCHAR szTemp[MAX_DEVICE_ID]; HANDLE hDevInfo; GUID Guid; DWORD Idx; SP_DEVINFO_DATA spDevInfoData; BOOL bFound; HKEY hKeyDevice; ULONG cbData; LONG lResult;
DebugTrace(TRACE_PROC_ENTER,(("SelectDevInfoFromDeviceId: Enter...\r\n")));
//
// Initialize local.
//
hDevInfo = INVALID_HANDLE_VALUE; Guid = GUID_DEVCLASS_IMAGE; // Guid = KSCATEGORY_CAPTURE;
Idx = 0; cbData = 0; bFound = FALSE; hKeyDevice = NULL; lResult = ERROR_SUCCESS;
memset(szTemp, 0, sizeof(szTemp)); memset(&spDevInfoData, 0, sizeof(spDevInfoData));
//
// Check argument.
//
if(NULL == pszDeviceId){ DebugTrace(TRACE_ERROR,(("SelectDevInfoFromDeviceId: Invalid arbument.\r\n")));
hDevInfo = INVALID_HANDLE_VALUE; goto SelectDevInfoFromDeviceId_return; }
//
// Get device info set of specified class.
//
hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, DIGCF_PROFILE); if (hDevInfo == INVALID_HANDLE_VALUE) { DebugTrace(TRACE_ERROR,(("SelectDevInfoFromDeviceId: SetupDiGetClassDevs failed. Err=0x%x\r\n"), GetLastError()));
hDevInfo = INVALID_HANDLE_VALUE; goto SelectDevInfoFromDeviceId_return; }
spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA); for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++) {
DebugTrace(TRACE_STATUS,(("SelectDevInfoFromDeviceId: Checking Device(0x%x)\r\n"), Idx)); hKeyDevice = SetupDiOpenDevRegKey (hDevInfo, &spDevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ);
if (hKeyDevice != INVALID_HANDLE_VALUE) {
//
// Is DeviceId == pszDeviceId?
//
cbData = sizeof(szTemp)-sizeof(TEXT('\0')); lResult = RegQueryValueEx(hKeyDevice, REGSTR_VAL_DEVICE_ID, NULL, NULL, (LPBYTE)szTemp, &cbData); if(ERROR_SUCCESS == lResult){
if(_tcsicmp((LPCTSTR)pszDeviceId, (LPCTSTR)szTemp) != 0) {
//
// Doesn't match, skip this one.
//
RegCloseKey(hKeyDevice); continue; } } else { DebugTrace(TRACE_ERROR,(("SelectDevInfoFromDeviceId: can't get DeviceId. Err=0x%x\r\n"), GetLastError())); RegCloseKey(hKeyDevice); continue; }
//
// Found the target!
//
bFound = TRUE; RegCloseKey(hKeyDevice); break; } else { DebugTrace(TRACE_ERROR,(("SelectDevInfoFromDeviceId: Invalid handle.\r\n"), GetLastError())); } // if (hKeyDevice != INVALID_HANDLE_VALUE)
} //for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++)
SelectDevInfoFromDeviceId_return:
if(!bFound){
//
// FriendleName is not found.
//
if (IS_VALID_HANDLE(hDevInfo)) { SetupDiDestroyDeviceInfoList(hDevInfo); hDevInfo = INVALID_HANDLE_VALUE; } } else {
//
// Device found. Select found device.
//
SetupDiSetSelectedDevice(hDevInfo, &spDevInfoData); }
DebugTrace(TRACE_PROC_LEAVE,(("SelectDevInfoFromDeviceId: Leaving... Ret=0x%x\r\n"), hDevInfo));
return hDevInfo; } // SelectDevInfoFromDeviceId()
HANDLE GetDeviceInterfaceIndex( LPTSTR pszDeviceId, DWORD *pdwIndex ) { TCHAR szTemp[MAX_DEVICE_ID]; HANDLE hDevInfo; GUID Guid; DWORD Idx; SP_DEVICE_INTERFACE_DATA spDevInterfaceData; BOOL bFound; HKEY hKeyInterface; ULONG cbData; LONG lResult;
DebugTrace(TRACE_PROC_ENTER,(("GetDeviceInterfaceIndex: Enter... DeviceId=%ws\r\n"), pszDeviceId));
//
// Initialize local.
//
hDevInfo = INVALID_HANDLE_VALUE; Guid = GUID_DEVCLASS_IMAGE; Idx = 0; cbData = 0; bFound = FALSE; hKeyInterface = NULL; lResult = ERROR_SUCCESS;
memset(szTemp, 0, sizeof(szTemp)); memset(&spDevInterfaceData, 0, sizeof(spDevInterfaceData));
//
// Check argument.
//
if(NULL == pszDeviceId){ DebugTrace(TRACE_ERROR,(("GetDeviceInterfaceIndex: Invalid arbument.\r\n")));
hDevInfo = INVALID_HANDLE_VALUE; goto GetDeviceInterfaceIndex_return; }
//
// Get device info set of specified class interface.
//
hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PROFILE); if (hDevInfo == INVALID_HANDLE_VALUE) { DebugTrace(TRACE_ERROR,(("GetDeviceInterfaceIndex: SetupDiGetClassDevs failed. Err=0x%x\r\n"), GetLastError()));
hDevInfo = INVALID_HANDLE_VALUE; goto GetDeviceInterfaceIndex_return; }
spDevInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); for (Idx = 0; SetupDiEnumDeviceInterfaces (hDevInfo, NULL, &Guid, Idx, &spDevInterfaceData); Idx++) {
DebugTrace(TRACE_STATUS,(("GetDeviceInterfaceIndex: Checking Interface(0x%x)\r\n"), Idx)); hKeyInterface = SetupDiOpenDeviceInterfaceRegKey(hDevInfo, &spDevInterfaceData, 0, KEY_ALL_ACCESS); if (INVALID_HANDLE_VALUE != hKeyInterface) {
//
// Is FriendlyName == pszLocalName?
//
cbData = sizeof(szTemp)-sizeof(TEXT('\0')); lResult = RegQueryValueEx(hKeyInterface, REGSTR_VAL_DEVICE_ID, NULL, NULL, (LPBYTE)szTemp, &cbData); if(ERROR_SUCCESS == lResult){
if(_tcsicmp((LPCTSTR)pszDeviceId, (LPCTSTR)szTemp) == 0) {
//
// Found the target!
//
bFound = TRUE; RegCloseKey(hKeyInterface); break; } } else { // if(ERROR_SUCCESS == lResult)
DebugTrace(TRACE_STATUS,(("GetDeviceInterfaceIndex: can't get DeviceID. Err=0x%x\r\n"), GetLastError())); } // if(ERROR_SUCCESS == lResult)
RegCloseKey(hKeyInterface); hKeyInterface = NULL; } else { // if (hKeyDevice != INVALID_HANDLE_VALUE)
DWORD Err; Err = GetLastError(); DebugTrace(TRACE_ERROR,(("GetDeviceInterfaceIndex: Invalid handle. Err=0x%x.\r\n"), Err)); } // if (hKeyDevice != INVALID_HANDLE_VALUE)
} //for (Idx = 0; SetupDiEnumDeviceInterface (hDevInfo, NULL, &Guid, Idx, &spDevInterfaceData); Idx++)
GetDeviceInterfaceIndex_return:
if(FALSE == bFound){ if (IS_VALID_HANDLE(hDevInfo)) { SetupDiDestroyDeviceInfoList(hDevInfo); hDevInfo = INVALID_HANDLE_VALUE; }
*pdwIndex = INVALID_DEVICE_INDEX;
} else {
//
// Interface found.
//
*pdwIndex = Idx; }
DebugTrace(TRACE_PROC_LEAVE,(("GetDeviceInterfaceIndex: Leaving... Ret=0x%x\r\n"), hDevInfo));
return hDevInfo; } // GetDeviceInterfaceIndex()
INT CALLBACK iHdwWizardDlgCallback( IN HWND hwndDlg, IN UINT uMsg, IN LPARAM lParam ) /*++
Routine Description:
Call back used to remove the "?" from the wizard page.
Arguments:
hwndDlg - Handle to the property sheet dialog box.
uMsg - Identifies the message being received. This parameter is one of the following values:
PSCB_INITIALIZED - Indicates that the property sheet is being initialized. The lParam value is zero for this message.
PSCB_PRECREATE Indicates that the property sheet is about to be created. The hwndDlg parameter is NULL and the lParam parameter is a pointer to a dialog template in memory. This template is in the form of a DLGTEMPLATE structure followed by one or more DLGITEMTEMPLATE structures.
lParam - Specifies additional information about the message. The meaning of this value depends on the uMsg parameter.
Return Value:
The function returns zero.
--*/ {
switch( uMsg ) {
case PSCB_INITIALIZED: break;
case PSCB_PRECREATE: if( lParam ){
DLGTEMPLATE *pDlgTemplate = (DLGTEMPLATE *)lParam; pDlgTemplate->style &= ~DS_CONTEXTHELP; } break; }
return FALSE; }
BOOL SetSelectDevTitleAndInstructions( HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData, LPCTSTR pszTitle, LPCTSTR pszSubTitle, LPCTSTR pszInstn, LPCTSTR pszListLabel ) /*++
Routine Description:
Arguments:
Return Value:
Side effects:
--*/ { SP_SELECTDEVICE_PARAMS SelectDevParams; BOOL fRet;
memset((void *)&SelectDevParams, 0, sizeof(SelectDevParams));
if ( pszTitle && (lstrlen(pszTitle) + 1 > MAX_TITLE_LEN ) ) {
SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
if ( pszSubTitle && (lstrlen(pszSubTitle) + 1 > MAX_SUBTITLE_LEN )) {
SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
if ( pszInstn && (lstrlen(pszInstn) + 1 > MAX_INSTRUCTION_LEN )) {
SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
if ( pszListLabel && (lstrlen(pszListLabel) + 1 > MAX_LABEL_LEN )) {
SetLastError(ERROR_INVALID_PARAMETER); return FALSE; }
SelectDevParams.ClassInstallHeader.cbSize = sizeof(SelectDevParams.ClassInstallHeader);
if ( !SetupDiGetClassInstallParams(hDevInfo, pspDevInfoData, &SelectDevParams.ClassInstallHeader, sizeof(SelectDevParams), NULL) ) { DWORD dwErr = GetLastError();
if (ERROR_NO_CLASSINSTALL_PARAMS != dwErr ) { return FALSE; } }
if ( pszTitle ){ lstrcpyn(SelectDevParams.Title, pszTitle, ARRAYSIZE(SelectDevParams.Title)); SelectDevParams.Title[ARRAYSIZE(SelectDevParams.Title)-1] = TEXT('\0'); }
if ( pszSubTitle ){ lstrcpyn(SelectDevParams.SubTitle, pszSubTitle, ARRAYSIZE(SelectDevParams.SubTitle)); SelectDevParams.SubTitle[ARRAYSIZE(SelectDevParams.SubTitle)-1] = TEXT('\0'); }
if ( pszInstn ){ lstrcpyn(SelectDevParams.Instructions, pszInstn, ARRAYSIZE(SelectDevParams.Instructions)); SelectDevParams.Instructions[ARRAYSIZE(SelectDevParams.Instructions)-1] = TEXT('\0'); } if ( pszListLabel ){ lstrcpyn(SelectDevParams.ListLabel, pszListLabel, ARRAYSIZE(SelectDevParams.ListLabel)); SelectDevParams.ListLabel[ARRAYSIZE(SelectDevParams.ListLabel)-1] = TEXT('\0'); }
SelectDevParams.ClassInstallHeader.InstallFunction = DIF_SELECTDEVICE; fRet = SetupDiSetClassInstallParams(hDevInfo, pspDevInfoData, &SelectDevParams.ClassInstallHeader, sizeof(SelectDevParams));
return fRet;
}
BOOL WINAPI WiaDeviceEnum( VOID ) { BOOL rVal = FALSE; SC_HANDLE hSvcMgr = NULL; SC_HANDLE hService = NULL; SERVICE_STATUS ServiceStatus; UINT uiRetry = 10;
DebugTrace(TRACE_PROC_ENTER,(("WiaDeviceEnum: Enter... \r\n")));
//
// Open Service Control Manager.
//
hSvcMgr = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS ); if (!hSvcMgr) { DebugTrace(TRACE_ERROR,(("WiaDeviceEnum: ERROR!! OpenSCManager failed. Err=0x%x\n"), GetLastError())); goto exit; }
//
// Open WIA service.
//
hService = OpenService( hSvcMgr, STI_SERVICE_NAME, SERVICE_ALL_ACCESS );
if (!hService) { DebugTrace(TRACE_ERROR,(("WiaDeviceEnum: ERROR!! OpenService failed. Err=0x%x\n"), GetLastError())); goto exit; }
//
// Inform WIA service to refresh its device list.
//
rVal = ControlService(hService, STI_SERVICE_CONTROL_REFRESH, &ServiceStatus); if (!rVal) { DebugTrace(TRACE_WARNING,(("WiaDeviceEnum: WARNING!! ControlService failed. Err=0x%x\n"), GetLastError())); goto exit; }
exit: if(NULL != hService){ CloseServiceHandle( hService ); } if(NULL != hSvcMgr){ CloseServiceHandle( hSvcMgr ); }
DebugTrace(TRACE_PROC_LEAVE,(("WiaDeviceEnum: Leaving... Ret=0x%x\n"), rVal)); return rVal;
} // WiaDeviceEnum()
DLLEXPORT PWIA_PORTLIST WINAPI WiaCreatePortList( LPWSTR szDeviceId ) {
PWIA_PORTLIST pReturn; GUID PortGuid; HDEVINFO hPortDevInfo = NULL; DWORD Idx; DWORD dwRequired; DWORD dwNumberOfPorts; DWORD dwSize; CStringArray csaPortName; TCHAR szPortName[MAX_DESCRIPTION]; TCHAR szPortFriendlyName[MAX_DESCRIPTION];
BOOL bIsSerial; BOOL bIsParallel; BOOL bIsAutoCapable; BOOL bIsPortSelectable; //
// Initialize local.
//
Idx = 0; hPortDevInfo = NULL; pReturn = NULL; dwSize = 0; dwRequired = 0; dwNumberOfPorts = 0;
bIsSerial = TRUE; bIsParallel = TRUE; bIsAutoCapable = FALSE; bIsPortSelectable = TRUE;
memset(szPortName, 0, sizeof(szPortName)); memset(szPortFriendlyName, 0, sizeof(szPortFriendlyName));
//
// Convert from WCHAR to TCHAR
//
#ifndef UNICODE
//
// #pragma message("Not optimal conversion - reimplement if running on nonUNICODE system")
//
// TCHAR szDeviceIdConverted[STI_MAX_INTERNAL_NAME_LENGTH+1];
//
// szDeviceIdConverted[0] = TEXT('\0');
// MultiByteToWideChar(CP_ACP,
// 0,
// szDeviceIdConverted,
// -1,
// szDeviceId,
// sizeof(szDeviceId));
//
#else
// On UNICODE system use the same buffer
#define szDeviceIdConverted szDeviceId
#endif
if(!CheckPortForDevice(szDeviceIdConverted, &bIsSerial, &bIsParallel, &bIsAutoCapable, &bIsPortSelectable)){ DebugTrace(TRACE_ERROR,(("WiaGetPortList: ERROR!! Unable to get port info for device.\r\n")));
pReturn = NULL; goto WiaGetPortList_return; }
if(bIsAutoCapable){ dwNumberOfPorts++; csaPortName.Add(AUTO); }
//
// Enumerate all Port class devices if "PortSelect=NO" is not specified.
//
if(bIsPortSelectable){
//
// Get GUID of port device.
//
if(!SetupDiClassGuidsFromName (PORTS, &PortGuid, sizeof(GUID), &dwRequired)){ DebugTrace(TRACE_ERROR,(("WiaGetPortList: ERROR!! SetupDiClassGuidsFromName Failed. Err=0x%lX\r\n"), GetLastError()));
pReturn = NULL; goto WiaGetPortList_return; } // if(!SetupDiClassGuidsFromName (PORTS, &Guid, sizeof(GUID), &dwRequired))
//
// Get device info set of port devices.
//
hPortDevInfo = SetupDiGetClassDevs (&PortGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE); if (hPortDevInfo == INVALID_HANDLE_VALUE) { DebugTrace(TRACE_ERROR,(("WiaGetPortList: ERROR!! SetupDiGetClassDevs Failed. Err=0x%lX\r\n"), GetLastError()));
pReturn = NULL; goto WiaGetPortList_return; }
//
// Process all of device element listed in device info set.
//
for(Idx = 0; GetPortNamesFromIndex(hPortDevInfo, Idx, szPortName, szPortFriendlyName); Idx++){
//
// Add valid Port CreateFile/Friendly Name to array.
//
if(0 == lstrlen(szPortName)){ DebugTrace(TRACE_ERROR,(("WiaGetPortList: ERROR!! Invalid Port/Friendly Name.\r\n")));
szPortName[0] = TEXT('\0'); continue; }
DebugTrace(TRACE_STATUS,(("WiaGetPortList: Found Port %d: %ws.\r\n"), Idx, szPortName));
//
// Check it's port type.
//
if(_tcsstr((const TCHAR *)szPortName, TEXT("LPT"))){ if(!bIsParallel){ szPortName[0] = TEXT('\0'); continue; } }
if(_tcsstr((const TCHAR *)szPortName, TEXT("COM"))){ if(!bIsSerial){ szPortName[0] = TEXT('\0'); continue; } }
dwNumberOfPorts++; csaPortName.Add(szPortName);
szPortName[0] = TEXT('\0');
} // for(Idx = 0; GetPortNamesFromIndex(hPortDevInfo, Idx, szPortName, szPortFriendlyName); Idx++)
} // if(bIsPortSelectable)
if(0 != dwNumberOfPorts){
//
// Allocate memory for returning structure.
//
dwSize = sizeof(DWORD) + sizeof(LPTSTR)*dwNumberOfPorts; pReturn = (PWIA_PORTLIST)new BYTE[dwSize]; if(NULL == pReturn){ goto WiaGetPortList_return; } memset(pReturn, 0, dwSize);
//
// Fill in the info.
//
pReturn->dwNumberOfPorts = dwNumberOfPorts; for(Idx = 0; Idx < dwNumberOfPorts; Idx++){ pReturn->szPortName[Idx] = (LPTSTR)new BYTE[lstrlen(csaPortName[Idx])*sizeof(TCHAR)+sizeof(TEXT('\0'))]; if(NULL != pReturn->szPortName[Idx]){ lstrcpy(pReturn->szPortName[Idx], csaPortName[Idx]); } else { WiaDestroyPortList(pReturn); pReturn = NULL; break; } // if(NULL != pReturn->szPortName[Idx])
} // for(Idx = 0; Idx < dwNumberOfPorts; Idx++)
} // if(0 != dwNumberOfPorts)
WiaGetPortList_return:
//
// Cleanup
//
if ( IS_VALID_HANDLE(hPortDevInfo) ) { SetupDiDestroyDeviceInfoList(hPortDevInfo); }
return pReturn;
} // WiaCreatePortList()
DLLEXPORT VOID WINAPI WiaDestroyPortList( PWIA_PORTLIST pWiaPortList ) { DWORD Idx;
if(NULL == pWiaPortList){ return; } // if(NULL == pWiaPortList)
for(Idx = 0; Idx < pWiaPortList->dwNumberOfPorts; Idx++){ if(NULL != pWiaPortList->szPortName[Idx]){ delete pWiaPortList->szPortName[Idx]; } // if(NULL != pWiaPortList->szPortName[Idx])
} // for(Idx = 0; Idx < pWiaPortList; Idx++)
delete pWiaPortList;
return;
} // WiaDestroyPortList()
BOOL CheckPortForDevice( LPTSTR szDeviceId, BOOL *pbIsSerial, BOOL *pbIsParallel, BOOL *pbIsAutoCapable, BOOL *pbIsPortSelectable ) {
GUID WiaGuid; HDEVINFO hWiaDevInfo; DWORD dwCapability; SP_DEVINFO_DATA spDevInfoData; CString csConnection; CString csPortSelect; DWORD dwDeviceIndex; HKEY hkDevice; BOOL bCapabilityAcquired; BOOL bRet;
BOOL bIsSerial; BOOL bIsParallel; BOOL bIsAutoCapable; BOOL bIsPortSelectable; DWORD dwIsPnp;
//
// Initialize locals.
//
dwCapability = 0; dwIsPnp = 0; hWiaDevInfo = INVALID_HANDLE_VALUE; dwDeviceIndex = INVALID_DEVICE_INDEX; WiaGuid = GUID_DEVCLASS_IMAGE;
bRet = FALSE; bCapabilityAcquired = FALSE;
bIsSerial = TRUE; bIsParallel = TRUE; bIsAutoCapable = FALSE; bIsPortSelectable = TRUE;
memset(&spDevInfoData, 0, sizeof(spDevInfoData));
//
// Get specified device property.
//
hWiaDevInfo = SelectDevInfoFromDeviceId(szDeviceId);
if(INVALID_HANDLE_VALUE != hWiaDevInfo){ spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); SetupDiGetSelectedDevice(hWiaDevInfo, &spDevInfoData);
hkDevice = SetupDiOpenDevRegKey(hWiaDevInfo, &spDevInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ);
if(INVALID_HANDLE_VALUE != hkDevice){ csConnection.Load(hkDevice, CONNECTION); csPortSelect.Load(hkDevice, PORTSELECT); GetDwordFromRegistry(hkDevice, ISPNP, &dwIsPnp);
if(GetDwordFromRegistry(hkDevice, CAPABILITIES, &dwCapability)){
bCapabilityAcquired = TRUE;
} // if(GetDwordFromRegistry(hkDevice, CAPABILITIES, &dwCapability))
RegCloseKey(hkDevice); hkDevice = (HKEY)INVALID_HANDLE_VALUE;
} // if(INVALID_HANDLE_VALUE != hkDevice)
SetupDiDestroyDeviceInfoList(hWiaDevInfo); hWiaDevInfo = INVALID_HANDLE_VALUE;
} else { // if(INVALID_HANDLE_VALUE != hDevInfo)
SP_DEVICE_INTERFACE_DATA spDeviceInterfaceData;
//
// See if it's "Interface-only" device.
//
hWiaDevInfo = GetDeviceInterfaceIndex(szDeviceId, &dwDeviceIndex); if( (INVALID_HANDLE_VALUE == hWiaDevInfo) || (INVALID_DEVICE_INDEX == dwDeviceIndex) ) { DebugTrace(TRACE_ERROR,(("CheckPortForDevice: ERROR!! Can't find \"%ws\".\r\n"), szDeviceId)); bRet = FALSE; goto CheckPortForDevice_return; }
spDeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if(!SetupDiEnumDeviceInterfaces(hWiaDevInfo, NULL, &WiaGuid, dwDeviceIndex, &spDeviceInterfaceData)){ DebugTrace(TRACE_ERROR,(("CheckPortForDevice: ERROR!! SetupDiEnumDeviceInterfaces() failed. Err=0x%x.\r\n"), GetLastError())); bRet = FALSE; goto CheckPortForDevice_return; }
hkDevice = SetupDiOpenDeviceInterfaceRegKey(hWiaDevInfo, &spDeviceInterfaceData, 0, KEY_READ); if(INVALID_HANDLE_VALUE == hkDevice){ DebugTrace(TRACE_ERROR,(("CheckPortForDevice: ERROR!! SetupDiOpenDeviceInterfaceRegKey() failed. Err=0x%x.\r\n"), GetLastError())); bRet = FALSE; goto CheckPortForDevice_return; }
csConnection.Load(hkDevice, CONNECTION); csPortSelect.Load(hkDevice, PORTSELECT); GetDwordFromRegistry(hkDevice, ISPNP, &dwIsPnp); if(GetDwordFromRegistry(hkDevice, CAPABILITIES, &dwCapability)){
bCapabilityAcquired = TRUE;
} // if(GetDwordFromRegistry(hkDevice, CAPABILITIES, &dwCapability))
RegCloseKey(hkDevice); hkDevice = (HKEY)INVALID_HANDLE_VALUE;
} // else (INVALID_HANDLE_VALUE != hDevInfo)
//
// Check what port should be shown.
//
if(0 != dwIsPnp){ //
// This is PnP device. No port should be available.
//
bRet = FALSE; goto CheckPortForDevice_return; }
if(bCapabilityAcquired){
if(csConnection.IsEmpty()){ bIsSerial = TRUE; bIsParallel = TRUE; } else { if(0 == _tcsicmp((LPTSTR)csConnection, SERIAL)){ bIsSerial = TRUE; bIsParallel = FALSE; } if(0 == _tcsicmp((LPTSTR)csConnection, PARALLEL)){ bIsSerial = FALSE; bIsParallel = TRUE; } }
if(dwCapability & STI_GENCAP_AUTO_PORTSELECT){ bIsAutoCapable = TRUE; } else { bIsAutoCapable = FALSE; }
if(0 == MyStrCmpi(csPortSelect, NO)){ bIsPortSelectable = FALSE; } else {// if(0 == lstrcmpi(csPortSelect, NO))
bIsPortSelectable = TRUE; } } else { DebugTrace(TRACE_ERROR,(("CheckPortForDevice: ERROR!! Unable to acquire info from registry.\r\n"))); bRet = FALSE; goto CheckPortForDevice_return; }
//
// Operation succeeded.
//
bRet = TRUE;
CheckPortForDevice_return:
if(IS_VALID_HANDLE(hWiaDevInfo)){ SetupDiDestroyDeviceInfoList(hWiaDevInfo); }
if(bRet){ *pbIsSerial = bIsSerial; *pbIsParallel = bIsParallel; *pbIsAutoCapable = bIsAutoCapable; *pbIsPortSelectable = bIsPortSelectable; }
return bRet;
} // CheckPortForDevice()
DLLEXPORT BOOL WINAPI MigrateDevice( PDEVICE_INFO pMigratingDevice ) { BOOL bSucceeded;
//
// Initialize local.
//
bSucceeded = TRUE;
//
// Validate migrating device.
//
if(!IsValidMigrationDevice(pMigratingDevice)){ DebugTrace(TRACE_ERROR,(("MigrateDevice: ERROR!! Invalid migration device.\r\n"))); bSucceeded = FALSE; return FALSE; } // if(!IsValidMigrationDevice(pMigratingDevice))
//
// Create Device class object.
//
CDevice cdThis(pMigratingDevice);
//
// Set default devnode selector.
//
cdThis.SetDevnodeSelectCallback((DEVNODESELCALLBACK)GetDevinfoFromPortName);
//
// Generate FriendlyName.
//
cdThis.NameDefaultUniqueName();
//
// Install(migrate) the device.
//
bSucceeded = cdThis.PreInstall(); if(bSucceeded){ bSucceeded = cdThis.Install(); }
//
// Do final touch. Clean up if failed, or finish installation.
//
cdThis.PostInstall(bSucceeded);
//MigrateDevice_return:
return bSucceeded; } // MigrateDevice()
BOOL IsValidMigrationDevice( PDEVICE_INFO pMigratingDevice ) { BOOL bRet; DWORD dwCounter; PARAM_LIST CurrentParam; PVOID pNext; HINF hInf;
//
// Initialize local.
//
bRet = FALSE; dwCounter = 0; pNext = NULL; hInf = INVALID_HANDLE_VALUE; memset(&CurrentParam, 0, sizeof(CurrentParam)); //
// See if given pointer is NULL.
//
if(NULL == pMigratingDevice){ DebugTrace(TRACE_ERROR,(("IsValidMigrationDevice: ERROR!! Passed pointer is NULL.\r\n"))); bRet = FALSE; goto IsValidMigrationDevice_return; } // if(NULL == pMigratingDevice)
//
// See if all members are valid.
//
_try { //
// It must have valid FridendlyName.
//
if( (NULL == pMigratingDevice->pszFriendlyName) || (!IsValidFriendlyName(pMigratingDevice->pszFriendlyName)) ) { DebugTrace(TRACE_ERROR,(("IsValidMigrationDevice: ERROR!! Invalid FriendlyName.\r\n"))); bRet = FALSE; goto IsValidMigrationDevice_return; }
//
// It must have valid INF path and section.
//
if( (NULL == pMigratingDevice->pszInfPath) || (NULL == pMigratingDevice->pszInfSection) ) { DebugTrace(TRACE_ERROR,(("IsValidMigrationDevice: ERROR!! Invalid INF info.\r\n"))); bRet = FALSE; goto IsValidMigrationDevice_return; }
//
// See if INF exists or not.
//
hInf = SetupOpenInfFileA(pMigratingDevice->pszInfPath, NULL, INF_STYLE_WIN4, NULL); if(INVALID_HANDLE_VALUE == hInf){ DebugTrace(TRACE_ERROR,(("IsValidMigrationDevice: ERROR!! INF doesn't exist.\r\n"))); bRet = FALSE; goto IsValidMigrationDevice_return; } else { SetupCloseInfFile(hInf); hInf = INVALID_HANDLE_VALUE; }
//
// It must have valid DeviceData parameters.
//
dwCounter = pMigratingDevice->dwNumberOfDeviceDataKey; pNext = pMigratingDevice->pDeviceDataParam; for(;dwCounter != 0; dwCounter--){ CurrentParam = *((PPARAM_LIST)pNext); pNext = CurrentParam.pNext; } // for(;dwCounter != 0; dwCounter--)
} // _try
_except (EXCEPTION_EXECUTE_HANDLER) { DebugTrace(TRACE_ERROR,(("IsValidMigrationDevice: ERROR!! Access to given data caused AV.\r\n"))); bRet = FALSE; goto IsValidMigrationDevice_return; } // _except (EXCEPTION_EXECUTE_HANDLER)
//
// Data validated.
//
bRet = TRUE; IsValidMigrationDevice_return: return bRet;
} // IsValidMigrationDevice()
|