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.

402 lines
9.9 KiB

  1. #include "precomp.h"
  2. #include "fsdiag.h"
  3. DEBUG_FILEZONE(ZONE_T120_UTILITY);
  4. /*
  5. * appcap.cpp
  6. *
  7. * Copyright (c) 1994 by DataBeam Corporation, Lexington, KY
  8. *
  9. * Abstract:
  10. * This is the implementation file for the class CAppCap.
  11. *
  12. * Caveats:
  13. * None.
  14. *
  15. * Author:
  16. * jbo
  17. */
  18. #include "appcap.h"
  19. #include "clists.h"
  20. /*
  21. * CAppCap ()
  22. *
  23. * Public Function Description:
  24. * This constructor is used to create a AppCapabilityData object
  25. * from an "API" GCCApplicationCapability list.
  26. */
  27. CAppCap::CAppCap(UINT number_of_capabilities,
  28. PGCCApplicationCapability * capabilities_list,
  29. PGCCError pRetCode)
  30. :
  31. CRefCount(MAKE_STAMP_ID('A','C','a','p')),
  32. m_AppCapItemList(DESIRED_MAX_CAPS),
  33. m_cbDataSize(0)
  34. {
  35. APP_CAP_ITEM *pAppCapItem;
  36. UINT i;
  37. GCCError rc;
  38. rc = GCC_NO_ERROR;
  39. for (i = 0; i < number_of_capabilities; i++)
  40. {
  41. DBG_SAVE_FILE_LINE
  42. pAppCapItem = new APP_CAP_ITEM((GCCCapabilityType) capabilities_list[i]->capability_class.eType);
  43. if (pAppCapItem != NULL)
  44. {
  45. DBG_SAVE_FILE_LINE
  46. pAppCapItem->pCapID = new CCapIDContainer(
  47. &capabilities_list[i]->capability_id,
  48. &rc);
  49. if ((pAppCapItem->pCapID != NULL) && (rc == GCC_NO_ERROR))
  50. {
  51. if (capabilities_list[i]->capability_class.eType ==
  52. GCC_UNSIGNED_MINIMUM_CAPABILITY)
  53. {
  54. pAppCapItem->nUnsignedMinimum =
  55. capabilities_list[i]->capability_class.nMinOrMax;
  56. }
  57. else if (capabilities_list[i]->capability_class.eType
  58. == GCC_UNSIGNED_MAXIMUM_CAPABILITY)
  59. {
  60. pAppCapItem->nUnsignedMaximum =
  61. capabilities_list[i]->capability_class.nMinOrMax;
  62. }
  63. pAppCapItem->cEntries = 1;
  64. /*
  65. * Add this capability to the list.
  66. */
  67. m_AppCapItemList.Append(pAppCapItem);
  68. }
  69. else if (pAppCapItem->pCapID == NULL)
  70. {
  71. rc = GCC_ALLOCATION_FAILURE;
  72. }
  73. else
  74. {
  75. delete pAppCapItem;
  76. }
  77. }
  78. else
  79. {
  80. rc = GCC_ALLOCATION_FAILURE;
  81. }
  82. if (rc != GCC_NO_ERROR)
  83. break;
  84. }
  85. *pRetCode = rc;
  86. }
  87. /*
  88. * ~CAppCap()
  89. *
  90. * Public Function Description
  91. * The CAppCap destructor is responsible for freeing
  92. * any memory allocated to hold the capability data.
  93. *
  94. */
  95. CAppCap::~CAppCap(void)
  96. {
  97. m_AppCapItemList.DeleteList();
  98. }
  99. /*
  100. * LockCapabilityData ()
  101. *
  102. * Public Function Description:
  103. * This routine locks the capability data and determines the amount of
  104. * memory referenced by the "API" non-collapsing capability data structure.
  105. */
  106. UINT CAppCap::LockCapabilityData(void)
  107. {
  108. /*
  109. * If this is the first time this routine is called, determine the size of
  110. * the memory required to hold the data referenced by the list of
  111. * capabilities. Otherwise, just increment the lock count.
  112. */
  113. if (Lock() == 1)
  114. {
  115. APP_CAP_ITEM *pAppCapItem;
  116. /*
  117. * Add the amount of memory necessary to hold the string data associated
  118. * with each capability ID.
  119. */
  120. m_AppCapItemList.Reset();
  121. /*
  122. * Lock the data for each capability ID. The lock call returns the
  123. * length of the data referenced by each capability ID rounded to occupy
  124. * an even multiple of four-bytes.
  125. */
  126. while (NULL != (pAppCapItem = m_AppCapItemList.Iterate()))
  127. {
  128. m_cbDataSize += pAppCapItem->pCapID->LockCapabilityIdentifierData();
  129. }
  130. /*
  131. * Add the memory to hold the application capability pointers
  132. * and structures.
  133. */
  134. m_cbDataSize += m_AppCapItemList.GetCount() *
  135. (sizeof (PGCCApplicationCapability) +
  136. ROUNDTOBOUNDARY( sizeof(GCCApplicationCapability)) );
  137. }
  138. return m_cbDataSize;
  139. }
  140. /*
  141. * GetGCCApplicationCapabilityList ()
  142. *
  143. * Public Function Description:
  144. * This routine retrieves the application capabilities list in the form of
  145. * a list of PGCCApplicationCapability's. This routine is called after
  146. * "locking" the capability data.
  147. */
  148. UINT CAppCap::GetGCCApplicationCapabilityList(
  149. PUShort number_of_capabilities,
  150. PGCCApplicationCapability * * capabilities_list,
  151. LPBYTE memory)
  152. {
  153. UINT cbDataSizeToRet = 0;
  154. /*
  155. * If the capability data has been locked, fill in the output structure and
  156. * the data referenced by the structure.
  157. */
  158. if (GetLockCount() > 0)
  159. {
  160. UINT data_length = 0;
  161. UINT capability_id_data_length = 0;
  162. USHORT capability_count;
  163. PGCCApplicationCapability gcc_capability;
  164. PGCCApplicationCapability * gcc_capability_list;
  165. APP_CAP_ITEM *pAppCapItem;
  166. /*
  167. * Fill in the output length parameter which indicates how much data
  168. * referenced outside the structure will be written.
  169. */
  170. cbDataSizeToRet = m_cbDataSize;
  171. /*
  172. * Retrieve the number of capabilities and fill in any that are present.
  173. */
  174. *number_of_capabilities = (USHORT) m_AppCapItemList.GetCount();
  175. if (*number_of_capabilities != 0)
  176. {
  177. /*
  178. * Fill in the pointer to the list of application capability
  179. * pointers. The pointer list will begin at the memory location
  180. * passed into this routine. Save the list pointer in a local
  181. * variable for convenience.
  182. */
  183. *capabilities_list = (PGCCApplicationCapability *)memory;
  184. gcc_capability_list = *capabilities_list;
  185. /*
  186. * Move the memory pointer past the list of capability pointers.
  187. * This is where the first application capability structure will be
  188. * written.
  189. */
  190. memory += (*number_of_capabilities * sizeof(PGCCApplicationCapability));
  191. /*
  192. * Add to the data length the amount of memory necessary to hold the
  193. * application capability pointers. Go ahead and add the amount of
  194. * memory necessary to hold all of the GCCApplicationCapability
  195. * structures.
  196. */
  197. data_length += *number_of_capabilities *
  198. (sizeof(PGCCApplicationCapability) +
  199. ROUNDTOBOUNDARY ( sizeof(GCCApplicationCapability)) );
  200. /*
  201. * Iterate through the capabilities list, building an "API"
  202. * capability for each capability in the list.
  203. */
  204. capability_count = 0;
  205. m_AppCapItemList.Reset();
  206. while (NULL != (pAppCapItem = m_AppCapItemList.Iterate()))
  207. {
  208. /*
  209. * Set the application capability pointer equal to the
  210. * location in memory where it will be written.
  211. */
  212. gcc_capability = (PGCCApplicationCapability)memory;
  213. /*
  214. * Save the pointer to the application capability in the
  215. * list of application capability pointers.
  216. */
  217. gcc_capability_list[capability_count] = gcc_capability;
  218. /*
  219. * Advance the memory pointer past the application capability
  220. * structure. This is where the string data for the capability
  221. * ID will be written. Ensure that the memory pointer falls on
  222. * an even four-byte boundary.
  223. */
  224. memory += ROUNDTOBOUNDARY(sizeof(GCCApplicationCapability));
  225. /*
  226. * Retrieve the capability ID information from the internal
  227. * CapabilityIDData object. The length returned by this call
  228. * will have already been rounded to an even multiple of four
  229. * bytes.
  230. */
  231. capability_id_data_length = pAppCapItem->pCapID->
  232. GetGCCCapabilityIDData(&gcc_capability->capability_id, memory);
  233. /*
  234. * Advance the memory pointer past the string data written into
  235. * memory by the capability ID object. Add the length of the
  236. * string data to the overall capability length.
  237. */
  238. memory += capability_id_data_length;
  239. data_length += capability_id_data_length;
  240. /*
  241. * Now fill in the rest of the capability.
  242. */
  243. gcc_capability->capability_class.eType = pAppCapItem->eCapType;
  244. if (gcc_capability->capability_class.eType ==
  245. GCC_UNSIGNED_MINIMUM_CAPABILITY)
  246. {
  247. gcc_capability->capability_class.nMinOrMax =
  248. pAppCapItem->nUnsignedMinimum;
  249. }
  250. else if (gcc_capability->capability_class.eType ==
  251. GCC_UNSIGNED_MAXIMUM_CAPABILITY)
  252. {
  253. gcc_capability->capability_class.nMinOrMax =
  254. pAppCapItem->nUnsignedMaximum;
  255. }
  256. gcc_capability->number_of_entities = pAppCapItem->cEntries;
  257. /*
  258. * Increment the capability array counter.
  259. */
  260. capability_count++;
  261. }
  262. }
  263. else
  264. {
  265. cbDataSizeToRet = 0;
  266. capabilities_list = NULL;
  267. }
  268. }
  269. else
  270. {
  271. ERROR_OUT(("CAppCap::GetData: Error: data not locked"));
  272. }
  273. return (cbDataSizeToRet);
  274. }
  275. /*
  276. * UnLockCapabilityData ()
  277. *
  278. * Public Function Description:
  279. * This routine decrements the lock count and frees the memory associated
  280. * with the "API" capability once the lock count reaches zero.
  281. */
  282. void CAppCap::UnLockCapabilityData(void)
  283. {
  284. if (Unlock(FALSE) == 0)
  285. {
  286. APP_CAP_ITEM *pAppCapItem;
  287. /*
  288. * Iterate through the list of collapsed capabilities, unlocking the
  289. * data for each CapabilityIDData object associated with each
  290. * capability.
  291. */
  292. m_AppCapItemList.Reset();
  293. while (NULL != (pAppCapItem = m_AppCapItemList.Iterate()))
  294. {
  295. pAppCapItem->pCapID->UnLockCapabilityIdentifierData();
  296. }
  297. }
  298. // we have to call Release() because we used Unlock(FALSE)
  299. Release();
  300. }
  301. APP_CAP_ITEM::APP_CAP_ITEM(GCCCapabilityType eCapType)
  302. :
  303. pCapID(NULL),
  304. eCapType(eCapType),
  305. cEntries(0),
  306. poszAppData(NULL)
  307. {
  308. }
  309. APP_CAP_ITEM::APP_CAP_ITEM(APP_CAP_ITEM *p, PGCCError pError)
  310. : poszAppData(NULL)
  311. {
  312. // First set up the capability id
  313. DBG_SAVE_FILE_LINE
  314. pCapID = new CCapIDContainer(p->pCapID, pError);
  315. if (NULL != pCapID)
  316. {
  317. // Initialize the new capability to default values.
  318. eCapType = p->eCapType;
  319. if (p->eCapType == GCC_UNSIGNED_MINIMUM_CAPABILITY)
  320. {
  321. nUnsignedMinimum = (UINT) -1;
  322. }
  323. else if (p->eCapType == GCC_UNSIGNED_MAXIMUM_CAPABILITY)
  324. {
  325. nUnsignedMaximum = 0;
  326. }
  327. cEntries = p->cEntries;
  328. //
  329. // LONCHANC: We do not copy the entries in application data???
  330. //
  331. *pError = GCC_NO_ERROR;
  332. }
  333. else
  334. {
  335. *pError = GCC_ALLOCATION_FAILURE;
  336. }
  337. }
  338. APP_CAP_ITEM::~APP_CAP_ITEM(void)
  339. {
  340. if (NULL != pCapID)
  341. {
  342. pCapID->Release();
  343. }
  344. delete poszAppData;
  345. }
  346. void CAppCapItemList::DeleteList(void)
  347. {
  348. APP_CAP_ITEM *pAppCapItem;
  349. while (NULL != (pAppCapItem = Get()))
  350. {
  351. delete pAppCapItem;
  352. }
  353. }