Source code of Windows XP (NT5)
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.

346 lines
9.8 KiB

  1. /****************************************************************************/
  2. /* */
  3. /* MYCRT.C - */
  4. /* */
  5. /* My special Unicode workaround file for CRT functions calls */
  6. /* from WIN32 Shell applications. */
  7. /* */
  8. /* Created by : Diane K. Oh */
  9. /* On Date : June 11, 1992 */
  10. /* */
  11. /* This is a temporary fix and needs to be modified when Unicode */
  12. /* is fully supported by CRT. */
  13. /* */
  14. /****************************************************************************/
  15. #include <windows.h>
  16. #include <stdlib.h>
  17. #include <tchar.h>
  18. #include <direct.h>
  19. #ifdef UNICODE
  20. #include <wchar.h>
  21. #else
  22. #include <string.h>
  23. #endif
  24. #define INT_SIZE_LENGTH 20
  25. #define LONG_SIZE_LENGTH 40
  26. //*****************************************************************
  27. //
  28. // MyAtoi and MyAtol
  29. //
  30. // Purpose : To convert from Unicode to ANSI string before
  31. // calling CRT atoi and atol functions.
  32. //
  33. //*****************************************************************
  34. INT MyAtoi (LPTSTR string)
  35. {
  36. CHAR szAnsi [INT_SIZE_LENGTH];
  37. BOOL fDefCharUsed;
  38. #ifdef UNICODE
  39. BOOL bDBCS;
  40. LCID lcid = GetThreadLocale();
  41. bDBCS = ( (PRIMARYLANGID(LANGIDFROMLCID(lcid)) == LANG_JAPANESE) ||
  42. (PRIMARYLANGID(LANGIDFROMLCID(lcid)) == LANG_KOREAN) ||
  43. (PRIMARYLANGID(LANGIDFROMLCID(lcid)) == LANG_CHINESE)
  44. );
  45. if (bDBCS)
  46. {
  47. //fix mskkbug: #3871
  48. //When Control panel calling this function, the string to be converted
  49. //has extra charcters (not able to be converted integer value, such as 'a','b'.
  50. //In that case, memory allocation error causes. So we have to make sure of it.
  51. int iCnt, rValue;
  52. LPBYTE mptr;
  53. if( !(iCnt = WideCharToMultiByte (CP_ACP, 0, string, -1, szAnsi,
  54. INT_SIZE_LENGTH, NULL, &fDefCharUsed)) )
  55. {
  56. iCnt = WideCharToMultiByte (CP_ACP, 0, string, -1, NULL,
  57. 0, NULL, &fDefCharUsed );
  58. mptr = (LPBYTE)LocalAlloc( LMEM_FIXED, iCnt );
  59. WideCharToMultiByte (CP_ACP, 0, string, -1, mptr,
  60. iCnt, NULL, &fDefCharUsed );
  61. rValue = atoi(mptr);
  62. LocalFree( (HLOCAL)mptr );
  63. return( rValue);
  64. }
  65. else
  66. {
  67. //on the safe side
  68. if( iCnt >= INT_SIZE_LENGTH ) szAnsi[INT_SIZE_LENGTH-1] = 0;
  69. return( atoi(szAnsi) );
  70. }
  71. }
  72. else
  73. {
  74. WideCharToMultiByte (CP_ACP, 0, string, INT_SIZE_LENGTH,
  75. szAnsi, INT_SIZE_LENGTH, NULL, &fDefCharUsed);
  76. return (atoi (szAnsi));
  77. }
  78. #else
  79. return (atoi (string));
  80. #endif
  81. } // end of MyAtoi()
  82. LONG MyAtol (LPTSTR string)
  83. {
  84. CHAR szAnsi [LONG_SIZE_LENGTH];
  85. BOOL fDefCharUsed;
  86. #ifdef UNICODE
  87. BOOL bDBCS;
  88. LCID lcid = GetThreadLocale();
  89. bDBCS = ( (PRIMARYLANGID(LANGIDFROMLCID(lcid)) == LANG_JAPANESE) ||
  90. (PRIMARYLANGID(LANGIDFROMLCID(lcid)) == LANG_KOREAN) ||
  91. (PRIMARYLANGID(LANGIDFROMLCID(lcid)) == LANG_CHINESE)
  92. );
  93. if (bDBCS)
  94. {
  95. int iCnt;
  96. if( !(iCnt = WideCharToMultiByte (CP_ACP, 0, string, -1,
  97. szAnsi, LONG_SIZE_LENGTH, NULL, &fDefCharUsed)) )
  98. {
  99. return FALSE;
  100. }
  101. //on the safe side
  102. if( iCnt >= LONG_SIZE_LENGTH )
  103. szAnsi[LONG_SIZE_LENGTH-1] = 0;
  104. }
  105. else
  106. {
  107. WideCharToMultiByte (CP_ACP, 0, string, LONG_SIZE_LENGTH,
  108. szAnsi, LONG_SIZE_LENGTH, NULL, &fDefCharUsed);
  109. }
  110. return (atol (szAnsi));
  111. #else
  112. return (atol (string));
  113. #endif
  114. } // end of MyAtol()
  115. //*****************************************************************
  116. //
  117. // MyItoa
  118. //
  119. // Purpose : To convert from ANSI to Unicode string after
  120. // calling CRT itoa function.
  121. //
  122. //*****************************************************************
  123. LPTSTR MyItoa (INT value, LPTSTR string, INT radix)
  124. {
  125. CHAR szAnsi [INT_SIZE_LENGTH];
  126. #ifdef UNICODE
  127. _itoa (value, szAnsi, radix);
  128. MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, szAnsi, -1,
  129. string, INT_SIZE_LENGTH);
  130. #else
  131. _itoa (value, string, radix);
  132. #endif
  133. return (string);
  134. } // end of MyItoa()
  135. LPTSTR MyUltoa (unsigned long value, LPTSTR string, INT radix)
  136. {
  137. CHAR szAnsi [LONG_SIZE_LENGTH];
  138. #ifdef UNICODE
  139. _ultoa (value, szAnsi, radix);
  140. MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, szAnsi, -1,
  141. string, LONG_SIZE_LENGTH);
  142. #else
  143. _ultoa (value, string, radix);
  144. #endif
  145. return (string);
  146. } // end of MyUltoa()
  147. //*****************************************************************
  148. //
  149. // MySplitpath
  150. //
  151. // Purpose : To convert from ANSI to Unicode string before
  152. // calling CRT strtok function.
  153. //
  154. //*****************************************************************
  155. VOID MySplitpath (LPTSTR path,
  156. LPTSTR drive,
  157. LPTSTR dir,
  158. LPTSTR fname,
  159. LPTSTR ext)
  160. {
  161. register LPTSTR p;
  162. LPTSTR last_slash = NULL, dot = NULL;
  163. WORD len;
  164. /* we assume that the path argument has the following form, where any
  165. * or all of the components may be missing.
  166. *
  167. * <drive><dir><fname><ext>
  168. *
  169. * and each of the components has the following expected form(s)
  170. *
  171. * drive:
  172. * 0 to _MAX_DRIVE-1 characters, the last of which, if any, is a
  173. * ':'
  174. * dir:
  175. * 0 to _MAX_DIR-1 characters in the form of an absolute path
  176. * (leading '/' or '\') or relative path, the last of which, if
  177. * any, must be a '/' or '\'. E.g -
  178. * absolute path:
  179. * \top\next\last\ ; or
  180. * /top/next/last/
  181. * relative path:
  182. * top\next\last\ ; or
  183. * top/next/last/
  184. * Mixed use of '/' and '\' within a path is also tolerated
  185. * fname:
  186. * 0 to _MAX_FNAME-1 characters not including the '.' character
  187. * ext:
  188. * 0 to _MAX_EXT-1 characters where, if any, the first must be a
  189. * '.'
  190. *
  191. */
  192. /* extract drive letter and :, if any */
  193. if (*(path + _MAX_DRIVE - 2) == TEXT(':'))
  194. {
  195. if (drive)
  196. {
  197. _tcsncpy(drive, path, _MAX_DRIVE - 1);
  198. *(drive + _MAX_DRIVE-1) = TEXT('\0');
  199. }
  200. path += _MAX_DRIVE - 1;
  201. }
  202. else if (drive)
  203. *drive = TEXT('\0');
  204. /* extract path string, if any. Path now points to the first character
  205. * of the path, if any, or the filename or extension, if no path was
  206. * specified. Scan ahead for the last occurence, if any, of a '/' or
  207. * '\' path separator character. If none is found, there is no path.
  208. * We will also note the last '.' character found, if any, to aid in
  209. * handling the extension.
  210. */
  211. for (last_slash = NULL, p = path; *p; p++)
  212. {
  213. if (*p == TEXT('/') || *p == TEXT('\\')) /* point to one beyond for later copy */
  214. last_slash = p + 1;
  215. else if (*p == TEXT('.'))
  216. dot = p;
  217. }
  218. if (last_slash)
  219. {
  220. /* found a path - copy up through last_slash or max. characters
  221. * allowed, whichever is smaller
  222. */
  223. if (dir)
  224. {
  225. len = (WORD)__min((WORD)(last_slash - path) / sizeof(TCHAR), _MAX_DIR - 1);
  226. _tcsncpy(dir, path, len);
  227. *(dir + len) = TEXT('\0');
  228. }
  229. path = last_slash;
  230. }
  231. else if (dir) /* no path found */
  232. *dir = TEXT('\0');
  233. /* extract file name and extension, if any. Path now points to the
  234. * first character of the file name, if any, or the extension if no
  235. * file name was given. Dot points to the '.' beginning the extension,
  236. * if any.
  237. */
  238. if (dot && (dot >= path))
  239. {
  240. /* found the marker for an extension - copy the file name up to
  241. * the '.'.
  242. */
  243. if (fname)
  244. {
  245. len = (WORD)__min((WORD)(dot - path) / sizeof(TCHAR), _MAX_FNAME - 1);
  246. _tcsncpy(fname, path, len);
  247. *(fname + len) = TEXT('\0');
  248. }
  249. /* now we can get the extension - remember that p still points
  250. * to the terminating nul character of path.
  251. */
  252. if (ext)
  253. {
  254. len = (WORD)__min((WORD)(p - dot) / sizeof(TCHAR), _MAX_EXT - 1);
  255. _tcsncpy(ext, dot, len);
  256. *(ext + len) = TEXT('\0');
  257. }
  258. }
  259. else
  260. {
  261. /* found no extension, give empty extension and copy rest of
  262. * string into fname.
  263. */
  264. if (fname)
  265. {
  266. len = (WORD)__min((WORD)(p - path) / sizeof (TCHAR), _MAX_FNAME - 1);
  267. _tcsncpy(fname, path, len);
  268. *(fname + len) = TEXT('\0');
  269. }
  270. if (ext)
  271. *ext = TEXT('\0');
  272. }
  273. } // end of MySplitpath()
  274. LPTSTR SkipProgramName (LPTSTR lpCmdLine)
  275. {
  276. LPTSTR p = lpCmdLine;
  277. BOOL bInQuotes = FALSE;
  278. //
  279. // Skip executable name
  280. //
  281. for (p; *p; p = CharNext(p))
  282. {
  283. if ((*p == TEXT(' ') || *p == TEXT('\t')) && !bInQuotes)
  284. break;
  285. if (*p == TEXT('\"'))
  286. bInQuotes = !bInQuotes;
  287. }
  288. while (*p == TEXT(' ') || *p == TEXT('\t'))
  289. p++;
  290. return (p);
  291. }