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

2406 lines
73 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT 2001, MICROSOFT CORP.
  4. *
  5. * TITLE: IWiaMiniDrv.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * DATE: 15 Nov, 2000
  10. *
  11. * DESCRIPTION:
  12. * Implementation of the WIA File System Device driver IWiaMiniDrv methods. This file
  13. * contains 3 sections. The first is the WIA minidriver entry points, all
  14. * starting with "drv". The next section is public help methods. The last
  15. * section is private helper methods.
  16. *
  17. *******************************************************************************/
  18. #include "pch.h"
  19. //
  20. // This structure is a convenient way to map between the FORMAT_CODEs and info
  21. // useful for WIA, such as the format GUIDs and item types. These need to
  22. // correspond to the constants defined in FakeCam.h.
  23. //
  24. // FORMAT_INFO *g_FormatInfo;
  25. // extern UINT g_NumFormatInfo=0;
  26. // The following are utility functions for populate the g_FormatInfo array
  27. LONG GetTypeInfoFromRegistry(HKEY *phKeyExt, WCHAR *wcsKeyName, GUID *pFormatGuid)
  28. {
  29. if( !pFormatGuid )
  30. {
  31. return ITEMTYPE_FILE; // In this case, no info from Registry about file type.
  32. }
  33. HKEY hKeyCur;
  34. const int c_nMaxValueLength = 64;
  35. DWORD dwRet = RegOpenKeyExW(*phKeyExt, wcsKeyName, 0, KEY_READ | KEY_QUERY_VALUE, &hKeyCur);
  36. if( dwRet != ERROR_SUCCESS )
  37. {
  38. return ITEMTYPE_FILE;
  39. }
  40. WCHAR wcsValueName[c_nMaxValueLength] = L"Generic";
  41. WCHAR wcsData[MAX_PATH];
  42. DWORD dwType = REG_SZ;
  43. DWORD dwSize = MAX_PATH;
  44. dwRet = RegQueryValueExW(hKeyCur,
  45. wcsValueName, NULL, &dwType, (LPBYTE)wcsData, &dwSize );
  46. DWORD dwItemType = ITEMTYPE_FILE;
  47. if( ERROR_SUCCESS == dwRet )
  48. {
  49. if( CSTR_EQUAL == CompareStringW(LOCALE_SYSTEM_DEFAULT,
  50. NORM_IGNORECASE, L"image", 5, wcsData, 5) )
  51. {
  52. dwItemType = ITEMTYPE_IMAGE;
  53. }
  54. else if ( CSTR_EQUAL == CompareStringW(LOCALE_SYSTEM_DEFAULT,
  55. NORM_IGNORECASE, L"audio", 5, wcsData, 5) )
  56. {
  57. dwItemType = ITEMTYPE_AUDIO;
  58. }
  59. else if ( CSTR_EQUAL == CompareStringW(LOCALE_SYSTEM_DEFAULT,
  60. NORM_IGNORECASE, L"video", 5, wcsData, 5) )
  61. {
  62. dwItemType = ITEMTYPE_VIDEO;
  63. }
  64. else
  65. {
  66. dwItemType = ITEMTYPE_FILE;
  67. }
  68. }
  69. StringCchCopyW(wcsValueName, c_nMaxValueLength, L"FormatGUID");
  70. dwType = REG_SZ;
  71. dwSize = MAX_PATH;
  72. dwRet = RegQueryValueExW(hKeyCur,
  73. wcsValueName,
  74. NULL,
  75. &dwType,
  76. (LPBYTE)wcsData,
  77. &dwSize );
  78. if( ERROR_SUCCESS == dwRet )
  79. {
  80. wcsData[dwSize]=0;
  81. if( NOERROR != CLSIDFromString(wcsData, pFormatGuid))
  82. {
  83. CopyMemory(pFormatGuid, (CONST VOID *)&WiaImgFmt_UNDEFINED, sizeof(GUID));
  84. }
  85. }
  86. else
  87. {
  88. CopyMemory(pFormatGuid, (CONST VOID *)&WiaImgFmt_UNDEFINED, sizeof(GUID));
  89. }
  90. RegCloseKey(hKeyCur);
  91. return dwItemType;
  92. }
  93. DWORD CWiaCameraDevice::PopulateFormatInfo(void)
  94. {
  95. HKEY hKeyExt = NULL;
  96. DWORD dwRet, dwCurAllocation = 32;
  97. DWORD dwIndex=0, dwIndexBase=0, dwKeyNameSize=32;
  98. m_FormatInfo = (FORMAT_INFO *)CoTaskMemAlloc(sizeof(FORMAT_INFO)*dwCurAllocation);
  99. if( !m_FormatInfo )
  100. {
  101. dwRet = ERROR_OUTOFMEMORY;
  102. goto Exit;
  103. }
  104. m_FormatInfo[0].FormatGuid = WiaImgFmt_UNDEFINED;
  105. m_FormatInfo[0].ItemType = ITEMTYPE_FILE;
  106. m_FormatInfo[0].ExtensionString[0] = L'\0';
  107. dwIndexBase=1;
  108. dwIndex=0;
  109. dwRet = RegOpenKeyExW(HKEY_CLASSES_ROOT,
  110. L"CLSID\\{D2923B86-15F1-46FF-A19A-DE825F919576}\\SupportedExtension",
  111. 0, KEY_READ | KEY_QUERY_VALUE, &hKeyExt);
  112. if( ERROR_SUCCESS != dwRet ) // No Key exist
  113. {
  114. goto Compilation;
  115. }
  116. WCHAR wcsKeyName[32], *pExt;
  117. FILETIME ftLWT;
  118. dwRet = RegEnumKeyExW(hKeyExt, dwIndex, wcsKeyName, &dwKeyNameSize, NULL, NULL, NULL, &ftLWT);
  119. if( ERROR_SUCCESS != dwRet ) // No key exist
  120. {
  121. goto Compilation;
  122. }
  123. while ( dwRet == ERROR_SUCCESS )
  124. {
  125. pExt = (wcsKeyName[0]==L'.'?(&wcsKeyName[1]):(&wcsKeyName[0])); // remove the dot
  126. pExt[MAXEXTENSIONSTRINGLENGTH-1] = NULL; // Truncate to avoid overrun
  127. // Set values in FORMAT_INFO structure
  128. StringCchCopyW(m_FormatInfo[dwIndex+dwIndexBase].ExtensionString, MAXEXTENSIONSTRINGLENGTH, pExt);
  129. m_FormatInfo[dwIndex+dwIndexBase].ItemType = GetTypeInfoFromRegistry(&hKeyExt, wcsKeyName, &(m_FormatInfo[dwIndex+dwIndexBase].FormatGuid));
  130. dwIndex++;
  131. if( dwIndex+dwIndexBase > dwCurAllocation-1 ) // need allocate more memory
  132. {
  133. dwCurAllocation += 32;
  134. m_FormatInfo = (FORMAT_INFO *)CoTaskMemRealloc(m_FormatInfo, sizeof(FORMAT_INFO)*dwCurAllocation);
  135. if( !m_FormatInfo )
  136. {
  137. dwRet = ERROR_OUTOFMEMORY;
  138. dwIndex --;
  139. goto Exit;
  140. }
  141. }
  142. dwKeyNameSize=32;
  143. dwRet = RegEnumKeyExW(hKeyExt, dwIndex, wcsKeyName, &dwKeyNameSize, NULL, NULL, NULL, &ftLWT);
  144. }
  145. if(dwRet == ERROR_NO_MORE_ITEMS )
  146. {
  147. dwRet = ERROR_SUCCESS;
  148. goto Exit;
  149. }
  150. Compilation: // Compile a fixed list of formats when error occurs
  151. dwIndex=dwIndexBase=0;
  152. dwRet = ERROR_SUCCESS;
  153. DEFAULT_FORMAT_INFO g_DefaultFormats[] =
  154. {
  155. { (GUID *)&WiaImgFmt_UNDEFINED, ITEMTYPE_FILE, L"" }, // Unknown
  156. { (GUID *)&WiaImgFmt_JPEG, ITEMTYPE_IMAGE, L"JPG" }, // JPEG or EXIF
  157. { (GUID *)&WiaImgFmt_TIFF, ITEMTYPE_IMAGE, L"TIF" }, // TIFF
  158. { (GUID *)&WiaImgFmt_BMP, ITEMTYPE_IMAGE, L"BMP" }, // BMP
  159. { (GUID *)&WiaImgFmt_GIF, ITEMTYPE_IMAGE, L"GIF" }, // GIF
  160. { NULL, 0, NULL }
  161. };
  162. while( g_DefaultFormats[dwIndex].pFormatGuid )
  163. {
  164. m_FormatInfo[dwIndex].FormatGuid = *g_DefaultFormats[dwIndex].pFormatGuid;
  165. m_FormatInfo[dwIndex].ItemType = g_DefaultFormats[dwIndex].ItemType;
  166. StringCchCopyW(m_FormatInfo[dwIndex].ExtensionString, MAXEXTENSIONSTRINGLENGTH, g_DefaultFormats[dwIndex].ExtensionString);
  167. dwIndex++;
  168. }
  169. Exit:
  170. m_NumFormatInfo = dwIndex+dwIndexBase;
  171. if (hKeyExt != NULL ) {
  172. RegCloseKey(hKeyExt);
  173. hKeyExt = NULL;
  174. }
  175. return dwRet;
  176. }
  177. void CWiaCameraDevice::UnPopulateFormatInfo(void)
  178. {
  179. CoTaskMemFree(m_FormatInfo);
  180. }
  181. /**************************************************************************\
  182. * CWiaCameraDevice::drvInitializeWia
  183. *
  184. * Initialize the WIA mini driver. This function will be called each time an
  185. * application creates a device. The first time through, the driver item tree
  186. * will be created and other initialization will be done.
  187. *
  188. * Arguments:
  189. *
  190. * pWiasContext - Pointer to the WIA item, unused.
  191. * lFlags - Operation flags, unused.
  192. * bstrDeviceID - Device ID.
  193. * bstrRootFullItemName - Full item name.
  194. * pIPropStg - Device info. properties.
  195. * pStiDevice - STI device interface.
  196. * pIUnknownOuter - Outer unknown interface.
  197. * ppIDrvItemRoot - Pointer to returned root item.
  198. * ppIUnknownInner - Pointer to returned inner unknown.
  199. * plDevErrVal - Pointer to the device error value.
  200. *
  201. \**************************************************************************/
  202. HRESULT CWiaCameraDevice::drvInitializeWia(
  203. BYTE *pWiasContext,
  204. LONG lFlags,
  205. BSTR bstrDeviceID,
  206. BSTR bstrRootFullItemName,
  207. IUnknown *pStiDevice,
  208. IUnknown *pIUnknownOuter,
  209. IWiaDrvItem **ppIDrvItemRoot,
  210. IUnknown **ppIUnknownInner,
  211. LONG *plDevErrVal)
  212. {
  213. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  214. WIALOG_NO_RESOURCE_ID,
  215. WIALOG_LEVEL1,
  216. "CWiaCameraDevice::drvInitializeWia");
  217. HRESULT hr = S_OK;
  218. *plDevErrVal = 0;
  219. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL4,("drvInitializeWia, device ID: %ws", bstrDeviceID));
  220. *ppIDrvItemRoot = NULL;
  221. *ppIUnknownInner = NULL;
  222. m_ConnectedApps++;;
  223. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvInitializeWia, number of connected apps is now %d", m_ConnectedApps));
  224. if (m_ConnectedApps == 1)
  225. {
  226. if (ERROR_SUCCESS != PopulateFormatInfo() ) {
  227. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, unable to populate FormatInfo array"));
  228. return E_OUTOFMEMORY;
  229. }
  230. //
  231. // Save STI device interface for calling locking functions
  232. //
  233. m_pStiDevice = (IStiDevice *)pStiDevice;
  234. //
  235. // Cache the device ID
  236. //
  237. m_bstrDeviceID = SysAllocString(bstrDeviceID);
  238. if (!m_bstrDeviceID) {
  239. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, unable to allocate device ID string"));
  240. return E_OUTOFMEMORY;
  241. }
  242. //
  243. // Cache the root item name
  244. //
  245. m_bstrRootFullItemName = SysAllocString(bstrRootFullItemName);
  246. if (!m_bstrRootFullItemName) {
  247. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, unable to allocate root item name"));
  248. return E_OUTOFMEMORY;
  249. }
  250. if( m_pDevice )
  251. {
  252. m_pDevice->m_FormatInfo = m_FormatInfo;
  253. m_pDevice->m_NumFormatInfo = m_NumFormatInfo;
  254. }
  255. else
  256. {
  257. return (HRESULT_FROM_WIN32(ERROR_INVALID_ACCESS));
  258. }
  259. //
  260. // Get information from the device
  261. //
  262. hr = m_pDevice->GetDeviceInfo(&m_DeviceInfo);
  263. if (FAILED(hr))
  264. {
  265. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, GetDeviceInfo failed"));
  266. return hr;
  267. }
  268. //
  269. // Build the capabilities array
  270. //
  271. hr = BuildCapabilities();
  272. if (FAILED(hr))
  273. {
  274. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, BuildCapabilities failed"));
  275. return hr;
  276. }
  277. //
  278. // Build the device item tree
  279. //
  280. hr = BuildItemTree();
  281. if (FAILED(hr))
  282. {
  283. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitializeWia, BuildItemTree failed"));
  284. return hr;
  285. }
  286. }
  287. *ppIDrvItemRoot = m_pRootItem;
  288. return hr;
  289. }
  290. /**************************************************************************\
  291. * CWiaCameraDevice::drvUnInitializeWia
  292. *
  293. * Gets called when a client connection is going away.
  294. *
  295. * Arguments:
  296. *
  297. * pWiasContext - Pointer to the WIA Root item context of the client's
  298. * item tree.
  299. *
  300. \**************************************************************************/
  301. HRESULT CWiaCameraDevice::drvUnInitializeWia(BYTE *pWiasContext)
  302. {
  303. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  304. WIALOG_NO_RESOURCE_ID,
  305. WIALOG_LEVEL1,
  306. "CWiaCameraDevice::drvUnInitializeWia");
  307. HRESULT hr = S_OK;
  308. m_ConnectedApps--;
  309. if (m_ConnectedApps == 0)
  310. {
  311. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL2,("drvUnInitializeWia, connected apps is zero, freeing resources..."));
  312. // Destroy the driver item tree
  313. hr = DeleteItemTree(WiaItemTypeDisconnected);
  314. if (FAILED(hr))
  315. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvUnInitializeWia, UnlinkItemTree failed"));
  316. // Delete allocated arrays
  317. DeleteCapabilitiesArrayContents();
  318. // Free the device info structure
  319. m_pDevice->FreeDeviceInfo(&m_DeviceInfo);
  320. // Free the item handle map
  321. m_HandleItemMap.RemoveAll();
  322. // Free the storage for the device ID
  323. if (m_bstrDeviceID) {
  324. SysFreeString(m_bstrDeviceID);
  325. }
  326. // Free the storage for the root item name
  327. if (m_bstrRootFullItemName) {
  328. SysFreeString(m_bstrRootFullItemName);
  329. }
  330. UnPopulateFormatInfo();
  331. //
  332. // Do not delete the device here, because GetStatus may still be called later
  333. //
  334. /*
  335. // Kill notification thread if it exists.
  336. SetNotificationHandle(NULL);
  337. // Close event for syncronization of notifications shutdown.
  338. if (m_hShutdownEvent && (m_hShutdownEvent != INVALID_HANDLE_VALUE)) {
  339. CloseHandle(m_hShutdownEvent);
  340. m_hShutdownEvent = NULL;
  341. }
  342. //
  343. // WIA member destruction
  344. //
  345. // Cleanup the WIA event sink.
  346. if (m_pIWiaEventCallback) {
  347. m_pIWiaEventCallback->Release();
  348. m_pIWiaEventCallback = NULL;
  349. }
  350. */
  351. }
  352. return hr;
  353. }
  354. /**************************************************************************\
  355. * CWiaCameraDevice::drvInitItemProperties
  356. *
  357. * Initialize the device item properties. Called during item
  358. * initialization. This is called by the WIA Class driver
  359. * after the item tree has been built. It is called once for every
  360. * item in the tree. For the root item, just set the properties already
  361. * set up in drvInitializeWia. For child items, access the camera for
  362. * information about the item and for images also get the thumbnail.
  363. *
  364. * Arguments:
  365. *
  366. * pWiasContext - Pointer to WIA item.
  367. * lFlags - Operation flags, unused.
  368. * plDevErrVal - Pointer to the device error value.
  369. *
  370. *
  371. \**************************************************************************/
  372. HRESULT CWiaCameraDevice::drvInitItemProperties(
  373. BYTE *pWiasContext,
  374. LONG lFlags,
  375. LONG *plDevErrVal)
  376. {
  377. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  378. WIALOG_NO_RESOURCE_ID,
  379. WIALOG_LEVEL1,
  380. "CWiaCameraDevice::drvInitItemProperties");
  381. HRESULT hr = S_OK;
  382. *plDevErrVal = 0;
  383. LONG lItemType;
  384. hr = wiasGetItemType(pWiasContext, &lItemType);
  385. if (FAILED(hr))
  386. {
  387. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvInitItemProperties, wiasGetItemType failed"));
  388. WIAS_LHRESULT(m_pIWiaLog, hr);
  389. return hr;
  390. }
  391. if (lItemType & WiaItemTypeRoot) {
  392. //
  393. // Build root item properties, initializing global
  394. // structures with their default and valid values
  395. //
  396. hr = BuildRootItemProperties(pWiasContext);
  397. } else {
  398. //
  399. // Build child item properties, initializing global
  400. // structures with their default and valid values
  401. //
  402. hr = BuildChildItemProperties(pWiasContext);
  403. }
  404. return hr;
  405. }
  406. /**************************************************************************\
  407. * CWiaCameraDevice::drvLockWiaDevice
  408. *
  409. * Lock access to the device.
  410. *
  411. * Arguments:
  412. *
  413. * pWiasContext - unused, can be NULL
  414. * lFlags - Operation flags, unused.
  415. * plDevErrVal - Pointer to the device error value.
  416. *
  417. *
  418. \**************************************************************************/
  419. HRESULT CWiaCameraDevice::drvLockWiaDevice(
  420. BYTE *pWiasContext,
  421. LONG lFlags,
  422. LONG *plDevErrVal)
  423. {
  424. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  425. WIALOG_NO_RESOURCE_ID,
  426. WIALOG_LEVEL1,
  427. "CWiaCameraDevice::drvLockWiaDevice");
  428. *plDevErrVal = 0;
  429. return m_pStiDevice->LockDevice(100);
  430. }
  431. /**************************************************************************\
  432. * CWiaCameraDevice::drvUnLockWiaDevice
  433. *
  434. * Unlock access to the device.
  435. *
  436. * Arguments:
  437. *
  438. * pWiasContext - Pointer to the WIA item, unused.
  439. * lFlags - Operation flags, unused.
  440. * plDevErrVal - Pointer to the device error value.
  441. *
  442. \**************************************************************************/
  443. HRESULT CWiaCameraDevice::drvUnLockWiaDevice(
  444. BYTE *pWiasContext,
  445. LONG lFlags,
  446. LONG *plDevErrVal)
  447. {
  448. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  449. WIALOG_NO_RESOURCE_ID,
  450. WIALOG_LEVEL1,
  451. "CWiaCameraDevice::drvUnLockWiaDevice");
  452. *plDevErrVal = 0;
  453. return m_pStiDevice->UnLockDevice();
  454. }
  455. /**************************************************************************\
  456. * CWiaCameraDevice::drvFreeDrvItemContext
  457. *
  458. * Free any device specific context.
  459. *
  460. * Arguments:
  461. *
  462. * lFlags - Operation flags, unused.
  463. * pDevSpecContext - Pointer to device specific context.
  464. * plDevErrVal - Pointer to the device error value.
  465. *
  466. \**************************************************************************/
  467. HRESULT CWiaCameraDevice::drvFreeDrvItemContext(
  468. LONG lFlags,
  469. BYTE *pSpecContext,
  470. LONG *plDevErrVal)
  471. {
  472. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  473. WIALOG_NO_RESOURCE_ID,
  474. WIALOG_LEVEL1,
  475. "CWiaCameraDevice::drvFreeDrvItemContext");
  476. *plDevErrVal = 0;
  477. ITEM_CONTEXT *pItemCtx = (ITEM_CONTEXT *) pSpecContext;
  478. if (pItemCtx)
  479. {
  480. if (!m_HandleItemMap.Remove(pItemCtx->ItemHandle))
  481. WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvFreeDrvItemContext, remove on handle item map failed"));
  482. if (pItemCtx->ItemHandle)
  483. m_pDevice->FreeItemInfo(pItemCtx->ItemHandle);
  484. pItemCtx->ItemHandle = NULL;
  485. if (pItemCtx->pFormatInfo)
  486. {
  487. delete []pItemCtx->pFormatInfo;
  488. pItemCtx->pFormatInfo = NULL;
  489. }
  490. pItemCtx->NumFormatInfo = 0;
  491. if (pItemCtx->pThumb)
  492. {
  493. delete []pItemCtx->pThumb;
  494. pItemCtx->pThumb = NULL;
  495. }
  496. pItemCtx->ThumbSize = 0;
  497. }
  498. return S_OK;
  499. }
  500. /**************************************************************************\
  501. * CWiaCameraDevice::drvReadItemProperties
  502. *
  503. * Read the device item properties. When a client application tries to
  504. * read a WIA Item's properties, the WIA Class driver will first notify
  505. * the driver by calling this method.
  506. *
  507. * Arguments:
  508. *
  509. * pWiasContext - wia item
  510. * lFlags - Operation flags, unused.
  511. * nPropSpec - Number of elements in pPropSpec.
  512. * pPropSpec - Pointer to property specification, showing which properties
  513. * the application wants to read.
  514. * plDevErrVal - Pointer to the device error value.
  515. *
  516. \**************************************************************************/
  517. HRESULT CWiaCameraDevice::drvReadItemProperties(
  518. BYTE *pWiasContext,
  519. LONG lFlags,
  520. ULONG nPropSpec,
  521. const PROPSPEC *pPropSpec,
  522. LONG *plDevErrVal)
  523. {
  524. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  525. WIALOG_NO_RESOURCE_ID,
  526. WIALOG_LEVEL1,
  527. "CWiaCameraDevice::drvReadItemProperties");
  528. HRESULT hr = S_OK;
  529. *plDevErrVal = 0;
  530. LONG lItemType;
  531. hr = wiasGetItemType(pWiasContext, &lItemType);
  532. if (FAILED(hr))
  533. {
  534. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvReadItemProperties, wiasGetItemType failed"));
  535. WIAS_LHRESULT(m_pIWiaLog, hr);
  536. return hr;
  537. }
  538. if (lItemType & WiaItemTypeRoot) {
  539. //
  540. // Build root item properties, initializing global
  541. // structures with their default and valid values
  542. //
  543. hr = ReadRootItemProperties(pWiasContext, nPropSpec, pPropSpec);
  544. } else {
  545. //
  546. // Build child item properties, initializing global
  547. // structures with their default and valid values
  548. //
  549. hr = ReadChildItemProperties(pWiasContext, nPropSpec, pPropSpec);
  550. }
  551. return hr;
  552. }
  553. /**************************************************************************\
  554. * CWiaCameraDevice::drvWriteItemProperties
  555. *
  556. * Write the device item properties to the hardware. This is called by the
  557. * WIA Class driver prior to drvAcquireItemData when the client requests
  558. * a data transfer.
  559. *
  560. * Arguments:
  561. *
  562. * pWiasContext - Pointer to WIA item.
  563. * lFlags - Operation flags, unused.
  564. * pmdtc - Pointer to mini driver context. On entry, only the
  565. * portion of the mini driver context which is derived
  566. * from the item properties is filled in.
  567. * plDevErrVal - Pointer to the device error value.
  568. *
  569. \**************************************************************************/
  570. HRESULT CWiaCameraDevice::drvWriteItemProperties(
  571. BYTE *pWiasContext,
  572. LONG lFlags,
  573. PMINIDRV_TRANSFER_CONTEXT pmdtc,
  574. LONG *plDevErrVal)
  575. {
  576. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  577. WIALOG_NO_RESOURCE_ID,
  578. WIALOG_LEVEL1,
  579. "CWiaCameraDevice::drvWriteItemProperties");
  580. HRESULT hr = S_OK;
  581. //
  582. // This function doesn't need to do anything, because all of the camera
  583. // properties are written in drvValidateItemProperties
  584. //
  585. *plDevErrVal = 0;
  586. return hr;
  587. }
  588. /**************************************************************************\
  589. * CWiaCameraDevice::drvAcquireItemData
  590. *
  591. * Transfer data from a mini driver item to device manger.
  592. *
  593. * Arguments:
  594. *
  595. * pWiasContext - Pointer to the WIA item.
  596. * lFlags - Operation flags, unused.
  597. * pmdtc - Pointer to mini driver context. On entry, only the
  598. * portion of the mini driver context which is derived
  599. * from the item properties is filled in.
  600. * plDevErrVal - Pointer to the device error value.
  601. *
  602. \**************************************************************************/
  603. HRESULT CWiaCameraDevice::drvAcquireItemData(
  604. BYTE *pWiasContext,
  605. LONG lFlags,
  606. PMINIDRV_TRANSFER_CONTEXT pmdtc,
  607. LONG *plDevErrVal)
  608. {
  609. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  610. WIALOG_NO_RESOURCE_ID,
  611. WIALOG_LEVEL1,
  612. "CWiaCameraDevice::drvAcquireItemData");
  613. HRESULT hr = S_OK;
  614. plDevErrVal = 0;
  615. //
  616. // Locals
  617. //
  618. BYTE *pTempBuf = NULL;
  619. LONG lBufSize = 0;
  620. //
  621. // Get item context
  622. //
  623. ITEM_CONTEXT *pItemCtx = NULL;
  624. hr = GetDrvItemContext(pWiasContext, &pItemCtx);
  625. if (FAILED(hr))
  626. {
  627. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, GetDrvItemContext"));
  628. return hr;
  629. }
  630. //
  631. // If the format requested is BMP or DIB, and the image is not already in BMP
  632. // format, convert it
  633. //
  634. BOOL bConvert = (IsEqualGUID(pmdtc->guidFormatID, WiaImgFmt_BMP) && !(IsEqualGUID(m_FormatInfo[pItemCtx->ItemHandle->Format].FormatGuid, WiaImgFmt_BMP)) ) ||
  635. (IsEqualGUID(pmdtc->guidFormatID, WiaImgFmt_MEMORYBMP) && !(IsEqualGUID(m_FormatInfo[pItemCtx->ItemHandle->Format].FormatGuid, WiaImgFmt_MEMORYBMP)) );
  636. WIAS_LTRACE(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,WIALOG_LEVEL1,("drvAcquireItemData, FormatCode=%d, bConvert=%d", pItemCtx->ItemHandle->Format, bConvert));
  637. //
  638. // If the class driver did not allocate the transfer buffer or the image is being
  639. // converted to DIB or BMP, allocate a temporary buffer.
  640. //
  641. if (bConvert || !pmdtc->bClassDrvAllocBuf) {
  642. lBufSize = pItemCtx->ItemHandle->Size;
  643. pTempBuf = new BYTE[lBufSize];
  644. if (!pTempBuf)
  645. {
  646. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, buffer allocation failed"));
  647. hr = E_FAIL;
  648. goto Cleanup;
  649. }
  650. }
  651. //
  652. // Acquire the data from the device
  653. //
  654. hr = AcquireData(pItemCtx, pmdtc, pTempBuf, lBufSize, bConvert);
  655. if (FAILED(hr))
  656. {
  657. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, AcquireData failed"));
  658. goto Cleanup;
  659. }
  660. if (hr == S_FALSE)
  661. {
  662. WIAS_LWARNING(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, transfer cancelled"));
  663. goto Cleanup;
  664. }
  665. //
  666. // Now convert the data to BMP, if necessary
  667. //
  668. if (bConvert)
  669. {
  670. hr = Convert(pWiasContext, pItemCtx, pmdtc, pTempBuf, lBufSize);
  671. if (FAILED(hr))
  672. {
  673. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvAcquireItemData, Convert failed"));
  674. goto Cleanup;
  675. }
  676. }
  677. Cleanup:
  678. if (pTempBuf)
  679. {
  680. delete []pTempBuf;
  681. pTempBuf = NULL;
  682. lBufSize = 0;
  683. }
  684. return hr;
  685. }
  686. /**************************************************************************\
  687. * CWiaCameraDevice::drvGetWiaFormatInfo
  688. *
  689. * Returns an array of WIA_FORMAT_INFO structs, which specify the format
  690. * and media type pairs that are supported.
  691. *
  692. * Arguments:
  693. *
  694. * pWiasContext - Pointer to the WIA item context, unused.
  695. * lFlags - Operation flags, unused.
  696. * pcelt - Pointer to returned number of elements in
  697. * returned WIA_FORMAT_INFO array.
  698. * ppwfi - Pointer to returned WIA_FORMAT_INFO array.
  699. * plDevErrVal - Pointer to the device error value.
  700. *
  701. \**************************************************************************/
  702. HRESULT CWiaCameraDevice::drvGetWiaFormatInfo(
  703. BYTE *pWiasContext,
  704. LONG lFlags,
  705. LONG *pcelt,
  706. WIA_FORMAT_INFO **ppwfi,
  707. LONG *plDevErrVal)
  708. {
  709. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  710. WIALOG_NO_RESOURCE_ID,
  711. WIALOG_LEVEL1,
  712. "CWiaCameraDevice::drvGetWiaFormatInfo");
  713. HRESULT hr = S_OK;
  714. *plDevErrVal = 0;
  715. *pcelt = 0;
  716. *ppwfi = NULL;
  717. IWiaDrvItem *pWiaDrvItem;
  718. hr = wiasGetDrvItem(pWiasContext, &pWiaDrvItem);
  719. if (FAILED(hr))
  720. {
  721. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetWiaFormatInfo, wiasGetDrvItem failed"));
  722. return hr;
  723. }
  724. ITEM_CONTEXT *pItemCtx = NULL;
  725. hr = pWiaDrvItem->GetDeviceSpecContext((BYTE **) &pItemCtx);
  726. if (FAILED(hr))
  727. {
  728. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetWiaFormatInfo, GetDeviceSpecContext failed"));
  729. return hr;
  730. }
  731. if (!pItemCtx)
  732. {
  733. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetWiaFormatInfo, item context is null"));
  734. return E_FAIL;
  735. }
  736. FORMAT_CODE FormatCode;
  737. WIA_FORMAT_INFO *pwfi;
  738. if (!pItemCtx->pFormatInfo)
  739. {
  740. //
  741. // The format info list is not intialized. Do it now.
  742. //
  743. LONG ItemType;
  744. DWORD ui32;
  745. hr = wiasGetItemType(pWiasContext, &ItemType);
  746. if (FAILED(hr))
  747. {
  748. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetWiaFormatInfo, wiasGetItemType failed"));
  749. WIAS_LHRESULT(m_pIWiaLog, hr);
  750. return hr;
  751. }
  752. if ((ItemType&WiaItemTypeFile)&&(ItemType&WiaItemTypeImage) )
  753. {
  754. //
  755. // Create the supported format for the item, based on the format stored in the
  756. // ObjectInfo structure.
  757. //
  758. if (!pItemCtx->ItemHandle)
  759. {
  760. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetWiaFormatInfo, ItemHandle is not initialized"));
  761. return E_FAIL;
  762. }
  763. //
  764. // If the format is not BMP, add the BMP types to the format array,
  765. // since this driver must support converting those to BMP
  766. //
  767. FormatCode = pItemCtx->ItemHandle->Format;
  768. BOOL bIsBmp = (IsEqualGUID(m_FormatInfo[FormatCode].FormatGuid, WiaImgFmt_BMP)) ||
  769. (IsEqualGUID(m_FormatInfo[FormatCode].FormatGuid, WiaImgFmt_MEMORYBMP));
  770. ULONG NumWfi = bIsBmp ? 1 : 2;
  771. //
  772. // Allocate two entries for each format, one for file transfer and one for callback
  773. //
  774. pwfi = new WIA_FORMAT_INFO[2 * NumWfi];
  775. if (!pwfi)
  776. {
  777. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetWiaFormatInfo, memory allocation failed"));
  778. return E_OUTOFMEMORY;
  779. }
  780. pwfi[0].guidFormatID = WiaImgFmt_BMP;
  781. pwfi[0].lTymed = TYMED_FILE;
  782. pwfi[1].guidFormatID = WiaImgFmt_MEMORYBMP;
  783. pwfi[1].lTymed = TYMED_CALLBACK;
  784. FORMAT_INFO *pFormatInfo = FormatCode2FormatInfo(FormatCode);
  785. //
  786. // Add entries when appropriate
  787. //
  788. if (!bIsBmp)
  789. {
  790. pwfi[2].guidFormatID = pFormatInfo->FormatGuid;
  791. pwfi[2].lTymed = TYMED_FILE;
  792. pwfi[3].guidFormatID = pFormatInfo->FormatGuid;
  793. pwfi[3].lTymed = TYMED_CALLBACK;
  794. }
  795. pItemCtx->NumFormatInfo = 2 * NumWfi;
  796. pItemCtx->pFormatInfo = pwfi;
  797. }
  798. else if (ItemType & WiaItemTypeFile) {
  799. if (!pItemCtx->ItemHandle)
  800. {
  801. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetWiaFormatInfo, ItemHandle is not initialized"));
  802. return E_FAIL;
  803. }
  804. FormatCode = pItemCtx->ItemHandle->Format;
  805. //
  806. // Allocate two entries for each format, one for file transfer and one for callback
  807. //
  808. pwfi = new WIA_FORMAT_INFO[2];
  809. if (!pwfi)
  810. {
  811. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetWiaFormatInfo, memory allocation failed"));
  812. return E_OUTOFMEMORY;
  813. }
  814. FORMAT_INFO *pFormatInfo = FormatCode2FormatInfo(FormatCode);
  815. if( !pFormatInfo )
  816. {
  817. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetWiaFormatInfo, FormatCode2FormatInfo failed"));
  818. return E_FAIL;
  819. }
  820. pwfi[0].guidFormatID = pFormatInfo->FormatGuid;
  821. pwfi[0].lTymed = TYMED_FILE;
  822. pwfi[1].guidFormatID = pFormatInfo->FormatGuid;
  823. pwfi[1].lTymed = TYMED_CALLBACK;
  824. //
  825. // Add entries when appropriate
  826. //
  827. pItemCtx->NumFormatInfo = 2;
  828. pItemCtx->pFormatInfo = pwfi;
  829. }
  830. else
  831. // ((ItemType & WiaItemTypeFolder) || (ItemType & WiaItemTypeRoot))
  832. {
  833. //
  834. // Folders and the root don't really need format info, but some apps may fail
  835. // without it. Create a fake list just in case.
  836. //
  837. pItemCtx->pFormatInfo = new WIA_FORMAT_INFO[2];
  838. if (!pItemCtx->pFormatInfo)
  839. {
  840. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetWiaFormatInfo, memory allocation failed"));
  841. return E_OUTOFMEMORY;
  842. }
  843. pItemCtx->NumFormatInfo = 2;
  844. pItemCtx->pFormatInfo[0].lTymed = TYMED_FILE;
  845. pItemCtx->pFormatInfo[0].guidFormatID = FMT_NOTHING;
  846. pItemCtx->pFormatInfo[1].lTymed = TYMED_CALLBACK;
  847. pItemCtx->pFormatInfo[1].guidFormatID = FMT_NOTHING;
  848. }
  849. } // end of IF
  850. *pcelt = pItemCtx->NumFormatInfo;
  851. *ppwfi = pItemCtx->pFormatInfo;
  852. return hr;
  853. }
  854. /**************************************************************************\
  855. * CWiaCameraDevice::drvValidateItemProperties
  856. *
  857. * Validate the device item properties. It is called when changes are made
  858. * to an item's properties. Driver should not only check that the values
  859. * are valid, but must update any valid values that may change as a result.
  860. * If an a property is not being written by the application, and it's value
  861. * is invalid, then "fold" it to a new value, else fail validation (because
  862. * the application is setting the property to an invalid value).
  863. *
  864. * Arguments:
  865. *
  866. * pWiasContext - Pointer to the WIA item, unused.
  867. * lFlags - Operation flags, unused.
  868. * nPropSpec - The number of properties that are being written
  869. * pPropSpec - An array of PropSpecs identifying the properties that
  870. * are being written.
  871. * plDevErrVal - Pointer to the device error value.
  872. *
  873. ***************************************************************************/
  874. HRESULT CWiaCameraDevice::drvValidateItemProperties(
  875. BYTE *pWiasContext,
  876. LONG lFlags,
  877. ULONG nPropSpec,
  878. const PROPSPEC *pPropSpec,
  879. LONG *plDevErrVal)
  880. {
  881. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  882. WIALOG_NO_RESOURCE_ID,
  883. WIALOG_LEVEL1,
  884. "CWiaCameraDevice::drvValidateItemProperties");
  885. HRESULT hr = S_OK;
  886. *plDevErrVal = 0;
  887. //
  888. // Have the service validate against the valid values for each property
  889. //
  890. hr = wiasValidateItemProperties(pWiasContext, nPropSpec, pPropSpec);
  891. if (FAILED(hr))
  892. {
  893. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, wiasValidateItemProperties failed"));
  894. return hr;
  895. }
  896. //
  897. // Get the item type
  898. //
  899. LONG lItemType = 0;
  900. hr = wiasGetItemType(pWiasContext, &lItemType);
  901. if (FAILED(hr))
  902. {
  903. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, wiasGetItemType failed"));
  904. return hr;
  905. }
  906. //
  907. // Validate root item properties
  908. //
  909. if (lItemType & WiaItemTypeRoot) {
  910. //
  911. // None yet
  912. //
  913. }
  914. //
  915. // Validate child item properties
  916. //
  917. else {
  918. //
  919. // If tymed property was changed, update format and item size
  920. //
  921. if (wiauPropInPropSpec(nPropSpec, pPropSpec, WIA_IPA_TYMED))
  922. {
  923. //
  924. // Create a property context needed by some WIA Service
  925. // functions used below.
  926. //
  927. WIA_PROPERTY_CONTEXT Context;
  928. hr = wiasCreatePropContext(nPropSpec,
  929. (PROPSPEC*)pPropSpec,
  930. 0,
  931. NULL,
  932. &Context);
  933. if (FAILED(hr))
  934. {
  935. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, wiasCreatePropContext failed"));
  936. return hr;
  937. }
  938. //
  939. // Use the WIA Service to update the valid values
  940. // for format. It will pull the values from the
  941. // structure returnd by drvGetWiaFormatInfo, using the
  942. // new value for tymed.
  943. //
  944. hr = wiasUpdateValidFormat(pWiasContext, &Context, (IWiaMiniDrv*) this);
  945. if (FAILED(hr))
  946. {
  947. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, wiasUpdateValidFormat failed"));
  948. return hr;
  949. }
  950. //
  951. // Free the property context
  952. //
  953. hr = wiasFreePropContext(&Context);
  954. if (FAILED(hr))
  955. {
  956. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, wiasFreePropContext failed"));
  957. return hr;
  958. }
  959. //
  960. // Update the item size
  961. //
  962. hr = SetItemSize(pWiasContext);
  963. if (FAILED(hr))
  964. {
  965. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, SetItemSize failed"));
  966. return hr;
  967. }
  968. }
  969. //
  970. // If the format was changed, just update the item size
  971. //
  972. else if (wiauPropInPropSpec(nPropSpec, pPropSpec, WIA_IPA_FORMAT))
  973. {
  974. //
  975. // Update the item size
  976. //
  977. hr = SetItemSize(pWiasContext);
  978. if (FAILED(hr))
  979. {
  980. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, SetItemSize failed"));
  981. return hr;
  982. }
  983. }
  984. //
  985. // Unconditionally update WIA_IPA_FILE_EXTENSION to match the current format
  986. //
  987. ITEM_CONTEXT *pItemCtx;
  988. hr = GetDrvItemContext(pWiasContext, &pItemCtx);
  989. if (FAILED(hr))
  990. {
  991. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvValidateItemProperties, GetDrvItemContext failed"));
  992. return hr;
  993. }
  994. BSTR bstrFileExt = NULL;
  995. ITEM_INFO *pItemInfo = pItemCtx->ItemHandle;
  996. FORMAT_INFO *pFormatInfo = NULL;
  997. if (pItemInfo)
  998. {
  999. pFormatInfo = FormatCode2FormatInfo(pItemInfo->Format);
  1000. if( pFormatInfo->ExtensionString[0] )
  1001. {
  1002. bstrFileExt = SysAllocString(pFormatInfo->ExtensionString);
  1003. }
  1004. else // unknown file extension, get it from filename
  1005. {
  1006. WCHAR *pwcsTemp = wcsrchr(pItemInfo->pName, L'.');
  1007. if( pwcsTemp )
  1008. {
  1009. bstrFileExt = SysAllocString(pwcsTemp+1);
  1010. }
  1011. else
  1012. {
  1013. bstrFileExt = SysAllocString(pFormatInfo->ExtensionString);
  1014. }
  1015. }
  1016. }
  1017. hr = wiasWritePropStr(pWiasContext, WIA_IPA_FILENAME_EXTENSION, bstrFileExt);
  1018. if (bstrFileExt)
  1019. {
  1020. SysFreeString(bstrFileExt);
  1021. bstrFileExt = NULL;
  1022. }
  1023. }
  1024. return hr;
  1025. }
  1026. /**************************************************************************\
  1027. * CWiaCameraDevice::drvDeleteItem
  1028. *
  1029. * Delete an item from the device.
  1030. *
  1031. * Arguments:
  1032. *
  1033. * pWiasContext - Indicates the item to delete.
  1034. * lFlags - Operation flags, unused.
  1035. * plDevErrVal - Pointer to the device error value.
  1036. *
  1037. \**************************************************************************/
  1038. HRESULT CWiaCameraDevice::drvDeleteItem(
  1039. BYTE *pWiasContext,
  1040. LONG lFlags,
  1041. LONG *plDevErrVal)
  1042. {
  1043. plDevErrVal = 0;
  1044. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1045. WIALOG_NO_RESOURCE_ID,
  1046. WIALOG_LEVEL1,
  1047. "CWiaCameraDevice::drvDeleteItem");
  1048. HRESULT hr = S_OK;
  1049. ITEM_CONTEXT *pItemCtx = NULL;
  1050. IWiaDrvItem *pDrvItem;
  1051. hr = GetDrvItemContext(pWiasContext, &pItemCtx, &pDrvItem);
  1052. if (FAILED(hr))
  1053. {
  1054. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvDeleteItem, GetDrvItemContext failed"));
  1055. return hr;
  1056. }
  1057. hr = m_pDevice->DeleteItem(pItemCtx->ItemHandle);
  1058. if (FAILED(hr))
  1059. {
  1060. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvDeleteItem, delete item failed"));
  1061. return hr;
  1062. }
  1063. //
  1064. // Get the item's full name
  1065. //
  1066. BSTR bstrFullName;
  1067. hr = pDrvItem->GetFullItemName(&bstrFullName);
  1068. if (FAILED(hr))
  1069. {
  1070. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvDeleteItem, GetFullItemName failed"));
  1071. WIAS_LHRESULT(m_pIWiaLog, hr);
  1072. return hr;
  1073. }
  1074. //
  1075. // Queue an "item deleted" event
  1076. //
  1077. hr = wiasQueueEvent(m_bstrDeviceID,
  1078. &WIA_EVENT_ITEM_DELETED,
  1079. bstrFullName);
  1080. if (FAILED(hr))
  1081. {
  1082. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvDeleteItem, wiasQueueEvent failed"));
  1083. WIAS_LHRESULT(m_pIWiaLog, hr);
  1084. // Continue to free the string and return hr
  1085. }
  1086. SysFreeString(bstrFullName);
  1087. return hr;
  1088. }
  1089. /**************************************************************************\
  1090. * CWiaCameraDevice::drvNotifyPnpEvent
  1091. *
  1092. * Pnp Event received by device manager. This is called when a Pnp event
  1093. * is received for this device.
  1094. *
  1095. * Arguments:
  1096. *
  1097. *
  1098. *
  1099. \**************************************************************************/
  1100. HRESULT CWiaCameraDevice::drvNotifyPnpEvent(
  1101. const GUID *pEventGUID,
  1102. BSTR bstrDeviceID,
  1103. ULONG ulReserved)
  1104. {
  1105. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1106. WIALOG_NO_RESOURCE_ID,
  1107. WIALOG_LEVEL1,
  1108. "CWiaCameraDevice::DrvNotifyPnpEvent");
  1109. HRESULT hr = S_OK;
  1110. return hr;
  1111. }
  1112. /**************************************************************************\
  1113. * CWiaCameraDevice::drvGetCapabilities
  1114. *
  1115. * Get supported device commands and events as an array of WIA_DEV_CAPS.
  1116. *
  1117. * Arguments:
  1118. *
  1119. * pWiasContext - Pointer to the WIA item, unused.
  1120. * lFlags - Operation flags.
  1121. * pcelt - Pointer to returned number of elements in
  1122. * returned GUID array.
  1123. * ppCapabilities - Pointer to returned GUID array.
  1124. * plDevErrVal - Pointer to the device error value.
  1125. *
  1126. \**************************************************************************/
  1127. HRESULT CWiaCameraDevice::drvGetCapabilities(
  1128. BYTE *pWiasContext,
  1129. LONG ulFlags,
  1130. LONG *pcelt,
  1131. WIA_DEV_CAP_DRV **ppCapabilities,
  1132. LONG *plDevErrVal)
  1133. {
  1134. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1135. WIALOG_NO_RESOURCE_ID,
  1136. WIALOG_LEVEL1,
  1137. "CWiaCameraDevice::drvGetCapabilites");
  1138. *plDevErrVal = 0;
  1139. if( !m_pCapabilities )
  1140. {
  1141. HRESULT hr = BuildCapabilities();
  1142. if( hr != S_OK )
  1143. {
  1144. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetCapabilities, BuildCapabilities failed"));
  1145. return (hr);
  1146. }
  1147. }
  1148. //
  1149. // Return values depend on the passed flags. Flags specify whether we should return
  1150. // commands, events, or both.
  1151. //
  1152. switch (ulFlags) {
  1153. case WIA_DEVICE_COMMANDS:
  1154. //
  1155. // report commands only
  1156. //
  1157. *pcelt = m_NumSupportedCommands;
  1158. *ppCapabilities = &m_pCapabilities[m_NumSupportedEvents];
  1159. break;
  1160. case WIA_DEVICE_EVENTS:
  1161. //
  1162. // report events only
  1163. //
  1164. *pcelt = m_NumSupportedEvents;
  1165. *ppCapabilities = m_pCapabilities;
  1166. break;
  1167. case (WIA_DEVICE_COMMANDS | WIA_DEVICE_EVENTS):
  1168. //
  1169. // report both events and commands
  1170. //
  1171. *pcelt = m_NumCapabilities;
  1172. *ppCapabilities = m_pCapabilities;
  1173. break;
  1174. default:
  1175. //
  1176. // invalid request
  1177. //
  1178. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvGetCapabilities, invalid flags"));
  1179. return E_INVALIDARG;
  1180. }
  1181. return S_OK;
  1182. }
  1183. /**************************************************************************\
  1184. * CWiaCameraDevice::drvDeviceCommand
  1185. *
  1186. * Issue a command to the device.
  1187. *
  1188. * Arguments:
  1189. *
  1190. * pWiasContext - Pointer to the WIA item.
  1191. * lFlags - Operation flags, unused.
  1192. * plCommand - Pointer to command GUID.
  1193. * ppWiaDrvItem - Optional pointer to returned item, unused.
  1194. * plDevErrVal - Pointer to the device error value.
  1195. *
  1196. \**************************************************************************/
  1197. HRESULT CWiaCameraDevice::drvDeviceCommand(
  1198. BYTE *pWiasContext,
  1199. LONG lFlags,
  1200. const GUID *plCommand,
  1201. IWiaDrvItem **ppWiaDrvItem,
  1202. LONG *plDevErrVal)
  1203. {
  1204. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1205. WIALOG_NO_RESOURCE_ID,
  1206. WIALOG_LEVEL1,
  1207. "CWiaCameraDevice::drvDeviceCommand");
  1208. *plDevErrVal = 0;
  1209. HRESULT hr = S_OK;
  1210. //
  1211. // Check which command was issued
  1212. //
  1213. if (*plCommand == WIA_CMD_SYNCHRONIZE) {
  1214. //
  1215. // SYNCHRONIZE - Re-build the item tree, if the device needs it.
  1216. //
  1217. if (m_DeviceInfo.bSyncNeeded)
  1218. {
  1219. hr = DeleteItemTree(WiaItemTypeDisconnected);
  1220. if (FAILED(hr))
  1221. {
  1222. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvDeviceCommand, DeleteItemTree failed"));
  1223. return hr;
  1224. }
  1225. m_pDevice->FreeDeviceInfo(&m_DeviceInfo);
  1226. memset(&m_DeviceInfo, 0, sizeof(m_DeviceInfo));
  1227. hr = m_pDevice->GetDeviceInfo(&m_DeviceInfo);
  1228. if (FAILED(hr))
  1229. {
  1230. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvDeviceCommand, GetDeviceInfo failed"));
  1231. return hr;
  1232. }
  1233. hr = BuildItemTree();
  1234. if (FAILED(hr))
  1235. {
  1236. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvDeviceCommand, BuildItemTree failed"));
  1237. return hr;
  1238. }
  1239. }
  1240. }
  1241. #if DEADCODE
  1242. //
  1243. // Not implemented yet
  1244. //
  1245. else if (*plCommand == WIA_CMD_TAKE_PICTURE) {
  1246. //
  1247. // TAKE_PICTURE - Command the camera to capture a new image.
  1248. //
  1249. ITEM_HANDLE NewImage = 0;
  1250. hr = m_pDevice->TakePicture(&NewImage);
  1251. if (FAILED(hr))
  1252. {
  1253. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvDeviceCommand, take picture failed"));
  1254. return hr;
  1255. }
  1256. // ISSUE-10/17/2000-davepar Create a new driver item for the new image
  1257. }
  1258. #endif
  1259. else {
  1260. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("drvDeviceCommand, unknown command"));
  1261. hr = E_NOTIMPL;
  1262. }
  1263. return hr;
  1264. }
  1265. /**************************************************************************\
  1266. * CWiaCameraDevice::drvAnalyzeItem
  1267. *
  1268. * This device does not support image analysis, so return E_NOTIMPL.
  1269. *
  1270. * Arguments:
  1271. *
  1272. * pWiasContext - Pointer to the device item to be analyzed.
  1273. * lFlags - Operation flags.
  1274. * plDevErrVal - Pointer to the device error value.
  1275. *
  1276. \**************************************************************************/
  1277. HRESULT CWiaCameraDevice::drvAnalyzeItem(
  1278. BYTE *pWiasContext,
  1279. LONG lFlags,
  1280. LONG *plDevErrVal)
  1281. {
  1282. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1283. WIALOG_NO_RESOURCE_ID,
  1284. WIALOG_LEVEL1,
  1285. "CWiaCameraDevice::drvAnalyzeItem");
  1286. *plDevErrVal = 0;
  1287. return E_NOTIMPL;
  1288. }
  1289. /**************************************************************************\
  1290. * CWiaCameraDevice::drvGetDeviceErrorStr
  1291. *
  1292. * Map a device error value to a string.
  1293. *
  1294. * Arguments:
  1295. *
  1296. * lFlags - Operation flags, unused.
  1297. * lDevErrVal - Device error value.
  1298. * ppszDevErrStr - Pointer to returned error string.
  1299. * plDevErrVal - Pointer to the device error value.
  1300. *
  1301. \**************************************************************************/
  1302. HRESULT CWiaCameraDevice::drvGetDeviceErrorStr(
  1303. LONG lFlags,
  1304. LONG lDevErrVal,
  1305. LPOLESTR *ppszDevErrStr,
  1306. LONG *plDevErr)
  1307. {
  1308. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1309. WIALOG_NO_RESOURCE_ID,
  1310. WIALOG_LEVEL1,
  1311. "CWiaCameraDevice::drvGetDeviceErrorStr");
  1312. HRESULT hr = S_OK;
  1313. *plDevErr = 0;
  1314. //
  1315. // Map device errors to a string appropriate for showing to the user
  1316. //
  1317. // ISSUE-10/17/2000-davepar These should be read from the resource file
  1318. switch (lDevErrVal) {
  1319. case 0:
  1320. *ppszDevErrStr = L"No Error";
  1321. break;
  1322. default:
  1323. *ppszDevErrStr = L"Device Error, Unknown Error";
  1324. hr = E_FAIL;
  1325. }
  1326. return hr;
  1327. }
  1328. /**************************************************************************\
  1329. * SetItemSize
  1330. *
  1331. * Calulate the new item size, and write the new Item Size property value.
  1332. *
  1333. * Arguments:
  1334. *
  1335. * pWiasContext - item
  1336. *
  1337. \**************************************************************************/
  1338. HRESULT CWiaCameraDevice::SetItemSize(BYTE *pWiasContext)
  1339. {
  1340. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1341. WIALOG_NO_RESOURCE_ID,
  1342. WIALOG_LEVEL3,
  1343. "CWiaCameraDevice::SetItemSize");
  1344. HRESULT hr = S_OK;
  1345. LONG lItemSize = 0;
  1346. LONG lWidthInBytes = 0;
  1347. GUID guidFormatID = GUID_NULL;
  1348. LONG lNumProperties = 2;
  1349. PROPVARIANT pv[2];
  1350. PROPSPEC ps[2] = {{PRSPEC_PROPID, WIA_IPA_ITEM_SIZE},
  1351. {PRSPEC_PROPID, WIA_IPA_BYTES_PER_LINE}};
  1352. //
  1353. // Get the driver item context
  1354. //
  1355. ITEM_CONTEXT *pItemCtx = NULL;
  1356. hr = GetDrvItemContext(pWiasContext, &pItemCtx);
  1357. if (FAILED(hr))
  1358. {
  1359. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, GetDrvItemContext failed"));
  1360. return hr;
  1361. }
  1362. //
  1363. // Read the format GUID
  1364. //
  1365. hr = wiasReadPropGuid(pWiasContext, WIA_IPA_FORMAT, &guidFormatID, NULL, TRUE);
  1366. if (FAILED(hr)) {
  1367. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, ReadPropLong WIA_IPA_FORMAT error"));
  1368. return hr;
  1369. }
  1370. if (IsEqualCLSID(guidFormatID, WiaImgFmt_BMP) ||
  1371. IsEqualCLSID(guidFormatID, WiaImgFmt_MEMORYBMP))
  1372. {
  1373. if( !(pItemCtx->ItemHandle->Width) ||
  1374. !(pItemCtx->ItemHandle->Depth) ||
  1375. !(pItemCtx->ItemHandle->Height) )
  1376. { // Since we are going to use these, make sure they are filled in
  1377. LONG lNumPropToRead = 3;
  1378. PROPSPEC pPropsToRead[3] = { {PRSPEC_PROPID, WIA_IPA_DEPTH},
  1379. {PRSPEC_PROPID, WIA_IPA_NUMBER_OF_LINES},
  1380. {PRSPEC_PROPID, WIA_IPA_PIXELS_PER_LINE} };
  1381. hr = ReadChildItemProperties(pWiasContext, lNumPropToRead, pPropsToRead);
  1382. if (FAILED(hr))
  1383. {
  1384. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, ReadItemProperties failed"));
  1385. return hr;
  1386. }
  1387. }
  1388. lItemSize = sizeof(BITMAPINFOHEADER);
  1389. //
  1390. // if this is a file, add file header to size
  1391. //
  1392. if (IsEqualCLSID(guidFormatID, WiaImgFmt_BMP))
  1393. {
  1394. lItemSize += sizeof(BITMAPFILEHEADER);
  1395. }
  1396. //
  1397. // Calculate number of bytes per line, width must be
  1398. // aligned to 4 byte boundary.
  1399. //
  1400. lWidthInBytes = ((pItemCtx->ItemHandle->Width * pItemCtx->ItemHandle->Depth + 31) & ~31) / 8;
  1401. //
  1402. // Calculate image size
  1403. //
  1404. lItemSize += lWidthInBytes * pItemCtx->ItemHandle->Height;
  1405. }
  1406. else
  1407. {
  1408. lItemSize = pItemCtx->ItemHandle->Size;
  1409. lWidthInBytes = 0;
  1410. }
  1411. //
  1412. // Initialize propvar's. Then write the values. Don't need to call
  1413. // PropVariantClear when done, since there are only LONG values.
  1414. //
  1415. for (int i = 0; i < lNumProperties; i++) {
  1416. PropVariantInit(&pv[i]);
  1417. pv[i].vt = VT_I4;
  1418. }
  1419. pv[0].lVal = lItemSize;
  1420. pv[1].lVal = lWidthInBytes;
  1421. //
  1422. // Write WIA_IPA_ITEM_SIZE and WIA_IPA_BYTES_PER_LINE property values
  1423. //
  1424. hr = wiasWriteMultiple(pWiasContext, lNumProperties, ps, pv);
  1425. if (FAILED(hr))
  1426. {
  1427. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("SetItemSize, wiasWriteMultiple failed"));
  1428. return hr;
  1429. }
  1430. return hr;
  1431. }
  1432. /*******************************************************************************
  1433. *
  1434. * P R I V A T E M E T H O D S
  1435. *
  1436. *******************************************************************************/
  1437. /**************************************************************************\
  1438. * DeleteItemTree
  1439. *
  1440. * Call device manager to unlink and release our reference to
  1441. * all items in the driver item tree.
  1442. *
  1443. * Arguments:
  1444. *
  1445. *
  1446. *
  1447. \**************************************************************************/
  1448. HRESULT
  1449. CWiaCameraDevice::DeleteItemTree(LONG lReason)
  1450. {
  1451. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1452. WIALOG_NO_RESOURCE_ID,
  1453. WIALOG_LEVEL3,
  1454. "CWiaCameraDevice::DeleteItemTree");
  1455. HRESULT hr = S_OK;
  1456. //
  1457. // If no tree, return.
  1458. //
  1459. if (!m_pRootItem) {
  1460. return S_OK;
  1461. }
  1462. //
  1463. // Call device manager to unlink the driver item tree.
  1464. //
  1465. hr = m_pRootItem->UnlinkItemTree(lReason);
  1466. if (FAILED(hr))
  1467. {
  1468. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("DeleteItemTree, UnlinkItemTree failed"));
  1469. return hr;
  1470. }
  1471. m_pRootItem->Release();
  1472. m_pRootItem = NULL;
  1473. return hr;
  1474. }
  1475. /**************************************************************************\
  1476. * BuildItemTree
  1477. *
  1478. * The device uses the WIA Service functions to build up a tree of
  1479. * device items.
  1480. *
  1481. * Arguments:
  1482. *
  1483. *
  1484. *
  1485. \**************************************************************************/
  1486. HRESULT
  1487. CWiaCameraDevice::BuildItemTree()
  1488. {
  1489. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1490. WIALOG_NO_RESOURCE_ID,
  1491. WIALOG_LEVEL3,
  1492. "CWiaCameraDevice::BuildItemTree");
  1493. HRESULT hr = S_OK;
  1494. //
  1495. // Make sure the item tree doesn't already exist
  1496. //
  1497. if (m_pRootItem)
  1498. {
  1499. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, item tree already exists"));
  1500. return E_FAIL;
  1501. }
  1502. //
  1503. // Create the root item name
  1504. //
  1505. BSTR bstrRoot = SysAllocString(L"Root");
  1506. if (!bstrRoot)
  1507. {
  1508. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, SysAllocString failed"));
  1509. hr = E_OUTOFMEMORY;
  1510. }
  1511. //
  1512. // Create the root item
  1513. //
  1514. ITEM_CONTEXT *pItemCtx = NULL;
  1515. hr = wiasCreateDrvItem(WiaItemTypeFolder | WiaItemTypeDevice | WiaItemTypeRoot,
  1516. bstrRoot,
  1517. m_bstrRootFullItemName,
  1518. (IWiaMiniDrv *)this,
  1519. sizeof(ITEM_CONTEXT),
  1520. (BYTE **) &pItemCtx,
  1521. &m_pRootItem);
  1522. SysFreeString(bstrRoot);
  1523. if (FAILED(hr)) {
  1524. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, wiasCreateDrvItem failed"));
  1525. return hr;
  1526. }
  1527. //
  1528. // Initialize item context fields for the root
  1529. //
  1530. memset(pItemCtx, 0, sizeof(ITEM_CONTEXT));
  1531. pItemCtx->ItemHandle = ROOT_ITEM_HANDLE;
  1532. //
  1533. // Put the root item in the handle map
  1534. //
  1535. m_HandleItemMap.Add(ROOT_ITEM_HANDLE, m_pRootItem);
  1536. //
  1537. // Get the list of items from the camera
  1538. //
  1539. ITEM_HANDLE *pItemArray = new ITEM_HANDLE[m_DeviceInfo.TotalItems];
  1540. if (!pItemArray)
  1541. {
  1542. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, memory allocation failed"));
  1543. return E_OUTOFMEMORY;
  1544. }
  1545. m_pDevice->GetItemList(pItemArray);
  1546. //
  1547. // Create a driver item for each item on the camera
  1548. //
  1549. for (int count = 0; count < m_DeviceInfo.TotalItems; count++)
  1550. {
  1551. hr = AddObject(pItemArray[count]);
  1552. if (FAILED(hr))
  1553. {
  1554. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildItemTree, AddObject failed"));
  1555. return hr;
  1556. }
  1557. }
  1558. return hr;
  1559. }
  1560. /**************************************************************************\
  1561. * AddObject
  1562. *
  1563. * Helper function to add an object to the tree
  1564. *
  1565. * Arguments:
  1566. *
  1567. * pItemHandle - Pointer to the item handle
  1568. *
  1569. \**************************************************************************/
  1570. HRESULT CWiaCameraDevice::AddObject(ITEM_HANDLE ItemHandle, BOOL bQueueEvent)
  1571. {
  1572. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1573. WIALOG_NO_RESOURCE_ID,
  1574. WIALOG_LEVEL1,
  1575. "CWiaCameraDevice::AddObject");
  1576. HRESULT hr = S_OK;
  1577. LONG ExtraFlags = 0;
  1578. //
  1579. // Get information about the item from the camera
  1580. //
  1581. ITEM_INFO *pItemInfo = ItemHandle;
  1582. if (!pItemInfo)
  1583. {
  1584. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("AddObject, invalid arg"));
  1585. return E_INVALIDARG;
  1586. }
  1587. //
  1588. // Look up the item's parent in the map
  1589. //
  1590. IWiaDrvItem *pParent = NULL;
  1591. pParent = m_HandleItemMap.Lookup(pItemInfo->Parent);
  1592. //
  1593. // If a parent wasn't found, just use the root as the parent
  1594. //
  1595. if (!pParent)
  1596. {
  1597. pParent = m_pRootItem;
  1598. }
  1599. #ifdef CHECK_DOT_IN_FILENAME
  1600. //
  1601. // Make sure there is no filename extension in the name
  1602. //
  1603. if (wcschr(pItemInfo->pName, L'.'))
  1604. {
  1605. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("AddObject, item name=%S", pItemInfo->pName));
  1606. return E_FAIL;
  1607. }
  1608. #endif
  1609. //
  1610. // Create the item's full name
  1611. //
  1612. BSTR bstrItemFullName = NULL;
  1613. BSTR bstrParentName = NULL;
  1614. hr = pParent->GetFullItemName(&bstrParentName);
  1615. if (FAILED(hr))
  1616. {
  1617. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("AddObject, GetFullItemName failed"));
  1618. return hr;
  1619. }
  1620. WCHAR wcsName[MAX_PATH];
  1621. StringCchPrintfW(wcsName, MAX_PATH, L"%s\\%s", bstrParentName, pItemInfo->pName);
  1622. bstrItemFullName = SysAllocString(wcsName);
  1623. if (!bstrItemFullName)
  1624. {
  1625. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("AddObject, SysAllocString failed"));
  1626. return E_OUTOFMEMORY;
  1627. }
  1628. //
  1629. // Look up information about the item's format
  1630. //
  1631. LONG lItemType=0;
  1632. //
  1633. // See if the item has attachments
  1634. //
  1635. if (pItemInfo->bHasAttachments)
  1636. ExtraFlags |= WiaItemTypeHasAttachments;
  1637. if( pItemInfo->bIsFolder)
  1638. {
  1639. lItemType = ITEMTYPE_FOLDER;
  1640. }
  1641. else
  1642. {
  1643. lItemType = m_FormatInfo[pItemInfo->Format].ItemType;
  1644. }
  1645. //
  1646. // Create the driver item
  1647. //
  1648. IWiaDrvItem *pItem = NULL;
  1649. ITEM_CONTEXT *pItemCtx = NULL;
  1650. hr = wiasCreateDrvItem(lItemType | ExtraFlags,
  1651. pItemInfo->pName,
  1652. bstrItemFullName,
  1653. (IWiaMiniDrv *)this,
  1654. sizeof(ITEM_CONTEXT),
  1655. (BYTE **) &pItemCtx,
  1656. &pItem);
  1657. SysFreeString(bstrParentName);
  1658. if (FAILED(hr) || !pItem || !pItemCtx)
  1659. {
  1660. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("AddObject, wiasCreateDrvItem failed"));
  1661. return hr;
  1662. }
  1663. //
  1664. // Fill in the driver item context. Wait until the thumbnail is requested before
  1665. // reading it in.
  1666. //
  1667. memset(pItemCtx, 0, sizeof(ITEM_CONTEXT));
  1668. pItemCtx->ItemHandle = ItemHandle;
  1669. //
  1670. // Place the new item under it's parent
  1671. //
  1672. hr = pItem->AddItemToFolder(pParent);
  1673. if (FAILED(hr))
  1674. {
  1675. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("AddObject, AddItemToFolder failed"));
  1676. WIAS_LHRESULT(m_pIWiaLog, hr);
  1677. return hr;
  1678. }
  1679. //
  1680. // Add the item to the item handle/driver item map
  1681. //
  1682. if (!m_HandleItemMap.Add(ItemHandle, pItem))
  1683. {
  1684. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("AddObject, handle item map Add failed"));
  1685. return E_OUTOFMEMORY;
  1686. }
  1687. //
  1688. // Eventhough, there is still a reference to the item in the handle/item map, release
  1689. // it here, because there isn't a convenient place to do it later
  1690. //
  1691. pItem->Release();
  1692. //
  1693. // Post an item added event, if requested
  1694. //
  1695. if (bQueueEvent)
  1696. {
  1697. hr = wiasQueueEvent(m_bstrDeviceID, &WIA_EVENT_ITEM_CREATED, bstrItemFullName);
  1698. if (FAILED(hr))
  1699. {
  1700. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("AddObject, wiasQueueEvent failed"));
  1701. WIAS_LHRESULT(m_pIWiaLog, hr);
  1702. return hr;
  1703. }
  1704. }
  1705. SysFreeString(bstrItemFullName);
  1706. return hr;
  1707. }
  1708. /**************************************************************************\
  1709. * BuildCapabilities
  1710. *
  1711. * This helper initializes the capabilities array
  1712. *
  1713. * Arguments:
  1714. *
  1715. * none
  1716. *
  1717. \**************************************************************************/
  1718. HRESULT CWiaCameraDevice::BuildCapabilities()
  1719. {
  1720. HRESULT hr = S_OK;
  1721. if(NULL != m_pCapabilities) {
  1722. //
  1723. // Capabilities have already been initialized,
  1724. // so return S_OK.
  1725. //
  1726. return hr;
  1727. }
  1728. m_NumSupportedCommands = 1;
  1729. m_NumSupportedEvents = 3;
  1730. m_NumCapabilities = (m_NumSupportedCommands + m_NumSupportedEvents);
  1731. m_pCapabilities = new WIA_DEV_CAP_DRV[m_NumCapabilities];
  1732. if (m_pCapabilities) {
  1733. //
  1734. // Initialize EVENTS
  1735. //
  1736. // WIA_EVENT_DEVICE_CONNECTED
  1737. GetOLESTRResourceString(IDS_EVENT_DEVICE_CONNECTED_NAME,&(m_pCapabilities[0].wszName),TRUE);
  1738. GetOLESTRResourceString(IDS_EVENT_DEVICE_CONNECTED_DESC,&(m_pCapabilities[0].wszDescription),TRUE);
  1739. m_pCapabilities[0].guid = (GUID*)&WIA_EVENT_DEVICE_CONNECTED;
  1740. m_pCapabilities[0].ulFlags = WIA_NOTIFICATION_EVENT | WIA_ACTION_EVENT;
  1741. m_pCapabilities[0].wszIcon = WIA_ICON_DEVICE_CONNECTED;
  1742. // WIA_EVENT_DEVICE_DISCONNECTED
  1743. GetOLESTRResourceString(IDS_EVENT_DEVICE_DISCONNECTED_NAME,&(m_pCapabilities[1].wszName),TRUE);
  1744. GetOLESTRResourceString(IDS_EVENT_DEVICE_DISCONNECTED_DESC,&(m_pCapabilities[1].wszDescription),TRUE);
  1745. m_pCapabilities[1].guid = (GUID*)&WIA_EVENT_DEVICE_DISCONNECTED;
  1746. m_pCapabilities[1].ulFlags = WIA_NOTIFICATION_EVENT;
  1747. m_pCapabilities[1].wszIcon = WIA_ICON_DEVICE_DISCONNECTED;
  1748. // WIA_EVENT_ITEM_DELETED
  1749. GetOLESTRResourceString(IDS_EVENT_ITEM_DELETED_NAME,&(m_pCapabilities[2].wszName),TRUE);
  1750. GetOLESTRResourceString(IDS_EVENT_ITEM_DELETED_DESC,&(m_pCapabilities[2].wszDescription),TRUE);
  1751. m_pCapabilities[2].guid = (GUID*)&WIA_EVENT_ITEM_DELETED;
  1752. m_pCapabilities[2].ulFlags = WIA_NOTIFICATION_EVENT;
  1753. m_pCapabilities[2].wszIcon = WIA_ICON_ITEM_DELETED;
  1754. //
  1755. // Initialize COMMANDS
  1756. //
  1757. // WIA_CMD_SYNCHRONIZE
  1758. GetOLESTRResourceString(IDS_CMD_SYNCRONIZE_NAME,&(m_pCapabilities[3].wszName),TRUE);
  1759. GetOLESTRResourceString(IDS_CMD_SYNCRONIZE_DESC,&(m_pCapabilities[3].wszDescription),TRUE);
  1760. m_pCapabilities[3].guid = (GUID*)&WIA_CMD_SYNCHRONIZE;
  1761. m_pCapabilities[3].ulFlags = 0;
  1762. m_pCapabilities[3].wszIcon = WIA_ICON_SYNCHRONIZE;
  1763. // ISSUE-10/17/2000-davepar Add TakePicture if the camera supports it
  1764. }
  1765. else {
  1766. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("BuildCapabilities, memory allocation failed"));
  1767. hr = E_OUTOFMEMORY;
  1768. }
  1769. return hr;
  1770. }
  1771. /**************************************************************************\
  1772. * DeleteCapabilitiesArrayContents
  1773. *
  1774. * This helper deletes the capabilities array
  1775. *
  1776. * Arguments:
  1777. *
  1778. * none
  1779. *
  1780. \**************************************************************************/
  1781. HRESULT CWiaCameraDevice::DeleteCapabilitiesArrayContents()
  1782. {
  1783. HRESULT hr = S_OK;
  1784. if (m_pCapabilities) {
  1785. for (LONG i = 0; i < m_NumCapabilities; i++) {
  1786. CoTaskMemFree(m_pCapabilities[i].wszName);
  1787. CoTaskMemFree(m_pCapabilities[i].wszDescription);
  1788. }
  1789. delete []m_pCapabilities;
  1790. m_pCapabilities = NULL;
  1791. }
  1792. m_NumSupportedCommands = 0;
  1793. m_NumSupportedEvents = 0;
  1794. m_NumCapabilities = 0;
  1795. return hr;
  1796. }
  1797. /**************************************************************************\
  1798. * GetBSTRResourceString
  1799. *
  1800. * This helper gets a BSTR from a resource location
  1801. *
  1802. * Arguments:
  1803. *
  1804. * lResourceID - Resource ID of the target BSTR value
  1805. * pBSTR - pointer to a BSTR value (caller must free this string)
  1806. * bLocal - TRUE - for local resources, FALSE - for wiaservc resources
  1807. *
  1808. \**************************************************************************/
  1809. HRESULT CWiaCameraDevice::GetBSTRResourceString(LONG lResourceID, BSTR *pBSTR, BOOL bLocal)
  1810. {
  1811. HRESULT hr = S_OK;
  1812. TCHAR szStringValue[MAX_PATH];
  1813. if (bLocal) {
  1814. //
  1815. // We are looking for a resource in our own private resource file
  1816. //
  1817. LoadString(g_hInst, lResourceID, szStringValue, MAX_PATH);
  1818. //
  1819. // NOTE: caller must free this allocated BSTR
  1820. //
  1821. #ifdef UNICODE
  1822. *pBSTR = SysAllocString(szStringValue);
  1823. #else
  1824. WCHAR wszStringValue[MAX_PATH];
  1825. //
  1826. // convert szStringValue from char* to unsigned short* (ANSI only)
  1827. //
  1828. MultiByteToWideChar(CP_ACP,
  1829. MB_PRECOMPOSED,
  1830. szStringValue,
  1831. lstrlenA(szStringValue)+1,
  1832. wszStringValue,
  1833. ARRAYSIZE(wszStringValue));
  1834. *pBSTR = SysAllocString(wszStringValue);
  1835. #endif
  1836. if (!*pBSTR) {
  1837. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetBSTRResourceString, SysAllocString failed"));
  1838. return E_OUTOFMEMORY;
  1839. }
  1840. } else {
  1841. //
  1842. // We are looking for a resource in the wiaservc's resource file
  1843. //
  1844. hr = E_NOTIMPL;
  1845. }
  1846. return hr;
  1847. }
  1848. /**************************************************************************\
  1849. * GetOLESTRResourceString
  1850. *
  1851. * This helper gets a LPOLESTR from a resource location
  1852. *
  1853. * Arguments:
  1854. *
  1855. * lResourceID - Resource ID of the target BSTR value
  1856. * ppsz - pointer to a OLESTR value (caller must free this string)
  1857. * bLocal - TRUE - for local resources, FALSE - for wiaservc resources
  1858. *
  1859. \**************************************************************************/
  1860. HRESULT CWiaCameraDevice::GetOLESTRResourceString(LONG lResourceID,LPOLESTR *ppsz,BOOL bLocal)
  1861. {
  1862. HRESULT hr = S_OK;
  1863. const int c_nMaxCharPerString = 255;
  1864. TCHAR szStringValue[c_nMaxCharPerString];
  1865. if(bLocal) {
  1866. //
  1867. // We are looking for a resource in our own private resource file
  1868. //
  1869. LoadString(g_hInst,lResourceID,szStringValue,255);
  1870. //
  1871. // NOTE: caller must free this allocated BSTR
  1872. //
  1873. #ifdef UNICODE
  1874. *ppsz = NULL;
  1875. *ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(szStringValue));
  1876. if(*ppsz != NULL) {
  1877. StringCchCopyW(*ppsz, c_nMaxCharPerString, szStringValue);
  1878. } else {
  1879. return E_OUTOFMEMORY;
  1880. }
  1881. #else
  1882. WCHAR wszStringValue[c_nMaxCharPerString];
  1883. //
  1884. // convert szStringValue from char* to unsigned short* (ANSI only)
  1885. //
  1886. MultiByteToWideChar(CP_ACP,
  1887. MB_PRECOMPOSED,
  1888. szStringValue,
  1889. lstrlenA(szStringValue)+1,
  1890. wszStringValue,
  1891. ARRAYSIZE(wszStringValue));
  1892. *ppsz = NULL;
  1893. *ppsz = (LPOLESTR)CoTaskMemAlloc(sizeof(wszStringValue));
  1894. if(*ppsz != NULL) {
  1895. StringCchCopyW(*ppsz, c_nMaxCharPerString, wszStringValue);
  1896. } else {
  1897. return E_OUTOFMEMORY;
  1898. }
  1899. #endif
  1900. } else {
  1901. //
  1902. // We are looking for a resource in the wiaservc's resource file
  1903. //
  1904. hr = E_NOTIMPL;
  1905. }
  1906. return hr;
  1907. }
  1908. /**************************************************************************\
  1909. * VerticalFlip
  1910. *
  1911. *
  1912. *
  1913. * Arguments:
  1914. *
  1915. *
  1916. *
  1917. \**************************************************************************/
  1918. VOID CWiaCameraDevice::VerticalFlip(
  1919. ITEM_CONTEXT *pItemCtx,
  1920. PMINIDRV_TRANSFER_CONTEXT pDataTransferContext
  1921. )
  1922. {
  1923. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  1924. WIALOG_NO_RESOURCE_ID,
  1925. WIALOG_LEVEL3,
  1926. "CWiaCameraDevice::VerticalFlip");
  1927. HRESULT hr = S_OK;
  1928. LONG iHeight;
  1929. LONG iWidth = pItemCtx->ItemHandle->Width;
  1930. ULONG uiDepth = pItemCtx->ItemHandle->Depth;
  1931. LONG ScanLineWidth = iWidth * uiDepth / 8;
  1932. PBITMAPINFO pbmi = NULL;
  1933. PBYTE pImageTop = NULL;
  1934. //
  1935. // find out if data is TYMED_FILE or TYMED_HGLOBAL
  1936. //
  1937. if (pDataTransferContext->tymed == TYMED_FILE) {
  1938. pbmi = (PBITMAPINFO)(pDataTransferContext->pTransferBuffer + sizeof(BITMAPFILEHEADER));
  1939. } else if (pDataTransferContext->tymed == TYMED_HGLOBAL) {
  1940. pbmi = (PBITMAPINFO)(pDataTransferContext->pTransferBuffer);
  1941. } else {
  1942. return;
  1943. }
  1944. //
  1945. // init memory pointer and height
  1946. //
  1947. pImageTop = &pDataTransferContext->pTransferBuffer[0] + pDataTransferContext->lHeaderSize;
  1948. iHeight = pbmi->bmiHeader.biHeight;
  1949. //
  1950. // try to allocat a temp scan line buffer
  1951. //
  1952. PBYTE pBuffer = (PBYTE)LocalAlloc(LPTR,ScanLineWidth);
  1953. if (pBuffer != NULL) {
  1954. LONG index;
  1955. PBYTE pImageBottom;
  1956. pImageBottom = pImageTop + (iHeight-1) * ScanLineWidth;
  1957. for (index = 0;index < (iHeight/2);index++) {
  1958. memcpy(pBuffer,pImageTop,ScanLineWidth);
  1959. memcpy(pImageTop,pImageBottom,ScanLineWidth);
  1960. memcpy(pImageBottom,pBuffer,ScanLineWidth);
  1961. pImageTop += ScanLineWidth;
  1962. pImageBottom -= ScanLineWidth;
  1963. }
  1964. LocalFree(pBuffer);
  1965. }
  1966. }
  1967. /**************************************************************************\
  1968. * FormatCode2FormatInfo
  1969. *
  1970. * This helper function looks up information about an item's format based
  1971. * on the format code.
  1972. *
  1973. * Arguments:
  1974. *
  1975. * ItemType - the item's type
  1976. *
  1977. \**************************************************************************/
  1978. FORMAT_INFO *CWiaCameraDevice::FormatCode2FormatInfo(FORMAT_CODE FormatCode)
  1979. {
  1980. if (FormatCode > (LONG)m_NumFormatInfo)
  1981. FormatCode = 0;
  1982. if (FormatCode < 0)
  1983. FormatCode = 0;
  1984. return &m_FormatInfo[FormatCode];
  1985. }
  1986. /**************************************************************************\
  1987. * GetDrvItemContext
  1988. *
  1989. * This helper function gets the driver item context.
  1990. *
  1991. * Arguments:
  1992. *
  1993. * pWiasContext - service context
  1994. * ppItemCtx - pointer to pointer to item context
  1995. *
  1996. \**************************************************************************/
  1997. HRESULT CWiaCameraDevice::GetDrvItemContext(BYTE *pWiasContext, ITEM_CONTEXT **ppItemCtx,
  1998. IWiaDrvItem **ppDrvItem)
  1999. {
  2000. CWiaLogProc WIAS_LOGPROC(m_pIWiaLog,
  2001. WIALOG_NO_RESOURCE_ID,
  2002. WIALOG_LEVEL1,
  2003. "CWiaCameraDevice::GetDrvItemContext");
  2004. HRESULT hr = S_OK;
  2005. if (!pWiasContext || !ppItemCtx)
  2006. {
  2007. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetDrvItemContext, invalid arg"));
  2008. return E_INVALIDARG;
  2009. }
  2010. IWiaDrvItem *pWiaDrvItem;
  2011. hr = wiasGetDrvItem(pWiasContext, &pWiaDrvItem);
  2012. if (FAILED(hr))
  2013. {
  2014. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetDrvItemContext, wiasGetDrvItem failed"));
  2015. WIAS_LHRESULT(m_pIWiaLog, hr);
  2016. return hr;
  2017. }
  2018. *ppItemCtx = NULL;
  2019. hr = pWiaDrvItem->GetDeviceSpecContext((BYTE **) ppItemCtx);
  2020. if (FAILED(hr))
  2021. {
  2022. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetDrvItemContext, GetDeviceSpecContext failed"));
  2023. WIAS_LHRESULT(m_pIWiaLog, hr);
  2024. return hr;
  2025. }
  2026. if (!*ppItemCtx)
  2027. {
  2028. WIAS_LERROR(m_pIWiaLog,WIALOG_NO_RESOURCE_ID,("GetDrvItemContext, item context is null"));
  2029. return E_FAIL;
  2030. }
  2031. if (ppDrvItem)
  2032. {
  2033. *ppDrvItem = pWiaDrvItem;
  2034. }
  2035. return hr;
  2036. }