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.

224 lines
5.3 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////
  2. // CRGSBag.cpp : Implementation for Read Only property bag on .RGS script fragment
  3. // Copyright (c) Microsoft Corporation 2000.
  4. #include "stdafx.h"
  5. #include "rgsbag.h"
  6. using namespace ::ATL::ATL;
  7. CRGSBag::CRGSBag(LPCTSTR szRGS, CRegObject& croi, int& cchEaten) : CRegParser(&croi) {
  8. TCHAR szToken[MAX_VALUE];
  9. HRESULT hr = S_OK;
  10. LPTSTR szReg = NULL;
  11. hr = PreProcessBuffer(szRGS, &szReg);
  12. if (FAILED(hr)) {
  13. THROWCOM(hr);
  14. }
  15. #if defined(_DEBUG) && defined(DEBUG_REGISTRATION)
  16. OutputDebugString(szReg); //would call ATLTRACE but szReg is > 512 bytes
  17. OutputDebugString(_T("\n"));
  18. #endif //_DEBUG
  19. szToken[0] = 0;
  20. m_pchCur = szReg;
  21. cchEaten = 0;
  22. try {
  23. while (NULL != *m_pchCur && chRightBracket != *szToken) {
  24. if (FAILED(hr = NextToken(szToken))) {
  25. break;
  26. }
  27. if (chLeftBracket != *szToken)
  28. {
  29. ATLTRACE2(atlTraceRegistrar, 0, _T("Syntax error, expecting a {, found a %s\n"), szToken);
  30. hr = GenerateError(E_ATL_MISSING_OPENKEY_TOKEN);
  31. THROWCOM(hr);
  32. }
  33. hr = BuildMapFromFragment(szToken);
  34. if (FAILED(hr)) {
  35. THROWCOM(hr);
  36. }
  37. }
  38. if (NULL != *m_pchCur) {
  39. m_pchCur = CharNext(m_pchCur); // eat the }
  40. }
  41. cchEaten = m_pchCur - szReg;
  42. if (szReg) {
  43. CoTaskMemFree(szReg);
  44. szReg = NULL;
  45. }
  46. } catch(ComException &e) {
  47. if (szReg) {
  48. CoTaskMemFree(szReg);
  49. szReg = NULL;
  50. }
  51. throw;
  52. }
  53. }
  54. HRESULT CRGSBag::BuildMapFromFragment(LPTSTR pszToken) {
  55. HRESULT hr = S_OK;
  56. if (FAILED(hr = NextToken(pszToken)))
  57. return hr;
  58. while (*pszToken != chRightBracket) // Continue till we see a }
  59. {
  60. TCHAR szValueName[MAX_VALUE];
  61. CComVariant v;
  62. if (!lstrcmpi(pszToken, szValToken)) // need to add a value to hkParent
  63. {
  64. if (FAILED(hr = NextToken(szValueName)))
  65. break;
  66. if (FAILED(hr = NextToken(pszToken)))
  67. break;
  68. if (*pszToken != chEquals)
  69. return GenerateError(E_ATL_EXPECTING_EQUAL);
  70. hr = GetValue(v);
  71. if (FAILED(hr)) {
  72. return hr;
  73. }
  74. } else {
  75. if (StrChr(pszToken, chDirSep) != NULL)
  76. return GenerateError(E_ATL_COMPOUND_KEY);
  77. lstrcpyn(szValueName, pszToken, sizeof(szValueName) / sizeof(TCHAR));
  78. hr = GetObject(v);
  79. if (FAILED(hr)) {
  80. return hr;
  81. }
  82. }
  83. m_mapBag[szValueName] = v;
  84. if (FAILED(hr = NextToken(pszToken)))
  85. break;
  86. }
  87. return hr;
  88. }
  89. HRESULT CRGSBag::GetObject(CComVariant& val) {
  90. ASSERT(val.vt == VT_EMPTY || val.vt == VT_NULL);
  91. val.vt = VT_UNKNOWN;
  92. val.punkVal = NULL;
  93. HRESULT hr;
  94. TCHAR szToken[MAX_VALUE];
  95. if (FAILED(hr = NextToken(szToken)))
  96. return hr;
  97. if (*szToken != chEquals) {
  98. return GenerateError(E_ATL_EXPECTING_EQUAL);
  99. }
  100. // currently we're just expecting a guid here with no type specifier(s'')
  101. // we should really take genuine .rgs syntax and report an error if it isn't a string
  102. if (FAILED(hr = NextToken(szToken))) {
  103. return GenerateError(CO_E_CLASSSTRING);
  104. }
  105. USES_CONVERSION;
  106. GUID2 clsid(T2COLE(szToken));
  107. PUnknown pobj(clsid, NULL, CLSCTX_INPROC_SERVER);
  108. if (!pobj) {
  109. return REGDB_E_CLASSNOTREG;
  110. }
  111. hr = LoadPersistedObject<PQPropertyBag2, PQPersistPropertyBag2> (pobj, *m_pRegObj, &m_pchCur);
  112. if (FAILED(hr)) {
  113. hr = LoadPersistedObject<PQPropertyBag, PQPersistPropertyBag> (pobj, *m_pRegObj, &m_pchCur);
  114. if (FAILED(hr)) {
  115. return hr;
  116. }
  117. }
  118. val.punkVal = pobj;
  119. (val.punkVal)->AddRef();
  120. return NOERROR;
  121. }
  122. HRESULT CRGSBag::GetValue(CComVariant &val) {
  123. USES_CONVERSION;
  124. HRESULT hr;
  125. VARTYPE vt;
  126. LONG lRes = ERROR_SUCCESS;
  127. UINT nIDRes = 0;
  128. TCHAR* pszToken = new TCHAR[MAX_TYPE];
  129. if (!pszToken) {
  130. return E_OUTOFMEMORY;
  131. }
  132. if (FAILED(hr = NextToken(pszToken))) {
  133. delete[] pszToken;
  134. return hr;
  135. }
  136. if (!VTFromRegType(pszToken, vt))
  137. {
  138. ATLTRACE2(atlTraceRegistrar, 0, _T("%s Type not supported\n"), pszToken);
  139. delete[] pszToken;
  140. return GenerateError(E_ATL_TYPE_NOT_SUPPORTED);
  141. }
  142. if (FAILED(hr = NextToken(pszToken))) {
  143. delete[] pszToken;
  144. return hr;
  145. }
  146. switch (vt)
  147. {
  148. case VT_BSTR:
  149. val.vt = VT_BSTR;
  150. ASSERT(val.bstrVal == NULL);
  151. val.bstrVal = ::SysAllocString(T2OLE(pszToken));
  152. break;
  153. case VT_UI4:
  154. #ifdef _WIN64
  155. ATLASSERT(FALSE);
  156. val.ulVal = 0;
  157. #pragma message( "Still need win64 version of VarUI4FromStr()." )
  158. #else
  159. VarUI4FromStr(T2OLE(pszToken), 0, 0, &val.ulVal);
  160. #endif
  161. val.vt = VT_UI4;
  162. break;
  163. case VT_UI1:
  164. {
  165. int cbValue = lstrlen(pszToken);
  166. if (cbValue & 0x00000001)
  167. {
  168. ATLTRACE2(atlTraceRegistrar, 0, _T("Binary Data does not fall on BYTE boundries\n"));
  169. delete[] pszToken;
  170. return E_FAIL;
  171. }
  172. int cbValDiv2 = cbValue/2;
  173. int cbLen = cbValDiv2 * sizeof(BYTE);
  174. BYTE* rgBinary = new BYTE[cbLen];
  175. if (!rgBinary) {
  176. delete[] pszToken;
  177. return E_OUTOFMEMORY;
  178. }
  179. memset(rgBinary, 0, cbValDiv2);
  180. if (rgBinary == NULL) {
  181. delete[] rgBinary;
  182. delete[] pszToken;
  183. return E_FAIL;
  184. }
  185. for (int irg = 0; irg < cbValue; irg++)
  186. rgBinary[(irg/2)] |= (ChToByte(pszToken[irg])) << (4*(1 - (irg & 0x00000001)));
  187. val.vt = VT_BSTR;
  188. val.bstrVal = ::SysAllocStringByteLen(reinterpret_cast<LPSTR>(rgBinary), cbLen);
  189. delete[] rgBinary;
  190. break;
  191. }
  192. }
  193. delete[] pszToken;
  194. return S_OK;
  195. }
  196. // end of file - crgsbag.cpp