/******************************************************************************* * * (C) COPYRIGHT MICROSOFT CORP., 1998 * * TITLE: AddDevice.cpp * * VERSION: 2.0 * * AUTHOR: Marke * * DATE: 9 Jan, 1998 * * DESCRIPTION: * Temp UI for adding Wia remote devices * *******************************************************************************/ #include "precomp.h" #include "stiexe.h" #include #include #include "wiacfact.h" #include "devmgr.h" #include "devinfo.h" #include "resource.h" #include "helpers.h" // // global info // WIA_ADD_DEVICE *gpAddDev; IWiaDevMgr *gpIWiaDevMgr; extern HINSTANCE g_hInst; #define REGSTR_PATH_STICONTROL_W L"System\\CurrentControlSet\\Control\\StillImage" #define REGSTR_PATH_STICONTROL_DEVLIST_W L"System\\CurrentControlSet\\Control\\StillImage\\DevList" #ifdef WINNT /**************************************************************************\ * AddDeviceDlgProc * * Dialog proc for add device dialog. * * Arguments: * * hDlg - window handle of the dialog box * message - type of message * wParam - message-specific information * lParam - message-specific information * * Return Value: * * Status * * History: * * 1/11/1999 Original Version * \**************************************************************************/ INT_PTR APIENTRY AddDeviceDlgProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) { LPWSTR lpwstrName; UINT ui; UINT uButton; switch (message) { case WM_INITDIALOG: // // default is local // CheckRadioButton(hDlg,IDC_LOCAL,IDC_REMOTE,IDC_REMOTE); break; case WM_COMMAND: switch(wParam) { // // end function // case IDOK: lpwstrName = &gpAddDev->wszServerName[0]; ui = GetDlgItemTextW(hDlg,IDC_DRIVER_NAME,lpwstrName,MAX_PATH); uButton = (UINT)SendDlgItemMessage(hDlg,IDC_LOCAL,BM_GETCHECK,0,0); if (uButton == 1) { gpAddDev->bLocal = TRUE; } else { gpAddDev->bLocal = FALSE; } EndDialog(hDlg, FALSE); return (TRUE); case IDCANCEL: EndDialog(hDlg, FALSE); return (TRUE); } break; } return (FALSE); } /**************************************************************************\ * DevListDlgProc * * Dialog proc for device list dialog. * * Arguments: * * hDlg - window handle of the dialog box * message - type of message * wParam - message-specific information * lParam - message-specific information * * Return Value: * * Status * * History: * * 1/11/1999 Original Version * \**************************************************************************/ INT_PTR APIENTRY DevListDlgProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) { static LONG cDevice = 0; static BSTR bstrDevice[16]; switch (message) { case WM_INITDIALOG: if (gpIWiaDevMgr != NULL) { IEnumWIA_DEV_INFO *pWiaEnumDevInfo; HRESULT hr; LONG cDevice = 0; // // get device list, only want to see local devices // hr = gpIWiaDevMgr->EnumDeviceInfo(WIA_DEVINFO_ENUM_LOCAL,&pWiaEnumDevInfo); if (hr == S_OK) { do { IWiaPropertyStorage *pIWiaPropStg; ULONG cEnum; // // get next device // hr = pWiaEnumDevInfo->Next(1,&pIWiaPropStg,&cEnum); if (hr == S_OK) { // // read device name // PROPSPEC PropSpec[2]; PROPVARIANT PropVar[2]; memset(PropVar,0,sizeof(PropVar)); PropSpec[0].ulKind = PRSPEC_PROPID; PropSpec[0].propid = WIA_DIP_DEV_ID; PropSpec[1].ulKind = PRSPEC_PROPID; PropSpec[1].propid = WIA_DIP_DEV_DESC; hr = pIWiaPropStg->ReadMultiple(sizeof(PropSpec)/sizeof(PROPSPEC), PropSpec, PropVar); if (hr == S_OK) { CHAR szTemp[ MAX_PATH ]; // // make sure property is string based // if (PropVar[0].vt == VT_BSTR) { //WideCharToMultiByte(CP_ACP, // 0, // PropVar[1].bstrVal, // -1, // szTemp, // MAX_PATH, // NULL, // NULL); // //SendDlgItemMessage(hDlg,IDC_COMBO1,CB_INSERTSTRING,cDevice,(long)szTemp); // SendDlgItemMessageW(hDlg,IDC_COMBO1,CB_INSERTSTRING,cDevice,(LONG_PTR)PropVar[1].bstrVal); bstrDevice[cDevice] = ::SysAllocString(PropVar[0].bstrVal); cDevice++; } FreePropVariantArray(sizeof(PropSpec)/sizeof(PROPSPEC),PropVar); } else { ReportReadWriteMultipleError(hr, "DevListDlgProc", NULL, TRUE, sizeof(PropSpec)/sizeof(PROPSPEC), PropSpec); } pIWiaPropStg->Release(); } } while (hr == S_OK); SendDlgItemMessage(hDlg,IDC_COMBO1,CB_SETCURSEL,0,0); pWiaEnumDevInfo->Release(); } else { TCHAR msg[MAX_PATH]; wsprintf(msg,TEXT("Error code = 0x%lx"),hr); MessageBox(NULL,msg,TEXT("Error in EnumDeviceInfo"),MB_OK); EndDialog(hDlg, FALSE); } } break; case WM_COMMAND: switch(wParam) { // // end function // case IDOK: { LRESULT lRet = SendDlgItemMessage(hDlg,IDC_COMBO1,CB_GETCURSEL,0,0); if (lRet != CB_ERR) { gpAddDev->bstrDeviceID = bstrDevice[lRet]; bstrDevice[lRet] = NULL; for (int index=0;indexwszServerName; WCHAR *wszIndex = pAddDev->bstrDeviceID; // // skip leading \\ if it is there // if (wszServer[0] == L'\\') { wszServer = &wszServer[2]; } // // skip STI CLASS // wszIndex = &wszIndex[39]; lstrcpyW(wszTemp,wszServer); lstrcatW(wszTemp,L"-"); lstrcatW(wszTemp,wszIndex); // // try to create remote device // IWiaItem *pWiaItemRoot = NULL; hr = gpIWiaDevMgr->CreateDevice(pAddDev->bstrDeviceID, &pWiaItemRoot); if (hr == S_OK) { // // read device properties // IWiaPropertyStorage *piprop; hr = pWiaItemRoot->QueryInterface(IID_IWiaPropertyStorage,(void **)&piprop); if (hr == S_OK) { // // read dev info prop // PROPSPEC PropSpec[WIA_NUM_DIP]; PROPVARIANT PropVar[WIA_NUM_DIP]; memset(PropVar,0,sizeof(PropVar)); for (int Index = 0;IndexReadMultiple(sizeof(PropSpec)/sizeof(PROPSPEC), PropSpec, PropVar); if (hr == S_OK) { // // create device registry entry // lResult = RegCreateKeyExW( hKeySetup, wszTemp, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyDevice, NULL) ; if (lResult != ERROR_SUCCESS) { FreePropVariantArray(sizeof(PropSpec)/sizeof(PROPSPEC),PropVar); piprop->Release(); pWiaItemRoot->Release(); return E_FAIL; } for (Index = 0;IndexwszServerName, (lstrlenW(pAddDev->wszServerName)+1) * sizeof(WCHAR)) ; // // need a local device ID // { WCHAR wszLocalID[MAX_PATH]; DWORD dwType = REG_SZ; DWORD dwSize = MAX_PATH; RegQueryValueExW(hKeyDevice, (LPCWSTR)WIA_DIP_DEV_ID_STR, 0, &dwType, (LPBYTE)wszLocalID, &dwSize); // // copy dev id to remote dev id. This is used in calls to // remote dev manager to create the device // RegSetValueExW(hKeyDevice, (LPCWSTR)WIA_DIP_REMOTE_DEV_ID_STR, 0, REG_SZ, (LPBYTE)wszLocalID, (lstrlenW(wszLocalID)+1) * sizeof(WCHAR)) ; // // make local dev id unique // lstrcatW(wszLocalID,pAddDev->wszServerName); RegSetValueExW(hKeyDevice, (LPCWSTR)WIA_DIP_DEV_ID_STR, 0, REG_SZ, (LPBYTE)wszLocalID, (lstrlenW(wszLocalID)+1) * sizeof(WCHAR)) ; } RegCloseKey(hKeyDevice); } else { ReportReadWriteMultipleError(hr, "WriteDeviceProperties", NULL, TRUE, sizeof(PropSpec)/sizeof(PROPSPEC), PropSpec); } FreePropVariantArray(sizeof(PropSpec)/sizeof(PROPSPEC),PropVar); piprop->Release(); } DBG_ERR(("WriteDeviceProperties, QI for IID_IWiaPropertyStorage failed")); pWiaItemRoot->Release(); } else { } return hr; } /**************************************************************************\ * VerifyRemoteDeviceList * * Open a registry key to the STI device list. * * Arguments: * * phKey - Pointer to returned registry key. * * Return Value: * * Status * * History: * * 3/2/1999 Original Version * \**************************************************************************/ HRESULT VerifyRemoteDeviceList(HKEY *phKey) { DBG_FN(::VerifyRemoteDeviceList); HRESULT hr; LONG lResult; LPWSTR szKeyNameSTI = REGSTR_PATH_STICONTROL_W; LPWSTR szKeyNameDev = REGSTR_PATH_STICONTROL_DEVLIST_W; HKEY hKeySTI; HKEY hKeyDev; *phKey = NULL; // // try to open dev list // if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, szKeyNameDev, 0, KEY_READ | KEY_WRITE, &hKeyDev) == ERROR_SUCCESS) { *phKey = hKeyDev; return S_OK; } // // open sti device control and create DevList Key // if (RegOpenKeyExW (HKEY_LOCAL_MACHINE, szKeyNameSTI, 0, KEY_READ | KEY_WRITE, &hKeySTI) == ERROR_SUCCESS) { // // try to create key // lResult = RegCreateKeyExW( hKeySTI, L"DevList", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKeyDev, NULL) ; if (lResult == ERROR_SUCCESS) { *phKey = hKeyDev; hr = S_OK; } else { DBG_ERR(("VerifyRemoteDeviceList: Couldn't create DevList Key")); hr = E_FAIL; } RegCloseKey(hKeySTI); } else { DBG_ERR(("VerifyRemoteDeviceList: Couldn't open STI DeviceControl Key")); hr = E_FAIL; } return(hr); } /**************************************************************************\ * DisplayAddDlg * * Put up the add device dialog. * * Arguments: * * pAddDev - Add device information data. * * Return Value: * * status * * History: * * 9/2/1998 Original Version * \**************************************************************************/ HRESULT DisplayAddDlg(WIA_ADD_DEVICE *pAddDev) { DBG_FN(::DisplayAddDlg); if (pAddDev == NULL) { return E_INVALIDARG; } HRESULT hr = S_OK; // // if reentrant then need semaphore // gpAddDev = pAddDev; INT_PTR iret = DialogBox(g_hInst,MAKEINTRESOURCE(IDD_ADD_DLG),pAddDev->hWndParent,AddDeviceDlgProc); if (iret == -1) { int err = GetLastError(); return HRESULT_FROM_WIN32(err); } // // Remote or local // if (pAddDev->bLocal == FALSE) { // // try to connect to remote dev manager // COSERVERINFO coServInfo; MULTI_QI multiQI[1]; multiQI[0].pIID = &IID_IWiaDevMgr; multiQI[0].pItf = NULL; coServInfo.pwszName = gpAddDev->wszServerName; coServInfo.pAuthInfo = NULL; coServInfo.dwReserved1 = 0; coServInfo.dwReserved2 = 0; // // create connection to dev mgr // hr = CoCreateInstanceEx( CLSID_WiaDevMgr, NULL, CLSCTX_REMOTE_SERVER, &coServInfo, 1, &multiQI[0] ); if (hr == S_OK) { gpIWiaDevMgr = (IWiaDevMgr*)multiQI[0].pItf; // // display list of devices on this server // INT_PTR iret = DialogBox(g_hInst,MAKEINTRESOURCE(IDD_DIALOG_DEVLIST),pAddDev->hWndParent,DevListDlgProc); if (iret != 0) { // // add device to auxillary list // HKEY hKeySetup; hr = VerifyRemoteDeviceList(&hKeySetup); if (hr == S_OK) { // // look for machine name // hr = WriteDeviceProperties(hKeySetup,pAddDev); RegCloseKey(hKeySetup); } } else { hr = E_FAIL; } gpIWiaDevMgr->Release(); gpIWiaDevMgr = NULL; } } else { // // local named driver // return E_NOTIMPL; } return hr; } #endif