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.

482 lines
14 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1998
  4. *
  5. * TITLE: WiaGItm.Cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ByronC
  10. *
  11. * DATE: 14 Jan, 2000
  12. *
  13. * DESCRIPTION:
  14. * Implementation of CGenWiaItem.
  15. *
  16. *******************************************************************************/
  17. #include "precomp.h"
  18. #include "stiexe.h"
  19. #include "wiapsc.h"
  20. #define WIA_DECLARE_MANAGED_PROPS
  21. #include "helpers.h"
  22. /**************************************************************************\
  23. * Initialize
  24. *
  25. * CGenWiaItem Initialize method. This method overrieds the base class
  26. * CWiaItem::Initialize, since a generated item
  27. *
  28. * Arguments:
  29. *
  30. * pIWiaItemRoot -
  31. * pIWiaMiniDrv -
  32. * pWiaDrvItem -
  33. * pIUnknownInner -
  34. *
  35. * Return Value:
  36. *
  37. * Status
  38. *
  39. * History:
  40. *
  41. * 14 Jan, 2000 - Original Version
  42. *
  43. \**************************************************************************/
  44. HRESULT _stdcall CGenWiaItem::Initialize(
  45. IWiaItem *pIWiaItemRoot,
  46. IWiaPropertyStorage *pIWiaDevInfoProps,
  47. ACTIVE_DEVICE *pActiveDevice,
  48. CWiaDrvItem *pWiaDrvItem,
  49. IUnknown *pIUnknownInner)
  50. {
  51. DBG_FN(CGenWiaItem::Initialize);
  52. HRESULT hr = S_OK;
  53. #ifdef DEBUG
  54. BSTR bstr;
  55. if (SUCCEEDED(pWiaDrvItem->GetItemName(&bstr))) {
  56. DBG_TRC(("CGenWiaItem::Initialize: 0x%08X, %ws, drv item: 0x%08X", this, bstr, pWiaDrvItem));
  57. SysFreeString(bstr);
  58. }
  59. #endif
  60. //
  61. // Validate parameters
  62. //
  63. if (!pActiveDevice || !pIWiaItemRoot || !pWiaDrvItem) {
  64. DBG_ERR(("CGenWiaItem::Initialize NULL input parameters"));
  65. return E_POINTER;
  66. }
  67. //
  68. // If optional inner component is present, save a pointer to it.
  69. //
  70. if (pIUnknownInner) {
  71. DBG_TRC(("CGenWiaItem::Initialize, pIUnknownInner: %X", pIUnknownInner));
  72. m_pIUnknownInner = pIUnknownInner;
  73. }
  74. //
  75. // Save driver info.
  76. //
  77. m_pWiaDrvItem = pWiaDrvItem;
  78. m_pActiveDevice = pActiveDevice;
  79. m_pIWiaItemRoot = pIWiaItemRoot;
  80. hr = pWiaDrvItem->LinkToDrvItem(this);
  81. if (FAILED(hr)) {
  82. DBG_ERR(("CGenWiaItem::Initialize, LinkToDrvItem failed"));
  83. return hr;
  84. }
  85. //
  86. // Create streams and property storage for item properties.
  87. //
  88. m_pPropStg = new CWiaPropStg();
  89. if (m_pPropStg) {
  90. hr = m_pPropStg->Initialize();
  91. if (FAILED(hr)) {
  92. delete m_pPropStg;
  93. m_pPropStg = NULL;
  94. DBG_ERR(("CGenWiaItem::Initialize, PropertyStorage Initialize failed"));
  95. return hr;
  96. }
  97. } else {
  98. DBG_ERR(("CGenWiaItem::Initialize, not enough memory to create CWiaPropStg"));
  99. hr = E_OUTOFMEMORY;
  100. return hr;
  101. }
  102. m_bInitialized = TRUE;
  103. //
  104. // AddRef the driver item which can not be deleted until all
  105. // CWiaItem references are released and the driver item has been
  106. // removed from the driver item tree.
  107. //
  108. pWiaDrvItem->AddRef();
  109. return hr;
  110. }
  111. /**************************************************************************\
  112. * GetItemType
  113. *
  114. * Get the item type from the corresponding driver item.
  115. *
  116. * Arguments:
  117. *
  118. * pItemType - Pointer to the returned item type.
  119. *
  120. * Return Value:
  121. *
  122. * Status
  123. *
  124. * History:
  125. *
  126. * 14 Jan, 2000 - Original Version
  127. *
  128. \**************************************************************************/
  129. HRESULT _stdcall CGenWiaItem::GetItemType(LONG *pItemType)
  130. {
  131. DBG_FN(CGenWiaItem::GetItemType);
  132. return m_pCWiaTree->GetItemFlags(pItemType);
  133. }
  134. /**************************************************************************\
  135. * InitManagedItemProperties
  136. *
  137. * A private helper for CGenWiaItem::Initialize, which initializes the
  138. * WIA managed item properties.
  139. *
  140. * Arguments:
  141. *
  142. * None
  143. *
  144. * Return Value:
  145. *
  146. * Status
  147. *
  148. * History:
  149. *
  150. * 14 Jan, 2000 - Original Version
  151. *
  152. \**************************************************************************/
  153. HRESULT _stdcall CGenWiaItem::InitManagedItemProperties(
  154. LONG lFlags,
  155. BSTR bstrItemName,
  156. BSTR bstrFullItemName)
  157. {
  158. DBG_FN(CWiaItem::InitManagedItemProperties);
  159. ULONG ulNumProps;
  160. ulNumProps = NUM_WIA_MANAGED_PROPS;
  161. //
  162. // WIA manages the item name and type properties, so set the
  163. // property names here.
  164. //
  165. HRESULT hr = wiasSetItemPropNames((BYTE*)this,
  166. ulNumProps,
  167. s_piItemNameType,
  168. s_pszItemNameType);
  169. //
  170. // Set the name and type properties attributes.
  171. //
  172. PROPVARIANT propvar;
  173. ULONG ulFlag;
  174. for (UINT i = 0; i < ulNumProps; i++) {
  175. if (i == PROFILE_INDEX) {
  176. propvar.vt = VT_BSTR | VT_VECTOR;
  177. ulFlag = WIA_PROP_RW | WIA_PROP_CACHEABLE | WIA_PROP_LIST;
  178. } else {
  179. propvar.vt = VT_I4;
  180. ulFlag = WIA_PROP_READ | WIA_PROP_CACHEABLE | WIA_PROP_NONE;
  181. }
  182. propvar.ulVal = 0;
  183. hr = wiasSetPropertyAttributes((BYTE*)this,
  184. 1,
  185. &s_psItemNameType[i],
  186. &ulFlag,
  187. &propvar);
  188. if (FAILED(hr)) {
  189. DBG_ERR(("CWiaItem::InitManagedItemProperties, wiasSetPropertyAttributes failed, index: %d", i));
  190. break;
  191. }
  192. }
  193. //
  194. // Set the item names and type.
  195. //
  196. PROPVARIANT *ppropvar;
  197. ppropvar = (PROPVARIANT*) LocalAlloc(LPTR, sizeof(PROPVARIANT) * ulNumProps);
  198. if (ppropvar) {
  199. memset(ppropvar, 0, sizeof(ppropvar[0]) * ulNumProps);
  200. ppropvar[0].vt = VT_BSTR;
  201. ppropvar[0].bstrVal = bstrItemName;
  202. ppropvar[1].vt = VT_BSTR;
  203. ppropvar[1].bstrVal = bstrFullItemName;
  204. ppropvar[2].vt = VT_I4;
  205. ppropvar[2].lVal = lFlags;
  206. hr = (m_pPropStg->CurStg())->WriteMultiple(ulNumProps,
  207. s_psItemNameType,
  208. ppropvar,
  209. WIA_DIP_FIRST);
  210. if (FAILED(hr)) {
  211. ReportReadWriteMultipleError(hr, "CWiaItem::InitManagedItemProperties",
  212. NULL,
  213. FALSE,
  214. ulNumProps,
  215. s_psItemNameType);
  216. }
  217. LocalFree(ppropvar);
  218. } else {
  219. DBG_ERR(("CWiaItem::InitManagedItemProperties, Out of Memory!"));
  220. hr = E_OUTOFMEMORY;
  221. }
  222. return hr;
  223. }
  224. HRESULT GetParamsForInitialize(
  225. BYTE *pWiasContext,
  226. CWiaItem **ppRoot,
  227. ACTIVE_DEVICE **ppActiveDevice,
  228. CWiaDrvItem **ppDrvItem)
  229. {
  230. DBG_FN(GetParamsForInitialize);
  231. HRESULT hr;
  232. //
  233. // Get the root item, the nearest driver item, and the minidriver
  234. // interfaces. These are needed for the child item's initialization.
  235. //
  236. hr = wiasGetRootItem(pWiasContext, (BYTE**) ppRoot);
  237. if (SUCCEEDED(hr)) {
  238. *ppDrvItem = ((CWiaItem*)pWiasContext)->GetDrvItemPtr();
  239. if (*ppDrvItem) {
  240. CWiaItem *pItem = (CWiaItem*) pWiasContext;
  241. *ppActiveDevice = pItem->m_pActiveDevice;
  242. } else {
  243. DBG_ERR(("GetParamsForInitialize, No driver item found!"));
  244. hr = E_INVALIDARG;
  245. }
  246. } else {
  247. DBG_ERR(("GetParamsForInitialize, Could not get root item!"));
  248. }
  249. return hr;
  250. }
  251. HRESULT AddGenItemToParent(
  252. CWiaItem *pParent,
  253. LONG lFlags,
  254. BSTR bstrItemName,
  255. BSTR bstrFullItemName,
  256. CGenWiaItem *pChild)
  257. {
  258. DBG_FN(GetParamsForInitialize);
  259. HRESULT hr = E_FAIL;
  260. //
  261. // Create the Tree
  262. //
  263. CWiaTree *pNewTreeItem = new CWiaTree;
  264. if (pNewTreeItem) {
  265. //
  266. // Adjust parent's flags to indicate folder
  267. //
  268. pParent->m_pCWiaTree->SetFolderFlags();
  269. //
  270. // Initialize the tree with flags, names and payload
  271. //
  272. hr = pNewTreeItem->Initialize(lFlags,
  273. bstrItemName,
  274. bstrFullItemName,
  275. (void*)pChild);
  276. if (SUCCEEDED(hr)) {
  277. pChild->m_pCWiaTree = pNewTreeItem;
  278. hr = pChild->m_pCWiaTree->AddItemToFolder(pParent->m_pCWiaTree);
  279. if (FAILED(hr)) {
  280. DBG_ERR(("AddGenItemToParent, Could not add item to folder!"));
  281. }
  282. } else {
  283. DBG_ERR(("AddGenItemToParent, Failed to initialize the tree!"));
  284. }
  285. if (FAILED(hr)) {
  286. delete pNewTreeItem;
  287. pChild->m_pCWiaTree = NULL;
  288. }
  289. } else {
  290. DBG_ERR(("AddGenItemToParent, Out of Memory!"));
  291. hr = E_OUTOFMEMORY;
  292. }
  293. return hr;
  294. }
  295. /**************************************************************************\
  296. * wiasCreateChildAppItem
  297. *
  298. * This function creates a new App. Item and inserts it as a child of the
  299. * specified (parent) item. Note, that this item will not have any
  300. * properties in it's property sets, until the driver/app actaully fills
  301. * them in.
  302. *
  303. * Arguments:
  304. *
  305. * pWiasContext - the address of the item context to which we
  306. * want to add a child.
  307. * ppWiasChildContext - the address of a pointer which will contain the
  308. * address of the newly created child item's
  309. * context.
  310. *
  311. * Return Value:
  312. *
  313. * Status
  314. *
  315. * History:
  316. *
  317. * 14 Jan, 2000 - Original Version
  318. *
  319. \**************************************************************************/
  320. HRESULT _stdcall wiasCreateChildAppItem(
  321. BYTE *pParentWiasContext,
  322. LONG lFlags,
  323. BSTR bstrItemName,
  324. BSTR bstrFullItemName,
  325. BYTE **ppWiasChildContext)
  326. {
  327. DBG_FN(wiasCreateChildAppItem);
  328. HRESULT hr = S_OK;
  329. CGenWiaItem *pChild;
  330. CWiaItem *pItem = (CWiaItem*) pParentWiasContext;
  331. CWiaItem *pRoot = NULL;
  332. CWiaDrvItem *pDrvItem = NULL;
  333. ACTIVE_DEVICE *pActiveDevice = NULL;
  334. if ((ValidateWiaItem((IWiaItem*) pParentWiasContext) != S_OK) ||
  335. (IsBadWritePtr(ppWiasChildContext, sizeof(BYTE*)))) {
  336. DBG_ERR(("wiasCreateChildAppItem, Invalid parameter!"));
  337. return E_INVALIDARG;
  338. } else {
  339. *ppWiasChildContext = NULL;
  340. }
  341. //
  342. // Mark that this item is a generated item.
  343. //
  344. lFlags |= WiaItemTypeGenerated;
  345. //
  346. // Create a new instance of a generated WIA app. item.
  347. //
  348. pChild = new CGenWiaItem();
  349. if (pChild) {
  350. hr = GetParamsForInitialize(pParentWiasContext, &pRoot, &pActiveDevice, &pDrvItem);
  351. if (SUCCEEDED(hr)) {
  352. //
  353. // Initialize the new child item
  354. //
  355. hr = pChild->Initialize((IWiaItem*) pRoot, NULL, pActiveDevice, pDrvItem, NULL);
  356. if (SUCCEEDED(hr)) {
  357. //
  358. // Initialize the WIA managed item properties (name, full name, type, ...)
  359. // from the driver item. Must set m_bInitialized to TRUE so that
  360. // InitWiaManagedProperties doesn't attempt to InitLazyProps()
  361. //
  362. hr = pChild->InitManagedItemProperties(lFlags,
  363. bstrItemName,
  364. bstrFullItemName);
  365. if (SUCCEEDED(hr)) {
  366. //
  367. // Add to the parent's Tree
  368. //
  369. hr = AddGenItemToParent(pItem,
  370. lFlags,
  371. bstrItemName,
  372. bstrFullItemName,
  373. pChild);
  374. if (SUCCEEDED(hr)) {
  375. //
  376. // Initialization successful. Note that we
  377. // don't AddRef here since if the caller was
  378. // a driver, IWiaItems are BYTE* pWiasContexts
  379. // and not COM objects. Caller must AddRef
  380. // if handing the created to an Application.
  381. //
  382. //
  383. // Fill in ICM Profile information, if not root item.
  384. // This would normally go in InitManagedItemProperties,
  385. // but the item had not been added to the tree by that
  386. // time...
  387. //
  388. if (pRoot != pChild) {
  389. hr = FillICMPropertyFromRegistry(NULL, (IWiaItem*) pChild);
  390. }
  391. }
  392. }
  393. }
  394. }
  395. if (FAILED(hr)) {
  396. delete pChild;
  397. pChild = NULL;
  398. }
  399. } else {
  400. DBG_ERR(("wiasCreateChildAppItem, Out of Memory!"));
  401. hr = E_OUTOFMEMORY;
  402. }
  403. if (SUCCEEDED(hr)) {
  404. *ppWiasChildContext = (BYTE*)pChild;
  405. }
  406. return hr;
  407. }