Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

800 lines
20 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1998
  4. *
  5. * TITLE: AddDevice.cpp
  6. *
  7. * VERSION: 2.0
  8. *
  9. * AUTHOR: Marke
  10. *
  11. * DATE: 9 Jan, 1998
  12. *
  13. * DESCRIPTION:
  14. * Temp UI for adding Wia remote devices
  15. *
  16. *******************************************************************************/
  17. #include "precomp.h"
  18. #include "stiexe.h"
  19. #include <wiamindr.h>
  20. #include <wiadbg.h>
  21. #include "wiacfact.h"
  22. #include "devmgr.h"
  23. #include "devinfo.h"
  24. #include "resource.h"
  25. #include "helpers.h"
  26. //
  27. // global info
  28. //
  29. WIA_ADD_DEVICE *gpAddDev;
  30. IWiaDevMgr *gpIWiaDevMgr;
  31. extern HINSTANCE g_hInst;
  32. #define REGSTR_PATH_STICONTROL_W L"System\\CurrentControlSet\\Control\\StillImage"
  33. #define REGSTR_PATH_STICONTROL_DEVLIST_W L"System\\CurrentControlSet\\Control\\StillImage\\DevList"
  34. #ifdef WINNT
  35. /**************************************************************************\
  36. * AddDeviceDlgProc
  37. *
  38. * Dialog proc for add device dialog.
  39. *
  40. * Arguments:
  41. *
  42. * hDlg - window handle of the dialog box
  43. * message - type of message
  44. * wParam - message-specific information
  45. * lParam - message-specific information
  46. *
  47. * Return Value:
  48. *
  49. * Status
  50. *
  51. * History:
  52. *
  53. * 1/11/1999 Original Version
  54. *
  55. \**************************************************************************/
  56. INT_PTR
  57. APIENTRY AddDeviceDlgProc(
  58. HWND hDlg,
  59. UINT message,
  60. WPARAM wParam,
  61. LPARAM lParam
  62. )
  63. {
  64. LPWSTR lpwstrName;
  65. UINT ui;
  66. UINT uButton;
  67. switch (message) {
  68. case WM_INITDIALOG:
  69. //
  70. // default is local
  71. //
  72. CheckRadioButton(hDlg,IDC_LOCAL,IDC_REMOTE,IDC_REMOTE);
  73. break;
  74. case WM_COMMAND:
  75. switch(wParam) {
  76. //
  77. // end function
  78. //
  79. case IDOK:
  80. lpwstrName = &gpAddDev->wszServerName[0];
  81. ui = GetDlgItemTextW(hDlg,IDC_DRIVER_NAME,lpwstrName,MAX_PATH);
  82. uButton = (UINT)SendDlgItemMessage(hDlg,IDC_LOCAL,BM_GETCHECK,0,0);
  83. if (uButton == 1) {
  84. gpAddDev->bLocal = TRUE;
  85. } else {
  86. gpAddDev->bLocal = FALSE;
  87. }
  88. EndDialog(hDlg, FALSE);
  89. return (TRUE);
  90. case IDCANCEL:
  91. EndDialog(hDlg, FALSE);
  92. return (TRUE);
  93. }
  94. break;
  95. }
  96. return (FALSE);
  97. }
  98. /**************************************************************************\
  99. * DevListDlgProc
  100. *
  101. * Dialog proc for device list dialog.
  102. *
  103. * Arguments:
  104. *
  105. * hDlg - window handle of the dialog box
  106. * message - type of message
  107. * wParam - message-specific information
  108. * lParam - message-specific information
  109. *
  110. * Return Value:
  111. *
  112. * Status
  113. *
  114. * History:
  115. *
  116. * 1/11/1999 Original Version
  117. *
  118. \**************************************************************************/
  119. INT_PTR
  120. APIENTRY DevListDlgProc(
  121. HWND hDlg,
  122. UINT message,
  123. WPARAM wParam,
  124. LPARAM lParam
  125. )
  126. {
  127. static LONG cDevice = 0;
  128. static BSTR bstrDevice[16];
  129. switch (message) {
  130. case WM_INITDIALOG:
  131. if (gpIWiaDevMgr != NULL) {
  132. IEnumWIA_DEV_INFO *pWiaEnumDevInfo;
  133. HRESULT hr;
  134. LONG cDevice = 0;
  135. //
  136. // get device list, only want to see local devices
  137. //
  138. hr = gpIWiaDevMgr->EnumDeviceInfo(WIA_DEVINFO_ENUM_LOCAL,&pWiaEnumDevInfo);
  139. if (hr == S_OK) {
  140. do
  141. {
  142. IWiaPropertyStorage *pIWiaPropStg;
  143. ULONG cEnum;
  144. //
  145. // get next device
  146. //
  147. hr = pWiaEnumDevInfo->Next(1,&pIWiaPropStg,&cEnum);
  148. if (hr == S_OK)
  149. {
  150. //
  151. // read device name
  152. //
  153. PROPSPEC PropSpec[2];
  154. PROPVARIANT PropVar[2];
  155. memset(PropVar,0,sizeof(PropVar));
  156. PropSpec[0].ulKind = PRSPEC_PROPID;
  157. PropSpec[0].propid = WIA_DIP_DEV_ID;
  158. PropSpec[1].ulKind = PRSPEC_PROPID;
  159. PropSpec[1].propid = WIA_DIP_DEV_DESC;
  160. hr = pIWiaPropStg->ReadMultiple(sizeof(PropSpec)/sizeof(PROPSPEC),
  161. PropSpec,
  162. PropVar);
  163. if (hr == S_OK)
  164. {
  165. CHAR szTemp[ MAX_PATH ];
  166. //
  167. // make sure property is string based
  168. //
  169. if (PropVar[0].vt == VT_BSTR)
  170. {
  171. //WideCharToMultiByte(CP_ACP,
  172. // 0,
  173. // PropVar[1].bstrVal,
  174. // -1,
  175. // szTemp,
  176. // MAX_PATH,
  177. // NULL,
  178. // NULL);
  179. //
  180. //SendDlgItemMessage(hDlg,IDC_COMBO1,CB_INSERTSTRING,cDevice,(long)szTemp);
  181. //
  182. SendDlgItemMessageW(hDlg,IDC_COMBO1,CB_INSERTSTRING,cDevice,(LONG_PTR)PropVar[1].bstrVal);
  183. bstrDevice[cDevice] = ::SysAllocString(PropVar[0].bstrVal);
  184. cDevice++;
  185. }
  186. FreePropVariantArray(sizeof(PropSpec)/sizeof(PROPSPEC),PropVar);
  187. }
  188. else {
  189. ReportReadWriteMultipleError(hr, "DevListDlgProc", NULL, TRUE, sizeof(PropSpec)/sizeof(PROPSPEC), PropSpec);
  190. }
  191. pIWiaPropStg->Release();
  192. }
  193. } while (hr == S_OK);
  194. SendDlgItemMessage(hDlg,IDC_COMBO1,CB_SETCURSEL,0,0);
  195. pWiaEnumDevInfo->Release();
  196. } else {
  197. TCHAR msg[MAX_PATH];
  198. wsprintf(msg,TEXT("Error code = 0x%lx"),hr);
  199. MessageBox(NULL,msg,TEXT("Error in EnumDeviceInfo"),MB_OK);
  200. EndDialog(hDlg, FALSE);
  201. }
  202. }
  203. break;
  204. case WM_COMMAND:
  205. switch(wParam) {
  206. //
  207. // end function
  208. //
  209. case IDOK:
  210. {
  211. LRESULT lRet = SendDlgItemMessage(hDlg,IDC_COMBO1,CB_GETCURSEL,0,0);
  212. if (lRet != CB_ERR) {
  213. gpAddDev->bstrDeviceID = bstrDevice[lRet];
  214. bstrDevice[lRet] = NULL;
  215. for (int index=0;index<cDevice;index++) {
  216. if (bstrDevice[index] != NULL) {
  217. SysFreeString(bstrDevice[index] );
  218. }
  219. }
  220. }
  221. EndDialog(hDlg, (lRet != CB_ERR));
  222. return (TRUE);
  223. }
  224. case IDCANCEL:
  225. for (int index=0;index<cDevice;index++) {
  226. if (bstrDevice[index] != NULL) {
  227. SysFreeString(bstrDevice[index] );
  228. }
  229. }
  230. EndDialog(hDlg, FALSE);
  231. return (TRUE);
  232. }
  233. break;
  234. }
  235. return (FALSE);
  236. }
  237. PROPID propidDev[WIA_NUM_DIP] =
  238. {
  239. WIA_DIP_DEV_ID ,
  240. WIA_DIP_VEND_DESC ,
  241. WIA_DIP_DEV_DESC ,
  242. WIA_DIP_DEV_TYPE ,
  243. WIA_DIP_PORT_NAME ,
  244. WIA_DIP_DEV_NAME ,
  245. WIA_DIP_SERVER_NAME ,
  246. WIA_DIP_REMOTE_DEV_ID,
  247. WIA_DIP_UI_CLSID
  248. };
  249. LPOLESTR pszPropName[WIA_NUM_DIP] =
  250. {
  251. WIA_DIP_DEV_ID_STR,
  252. WIA_DIP_VEND_DESC_STR,
  253. WIA_DIP_DEV_DESC_STR,
  254. WIA_DIP_DEV_TYPE_STR,
  255. WIA_DIP_PORT_NAME_STR,
  256. WIA_DIP_DEV_NAME_STR,
  257. WIA_DIP_SERVER_NAME_STR,
  258. WIA_DIP_REMOTE_DEV_ID_STR,
  259. WIA_DIP_UI_CLSID_STR
  260. };
  261. DWORD pszPropType[WIA_NUM_DIP] =
  262. {
  263. REG_SZ,
  264. REG_SZ,
  265. REG_SZ,
  266. REG_DWORD,
  267. REG_SZ,
  268. REG_SZ,
  269. REG_SZ,
  270. REG_SZ,
  271. REG_SZ
  272. };
  273. /**************************************************************************\
  274. * WriteDeviceProperties
  275. *
  276. * Write all device information properties to registry.
  277. *
  278. * Arguments:
  279. *
  280. * hKeySetup - Open registry key.
  281. * pAddDev - Add device information data.
  282. *
  283. * Return Value:
  284. *
  285. * status
  286. *
  287. * History:
  288. *
  289. * 9/2/1998 Original Version
  290. *
  291. \**************************************************************************/
  292. HRESULT
  293. WriteDeviceProperties(
  294. HKEY hKeySetup,
  295. WIA_ADD_DEVICE *pAddDev
  296. )
  297. {
  298. DBG_FN(::WriteDeviceProperties);
  299. HRESULT hr = S_OK;
  300. HKEY hKeyDevice;
  301. LONG lResult;
  302. //
  303. // build device connection name as SERVER-INDEX
  304. //
  305. WCHAR wszTemp[MAX_PATH];
  306. WCHAR *wszServer = pAddDev->wszServerName;
  307. WCHAR *wszIndex = pAddDev->bstrDeviceID;
  308. //
  309. // skip leading \\ if it is there
  310. //
  311. if (wszServer[0] == L'\\') {
  312. wszServer = &wszServer[2];
  313. }
  314. //
  315. // skip STI CLASS
  316. //
  317. wszIndex = &wszIndex[39];
  318. lstrcpyW(wszTemp,wszServer);
  319. lstrcatW(wszTemp,L"-");
  320. lstrcatW(wszTemp,wszIndex);
  321. //
  322. // try to create remote device
  323. //
  324. IWiaItem *pWiaItemRoot = NULL;
  325. hr = gpIWiaDevMgr->CreateDevice(pAddDev->bstrDeviceID, &pWiaItemRoot);
  326. if (hr == S_OK) {
  327. //
  328. // read device properties
  329. //
  330. IWiaPropertyStorage *piprop;
  331. hr = pWiaItemRoot->QueryInterface(IID_IWiaPropertyStorage,(void **)&piprop);
  332. if (hr == S_OK) {
  333. //
  334. // read dev info prop
  335. //
  336. PROPSPEC PropSpec[WIA_NUM_DIP];
  337. PROPVARIANT PropVar[WIA_NUM_DIP];
  338. memset(PropVar,0,sizeof(PropVar));
  339. for (int Index = 0;Index<WIA_NUM_DIP;Index++)
  340. {
  341. PropSpec[Index].ulKind = PRSPEC_PROPID;
  342. PropSpec[Index].propid = propidDev[Index];
  343. }
  344. hr = piprop->ReadMultiple(sizeof(PropSpec)/sizeof(PROPSPEC),
  345. PropSpec,
  346. PropVar);
  347. if (hr == S_OK) {
  348. //
  349. // create device registry entry
  350. //
  351. lResult = RegCreateKeyExW(
  352. hKeySetup,
  353. wszTemp,
  354. 0,
  355. NULL,
  356. REG_OPTION_NON_VOLATILE,
  357. KEY_ALL_ACCESS,
  358. NULL,
  359. &hKeyDevice,
  360. NULL) ;
  361. if (lResult != ERROR_SUCCESS) {
  362. FreePropVariantArray(sizeof(PropSpec)/sizeof(PROPSPEC),PropVar);
  363. piprop->Release();
  364. pWiaItemRoot->Release();
  365. return E_FAIL;
  366. }
  367. for (Index = 0;Index<WIA_NUM_DIP;Index++)
  368. {
  369. //
  370. // write dev info values to registry
  371. //
  372. if (pszPropType[Index] == REG_SZ) {
  373. //
  374. // write string prop
  375. //
  376. if (PropVar[Index].vt == VT_BSTR) {
  377. RegSetValueExW(hKeyDevice,
  378. (LPCWSTR)pszPropName[Index],
  379. 0,
  380. pszPropType[Index],
  381. (const UCHAR *)PropVar[Index].bstrVal,
  382. (lstrlenW(PropVar[Index].bstrVal)+1) * sizeof(WCHAR)) ;
  383. }
  384. } else {
  385. //
  386. // write int prop
  387. //
  388. RegSetValueExW(hKeyDevice,
  389. (LPCWSTR)pszPropName[Index],
  390. 0,
  391. pszPropType[Index],
  392. (const UCHAR *)&PropVar[Index].lVal,
  393. sizeof(DWORD)) ;
  394. }
  395. }
  396. //
  397. // server name must be remote server
  398. //
  399. RegSetValueExW(hKeyDevice,
  400. (LPCWSTR)WIA_DIP_SERVER_NAME_STR,
  401. 0,
  402. REG_SZ,
  403. (LPBYTE)pAddDev->wszServerName,
  404. (lstrlenW(pAddDev->wszServerName)+1) * sizeof(WCHAR)) ;
  405. //
  406. // need a local device ID
  407. //
  408. {
  409. WCHAR wszLocalID[MAX_PATH];
  410. DWORD dwType = REG_SZ;
  411. DWORD dwSize = MAX_PATH;
  412. RegQueryValueExW(hKeyDevice,
  413. (LPCWSTR)WIA_DIP_DEV_ID_STR,
  414. 0,
  415. &dwType,
  416. (LPBYTE)wszLocalID,
  417. &dwSize);
  418. //
  419. // copy dev id to remote dev id. This is used in calls to
  420. // remote dev manager to create the device
  421. //
  422. RegSetValueExW(hKeyDevice,
  423. (LPCWSTR)WIA_DIP_REMOTE_DEV_ID_STR,
  424. 0,
  425. REG_SZ,
  426. (LPBYTE)wszLocalID,
  427. (lstrlenW(wszLocalID)+1) * sizeof(WCHAR)) ;
  428. //
  429. // make local dev id unique
  430. //
  431. lstrcatW(wszLocalID,pAddDev->wszServerName);
  432. RegSetValueExW(hKeyDevice,
  433. (LPCWSTR)WIA_DIP_DEV_ID_STR,
  434. 0,
  435. REG_SZ,
  436. (LPBYTE)wszLocalID,
  437. (lstrlenW(wszLocalID)+1) * sizeof(WCHAR)) ;
  438. }
  439. RegCloseKey(hKeyDevice);
  440. }
  441. else {
  442. ReportReadWriteMultipleError(hr, "WriteDeviceProperties", NULL, TRUE, sizeof(PropSpec)/sizeof(PROPSPEC), PropSpec);
  443. }
  444. FreePropVariantArray(sizeof(PropSpec)/sizeof(PROPSPEC),PropVar);
  445. piprop->Release();
  446. }
  447. DBG_ERR(("WriteDeviceProperties, QI for IID_IWiaPropertyStorage failed"));
  448. pWiaItemRoot->Release();
  449. }
  450. else {
  451. }
  452. return hr;
  453. }
  454. /**************************************************************************\
  455. * VerifyRemoteDeviceList
  456. *
  457. * Open a registry key to the STI device list.
  458. *
  459. * Arguments:
  460. *
  461. * phKey - Pointer to returned registry key.
  462. *
  463. * Return Value:
  464. *
  465. * Status
  466. *
  467. * History:
  468. *
  469. * 3/2/1999 Original Version
  470. *
  471. \**************************************************************************/
  472. HRESULT
  473. VerifyRemoteDeviceList(HKEY *phKey)
  474. {
  475. DBG_FN(::VerifyRemoteDeviceList);
  476. HRESULT hr;
  477. LONG lResult;
  478. LPWSTR szKeyNameSTI = REGSTR_PATH_STICONTROL_W;
  479. LPWSTR szKeyNameDev = REGSTR_PATH_STICONTROL_DEVLIST_W;
  480. HKEY hKeySTI;
  481. HKEY hKeyDev;
  482. *phKey = NULL;
  483. //
  484. // try to open dev list
  485. //
  486. if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
  487. szKeyNameDev,
  488. 0,
  489. KEY_READ | KEY_WRITE,
  490. &hKeyDev) == ERROR_SUCCESS) {
  491. *phKey = hKeyDev;
  492. return S_OK;
  493. }
  494. //
  495. // open sti device control and create DevList Key
  496. //
  497. if (RegOpenKeyExW (HKEY_LOCAL_MACHINE,
  498. szKeyNameSTI,
  499. 0,
  500. KEY_READ | KEY_WRITE,
  501. &hKeySTI) == ERROR_SUCCESS) {
  502. //
  503. // try to create key
  504. //
  505. lResult = RegCreateKeyExW(
  506. hKeySTI,
  507. L"DevList",
  508. 0,
  509. NULL,
  510. REG_OPTION_NON_VOLATILE,
  511. KEY_ALL_ACCESS,
  512. NULL,
  513. &hKeyDev,
  514. NULL) ;
  515. if (lResult == ERROR_SUCCESS) {
  516. *phKey = hKeyDev;
  517. hr = S_OK;
  518. } else {
  519. DBG_ERR(("VerifyRemoteDeviceList: Couldn't create DevList Key"));
  520. hr = E_FAIL;
  521. }
  522. RegCloseKey(hKeySTI);
  523. } else {
  524. DBG_ERR(("VerifyRemoteDeviceList: Couldn't open STI DeviceControl Key"));
  525. hr = E_FAIL;
  526. }
  527. return(hr);
  528. }
  529. /**************************************************************************\
  530. * DisplayAddDlg
  531. *
  532. * Put up the add device dialog.
  533. *
  534. * Arguments:
  535. *
  536. * pAddDev - Add device information data.
  537. *
  538. * Return Value:
  539. *
  540. * status
  541. *
  542. * History:
  543. *
  544. * 9/2/1998 Original Version
  545. *
  546. \**************************************************************************/
  547. HRESULT
  548. DisplayAddDlg(WIA_ADD_DEVICE *pAddDev)
  549. {
  550. DBG_FN(::DisplayAddDlg);
  551. if (pAddDev == NULL) {
  552. return E_INVALIDARG;
  553. }
  554. HRESULT hr = S_OK;
  555. //
  556. // if reentrant then need semaphore
  557. //
  558. gpAddDev = pAddDev;
  559. INT_PTR iret = DialogBox(g_hInst,MAKEINTRESOURCE(IDD_ADD_DLG),pAddDev->hWndParent,AddDeviceDlgProc);
  560. if (iret == -1) {
  561. int err = GetLastError();
  562. return HRESULT_FROM_WIN32(err);
  563. }
  564. //
  565. // Remote or local
  566. //
  567. if (pAddDev->bLocal == FALSE) {
  568. //
  569. // try to connect to remote dev manager
  570. //
  571. COSERVERINFO coServInfo;
  572. MULTI_QI multiQI[1];
  573. multiQI[0].pIID = &IID_IWiaDevMgr;
  574. multiQI[0].pItf = NULL;
  575. coServInfo.pwszName = gpAddDev->wszServerName;
  576. coServInfo.pAuthInfo = NULL;
  577. coServInfo.dwReserved1 = 0;
  578. coServInfo.dwReserved2 = 0;
  579. //
  580. // create connection to dev mgr
  581. //
  582. hr = CoCreateInstanceEx(
  583. CLSID_WiaDevMgr,
  584. NULL,
  585. CLSCTX_REMOTE_SERVER,
  586. &coServInfo,
  587. 1,
  588. &multiQI[0]
  589. );
  590. if (hr == S_OK) {
  591. gpIWiaDevMgr = (IWiaDevMgr*)multiQI[0].pItf;
  592. //
  593. // display list of devices on this server
  594. //
  595. INT_PTR iret = DialogBox(g_hInst,MAKEINTRESOURCE(IDD_DIALOG_DEVLIST),pAddDev->hWndParent,DevListDlgProc);
  596. if (iret != 0) {
  597. //
  598. // add device to auxillary list
  599. //
  600. HKEY hKeySetup;
  601. hr = VerifyRemoteDeviceList(&hKeySetup);
  602. if (hr == S_OK) {
  603. //
  604. // look for machine name
  605. //
  606. hr = WriteDeviceProperties(hKeySetup,pAddDev);
  607. RegCloseKey(hKeySetup);
  608. }
  609. } else {
  610. hr = E_FAIL;
  611. }
  612. gpIWiaDevMgr->Release();
  613. gpIWiaDevMgr = NULL;
  614. }
  615. } else {
  616. //
  617. // local named driver
  618. //
  619. return E_NOTIMPL;
  620. }
  621. return hr;
  622. }
  623. #endif