Source code of Windows XP (NT5)
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.

3555 lines
96 KiB

  1. /*****************************************************************************
  2. *
  3. * StiObj.c
  4. *
  5. * Copyright (c) 1996 Microsoft Corporation. All Rights Reserved.
  6. *
  7. * Abstract:
  8. *
  9. * The IStillImage main interface.
  10. *
  11. * Contents:
  12. *
  13. * CStiObj_New
  14. *
  15. *****************************************************************************/
  16. #include "sticomm.h"
  17. #include "enum.h"
  18. #include "stisvc.h"
  19. //
  20. // Private defines
  21. //
  22. #define DbgFl DbgFlSti
  23. //
  24. //
  25. //
  26. #undef IStillImage
  27. //
  28. // DEVICE_INFO_SIZE and WIA_DEVICE_INFO_SIZE
  29. //
  30. // These defines represent the space needed to store the device information
  31. // structs and the string data that some of their members point to.
  32. // STI_DEVICE_INFORMATION has 5 strings while STI_WIA_DEVICE_INFORMATION
  33. // has 6. To be completely safe, these device info sizes should be
  34. // (MAX_PATH * sizeof(WCHAR) * no. of strings) + struct size.
  35. //
  36. #define DEVICE_INFO_SIZE (sizeof(STI_DEVICE_INFORMATION)+(MAX_PATH * sizeof(WCHAR) * 5))
  37. #define WIA_DEVICE_INFO_SIZE (sizeof(STI_WIA_DEVICE_INFORMATION)+(MAX_PATH * sizeof(WCHAR) * 6))
  38. //
  39. // DEVICE_LIST_SIZE. Note that this is currently a fixed size, but will change
  40. // as soon we abstract device enumeration into a class.
  41. //
  42. // Device list size is fixed at the moment. It's size is:
  43. // MAX_NUM_DEVICES * (max(DEVICE_INFO_SIZE, WIA_DEVICE_INFO_SIZE))
  44. // i.e. enough to hold MAX_NUM_DEVICES only.
  45. #define MAX_NUM_DEVICES 16
  46. #define DEVICE_LIST_SIZE MAX_NUM_DEVICES * (max(DEVICE_INFO_SIZE, WIA_DEVICE_INFO_SIZE))
  47. /*****************************************************************************
  48. *
  49. * @doc INTERNAL
  50. *
  51. * @struct CStiObj |
  52. *
  53. * The <i IStillImage> object, from which other things come.
  54. *
  55. *
  56. * @field IStillImage | Sti |
  57. *
  58. * STI interface
  59. *
  60. * @field IStillImage | dwVersion |
  61. *
  62. * Version identifier
  63. *
  64. * @comm
  65. *
  66. * We contain no instance data, so no critical section
  67. * is necessary.
  68. *
  69. *****************************************************************************/
  70. typedef struct CStiObj {
  71. /* Supported interfaces */
  72. TFORM(IStillImage) TFORM(sti);
  73. SFORM(IStillImage) SFORM(sti);
  74. DWORD dwVersion;
  75. } CStiObj, *PCStiObj;
  76. #define ThisClass CStiObj
  77. #define ThisInterface TFORM(IStillImage)
  78. #define ThisInterfaceA IStillImageA
  79. #define ThisInterfaceW IStillImageW
  80. #define ThisInterfaceT IStillImage
  81. /*****************************************************************************
  82. *
  83. * Declare the interfaces we will be providing.
  84. *
  85. *****************************************************************************/
  86. Primary_Interface(CStiObj, TFORM(ThisInterfaceT));
  87. Secondary_Interface(CStiObj, SFORM(ThisInterfaceT));
  88. /*****************************************************************************
  89. *
  90. * @doc EXTERNAL
  91. *
  92. * @method HRESULT | IStillImage | QueryInterface |
  93. *
  94. * Gives a client access to other interfaces on an object.
  95. *
  96. * @cwrap LPStillImage | lpStillImage
  97. *
  98. * @parm IN REFIID | riid |
  99. *
  100. * The requested interface's IID.
  101. *
  102. * @parm OUT LPVOID * | ppvObj |
  103. *
  104. * Receives a pointer to the obtained interface.
  105. *
  106. * @returns
  107. *
  108. * Returns a COM error code.
  109. *
  110. * @xref OLE documentation for <mf IUnknown::QueryInterface>.
  111. *
  112. *****************************************************************************
  113. *
  114. * @doc EXTERNAL
  115. *
  116. * @method HRESULT | IStillImage | AddRef |
  117. *
  118. * Increments the reference count for the interface.
  119. *
  120. * @cwrap LPStillImage | lpStillImage
  121. *
  122. * @returns
  123. *
  124. * Returns the object reference count.
  125. *
  126. * @xref OLE documentation for <mf IUnknown::AddRef>.
  127. *
  128. *****************************************************************************
  129. *
  130. * @doc EXTERNAL
  131. *
  132. * @method HRESULT | IStillImage | Release |
  133. *
  134. * Decrements the reference count for the interface.
  135. * If the reference count on the object falls to zero,
  136. * the object is freed from memory.
  137. *
  138. * @cwrap LPStillImage | lpStillImage
  139. *
  140. * @returns
  141. *
  142. * Returns the object reference count.
  143. *
  144. * @xref OLE documentation for <mf IUnknown::Release>.
  145. *
  146. *****************************************************************************
  147. *
  148. * @doc INTERNAL
  149. *
  150. * @method HRESULT | IStillImage | QIHelper |
  151. *
  152. * We don't have any dynamic interfaces and simply forward
  153. * to <f Common_QIHelper>.
  154. *
  155. * @parm IN REFIID | riid |
  156. *
  157. * The requested interface's IID.
  158. *
  159. * @parm OUT LPVOID * | ppvObj |
  160. *
  161. * Receives a pointer to the obtained interface.
  162. *
  163. *****************************************************************************
  164. *
  165. * @doc INTERNAL
  166. *
  167. * @method HRESULT | IStillImage | Finalize |
  168. *
  169. * We don't have any instance data, so we can just
  170. * forward to <f Common_Finalize>.
  171. *
  172. *****************************************************************************/
  173. #ifdef DEBUG
  174. Default_QueryInterface(CStiObj)
  175. Default_AddRef(CStiObj)
  176. Default_Release(CStiObj)
  177. #else
  178. #define CStiObj_QueryInterface Common_QueryInterface
  179. #define CStiObj_AddRef Common_AddRef
  180. #define CStiObj_Release Common_Release
  181. #endif
  182. #define CStiObj_QIHelper Common_QIHelper
  183. //#define CStiObj_Finalize Common_Finalize
  184. #pragma BEGIN_CONST_DATA
  185. #pragma END_CONST_DATA
  186. /*****************************************************************************
  187. *
  188. * @doc INTERNAL
  189. *
  190. * @method HRESULT | IStillImage | CreateDeviceHelper |
  191. *
  192. * Creates and initializes an instance of a device which is
  193. * specified by the GUID and IID.
  194. *
  195. * @cwrap LPStillImage | lpStillImage
  196. *
  197. * @parm IN PCGUID | pguid |
  198. *
  199. * See <mf IStillImage::CreateDevice>.
  200. *
  201. * @parm OUT PPV | ppvObj |
  202. *
  203. * See <mf IStillImage::CreateDevice>.
  204. *
  205. * @parm IN LPUNKNOWN | punkOuter |
  206. *
  207. * See <mf IStillImage::CreateDevice>.
  208. *
  209. * @parm IN RIID | riid |
  210. *
  211. * The interface the application wants to create. This will
  212. * be <i IStillImageDevice> .
  213. * If the object is aggregated, then this parameter is ignored.
  214. *
  215. * @returns
  216. *
  217. * Returns a COM error code.
  218. *
  219. *****************************************************************************/
  220. STDMETHODIMP
  221. CStiObj_CreateDeviceHelper(
  222. PCStiObj this,
  223. LPWSTR pwszDeviceName,
  224. PPV ppvObj,
  225. DWORD dwMode,
  226. PUNK punkOuter,
  227. RIID riid)
  228. {
  229. HRESULT hres = STIERR_INVALID_PARAM;
  230. EnterProc(CStiObj_CreateDeviceHelper,(_ "ppxG", this, pwszDeviceName, punkOuter, riid));
  231. hres = CStiDevice_New(punkOuter, riid, ppvObj);
  232. if (SUCCEEDED(hres) && punkOuter == 0) {
  233. PSTIDEVICE pdev = *ppvObj;
  234. hres = IStiDevice_Initialize(pdev, g_hInst,pwszDeviceName,this->dwVersion,dwMode);
  235. if (SUCCEEDED(hres)) {
  236. } else {
  237. Invoke_Release(ppvObj);
  238. }
  239. }
  240. ExitOleProcPpv(ppvObj);
  241. return hres;
  242. }
  243. /*****************************************************************************
  244. *
  245. * @doc EXTERNAL
  246. *
  247. * @method HRESULT | IStillImage | CreateDevice |
  248. *
  249. * Creates and initializes an instance of a device which is
  250. * specified by the GUID and IID.
  251. *
  252. * @cwrap LPStillImage | lpStillImage
  253. *
  254. * @parm REFGUID | rguid |
  255. * Identifies the instance of the
  256. * device for which the indicated interface
  257. * is requested. The <mf IStillImage::EnumDevices> method
  258. * can be used to determine which instance GUIDs are supported by
  259. * the system.
  260. *
  261. * @parm OUT LPSTIDEVICE * | lplpStillImageDevice |
  262. * Points to where to return
  263. * the pointer to the <i IStillImageDevice> interface, if successful.
  264. *
  265. * @parm IN LPUNKNOWN | punkOuter | Pointer to controlling unknown
  266. * for OLE aggregation, or 0 if the interface is not aggregated.
  267. * Most callers will pass 0.
  268. *
  269. * @comm Calling this function with <p punkOuter> = NULL
  270. * is equivalent to creating the object via
  271. * <f CoCreateInstance>(&CLSID_StillImageDevice, NULL,
  272. * CLSCTX_INPROC_SERVER, <p riid>, <p lplpStillImageDevice>);
  273. * then initializing it with <f Initialize>.
  274. *
  275. * Calling this function with <p punkOuter> != NULL
  276. * is equivalent to creating the object via
  277. * <f CoCreateInstance>(&CLSID_StillImageDevice, <p punkOuter>,
  278. * CLSCTX_INPROC_SERVER, &IID_IUnknown, <p lplpStillImageDevice>).
  279. * The aggregated object must be initialized manually.
  280. *
  281. * @returns
  282. *
  283. * Returns a COM error code. The following error codes are
  284. * intended to be illustrative and not necessarily comprehensive.
  285. *
  286. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  287. *
  288. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  289. * <p ppvOut> parameter is not a valid pointer.
  290. *
  291. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  292. * Out of memory.
  293. *
  294. * <c STIERR_NOINTERFACE> = <c E_NOINTERFACE>
  295. * The specified interface is not supported by the object.
  296. *
  297. * <c STIERR_DEVICENOTREG> = The device instance does not
  298. * correspond to a device that is registered with StillImage.
  299. *
  300. *****************************************************************************/
  301. STDMETHODIMP
  302. CStiObj_CreateDeviceW(
  303. PV pSti,
  304. LPWSTR pwszDeviceName,
  305. DWORD dwMode,
  306. PSTIDEVICE *ppDev,
  307. PUNK punkOuter
  308. )
  309. {
  310. HRESULT hres = STIERR_INVALID_PARAM;
  311. EnterProcR(IStillImage::CreateDevice,(_ "ppp", pSti, pwszDeviceName, punkOuter));
  312. // Validate passed pointer to interface and obtain pointer to object instance
  313. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  314. PCStiObj this = _thisPvNm(pSti, stiW);
  315. hres = CStiObj_CreateDeviceHelper(this, pwszDeviceName, (PPV)ppDev,dwMode,punkOuter, &IID_IStiDevice);
  316. }
  317. ExitOleProcPpv(ppDev);
  318. return hres;
  319. }
  320. STDMETHODIMP
  321. CStiObj_CreateDeviceA(
  322. PV pSti,
  323. LPCSTR pszDeviceName,
  324. DWORD dwMode,
  325. PSTIDEVICE *ppDev,
  326. PUNK punkOuter
  327. )
  328. {
  329. HRESULT hres = STIERR_INVALID_PARAM;
  330. EnterProcR(IStillImage::CreateDevice,(_ "ppp", pSti, pszDeviceName, punkOuter));
  331. // Validate passed pointer to interface and obtain pointer to object instance
  332. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  333. PCStiObj this = _thisPvNm(pSti, stiA);
  334. PVOID pBuffer = NULL;
  335. UINT uiSize = (lstrlenA(pszDeviceName)+1)*sizeof(WCHAR);
  336. hres = AllocCbPpv(uiSize, &pBuffer);
  337. if (SUCCEEDED(hres)) {
  338. *((LPWSTR)pBuffer) = L'\0';
  339. AToU(pBuffer,uiSize,pszDeviceName);
  340. hres = CStiObj_CreateDeviceHelper(this,
  341. (LPWSTR)pBuffer,
  342. (PPV)ppDev,
  343. dwMode,
  344. punkOuter,
  345. &IID_IStiDevice);
  346. FreePpv(&pBuffer);
  347. }
  348. }
  349. ExitOleProcPpv(ppDev);
  350. return hres;
  351. }
  352. /*****************************************************************************
  353. *
  354. * @doc INTERNAL
  355. *
  356. * @method HRESULT | IStillImage | GetDeviceInfoHelper |
  357. *
  358. *
  359. * @cwrap LPStillImage | lpStillImage
  360. *
  361. * @returns
  362. *
  363. * Returns a COM error code.
  364. *
  365. * No validation performed
  366. *
  367. *****************************************************************************/
  368. BOOL INLINE
  369. AddOneString(LPCWSTR pStart,LPCWSTR pNew,LPWSTR *ppTarget)
  370. {
  371. if (pStart + OSUtil_StrLenW(pNew) + 1 < *ppTarget ) {
  372. (*ppTarget)-= (OSUtil_StrLenW(pNew) + 1);
  373. OSUtil_lstrcpyW(*ppTarget,pNew);
  374. return TRUE;
  375. }
  376. return FALSE;
  377. }
  378. /*
  379. BOOL INLINE
  380. AddOneStringA(LPCSTR pStart,LPCSTR pNew,LPSTR *ppTarget)
  381. {
  382. if (pStart + lstrlenA(pNew) + 1 < *ppTarget ) {
  383. (*ppTarget)-= (lstrlenA(pNew) + 1);
  384. lstrcpyA(*ppTarget,pNew);
  385. return TRUE;
  386. }
  387. return FALSE;
  388. }
  389. */
  390. BOOL
  391. PullFromRegistry(
  392. HKEY hkeyDevice,
  393. LPWSTR *ppwstrPointer,
  394. LPCWSTR lpwstrKey,
  395. LPCWSTR lpwstrBarrier,
  396. LPWSTR *ppwstrBuffer
  397. )
  398. {
  399. BOOL bReturn = TRUE;
  400. LPWSTR pwstrNewString = NULL;
  401. ReadRegistryString(hkeyDevice,lpwstrKey,L"",FALSE,&pwstrNewString);
  402. *ppwstrPointer = NULL;
  403. if (pwstrNewString) {
  404. bReturn = AddOneString(lpwstrBarrier, pwstrNewString,ppwstrBuffer);
  405. FreePv(pwstrNewString);
  406. *ppwstrPointer = *ppwstrBuffer;
  407. }
  408. return bReturn;
  409. }
  410. STDMETHODIMP
  411. GetDeviceInfoHelper(
  412. LPWSTR pszDeviceName,
  413. PSTI_DEVICE_INFORMATION *ppCurrentDevPtr,
  414. PWSTR *ppwszCurrentString
  415. )
  416. {
  417. HRESULT hres = STIERR_INVALID_PARAM;
  418. HKEY hkeyDevice;
  419. PSTI_DEVICE_INFORMATION pDevPtr = *ppCurrentDevPtr;
  420. // PWSTR pwszNewString = NULL;
  421. PWSTR pwszBarrier;
  422. PWSTR pwszTargetString = *ppwszCurrentString;
  423. DWORD dwMajorType,dwMinorType;
  424. // Open device registry key
  425. hres = OpenDeviceRegistryKey(pszDeviceName,NULL,&hkeyDevice);
  426. if (!SUCCEEDED(hres)) {
  427. return hres;
  428. }
  429. //
  430. // Read flags and strings
  431. //
  432. pDevPtr->dwSize = cbX(STI_DEVICE_INFORMATION);
  433. dwMajorType = dwMinorType = 0;
  434. ZeroX(pDevPtr->DeviceCapabilities) ;
  435. ZeroX(pDevPtr->dwHardwareConfiguration) ;
  436. dwMajorType = (STI_DEVICE_TYPE)ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_DEVICETYPE_W,StiDeviceTypeDefault);
  437. dwMinorType = (STI_DEVICE_TYPE)ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_DEVICESUBTYPE_W,0);
  438. pDevPtr->DeviceCapabilities.dwGeneric = ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_GENERIC_CAPS_W,0);
  439. pDevPtr->DeviceType = MAKELONG(dwMinorType,dwMajorType);
  440. pDevPtr->dwHardwareConfiguration = ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_HARDWARE_W,0);
  441. OSUtil_lstrcpyW(pDevPtr->szDeviceInternalName,pszDeviceName);
  442. //
  443. // Add strings
  444. //
  445. pwszBarrier = (LPWSTR)((LPBYTE)pDevPtr + pDevPtr->dwSize);
  446. //
  447. // Add strings
  448. //
  449. pwszBarrier = (LPWSTR)((LPBYTE)pDevPtr + pDevPtr->dwSize);
  450. if (
  451. !PullFromRegistry(hkeyDevice, &pDevPtr -> pszVendorDescription,
  452. REGSTR_VAL_VENDOR_NAME_W, pwszBarrier, &pwszTargetString) ||
  453. !PullFromRegistry(hkeyDevice, &pDevPtr->pszLocalName,
  454. REGSTR_VAL_FRIENDLY_NAME_W, pwszBarrier, &pwszTargetString) ||
  455. !PullFromRegistry(hkeyDevice, &pDevPtr->pszDeviceDescription,
  456. REGSTR_VAL_DEVICE_NAME_W, pwszBarrier, &pwszTargetString) ||
  457. !PullFromRegistry(hkeyDevice, &pDevPtr->pszPortName,
  458. REGSTR_VAL_DEVICEPORT_W, pwszBarrier, &pwszTargetString) ||
  459. //!PullFromRegistry(hkeyDevice, &pDevPtr->pszTwainDataSource,
  460. //REGSTR_VAL_TWAIN_SOURCE_W, pwszBarrier, &pwszTargetString) ||
  461. //!PullFromRegistry(hkeyDevice, &pDevPtr->pszEventList,
  462. //REGSTR_VAL_EVENTS_W, pwszBarrier, &pwszTargetString) ||
  463. !PullFromRegistry(hkeyDevice, &pDevPtr->pszPropProvider,
  464. REGSTR_VAL_PROP_PROVIDER_W, pwszBarrier, &pwszTargetString)) {
  465. // we ran out of memory, somewhere
  466. RegCloseKey(hkeyDevice);
  467. return E_OUTOFMEMORY;
  468. }
  469. #ifdef DEAD_CODE
  470. ReadRegistryString(hkeyDevice,REGSTR_VAL_VENDOR_NAME_W,L"",FALSE,&pwszNewString);
  471. pDevPtr->pszVendorDescription = NULL;
  472. if (pwszNewString) {
  473. if (!AddOneString(pwszBarrier,pwszNewString,&pwszTargetString)) {
  474. // Not enough room for next string
  475. hres = E_OUTOFMEMORY;
  476. goto Cleanup;
  477. }
  478. FreePv(pwszNewString);
  479. pwszNewString = NULL;
  480. pDevPtr->pszVendorDescription = pwszTargetString;
  481. }
  482. ReadRegistryString(hkeyDevice,REGSTR_VAL_DEV_NAME_W,L"",FALSE,&pwszNewString);
  483. if (!pwszNewString || !*pwszNewString) {
  484. FreePv(pwszNewString);
  485. pwszNewString = NULL;
  486. ReadRegistryString(hkeyDevice,REGSTR_VAL_DRIVER_DESC_W,L"",FALSE,&pwszNewString);
  487. }
  488. pDevPtr->pszLocalName = NULL;
  489. if (pwszNewString) {
  490. if (!AddOneString(pwszBarrier,pwszNewString,&pwszTargetString)) {
  491. // Not enough room for next string
  492. hres = E_OUTOFMEMORY;
  493. goto Cleanup;
  494. }
  495. FreePv(pwszNewString);
  496. pwszNewString = NULL;
  497. pDevPtr->pszLocalName = pwszTargetString;
  498. }
  499. #endif
  500. *ppCurrentDevPtr += 1;
  501. *ppwszCurrentString = pwszTargetString;
  502. #ifdef DEAD_CODE
  503. Cleanup:
  504. if (pwszNewString) {
  505. FreePv(pwszNewString);
  506. }
  507. #endif
  508. RegCloseKey(hkeyDevice);
  509. return S_OK;
  510. }
  511. /**************************************************************************\
  512. * GetDeviceInfoHelperWIA
  513. *
  514. * get WIA info as well
  515. *
  516. * Arguments:
  517. *
  518. *
  519. *
  520. * Return Value:
  521. *
  522. * Status
  523. *
  524. * History:
  525. *
  526. * 10/6/1998 Original Version
  527. *
  528. \**************************************************************************/
  529. STDMETHODIMP
  530. GetDeviceInfoHelperWIA(
  531. LPWSTR pszDeviceName,
  532. PSTI_WIA_DEVICE_INFORMATION *ppCurrentDevPtr,
  533. PWSTR *ppwszCurrentString
  534. )
  535. {
  536. HRESULT hres = STIERR_INVALID_PARAM;
  537. HKEY hkeyDevice;
  538. HKEY hkeyDeviceData;
  539. PSTI_WIA_DEVICE_INFORMATION pDevPtr = *ppCurrentDevPtr;
  540. PWSTR pwszBarrier;
  541. PWSTR pwszTargetString = *ppwszCurrentString;
  542. DWORD dwMajorType,dwMinorType;
  543. BOOL bRet;
  544. // Open device registry key
  545. hres = OpenDeviceRegistryKey(pszDeviceName,NULL,&hkeyDevice);
  546. if (!SUCCEEDED(hres)) {
  547. return hres;
  548. }
  549. //
  550. // open DeviceData field
  551. //
  552. hres = OpenDeviceRegistryKey(pszDeviceName,L"DeviceData",&hkeyDeviceData);
  553. if (!SUCCEEDED(hres)) {
  554. RegCloseKey(hkeyDevice);
  555. return hres;
  556. }
  557. //
  558. // Read flags and strings
  559. //
  560. pDevPtr->dwSize = cbX(STI_WIA_DEVICE_INFORMATION);
  561. dwMajorType = dwMinorType = 0;
  562. ZeroX(pDevPtr->DeviceCapabilities) ;
  563. ZeroX(pDevPtr->dwHardwareConfiguration) ;
  564. dwMajorType = (STI_DEVICE_TYPE)ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_DEVICETYPE_W,StiDeviceTypeDefault);
  565. dwMinorType = (STI_DEVICE_TYPE)ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_DEVICESUBTYPE_W,0);
  566. pDevPtr->DeviceCapabilities.dwGeneric = ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_GENERIC_CAPS_W,0);
  567. pDevPtr->DeviceType = MAKELONG(dwMinorType,dwMajorType);
  568. pDevPtr->dwHardwareConfiguration = ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_HARDWARE_W,0);
  569. OSUtil_lstrcpyW(pDevPtr->szDeviceInternalName,pszDeviceName);
  570. //
  571. // Add strings
  572. //
  573. pwszBarrier = (LPWSTR)((LPBYTE)pDevPtr + pDevPtr->dwSize);
  574. bRet = PullFromRegistry(hkeyDevice, &pDevPtr ->pszVendorDescription,
  575. REGSTR_VAL_VENDOR_NAME_W, pwszBarrier, &pwszTargetString);
  576. if (!bRet) {
  577. goto InfoCleanup;
  578. }
  579. bRet = PullFromRegistry(hkeyDevice, &pDevPtr->pszLocalName,
  580. REGSTR_VAL_FRIENDLY_NAME_W, pwszBarrier, &pwszTargetString);
  581. if (!bRet) {
  582. goto InfoCleanup;
  583. }
  584. bRet = PullFromRegistry(hkeyDevice, &pDevPtr->pszDeviceDescription,
  585. REGSTR_VAL_DEVICE_NAME_W, pwszBarrier, &pwszTargetString);
  586. if (!bRet) {
  587. goto InfoCleanup;
  588. }
  589. bRet = PullFromRegistry(hkeyDevice, &pDevPtr->pszPortName,
  590. REGSTR_VAL_DEVICEPORT_W, pwszBarrier, &pwszTargetString);
  591. if (!bRet) {
  592. goto InfoCleanup;
  593. }
  594. bRet = PullFromRegistry(hkeyDevice, &pDevPtr->pszPropProvider,
  595. REGSTR_VAL_PROP_PROVIDER_W, pwszBarrier, &pwszTargetString);
  596. if (!bRet) {
  597. goto InfoCleanup;
  598. }
  599. //
  600. // WIA VALUES
  601. //
  602. bRet = PullFromRegistry(hkeyDeviceData, &pDevPtr->pszServer,
  603. WIA_DIP_SERVER_NAME_STR, pwszBarrier, &pwszTargetString);
  604. if (!bRet) {
  605. goto InfoCleanup;
  606. }
  607. *ppCurrentDevPtr += 1;
  608. *ppwszCurrentString = pwszTargetString;
  609. RegCloseKey(hkeyDeviceData);
  610. RegCloseKey(hkeyDevice);
  611. return S_OK;
  612. InfoCleanup:
  613. //
  614. // we ran out of memory, somewhere
  615. //
  616. RegCloseKey(hkeyDevice);
  617. RegCloseKey(hkeyDeviceData);
  618. return E_OUTOFMEMORY;
  619. }
  620. /*
  621. * Setting device information helper
  622. *
  623. */
  624. STDMETHODIMP
  625. SetDeviceInfoHelper(
  626. PSTI_DEVICE_INFORMATION pDevPtr
  627. )
  628. {
  629. HRESULT hres = S_OK;
  630. HKEY hkeyDevice;
  631. PWSTR pwszNewString = NULL;
  632. DWORD dwHardwareConfiguration;
  633. DWORD dwError;
  634. if (!pDevPtr || OSUtil_StrLenW(pDevPtr->szDeviceInternalName) > STI_MAX_INTERNAL_NAME_LENGTH) {
  635. return STIERR_INVALID_PARAM;
  636. }
  637. //
  638. // Open device registry key
  639. //
  640. hres = OpenDeviceRegistryKey(pDevPtr->szDeviceInternalName,NULL,&hkeyDevice);
  641. if (!SUCCEEDED(hres)) {
  642. return STIERR_INVALID_DEVICE_NAME;
  643. }
  644. ZeroX(dwHardwareConfiguration) ;
  645. dwHardwareConfiguration = ReadRegistryDwordW( hkeyDevice,REGSTR_VAL_HARDWARE_W,0);
  646. #ifdef NOT_IMPL
  647. //
  648. // Changing device information by caller is allowed only for Unknown device types
  649. // For all others settings are handled by setup and control panel
  650. //
  651. if (dwHardwareConfiguration != STI_HW_CONFIG_UNKNOWN ) {
  652. hres = STIERR_INVALID_HW_TYPE;
  653. goto Cleanup;
  654. }
  655. #endif
  656. //
  657. // Store new port name, and new FriendlyName
  658. //
  659. if (!IsBadStringPtrW(pDevPtr->pszPortName, MAX_PATH * sizeof(WCHAR))) {
  660. dwError = WriteRegistryStringW(hkeyDevice ,
  661. REGSTR_VAL_DEVICEPORT_W,
  662. pDevPtr->pszPortName,
  663. (OSUtil_StrLenW(pDevPtr->pszPortName)+1)*sizeof(WCHAR),
  664. REG_SZ
  665. );
  666. if ((dwError == ERROR_SUCCESS) &&
  667. !(IsBadStringPtrW(pDevPtr->pszLocalName, MAX_PATH * sizeof(WCHAR)))) {
  668. dwError = WriteRegistryStringW(hkeyDevice ,
  669. REGSTR_VAL_FRIENDLY_NAME_W,
  670. pDevPtr->pszLocalName,
  671. (OSUtil_StrLenW(pDevPtr->pszLocalName)+1)*sizeof(WCHAR),
  672. REG_SZ
  673. );
  674. if (dwError == ERROR_SUCCESS) {
  675. hres = S_OK;
  676. }
  677. }
  678. if (dwError != ERROR_SUCCESS) {
  679. hres = MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
  680. }
  681. }
  682. else {
  683. hres = STIERR_INVALID_PARAM;
  684. goto Cleanup;
  685. }
  686. Cleanup:
  687. if (pwszNewString) {
  688. FreePv(pwszNewString);
  689. }
  690. RegCloseKey(hkeyDevice);
  691. return hres;
  692. }
  693. /*****************************************************************************
  694. *
  695. * @doc INTERNAL
  696. *
  697. * @method HRESULT | IStillImage | IsStillImageDeviceRegistryNode |
  698. *
  699. * Verifies if given enumeration registry node is associated with Still Image device
  700. *
  701. * @cwrap LPStillImage | lpStillImage
  702. *
  703. * @returns
  704. *
  705. * TRUE if node is representing still image devie
  706. *
  707. * No validation performed
  708. *
  709. *****************************************************************************/
  710. BOOL WINAPI
  711. IsStillImageDeviceRegistryNode(
  712. LPTSTR ptszDeviceKey
  713. )
  714. {
  715. BOOL fRet = FALSE;
  716. DWORD dwError;
  717. HKEY hkeyDevice = NULL;
  718. HKEY hkeyDeviceParameters = NULL;
  719. TCHAR szDevClass[64]; // NOTE: This technically shouldn't be a
  720. // hardcoded number, we should do a RegQueryValueEx
  721. // to get the required size, allocate the memory,
  722. // and then call RegQueryValueEx for the data.
  723. // However, if either the class name or image name
  724. // cannot fit into this buffer, we know it doesn't
  725. // belong to us, so this is OK.
  726. TCHAR szDevDriver[STI_MAX_INTERNAL_NAME_LENGTH];
  727. TCHAR szDeviceKey[MAX_PATH];
  728. ULONG cbData;
  729. //
  730. // Open enumeration registry key
  731. //
  732. dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, // hkey
  733. ptszDeviceKey, // reg entry string
  734. 0, // dwReserved
  735. KEY_READ, // access
  736. &hkeyDevice); // pHkeyReturned.
  737. if (ERROR_SUCCESS != dwError) {
  738. return FALSE;
  739. }
  740. //
  741. // First check it's class . It should be equal to "Image"
  742. //
  743. cbData = sizeof(szDevClass);
  744. *szDevClass = TEXT('\0');
  745. if ((RegQueryValueEx(hkeyDevice,
  746. REGSTR_VAL_CLASS,
  747. NULL,
  748. NULL,
  749. (PBYTE)szDevClass,
  750. &cbData) != ERROR_SUCCESS) ||
  751. (lstrcmpi(szDevClass, CLASSNAME) != 0)) {
  752. fRet = FALSE;
  753. goto CleanUp;
  754. }
  755. //
  756. // Now we check subclass in one of two locations: either in enumeration subkey, or in
  757. // control subkey
  758. //
  759. cbData = sizeof(szDevClass);
  760. if (RegQueryValueEx(hkeyDevice,
  761. REGSTR_VAL_SUBCLASS,
  762. NULL,
  763. NULL,
  764. (PBYTE)szDevClass,
  765. &cbData) == ERROR_SUCCESS) {
  766. fRet = (lstrcmpi(szDevClass, STILLIMAGE) == 0) ? TRUE : FALSE;
  767. goto CleanUp;
  768. }
  769. cbData = sizeof(szDevDriver);
  770. dwError = RegQueryValueEx(hkeyDevice,
  771. REGSTR_VAL_DRIVER,
  772. NULL,
  773. NULL,
  774. (PBYTE)szDevDriver,
  775. &cbData);
  776. if (ERROR_SUCCESS != dwError ) {
  777. goto CleanUp;
  778. }
  779. lstrcat(lstrcpy(szDeviceKey,
  780. (g_NoUnicodePlatform) ? REGSTR_PATH_STIDEVICES : REGSTR_PATH_STIDEVICES_NT),
  781. TEXT("\\"));
  782. lstrcat(szDeviceKey,szDevDriver);
  783. dwError = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
  784. szDeviceKey,
  785. 0L,
  786. NULL,
  787. 0L,
  788. KEY_READ,
  789. NULL,
  790. &hkeyDeviceParameters,
  791. NULL
  792. );
  793. if (ERROR_SUCCESS != dwError) {
  794. goto CleanUp;
  795. }
  796. cbData = sizeof(szDevClass);
  797. dwError = RegQueryValueEx(hkeyDeviceParameters,
  798. REGSTR_VAL_SUBCLASS,
  799. NULL,
  800. NULL,
  801. (PBYTE)szDevClass,
  802. &cbData);
  803. if (ERROR_SUCCESS == dwError) {
  804. fRet = (lstrcmpi(szDevClass, STILLIMAGE) == 0) ? TRUE : FALSE;
  805. goto CleanUp;
  806. }
  807. CleanUp:
  808. if (hkeyDevice) {
  809. RegCloseKey(hkeyDevice);
  810. hkeyDevice = NULL;
  811. }
  812. if (hkeyDeviceParameters) {
  813. RegCloseKey(hkeyDeviceParameters);
  814. hkeyDeviceParameters = NULL;
  815. }
  816. return fRet;
  817. } // endproc IsStillImageDeviceRegistryNode
  818. /*
  819. DWORD
  820. EnumNextLevel(
  821. LPSTR *ppCurrentDevPtr,
  822. LPWSTR *ppwszCurrentString,
  823. DWORD *pdwItemsReturned,
  824. BOOL *pfAlreadyEnumerated,
  825. LPSTR pszDeviceKey,
  826. int Level
  827. )
  828. {
  829. HKEY hkeyDevice;
  830. char szDevDriver[STI_MAX_INTERNAL_NAME_LENGTH];
  831. WCHAR wszDeviceKey[MAX_PATH];
  832. ULONG cbString;
  833. ULONG cbData;
  834. DWORD dwIndex;
  835. DWORD dwError;
  836. DEVINST dnDevNode;
  837. USHORT cbEnumPath;
  838. HANDLE hDevInfo;
  839. GUID Guid;
  840. DWORD dwRequired;
  841. DWORD Idx;
  842. SP_DEVINFO_DATA spDevInfoData;
  843. DWORD dwConfigFlags;
  844. dwError = 0;
  845. if (Level == 0) {
  846. if(!IsStillImageDeviceRegistryNodeA(pszDeviceKey)) {
  847. //
  848. // Nobody there...continue with the enumeration
  849. //
  850. return 0;
  851. }
  852. dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, // hkey
  853. pszDeviceKey, // reg entry string
  854. 0, // dwReserved
  855. KEY_READ, // access
  856. &hkeyDevice); // pHkeyReturned.
  857. if (dwError != ERROR_SUCCESS) {
  858. return 0;
  859. }
  860. dnDevNode = 0;
  861. cbEnumPath = ((g_NoUnicodePlatform) ? lstrlen(REGSTR_PATH_ENUM) : lstrlen(REGSTR_PATH_NT_ENUM_A)) + 1;
  862. CM_Locate_DevNode (&dnDevNode, pszDeviceKey + cbEnumPath, 0);
  863. if (dnDevNode == 0 && *pfAlreadyEnumerated == FALSE) {
  864. #ifdef NODEF
  865. //
  866. // This is dead code, it should be removed.
  867. //
  868. //
  869. // Try to locate this devnode by forcing a re-enumeration.
  870. //
  871. if (SetupDiClassGuidsFromName (REGSTR_KEY_SCSI_CLASS, &Guid, sizeof(GUID), &dwRequired)) {
  872. hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, 0);
  873. if (hDevInfo != INVALID_HANDLE_VALUE) {
  874. spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
  875. for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++) {
  876. CM_Reenumerate_DevNode (spDevInfoData.DevInst, CM_REENUMERATE_SYNCHRONOUS);
  877. }
  878. }
  879. SetupDiDestroyDeviceInfoList (hDevInfo);
  880. }
  881. #endif
  882. //
  883. // Try again to locate our devnode.
  884. //
  885. *pfAlreadyEnumerated = TRUE;
  886. CM_Locate_DevNode (&dnDevNode, pszDeviceKey + cbEnumPath, 0);
  887. if (dnDevNode == 0) {
  888. //
  889. // Skip this one.
  890. //
  891. RegCloseKey(hkeyDevice);
  892. return 0;
  893. }
  894. }
  895. //
  896. // Check that this device is in the current hardware profile
  897. //
  898. dwConfigFlags = 0;
  899. CM_Get_HW_Prof_Flags (pszDeviceKey + cbEnumPath, 0, &dwConfigFlags, 0);
  900. if (dwConfigFlags & CSCONFIGFLAG_DO_NOT_CREATE) {
  901. //
  902. // Skip this one.
  903. //
  904. RegCloseKey(hkeyDevice);
  905. return 0;
  906. }
  907. cbData = sizeof(szDevDriver);
  908. if ((RegQueryValueEx(hkeyDevice, REGSTR_VAL_DRIVER, NULL, NULL, szDevDriver,
  909. &cbData) == ERROR_SUCCESS)) {
  910. //
  911. // Got one device - add it to the buffer
  912. //
  913. AToU(wszDeviceKey,sizeof(wszDeviceKey)/sizeof(WCHAR),szDevDriver);
  914. dwError = (DWORD)GetDeviceInfoHelper(wszDeviceKey,
  915. (PSTI_DEVICE_INFORMATION *)ppCurrentDevPtr,
  916. ppwszCurrentString);
  917. if (!SUCCEEDED(dwError)) {
  918. RegCloseKey(hkeyDevice);
  919. //
  920. // Return value is HRESULT, we should return a Win32 error
  921. //
  922. if (dwError == E_OUTOFMEMORY) {
  923. return ERROR_NOT_ENOUGH_MEMORY;
  924. } else {
  925. return ERROR_INVALID_DATA;
  926. }
  927. }
  928. (*pdwItemsReturned)++;
  929. RegCloseKey(hkeyDevice);
  930. return 0;
  931. }
  932. RegCloseKey(hkeyDevice);
  933. return 0;
  934. }
  935. cbString = lstrlen(pszDeviceKey);
  936. dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, // hkey
  937. pszDeviceKey, // reg entry string
  938. 0, // dwReserved
  939. KEY_READ, // access
  940. &hkeyDevice); // pHkeyReturned.
  941. for (dwIndex = 0; dwError == ERROR_SUCCESS; dwIndex++) {
  942. *(pszDeviceKey + cbString) = '\\';
  943. cbData = MAX_PATH - cbString - 1;
  944. dwError = RegEnumKey(hkeyDevice,
  945. dwIndex,
  946. &pszDeviceKey[cbString+1],
  947. cbData);
  948. if (dwError == ERROR_SUCCESS) {
  949. if ((dwError = EnumNextLevel (ppCurrentDevPtr,
  950. ppwszCurrentString,
  951. pdwItemsReturned,
  952. pfAlreadyEnumerated,
  953. pszDeviceKey,
  954. Level - 1)) != ERROR_SUCCESS) {
  955. RegCloseKey(hkeyDevice);
  956. pszDeviceKey[cbString] = '\0';
  957. return (dwError);
  958. }
  959. }
  960. }
  961. RegCloseKey(hkeyDevice);
  962. pszDeviceKey[cbString] = '\0';
  963. return(0);
  964. }
  965. */
  966. DWORD
  967. EnumFromSetupApi(
  968. LPSTR *ppCurrentDevPtr,
  969. LPWSTR *ppwszCurrentString,
  970. DWORD *pdwItemsReturned
  971. )
  972. {
  973. HANDLE hDevInfo;
  974. GUID Guid = GUID_DEVCLASS_IMAGE;
  975. DWORD dwRequired;
  976. DWORD Idx;
  977. SP_DEVINFO_DATA spDevInfoData;
  978. SP_DEVICE_INTERFACE_DATA spDevInterfaceData;
  979. HKEY hKeyDevice;
  980. char szDevDriver[STI_MAX_INTERNAL_NAME_LENGTH];
  981. TCHAR tszDevClass[32];
  982. WCHAR wszDeviceKey[MAX_PATH];
  983. ULONG cbData;
  984. DWORD dwError;
  985. DWORD dwReturn;
  986. DWORD dwType;
  987. DWORD dwKeyType;
  988. BOOL fRet;
  989. LONG lRet;
  990. PWIA_DEVKEYLIST pWiaDevKeyList;
  991. dwRequired = 0;
  992. dwError = ERROR_SUCCESS;
  993. dwReturn = ERROR_NO_MATCH;
  994. pWiaDevKeyList = NULL;
  995. //
  996. // Get the class device list
  997. //
  998. pWiaDevKeyList = WiaCreateDeviceRegistryList(TRUE);
  999. if(NULL != pWiaDevKeyList){
  1000. for (Idx = 0; Idx < pWiaDevKeyList->dwNumberOfDevices; Idx++) {
  1001. //
  1002. // Check whether we have space for this device inside the device list.
  1003. // NOTE: This will change when the device list size becomes dynamic
  1004. //
  1005. if (((Idx + 1) * max(DEVICE_INFO_SIZE, WIA_DEVICE_INFO_SIZE)) > DEVICE_LIST_SIZE) {
  1006. break;
  1007. }
  1008. //
  1009. // Now get all the device info
  1010. //
  1011. cbData = sizeof(szDevDriver);
  1012. *szDevDriver = '\0';
  1013. dwError = RegQueryValueExA(pWiaDevKeyList->Dev[Idx].hkDeviceRegistry,
  1014. REGSTR_VAL_DEVICE_ID_A,
  1015. // REGSTR_VAL_FRIENDLY_NAME_A,
  1016. NULL,
  1017. NULL,
  1018. (LPBYTE)szDevDriver,
  1019. &cbData);
  1020. if(ERROR_SUCCESS == dwError){
  1021. AToU(wszDeviceKey,sizeof(wszDeviceKey)/sizeof(WCHAR),szDevDriver);
  1022. dwError = (DWORD)GetDeviceInfoHelper(wszDeviceKey,
  1023. (PSTI_DEVICE_INFORMATION *)ppCurrentDevPtr,
  1024. ppwszCurrentString);
  1025. if (!SUCCEEDED(dwError)) {
  1026. //
  1027. // dwError is an HRESULT, we should return a Win32 error
  1028. //
  1029. if (dwError == E_OUTOFMEMORY) {
  1030. dwReturn = ERROR_NOT_ENOUGH_MEMORY;
  1031. } else {
  1032. dwReturn = ERROR_INVALID_DATA;
  1033. }
  1034. break;
  1035. } else {
  1036. //
  1037. // At least one device passed.
  1038. //
  1039. dwReturn = ERROR_SUCCESS;
  1040. }
  1041. (*pdwItemsReturned)++;
  1042. } else { // if(ERROR_SUCCESS == dwError)
  1043. } // if(ERROR_SUCCESS == dwError)
  1044. } // for (Idx = 0; pWiaDevKeyList->dwNumberOfDevices; Idx++)
  1045. } // if(NULL != pWiaDevKeyList)
  1046. //
  1047. // Free device registry list.
  1048. //
  1049. if(NULL != pWiaDevKeyList){
  1050. WiaDestroyDeviceRegistryList(pWiaDevKeyList);
  1051. }
  1052. return (dwReturn);
  1053. }
  1054. /*****************************************************************************
  1055. *
  1056. * @doc INTERNAL
  1057. *
  1058. * @method HRESULT | IStillImage | BuildDeviceListHelper |
  1059. *
  1060. * Fills passed buffer with list of available still image devices
  1061. *
  1062. * @cwrap LPStillImage | lpStillImage
  1063. *
  1064. * @returns
  1065. *
  1066. * Returns a COM error code.
  1067. *
  1068. *****************************************************************************/
  1069. // BUGBUG does not honor filter flags
  1070. STDMETHODIMP
  1071. BuildDeviceListHelper(
  1072. DWORD dwType,
  1073. DWORD dwFlags,
  1074. DWORD *pdwItemsReturned,
  1075. LPVOID *ppBuffer
  1076. )
  1077. {
  1078. HRESULT hres;
  1079. DWORD dwError;
  1080. LPSTR pCurrentDevPtr;
  1081. LPWSTR pwszCurrentString;
  1082. BOOL fAlreadyEnumerated;
  1083. *pdwItemsReturned = 0;
  1084. *ppBuffer = NULL;
  1085. hres = S_OK;
  1086. // Get initial buffer for return data
  1087. hres = AllocCbPpv(DEVICE_LIST_SIZE, ppBuffer);
  1088. if (!SUCCEEDED(hres)) {
  1089. return E_OUTOFMEMORY;
  1090. }
  1091. hres = S_OK;
  1092. //
  1093. // Re-enumerate parallel device if it's installed and not detected on OS boot.
  1094. //
  1095. if(0 == dwFlags){
  1096. //
  1097. // Enumerate LPT port via WIA service.
  1098. //
  1099. SC_HANDLE hSCM;
  1100. SC_HANDLE hService;
  1101. SERVICE_STATUS ServiceStatus;
  1102. __try {
  1103. //
  1104. // Open Service Control Manager.
  1105. //
  1106. hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_CONNECT);
  1107. if (!hSCM) {
  1108. dwError = GetLastError();
  1109. __leave;
  1110. }
  1111. //
  1112. // Open WIA service.
  1113. //
  1114. hService = OpenService(
  1115. hSCM,
  1116. STI_SERVICE_NAME,
  1117. SERVICE_USER_DEFINED_CONTROL
  1118. );
  1119. if (!hService) {
  1120. dwError = GetLastError();
  1121. __leave;
  1122. }
  1123. //
  1124. // Post custom service control message.
  1125. //
  1126. ControlService(hService, STI_SERVICE_CONTROL_LPTENUM, &ServiceStatus);
  1127. //
  1128. // Close service handle.
  1129. //
  1130. CloseServiceHandle(hService);
  1131. } // __try
  1132. __finally {
  1133. if(NULL != hSCM){
  1134. CloseServiceHandle( hSCM );
  1135. } // if(NULL != hSCM)
  1136. } // __finally
  1137. } // if(0 == dwFlags)
  1138. //
  1139. // NOTE: DEVICE_LIST_SIZE is hard coded for the time being. Checks are done in
  1140. // EnumFromSetupApi to ensure we never overrun this buffer.
  1141. //
  1142. pCurrentDevPtr = *ppBuffer;
  1143. pwszCurrentString = (LPWSTR)(pCurrentDevPtr + DEVICE_LIST_SIZE);
  1144. fAlreadyEnumerated = FALSE;
  1145. dwError = EnumFromSetupApi (&pCurrentDevPtr,
  1146. &pwszCurrentString,
  1147. pdwItemsReturned);
  1148. if (dwError != NOERROR) {
  1149. hres = MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
  1150. FreePpv(ppBuffer);
  1151. }
  1152. return hres;
  1153. }
  1154. BOOL
  1155. TranslateDeviceInfo(
  1156. PSTI_DEVICE_INFORMATIONA pDest,
  1157. LPSTR *pCurrentStringDest,
  1158. PSTI_DEVICE_INFORMATIONW pSrc
  1159. )
  1160. {
  1161. LPSTR pStringDest = *pCurrentStringDest;
  1162. pDest->dwSize = cbX(STI_DEVICE_INFORMATIONA);
  1163. pDest->DeviceType = pSrc->DeviceType;
  1164. pDest->DeviceCapabilities = pSrc->DeviceCapabilities;
  1165. pDest->dwHardwareConfiguration = pSrc->dwHardwareConfiguration;
  1166. UToA(pDest->szDeviceInternalName,STI_MAX_INTERNAL_NAME_LENGTH,pSrc->szDeviceInternalName);
  1167. UToA(pStringDest,MAX_PATH,pSrc->pszVendorDescription);
  1168. pDest->pszVendorDescription = pStringDest;
  1169. pStringDest+=lstrlenA(pStringDest)+sizeof(CHAR);
  1170. UToA(pStringDest,MAX_PATH,pSrc->pszDeviceDescription);
  1171. pDest->pszDeviceDescription = pStringDest;
  1172. pStringDest+=lstrlenA(pStringDest)+sizeof(CHAR);
  1173. UToA(pStringDest,MAX_PATH,pSrc->pszPortName);
  1174. pDest->pszPortName = pStringDest;
  1175. pStringDest+=lstrlenA(pStringDest)+sizeof(CHAR);
  1176. UToA(pStringDest,MAX_PATH,pSrc->pszPropProvider);
  1177. pDest->pszPropProvider = pStringDest;
  1178. pStringDest+=lstrlenA(pStringDest)+sizeof(CHAR);
  1179. UToA(pStringDest,MAX_PATH,pSrc->pszLocalName);
  1180. pDest->pszLocalName = pStringDest;
  1181. pStringDest+=lstrlenA(pStringDest)+sizeof(CHAR);
  1182. *pCurrentStringDest = pStringDest;
  1183. return TRUE;
  1184. }
  1185. /*****************************************************************************
  1186. *
  1187. * @doc EXTERNAL
  1188. *
  1189. * @method HRESULT | IStillImage | GetDeviceList |
  1190. *
  1191. *
  1192. * @cwrap LPStillImage | lpStillImage
  1193. *
  1194. *
  1195. * @returns
  1196. *
  1197. * Returns a COM error code. The following error codes are
  1198. * intended to be illustrative and not necessarily comprehensive.
  1199. *
  1200. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  1201. *
  1202. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  1203. * <p ppvOut> parameter is not a valid pointer.
  1204. *
  1205. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  1206. * Out of memory.
  1207. *
  1208. * <c STIERR_NOINTERFACE> = <c E_NOINTERFACE>
  1209. * The specified interface is not supported by the object.
  1210. *
  1211. * <c STIERR_DEVICENOTREG> = The device instance does not
  1212. * correspond to a device that is registered with StillImage.
  1213. *
  1214. *****************************************************************************/
  1215. STDMETHODIMP
  1216. CStiObj_GetDeviceListW(
  1217. PV pSti,
  1218. DWORD dwType,
  1219. DWORD dwFlags,
  1220. DWORD *pdwItemsReturned,
  1221. LPVOID *ppBuffer
  1222. )
  1223. {
  1224. HRESULT hres = STIERR_INVALID_PARAM;
  1225. EnterProcR(IStillImage::GetDeviceList,(_ "pp", pSti,ppBuffer ));
  1226. // Validate passed pointer to interface and obtain pointer to object instance
  1227. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  1228. PCStiObj this = _thisPvNm(pSti, stiW);
  1229. if ( SUCCEEDED(hres = hresFullValidPdwOut_(ppBuffer, s_szProc, 5)) &&
  1230. SUCCEEDED(hres = hresFullValidPdwOut_(pdwItemsReturned, s_szProc, 4))
  1231. ) {
  1232. hres = BuildDeviceListHelper(dwType,dwFlags,pdwItemsReturned,ppBuffer);
  1233. if (!SUCCEEDED(hres) ) {
  1234. FreePpv(ppBuffer);
  1235. }
  1236. }
  1237. }
  1238. ExitOleProc();
  1239. return hres;
  1240. }
  1241. STDMETHODIMP
  1242. CStiObj_GetDeviceListA(
  1243. PV pSti,
  1244. DWORD dwType,
  1245. DWORD dwFlags,
  1246. DWORD *pdwItemsReturned,
  1247. LPVOID *ppBuffer
  1248. )
  1249. {
  1250. HRESULT hres = STIERR_INVALID_PARAM;
  1251. EnterProcR(IStillImage::GetDeviceList,(_ "pp", pSti,ppBuffer ));
  1252. //
  1253. // Validate passed pointer to interface and obtain pointer to object instance
  1254. //
  1255. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  1256. PCStiObj this = _thisPvNm(pSti, stiA);
  1257. if ( SUCCEEDED(hres = hresFullValidPdwOut_(ppBuffer, s_szProc, 5)) &&
  1258. SUCCEEDED(hres = hresFullValidPdwOut_(pdwItemsReturned, s_szProc, 4))
  1259. ) {
  1260. LPVOID pvTempBuffer = NULL;
  1261. UINT uiSize;
  1262. hres = BuildDeviceListHelper(dwType,dwFlags,pdwItemsReturned,&pvTempBuffer);
  1263. if (SUCCEEDED(hres) ) {
  1264. LPSTR pStringDest;
  1265. PSTI_DEVICE_INFORMATIONA pDest;
  1266. PSTI_DEVICE_INFORMATIONW pSrc;
  1267. UINT uiIndex;
  1268. //
  1269. // Allocate new buffer , transform data into ANSI and free scratch
  1270. //
  1271. uiSize = (UINT)LocalSize(pvTempBuffer);
  1272. if (uiSize > 0 && pdwItemsReturned > 0) {
  1273. hres = AllocCbPpv(uiSize, ppBuffer);
  1274. if (SUCCEEDED(hres)) {
  1275. pDest = *ppBuffer;
  1276. pSrc = pvTempBuffer;
  1277. pStringDest = (LPSTR)(pDest+ *pdwItemsReturned);
  1278. for (uiIndex = 0;
  1279. uiIndex < *pdwItemsReturned;
  1280. uiIndex++) {
  1281. TranslateDeviceInfo(pDest,&pStringDest,pSrc);
  1282. pDest++, pSrc++;
  1283. }
  1284. }
  1285. }
  1286. FreePpv(&pvTempBuffer);
  1287. }
  1288. }
  1289. }
  1290. ExitOleProc();
  1291. return hres;
  1292. }
  1293. /*****************************************************************************
  1294. *
  1295. * @doc EXTERNAL
  1296. *
  1297. * @method HRESULT | IStillImage | GetDeviceInfo |
  1298. *
  1299. * @cwrap LPStillImage | lpStillImage
  1300. *
  1301. * @parm REFGUID | rguid |
  1302. * Identifies the instance of the
  1303. * device for which the indicated interface
  1304. * is requested. The <mf IStillImage::EnumDevices> method
  1305. * can be used to determine which instance GUIDs are supported by
  1306. * the system.
  1307. *
  1308. * @returns
  1309. *
  1310. * Returns a COM error code. The following error codes are
  1311. * intended to be illustrative and not necessarily comprehensive.
  1312. *
  1313. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  1314. *
  1315. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  1316. * <p ppvOut> parameter is not a valid pointer.
  1317. *
  1318. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  1319. * Out of memory.
  1320. *
  1321. *****************************************************************************/
  1322. STDMETHODIMP
  1323. CStiObj_GetDeviceInfoW(
  1324. PV pSti,
  1325. LPWSTR pwszDeviceName,
  1326. LPVOID *ppBuffer
  1327. )
  1328. {
  1329. HRESULT hres= STIERR_INVALID_PARAM;
  1330. PSTI_DEVICE_INFORMATION pCurrentDevPtr;
  1331. LPWSTR pwszCurrentString;
  1332. EnterProcR(IStillImage::GetDeviceInfo,(_ "ppp", pSti,pwszDeviceName,ppBuffer ));
  1333. // Validate passed pointer to interface and obtain pointer to object instance
  1334. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  1335. PCStiObj this = _thisPvNm(pSti, stiW);
  1336. // Get initial buffer for return data
  1337. hres = AllocCbPpv(DEVICE_INFO_SIZE, ppBuffer);
  1338. if (!SUCCEEDED(hres)) {
  1339. return E_OUTOFMEMORY;
  1340. }
  1341. // Get information on this device calling helper routine
  1342. pCurrentDevPtr = (PSTI_DEVICE_INFORMATION)*ppBuffer;
  1343. pwszCurrentString = (LPWSTR)((LPBYTE)*ppBuffer+DEVICE_INFO_SIZE);
  1344. hres=GetDeviceInfoHelper(pwszDeviceName,&pCurrentDevPtr,&pwszCurrentString);
  1345. if (!SUCCEEDED(hres)) {
  1346. FreePpv(ppBuffer);
  1347. }
  1348. }
  1349. ExitOleProc();
  1350. return hres;
  1351. }
  1352. STDMETHODIMP
  1353. CStiObj_GetDeviceInfoA(
  1354. PV pSti,
  1355. LPCSTR pszDeviceName,
  1356. LPVOID *ppBuffer
  1357. )
  1358. {
  1359. HRESULT hres = STIERR_INVALID_PARAM;
  1360. EnterProcR(IStillImage::GetDeviceInfo,(_ "ppp", pSti,pszDeviceName,ppBuffer ));
  1361. // Validate passed pointer to interface and obtain pointer to object instance
  1362. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  1363. PCStiObj this = _thisPvNm(pSti, stiA);
  1364. WCHAR wszDeviceName[STI_MAX_INTERNAL_NAME_LENGTH] = {L'\0'};
  1365. PVOID pBuffer;
  1366. AToU(wszDeviceName,STI_MAX_INTERNAL_NAME_LENGTH,pszDeviceName);
  1367. hres = CStiObj_GetDeviceInfoW(pSti,wszDeviceName,&pBuffer);
  1368. if (SUCCEEDED(hres)) {
  1369. hres = AllocCbPpv(DEVICE_INFO_SIZE, ppBuffer);
  1370. if (SUCCEEDED(hres)) {
  1371. LPSTR pStringDest = (LPSTR)*ppBuffer+sizeof(STI_DEVICE_INFORMATIONA);
  1372. TranslateDeviceInfo((PSTI_DEVICE_INFORMATIONA)*ppBuffer,
  1373. &pStringDest,
  1374. (PSTI_DEVICE_INFORMATIONW)pBuffer);
  1375. FreePpv(&pBuffer);
  1376. }
  1377. }
  1378. }
  1379. ExitOleProc();
  1380. return hres;
  1381. }
  1382. /**************************************************************************\
  1383. * PrivateGetDeviceInfoW
  1384. *
  1385. * Private server entry point to get WIA device info
  1386. *
  1387. * Arguments:
  1388. *
  1389. *
  1390. *
  1391. * Return Value:
  1392. *
  1393. * Status
  1394. *
  1395. * History:
  1396. *
  1397. * 10/7/1998 Original Version
  1398. *
  1399. \**************************************************************************/
  1400. STDMETHODIMP
  1401. StiPrivateGetDeviceInfoHelperW(
  1402. LPWSTR pwszDeviceName,
  1403. LPVOID *ppBuffer
  1404. )
  1405. {
  1406. HRESULT hres = STIERR_INVALID_PARAM;
  1407. LPWSTR pwszCurrentString;
  1408. PSTI_WIA_DEVICE_INFORMATION pCurrentDevPtr;
  1409. //
  1410. // Get initial buffer for return data
  1411. //
  1412. hres = AllocCbPpv(WIA_DEVICE_INFO_SIZE, ppBuffer);
  1413. if (!SUCCEEDED(hres)) {
  1414. return E_OUTOFMEMORY;
  1415. }
  1416. //
  1417. // Get information on this device calling helper routine
  1418. //
  1419. pCurrentDevPtr = (PSTI_WIA_DEVICE_INFORMATION)*ppBuffer;
  1420. pwszCurrentString = (LPWSTR)((LPBYTE)*ppBuffer+WIA_DEVICE_INFO_SIZE);
  1421. hres=GetDeviceInfoHelperWIA(pwszDeviceName, &pCurrentDevPtr,&pwszCurrentString);
  1422. if (!SUCCEEDED(hres)) {
  1423. FreePpv(ppBuffer);
  1424. *ppBuffer = NULL;
  1425. } else
  1426. {
  1427. if (*ppBuffer) {
  1428. if (OSUtil_StrLenW(((PSTI_WIA_DEVICE_INFORMATION) *ppBuffer)->pszServer) == 0)
  1429. {
  1430. //
  1431. // Assume that this is not a WIA device, since server name is
  1432. // blank.
  1433. //
  1434. FreePpv(ppBuffer);
  1435. *ppBuffer = NULL;
  1436. } else
  1437. {
  1438. //
  1439. // set size of buffer so buffers can be chained independently
  1440. //
  1441. if (pCurrentDevPtr) {
  1442. pCurrentDevPtr->dwSize = WIA_DEVICE_INFO_SIZE;
  1443. }
  1444. }
  1445. }
  1446. }
  1447. return hres;
  1448. }
  1449. /*****************************************************************************
  1450. *
  1451. * @doc EXTERNAL
  1452. *
  1453. * @method HRESULT | IStillImage | SetDeviceValue |
  1454. *
  1455. * @cwrap LPStillImage | lpStillImage
  1456. *
  1457. * @parm
  1458. *
  1459. * @returns
  1460. *
  1461. * Returns a COM error code. The following error codes are
  1462. * intended to be illustrative and not necessarily comprehensive.
  1463. *
  1464. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  1465. *
  1466. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  1467. * <p ppvOut> parameter is not a valid pointer.
  1468. *
  1469. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  1470. * Out of memory.
  1471. *
  1472. *****************************************************************************/
  1473. STDMETHODIMP
  1474. CStiObj_SetDeviceValueW(
  1475. PV pSti,
  1476. LPWSTR pwszDeviceName,
  1477. LPWSTR pwszValueName,
  1478. DWORD Type,
  1479. LPBYTE pData,
  1480. DWORD cbData
  1481. )
  1482. {
  1483. HRESULT hres = STIERR_INVALID_PARAM;
  1484. HKEY hkeyDevice;
  1485. LONG dwError;
  1486. EnterProcR(IStillImage::SetDeviceValue,(_ "ppp", pSti,pwszDeviceName,pData ));
  1487. //
  1488. // Validate passed pointer to interface and obtain pointer to object instance
  1489. //
  1490. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  1491. PCStiObj this = _thisPvNm(pSti, stiW);
  1492. //
  1493. // Open device registry key
  1494. //
  1495. hres = OpenDeviceRegistryKey(pwszDeviceName,REGSTR_VAL_DATA_W,&hkeyDevice);
  1496. if (!SUCCEEDED(hres)) {
  1497. return hres;
  1498. }
  1499. //
  1500. // Implement set value
  1501. //
  1502. dwError = OSUtil_RegSetValueExW(hkeyDevice,
  1503. pwszValueName,
  1504. Type,
  1505. pData,
  1506. cbData,
  1507. (this->dwVersion & STI_VERSION_FLAG_UNICODE) ? TRUE : FALSE);
  1508. if (hkeyDevice) {
  1509. RegCloseKey(hkeyDevice);
  1510. }
  1511. hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
  1512. }
  1513. ExitOleProc();
  1514. return hres;
  1515. }
  1516. STDMETHODIMP
  1517. CStiObj_SetDeviceValueA(
  1518. PV pSti,
  1519. LPCSTR pszDeviceName,
  1520. LPCSTR pszValueName,
  1521. DWORD Type,
  1522. LPBYTE pData,
  1523. DWORD cbData
  1524. )
  1525. {
  1526. HRESULT hres;
  1527. HKEY hkeyDevice;
  1528. LONG dwError;
  1529. EnterProcR(IStillImage::SetDeviceValue,(_ "ppp", pSti,pszDeviceName,pData ));
  1530. //
  1531. // Validate passed pointer to interface and obtain pointer to object instance
  1532. //
  1533. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  1534. PCStiObj this = _thisPvNm(pSti, stiA);
  1535. WCHAR wszDeviceName[STI_MAX_INTERNAL_NAME_LENGTH] = {L'\0'};
  1536. WCHAR wszValueName[MAX_PATH] = {L'\0'};
  1537. AToU(wszDeviceName,STI_MAX_INTERNAL_NAME_LENGTH,pszDeviceName);
  1538. AToU(wszValueName,MAX_PATH,pszValueName);
  1539. //
  1540. // Open device registry key
  1541. //
  1542. hres = OpenDeviceRegistryKey(wszDeviceName,REGSTR_VAL_DATA_W,&hkeyDevice);
  1543. if (SUCCEEDED(hres)) {
  1544. //
  1545. // Implement set value
  1546. //
  1547. dwError = OSUtil_RegSetValueExW(hkeyDevice,
  1548. wszValueName,
  1549. Type,
  1550. pData,
  1551. cbData,
  1552. (this->dwVersion & STI_VERSION_FLAG_UNICODE) ? TRUE : FALSE);
  1553. if (hkeyDevice) {
  1554. RegCloseKey(hkeyDevice);
  1555. }
  1556. hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
  1557. }
  1558. }
  1559. ExitOleProc();
  1560. return hres;
  1561. }
  1562. /****************************************************************************
  1563. *
  1564. * @doc EXTERNAL
  1565. *
  1566. * @method HRESULT | IStillImage | GetDeviceValue |
  1567. *
  1568. * @cwrap LPStillImage | lpStillImage
  1569. *
  1570. * @parm
  1571. *
  1572. * @returns
  1573. *
  1574. * Returns a COM error code. The following error codes are
  1575. * intended to be illustrative and not necessarily comprehensive.
  1576. *
  1577. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  1578. *
  1579. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  1580. * <p ppvOut> parameter is not a valid pointer.
  1581. *
  1582. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  1583. * Out of memory.
  1584. *
  1585. *****************************************************************************/
  1586. STDMETHODIMP
  1587. CStiObj_GetDeviceValueW(
  1588. PV pSti,
  1589. LPWSTR pwszDeviceName,
  1590. LPWSTR pwszValueName,
  1591. LPDWORD pType,
  1592. LPBYTE pData,
  1593. LPDWORD pcbData
  1594. )
  1595. {
  1596. HRESULT hres = STIERR_INVALID_PARAM;
  1597. HKEY hkeyDevice;
  1598. LONG dwError;
  1599. EnterProcR(IStillImage::GetDeviceValue,(_ "ppp", pSti,pwszDeviceName,pData ));
  1600. //
  1601. // Validate passed pointer to interface and obtain pointer to object instance
  1602. //
  1603. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  1604. PCStiObj this = _thisPvNm(pSti, stiW);
  1605. //
  1606. // Open device registry key
  1607. //
  1608. hres = OpenDeviceRegistryKey(pwszDeviceName,REGSTR_VAL_DATA_W,&hkeyDevice);
  1609. if (!SUCCEEDED(hres)) {
  1610. return hres;
  1611. }
  1612. //
  1613. // Implement get value
  1614. //
  1615. dwError = OSUtil_RegQueryValueExW(hkeyDevice,
  1616. pwszValueName,
  1617. pType,
  1618. pData,
  1619. pcbData,
  1620. (this->dwVersion & STI_VERSION_FLAG_UNICODE) ? TRUE : FALSE);
  1621. if (hkeyDevice) {
  1622. RegCloseKey(hkeyDevice);
  1623. }
  1624. hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
  1625. }
  1626. ExitOleProc();
  1627. return hres;
  1628. }
  1629. STDMETHODIMP
  1630. CStiObj_GetDeviceValueA(
  1631. PV pSti,
  1632. LPCSTR pszDeviceName,
  1633. LPCSTR pszValueName,
  1634. LPDWORD pType,
  1635. LPBYTE pData,
  1636. LPDWORD pcbData
  1637. )
  1638. {
  1639. HRESULT hres = STIERR_INVALID_PARAM;
  1640. HKEY hkeyDevice;
  1641. LONG dwError;
  1642. EnterProcR(IStillImage::GetDeviceValue,(_ "ppp", pSti,pszDeviceName,pData ));
  1643. //
  1644. // Validate passed pointer to interface and obtain pointer to object instance
  1645. //
  1646. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  1647. PCStiObj this = _thisPvNm(pSti, stiA);
  1648. LPWSTR pwszDevName = NULL;
  1649. hres = OSUtil_GetWideString(&pwszDevName,pszDeviceName);
  1650. if (SUCCEEDED(hres)) {
  1651. //
  1652. // Open device registry key
  1653. //
  1654. hres = OpenDeviceRegistryKey(pwszDevName,REGSTR_VAL_DATA_W,&hkeyDevice);
  1655. if (SUCCEEDED(hres)) {
  1656. //
  1657. // Implement get value
  1658. //
  1659. dwError = RegQueryValueExA(hkeyDevice,
  1660. pszValueName,
  1661. 0,
  1662. pType,
  1663. pData,
  1664. pcbData);
  1665. if (hkeyDevice) {
  1666. RegCloseKey(hkeyDevice);
  1667. }
  1668. hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
  1669. }
  1670. }
  1671. }
  1672. ExitOleProc();
  1673. return hres;
  1674. }
  1675. /*****************************************************************************
  1676. *
  1677. * @doc EXTERNAL
  1678. *
  1679. * @method HRESULT | IStillImage | GetSTILaunchInformation |
  1680. *
  1681. * @cwrap LPStillImage | lpStillImage
  1682. *
  1683. * @parm
  1684. *
  1685. * @returns
  1686. *
  1687. * Returns a COM error code. The following error codes are
  1688. * intended to be illustrative and not necessarily comprehensive.
  1689. *
  1690. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  1691. *
  1692. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  1693. * <p ppvOut> parameter is not a valid pointer.
  1694. *
  1695. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  1696. * Out of memory.
  1697. *
  1698. *****************************************************************************/
  1699. STDMETHODIMP
  1700. CStiObj_GetSTILaunchInformationW(
  1701. PV pSti,
  1702. WCHAR *pwszDeviceName,
  1703. DWORD *pdwEventCode,
  1704. WCHAR *pwszEventName
  1705. )
  1706. {
  1707. HRESULT hres = STIERR_INVALID_PARAM;
  1708. EnterProcR(IStillImage::GetSTILaunchInformation,(_ "pppp", pSti,pwszDeviceName,pdwEventCode,pwszEventName ));
  1709. //
  1710. // Validate passed pointer to interface and obtain pointer to object instance
  1711. //
  1712. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  1713. PCStiObj this = _thisPvNm(pSti, stiW);
  1714. //
  1715. // Parse process command line to check if there is STI information
  1716. //
  1717. hres = ExtractCommandLineArgumentW("StiDevice",pwszDeviceName);
  1718. if (SUCCEEDED(hres) ) {
  1719. hres = ExtractCommandLineArgumentW("StiEvent",pwszEventName);
  1720. }
  1721. }
  1722. ExitOleProc();
  1723. return hres;
  1724. }
  1725. STDMETHODIMP
  1726. CStiObj_GetSTILaunchInformationA(
  1727. PV pSti,
  1728. LPSTR pszDeviceName,
  1729. DWORD *pdwEventCode,
  1730. LPSTR pszEventName
  1731. )
  1732. {
  1733. HRESULT hres = STIERR_INVALID_PARAM;
  1734. EnterProcR(IStillImage::GetSTILaunchInformation,(_ "pppp", pSti,pszDeviceName,pdwEventCode,pszEventName ));
  1735. //
  1736. // Validate passed pointer to interface and obtain pointer to object instance
  1737. //
  1738. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  1739. PCStiObj this = _thisPvNm(pSti, stiA);
  1740. hres = ExtractCommandLineArgumentA("StiDevice",pszDeviceName);
  1741. if (SUCCEEDED(hres) ) {
  1742. hres = ExtractCommandLineArgumentA("StiEvent",pszEventName);
  1743. }
  1744. }
  1745. ExitOleProc();
  1746. return hres;
  1747. }
  1748. /*****************************************************************************
  1749. *
  1750. * @doc EXTERNAL
  1751. *
  1752. * @method HRESULT | IStillImage | RegisterLaunchApplication |
  1753. *
  1754. * @cwrap LPStillImage | lpStillImage
  1755. *
  1756. * @parm
  1757. *
  1758. * @returns
  1759. *
  1760. * Returns a COM error code. The following error codes are
  1761. * intended to be illustrative and not necessarily comprehensive.
  1762. *
  1763. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  1764. *
  1765. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  1766. * <p ppvOut> parameter is not a valid pointer.
  1767. *
  1768. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  1769. * Out of memory.
  1770. *
  1771. *****************************************************************************/
  1772. static WCHAR szSTICommandLineTail[] = {L" /StiDevice:%1 /StiEvent:%2"};
  1773. static CHAR szSTICommandLineTail_A[] = {" /StiDevice:%1 /StiEvent:%2"};
  1774. STDMETHODIMP
  1775. CStiObj_RegisterLaunchApplicationW(
  1776. PV pSti,
  1777. LPWSTR pwszAppName,
  1778. LPWSTR pwszCommandLine
  1779. )
  1780. {
  1781. HRESULT hres = STIERR_INVALID_PARAM;
  1782. DWORD dwErr = 0;
  1783. DWORD dwCommandLineLength, cbNewLength;
  1784. LPWSTR pszWide = NULL;
  1785. HKEY hkeyApps;
  1786. CHAR szAppName[MAX_PATH] = {'\0'};
  1787. CHAR szCmdLine[MAX_PATH] = {'\0'};
  1788. EnterProcR(IStillImage::RegisterLaunchApplication,(_ "ppp", pSti,pwszAppName,pwszCommandLine ));
  1789. //
  1790. // Validate passed pointer to interface and obtain pointer to object instance
  1791. //
  1792. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  1793. PCStiObj this = _thisPvNm(pSti, stiW);
  1794. if (pwszCommandLine && *pwszCommandLine &&
  1795. pwszAppName && *pwszAppName
  1796. ) {
  1797. //
  1798. // Add STI formatiing tail to the command line
  1799. //
  1800. dwCommandLineLength = OSUtil_StrLenW(pwszCommandLine);
  1801. cbNewLength = ((dwCommandLineLength+1) + OSUtil_StrLenW(szSTICommandLineTail) + 1)*sizeof(WCHAR) ;
  1802. hres = AllocCbPpv(cbNewLength, (PPV)&pszWide);
  1803. if (pszWide) {
  1804. HRESULT hresCom ;
  1805. // Need to initialize COM apartment to call WIA event registration
  1806. hresCom = CoInitialize(NULL);
  1807. OSUtil_lstrcpyW(pszWide,pwszCommandLine);
  1808. OSUtil_lstrcatW(pszWide,szSTICommandLineTail);
  1809. dwErr = OSUtil_RegCreateKeyExW(HKEY_LOCAL_MACHINE,
  1810. REGSTR_PATH_REG_APPS_W,
  1811. 0L,
  1812. NULL,
  1813. 0L,
  1814. KEY_ALL_ACCESS,
  1815. NULL,
  1816. &hkeyApps,
  1817. NULL
  1818. );
  1819. if (NOERROR == dwErr ) {
  1820. WriteRegistryStringW(hkeyApps,
  1821. pwszAppName ,
  1822. pszWide,
  1823. cbNewLength,
  1824. REG_SZ);
  1825. RegCloseKey(hkeyApps);
  1826. }
  1827. //
  1828. // Register for standard WIA events on all devices , setting as non default
  1829. //
  1830. if (WideCharToMultiByte(CP_ACP,
  1831. 0,
  1832. pwszAppName,
  1833. -1,
  1834. szAppName,
  1835. MAX_PATH,
  1836. NULL,
  1837. NULL)) {
  1838. if (WideCharToMultiByte(CP_ACP,
  1839. 0,
  1840. pszWide,
  1841. -1,
  1842. szCmdLine,
  1843. MAX_PATH,
  1844. NULL,
  1845. NULL)) {
  1846. hres = RunRegisterProcess(szAppName, szCmdLine);
  1847. } else {
  1848. hres = E_FAIL;
  1849. }
  1850. } else {
  1851. hres = E_FAIL;
  1852. }
  1853. FreePpv(&pszWide);
  1854. // Balance apartment initiazation
  1855. if ((S_OK == hresCom) || (S_FALSE == hresCom)) {
  1856. CoUninitialize();
  1857. }
  1858. hres = (dwErr == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwErr);
  1859. }
  1860. else {
  1861. DebugOutPtszV(DbgFl, TEXT("Could not get unicode string -- out of memory"));
  1862. hres = E_OUTOFMEMORY;
  1863. }
  1864. }
  1865. else {
  1866. hres = STIERR_INVALID_PARAM;
  1867. }
  1868. }
  1869. ExitOleProc();
  1870. return hres;
  1871. }
  1872. STDMETHODIMP
  1873. CStiObj_RegisterLaunchApplicationA(
  1874. PV pSti,
  1875. LPCSTR pszAppName,
  1876. LPCSTR pszCommandLine
  1877. )
  1878. {
  1879. HRESULT hres = STIERR_INVALID_PARAM;
  1880. DWORD dwErr = 0;
  1881. DWORD dwCommandLineLength, cbNewLength;
  1882. LPWSTR pszWide = NULL;
  1883. HKEY hkeyApps;
  1884. EnterProcR(IStillImage::RegisterLaunchApplication,(_ "ppp", pSti,pszAppName,pszCommandLine ));
  1885. //
  1886. // Validate passed pointer to interface and obtain pointer to object instance
  1887. //
  1888. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  1889. PCStiObj this = _thisPvNm(pSti, stiA);
  1890. // Add STI formatiing tail to the command line
  1891. //
  1892. if (pszCommandLine && *pszCommandLine &&
  1893. pszAppName && *pszAppName
  1894. ) {
  1895. LPSTR pszBuffer;
  1896. // Add STI formatiing tail to the command line
  1897. //
  1898. dwCommandLineLength = lstrlenA(pszCommandLine);
  1899. cbNewLength = ((dwCommandLineLength+1) + OSUtil_StrLenW(szSTICommandLineTail) + 1)*sizeof(WCHAR) ;
  1900. hres = AllocCbPpv(cbNewLength, (PPV)&pszBuffer);
  1901. if (pszBuffer) {
  1902. lstrcpyA(pszBuffer,pszCommandLine);
  1903. UToA(pszBuffer+lstrlenA(pszBuffer),
  1904. (cbNewLength - dwCommandLineLength),
  1905. szSTICommandLineTail);
  1906. dwErr = RegCreateKeyExA(HKEY_LOCAL_MACHINE,
  1907. REGSTR_PATH_REG_APPS_A,
  1908. 0L,
  1909. NULL,
  1910. 0L,
  1911. KEY_ALL_ACCESS,
  1912. NULL,
  1913. &hkeyApps,
  1914. NULL
  1915. );
  1916. if (NOERROR == dwErr ) {
  1917. WriteRegistryStringA(hkeyApps,
  1918. pszAppName ,
  1919. pszBuffer,
  1920. lstrlenA(pszBuffer)+1,
  1921. REG_SZ);
  1922. RegCloseKey(hkeyApps);
  1923. }
  1924. {
  1925. //
  1926. // Register for standard WIA events on all devices , setting as non default
  1927. //
  1928. PVOID pWideCMDLine = NULL;
  1929. UINT uiSize = (lstrlenA(pszBuffer)+1)*sizeof(WCHAR);
  1930. CHAR szCmdLine[MAX_PATH] = {'\0'};
  1931. //
  1932. // Make sure we wont overrun our buffer
  1933. //
  1934. if ((lstrlenA(szCmdLine) + lstrlenA(szSTICommandLineTail_A) + lstrlenA(" ") + sizeof('\0'))
  1935. < (MAX_PATH)) {
  1936. lstrcatA(szCmdLine, pszCommandLine);
  1937. lstrcatA(szCmdLine, " ");
  1938. lstrcatA(szCmdLine, szSTICommandLineTail_A);
  1939. dwErr = (DWORD) RunRegisterProcess((LPSTR)pszAppName, szCmdLine);
  1940. } else {
  1941. dwErr = (DWORD) E_INVALIDARG;
  1942. }
  1943. }
  1944. FreePpv(&pszBuffer);
  1945. hres = (dwErr == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwErr);
  1946. }
  1947. else {
  1948. DebugOutPtszV(DbgFl,TEXT("Could not get unicode string -- out of memory"));
  1949. hres = E_OUTOFMEMORY;
  1950. }
  1951. }
  1952. else {
  1953. hres = STIERR_INVALID_PARAM;
  1954. }
  1955. }
  1956. ExitOleProc();
  1957. return hres;
  1958. }
  1959. /*****************************************************************************
  1960. *
  1961. * @doc EXTERNAL
  1962. *
  1963. * @method HRESULT | IStillImage | RegisterLaunchApplication |
  1964. *
  1965. * @cwrap LPStillImage | lpStillImage
  1966. *
  1967. * @parm
  1968. *
  1969. * @returns
  1970. *
  1971. * Returns a COM error code. The following error codes are
  1972. * intended to be illustrative and not necessarily comprehensive.
  1973. *
  1974. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  1975. *
  1976. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  1977. * <p ppvOut> parameter is not a valid pointer.
  1978. *
  1979. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  1980. * Out of memory.
  1981. *
  1982. *****************************************************************************/
  1983. STDMETHODIMP
  1984. CStiObj_UnregisterLaunchApplicationW(
  1985. PV pSti,
  1986. LPWSTR pwszAppName
  1987. )
  1988. {
  1989. HRESULT hres = STIERR_INVALID_PARAM;
  1990. DWORD dwErr;
  1991. HKEY hkeyApps;
  1992. EnterProcR(IStillImage::UnregisterLaunchApplication,(_ "pp", pSti,pwszAppName ));
  1993. //
  1994. // Validate passed pointer to interface and obtain pointer to object instance
  1995. //
  1996. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  1997. PCStiObj this = _thisPvNm(pSti, stiW);
  1998. dwErr = OSUtil_RegOpenKeyExW(HKEY_LOCAL_MACHINE,
  1999. REGSTR_PATH_REG_APPS_W,
  2000. 0L,
  2001. KEY_ALL_ACCESS,
  2002. &hkeyApps
  2003. );
  2004. if (NOERROR == dwErr ) {
  2005. OSUtil_RegDeleteValueW(hkeyApps,pwszAppName);
  2006. RegCloseKey(hkeyApps);
  2007. }
  2008. hres = (dwErr == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwErr);
  2009. }
  2010. ExitOleProc();
  2011. return hres;
  2012. }
  2013. STDMETHODIMP
  2014. CStiObj_UnregisterLaunchApplicationA(
  2015. PV pSti,
  2016. LPCSTR pszAppName
  2017. )
  2018. {
  2019. HRESULT hres = STIERR_INVALID_PARAM;
  2020. DWORD dwErr;
  2021. HKEY hkeyApps;
  2022. EnterProcR(IStillImage::UnregisterLaunchApplication,(_ "pp", pSti,pszAppName ));
  2023. //
  2024. // Validate passed pointer to interface and obtain pointer to object instance
  2025. //
  2026. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  2027. PCStiObj this = _thisPvNm(pSti, stiA);
  2028. dwErr = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
  2029. REGSTR_PATH_REG_APPS_A,
  2030. 0L,
  2031. KEY_ALL_ACCESS,
  2032. &hkeyApps
  2033. );
  2034. if (NOERROR == dwErr ) {
  2035. RegDeleteValueA(hkeyApps,pszAppName);
  2036. RegCloseKey(hkeyApps);
  2037. }
  2038. hres = (dwErr == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwErr);
  2039. }
  2040. ExitOleProc();
  2041. return hres;
  2042. }
  2043. /*****************************************************************************
  2044. *
  2045. * @doc EXTERNAL
  2046. *
  2047. * @method HRESULT | IStillImage | LaunchApplicationForDevice |
  2048. *
  2049. * @cwrap LPStillImage | lpStillImage
  2050. *
  2051. * @parm
  2052. *
  2053. * @returns
  2054. *
  2055. * Returns a COM error code. The following error codes are
  2056. * intended to be illustrative and not necessarily comprehensive.
  2057. *
  2058. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  2059. *
  2060. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  2061. * <p ppvOut> parameter is not a valid pointer.
  2062. *
  2063. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  2064. * Out of memory.
  2065. *
  2066. *****************************************************************************/
  2067. STDMETHODIMP
  2068. CStiObj_LaunchApplicationForDeviceW(
  2069. PV pSti,
  2070. LPWSTR pwszDeviceName,
  2071. LPWSTR pwszAppName,
  2072. LPSTINOTIFY pStiNotify
  2073. )
  2074. {
  2075. HRESULT hres = STIERR_INVALID_PARAM;
  2076. DWORD dwError ;
  2077. EnterProcR(IStillImage::LaunchApplicationForDevice,(_ "pp", pSti,pwszAppName ));
  2078. //
  2079. // Validate passed pointer to interface and obtain pointer to object instance
  2080. //
  2081. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  2082. PCStiObj this = _thisPvNm(pSti, stiW);
  2083. dwError = RpcStiApiLaunchApplication(NULL,
  2084. pwszDeviceName,
  2085. pwszAppName,
  2086. pStiNotify
  2087. );
  2088. hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
  2089. }
  2090. ExitOleProc();
  2091. return hres;
  2092. }
  2093. STDMETHODIMP
  2094. CStiObj_LaunchApplicationForDeviceA(
  2095. PV pSti,
  2096. LPCSTR pszDeviceName,
  2097. LPCSTR pszApplicationName,
  2098. LPSTINOTIFY pStiNotify
  2099. )
  2100. {
  2101. HRESULT hres = STIERR_INVALID_PARAM;
  2102. DWORD dwError;
  2103. EnterProcR(IStillImage::LaunchApplicationForDevice,(_ "pp", pSti,pszApplicationName ));
  2104. //
  2105. // Validate passed pointer to interface and obtain pointer to object instance
  2106. //
  2107. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  2108. PCStiObj this = _thisPvNm(pSti, stiA);
  2109. LPWSTR pwszDevName = NULL;
  2110. LPWSTR pwszAppName = NULL;
  2111. hres = OSUtil_GetWideString(&pwszDevName,pszDeviceName);
  2112. if (SUCCEEDED(hres)) {
  2113. hres = OSUtil_GetWideString(&pwszAppName,pszApplicationName);
  2114. if (SUCCEEDED(hres)) {
  2115. dwError = RpcStiApiLaunchApplication(NULL,
  2116. pwszDevName,
  2117. pwszAppName,
  2118. pStiNotify
  2119. );
  2120. hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
  2121. }
  2122. }
  2123. FreePpv(&pwszAppName);
  2124. FreePpv(&pwszDevName);
  2125. }
  2126. ExitOleProc();
  2127. return hres;
  2128. }
  2129. /*****************************************************************************
  2130. *
  2131. * @doc EXTERNAL
  2132. *
  2133. * @method HRESULT | IStillImage | SetupDeviceParameters |
  2134. *
  2135. * @cwrap LPStillImage | lpStillImage
  2136. *
  2137. * @parm
  2138. *
  2139. * @returns
  2140. *
  2141. * Returns a COM error code. The following error codes are
  2142. * intended to be illustrative and not necessarily comprehensive.
  2143. *
  2144. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  2145. *
  2146. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  2147. * <p ppvOut> parameter is not a valid pointer.
  2148. *
  2149. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  2150. * Out of memory.
  2151. *
  2152. *****************************************************************************/
  2153. STDMETHODIMP
  2154. CStiObj_SetupDeviceParametersW(
  2155. PV pSti,
  2156. PSTI_DEVICE_INFORMATIONW pDevInfo
  2157. )
  2158. {
  2159. HRESULT hres = STIERR_INVALID_PARAM;
  2160. EnterProcR(IStillImage::SetupDeviceParameters,(_ "pp", pSti, pDevInfo));
  2161. //
  2162. // Validate passed pointer to interface and obtain pointer to object instance
  2163. //
  2164. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  2165. PCStiObj this = _thisPvNm(pSti, stiW);
  2166. hres = SetDeviceInfoHelper(pDevInfo);
  2167. }
  2168. ExitOleProc();
  2169. return hres;
  2170. }
  2171. STDMETHODIMP
  2172. CStiObj_SetupDeviceParametersA(
  2173. PV pSti,
  2174. PSTI_DEVICE_INFORMATIONA pDevInfo
  2175. )
  2176. {
  2177. HRESULT hres = STIERR_INVALID_PARAM;
  2178. EnterProcR(IStillImage::SetupDeviceParameters,(_ "pp", pSti, pDevInfo));
  2179. //
  2180. // Validate passed pointer to interface and obtain pointer to object instance
  2181. //
  2182. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  2183. PCStiObj this = _thisPvNm(pSti, stiA);
  2184. hres = STIERR_UNSUPPORTED;
  2185. }
  2186. ExitOleProc();
  2187. return hres;
  2188. }
  2189. /*****************************************************************************
  2190. *
  2191. * @doc EXTERNAL
  2192. *
  2193. * @method HRESULT | IStillImage | SetupDeviceParameters |
  2194. *
  2195. * @cwrap LPStillImage | lpStillImage
  2196. *
  2197. * @parm
  2198. *
  2199. * @returns
  2200. *
  2201. * Returns a COM error code. The following error codes are
  2202. * intended to be illustrative and not necessarily comprehensive.
  2203. *
  2204. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  2205. *
  2206. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  2207. * <p ppvOut> parameter is not a valid pointer.
  2208. *
  2209. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  2210. * Out of memory.
  2211. *
  2212. *****************************************************************************/
  2213. STDMETHODIMP
  2214. CStiObj_WriteToErrorLogW(
  2215. PV pSti,
  2216. DWORD dwMessageType,
  2217. LPCWSTR pwszMessage
  2218. )
  2219. {
  2220. HRESULT hres = S_OK;
  2221. EnterProcR(IStillImage::WriteToErrorLog,(_ "pp", pSti, pwszMessage));
  2222. //
  2223. // Validate passed pointer to interface and obtain pointer to object instance
  2224. //
  2225. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  2226. PCStiObj this = _thisPvNm(pSti, stiW);
  2227. //
  2228. // Validate parameters here
  2229. //
  2230. if (SUCCEEDED(hres = hresFullValidReadPvCb(pwszMessage,2, 3))) {
  2231. #ifndef UNICODE
  2232. //
  2233. // Since we're ANSI, the ReportStiLogMessage is expecting an ANSI string,
  2234. // but our message is UNICODE, so we must convert.
  2235. // NOTE: We never expect CStiObj_WriteToErrorLogW to be called if we're compiling
  2236. // ANSI, but just in case...
  2237. //
  2238. LPSTR lpszANSI = NULL;
  2239. if ( SUCCEEDED(OSUtil_GetAnsiString(&lpszANSI,pwszMessage))) {
  2240. ReportStiLogMessage(g_hStiFileLog,
  2241. dwMessageType,
  2242. lpszANSI
  2243. );
  2244. FreePpv(&lpszANSI);
  2245. }
  2246. #else
  2247. ReportStiLogMessage(g_hStiFileLog,
  2248. dwMessageType,
  2249. pwszMessage
  2250. );
  2251. #endif
  2252. }
  2253. }
  2254. ExitOleProc();
  2255. return hres;
  2256. }
  2257. STDMETHODIMP
  2258. CStiObj_WriteToErrorLogA(
  2259. PV pSti,
  2260. DWORD dwMessageType,
  2261. LPCSTR pszMessage
  2262. )
  2263. {
  2264. HRESULT hres = S_OK;
  2265. EnterProcR(IStillImage::WriteToErrorLog,(_ "pp", pSti, pszMessage));
  2266. //
  2267. // Validate passed pointer to interface and obtain pointer to object instance
  2268. //
  2269. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  2270. PCStiObj this = _thisPvNm(pSti, stiA);
  2271. //
  2272. // Validate parameters here
  2273. //
  2274. if (SUCCEEDED(hres = hresFullValidReadPvCb(pszMessage,2, 3))) {
  2275. #ifndef UNICODE
  2276. ReportStiLogMessage(g_hStiFileLog,
  2277. dwMessageType,
  2278. pszMessage
  2279. );
  2280. #else
  2281. //
  2282. // Since we're UNICODE, the ReportStiLogMessage is expecting a WideString,
  2283. // but our message is ANSI, so we must convert.
  2284. // NOTE: We never expect CStiObj_WriteToErrorLogA to be called if we're compiling
  2285. // UNICODE, but just in case...
  2286. //
  2287. LPWSTR lpwszWide = NULL;
  2288. if ( SUCCEEDED(OSUtil_GetWideString(&lpwszWide,pszMessage))) {
  2289. ReportStiLogMessage(g_hStiFileLog,
  2290. dwMessageType,
  2291. lpwszWide
  2292. );
  2293. FreePpv(&lpwszWide);
  2294. }
  2295. #endif
  2296. }
  2297. }
  2298. ExitOleProc();
  2299. return hres;
  2300. }
  2301. /*****************************************************************************
  2302. *
  2303. * @doc EXTERNAL
  2304. *
  2305. * @method HRESULT | IStillImage | |
  2306. *
  2307. *
  2308. * To control state of notification handling. For polled devices this means state of monitor
  2309. * polling, for true notification devices means enabling/disabling notification flow
  2310. * from monitor to registered applications
  2311. *
  2312. *
  2313. * @cwrap LPStillImage | lpStillImage
  2314. *
  2315. * @parm
  2316. *
  2317. * @returns
  2318. *
  2319. * Returns a COM error code. The following error codes are
  2320. * intended to be illustrative and not necessarily comprehensive.
  2321. *
  2322. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  2323. *
  2324. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  2325. * <p ppvOut> parameter is not a valid pointer.
  2326. *
  2327. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  2328. * Out of memory.
  2329. *
  2330. *****************************************************************************/
  2331. STDMETHODIMP
  2332. CStiObj_EnableHwNotificationsW(
  2333. PV pSti,
  2334. LPCWSTR pwszDeviceName,
  2335. BOOL bNewState)
  2336. {
  2337. HRESULT hres = STIERR_INVALID_PARAM;
  2338. DWORD dwError = NOERROR;
  2339. EnterProcR(IStillImage::CStiObj_EnableHwNotifications,(_ "pp", pSti,pwszDeviceName ));
  2340. //
  2341. // Validate passed pointer to interface and obtain pointer to object instance
  2342. //
  2343. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  2344. PCStiObj this = _thisPvNm(pSti, stiW);
  2345. dwError = RpcStiApiEnableHwNotifications(NULL,
  2346. pwszDeviceName,
  2347. bNewState);
  2348. hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
  2349. }
  2350. ExitOleProc();
  2351. return hres;
  2352. }
  2353. STDMETHODIMP
  2354. CStiObj_EnableHwNotificationsA(
  2355. PV pSti,
  2356. LPCSTR pszDeviceName,
  2357. BOOL bNewState)
  2358. {
  2359. HRESULT hres = STIERR_INVALID_PARAM;
  2360. DWORD dwError = NOERROR;
  2361. EnterProcR(IStillImage::CStiObj_EnableHwNotifications,(_ "pp", pSti,pszDeviceName ));
  2362. //
  2363. // Validate passed pointer to interface and obtain pointer to object instance
  2364. //
  2365. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  2366. PCStiObj this = _thisPvNm(pSti, stiA);
  2367. LPWSTR pwszDeviceName=NULL ;
  2368. hres = OSUtil_GetWideString(&pwszDeviceName,pszDeviceName);
  2369. if (SUCCEEDED(hres)) {
  2370. dwError = RpcStiApiEnableHwNotifications(NULL,
  2371. pwszDeviceName,
  2372. bNewState);
  2373. hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
  2374. }
  2375. FreePpv(&pwszDeviceName);
  2376. }
  2377. ExitOleProc();
  2378. return hres;
  2379. }
  2380. /*****************************************************************************
  2381. *
  2382. * @doc EXTERNAL
  2383. *
  2384. * @method HRESULT | IStillImage | |
  2385. *
  2386. *
  2387. * To control state of notification handling. For polled devices this means state of monitor
  2388. * polling, for true notification devices means enabling/disabling notification flow
  2389. * from monitor to registered applications
  2390. *
  2391. *
  2392. * @cwrap LPStillImage | lpStillImage
  2393. *
  2394. * @parm
  2395. *
  2396. * @returns
  2397. *
  2398. * Returns a COM error code. The following error codes are
  2399. * intended to be illustrative and not necessarily comprehensive.
  2400. *
  2401. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  2402. *
  2403. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  2404. * <p ppvOut> parameter is not a valid pointer.
  2405. *
  2406. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  2407. * Out of memory.
  2408. *
  2409. *****************************************************************************/
  2410. STDMETHODIMP
  2411. CStiObj_GetHwNotificationStateW(
  2412. PV pSti,
  2413. LPCWSTR pwszDeviceName,
  2414. BOOL* pbCurrentState)
  2415. {
  2416. HRESULT hres = STIERR_INVALID_PARAM;
  2417. DWORD dwError = NOERROR;
  2418. EnterProcR(IStillImage::CStiObj_GetHwNotificationState,(_ "pp", pSti,pwszDeviceName ));
  2419. //
  2420. // Validate passed pointer to interface and obtain pointer to object instance
  2421. //
  2422. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  2423. PCStiObj this = _thisPvNm(pSti, stiW);
  2424. dwError = RpcStiApiGetHwNotificationState(NULL,
  2425. pwszDeviceName,
  2426. pbCurrentState);
  2427. hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
  2428. }
  2429. ExitOleProc();
  2430. return hres;
  2431. }
  2432. STDMETHODIMP
  2433. CStiObj_GetHwNotificationStateA(
  2434. PV pSti,
  2435. LPCSTR pszDeviceName,
  2436. BOOL* pbCurrentState)
  2437. {
  2438. HRESULT hres = STIERR_INVALID_PARAM;
  2439. DWORD dwError = NOERROR;
  2440. EnterProcR(IStillImage::CStiObj_GetHwNotificationState,(_ "pp", pSti,pszDeviceName ));
  2441. //
  2442. // Validate passed pointer to interface and obtain pointer to object instance
  2443. //
  2444. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  2445. PCStiObj this = _thisPvNm(pSti, stiA);
  2446. LPWSTR pwszDeviceName=NULL ;
  2447. hres = OSUtil_GetWideString(&pwszDeviceName,pszDeviceName);
  2448. if (SUCCEEDED(hres)) {
  2449. dwError = RpcStiApiGetHwNotificationState(NULL,
  2450. pwszDeviceName,
  2451. pbCurrentState);
  2452. hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
  2453. }
  2454. FreePpv(&pwszDeviceName);
  2455. }
  2456. ExitOleProc();
  2457. return hres;
  2458. }
  2459. /*****************************************************************************
  2460. *
  2461. * @doc EXTERNAL
  2462. *
  2463. * @method HRESULT | IStillImage | RefreshDeviceBus |
  2464. *
  2465. *
  2466. * When device is installed but not accessible, application may request bus refresh
  2467. * which in some cases will make device known. This is mainly used for nonPnP buses
  2468. * like SCSI, when device was powered on after PnP enumeration
  2469. *
  2470. *
  2471. *
  2472. *
  2473. * @cwrap LPStillImage | lpStillImage
  2474. *
  2475. * @parm
  2476. *
  2477. * @returns
  2478. *
  2479. * Returns a COM error code. The following error codes are
  2480. * intended to be illustrative and not necessarily comprehensive.
  2481. *
  2482. * <c DI_OK> = <c S_OK>: The operation completed successfully.
  2483. *
  2484. * <c STIERR_INVALIDPARAM> = <c E_INVALIDARG>: The
  2485. * <p ppvOut> parameter is not a valid pointer.
  2486. *
  2487. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  2488. * Out of memory.
  2489. *
  2490. *****************************************************************************/
  2491. HRESULT
  2492. WINAPI
  2493. RefreshDeviceParentHelper(
  2494. LPCWSTR pwszDeviceName
  2495. )
  2496. {
  2497. HRESULT hres;
  2498. DWORD dwError = NOERROR;
  2499. CONFIGRET cmRetCode = CR_SUCCESS ;
  2500. HANDLE hDevInfo;
  2501. DEVINST hdevParent;
  2502. GUID Guid = GUID_DEVCLASS_IMAGE;
  2503. DWORD dwRequired;
  2504. DWORD Idx;
  2505. SP_DEVINFO_DATA spDevInfoData;
  2506. WCHAR szDevDriver[STI_MAX_INTERNAL_NAME_LENGTH];
  2507. ULONG cbData;
  2508. BOOL fRet;
  2509. BOOL fFoundDriverNameMatch;
  2510. dwRequired = 0;
  2511. dwError = 0;
  2512. //
  2513. // Navigating through Setup API set
  2514. // As we don't have reverse search to retrive device info handle , based on
  2515. // driver name, we do exsaustive search. Number of imaging devices for given class ID
  2516. // is never as large to make a problem.
  2517. //
  2518. //
  2519. hDevInfo = SetupDiGetClassDevs (&Guid, NULL, NULL, DIGCF_PRESENT | DIGCF_PROFILE);
  2520. fFoundDriverNameMatch = FALSE;
  2521. hres = STIERR_INVALID_DEVICE_NAME;
  2522. if (hDevInfo != INVALID_HANDLE_VALUE) {
  2523. spDevInfoData.cbSize = sizeof (SP_DEVINFO_DATA);
  2524. for (Idx = 0; SetupDiEnumDeviceInfo (hDevInfo, Idx, &spDevInfoData); Idx++) {
  2525. //
  2526. // Compare driver name
  2527. //
  2528. *szDevDriver = L'\0';
  2529. fRet = SetupDiGetDeviceRegistryPropertyW (hDevInfo,
  2530. &spDevInfoData,
  2531. SPDRP_DRIVER,
  2532. NULL,
  2533. (LPBYTE)szDevDriver,
  2534. sizeof (szDevDriver),
  2535. &cbData
  2536. );
  2537. if (fRet && !lstrcmpiW(szDevDriver,pwszDeviceName)) {
  2538. fFoundDriverNameMatch = TRUE;
  2539. break;
  2540. }
  2541. }
  2542. if(fFoundDriverNameMatch) {
  2543. //
  2544. // Found instance for the device with matching driver name
  2545. //
  2546. hdevParent = 0;
  2547. cmRetCode = CM_Get_Parent(&hdevParent,
  2548. spDevInfoData.DevInst,
  2549. 0);
  2550. dwError = GetLastError();
  2551. if((CR_SUCCESS == cmRetCode) && hdevParent) {
  2552. CM_Reenumerate_DevNode(hdevParent,CM_REENUMERATE_NORMAL );
  2553. dwError = GetLastError();
  2554. }
  2555. hres = (dwError == NOERROR) ? S_OK : MAKE_HRESULT(SEVERITY_ERROR,FACILITY_WIN32,dwError);
  2556. }
  2557. else {
  2558. hres = STIERR_INVALID_DEVICE_NAME;
  2559. }
  2560. //
  2561. SetupDiDestroyDeviceInfoList (hDevInfo);
  2562. }
  2563. else {
  2564. hres = STIERR_INVALID_DEVICE_NAME;
  2565. }
  2566. return hres;
  2567. }
  2568. STDMETHODIMP
  2569. CStiObj_RefreshDeviceBusW(
  2570. PV pSti,
  2571. LPCWSTR pwszDeviceName
  2572. )
  2573. {
  2574. HRESULT hres = STIERR_INVALID_PARAM;
  2575. DWORD dwErr = NOERROR;
  2576. CONFIGRET cmRetCode = CR_SUCCESS ;
  2577. EnterProcR(IStillImage::CStiObj_RefreshDeviceBus,(_ "pp", pSti,pwszDeviceName ));
  2578. //
  2579. // Validate passed pointer to interface and obtain pointer to object instance
  2580. //
  2581. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  2582. PCStiObj this = _thisPvNm(pSti, stiW);
  2583. hres = RefreshDeviceParentHelper(pwszDeviceName);
  2584. }
  2585. ExitOleProc();
  2586. return hres;
  2587. }
  2588. STDMETHODIMP
  2589. CStiObj_RefreshDeviceBusA(
  2590. PV pSti,
  2591. LPCSTR pszDeviceName
  2592. )
  2593. {
  2594. HRESULT hres = STIERR_INVALID_PARAM;
  2595. DWORD dwError = NOERROR;
  2596. EnterProcR(IStillImage::CStiObj_RefreshDeviceBus,(_ "pp", pSti,pszDeviceName ));
  2597. //
  2598. // Validate passed pointer to interface and obtain pointer to object instance
  2599. //
  2600. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  2601. PCStiObj this = _thisPvNm(pSti, stiA);
  2602. LPWSTR pwszDeviceName=NULL ;
  2603. hres = OSUtil_GetWideString(&pwszDeviceName,pszDeviceName);
  2604. if (SUCCEEDED(hres)) {
  2605. if (pwszDeviceName) {
  2606. hres = RefreshDeviceParentHelper(pwszDeviceName);
  2607. FreePpv(&pwszDeviceName);
  2608. }
  2609. }
  2610. }
  2611. ExitOleProc();
  2612. return hres;
  2613. }
  2614. ////////////////////////////////////////////////////////////////////////////////
  2615. /*****************************************************************************
  2616. *
  2617. * @doc EXTERNAL
  2618. *
  2619. * @method HRESULT | IStillImage | Initialize |
  2620. *
  2621. * Initialize a StillImage object.
  2622. *
  2623. * The <f StillImageCreate> method automatically
  2624. * initializes the StillImage object device after creating it.
  2625. * Applications normally do not need to call this function.
  2626. *
  2627. * @cwrap LPStillImage | lpStillImage
  2628. *
  2629. * @parm IN HINSTANCE | hinst |
  2630. *
  2631. * Instance handle of the application or DLL that is creating
  2632. * the StillImage object.
  2633. *
  2634. * StillImage uses this value to determine whether the
  2635. * application or DLL has been certified.
  2636. *
  2637. * @parm DWORD | dwVersion |
  2638. *
  2639. * Version number of the dinput.h header file that was used.
  2640. * This value must be <c StillImage_VERSION>.
  2641. *
  2642. * StillImage uses this value to determine what version of
  2643. * StillImage the application or DLL was designed for.
  2644. *
  2645. * @returns
  2646. * Returns a COM error code. The following error codes are
  2647. * intended to be illustrative and not necessarily comprehensive.
  2648. *
  2649. * <c DI_OK> = <c S_OK>: The device is attached.
  2650. *
  2651. *****************************************************************************/
  2652. STDMETHODIMP
  2653. CStiObj_InitializeW(
  2654. PV pSti,
  2655. HINSTANCE hinst,
  2656. DWORD dwVersion
  2657. )
  2658. {
  2659. HRESULT hres;
  2660. EnterProcR(IStillImage::Initialize, (_ "pxx", pSti, hinst, dwVersion));
  2661. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceW))) {
  2662. PCStiObj this = _thisPv(pSti);
  2663. if (SUCCEEDED(hres = hresValidInstanceVer(hinst, dwVersion))) {
  2664. this->dwVersion = dwVersion;
  2665. }
  2666. }
  2667. ExitOleProc();
  2668. return hres;
  2669. }
  2670. STDMETHODIMP
  2671. CStiObj_InitializeA(
  2672. PV pSti,
  2673. HINSTANCE hinst,
  2674. DWORD dwVersion
  2675. )
  2676. {
  2677. HRESULT hres;
  2678. EnterProcR(IStillImage::Initialize, (_ "pxx", pSti, hinst, dwVersion));
  2679. if (SUCCEEDED(hres = hresPvI(pSti, ThisInterfaceA))) {
  2680. PCStiObj this = _thisPv(pSti);
  2681. if (SUCCEEDED(hres = hresValidInstanceVer(hinst, dwVersion))) {
  2682. this->dwVersion = dwVersion;
  2683. }
  2684. }
  2685. ExitOleProc();
  2686. return hres;
  2687. }
  2688. /*****************************************************************************
  2689. *
  2690. * @doc INTERNAL
  2691. *
  2692. * @func void | CStiObj_Finalize |
  2693. *
  2694. * Releases the resources of a STI object
  2695. *
  2696. * @parm PV | pvObj |
  2697. *
  2698. * Object being released. Note that it may not have been
  2699. * completely initialized, so everything should be done
  2700. * carefully.
  2701. *
  2702. *****************************************************************************/
  2703. void INTERNAL
  2704. CStiObj_Finalize(PV pvObj)
  2705. {
  2706. PCStiObj this = pvObj;
  2707. //
  2708. // Free COM libraries if connected to them
  2709. //
  2710. DllUnInitializeCOM();
  2711. }
  2712. /*****************************************************************************
  2713. *
  2714. * @doc INTERNAL
  2715. *
  2716. * @func HRESULT | StiCreateHelper |
  2717. *
  2718. * <bnew>This function creates a new StillImage object
  2719. * which supports the <i IStillImage> COM interface.
  2720. *
  2721. * On success, the function returns a pointer to the new object in
  2722. * *<p lplpSti>.
  2723. * <enew>
  2724. *
  2725. * @parm IN HINSTANCE | hinst |
  2726. *
  2727. * Instance handle of the application or DLL that is creating
  2728. * the Sti object.
  2729. *
  2730. * @parm DWORD | dwVersion |
  2731. *
  2732. * Version number of the sti.h header file that was used.
  2733. * This value must be <c STI_VERSION>.
  2734. *
  2735. * @parm OUT PPV | ppvObj |
  2736. * Points to where to return
  2737. * the pointer to the <i ISti> interface, if successful.
  2738. *
  2739. * @parm IN LPUNKNOWN | punkOuter | Pointer to controlling unknown.
  2740. *
  2741. * @parm RIID | riid |
  2742. *
  2743. * The interface the application wants to create.
  2744. *
  2745. * If the object is aggregated, then this parameter is ignored.
  2746. *
  2747. * @returns
  2748. *
  2749. * Returns a COM error code. The following error codes are
  2750. * intended to be illustrative and not necessarily comprehensive.
  2751. *
  2752. * <c STI_OK> = <c S_OK>: The operation completed successfully.
  2753. *
  2754. * <c STIERR_INVALIDPARAM>
  2755. *
  2756. * <c STIERR_OUTOFMEMORY> = <c E_OUTOFMEMORY>:
  2757. * Out of memory.
  2758. *
  2759. *****************************************************************************/
  2760. STDMETHODIMP
  2761. StiCreateHelper(
  2762. HINSTANCE hinst,
  2763. DWORD dwVer,
  2764. PPV ppvObj,
  2765. PUNK punkOuter,
  2766. RIID riid)
  2767. {
  2768. HRESULT hres;
  2769. EnterProc(StiCreateHelper,
  2770. (_ "xxxG", hinst, dwVer, punkOuter, riid));
  2771. hres = CStiObj_New(punkOuter,punkOuter ? &IID_IUnknown : riid, ppvObj);
  2772. if (SUCCEEDED(hres) && punkOuter == 0) {
  2773. PSTI psti = *ppvObj;
  2774. hres = psti->lpVtbl->Initialize(psti, hinst, dwVer);
  2775. if (SUCCEEDED(hres)) {
  2776. } else {
  2777. Invoke_Release(ppvObj);
  2778. }
  2779. }
  2780. ExitOleProcPpv(ppvObj);
  2781. return hres;
  2782. }
  2783. /*****************************************************************************
  2784. *
  2785. * @doc INTERNAL
  2786. *
  2787. * @mfunc HRESULT | IStillImage | New |
  2788. *
  2789. * Create a new instance of an IStillImage object.
  2790. *
  2791. * @parm IN PUNK | punkOuter |
  2792. *
  2793. * Controlling unknown for aggregation.
  2794. *
  2795. * @parm IN RIID | riid |
  2796. * Desired interface to new object.
  2797. *
  2798. * @parm OUT PPV | ppvObj |
  2799. * Output pointer for new object.
  2800. *
  2801. * @returns
  2802. *
  2803. * Standard OLE <t HRESULT>.
  2804. *
  2805. *****************************************************************************/
  2806. STDMETHODIMP
  2807. CStiObj_New(PUNK punkOuter, RIID riid, PPV ppvObj)
  2808. {
  2809. HRESULT hres;
  2810. EnterProcR(IStillImage::CreateInstance, (_ "Gp", riid, ppvObj));
  2811. hres = Common_NewRiid(CStiObj, punkOuter, riid, ppvObj);
  2812. ExitOleProcPpvR(ppvObj);
  2813. return hres;
  2814. }
  2815. /*****************************************************************************
  2816. *
  2817. * The long-awaited vtbls and templates
  2818. *
  2819. *****************************************************************************/
  2820. #pragma BEGIN_CONST_DATA
  2821. #define CStiObj_Signature (DWORD)'STI'
  2822. Interface_Template_Begin(CStiObj)
  2823. Primary_Interface_Template(CStiObj,TFORM(ThisInterfaceT))
  2824. Secondary_Interface_Template(CStiObj, SFORM(ThisInterfaceT))
  2825. Interface_Template_End(CStiObj)
  2826. Primary_Interface_Begin(CStiObj, TFORM(ThisInterfaceT))
  2827. TFORM(CStiObj_Initialize),
  2828. TFORM(CStiObj_GetDeviceList),
  2829. TFORM(CStiObj_GetDeviceInfo),
  2830. TFORM(CStiObj_CreateDevice),
  2831. TFORM(CStiObj_GetDeviceValue),
  2832. TFORM(CStiObj_SetDeviceValue),
  2833. TFORM(CStiObj_GetSTILaunchInformation),
  2834. TFORM(CStiObj_RegisterLaunchApplication),
  2835. TFORM(CStiObj_UnregisterLaunchApplication),
  2836. TFORM(CStiObj_EnableHwNotifications),
  2837. TFORM(CStiObj_GetHwNotificationState),
  2838. TFORM(CStiObj_RefreshDeviceBus),
  2839. TFORM(CStiObj_LaunchApplicationForDevice),
  2840. TFORM(CStiObj_SetupDeviceParameters),
  2841. TFORM(CStiObj_WriteToErrorLog)
  2842. Primary_Interface_End(CStiObj, TFORM(ThisInterfaceT))
  2843. Secondary_Interface_Begin(CStiObj,SFORM(ThisInterfaceT), SFORM(sti))
  2844. SFORM(CStiObj_Initialize),
  2845. SFORM(CStiObj_GetDeviceList),
  2846. SFORM(CStiObj_GetDeviceInfo),
  2847. SFORM(CStiObj_CreateDevice),
  2848. SFORM(CStiObj_GetDeviceValue),
  2849. SFORM(CStiObj_SetDeviceValue),
  2850. SFORM(CStiObj_GetSTILaunchInformation),
  2851. SFORM(CStiObj_RegisterLaunchApplication),
  2852. SFORM(CStiObj_UnregisterLaunchApplication),
  2853. SFORM(CStiObj_EnableHwNotifications),
  2854. SFORM(CStiObj_GetHwNotificationState),
  2855. SFORM(CStiObj_RefreshDeviceBus),
  2856. SFORM(CStiObj_LaunchApplicationForDevice),
  2857. SFORM(CStiObj_SetupDeviceParameters),
  2858. SFORM(CStiObj_WriteToErrorLog)
  2859. Secondary_Interface_End(CStiObj,SFORM(ThisInterfaceT), SFORM(sti))