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.

335 lines
7.6 KiB

  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <stdarg.h>
  4. #ifdef __cplusplus
  5. extern "C" {
  6. #endif
  7. #ifndef DIMA
  8. #define DIMAT(Array, EltType) (sizeof(Array) / sizeof(EltType))
  9. #define DIMA(Array) DIMAT(Array, (Array)[0])
  10. #endif
  11. BOOL CopyNString(PSTR To, PCSTR From, ULONG FromChars, ULONG ToChars);
  12. BOOL CatNString(PSTR To, PCSTR From, ULONG FromChars, ULONG ToChars);
  13. #ifndef COPYSTR_NO_PRINTSTRING
  14. BOOL __cdecl PrintString(PSTR To, ULONG ToChars, PCSTR Format, ...);
  15. #endif
  16. #define CopyString(To, From, ToChars) CopyNString(To, From, (ULONG)-1, ToChars)
  17. #define CatString(To, From, ToChars) CatNString(To, From, (ULONG)-1, ToChars)
  18. #define CopyNStrArray(To, From, FromChars) CopyNString(To, From, FromChars, DIMA(To))
  19. #define CopyStrArray(To, From) CopyString(To, From, DIMA(To))
  20. #define CatStrArray(To, From) CatString(To, From, DIMA(To))
  21. #ifndef COPYSTR_NO_WCHAR
  22. BOOL CopyNStringW(PWSTR To, PCWSTR From, ULONG FromChars, ULONG ToChars);
  23. BOOL CatNStringW(PWSTR To, PCWSTR From, ULONG FromChars, ULONG ToChars);
  24. #ifndef COPYSTR_NO_PRINTSTRING
  25. BOOL __cdecl PrintStringW(PWSTR To, ULONG ToChars, PCWSTR Format, ...);
  26. #endif
  27. #define CopyStringW(To, From, ToChars) CopyNStringW(To, From, (ULONG)-1, ToChars)
  28. #define CatStringW(To, From, ToChars) CatNStringW(To, From, (ULONG)-1, ToChars)
  29. #define CopyNStrArrayW(To, From, FromChars) CopyNStringW(To, From, FromChars, DIMA(To))
  30. #define CopyStrArrayW(To, From) CopyStringW(To, From, DIMA(To))
  31. #define CatStrArrayW(To, From) CatStringW(To, From, DIMA(To))
  32. #endif // #ifndef COPYSTR_NO_WCHAR
  33. #ifdef COPYSTR_MOD
  34. BOOL
  35. CopyNString(PSTR To, PCSTR From, ULONG FromChars, ULONG ToChars)
  36. {
  37. //
  38. // The CRT str'n'cpy doesn't guarantee termination of the
  39. // resulting string, so define a new function that does.
  40. // Returns TRUE for a full copy with terminator.
  41. //
  42. if (ToChars == 0)
  43. {
  44. return FALSE;
  45. }
  46. BOOL Succ = TRUE;
  47. ULONG Len = strlen(From);
  48. if (FromChars == (ULONG)-1)
  49. {
  50. // This is a regular strcpy. Don't fool with the length.
  51. }
  52. else if (FromChars > Len)
  53. {
  54. // The source string is smaller than the amount of characters
  55. // we were asked to copy. Do it anyway, but return FALSE;
  56. Succ = FALSE;
  57. }
  58. else
  59. {
  60. // Set amount of characters to copy as in a normal strncpy.
  61. Len = FromChars;
  62. }
  63. if (Len >= ToChars)
  64. {
  65. Len = ToChars - 1;
  66. Succ = FALSE;
  67. }
  68. memcpy(To, From, Len);
  69. To[Len] = 0;
  70. return Succ;
  71. }
  72. BOOL
  73. CatNString(PSTR To, PCSTR From, ULONG FromChars, ULONG ToChars)
  74. {
  75. //
  76. // The CRT str'n'cat works with the number of characters to
  77. // append, which is usually inconvenient when filling
  78. // fixed-length buffers as you need to make sure to
  79. // subtract off the size of any existing content to
  80. // prevent buffer overflows. Define a new function that
  81. // works with the absolute buffer size.
  82. // Returns TRUE for a full copy with terminator.
  83. //
  84. if (ToChars == 0)
  85. {
  86. return FALSE;
  87. }
  88. ULONG ToLen = strlen(To);
  89. if (ToLen >= ToChars)
  90. {
  91. ULONG i;
  92. // To string is garbage. Copy in a special
  93. // marker string.
  94. if (ToChars > 8)
  95. {
  96. ToChars = 8;
  97. }
  98. for (i = 0; i < ToChars - 1; i++)
  99. {
  100. To[i] = 'G';
  101. }
  102. To[i] = 0;
  103. return FALSE;
  104. }
  105. ToChars -= ToLen;
  106. BOOL Succ = TRUE;
  107. ULONG FromLen = strlen(From);
  108. if (FromChars != (ULONG)-1)
  109. {
  110. FromLen = min(FromLen, FromChars);
  111. }
  112. if (FromLen >= ToChars)
  113. {
  114. FromLen = ToChars - 1;
  115. Succ = FALSE;
  116. }
  117. memcpy(To + ToLen, From, FromLen);
  118. To[ToLen + FromLen] = 0;
  119. return Succ;
  120. }
  121. #ifndef COPYSTR_NO_PRINTSTRING
  122. BOOL __cdecl
  123. PrintString(PSTR To, ULONG ToChars, PCSTR Format, ...)
  124. {
  125. va_list Args;
  126. int PrintChars;
  127. //
  128. // _snprintf leaves strings unterminated on overflow.
  129. // This wrapper guarantees termination.
  130. //
  131. if (ToChars == 0)
  132. {
  133. return FALSE;
  134. }
  135. va_start(Args, Format);
  136. PrintChars = _vsnprintf(To, ToChars, Format, Args);
  137. if (PrintChars < 0 || PrintChars == ToChars)
  138. {
  139. va_end(Args);
  140. // Overflow, force termination.
  141. To[ToChars - 1] = 0;
  142. return FALSE;
  143. }
  144. else
  145. {
  146. va_end(Args);
  147. return TRUE;
  148. }
  149. }
  150. #endif // #ifndef COPYSTR_NO_PRINTSTRING
  151. #ifndef COPYSTR_NO_WCHAR
  152. BOOL
  153. CopyNStringW(PWSTR To, PCWSTR From, ULONG FromChars, ULONG ToChars)
  154. {
  155. //
  156. // The CRT str'n'cpy doesn't guarantee termination of the
  157. // resulting string, so define a new function that does.
  158. // Returns TRUE for a full copy with terminator.
  159. //
  160. if (ToChars == 0)
  161. {
  162. return FALSE;
  163. }
  164. BOOL Succ = TRUE;
  165. ULONG Len = wcslen(From);
  166. if (FromChars == (ULONG)-1)
  167. {
  168. // This is a regular strcpy. Don't fool with the length.
  169. }
  170. else if (FromChars > Len)
  171. {
  172. // The source string is smaller than the amount of characters
  173. // we were asked to copy. Do it anyway, but return FALSE;
  174. Succ = FALSE;
  175. }
  176. else
  177. {
  178. // Set amount of characters to copy as in a normal strncpy.
  179. Len = FromChars;
  180. }
  181. if (Len >= ToChars)
  182. {
  183. Len = ToChars - 1;
  184. Succ = FALSE;
  185. }
  186. memcpy(To, From, Len * sizeof(WCHAR));
  187. To[Len] = 0;
  188. return Succ;
  189. }
  190. BOOL
  191. CatNStringW(PWSTR To, PCWSTR From, ULONG FromChars, ULONG ToChars)
  192. {
  193. //
  194. // The CRT str'n'cat works with the number of characters to
  195. // append, which is usually inconvenient when filling
  196. // fixed-length buffers as you need to make sure to
  197. // subtract off the size of any existing content to
  198. // prevent buffer overflows. Define a new function that
  199. // works with the absolute buffer size.
  200. // Returns TRUE for a full copy with terminator.
  201. //
  202. if (ToChars == 0)
  203. {
  204. return FALSE;
  205. }
  206. ULONG ToLen = wcslen(To);
  207. if (ToLen >= ToChars)
  208. {
  209. ULONG i;
  210. // To string is garbage. Copy in a special
  211. // marker string.
  212. if (ToChars > 8)
  213. {
  214. ToChars = 8;
  215. }
  216. for (i = 0; i < ToChars - 1; i++)
  217. {
  218. To[i] = L'G';
  219. }
  220. To[i] = 0;
  221. return FALSE;
  222. }
  223. ToChars -= ToLen;
  224. BOOL Succ = TRUE;
  225. ULONG FromLen = wcslen(From);
  226. if (FromChars != (ULONG)-1)
  227. {
  228. FromLen = min(FromLen, FromChars);
  229. }
  230. if (FromLen >= ToChars)
  231. {
  232. FromLen = ToChars - 1;
  233. Succ = FALSE;
  234. }
  235. memcpy(To + ToLen, From, FromLen * sizeof(WCHAR));
  236. To[ToLen + FromLen] = 0;
  237. return Succ;
  238. }
  239. #ifndef COPYSTR_NO_PRINTSTRING
  240. BOOL __cdecl
  241. PrintStringW(PWSTR To, ULONG ToChars, PCWSTR Format, ...)
  242. {
  243. va_list Args;
  244. int PrintChars;
  245. //
  246. // _snprintf leaves strings unterminated on overflow.
  247. // This wrapper guarantees termination.
  248. //
  249. if (ToChars == 0)
  250. {
  251. return FALSE;
  252. }
  253. va_start(Args, Format);
  254. PrintChars = _vsnwprintf(To, ToChars, Format, Args);
  255. if (PrintChars < 0 || PrintChars == ToChars)
  256. {
  257. va_end(Args);
  258. // Overflow, force termination.
  259. To[ToChars - 1] = 0;
  260. return FALSE;
  261. }
  262. else
  263. {
  264. va_end(Args);
  265. return TRUE;
  266. }
  267. }
  268. #endif // #ifndef COPYSTR_NO_PRINTSTRING
  269. #endif // #ifndef COPYSTR_NO_WCHAR
  270. #endif // #ifdef COPYSTR_MOD
  271. #ifdef __cplusplus
  272. }
  273. #endif