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.

466 lines
12 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. ticketSchema.cpp
  5. Abstract:
  6. Implementation of ticket schema lookup
  7. Usage:
  8. Author:
  9. Wei Jiang(weijiang) 15-Jan-2001
  10. Revision History:
  11. 15-Jan-2001 weijiang Created.
  12. --*/
  13. #include "stdafx.h"
  14. #include "ticketschema.h"
  15. #include "BstrDebug.h"
  16. #include <winsock2.h> // u_short, u_long, ntohs, ntohl
  17. #include <crtdbg.h>
  18. #include <pmerrorcodes.h>
  19. #include <time.h>
  20. // #include <pmalerts.h>
  21. CTicketSchema::CTicketSchema()
  22. : m_isOk(FALSE), m_szReason(L"Uninitialized"),
  23. m_numAtts(0), m_attsDef(NULL), m_version(0)
  24. {
  25. }
  26. CTicketSchema::~CTicketSchema()
  27. {
  28. if (m_attsDef != NULL)
  29. delete[] m_attsDef;
  30. }
  31. BOOL CTicketSchema::ReadSchema(MSXML::IXMLElementPtr &root)
  32. {
  33. BOOL bResult = FALSE;
  34. LPTSTR r=NULL; // The current error, if it happens
  35. int cAtts = 0;
  36. MSXML::IXMLElementCollectionPtr atts;
  37. MSXML::IXMLElementPtr pElt;
  38. VARIANT iAtts;
  39. // Type identifiers
  40. try
  41. {
  42. // Ok, now iterate over attributes
  43. atts = root->children;
  44. cAtts = atts->length;
  45. if (cAtts <= 0)
  46. {
  47. _com_issue_error(E_FAIL);
  48. }
  49. if (m_attsDef)
  50. {
  51. delete[] m_attsDef;
  52. //
  53. // Paranoid
  54. //
  55. m_attsDef = NULL;
  56. }
  57. m_attsDef = new TicketFieldDef[cAtts];
  58. if (NULL == m_attsDef)
  59. {
  60. m_isOk = FALSE;
  61. bResult = FALSE;
  62. goto Cleanup;
  63. }
  64. // get name and version info
  65. m_name = root->getAttribute(ATTRNAME_NAME);
  66. _bstr_t aVersion = root->getAttribute(ATTRNAME_VERSION);
  67. if(aVersion.length() != 0)
  68. m_version = (short)_wtol(aVersion);
  69. else
  70. m_version = 0; // invalid
  71. VariantInit(&iAtts);
  72. iAtts.vt = VT_I4;
  73. for (iAtts.lVal = 0; iAtts.lVal < cAtts; iAtts.lVal++)
  74. {
  75. pElt = atts->item(iAtts);
  76. m_attsDef[iAtts.lVal].name = pElt->getAttribute(ATTRNAME_NAME);
  77. _bstr_t aType = pElt->getAttribute(ATTRNAME_TYPE);
  78. _bstr_t aFlags = pElt->getAttribute(ATTRNAME_FLAGS);
  79. // find out the type information
  80. m_attsDef[iAtts.lVal].type = tInvalid;
  81. if(aType.length() != 0)
  82. {
  83. for(int i = 0; i < (sizeof(TicketTypeNameMap) / sizeof(CTicketTypeNameMap)); ++i)
  84. {
  85. if(_wcsicmp(aType, TicketTypeNameMap[i].name) == 0)
  86. {
  87. m_attsDef[iAtts.lVal].type = TicketTypeNameMap[i].type;
  88. break;
  89. }
  90. }
  91. }
  92. // flags
  93. if(aFlags.length() != 0)
  94. m_attsDef[iAtts.lVal].flags = _wtol(aFlags);
  95. else
  96. m_attsDef[iAtts.lVal].flags = 0;
  97. }
  98. m_numAtts = iAtts.lVal;
  99. bResult = m_isOk = TRUE;
  100. }
  101. catch (_com_error &e)
  102. {
  103. if (m_attsDef)
  104. {
  105. delete[] m_attsDef;
  106. //
  107. // Paranoid
  108. //
  109. m_attsDef = NULL;
  110. }
  111. bResult = m_isOk = FALSE;
  112. }
  113. Cleanup:
  114. return bResult;
  115. }
  116. HRESULT CTicketSchema::parseTicket(LPCSTR raw, UINT size, CTicketPropertyBag& bag)
  117. {
  118. DWORD cParsed = 0;
  119. HRESULT hr = S_OK;
  120. LPBYTE dataToParse = (LPBYTE)raw;
  121. UINT cDataToParse = size;
  122. //
  123. // Make sure the data passed in is good.
  124. // maskF.Parse doesn't validate the parameter.
  125. //
  126. if (IsBadReadPtr(raw, size)) return E_INVALIDARG;
  127. // then the schema version #
  128. if(cDataToParse > 2) // enough for version
  129. {
  130. unsigned short * p = (unsigned short *)(dataToParse);
  131. if (m_version < VALID_SCHEMA_VERSION_MIN || m_version > VALID_SCHEMA_VERSION_MAX)
  132. return S_FALSE; // not able to process with this version of ppm
  133. dataToParse += 2;
  134. cDataToParse -= 2;
  135. }
  136. // then the maskK
  137. CTicketFieldMasks maskF;
  138. hr = maskF.Parse(dataToParse, cDataToParse, &cParsed);
  139. if(hr != S_OK)
  140. return hr;
  141. // pointer advances
  142. dataToParse += cParsed;
  143. cDataToParse -= cParsed;
  144. USHORT* pIndexes = maskF.GetIndexes();
  145. DWORD type = 0;
  146. DWORD flags = 0;
  147. DWORD fSize = 0;
  148. variant_t value;
  149. u_short slen;
  150. u_long llen;
  151. USHORT index = MASK_INDEX_INVALID;
  152. // then the data
  153. // get items that enabled by the schema
  154. while((index = *pIndexes) != MASK_INDEX_INVALID && cDataToParse > 0)
  155. {
  156. TicketProperty prop;
  157. // if index is out of schema range
  158. if (index >= m_numAtts) break;
  159. // fill-in the offset of the property
  160. prop.offset = dataToParse - (LPBYTE)raw;
  161. // type
  162. type = m_attsDef[index].type;
  163. fSize = TicketTypeSizes[type];
  164. switch (type)
  165. {
  166. case tText:
  167. {
  168. //
  169. // due to IA64 alignment faults this memcpy needs to be performed
  170. //
  171. memcpy((PBYTE)&slen, dataToParse, sizeof(slen));
  172. slen = ntohs(slen);
  173. value.vt = VT_BSTR;
  174. if (slen == 0)
  175. {
  176. value.bstrVal = ALLOC_AND_GIVEAWAY_BSTR_LEN(L"", 0);
  177. }
  178. else
  179. {
  180. int wlen = MultiByteToWideChar(CP_UTF8, 0,
  181. (LPCSTR)dataToParse+sizeof(u_short),
  182. slen, NULL, 0);
  183. if (!wlen) {
  184. //
  185. // BUGBUG:
  186. // What should we do here? free all the previously allocated memory?
  187. // The original code was not doing that. See case default below. Keep
  188. // the data parsed so far? That seems the original logic. This needs to
  189. // further looked at.
  190. //
  191. return HRESULT_FROM_WIN32(GetLastError());
  192. }
  193. value.bstrVal = ALLOC_AND_GIVEAWAY_BSTR_LEN(NULL, wlen);
  194. if (!MultiByteToWideChar(
  195. CP_UTF8,
  196. 0,
  197. (LPCSTR)dataToParse+sizeof(u_short),
  198. slen,
  199. value.bstrVal,
  200. wlen))
  201. {
  202. FREE_BSTR(value.bstrVal);
  203. return HRESULT_FROM_WIN32(GetLastError());
  204. }
  205. value.bstrVal[wlen] = L'\0';
  206. }
  207. dataToParse += slen + sizeof(u_short);
  208. cDataToParse -= slen + sizeof(u_short);
  209. }
  210. break;
  211. case tChar:
  212. _ASSERTE(0); // NEED MORE THOUGHT -- IF unicode makes more sense
  213. /*
  214. {
  215. int wlen = MultiByteToWideChar(CP_UTF8, 0,
  216. raw+m_pos[index],
  217. m_schema->GetByteSize(index), NULL, 0);
  218. pVal->vt = VT_BSTR;
  219. pVal->bstrVal = ALLOC_AND_GIVEAWAY_BSTR_LEN(NULL, wlen);
  220. MultiByteToWideChar(CP_UTF8, 0,
  221. raw+m_pos[index],
  222. m_schema->GetByteSize(index), pVal->bstrVal, wlen);
  223. pVal->bstrVal[wlen] = L'\0';
  224. }
  225. */
  226. break;
  227. case tByte:
  228. value.vt = VT_I2;
  229. value.iVal = *(BYTE*)(dataToParse);
  230. break;
  231. case tWord:
  232. value.vt = VT_I2;
  233. //
  234. // due to IA64 alignment faults this memcpy needs to be performed
  235. //
  236. memcpy((PBYTE)slen, dataToParse, sizeof(slen));
  237. value.iVal = ntohs(slen);
  238. break;
  239. case tLong:
  240. value.vt = VT_I4;
  241. //
  242. // due to IA64 alignment faults this memcpy needs to be performed
  243. //
  244. memcpy((PBYTE)&llen, dataToParse, sizeof(llen));
  245. value.lVal = ntohl(llen);
  246. break;
  247. case tDate:
  248. value.vt = VT_DATE;
  249. //
  250. // due to IA64 alignment faults this memcpy needs to be performed
  251. //
  252. memcpy((PBYTE)&llen, dataToParse, sizeof(llen));
  253. llen = ntohl(llen);
  254. VarDateFromI4(llen, &(value.date));
  255. break;
  256. default:
  257. return PP_E_BAD_DATA_FORMAT;
  258. }
  259. // now with name, flags, value, type, we can put it into property bag
  260. // name, flags, value
  261. prop.flags = m_attsDef[index].flags;
  262. prop.type = type;
  263. prop.value.Attach(value.Detach());
  264. bag.PutProperty(m_attsDef[index].name, prop);
  265. // for text data, the pointer was already adjusted
  266. if (fSize != SIZE_TEXT)
  267. {
  268. dataToParse += fSize;
  269. cDataToParse -= fSize;
  270. }
  271. ++pIndexes;
  272. }
  273. return S_OK;
  274. }
  275. //
  276. //
  277. // Ticket property bag
  278. //
  279. CTicketPropertyBag::CTicketPropertyBag()
  280. {
  281. }
  282. CTicketPropertyBag::~CTicketPropertyBag()
  283. {
  284. }
  285. HRESULT CTicketPropertyBag::GetProperty(LPCWSTR name, TicketProperty& prop)
  286. {
  287. HRESULT hr = S_OK;
  288. if(!name || (!*name))
  289. return E_INVALIDARG;
  290. TicketPropertyMap::iterator i;
  291. i = m_props.find(name);
  292. if(i!= m_props.end())
  293. prop = i->second;
  294. else
  295. hr = S_FALSE;
  296. return hr;
  297. }
  298. HRESULT CTicketPropertyBag::PutProperty(LPCWSTR name, const TicketProperty& prop)
  299. {
  300. HRESULT hr = S_OK;
  301. if(!name || (!*name))
  302. return E_INVALIDARG;
  303. try{
  304. m_props[name] = prop;
  305. }
  306. catch (...)
  307. {
  308. hr = E_OUTOFMEMORY;
  309. }
  310. return hr;
  311. }
  312. //
  313. //
  314. // class CTicketFieldMasks
  315. //
  316. inline HRESULT CTicketFieldMasks::Parse(PBYTE masks, ULONG size, ULONG* pcParsed) throw()
  317. {
  318. _ASSERT(pcParsed && masks);
  319. // 16 bits as a unit of masks
  320. *pcParsed = 0;
  321. if (!masks || size < 2) return E_INVALIDARG;
  322. // validate the masks
  323. PBYTE p = masks;
  324. ULONG totalMasks = 15;
  325. BOOL fContinue = FALSE;
  326. u_short mask;
  327. *pcParsed += 2;
  328. // find out size
  329. //
  330. // due to IA64 alignment faults this memcpy needs to be performed
  331. //
  332. memcpy((PBYTE)&mask, p, sizeof(u_short));
  333. p += 2;
  334. fContinue = MORE_MASKUNIT(ntohs(mask));
  335. while(fContinue) //the folling short is mask unit
  336. {
  337. totalMasks += 15;
  338. // insufficient data in buffer
  339. if (*pcParsed + 2 > size) return E_INVALIDARG;
  340. *pcParsed += 2;
  341. //
  342. // due to IA64 alignment faults this memcpy needs to be performed
  343. //
  344. memcpy((PBYTE)&mask, p, sizeof(u_short));
  345. p += 2;
  346. fContinue = MORE_MASKUNIT(ntohs(mask));
  347. }
  348. if(m_fieldIndexes) delete[] m_fieldIndexes;
  349. m_fieldIndexes = new unsigned short[totalMasks]; // max number of mask bits
  350. if (NULL == m_fieldIndexes)
  351. {
  352. return E_OUTOFMEMORY;
  353. }
  354. for ( unsigned int i = 0; i < totalMasks; ++i)
  355. {
  356. m_fieldIndexes[i] = MASK_INDEX_INVALID;
  357. }
  358. p = masks;
  359. unsigned short index = 0;
  360. totalMasks = 0;
  361. // fill in the mask
  362. do
  363. {
  364. //
  365. // due to IA64 alignment faults this memcpy needs to be performed
  366. //
  367. memcpy((PBYTE)&mask, p, sizeof(u_short));
  368. p += 2;
  369. mask = ntohs(mask);
  370. //// find the bits
  371. if (mask & 0x7fff) // any 1s
  372. {
  373. unsigned short j = 0x0001;
  374. while( j != 0x8000 )
  375. {
  376. if(j & mask)
  377. m_fieldIndexes[totalMasks++] = index;
  378. ++index;
  379. j <<= 1;
  380. }
  381. }
  382. else
  383. index += 15;
  384. } while(MORE_MASKUNIT(mask)); //the folling short is mask unit
  385. return S_OK;
  386. }