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.

661 lines
16 KiB

  1. #include "stdafx.h"
  2. #include "wsb.h"
  3. #include "wsbbstrg.h"
  4. // {C03D4862-70D7-11d1-994F-0060976A546D}
  5. static const GUID BstrPtrGuid =
  6. { 0xc03d4862, 0x70d7, 0x11d1, { 0x99, 0x4f, 0x0, 0x60, 0x97, 0x6a, 0x54, 0x6d } };
  7. CWsbBstrPtr::CWsbBstrPtr()
  8. {
  9. HRESULT hr = S_OK;
  10. m_pString = 0;
  11. m_givenSize = 0;
  12. WSB_OBJECT_ADD(BstrPtrGuid, this);
  13. }
  14. CWsbBstrPtr::CWsbBstrPtr(const CHAR* pChar)
  15. {
  16. m_pString = 0;
  17. m_givenSize = 0;
  18. WSB_OBJECT_ADD(BstrPtrGuid, this);
  19. *this = pChar;
  20. }
  21. CWsbBstrPtr::CWsbBstrPtr(const WCHAR* pWchar)
  22. {
  23. m_pString = 0;
  24. m_givenSize = 0;
  25. WSB_OBJECT_ADD(BstrPtrGuid, this);
  26. *this = pWchar;
  27. }
  28. CWsbBstrPtr::CWsbBstrPtr(REFGUID rguid)
  29. {
  30. m_pString = 0;
  31. m_givenSize = 0;
  32. WSB_OBJECT_ADD(BstrPtrGuid, this);
  33. *this = rguid;
  34. }
  35. CWsbBstrPtr::CWsbBstrPtr(const CWsbBstrPtr& pString)
  36. {
  37. m_pString = 0;
  38. m_givenSize = 0;
  39. WSB_OBJECT_ADD(BstrPtrGuid, this);
  40. *this = pString;
  41. }
  42. CWsbBstrPtr::~CWsbBstrPtr()
  43. {
  44. WSB_OBJECT_SUB(BstrPtrGuid, this);
  45. Free();
  46. }
  47. CWsbBstrPtr::operator BSTR()
  48. {
  49. return(m_pString);
  50. }
  51. WCHAR& CWsbBstrPtr::operator *()
  52. {
  53. _ASSERTE(0 != m_pString);
  54. return(*m_pString);
  55. }
  56. WCHAR** CWsbBstrPtr::operator &()
  57. {
  58. // This assert only allows the caller to get the address of our pointer
  59. // if we don't have anything allocated.
  60. _ASSERTE(0 == m_pString);
  61. return(&m_pString);
  62. }
  63. WCHAR& CWsbBstrPtr::operator [](const int i)
  64. {
  65. _ASSERTE(0 != m_pString);
  66. return(m_pString[i]);
  67. }
  68. CWsbBstrPtr& CWsbBstrPtr::operator =(const CHAR* pChar)
  69. {
  70. HRESULT hr = S_OK;
  71. ULONG length;
  72. int count;
  73. try {
  74. // Are they setting it to something?
  75. if (0 != pChar) {
  76. // Otherwise, see if our current buffer is big enough.
  77. //
  78. // NOTE: With multibyte characters, we may be getting a bigger
  79. // buffer than we need, but the call to return the accurate
  80. // size is not ANSI.
  81. length = strlen(pChar);
  82. WsbAffirmHr(Realloc(length));
  83. WsbAffirm(0 != m_pString, E_OUTOFMEMORY);
  84. // Copy the data (and convert to wide characters)
  85. count = mbstowcs(m_pString, pChar, length + 1);
  86. WsbAffirm((count != -1), E_FAIL);
  87. }
  88. else {
  89. Free();
  90. }
  91. } WsbCatch(hr);
  92. return(*this);
  93. }
  94. CWsbBstrPtr& CWsbBstrPtr::operator =(const WCHAR* pWchar)
  95. {
  96. HRESULT hr = S_OK;
  97. ULONG length;
  98. try {
  99. // Are they setting it to something?
  100. if (0 != pWchar) {
  101. // Otherwise, see if our current buffer is big enough.
  102. length = wcslen(pWchar);
  103. WsbAssertHr(Realloc(length));
  104. // Copy the data (and convert to wide characters)
  105. wcscpy(m_pString, pWchar);
  106. }
  107. else {
  108. Free();
  109. }
  110. } WsbCatch(hr);
  111. return(*this);
  112. }
  113. CWsbBstrPtr& CWsbBstrPtr::operator =(REFGUID rguid)
  114. {
  115. HRESULT hr = S_OK;
  116. try {
  117. // Otherwise, see if our current buffer is big enough.
  118. WsbAssertHr(Realloc(WSB_GUID_STRING_SIZE));
  119. // Copy the data (and convert to wide characters)
  120. WsbStringFromGuid(rguid, m_pString);
  121. } WsbCatch(hr);
  122. return (*this);
  123. }
  124. CWsbBstrPtr& CWsbBstrPtr::operator =(const CWsbBstrPtr& pString)
  125. {
  126. *this = pString.m_pString;
  127. return(*this);
  128. }
  129. BOOL CWsbBstrPtr::operator !()
  130. {
  131. return((0 == m_pString) ? TRUE : FALSE);
  132. }
  133. HRESULT CWsbBstrPtr::Alloc(ULONG size)
  134. {
  135. HRESULT hr = S_OK;
  136. try {
  137. WsbAssert(0 == m_pString, E_UNEXPECTED);
  138. // m_pString = (WCHAR*) SysAllocStringLen(0, size);
  139. m_pString = (WCHAR*) WsbAllocStringLen(0, size);
  140. WsbAffirm(0 != m_pString, E_OUTOFMEMORY);
  141. // Make sure we always have a valid string so bad things don't happen.
  142. *m_pString = 0;
  143. } WsbCatch(hr);
  144. return(hr);
  145. }
  146. HRESULT CWsbBstrPtr::Append(const CHAR* pChar)
  147. {
  148. HRESULT hr = S_OK;
  149. CWsbBstrPtr tmpString = pChar;
  150. hr = Append(tmpString);
  151. return(hr);
  152. }
  153. HRESULT CWsbBstrPtr::Append(const WCHAR* pWchar)
  154. {
  155. HRESULT hr = S_OK;
  156. ULONG length = 0;
  157. ULONG appendLength;
  158. try {
  159. // If they passed us a null pointer, then we don't need to do anything.
  160. WsbAffirm(pWchar != 0, S_OK);
  161. // If they passed us an empty string, then we don't need to do anything.
  162. appendLength = wcslen(pWchar);
  163. WsbAffirm(0 != appendLength, S_OK);
  164. //
  165. if (0 != m_pString) {
  166. length = wcslen(m_pString);
  167. }
  168. // Make sure the buffer is big enough.
  169. WsbAffirmHr(Realloc(length + appendLength));
  170. // Append the string.
  171. wcscat(m_pString, pWchar);
  172. } WsbCatch(hr);
  173. return(hr);
  174. }
  175. HRESULT CWsbBstrPtr::Append(const CWsbBstrPtr& pString) {
  176. HRESULT hr = S_OK;
  177. hr = Append(pString.m_pString);
  178. return(hr);
  179. }
  180. HRESULT CWsbBstrPtr::CopyTo(CHAR** ppChar)
  181. {
  182. HRESULT hr = S_OK;
  183. hr = CopyTo(ppChar, 0);
  184. return(hr);
  185. }
  186. HRESULT CWsbBstrPtr::CopyTo(CHAR** ppChar, ULONG bufferSize)
  187. {
  188. HRESULT hr = S_OK;
  189. ULONG length = 0;
  190. CHAR* tmpString = 0;
  191. try {
  192. // Allocate a buffer big enough to hold their string.
  193. //
  194. // NOTE: With multibyte characters, we may be getting a bigger
  195. // buffer than we need, but the call to return the accurate
  196. // size is not ANSI.
  197. if (m_pString != 0) {
  198. length = wcstombs(0, m_pString, 0);
  199. }
  200. if (bufferSize == 0) {
  201. tmpString = (CHAR*) WsbRealloc(*ppChar, (length + 1) * sizeof(CHAR));
  202. } else {
  203. WsbAssert(bufferSize >= length, E_FAIL);
  204. if (*ppChar == 0) {
  205. tmpString = (CHAR*) WsbRealloc(*ppChar, (bufferSize + 1) * sizeof(CHAR));
  206. }
  207. }
  208. WsbAffirm(0 != tmpString, E_OUTOFMEMORY);
  209. *ppChar = tmpString;
  210. // Copy and return the string;
  211. if (m_pString != 0) {
  212. WsbAffirm (-1 != wcstombs(*ppChar, m_pString, length + 1), E_FAIL);
  213. } else {
  214. **ppChar = 0;
  215. }
  216. } WsbCatch(hr);
  217. return(hr);
  218. }
  219. HRESULT CWsbBstrPtr::CopyTo(WCHAR** ppWchar)
  220. {
  221. HRESULT hr = S_OK;
  222. hr = CopyTo(ppWchar, 0);
  223. return(hr);
  224. }
  225. HRESULT CWsbBstrPtr::CopyTo(WCHAR** ppWchar, ULONG bufferSize)
  226. {
  227. HRESULT hr = S_OK;
  228. ULONG length = 0;
  229. WCHAR* tmpString = 0;
  230. try {
  231. // Allocate a buffer big enough to hold their string.
  232. if (m_pString != 0) {
  233. length = wcslen(m_pString);
  234. }
  235. if (bufferSize == 0) {
  236. tmpString = (WCHAR*) WsbRealloc(*ppWchar, (length + 1) * sizeof(WCHAR));
  237. } else {
  238. WsbAssert(bufferSize >= length, E_FAIL);
  239. if (*ppWchar == 0) {
  240. tmpString = (WCHAR*) WsbRealloc(*ppWchar, (bufferSize + 1) * sizeof(WCHAR));
  241. }
  242. }
  243. WsbAffirm(0 != tmpString, E_OUTOFMEMORY);
  244. *ppWchar = tmpString;
  245. // Copy and return the string;
  246. if (m_pString != 0) {
  247. wcscpy(*ppWchar, m_pString);
  248. } else {
  249. **ppWchar = 0;
  250. }
  251. } WsbCatch(hr);
  252. return(hr);
  253. }
  254. HRESULT CWsbBstrPtr::CopyTo(GUID * pguid)
  255. {
  256. HRESULT hr = S_OK;
  257. hr = WsbGuidFromString(m_pString, pguid);
  258. return(hr);
  259. }
  260. HRESULT CWsbBstrPtr::CopyToBstr(BSTR* pBstr)
  261. {
  262. HRESULT hr = S_OK;
  263. hr = CopyToBstr(pBstr, 0);
  264. return(hr);
  265. }
  266. HRESULT CWsbBstrPtr::CopyToBstr(BSTR* pBstr, ULONG bufferSize)
  267. {
  268. HRESULT hr = S_OK;
  269. ULONG length = 0;
  270. try {
  271. // Allocate a buffer big enough to hold their string.
  272. if (m_pString != 0) {
  273. length = wcslen(m_pString);
  274. }
  275. if (bufferSize == 0) {
  276. if (0 == *pBstr) {
  277. // *pBstr = SysAllocString(m_pString);
  278. *pBstr = WsbAllocString(m_pString);
  279. } else {
  280. // WsbAffirm(SysReAllocString(pBstr, m_pString), E_OUTOFMEMORY);
  281. WsbAffirm(WsbReallocString(pBstr, m_pString), E_OUTOFMEMORY);
  282. }
  283. } else {
  284. WsbAssert(bufferSize >= length, E_FAIL);
  285. if (0 == *pBstr) {
  286. // *pBstr = SysAllocStringLen(m_pString, bufferSize);
  287. *pBstr = WsbAllocStringLen(m_pString, bufferSize);
  288. } else {
  289. // WsbAffirm(SysReAllocStringLen(pBstr, m_pString, bufferSize), E_OUTOFMEMORY);
  290. WsbAffirm(WsbReallocStringLen(pBstr, m_pString, bufferSize), E_OUTOFMEMORY);
  291. }
  292. }
  293. WsbAffirm(0 != pBstr, E_OUTOFMEMORY);
  294. } WsbCatch(hr);
  295. return(hr);
  296. }
  297. HRESULT CWsbBstrPtr::FindInRsc(ULONG startId, ULONG idsToCheck, ULONG* pMatchId)
  298. {
  299. HRESULT hr = S_FALSE;
  300. CWsbBstrPtr dest;
  301. try {
  302. WsbAssert(0 != pMatchId, E_POINTER);
  303. // Initialize the return value.
  304. *pMatchId = 0;
  305. // Check each resource string mention and see if it is the same as
  306. // the string provided.
  307. for (ULONG testId = startId; (testId < (startId + idsToCheck)) && (*pMatchId == 0); testId++) {
  308. WsbAffirmHr(dest.LoadFromRsc(_Module.m_hInst, testId));
  309. if (wcscmp(dest, m_pString) == 0) {
  310. *pMatchId = testId;
  311. hr = S_OK;
  312. }
  313. }
  314. } WsbCatch(hr);
  315. return(hr);
  316. }
  317. HRESULT CWsbBstrPtr::Free(void)
  318. {
  319. HRESULT hr = S_OK;
  320. try {
  321. if ((0 != m_pString) && (0 == m_givenSize)) {
  322. // SysFreeString(m_pString);
  323. WsbFreeString(m_pString);
  324. m_pString = 0;
  325. }
  326. } WsbCatch(hr);
  327. return(hr);
  328. }
  329. HRESULT CWsbBstrPtr::GetSize(ULONG* pSize)
  330. {
  331. HRESULT hr = S_OK;
  332. try {
  333. WsbAssert(0 != pSize, E_POINTER);
  334. if (0 == m_pString) {
  335. *pSize = 0;
  336. } else if (0 != m_givenSize) {
  337. *pSize = m_givenSize;
  338. } else {
  339. *pSize = SysStringLen(m_pString);
  340. }
  341. } WsbCatch(hr);
  342. return(hr);
  343. }
  344. HRESULT CWsbBstrPtr::GiveTo(BSTR* pBstr)
  345. {
  346. HRESULT hr = S_OK;
  347. try {
  348. WsbAssert(0 != pBstr, E_POINTER);
  349. // Given the our string buffer, and forget about it.
  350. *pBstr = m_pString;
  351. m_pString = 0;
  352. m_givenSize = 0;
  353. } WsbCatch(hr);
  354. return(hr);
  355. }
  356. HRESULT CWsbBstrPtr::LoadFromRsc(HINSTANCE instance, ULONG id)
  357. {
  358. HRESULT hr = S_OK;
  359. HRSRC resource;
  360. ULONG stringSize;
  361. try {
  362. // Find the resource requested. This requires converting the resource
  363. // identifier into a string.
  364. //
  365. // NOTE: Strings are not number individually, but in groups of 16!! This throws
  366. // off the latter size calculation, and some other strategy might be better
  367. // here (e.g. load to a fixed size and then allocate again if too small).
  368. resource = FindResource(instance, MAKEINTRESOURCE((id/16) + 1), RT_STRING);
  369. WsbAffirm(resource != 0, E_FAIL);
  370. // How big is the string?
  371. stringSize = SizeofResource(instance, resource);
  372. WsbAffirm(0 != stringSize, E_FAIL);
  373. // Get the right sized buffer.
  374. WsbAffirmHr(Realloc(stringSize / sizeof(WCHAR)));
  375. // Load the string into the buffer.
  376. WsbAffirm(LoadString(instance, id, m_pString, (stringSize / sizeof(WCHAR)) + 1) != 0, E_FAIL);
  377. } WsbCatch(hr);
  378. return(hr);
  379. }
  380. HRESULT CWsbBstrPtr::Prepend(const CHAR* pChar) {
  381. HRESULT hr = S_OK;
  382. CWsbBstrPtr tmpString = pChar;
  383. hr = Prepend(tmpString);
  384. return(hr);
  385. }
  386. HRESULT CWsbBstrPtr::Prepend(const WCHAR* pWchar) {
  387. HRESULT hr = S_OK;
  388. ULONG length;
  389. ULONG prependLength;
  390. ULONG i, j;
  391. try {
  392. // If they passed us a null pointer, then we don't need to do anything.
  393. WsbAffirm(pWchar != 0, S_OK);
  394. // If they passed us an empty string, then we don't need to do anything.
  395. prependLength = wcslen(pWchar);
  396. WsbAffirm(0 != prependLength, S_OK);
  397. if (0 != m_pString) {
  398. length = wcslen(m_pString);
  399. } else {
  400. // Prepend code will work as long as we have a null string and not a null pointer...
  401. // Next Realloc statement will make it happen...
  402. length = 0;
  403. }
  404. WsbAffirmHr(Realloc(length + prependLength));
  405. // First move the existing string down in the buffer.
  406. for (i = length + 1, j = length + prependLength; i > 0; i--, j--) {
  407. m_pString[j] = m_pString[i - 1];
  408. }
  409. // Now prepend the string (except for the null)
  410. for (i = 0; i < prependLength; i++) {
  411. m_pString[i] = pWchar[i];
  412. }
  413. } WsbCatch(hr);
  414. return(hr);
  415. }
  416. HRESULT CWsbBstrPtr::Prepend(const CWsbBstrPtr& pString) {
  417. HRESULT hr = S_OK;
  418. hr = Prepend(pString.m_pString);
  419. return(hr);
  420. }
  421. HRESULT CWsbBstrPtr::Realloc(ULONG size)
  422. {
  423. HRESULT hr = S_OK;
  424. ULONG currentSize = 0;
  425. BOOL bigEnough = FALSE;
  426. OLECHAR* pString;
  427. try {
  428. // We want to try to get a buffer of the size indicated.
  429. // If the buffer is already bigger than the size needed, then
  430. // don't do anything.
  431. if (0 != m_pString) {
  432. WsbAffirmHr(GetSize(&currentSize));
  433. if (currentSize >= size) {
  434. bigEnough = TRUE;
  435. }
  436. }
  437. // Reallocate the buffer if we need a bigger one.
  438. if (!bigEnough) {
  439. // If we were given this buffer, then we can't reallocate it.
  440. WsbAssert(0 == m_givenSize, E_UNEXPECTED);
  441. // The realloc won't handle it properly if no BSTR has ever been allocated, so
  442. // use Alloc() in that case.
  443. if (0 == m_pString) {
  444. WsbAffirmHr(Alloc(size));
  445. } else {
  446. // According to Bounds checker, Realloc doesn't work the way we expected, so
  447. // do the steps by hand.
  448. pString = m_pString;
  449. m_pString = 0;
  450. WsbAffirmHr(Alloc(size));
  451. wcsncpy(m_pString, pString, currentSize + 1);
  452. // SysFreeString(pString);
  453. WsbFreeString(pString);
  454. // WsbAffirm(SysReAllocStringLen(&m_pString, 0, size + 1), E_OUTOFMEMORY);
  455. }
  456. }
  457. } WsbCatch(hr);
  458. return(hr);
  459. }
  460. HRESULT CWsbBstrPtr::TakeFrom(BSTR bstr, ULONG bufferSize)
  461. {
  462. HRESULT hr = S_OK;
  463. try {
  464. // Clear out any previously "taken" string.
  465. if (0 != m_givenSize) {
  466. m_pString = 0;
  467. m_givenSize = 0;
  468. }
  469. // If the given buffer is null, then we are responsible for allocating it.
  470. if (0 == bstr) {
  471. if (0 != bufferSize) {
  472. WsbAffirmHr(Realloc(bufferSize));
  473. }
  474. }
  475. // Otherwise, we need to get rid of any buffer we had and use the one indicated.
  476. else {
  477. if (0 != m_pString) {
  478. WsbAffirmHr(Free());
  479. }
  480. m_pString = bstr;
  481. if (0 != bufferSize) {
  482. m_givenSize = bufferSize;
  483. }
  484. }
  485. } WsbCatch(hr);
  486. return(hr);
  487. }