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.

380 lines
11 KiB

  1. #include <fusenetincludes.h>
  2. #include <manifestdata.h>
  3. // special key for data type
  4. LPCWSTR pcwzManifestDataType = L"_t";
  5. #define DATA_TABLE_ARRAY_SIZE 0x08
  6. // ---------------------------------------------------------------------------
  7. // CManifestDataObject ctor
  8. // ---------------------------------------------------------------------------
  9. CManifestDataObject::CManifestDataObject()
  10. : _dwSig('JBOD'), _hr(S_OK), _dwType(MAN_DATA_TYPE_UNDEF),
  11. _pIUnknownData(NULL), _dwData(0)
  12. {
  13. }
  14. // ---------------------------------------------------------------------------
  15. // CManifestDataObject dtor
  16. // ---------------------------------------------------------------------------
  17. CManifestDataObject::~CManifestDataObject()
  18. {
  19. if (_dwType == MAN_DATA_TYPE_IUNKNOWN_PTR)
  20. SAFERELEASE(_pIUnknownData);
  21. }
  22. // ISSUE not support remove property
  23. // no this Property CPropertyArray::operator [] (DWORD PropertyId)
  24. // probably not the best for iunknown* or DWORD properties
  25. // no need to SAFEDELETEARRAY for bool/dword types
  26. // work slightly differently if setting IUnknown* (pass (LPVOID) pUnkwn)
  27. // ---------------------------------------------------------------------------
  28. // CManifestDataObject::Set
  29. // ---------------------------------------------------------------------------
  30. HRESULT CManifestDataObject::Set(LPVOID pvProperty, DWORD cbProperty, DWORD dwType)
  31. {
  32. _dwType = MAN_DATA_TYPE_UNDEF;
  33. SAFERELEASE(_pIUnknownData);
  34. if (dwType == MAN_DATA_TYPE_LPWSTR)
  35. {
  36. DWORD dwLen = cbProperty/sizeof(WCHAR);
  37. IF_FALSE_EXIT(dwLen >= 1, E_INVALIDARG);
  38. IF_FALSE_EXIT(((LPCWSTR)pvProperty)[dwLen-1] == L'\0', E_INVALIDARG);
  39. IF_FAILED_EXIT(_sData.Assign(((LPCWSTR)pvProperty), dwLen));
  40. }
  41. else if (dwType == MAN_DATA_TYPE_IUNKNOWN_PTR)
  42. {
  43. IF_FALSE_EXIT(cbProperty == sizeof(LPVOID), E_INVALIDARG);
  44. _pIUnknownData = (IUnknown*) pvProperty;
  45. _pIUnknownData->AddRef();
  46. }
  47. else if (dwType == MAN_DATA_TYPE_DWORD
  48. || dwType == MAN_DATA_TYPE_ENUM)
  49. {
  50. _dwData = *((LPDWORD)pvProperty);
  51. }
  52. else if (dwType == MAN_DATA_TYPE_BOOL)
  53. {
  54. _dwData = *((LPBOOL)pvProperty);
  55. }
  56. else
  57. {
  58. IF_FAILED_EXIT(E_INVALIDARG);
  59. }
  60. _dwType = dwType;
  61. _hr = S_OK;
  62. exit:
  63. return _hr;
  64. }
  65. // ---------------------------------------------------------------------------
  66. // CManifestDataObject::Get
  67. // ---------------------------------------------------------------------------
  68. HRESULT CManifestDataObject::Get(LPVOID *ppvProperty, DWORD *pcbProperty, DWORD *pdwType)
  69. {
  70. if (_dwType == MAN_DATA_TYPE_LPWSTR)
  71. {
  72. CString sValue;
  73. IF_FAILED_EXIT(sValue.Assign(_sData));
  74. IF_FAILED_EXIT(sValue.ReleaseOwnership((LPWSTR*)ppvProperty));
  75. *pcbProperty = sValue.ByteCount();
  76. }
  77. else if (_dwType == MAN_DATA_TYPE_IUNKNOWN_PTR)
  78. {
  79. *ppvProperty = _pIUnknownData;
  80. *pcbProperty = sizeof(IUnknown*);
  81. _pIUnknownData->AddRef();
  82. }
  83. else if (_dwType == MAN_DATA_TYPE_BOOL)
  84. {
  85. BOOL *pbData = NULL;
  86. IF_ALLOC_FAILED_EXIT(pbData = new BOOL);
  87. *pbData = _dwData;
  88. *ppvProperty = pbData;
  89. *pcbProperty = sizeof(BOOL);
  90. }
  91. else if (_dwType == MAN_DATA_TYPE_DWORD || _dwType == MAN_DATA_TYPE_ENUM)
  92. {
  93. DWORD *pdwData = NULL;
  94. IF_ALLOC_FAILED_EXIT(pdwData = new DWORD);
  95. *pdwData = _dwData;
  96. *ppvProperty = pdwData;
  97. *pcbProperty = sizeof(DWORD);
  98. }
  99. else
  100. {
  101. IF_FAILED_EXIT(E_FAIL);
  102. }
  103. *pdwType = _dwType;
  104. _hr = S_OK;
  105. exit:
  106. return _hr;
  107. }
  108. // ---------------------------------------------------------------------------
  109. // CManifestDataObject::Assign
  110. // ---------------------------------------------------------------------------
  111. HRESULT CManifestDataObject::Assign(CManifestDataObject& dataObj)
  112. {
  113. if (_dwType == MAN_DATA_TYPE_IUNKNOWN_PTR)
  114. SAFERELEASE(_pIUnknownData);
  115. _sData.FreeBuffer();
  116. if (dataObj._sData.CharCount() != 0)
  117. IF_FAILED_EXIT(_sData.Assign(dataObj._sData));
  118. _pIUnknownData = dataObj._pIUnknownData;
  119. if (_pIUnknownData)
  120. _pIUnknownData->AddRef();
  121. _dwData = dataObj._dwData;
  122. _dwType = dataObj._dwType;
  123. _hr = S_OK;
  124. exit:
  125. return _hr;
  126. }
  127. // ---------------------------------------------------------------------------
  128. // CreateManifestData
  129. // ---------------------------------------------------------------------------
  130. STDAPI CreateManifestData(LPCWSTR pwzDataType, LPMANIFEST_DATA* ppManifestData)
  131. {
  132. HRESULT hr = S_OK;
  133. MAKE_ERROR_MACROS_STATIC(hr);
  134. DWORD dwLen = 0;
  135. CManifestData *pManifestData = NULL;
  136. IF_ALLOC_FAILED_EXIT(pManifestData = new(CManifestData));
  137. IF_FAILED_EXIT(pManifestData->Init());
  138. dwLen = lstrlen(pwzDataType);
  139. IF_FALSE_EXIT(dwLen < dwLen+1, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
  140. dwLen++;
  141. IF_FAILED_EXIT(pManifestData->Set(pcwzManifestDataType, (LPVOID)pwzDataType, dwLen*sizeof(WCHAR), MAN_DATA_TYPE_LPWSTR));
  142. *ppManifestData = static_cast<IManifestData*> (pManifestData);
  143. pManifestData = NULL;
  144. exit:
  145. SAFERELEASE(pManifestData);
  146. return hr;
  147. }
  148. // ---------------------------------------------------------------------------
  149. // ctor
  150. // ---------------------------------------------------------------------------
  151. CManifestData::CManifestData()
  152. : _dwSig('DNAM'), _cRef(1), _hr(S_OK)
  153. {
  154. }
  155. // ---------------------------------------------------------------------------
  156. // dtor
  157. // ---------------------------------------------------------------------------
  158. CManifestData::~CManifestData()
  159. {
  160. }
  161. // ---------------------------------------------------------------------------
  162. // Init
  163. // ---------------------------------------------------------------------------
  164. HRESULT CManifestData::Init()
  165. {
  166. _hr = _DataTable.Init(DATA_TABLE_ARRAY_SIZE);
  167. return _hr;
  168. }
  169. // ---------------------------------------------------------------------------
  170. // Set
  171. // ---------------------------------------------------------------------------
  172. HRESULT CManifestData::Set(LPCWSTR pwzPropertyId, LPVOID pvProperty, DWORD cbProperty, DWORD dwType)
  173. {
  174. CString sId;
  175. CManifestDataObject DataObj;
  176. IF_NULL_EXIT(pvProperty, E_INVALIDARG);
  177. IF_FALSE_EXIT(cbProperty>0, E_INVALIDARG);
  178. IF_FALSE_EXIT(dwType<MAN_DATA_TYPE_MAX, E_INVALIDARG);
  179. IF_NULL_EXIT(pwzPropertyId, E_INVALIDARG);
  180. IF_FAILED_EXIT(sId.Assign((LPWSTR)pwzPropertyId));
  181. IF_FAILED_EXIT(DataObj.Set(pvProperty, cbProperty, dwType));
  182. IF_FAILED_EXIT(_DataTable.Insert(sId, DataObj));
  183. exit:
  184. return _hr;
  185. }
  186. // ---------------------------------------------------------------------------
  187. // Get
  188. // ---------------------------------------------------------------------------
  189. HRESULT CManifestData::Get(LPCWSTR pwzPropertyId, LPVOID *ppvProperty, DWORD *pcbProperty, DWORD *pdwType)
  190. {
  191. CString sId;
  192. CManifestDataObject* pDataObj = NULL;
  193. IF_NULL_EXIT(ppvProperty, E_INVALIDARG);
  194. *ppvProperty = NULL;
  195. IF_NULL_EXIT(pcbProperty, E_INVALIDARG);
  196. *pcbProperty = 0;
  197. IF_NULL_EXIT(pdwType, E_INVALIDARG);
  198. *pdwType = MAN_DATA_TYPE_UNDEF;
  199. IF_NULL_EXIT(pwzPropertyId, E_INVALIDARG);
  200. IF_FAILED_EXIT(sId.Assign((LPWSTR) pwzPropertyId));
  201. IF_FAILED_EXIT(_DataTable.Retrieve(sId, &pDataObj));
  202. if (_hr == S_OK)
  203. {
  204. IF_FAILED_EXIT(pDataObj->Get(ppvProperty, pcbProperty, pdwType));
  205. }
  206. else
  207. _hr = S_OK; // if not found, return *ppvProperty == NULL
  208. exit:
  209. return _hr;
  210. }
  211. // ---------------------------------------------------------------------------
  212. // Set
  213. // ---------------------------------------------------------------------------
  214. HRESULT CManifestData::Set(DWORD dwPropertyIndex, LPVOID pvProperty, DWORD cbProperty, DWORD dwType)
  215. {
  216. // indexed insert - note: this is not as optimizied as a normal array would, due to the use of CStrings as keys
  217. CString sId;
  218. WCHAR wzId[3] = {L'\0', L'\0', L'\0'};
  219. CManifestDataObject DataObj;
  220. IF_NULL_EXIT(pvProperty, E_INVALIDARG);
  221. IF_FALSE_EXIT(cbProperty>0, E_INVALIDARG);
  222. IF_FALSE_EXIT(dwType<MAN_DATA_TYPE_MAX, E_INVALIDARG);
  223. wzId[0] = LOWORD(dwPropertyIndex);
  224. wzId[1] = HIWORD(dwPropertyIndex);
  225. IF_FAILED_EXIT(sId.Assign(wzId));
  226. IF_FAILED_EXIT(DataObj.Set(pvProperty, cbProperty, dwType));
  227. IF_FAILED_EXIT(_DataTable.Insert(sId, DataObj));
  228. exit:
  229. return _hr;
  230. }
  231. // ---------------------------------------------------------------------------
  232. // Get
  233. // ---------------------------------------------------------------------------
  234. HRESULT CManifestData::Get(DWORD dwPropertyIndex, LPVOID *ppvProperty, DWORD *pcbProperty, DWORD *pdwType)
  235. {
  236. // indexed retrieve
  237. CString sId;
  238. WCHAR wzId[3] = {L'\0', L'\0', L'\0'};
  239. CManifestDataObject* pDataObj = NULL;
  240. IF_NULL_EXIT(ppvProperty, E_INVALIDARG);
  241. *ppvProperty = NULL;
  242. IF_NULL_EXIT(pcbProperty, E_INVALIDARG);
  243. *pcbProperty = 0;
  244. IF_NULL_EXIT(pdwType, E_INVALIDARG);
  245. *pdwType = MAN_DATA_TYPE_UNDEF;
  246. wzId[0] = LOWORD(dwPropertyIndex);
  247. wzId[1] = HIWORD(dwPropertyIndex);
  248. IF_FAILED_EXIT(sId.Assign(wzId));
  249. IF_FAILED_EXIT(_DataTable.Retrieve(sId, &pDataObj));
  250. if (_hr == S_OK)
  251. {
  252. IF_FAILED_EXIT(pDataObj->Get(ppvProperty, pcbProperty, pdwType));
  253. }
  254. else
  255. _hr = S_OK; // if not found, return *ppvProperty == NULL
  256. exit:
  257. return _hr;
  258. }
  259. // ---------------------------------------------------------------------------
  260. // GetType
  261. // ---------------------------------------------------------------------------
  262. HRESULT CManifestData::GetType(LPWSTR *ppwzType)
  263. {
  264. DWORD cbProperty = 0;
  265. DWORD dwType = 0;
  266. IF_FAILED_EXIT(Get(pcwzManifestDataType, (LPVOID*) ppwzType, &cbProperty, &dwType));
  267. IF_FALSE_EXIT(dwType == MAN_DATA_TYPE_LPWSTR, E_FAIL);
  268. exit:
  269. return _hr;
  270. }
  271. // IUnknown Boilerplate
  272. // ---------------------------------------------------------------------------
  273. // CManifestData::QI
  274. // ---------------------------------------------------------------------------
  275. STDMETHODIMP
  276. CManifestData::QueryInterface(REFIID riid, void** ppvObj)
  277. {
  278. if ( IsEqualIID(riid, IID_IUnknown)
  279. || IsEqualIID(riid, IID_IManifestData)
  280. )
  281. {
  282. *ppvObj = static_cast<IManifestData*> (this);
  283. AddRef();
  284. _hr = S_OK;
  285. }
  286. else
  287. {
  288. *ppvObj = NULL;
  289. _hr = E_NOINTERFACE;
  290. }
  291. return _hr;
  292. }
  293. // ---------------------------------------------------------------------------
  294. // CManifestData::AddRef
  295. // ---------------------------------------------------------------------------
  296. STDMETHODIMP_(ULONG)
  297. CManifestData::AddRef()
  298. {
  299. return InterlockedIncrement ((LONG*) &_cRef);
  300. }
  301. // ---------------------------------------------------------------------------
  302. // CManifestData::Release
  303. // ---------------------------------------------------------------------------
  304. STDMETHODIMP_(ULONG)
  305. CManifestData::Release()
  306. {
  307. ULONG lRet = InterlockedDecrement ((LONG*) &_cRef);
  308. if (!lRet)
  309. delete this;
  310. return lRet;
  311. }