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.

613 lines
14 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. item.cpp
  5. Abstract:
  6. This module contains the implementation for the Server
  7. Extension Object Item class.
  8. Author:
  9. Don Dumitru (dondu@microsoft.com)
  10. Revision History:
  11. dondu 02/18/97 created
  12. --*/
  13. // item.cpp : Implementation of CSEODictionaryItem
  14. #include "stdafx.h"
  15. #include "seodefs.h"
  16. #include "item.h"
  17. static HRESULT VarToIndex(DWORD *pdwIndex, VARIANT *pvarFrom, DWORD dwCount, BOOL bBoundsError=TRUE) {
  18. TraceFunctEnter("VarToIndex");
  19. VARIANT varIndex;
  20. HRESULT hr;
  21. if (!pvarFrom || (pvarFrom->vt == VT_ERROR)) {
  22. if (bBoundsError && !dwCount) {
  23. TraceFunctLeave();
  24. return (SEO_E_NOTPRESENT);
  25. }
  26. *pdwIndex = 0;
  27. TraceFunctLeave();
  28. return (S_OK);
  29. }
  30. if (!dwCount) {
  31. TraceFunctLeave();
  32. return (SEO_E_NOTPRESENT);
  33. }
  34. VariantInit(&varIndex);
  35. if (pvarFrom->vt != VT_I4) {
  36. hr = VariantChangeTypeEx(&varIndex,pvarFrom,LOCALE_NEUTRAL,0,VT_I4);
  37. if (!SUCCEEDED(hr)) {
  38. VariantClear(&varIndex);
  39. TraceFunctLeave();
  40. return (hr);
  41. }
  42. } else {
  43. varIndex.vt = VT_I4;
  44. varIndex.lVal = pvarFrom->lVal;
  45. }
  46. if ((varIndex.iVal < 0) || (bBoundsError && ((DWORD) varIndex.iVal >= dwCount))) {
  47. TraceFunctLeave();
  48. return (SEO_E_NOTPRESENT);
  49. }
  50. *pdwIndex = min(dwCount,(DWORD) varIndex.iVal);
  51. TraceFunctLeave();
  52. return (S_OK);
  53. }
  54. /////////////////////////////////////////////////////////////////////////////
  55. // CSEODictionaryItem
  56. HRESULT CSEODictionaryItem::FinalConstruct() {
  57. HRESULT hrRes;
  58. TraceFunctEnter("CSEODictionaryItem::FinalConstruct");
  59. m_dwCount = 0;
  60. m_pvcValues = NULL;
  61. hrRes = CoCreateFreeThreadedMarshaler(GetControllingUnknown(),&m_pUnkMarshaler.p);
  62. _ASSERTE(!SUCCEEDED(hrRes)||m_pUnkMarshaler);
  63. TraceFunctLeave();
  64. return (SUCCEEDED(hrRes)?S_OK:hrRes);
  65. }
  66. void CSEODictionaryItem::FinalRelease() {
  67. TraceFunctEnter("CSEODictionaryItem::FinalRelease");
  68. if (m_pvcValues) {
  69. DWORD dwIdx;
  70. for (dwIdx=0;dwIdx<m_dwCount;dwIdx++) {
  71. m_pvcValues[dwIdx].~ValueClass();
  72. }
  73. CoTaskMemFree(m_pvcValues);
  74. m_pvcValues = NULL;
  75. }
  76. m_dwCount = 0;
  77. m_pUnkMarshaler.Release();
  78. TraceFunctLeave();
  79. }
  80. HRESULT STDMETHODCALLTYPE CSEODictionaryItem::get_Value(VARIANT *pvarIndex, VARIANT *pvarResult) {
  81. TraceFunctEnter("CSEODictionaryItem::get_Value");
  82. DWORD dwIndex;
  83. HRESULT hr;
  84. if (!pvarResult) {
  85. TraceFunctLeave();
  86. return (E_POINTER);
  87. }
  88. VariantInit(pvarResult);
  89. hr = VarToIndex(&dwIndex,pvarIndex,m_dwCount);
  90. if (!SUCCEEDED(hr)) {
  91. TraceFunctLeave();
  92. return (hr);
  93. }
  94. TraceFunctLeave();
  95. return (m_pvcValues[dwIndex].AsVariant(pvarResult));
  96. }
  97. HRESULT STDMETHODCALLTYPE CSEODictionaryItem::AddValue(VARIANT *pvarIndex, VARIANT *pvarValue) {
  98. TraceFunctEnter("CSEODictionaryItem::AddValue");
  99. DWORD dwIndex;
  100. HRESULT hr;
  101. ValueClass *pvcValue;
  102. if (!pvarValue) {
  103. TraceFunctLeave();
  104. return (E_POINTER);
  105. }
  106. hr = VarToIndex(&dwIndex,pvarIndex,m_dwCount,FALSE);
  107. if (!SUCCEEDED(hr)) {
  108. TraceFunctLeave();
  109. return (hr);
  110. }
  111. hr = AddSlot(&dwIndex,&pvcValue);
  112. if (!SUCCEEDED(hr)) {
  113. TraceFunctLeave();
  114. return (hr);
  115. }
  116. hr = m_pvcValues[dwIndex].Assign(pvarValue);
  117. if (!SUCCEEDED(hr)) {
  118. VARIANT varIndex;
  119. VariantInit(&varIndex);
  120. varIndex.vt = VT_I4;
  121. varIndex.lVal = dwIndex;
  122. DeleteValue(&varIndex);
  123. TraceFunctLeave();
  124. return (hr);
  125. }
  126. TraceFunctLeave();
  127. return (S_OK);
  128. }
  129. HRESULT STDMETHODCALLTYPE CSEODictionaryItem::DeleteValue(VARIANT *pvarIndex) {
  130. TraceFunctEnter("CSEODictionaryItem::DeleteValue");
  131. DWORD dwIndex;
  132. HRESULT hr;
  133. if (!pvarIndex) {
  134. TraceFunctLeave();
  135. return (E_POINTER);
  136. }
  137. hr = VarToIndex(&dwIndex,pvarIndex,m_dwCount);
  138. if (!SUCCEEDED(hr)) {
  139. TraceFunctLeave();
  140. return (hr);
  141. }
  142. m_pvcValues[dwIndex].~ValueClass();
  143. m_dwCount--;
  144. memcpy(&m_pvcValues[dwIndex-1],&m_pvcValues[dwIndex],sizeof(m_pvcValues[0])*(m_dwCount-dwIndex));
  145. TraceFunctLeave();
  146. return (S_OK);
  147. }
  148. HRESULT STDMETHODCALLTYPE CSEODictionaryItem::get_Count(VARIANT *pvarResult) {
  149. TraceFunctEnter("CSEODictionaryItem::get_Count");
  150. if (!pvarResult) {
  151. TraceFunctLeave();
  152. return (E_POINTER);
  153. }
  154. VariantInit(pvarResult);
  155. pvarResult->vt = VT_I4;
  156. pvarResult->lVal = (LONG) m_dwCount;
  157. TraceFunctLeave();
  158. return (S_OK);
  159. }
  160. HRESULT STDMETHODCALLTYPE CSEODictionaryItem::GetStringA(DWORD dwIndex, DWORD *pchCount, LPSTR pszResult) {
  161. TraceFunctEnter("CSEODictionaryItem::GetStringA");
  162. if (dwIndex >= m_dwCount) {
  163. TraceFunctLeave();
  164. return (SEO_E_NOTPRESENT);
  165. }
  166. TraceFunctLeave();
  167. return (m_pvcValues[dwIndex].AsStringA(pchCount,pszResult));
  168. }
  169. HRESULT STDMETHODCALLTYPE CSEODictionaryItem::GetStringW(DWORD dwIndex, DWORD *pchCount, LPWSTR pszResult) {
  170. TraceFunctEnter("CSEODictionaryItem::GetStringW");
  171. if (dwIndex >= m_dwCount) {
  172. TraceFunctLeave();
  173. return (SEO_E_NOTPRESENT);
  174. }
  175. TraceFunctLeave();
  176. return (m_pvcValues[dwIndex].AsStringW(pchCount,pszResult));
  177. }
  178. HRESULT STDMETHODCALLTYPE CSEODictionaryItem::AddStringA(DWORD dwIndex, LPCSTR pszValue) {
  179. TraceFunctEnter("CSEODictionaryItem::AddStringA");
  180. HRESULT hr;
  181. ValueClass *pvcValue;
  182. if (!pszValue) {
  183. TraceFunctLeave();
  184. return (E_POINTER);
  185. }
  186. hr = AddSlot(&dwIndex,&pvcValue);
  187. if (!SUCCEEDED(hr)) {
  188. TraceFunctLeave();
  189. return (hr);
  190. }
  191. hr = m_pvcValues[dwIndex].Assign(pszValue);
  192. if (!SUCCEEDED(hr)) {
  193. VARIANT varIndex;
  194. VariantInit(&varIndex);
  195. varIndex.vt = VT_I4;
  196. varIndex.lVal = dwIndex;
  197. DeleteValue(&varIndex);
  198. TraceFunctLeave();
  199. return (hr);
  200. }
  201. TraceFunctLeave();
  202. return (S_OK);
  203. }
  204. HRESULT STDMETHODCALLTYPE CSEODictionaryItem::AddStringW(DWORD dwIndex, LPCWSTR pszValue) {
  205. TraceFunctEnter("CSEODictionaryItem::AddStringW");
  206. HRESULT hr;
  207. ValueClass *pvcValue;
  208. if (!pszValue) {
  209. TraceFunctLeave();
  210. return (E_POINTER);
  211. }
  212. hr = AddSlot(&dwIndex,&pvcValue);
  213. if (!SUCCEEDED(hr)) {
  214. TraceFunctLeave();
  215. return (hr);
  216. }
  217. hr = m_pvcValues[dwIndex].Assign(pszValue);
  218. if (!SUCCEEDED(hr)) {
  219. VARIANT varIndex;
  220. VariantInit(&varIndex);
  221. varIndex.vt = VT_I4;
  222. varIndex.lVal = dwIndex;
  223. DeleteValue(&varIndex);
  224. TraceFunctLeave();
  225. return (hr);
  226. }
  227. TraceFunctLeave();
  228. return (S_OK);
  229. }
  230. HRESULT CSEODictionaryItem::AddSlot(DWORD *pdwIndex, ValueClass **ppvcResult) {
  231. TraceFunctEnter("CSEODictionaryItem::AddSlot");
  232. LPVOID pvRes;
  233. if (*pdwIndex > m_dwCount) {
  234. *pdwIndex = m_dwCount;
  235. }
  236. pvRes = CoTaskMemRealloc(m_pvcValues,sizeof(m_pvcValues[0])*(m_dwCount+1));
  237. if (!pvRes) {
  238. TraceFunctLeave();
  239. return (E_OUTOFMEMORY);
  240. }
  241. m_pvcValues = (ValueClass *) pvRes;
  242. memcpy(&m_pvcValues[*pdwIndex+1],&m_pvcValues[*pdwIndex],sizeof(m_pvcValues[0])*(m_dwCount-*pdwIndex));
  243. new(&m_pvcValues[*pdwIndex]) ValueClass();
  244. m_dwCount++;
  245. *ppvcResult = &m_pvcValues[*pdwIndex];
  246. TraceFunctLeave();
  247. return (S_OK);
  248. }
  249. CSEODictionaryItem::ValueClass::ValueClass() {
  250. TraceFunctEnter("CSEODictionaryItem::ValueClass::ValueClass");
  251. Init();
  252. TraceFunctLeave();
  253. }
  254. CSEODictionaryItem::ValueClass::ValueClass(ValueClass& vcFrom) {
  255. TraceFunctEnter("CSEODictionaryItem::ValueClass::ValueClass");
  256. Init();
  257. Assign(vcFrom);
  258. TraceFunctLeave();
  259. }
  260. CSEODictionaryItem::ValueClass::~ValueClass() {
  261. TraceFunctEnter("CSEODictionaryItem::ValueClass::~ValueClass");
  262. Clear();
  263. TraceFunctLeave();
  264. }
  265. void CSEODictionaryItem::ValueClass::Init() {
  266. TraceFunctEnter("CSEODictionaryItem::ValueClass::Init");
  267. m_vtValue.veType = veNone;
  268. m_vtValue.pszStringA = NULL;
  269. VariantInit(&m_vtValue.varVARIANT);
  270. TraceFunctLeave();
  271. }
  272. void CSEODictionaryItem::ValueClass::Clear() {
  273. TraceFunctEnter("CSEODictionaryItem::ValueClass::Clear");
  274. m_vtValue.veType = veNone;
  275. if (m_vtValue.pszStringA) {
  276. CoTaskMemFree(m_vtValue.pszStringA);
  277. m_vtValue.pszStringA = NULL;
  278. }
  279. VariantClear(&m_vtValue.varVARIANT);
  280. TraceFunctLeave();
  281. }
  282. HRESULT CSEODictionaryItem::ValueClass::Assign(ValueClass& vcFrom) {
  283. TraceFunctEnter("CSEODictionaryItem::ValueClass::Assign");
  284. if (&vcFrom != this) {
  285. switch (m_vtValue.veType) {
  286. case veStringA:
  287. TraceFunctLeave();
  288. return (Assign(vcFrom.m_vtValue.pszStringA));
  289. case veVARIANT:
  290. TraceFunctLeave();
  291. return (Assign(&vcFrom.m_vtValue.varVARIANT));
  292. }
  293. }
  294. TraceFunctLeave();
  295. return (E_UNEXPECTED);
  296. }
  297. HRESULT CSEODictionaryItem::ValueClass::Assign(LPCSTR pszFromA) {
  298. TraceFunctEnter("CSEODictionaryItem::ValueClass::Assign");
  299. if (!pszFromA) {
  300. TraceFunctLeave();
  301. return (E_POINTER);
  302. }
  303. Clear();
  304. m_vtValue.pszStringA = (LPSTR) CoTaskMemAlloc(strlen(pszFromA)+1);
  305. if (!m_vtValue.pszStringA) {
  306. TraceFunctLeave();
  307. return (E_OUTOFMEMORY);
  308. }
  309. m_vtValue.veType = veStringA;
  310. strcpy(m_vtValue.pszStringA,pszFromA);
  311. TraceFunctLeave();
  312. return (S_OK);
  313. }
  314. HRESULT CSEODictionaryItem::ValueClass::Assign(VARIANT *pvarFrom) {
  315. TraceFunctEnter("CSEODictionaryItem::ValueClass::Assign");
  316. HRESULT hr;
  317. if (!pvarFrom) {
  318. TraceFunctLeave();
  319. return (E_POINTER);
  320. }
  321. Clear();
  322. hr = VariantCopy(&m_vtValue.varVARIANT,pvarFrom);
  323. if (SUCCEEDED(hr)) {
  324. m_vtValue.veType = veVARIANT;
  325. }
  326. TraceFunctLeave();
  327. return (hr);
  328. }
  329. HRESULT CSEODictionaryItem::ValueClass::Assign(LPCWSTR pszFromW) {
  330. TraceFunctEnter("CSEODictionaryItem::ValueClass::Assign");
  331. if (!pszFromW) {
  332. TraceFunctLeave();
  333. return (E_POINTER);
  334. }
  335. Clear();
  336. m_vtValue.varVARIANT.bstrVal = SysAllocString(pszFromW);
  337. if (!m_vtValue.varVARIANT.bstrVal) {
  338. TraceFunctLeave();
  339. return (E_OUTOFMEMORY);
  340. }
  341. m_vtValue.varVARIANT.vt = VT_BSTR;
  342. m_vtValue.veType = veVARIANT;
  343. TraceFunctLeave();
  344. return (S_OK);
  345. }
  346. HRESULT CSEODictionaryItem::ValueClass::AsVariant(VARIANT *pvarResult) {
  347. TraceFunctEnter("CSEODictionaryItem::ValueClass::AsVariant");
  348. if (!pvarResult) {
  349. TraceFunctLeave();
  350. return (E_POINTER);
  351. }
  352. VariantInit(pvarResult);
  353. switch (m_vtValue.veType) {
  354. case veStringA: {
  355. DWORD dwLen = strlen(m_vtValue.pszStringA);
  356. pvarResult->bstrVal = SysAllocStringLen(NULL,dwLen);
  357. if (!pvarResult->bstrVal) {
  358. TraceFunctLeave();
  359. return (E_OUTOFMEMORY);
  360. }
  361. ATLA2WHELPER(pvarResult->bstrVal,m_vtValue.pszStringA,dwLen);
  362. pvarResult->vt = VT_BSTR;
  363. TraceFunctLeave();
  364. return (S_OK);
  365. }
  366. case veVARIANT:
  367. TraceFunctLeave();
  368. return (VariantCopy(pvarResult,&m_vtValue.varVARIANT));
  369. }
  370. TraceFunctLeave();
  371. return (E_UNEXPECTED);
  372. }
  373. HRESULT CSEODictionaryItem::ValueClass::AsStringA(DWORD *pchCount, LPSTR pszResult) {
  374. TraceFunctEnter("CSEODictionaryItem::ValueClass::AsStringA");
  375. if (!pchCount) {
  376. TraceFunctLeave();
  377. return (E_POINTER);
  378. }
  379. switch (m_vtValue.veType) {
  380. case veStringA:
  381. if (pszResult) {
  382. DWORD dwLen = strlen(m_vtValue.pszStringA);
  383. DWORD dwCopy = min(*pchCount,dwLen+1);
  384. BOOL bMoreData = FALSE;
  385. memcpy(pszResult,m_vtValue.pszStringA,dwCopy);
  386. if (dwCopy == *pchCount) {
  387. pszResult[dwCopy-1] = 0;
  388. bMoreData = TRUE;
  389. }
  390. *pchCount = dwCopy;
  391. TraceFunctLeave();
  392. return (bMoreData?SEO_S_MOREDATA:S_OK);
  393. } else {
  394. *pchCount = strlen(m_vtValue.pszStringA) + 1;
  395. TraceFunctLeave();
  396. return (S_OK);
  397. }
  398. case veVARIANT: {
  399. VARIANT varValue;
  400. LPCWSTR pszValue;
  401. HRESULT hr;
  402. VariantInit(&varValue);
  403. if (m_vtValue.varVARIANT.vt != VT_BSTR) {
  404. hr = VariantChangeTypeEx(&varValue,&m_vtValue.varVARIANT,LOCALE_NEUTRAL,0,VT_BSTR);
  405. if (!SUCCEEDED(hr)) {
  406. VariantClear(&varValue);
  407. TraceFunctLeave();
  408. return (hr);
  409. }
  410. pszValue = varValue.bstrVal;
  411. } else {
  412. pszValue = m_vtValue.varVARIANT.bstrVal;
  413. }
  414. if (pszResult) {
  415. DWORD dwLen = wcslen(pszValue);
  416. DWORD dwCopy = min(*pchCount,dwLen+1);
  417. BOOL bMoreData = FALSE;
  418. ATLW2AHELPER(pszResult,pszValue,dwCopy);
  419. VariantClear(&varValue);
  420. if (dwCopy == *pchCount) {
  421. bMoreData = TRUE;
  422. }
  423. *pchCount = dwCopy;
  424. TraceFunctLeave();
  425. return (bMoreData?SEO_S_MOREDATA:S_OK);
  426. } else {
  427. *pchCount = wcslen(pszValue) + 1;
  428. VariantClear(&varValue);
  429. TraceFunctLeave();
  430. return (S_OK);
  431. }
  432. }
  433. }
  434. TraceFunctLeave();
  435. return (E_UNEXPECTED);
  436. }
  437. HRESULT CSEODictionaryItem::ValueClass::AsStringW(DWORD *pchCount, LPWSTR pszResult) {
  438. TraceFunctEnter("CSEODictionaryItem::ValueClass::AsStringW");
  439. if (!pchCount) {
  440. TraceFunctLeave();
  441. return (E_POINTER);
  442. }
  443. switch (m_vtValue.veType) {
  444. case veStringA:
  445. if (pszResult) {
  446. DWORD dwLen = strlen(m_vtValue.pszStringA);
  447. DWORD dwCopy = min(*pchCount,dwLen+1);
  448. BOOL bMoreData = FALSE;
  449. ATLA2WHELPER(pszResult,m_vtValue.pszStringA,dwCopy);
  450. if (dwCopy == *pchCount) {
  451. bMoreData = TRUE;
  452. }
  453. *pchCount = dwCopy;
  454. TraceFunctLeave();
  455. return (bMoreData?SEO_S_MOREDATA:S_OK);
  456. } else {
  457. *pchCount = strlen(m_vtValue.pszStringA) + 1;
  458. TraceFunctLeave();
  459. return (S_OK);
  460. }
  461. case veVARIANT: {
  462. VARIANT varValue;
  463. LPCWSTR pszValue;
  464. HRESULT hr;
  465. VariantInit(&varValue);
  466. if (m_vtValue.varVARIANT.vt != VT_BSTR) {
  467. hr = VariantChangeTypeEx(&varValue,&m_vtValue.varVARIANT,LOCALE_NEUTRAL,0,VT_BSTR);
  468. if (!SUCCEEDED(hr)) {
  469. VariantClear(&varValue);
  470. TraceFunctLeave();
  471. return (hr);
  472. }
  473. pszValue = varValue.bstrVal;
  474. } else {
  475. pszValue = m_vtValue.varVARIANT.bstrVal;
  476. }
  477. if (pszResult) {
  478. DWORD dwLen = wcslen(pszValue);
  479. DWORD dwCopy = min(*pchCount,dwLen+1);
  480. BOOL bMoreData = FALSE;
  481. memcpy(pszResult,pszValue,dwCopy);
  482. VariantClear(&varValue);
  483. if (dwCopy == *pchCount) {
  484. pszResult[dwCopy-1] = 0;
  485. bMoreData = TRUE;
  486. }
  487. *pchCount = dwCopy;
  488. TraceFunctLeave();
  489. return (bMoreData?SEO_S_MOREDATA:S_OK);
  490. } else {
  491. *pchCount = wcslen(pszValue) + 1;
  492. VariantClear(&varValue);
  493. TraceFunctLeave();
  494. return (S_OK);
  495. }
  496. }
  497. }
  498. TraceFunctLeave();
  499. return (E_UNEXPECTED);
  500. }
  501. void *CSEODictionaryItem::ValueClass::operator new(size_t cbSize, CSEODictionaryItem::ValueClass *pvcInPlace) {
  502. TraceFunctEnter("CSEODictionaryItem::ValueClass::operator new");
  503. TraceFunctLeave();
  504. return (pvcInPlace);
  505. }