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.

704 lines
18 KiB

  1. //------------------------------------------------------------------------------
  2. // (C) COPYRIGHT MICROSOFT CORP., 1998
  3. //
  4. // wiadev.cpp
  5. //
  6. // Implementation of device methods for the IrTran-P USD mini driver.
  7. //
  8. // Author
  9. // EdwardR 05-Aug-99 Initial code.
  10. // Modeled after code written by ReedB.
  11. //
  12. //------------------------------------------------------------------------------
  13. #define __FORMATS_AND_MEDIA_TYPES__
  14. #include <stdio.h>
  15. #include <objbase.h>
  16. #include <sti.h>
  17. #include "ircamera.h"
  18. #include "defprop.h"
  19. #include "resource.h"
  20. #include <irthread.h>
  21. #include <malloc.h>
  22. extern HINSTANCE g_hInst; // Global hInstance
  23. extern WIA_FORMAT_INFO *g_wfiTable;
  24. //----------------------------------------------------------------------------
  25. // IrUsdDevice::InitializWia()
  26. //
  27. //
  28. //
  29. // Arguments:
  30. //
  31. //
  32. //
  33. // Return Value:
  34. //
  35. // HRESULT S_OK
  36. //
  37. //----------------------------------------------------------------------------
  38. HRESULT _stdcall IrUsdDevice::drvInitializeWia(
  39. BYTE *pWiasContext,
  40. LONG lFlags,
  41. BSTR bstrDeviceID,
  42. BSTR bstrRootFullItemName,
  43. IUnknown *pStiDevice,
  44. IUnknown *pIUnknownOuter,
  45. IWiaDrvItem **ppIDrvItemRoot,
  46. IUnknown **ppIUnknownInner,
  47. LONG *plDevErrVal )
  48. {
  49. HRESULT hr;
  50. LONG lDevErrVal;
  51. WIAS_TRACE((g_hInst,"IrUsdDevice::drvInitializeWia(): Device ID: %ws", bstrDeviceID));
  52. *ppIDrvItemRoot = NULL;
  53. *ppIUnknownInner = NULL;
  54. *plDevErrVal = 0;
  55. //
  56. // Initialize names and STI pointer?
  57. //
  58. if (m_pStiDevice == NULL)
  59. {
  60. //
  61. // save STI device inteface for locking:
  62. //
  63. m_pStiDevice = (IStiDevice*)pStiDevice;
  64. //
  65. // Cache the device ID:
  66. //
  67. m_bstrDeviceID = SysAllocString(bstrDeviceID);
  68. if (! m_bstrDeviceID)
  69. {
  70. return E_OUTOFMEMORY;
  71. }
  72. m_bstrRootFullItemName = SysAllocString(bstrRootFullItemName);
  73. if (! m_bstrRootFullItemName)
  74. {
  75. return E_OUTOFMEMORY;
  76. }
  77. }
  78. //
  79. // Build the device item tree
  80. //
  81. hr = drvDeviceCommand( NULL, 0, &WIA_CMD_SYNCHRONIZE, NULL, &lDevErrVal );
  82. if (SUCCEEDED(hr))
  83. {
  84. *ppIDrvItemRoot = m_pIDrvItemRoot;
  85. }
  86. return hr;
  87. }
  88. //----------------------------------------------------------------------------
  89. // IrUsdDevice::drvUnInitializeWia
  90. //
  91. // Gets called when a client connection is going away.
  92. //
  93. // Arguments:
  94. //
  95. // pWiasContext - Pointer to the WIA Root item context of the client's
  96. // item tree.
  97. //
  98. // Return Value:
  99. // Status
  100. //
  101. // History:
  102. //
  103. // 30/12/1999 Original Version
  104. //----------------------------------------------------------------------------
  105. HRESULT _stdcall IrUsdDevice::drvUnInitializeWia(
  106. BYTE *pWiasContext)
  107. {
  108. return S_OK;
  109. }
  110. //----------------------------------------------------------------------------
  111. //
  112. // Mini Driver Device Services
  113. //
  114. //----------------------------------------------------------------------------
  115. /**************************************************************************\
  116. * drvGetDeviceErrorStr
  117. *
  118. * Map a device error value to a string.
  119. *
  120. * Arguments:
  121. *
  122. *
  123. *
  124. * Return Value:
  125. *
  126. * Status
  127. *
  128. * History:
  129. *
  130. * 10/2/1998 Original Version
  131. *
  132. \**************************************************************************/
  133. HRESULT _stdcall IrUsdDevice::drvGetDeviceErrorStr(
  134. LONG lFlags,
  135. LONG lDevErrVal,
  136. LPOLESTR *ppszDevErrStr,
  137. LONG *plDevErr)
  138. {
  139. *plDevErr = 0;
  140. if (!ppszDevErrStr) {
  141. WIAS_ERROR((g_hInst,"drvGetDeviceErrorStr, NULL ppszDevErrStr"));
  142. return E_POINTER;
  143. }
  144. // Map device errors to a string to be placed in the event log.
  145. switch (lDevErrVal) {
  146. case 0:
  147. *ppszDevErrStr = L"No Error";
  148. break;
  149. default:
  150. *ppszDevErrStr = L"Device Error, Unknown Error";
  151. return E_FAIL;
  152. }
  153. return S_OK;
  154. }
  155. //--------------------------------------------------------------------------
  156. // IrUsdDevice::DeleteDeviceItemTree()
  157. //
  158. // Recursive device item tree delete routine. Deletes the whole tree.
  159. //
  160. // Arguments:
  161. //
  162. //
  163. //
  164. // Return Value:
  165. //
  166. // HRESULT
  167. //
  168. //--------------------------------------------------------------------------
  169. HRESULT IrUsdDevice::DeleteDeviceItemTree( OUT LONG *plDevErrVal )
  170. {
  171. HRESULT hr;
  172. //
  173. // does tree exist
  174. //
  175. if (m_pIDrvItemRoot == NULL)
  176. {
  177. return S_OK;
  178. }
  179. //
  180. // Unlink and release the driver item tree.
  181. //
  182. hr = m_pIDrvItemRoot->UnlinkItemTree(WiaItemTypeDisconnected);
  183. m_pIDrvItemRoot = NULL;
  184. return hr;
  185. }
  186. //--------------------------------------------------------------------------
  187. // IrUsdDevice::BuildDeviceItemTree()
  188. //
  189. // The device uses the IWiaDrvServices methods to build up a tree of
  190. // device items. The test scanner supports only a single scanning item so
  191. // build a device item tree with one entry.
  192. //
  193. // Arguments:
  194. //
  195. //
  196. //
  197. // Return Value:
  198. //
  199. // HRESULT
  200. //
  201. //--------------------------------------------------------------------------
  202. HRESULT IrUsdDevice::BuildDeviceItemTree( OUT LONG *plDevErrVal )
  203. {
  204. HRESULT hr = S_OK;
  205. //
  206. // Note: This device doesn't touch hardware to build the tree.
  207. //
  208. if (plDevErrVal)
  209. {
  210. *plDevErrVal = 0;
  211. }
  212. //
  213. // Rebuild the new device item tree (of JPEG images):
  214. //
  215. CAMERA_STATUS camStatus;
  216. if (!m_pIDrvItemRoot)
  217. {
  218. hr = CamBuildImageTree( &camStatus, &m_pIDrvItemRoot );
  219. }
  220. return hr;
  221. }
  222. //--------------------------------------------------------------------------
  223. // IrUsdDevice::InitDeviceProperties()
  224. //
  225. //
  226. //
  227. // Arguments:
  228. //
  229. //
  230. //
  231. // Return Value:
  232. //
  233. // HRESULT -- S_OK
  234. // E_POINTER
  235. // E_OUTOFMEMORY
  236. //
  237. //--------------------------------------------------------------------------
  238. HRESULT IrUsdDevice::InitDeviceProperties(
  239. BYTE *pWiasContext,
  240. LONG *plDevErrVal )
  241. {
  242. int i;
  243. HRESULT hr;
  244. BSTR bstrFirmwreVer;
  245. SYSTEMTIME camTime;
  246. PROPVARIANT propVar;
  247. //
  248. // This device doesn't actually touch any hardware to initialize
  249. // the device properties.
  250. //
  251. if (plDevErrVal)
  252. {
  253. *plDevErrVal = 0;
  254. }
  255. //
  256. // Parameter validation.
  257. //
  258. if (!pWiasContext)
  259. {
  260. WIAS_ERROR((g_hInst,"IrUsdDevice::InitDeviceProperties(): NULL WIAS context"));
  261. return E_POINTER;
  262. }
  263. //
  264. // Write standard property names
  265. //
  266. hr = wiasSetItemPropNames(pWiasContext,
  267. sizeof(gDevicePropIDs)/sizeof(PROPID),
  268. gDevicePropIDs,
  269. gDevicePropNames);
  270. if (FAILED(hr))
  271. {
  272. WIAS_TRACE((g_hInst,"IrUsdDevice::InitDeviceProperties(): WritePropertyNames() failed: 0x%x",hr));
  273. return hr;
  274. }
  275. //
  276. // Write the properties supported by all WIA devices
  277. //
  278. bstrFirmwreVer = SysAllocString(L"02161999");
  279. if (bstrFirmwreVer)
  280. {
  281. wiasWritePropStr( pWiasContext,
  282. WIA_DPA_FIRMWARE_VERSION,
  283. bstrFirmwreVer );
  284. SysFreeString(bstrFirmwreVer);
  285. }
  286. wiasWritePropLong( pWiasContext, WIA_DPA_CONNECT_STATUS, 1);
  287. wiasWritePropLong( pWiasContext, WIA_DPC_PICTURES_TAKEN, 0);
  288. GetSystemTime(&camTime);
  289. wiasWritePropBin( pWiasContext,
  290. WIA_DPA_DEVICE_TIME,
  291. sizeof(SYSTEMTIME),
  292. (PBYTE)&camTime );
  293. //
  294. // Write the camera properties, just default values, it may vary with items
  295. //
  296. wiasWritePropLong(
  297. pWiasContext, WIA_DPC_PICTURES_REMAINING, 0);
  298. wiasWritePropLong(
  299. pWiasContext, WIA_DPC_THUMB_WIDTH, 80);
  300. wiasWritePropLong(
  301. pWiasContext, WIA_DPC_THUMB_HEIGHT, 60);
  302. wiasWritePropLong(
  303. pWiasContext, WIA_DPC_PICT_WIDTH, 1024);
  304. wiasWritePropLong(
  305. pWiasContext, WIA_DPC_PICT_HEIGHT, 768);
  306. // Give WIA_DPC_EXPOSURE_MODE to WIA_DPC_TIMER_VALUE some default.
  307. wiasWritePropLong(
  308. pWiasContext, WIA_DPC_EXPOSURE_MODE, 0);
  309. wiasWritePropLong(
  310. pWiasContext, WIA_DPC_FLASH_MODE, 1);
  311. wiasWritePropLong(
  312. pWiasContext, WIA_DPC_FOCUS_MODE, 0);
  313. wiasWritePropLong(
  314. pWiasContext, WIA_DPC_ZOOM_POSITION, 0);
  315. wiasWritePropLong(
  316. pWiasContext, WIA_DPC_BATTERY_STATUS, 1);
  317. wiasWritePropLong(
  318. pWiasContext, WIA_DPC_TIMER_MODE, 0);
  319. wiasWritePropLong(
  320. pWiasContext, WIA_DPC_TIMER_VALUE, 0);
  321. //
  322. // Write the WIA_DPP_TCAM_ROOT_PATH property
  323. //
  324. BSTR bstrRootPath;
  325. CHAR *pszPath = ::GetImageDirectory(); // Don't try to free...
  326. WCHAR wszPath[MAX_PATH];
  327. if (!pszPath)
  328. {
  329. return E_OUTOFMEMORY;
  330. }
  331. mbstowcs( wszPath, pszPath, strlen(pszPath) );
  332. bstrRootPath = SysAllocString(wszPath);
  333. if (! bstrRootPath)
  334. {
  335. return E_OUTOFMEMORY;
  336. }
  337. wiasWritePropStr(pWiasContext, WIA_DPP_TCAM_ROOT_PATH, bstrRootPath);
  338. //
  339. // Use WIA services to set the property access and
  340. // valid value information from gDevPropInfoDefaults.
  341. //
  342. hr = wiasSetItemPropAttribs(pWiasContext,
  343. NUM_CAM_DEV_PROPS,
  344. gDevicePropSpecDefaults,
  345. gDevPropInfoDefaults);
  346. return S_OK;
  347. }
  348. //--------------------------------------------------------------------------
  349. // IrUsdDevice::drvDeviceCommand()
  350. //
  351. //
  352. //
  353. // Arguments:
  354. //
  355. //
  356. //
  357. // Return Value:
  358. //
  359. // HRESULT S_OK
  360. // E_NOTIMPL
  361. //
  362. //--------------------------------------------------------------------------
  363. HRESULT _stdcall IrUsdDevice::drvDeviceCommand(
  364. BYTE *pWiasContext,
  365. LONG lFlags,
  366. const GUID *plCommand,
  367. IWiaDrvItem **ppWiaDrvItem,
  368. LONG *plErr)
  369. {
  370. HRESULT hr;
  371. //
  372. // init return value
  373. //
  374. if (ppWiaDrvItem != NULL)
  375. {
  376. *ppWiaDrvItem = NULL;
  377. }
  378. //
  379. // dispatch command
  380. //
  381. if (*plCommand == WIA_CMD_SYNCHRONIZE)
  382. {
  383. WIAS_TRACE((g_hInst,"IrUsdDevice::drvDeviceCommand(): WIA_CMD_SYNCHRONIZE"));
  384. hr = drvLockWiaDevice(pWiasContext, lFlags, plErr);
  385. if (FAILED(hr))
  386. {
  387. return (hr);
  388. }
  389. //
  390. // SYNCHRONIZE - make sure tree is up to date with device
  391. //
  392. // The dirver's responsibility is to make sure the tree is accurate.
  393. //
  394. hr = BuildDeviceItemTree(plErr);
  395. drvUnLockWiaDevice( pWiasContext, lFlags, plErr );
  396. }
  397. else
  398. {
  399. WIAS_TRACE((g_hInst,"drvDeviceCommand: Unsupported command"));
  400. hr = E_NOTIMPL;
  401. }
  402. return hr;
  403. }
  404. //--------------------------------------------------------------------------
  405. // LoadStringResource()
  406. //
  407. //
  408. //--------------------------------------------------------------------------
  409. int LoadStringResource( IN HINSTANCE hInst,
  410. IN UINT uID,
  411. OUT WCHAR *pwszBuff,
  412. IN int iBuffMax )
  413. {
  414. #ifdef UNICODE
  415. return LoadString(hInst,uID,pwszBuff,iBuffMax);
  416. #else
  417. CHAR *pszBuff = (CHAR*)_alloca(sizeof(CHAR)*iBuffMax);
  418. int iCount = LoadString(hInst,uID,pszBuff,iBuffMax);
  419. if (iCount > 0)
  420. {
  421. MultiByteToWideChar( CP_ACP, 0, pszBuff, -1, pwszBuff, iBuffMax );
  422. }
  423. return iCount;
  424. #endif
  425. }
  426. //--------------------------------------------------------------------------
  427. // IrUsdDevice::InitializeCapabilities()
  428. //
  429. // This helper function is called by IrUsdDevice::drvGetCapabilities() to
  430. // make sure that the string resources are setup in the gCapabilities[]
  431. // array before it is passed back to WIA.
  432. //
  433. //--------------------------------------------------------------------------
  434. void IrUsdDevice::InitializeCapabilities()
  435. {
  436. int i;
  437. UINT uIDS;
  438. WCHAR *pwszName;
  439. WCHAR *pwszDescription;
  440. # define MAX_IDS_WSTR 64
  441. //
  442. // If we have entries already, then this function was already called
  443. // and we can just return:
  444. //
  445. if (gCapabilities[0].wszName)
  446. {
  447. return;
  448. }
  449. for (i=0; i<NUM_CAP_ENTRIES; i++)
  450. {
  451. //
  452. // Get the string table string ID for this entry:
  453. //
  454. uIDS = gCapabilityIDS[i];
  455. //
  456. // Get the name string for this entry fron the resource file:
  457. //
  458. pwszName = new WCHAR [MAX_IDS_WSTR];
  459. if ( (pwszName)
  460. && (LoadStringResource(g_hInst,uIDS,pwszName,MAX_IDS_WSTR)))
  461. {
  462. gCapabilities[i].wszName = pwszName;
  463. }
  464. else
  465. {
  466. gCapabilities[i].wszName = gDefaultStrings[i];
  467. }
  468. //
  469. // Get the Discription string for this entry from the resource file:
  470. //
  471. pwszDescription = new WCHAR [MAX_IDS_WSTR];
  472. if ( (pwszDescription)
  473. && (LoadStringResource(g_hInst,uIDS,pwszDescription,MAX_IDS_WSTR)))
  474. {
  475. gCapabilities[i].wszDescription = pwszDescription;
  476. }
  477. else
  478. {
  479. gCapabilities[i].wszDescription = gDefaultStrings[i];
  480. }
  481. }
  482. }
  483. //--------------------------------------------------------------------------
  484. // IrUsdDevice::drvGetCapabilities()
  485. //
  486. //
  487. //
  488. // Arguments:
  489. //
  490. //
  491. //
  492. // Return Value:
  493. //
  494. // HRESULT -- S_OK
  495. // -- E_INVALIDARG
  496. //
  497. //--------------------------------------------------------------------------
  498. HRESULT _stdcall IrUsdDevice::drvGetCapabilities(
  499. BYTE *pWiasContext,
  500. LONG ulFlags,
  501. LONG *pCelt,
  502. WIA_DEV_CAP_DRV **ppCapabilities,
  503. LONG *plDevErrVal )
  504. {
  505. HRESULT hr = S_OK;
  506. *plDevErrVal = 0;
  507. //
  508. // Make sure the device capabilities array is setup
  509. //
  510. InitializeCapabilities();
  511. //
  512. // Return Commmand and/or Events depending on flags:
  513. //
  514. switch (ulFlags)
  515. {
  516. case WIA_DEVICE_COMMANDS:
  517. //
  518. // Only asked for commands:
  519. //
  520. *pCelt = NUM_CAP_ENTRIES - NUM_EVENTS;
  521. *ppCapabilities = &gCapabilities[NUM_EVENTS];
  522. break;
  523. case WIA_DEVICE_EVENTS:
  524. //
  525. // Return only events:
  526. //
  527. *pCelt = NUM_EVENTS;
  528. *ppCapabilities = gCapabilities;
  529. break;
  530. case (WIA_DEVICE_COMMANDS | WIA_DEVICE_EVENTS):
  531. //
  532. // Return both events and commands:
  533. //
  534. *pCelt = NUM_CAP_ENTRIES;
  535. *ppCapabilities = gCapabilities;
  536. break;
  537. default:
  538. //
  539. // Flags is invalid
  540. //
  541. WIAS_ERROR((g_hInst, "drvGetCapabilities, flags was invalid"));
  542. hr = E_INVALIDARG;
  543. }
  544. return hr;
  545. }
  546. //--------------------------------------------------------------------------
  547. // IrUsdDevice::drvGetFormatEtc()
  548. //
  549. // Return an array of the supported formats and mediatypes.
  550. //
  551. // Arguments:
  552. //
  553. // pWiasConext -
  554. // ulFlags -
  555. // plNumFE - Number of returned formats.
  556. // ppFE - Pointer to array of FORMATETC for supported formats
  557. // and mediatypes.
  558. // plDevErrVal - Return error number.
  559. //
  560. // Return Value:
  561. //
  562. // HRESULT - S_OK
  563. //
  564. //--------------------------------------------------------------------------
  565. HRESULT _stdcall IrUsdDevice::drvGetWiaFormatInfo(
  566. IN BYTE *pWiasContext,
  567. IN LONG ulFlags,
  568. OUT LONG *plNumWFI,
  569. OUT WIA_FORMAT_INFO **ppWFI,
  570. OUT LONG *plDevErrVal)
  571. {
  572. #define NUM_WIA_FORMAT_INFO 2
  573. WIAS_TRACE((g_hInst, "IrUsdDevice::drvGetWiaFormatInfo()"));
  574. //
  575. // If necessary, setup the g_wfiTable.
  576. //
  577. if (!g_wfiTable)
  578. {
  579. g_wfiTable = (WIA_FORMAT_INFO*) CoTaskMemAlloc(sizeof(WIA_FORMAT_INFO) * NUM_WIA_FORMAT_INFO);
  580. if (!g_wfiTable)
  581. {
  582. WIAS_ERROR((g_hInst, "drvGetWiaFormatInfo(): out of memory"));
  583. return E_OUTOFMEMORY;
  584. }
  585. //
  586. // Set the format/tymed pairs:
  587. //
  588. g_wfiTable[0].guidFormatID = WiaImgFmt_JPEG;
  589. g_wfiTable[0].lTymed = TYMED_CALLBACK;
  590. g_wfiTable[1].guidFormatID = WiaImgFmt_JPEG;
  591. g_wfiTable[1].lTymed = TYMED_FILE;
  592. }
  593. *plNumWFI = NUM_WIA_FORMAT_INFO;
  594. *ppWFI = g_wfiTable;
  595. *plDevErrVal = 0;
  596. return S_OK;
  597. }
  598. //--------------------------------------------------------------------------
  599. // IrUsdDevice::drvNotifyPnpEvent()
  600. //
  601. // Notify PnP event received by device manager.
  602. //
  603. //--------------------------------------------------------------------------
  604. HRESULT _stdcall IrUsdDevice::drvNotifyPnpEvent(
  605. IN const GUID *pEventGUID,
  606. IN BSTR bstrDeviceID,
  607. IN ULONG ulReserved )
  608. {
  609. return S_OK;
  610. }