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.

421 lines
11 KiB

  1. #include <fusenetincludes.h>
  2. #include <manifestinfo.h>
  3. // Must be in the same order as the MAN_INFO enumeration in fusenet.idl
  4. DWORD CPropertyArray::max_params[MAN_INFO_MAX] = {
  5. MAN_INFO_ASM_FILE_MAX,
  6. MAN_INFO_APPLICATION_MAX,
  7. MAN_INFO_SUBSCRIPTION_MAX,
  8. MAN_INFO_DEPENDANT_ASM_MAX,
  9. MAN_INFO_SOURCE_ASM_MAX,
  10. MAN_INFO_PATCH_INFO_MAX,
  11. };
  12. // ---------------------------------------------------------------------------
  13. // CreatePropertyArray
  14. // ---------------------------------------------------------------------------
  15. STDAPI CreatePropertyArray(DWORD dwType, CPropertyArray** ppPropertyArray)
  16. {
  17. HRESULT hr = S_OK;
  18. MAKE_ERROR_MACROS_STATIC(hr);
  19. CPropertyArray *pPropArray = NULL;
  20. *ppPropertyArray = NULL;
  21. IF_ALLOC_FAILED_EXIT(pPropArray = new (CPropertyArray));
  22. IF_FAILED_EXIT(pPropArray->Init(dwType));
  23. *ppPropertyArray = pPropArray;
  24. pPropArray = NULL;
  25. exit:
  26. SAFEDELETE(pPropArray);
  27. return hr;
  28. }
  29. // ---------------------------------------------------------------------------
  30. // CPropertyArray ctor
  31. // ---------------------------------------------------------------------------
  32. CPropertyArray::CPropertyArray()
  33. : _dwType(0), _rProp(NULL)
  34. {
  35. _dwSig = 'PORP';
  36. }
  37. // ---------------------------------------------------------------------------
  38. // CPropertyArray dtor
  39. // ---------------------------------------------------------------------------
  40. CPropertyArray::~CPropertyArray()
  41. {
  42. for (DWORD i = 0; i < max_params[_dwType]; i++)
  43. {
  44. if (_rProp[i].flag == MAN_INFO_FLAG_IUNKNOWN_PTR)
  45. {
  46. IUnknown *pUnk = ((IUnknown*) _rProp[i].pv);
  47. SAFERELEASE(pUnk);
  48. }
  49. if (_rProp[i].cb > sizeof(DWORD))
  50. SAFEDELETEARRAY(_rProp[i].pv);
  51. }
  52. SAFEDELETEARRAY(_rProp);
  53. }
  54. // ---------------------------------------------------------------------------
  55. // CPropertyArray::Init
  56. // ---------------------------------------------------------------------------
  57. HRESULT CPropertyArray::Init(DWORD dwType)
  58. {
  59. HRESULT hr = S_OK;
  60. MAKE_ERROR_MACROS_STATIC(hr);
  61. _dwType = dwType;
  62. IF_ALLOC_FAILED_EXIT(_rProp = new Property[max_params[dwType]]);
  63. memset(_rProp, 0, max_params[dwType]* sizeof(Property));
  64. exit:
  65. return hr;
  66. }
  67. // ---------------------------------------------------------------------------
  68. // CPropertyArray::Set
  69. // ---------------------------------------------------------------------------
  70. HRESULT CPropertyArray::Set(DWORD PropertyId,
  71. LPVOID pvProperty, DWORD cbProperty, DWORD flag)
  72. {
  73. HRESULT hr = S_OK;
  74. MAKE_ERROR_MACROS_STATIC(hr);
  75. Property *pItem ;
  76. if (PropertyId > max_params[_dwType])
  77. {
  78. hr = E_INVALIDARG;
  79. goto exit;
  80. }
  81. pItem = &(_rProp[PropertyId]);
  82. if (!cbProperty && !pvProperty)
  83. {
  84. if (pItem->cb > sizeof(DWORD))
  85. SAFEDELETEARRAY(pItem->pv);
  86. pItem->pv = NULL;
  87. }
  88. else if (cbProperty > sizeof(DWORD))
  89. {
  90. LPBYTE ptr = NULL;
  91. IF_ALLOC_FAILED_EXIT(ptr = new (BYTE[cbProperty]));
  92. if (pItem->cb > sizeof(DWORD))
  93. SAFEDELETEARRAY(pItem->pv);
  94. memcpy(ptr, pvProperty, cbProperty);
  95. pItem->pv = ptr;
  96. }
  97. else
  98. {
  99. if (pItem->cb > sizeof(DWORD))
  100. SAFEDELETEARRAY(pItem->pv);
  101. memcpy(&(pItem->pv), pvProperty, cbProperty);
  102. }
  103. pItem->cb = cbProperty;
  104. pItem->flag = flag;
  105. exit:
  106. return hr;
  107. }
  108. // ---------------------------------------------------------------------------
  109. // CPropertyArray::Get
  110. // ---------------------------------------------------------------------------
  111. HRESULT CPropertyArray::Get(DWORD PropertyId,
  112. LPVOID pvProperty, LPDWORD pcbProperty, DWORD *flag)
  113. {
  114. HRESULT hr = S_OK;
  115. Property *pItem;
  116. if ((!pvProperty && *pcbProperty) || (PropertyId > max_params[_dwType]))
  117. {
  118. hr = E_INVALIDARG;
  119. goto exit;
  120. }
  121. pItem = &(_rProp[PropertyId]);
  122. if (pItem->cb > *pcbProperty)
  123. hr = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
  124. else if (pItem->cb)
  125. {
  126. memcpy(pvProperty, (pItem->cb > sizeof(DWORD) ?
  127. pItem->pv : (LPBYTE) &(pItem->pv)), pItem->cb);
  128. }
  129. *pcbProperty = pItem->cb;
  130. *flag = pItem->flag;
  131. exit:
  132. return hr;
  133. }
  134. // ---------------------------------------------------------------------------
  135. // GetType
  136. // ---------------------------------------------------------------------------
  137. HRESULT CPropertyArray::GetType(DWORD *pdwType)
  138. {
  139. *pdwType = _dwType;
  140. return S_OK;
  141. }
  142. // ---------------------------------------------------------------------------
  143. // CPropertyArray::operator []
  144. // Wraps DWORD optimization test.
  145. // ---------------------------------------------------------------------------
  146. Property CPropertyArray::operator [] (DWORD PropertyId)
  147. {
  148. Property Prop;
  149. Prop.pv = _rProp[PropertyId].cb > sizeof(DWORD) ?
  150. _rProp[PropertyId].pv : &(_rProp[PropertyId].pv);
  151. Prop.cb = _rProp[PropertyId].cb;
  152. return Prop;
  153. }
  154. // ---------------------------------------------------------------------------
  155. // CreateManifestInfo
  156. // ---------------------------------------------------------------------------
  157. STDAPI CreateManifestInfo(DWORD dwType, LPMANIFEST_INFO* ppManifestInfo)
  158. {
  159. HRESULT hr = S_OK;
  160. MAKE_ERROR_MACROS_STATIC(hr);
  161. CManifestInfo *pManifestInfo = NULL;
  162. IF_ALLOC_FAILED_EXIT(pManifestInfo = new(CManifestInfo));
  163. IF_FAILED_EXIT(pManifestInfo->Init(dwType));
  164. *ppManifestInfo = static_cast<IManifestInfo*> (pManifestInfo);
  165. pManifestInfo = NULL;
  166. exit:
  167. SAFERELEASE(pManifestInfo);
  168. return hr;
  169. }
  170. // ---------------------------------------------------------------------------
  171. // ctor
  172. // ---------------------------------------------------------------------------
  173. CManifestInfo::CManifestInfo()
  174. : _dwSig('INAM'), _cRef(1), _hr(S_OK)
  175. {
  176. }
  177. // ---------------------------------------------------------------------------
  178. // dtor
  179. // ---------------------------------------------------------------------------
  180. CManifestInfo::~CManifestInfo()
  181. {
  182. SAFEDELETE(_properties);
  183. }
  184. // ---------------------------------------------------------------------------
  185. // Set
  186. // ---------------------------------------------------------------------------
  187. HRESULT CManifestInfo::Set(DWORD PropertyId, LPVOID pvProperty, DWORD cbProperty, DWORD flag)
  188. {
  189. IF_FAILED_EXIT( (*_properties).Set(PropertyId, pvProperty, cbProperty, flag));
  190. if (flag == MAN_INFO_FLAG_IUNKNOWN_PTR)
  191. (*(IUnknown**) pvProperty)->AddRef();
  192. exit:
  193. return _hr;
  194. }
  195. // ---------------------------------------------------------------------------
  196. // Get
  197. // ---------------------------------------------------------------------------
  198. HRESULT CManifestInfo::Get(DWORD PropertyId, LPVOID *ppvProperty, DWORD *pcbProperty, DWORD *pflag)
  199. {
  200. DWORD flag;
  201. LPBYTE pbAlloc;
  202. DWORD cbAlloc;
  203. *ppvProperty = NULL;
  204. *pcbProperty = 0;
  205. // Get property size
  206. _hr = (*_properties).Get(PropertyId, NULL, &(cbAlloc = 0), &flag);
  207. if (_hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
  208. {
  209. // Property is set; alloc buf
  210. IF_ALLOC_FAILED_EXIT(pbAlloc = new(BYTE[cbAlloc]));
  211. // Get the property
  212. IF_FAILED_EXIT( (*_properties).Get(PropertyId, pbAlloc, &cbAlloc, &flag));
  213. if (flag == MAN_INFO_FLAG_IUNKNOWN_PTR)
  214. {
  215. memcpy(ppvProperty, pbAlloc, cbAlloc);
  216. ((IUnknown *)(*ppvProperty))-> AddRef();
  217. SAFEDELETEARRAY(pbAlloc);
  218. }
  219. else
  220. *ppvProperty = pbAlloc;
  221. *pcbProperty = cbAlloc;
  222. *pflag = flag;
  223. }
  224. else
  225. {
  226. // If property unset, hr should be S_OK
  227. if (_hr != S_OK)
  228. goto exit;
  229. // Success, returning 0 bytes, ensure buf is null.
  230. *pflag = MAN_INFO_FLAG_UNDEF;
  231. }
  232. exit:
  233. return _hr;
  234. }
  235. // ---------------------------------------------------------------------------
  236. // IsEqual
  237. // As of now, only valid to check equality of MAN_INFO_FILE property bags
  238. // ---------------------------------------------------------------------------
  239. HRESULT CManifestInfo::IsEqual(IManifestInfo *pManifestInfo)
  240. {
  241. _hr = S_OK;
  242. DWORD dwType1, dwType2, cbBuf, dwFlag;
  243. LPWSTR pwzBuf1=NULL, pwzBuf2=NULL;
  244. GetType(&dwType1);
  245. pManifestInfo->GetType(&dwType2);
  246. if (dwType1 != MAN_INFO_FILE && dwType2 != MAN_INFO_FILE)
  247. {
  248. _hr = E_INVALIDARG;
  249. goto exit;
  250. }
  251. for (DWORD i = MAN_INFO_ASM_FILE_NAME; i < MAN_INFO_ASM_FILE_MAX; i++)
  252. {
  253. // BUGBUG?: case sensitivity and issues?
  254. // BUGBUG?: locale?
  255. Get(i, (LPVOID *)&pwzBuf1, &cbBuf, &dwFlag);
  256. pManifestInfo->Get(i, (LPVOID *)&pwzBuf2, &cbBuf, &dwFlag);
  257. if ((pwzBuf1 && !pwzBuf2) || (!pwzBuf1 && pwzBuf2))
  258. _hr= S_FALSE;
  259. if(pwzBuf1 && pwzBuf2)
  260. IF_FAILED_EXIT(FusionCompareString(pwzBuf1, pwzBuf2, 0));
  261. SAFEDELETEARRAY(pwzBuf1);
  262. SAFEDELETEARRAY(pwzBuf2);
  263. // if one entry is false, no need to check the rest
  264. if (_hr == S_FALSE)
  265. break;
  266. }
  267. goto exit;
  268. exit:
  269. return _hr;
  270. }
  271. // ---------------------------------------------------------------------------
  272. // GetType
  273. // ---------------------------------------------------------------------------
  274. HRESULT CManifestInfo::GetType(DWORD *pdwType)
  275. {
  276. DWORD dwType;
  277. _hr = _properties->GetType(&dwType);
  278. *pdwType = dwType;
  279. return _hr;
  280. }
  281. // ---------------------------------------------------------------------------
  282. // Init
  283. // ---------------------------------------------------------------------------
  284. HRESULT CManifestInfo::Init(DWORD dwType)
  285. {
  286. _hr = S_OK;
  287. if (dwType >= MAN_INFO_MAX)
  288. {
  289. _hr = E_INVALIDARG;
  290. goto exit;
  291. }
  292. _hr = CreatePropertyArray(dwType, &_properties);
  293. exit:
  294. return _hr;
  295. }
  296. // IUnknown Boilerplate
  297. // ---------------------------------------------------------------------------
  298. // CManifestInfo::QI
  299. // ---------------------------------------------------------------------------
  300. STDMETHODIMP
  301. CManifestInfo::QueryInterface(REFIID riid, void** ppvObj)
  302. {
  303. if ( IsEqualIID(riid, IID_IUnknown)
  304. || IsEqualIID(riid, IID_IManifestInfo)
  305. )
  306. {
  307. *ppvObj = static_cast<IManifestInfo*> (this);
  308. AddRef();
  309. return S_OK;
  310. }
  311. else
  312. {
  313. *ppvObj = NULL;
  314. return E_NOINTERFACE;
  315. }
  316. }
  317. // ---------------------------------------------------------------------------
  318. // CManifestInfo::AddRef
  319. // ---------------------------------------------------------------------------
  320. STDMETHODIMP_(ULONG)
  321. CManifestInfo::AddRef()
  322. {
  323. return InterlockedIncrement ((LONG*) &_cRef);
  324. }
  325. // ---------------------------------------------------------------------------
  326. // CManifestInfo::Release
  327. // ---------------------------------------------------------------------------
  328. STDMETHODIMP_(ULONG)
  329. CManifestInfo::Release()
  330. {
  331. ULONG lRet = InterlockedDecrement ((LONG*) &_cRef);
  332. if (!lRet)
  333. delete this;
  334. return lRet;
  335. }