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.

723 lines
17 KiB

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