/lwadvapi/unthreaded/lwunistr/lwunistr.c

https://github.com/BeyondTrust/pbis-open · C · 687 lines · 492 code · 152 blank · 43 comment · 41 complexity · f6ec5926e24411d0eb07bba9894c2885 MD5 · raw file

  1. /* Editor Settings: expandtabs and use 4 spaces for indentation
  2. * ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
  3. */
  4. /*
  5. * Copyright © BeyondTrust Software 2004 - 2019
  6. * All rights reserved.
  7. *
  8. * Licensed under the Apache License, Version 2.0 (the "License");
  9. * you may not use this file except in compliance with the License.
  10. * You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing, software
  15. * distributed under the License is distributed on an "AS IS" BASIS,
  16. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17. * See the License for the specific language governing permissions and
  18. * limitations under the License.
  19. *
  20. * BEYONDTRUST MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING TERMS AS
  21. * WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT WITH
  22. * BEYONDTRUST, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE TERMS OF THAT
  23. * SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE APACHE LICENSE,
  24. * NOTWITHSTANDING THE ABOVE NOTICE. IF YOU HAVE QUESTIONS, OR WISH TO REQUEST
  25. * A COPY OF THE ALTERNATE LICENSING TERMS OFFERED BY BEYONDTRUST, PLEASE CONTACT
  26. * BEYONDTRUST AT beyondtrust.com/contact
  27. */
  28. #include "includes.h"
  29. DWORD
  30. LwMbsToWc16s(
  31. PCSTR pszInput,
  32. PWSTR* ppszOutput
  33. )
  34. {
  35. DWORD dwError = 0;
  36. PWSTR pszOutput = NULL;
  37. if (!pszInput) {
  38. dwError = LW_ERROR_INVALID_PARAMETER;
  39. BAIL_ON_LW_ERROR(dwError);
  40. }
  41. pszOutput = ambstowc16s(pszInput);
  42. if (!pszOutput) {
  43. dwError = LW_ERROR_STRING_CONV_FAILED;
  44. BAIL_ON_LW_ERROR(dwError);
  45. }
  46. *ppszOutput = pszOutput;
  47. cleanup:
  48. return dwError;
  49. error:
  50. *ppszOutput = NULL;
  51. goto cleanup;
  52. }
  53. DWORD
  54. LwWc16snToMbs(
  55. PCWSTR pwszInput,
  56. PSTR* ppszOutput,
  57. size_t sMaxChars
  58. )
  59. {
  60. DWORD dwError = 0;
  61. PWSTR pwszTruncated = NULL;
  62. PSTR pszOutput = NULL;
  63. if (!pwszInput) {
  64. dwError = LW_ERROR_INVALID_PARAMETER;
  65. BAIL_ON_LW_ERROR(dwError);
  66. }
  67. pwszTruncated = _wc16sndup(pwszInput, sMaxChars);
  68. if (!pwszTruncated) {
  69. dwError = LwMapErrnoToLwError(errno);
  70. BAIL_ON_LW_ERROR(dwError);
  71. }
  72. pszOutput = awc16stombs(pwszTruncated);
  73. if (!pszOutput) {
  74. dwError = LW_ERROR_STRING_CONV_FAILED;
  75. BAIL_ON_LW_ERROR(dwError);
  76. }
  77. *ppszOutput = pszOutput;
  78. cleanup:
  79. LW_SAFE_FREE_MEMORY(pwszTruncated);
  80. return dwError;
  81. error:
  82. *ppszOutput = NULL;
  83. goto cleanup;
  84. }
  85. DWORD
  86. LwWc16sToMbs(
  87. PCWSTR pwszInput,
  88. PSTR* ppszOutput
  89. )
  90. {
  91. DWORD dwError = 0;
  92. PSTR pszOutput = NULL;
  93. if (!pwszInput) {
  94. dwError = LW_ERROR_INVALID_PARAMETER;
  95. BAIL_ON_LW_ERROR(dwError);
  96. }
  97. pszOutput = awc16stombs(pwszInput);
  98. if (!pszOutput) {
  99. dwError = LW_ERROR_STRING_CONV_FAILED;
  100. BAIL_ON_LW_ERROR(dwError);
  101. }
  102. *ppszOutput = pszOutput;
  103. cleanup:
  104. return dwError;
  105. error:
  106. *ppszOutput = NULL;
  107. goto cleanup;
  108. }
  109. DWORD
  110. LwWc16sLen(
  111. PCWSTR pwszInput,
  112. size_t* psLen
  113. )
  114. {
  115. DWORD dwError = 0;
  116. size_t sLen = 0;
  117. if (!pwszInput) {
  118. dwError = LW_ERROR_INVALID_PARAMETER;
  119. BAIL_ON_LW_ERROR(dwError);
  120. }
  121. sLen = wc16slen(pwszInput);
  122. *psLen = sLen;
  123. cleanup:
  124. return dwError;
  125. error:
  126. *psLen = 0;
  127. goto cleanup;
  128. }
  129. DWORD
  130. LwWc16sCpy(
  131. PWSTR pwszOutputString,
  132. PCWSTR pwszInputString
  133. )
  134. {
  135. DWORD dwError = 0;
  136. if (!pwszInputString ||
  137. !pwszOutputString)
  138. {
  139. dwError = LW_ERROR_INVALID_PARAMETER;
  140. BAIL_ON_LW_ERROR(dwError);
  141. }
  142. wc16scpy(pwszOutputString, pwszInputString);
  143. cleanup:
  144. return dwError;
  145. error:
  146. goto cleanup;
  147. }
  148. DWORD
  149. LwWc16snCpy(
  150. PWSTR pwszOutputString,
  151. PCWSTR pwszInputString,
  152. DWORD dwLen
  153. )
  154. {
  155. DWORD dwError = 0;
  156. size_t sLen = (size_t)dwLen;
  157. if (!pwszInputString ||
  158. !pwszOutputString)
  159. {
  160. dwError = LW_ERROR_INVALID_PARAMETER;
  161. BAIL_ON_LW_ERROR(dwError);
  162. }
  163. if (sLen)
  164. {
  165. wc16sncpy(pwszOutputString, pwszInputString, sLen);
  166. }
  167. cleanup:
  168. return dwError;
  169. error:
  170. goto cleanup;
  171. }
  172. DWORD
  173. LwSW16printf(
  174. PWSTR* ppwszStrOutput,
  175. PCSTR pszFormat,
  176. ...)
  177. {
  178. DWORD dwError = 0;
  179. INT ret = 0;
  180. PWSTR pwszStrOutput = NULL;
  181. va_list args;
  182. va_start(args, pszFormat);
  183. ret = sw16printf(
  184. pwszStrOutput,
  185. pszFormat,
  186. args);
  187. if (ret == -1){
  188. dwError = LwMapErrnoToLwError(errno);
  189. BAIL_ON_LW_ERROR(dwError);
  190. }
  191. *ppwszStrOutput = pwszStrOutput;
  192. cleanup:
  193. va_end(args);
  194. return dwError;
  195. error:
  196. LW_SAFE_FREE_MEMORY(pwszStrOutput);
  197. goto cleanup;
  198. }
  199. DWORD
  200. LwAllocateWc16sPrintfW(
  201. PWSTR* ppszString,
  202. const wchar_t* pszFormat,
  203. ...
  204. )
  205. {
  206. DWORD dwError = 0;
  207. PWSTR pszNewString = NULL;
  208. va_list args;
  209. va_start(args, pszFormat);
  210. pszNewString = asw16printfwv(pszFormat, args);
  211. if (pszNewString == NULL)
  212. {
  213. dwError = LwMapErrnoToLwError(errno);
  214. }
  215. *ppszString = pszNewString;
  216. va_end(args);
  217. return dwError;
  218. }
  219. DWORD
  220. LwWc16sToUpper(
  221. IN OUT PWSTR pwszString
  222. )
  223. {
  224. DWORD dwError = LW_ERROR_SUCCESS;
  225. wc16supper(pwszString);
  226. return dwError;
  227. }
  228. DWORD
  229. LwWc16sToLower(
  230. IN OUT PWSTR pwszString
  231. )
  232. {
  233. DWORD dwError = LW_ERROR_SUCCESS;
  234. wc16slower(pwszString);
  235. return dwError;
  236. }
  237. DWORD
  238. LwAllocateWc16String(
  239. PWSTR *ppwszOutputString,
  240. PCWSTR pwszInputString
  241. )
  242. {
  243. DWORD dwError = ERROR_SUCCESS;
  244. DWORD dwLen = 0;
  245. PWSTR pwszOutputString = NULL;
  246. if (!pwszInputString)
  247. {
  248. dwError = ERROR_INVALID_PARAMETER;
  249. BAIL_ON_LW_ERROR(dwError);
  250. }
  251. dwLen = wc16slen(pwszInputString);
  252. dwError = LwAllocateMemory(sizeof(pwszOutputString[0]) * (dwLen + 1),
  253. OUT_PPVOID(&pwszOutputString));
  254. BAIL_ON_LW_ERROR(dwError);
  255. if (dwLen)
  256. {
  257. wc16sncpy(pwszOutputString, pwszInputString, dwLen);
  258. }
  259. *ppwszOutputString = pwszOutputString;
  260. cleanup:
  261. return dwError;
  262. error:
  263. LW_SAFE_FREE_MEMORY(pwszOutputString);
  264. *ppwszOutputString = NULL;
  265. goto cleanup;
  266. }
  267. DWORD
  268. LwAllocateUnicodeStringFromWc16String(
  269. PUNICODE_STRING pOutputString,
  270. PCWSTR pwszInputString
  271. )
  272. {
  273. DWORD dwError = ERROR_SUCCESS;
  274. DWORD dwLen = 0;
  275. DWORD dwSize = 0;
  276. PWSTR pwszBuffer = NULL;
  277. if (!pOutputString)
  278. {
  279. dwError = ERROR_INVALID_PARAMETER;
  280. BAIL_ON_LW_ERROR(dwError);
  281. }
  282. if (pwszInputString)
  283. {
  284. dwLen = wc16slen(pwszInputString);
  285. }
  286. dwSize = dwLen + 1;
  287. dwError = LwAllocateMemory(sizeof(pwszBuffer[0]) * dwSize,
  288. OUT_PPVOID(&pwszBuffer));
  289. BAIL_ON_LW_ERROR(dwError);
  290. if (dwLen)
  291. {
  292. wc16sncpy(pwszBuffer, pwszInputString, dwLen);
  293. }
  294. pOutputString->Length = sizeof(pwszBuffer[0]) * dwLen;
  295. pOutputString->MaximumLength = sizeof(pwszBuffer[0]) * dwSize;
  296. pOutputString->Buffer = pwszBuffer;
  297. cleanup:
  298. return dwError;
  299. error:
  300. LW_SAFE_FREE_MEMORY(pwszBuffer);
  301. pOutputString->Length = 0;
  302. pOutputString->MaximumLength = 0;
  303. pOutputString->Buffer = NULL;
  304. goto cleanup;
  305. }
  306. DWORD
  307. LwAllocateUnicodeStringExFromWc16String(
  308. PUNICODE_STRING pOutputString,
  309. PCWSTR pwszInputString
  310. )
  311. {
  312. DWORD dwError = ERROR_SUCCESS;
  313. DWORD dwLen = 0;
  314. DWORD dwSize = 0;
  315. PWSTR pwszBuffer = NULL;
  316. if (!pOutputString)
  317. {
  318. dwError = ERROR_INVALID_PARAMETER;
  319. BAIL_ON_LW_ERROR(dwError);
  320. }
  321. if (pwszInputString)
  322. {
  323. dwLen = wc16slen(pwszInputString);
  324. }
  325. dwSize = dwLen + 1;
  326. dwError = LwAllocateMemory(sizeof(pwszBuffer[0]) * dwSize,
  327. OUT_PPVOID(&pwszBuffer));
  328. BAIL_ON_LW_ERROR(dwError);
  329. if (dwLen)
  330. {
  331. wc16sncpy(pwszBuffer, pwszInputString, dwLen);
  332. }
  333. pOutputString->Length = sizeof(pwszBuffer[0]) * dwLen;
  334. pOutputString->MaximumLength = sizeof(pwszBuffer[0]) * dwSize;
  335. pOutputString->Buffer = pwszBuffer;
  336. cleanup:
  337. return dwError;
  338. error:
  339. LW_SAFE_FREE_MEMORY(pwszBuffer);
  340. pOutputString->Length = 0;
  341. pOutputString->MaximumLength = 0;
  342. pOutputString->Buffer = NULL;
  343. goto cleanup;
  344. }
  345. DWORD
  346. LwAllocateWc16StringFromUnicodeString(
  347. PWSTR *ppOutputString,
  348. PUNICODE_STRING pInputString
  349. )
  350. {
  351. DWORD dwError = ERROR_SUCCESS;
  352. PWSTR pwszString = NULL;
  353. DWORD dwSize = 0;
  354. if (!ppOutputString ||
  355. !pInputString ||
  356. !pInputString->Buffer)
  357. {
  358. dwError = ERROR_INVALID_PARAMETER;
  359. BAIL_ON_LW_ERROR(dwError);
  360. }
  361. /*
  362. * Correctly handle the case where windows (incorrectly) sets
  363. * max length to the same value as length
  364. */
  365. if (pInputString->MaximumLength > pInputString->Length)
  366. {
  367. dwSize = pInputString->MaximumLength;
  368. }
  369. else if (pInputString->MaximumLength == pInputString->Length)
  370. {
  371. dwSize = pInputString->Length + sizeof(WCHAR);
  372. }
  373. else
  374. {
  375. dwError = ERROR_INVALID_PARAMETER;
  376. BAIL_ON_LW_ERROR(dwError);
  377. }
  378. dwError = LwAllocateMemory(dwSize,
  379. OUT_PPVOID(&pwszString));
  380. BAIL_ON_LW_ERROR(dwError);
  381. wc16sncpy(pwszString, pInputString->Buffer, pInputString->Length / 2);
  382. *ppOutputString = pwszString;
  383. cleanup:
  384. return dwError;
  385. error:
  386. LW_SAFE_FREE_MEMORY(pwszString);
  387. *ppOutputString = NULL;
  388. goto cleanup;
  389. }
  390. DWORD
  391. LwAllocateUnicodeStringFromCString(
  392. PUNICODE_STRING pOutputString,
  393. PCSTR pszInputString
  394. )
  395. {
  396. DWORD dwError = ERROR_SUCCESS;
  397. DWORD dwLen = 0;
  398. DWORD dwSize = 0;
  399. PWSTR pwszBuffer = NULL;
  400. if (!pOutputString)
  401. {
  402. dwError = ERROR_INVALID_PARAMETER;
  403. BAIL_ON_LW_ERROR(dwError);
  404. }
  405. if (pszInputString)
  406. {
  407. dwLen = strlen(pszInputString);
  408. }
  409. dwSize = dwLen + 1;
  410. dwError = LwAllocateMemory(sizeof(pwszBuffer[0]) * dwSize,
  411. OUT_PPVOID(&pwszBuffer));
  412. BAIL_ON_LW_ERROR(dwError);
  413. if (dwLen)
  414. {
  415. mbstowc16s(pwszBuffer, pszInputString, dwLen);
  416. }
  417. pOutputString->Length = sizeof(pwszBuffer[0]) * dwLen;
  418. pOutputString->MaximumLength = sizeof(pwszBuffer[0]) * dwSize;
  419. pOutputString->Buffer = pwszBuffer;
  420. cleanup:
  421. return dwError;
  422. error:
  423. LW_SAFE_FREE_MEMORY(pwszBuffer);
  424. pOutputString->Length = 0;
  425. pOutputString->MaximumLength = 0;
  426. pOutputString->Buffer = NULL;
  427. goto cleanup;
  428. }
  429. DWORD
  430. LwAllocateUnicodeStringExFromCString(
  431. PUNICODE_STRING pOutputString,
  432. PCSTR pszInputString
  433. )
  434. {
  435. DWORD dwError = ERROR_SUCCESS;
  436. DWORD dwLen = 0;
  437. DWORD dwSize = 0;
  438. PWSTR pwszBuffer = NULL;
  439. if (!pOutputString)
  440. {
  441. dwError = ERROR_INVALID_PARAMETER;
  442. BAIL_ON_LW_ERROR(dwError);
  443. }
  444. if (pszInputString)
  445. {
  446. dwLen = strlen(pszInputString);
  447. }
  448. dwSize = dwLen + 1;
  449. dwError = LwAllocateMemory(sizeof(pwszBuffer[0]) * dwSize,
  450. OUT_PPVOID(&pwszBuffer));
  451. BAIL_ON_LW_ERROR(dwError);
  452. if (dwLen)
  453. {
  454. mbstowc16s(pwszBuffer, pszInputString, dwLen);
  455. }
  456. pOutputString->Length = sizeof(pwszBuffer[0]) * dwLen;
  457. pOutputString->MaximumLength = sizeof(pwszBuffer[0]) * dwSize;
  458. pOutputString->Buffer = pwszBuffer;
  459. cleanup:
  460. return dwError;
  461. error:
  462. LW_SAFE_FREE_MEMORY(pwszBuffer);
  463. pOutputString->Length = 0;
  464. pOutputString->MaximumLength = 0;
  465. pOutputString->Buffer = NULL;
  466. goto cleanup;
  467. }
  468. DWORD
  469. LwAllocateCStringFromUnicodeString(
  470. PSTR *ppszOutputString,
  471. PUNICODE_STRING pInputString
  472. )
  473. {
  474. DWORD dwError = ERROR_SUCCESS;
  475. PSTR pszString = NULL;
  476. DWORD dwSize = 0;
  477. if (!ppszOutputString ||
  478. !pInputString ||
  479. !pInputString->Buffer)
  480. {
  481. dwError = ERROR_INVALID_PARAMETER;
  482. BAIL_ON_LW_ERROR(dwError);
  483. }
  484. /*
  485. * Correctly handle the case where windows (incorrectly) sets
  486. * max length to the same value as length
  487. */
  488. if (pInputString->MaximumLength > pInputString->Length)
  489. {
  490. dwSize = (pInputString->MaximumLength / sizeof(WCHAR));
  491. }
  492. else if (pInputString->MaximumLength == pInputString->Length)
  493. {
  494. dwSize = (pInputString->Length / sizeof(WCHAR)) + sizeof(CHAR);
  495. }
  496. else
  497. {
  498. dwError = ERROR_INVALID_PARAMETER;
  499. BAIL_ON_LW_ERROR(dwError);
  500. }
  501. dwError = LwAllocateMemory(dwSize,
  502. OUT_PPVOID(&pszString));
  503. BAIL_ON_LW_ERROR(dwError);
  504. wc16stombs(pszString, pInputString->Buffer,
  505. pInputString->Length / sizeof(WCHAR));
  506. *ppszOutputString = pszString;
  507. cleanup:
  508. return dwError;
  509. error:
  510. LW_SAFE_FREE_MEMORY(pszString);
  511. *ppszOutputString = NULL;
  512. goto cleanup;
  513. }
  514. VOID
  515. LwFreeUnicodeString(
  516. PUNICODE_STRING pString
  517. )
  518. {
  519. if (!pString ||
  520. pString->MaximumLength == 0 ||
  521. !pString->Buffer)
  522. {
  523. return;
  524. }
  525. LW_SAFE_FREE_MEMORY(pString->Buffer);
  526. pString->Buffer = NULL;
  527. }
  528. /*
  529. local variables:
  530. mode: c
  531. c-basic-offset: 4
  532. indent-tabs-mode: nil
  533. tab-width: 4
  534. end:
  535. */