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.

474 lines
9.0 KiB

  1. /*++
  2. Copyright (c) 1999-2000 Microsoft Corporation
  3. Module Name:
  4. util.c
  5. Abstract:
  6. Contains utilities for Win9X debugger extensions.
  7. Author:
  8. Scott Holden (sholden) 24-Apr-1999
  9. Revision History:
  10. --*/
  11. #include "tcpipxp.h"
  12. #include "tcpipkd.h"
  13. #if TCPIPKD
  14. unsigned short
  15. htons(unsigned short hosts) {
  16. return ((hosts << 8) | (hosts >> 8));
  17. }
  18. int __cdecl
  19. mystrnicmp(
  20. const char *first,
  21. const char *last,
  22. size_t count
  23. )
  24. {
  25. int f,l;
  26. if ( count )
  27. {
  28. do {
  29. if ( ((f = (unsigned char)(*(first++))) >= 'A') &&
  30. (f <= 'Z') )
  31. f -= 'A' - 'a';
  32. if ( ((l = (unsigned char)(*(last++))) >= 'A') &&
  33. (l <= 'Z') )
  34. l -= 'A' - 'a';
  35. } while ( --count && f && (f == l) );
  36. return( f - l );
  37. }
  38. return 0;
  39. }
  40. int __cdecl
  41. mystricmp(
  42. const char *str1,
  43. const char *str2
  44. )
  45. {
  46. for (;(*str1 != '\0') && (*str2 != '\0'); str1++, str2++) {
  47. if (toupper(*str1) != toupper(*str2)) {
  48. return *str1 - *str2;
  49. }
  50. }
  51. // Check last character.
  52. return *str1 - *str2;
  53. }
  54. int
  55. myisspace(
  56. int c
  57. )
  58. {
  59. return ( c == ' ' || c == '\n' || c == '\t' || c == '\r' || c == '\f' || c == '\v');
  60. }
  61. unsigned long
  62. mystrtoul(
  63. const char *nptr,
  64. char **endptr,
  65. int base
  66. )
  67. {
  68. unsigned long RetVal = 0;
  69. char szHex[] = "0123456789ABCDEF";
  70. char szOct[] = "01234567";
  71. char *ptr = NULL;
  72. for (; isspace(*nptr); ++nptr) {
  73. }
  74. //
  75. // Optional plus or minus sign is NOT allowed. In retail, we will just
  76. // return a value of 0.
  77. //
  78. ASSERT((*nptr != '-') && (*nptr != '+'));
  79. if (base == 0) {
  80. //
  81. // Need to determine whether we have octal, decimal, or hexidecimal.
  82. //
  83. if ((*nptr == '0') &&
  84. (isdigit(*(nptr + 1)))
  85. ) {
  86. base = 8;
  87. }
  88. else if ((*nptr == '0') &&
  89. (toupper(*(nptr + 1)) == 'X')
  90. ) {
  91. base = 16;
  92. }
  93. else {
  94. base = 10;
  95. }
  96. }
  97. //
  98. // Need to advance beyond the base prefix.
  99. //
  100. if (base == 16) {
  101. if (mystrnicmp(nptr, "0x", 2) == 0) {
  102. nptr += 2;
  103. }
  104. }
  105. //
  106. // Both octal and decimal prefixes can be handled by the regular
  107. // path.
  108. //
  109. //
  110. // Now scan for digits.
  111. //
  112. for (; *nptr != '\0'; ++nptr) {
  113. if (base == 10) {
  114. if (isdigit(*nptr)) {
  115. RetVal = RetVal * 10 + (*nptr - '0');
  116. }
  117. else {
  118. break;
  119. }
  120. }
  121. else if (base == 16) {
  122. ptr = strchr(szHex, toupper(*nptr));
  123. if (ptr != NULL) {
  124. RetVal = RetVal * 16 + (unsigned long)(ptr - szHex);
  125. }
  126. else {
  127. break;
  128. }
  129. //
  130. // Old code.
  131. //
  132. // if (strchr("0123456789ABCDEF", _totupper(*nptr)) != NULL)
  133. // {
  134. // if (isdigit(*nptr))
  135. // {
  136. // RetVal = RetVal * 16 + (*nptr - '0');
  137. // }
  138. // else
  139. // {
  140. // RetVal = RetVal * 16 + ((_totupper(*nptr) - 'A') + 10);
  141. // }
  142. // }
  143. }
  144. else if (base == 8) {
  145. ptr = strchr(szOct, toupper(*nptr));
  146. if (ptr != NULL) {
  147. RetVal = RetVal * 8 + (unsigned long)(ptr - szOct);
  148. }
  149. else {
  150. break;
  151. }
  152. }
  153. else {
  154. ASSERT(FALSE);
  155. }
  156. }
  157. //
  158. // Tell them what character we stopped on.
  159. //
  160. if (endptr != NULL) {
  161. *endptr = (char *)nptr;
  162. }
  163. return(RetVal);
  164. }
  165. char *mystrtok ( char *string, char * control )
  166. {
  167. static unsigned char *str;
  168. char *p, *s;
  169. if( string )
  170. str = string;
  171. if( str == NULL || *str == '\0' )
  172. return NULL;
  173. //
  174. // Skip leading delimiters...
  175. //
  176. for( ; *str; str++ ) {
  177. for( s=control; *s; s++ ) {
  178. if( *str == *s )
  179. break;
  180. }
  181. if( *s == '\0' )
  182. break;
  183. }
  184. //
  185. // Was it was all delimiters?
  186. //
  187. if( *str == '\0' ) {
  188. str = NULL;
  189. return NULL;
  190. }
  191. //
  192. // We've got a string, terminate it at first delimeter
  193. //
  194. for( p = str+1; *p; p++ ) {
  195. for( s = control; *s; s++ ) {
  196. if( *p == *s ) {
  197. s = str;
  198. *p = '\0';
  199. str = p+1;
  200. return s;
  201. }
  202. }
  203. }
  204. //
  205. // We've got a string that ends with the NULL
  206. //
  207. s = str;
  208. str = NULL;
  209. return s;
  210. }
  211. int
  212. CreateArgvArgc(
  213. CHAR *pProgName,
  214. CHAR *argv[20],
  215. CHAR *pCmdLine
  216. )
  217. {
  218. CHAR *pEnd;
  219. int argc = 0;
  220. memset(argv, 0, sizeof(argv));
  221. while (*pCmdLine != '\0') {
  222. // Skip to first whitespace.
  223. while (isspace(*pCmdLine)) {
  224. pCmdLine++;
  225. }
  226. // Break at EOL
  227. if (*pCmdLine == '\0') {
  228. break;
  229. }
  230. // Check for '' or ""
  231. if ((*pCmdLine == '"') || (*pCmdLine == '\'')) {
  232. CHAR cTerm = *pCmdLine++;
  233. for (pEnd = pCmdLine; (*pEnd != cTerm) && (*pEnd != '\0');) {
  234. pEnd++;
  235. }
  236. } else {
  237. // Find the end.
  238. for (pEnd = pCmdLine; !isspace(*pEnd) && (*pEnd != '\0');) {
  239. pEnd++;
  240. }
  241. }
  242. if (*pEnd != '\0') {
  243. *pEnd = '\0';
  244. pEnd++;
  245. }
  246. argv[argc] = pCmdLine;
  247. argc++;
  248. pCmdLine = pEnd;
  249. }
  250. return argc;
  251. }
  252. NTSTATUS
  253. ParseSrch(
  254. PCHAR args[],
  255. ULONG ulDefaultOp,
  256. ULONG ulAllowedOps,
  257. PTCPIP_SRCH pSrch
  258. )
  259. {
  260. ULONG cbArgs;
  261. ULONG Status = STATUS_SUCCESS;
  262. pSrch->ulOp = ulDefaultOp;
  263. // If we need to parse out an addr, do it first...
  264. if (*args == NULL)
  265. {
  266. // If default is invalid (i.e. NO default), return error.
  267. if (pSrch->ulOp == 0 ||
  268. (ulAllowedOps & TCPIP_SRCH_PTR_LIST))
  269. {
  270. Status = STATUS_INVALID_PARAMETER;
  271. }
  272. goto done;
  273. }
  274. if (ulAllowedOps & TCPIP_SRCH_PTR_LIST)
  275. {
  276. pSrch->ListAddr = mystrtoul(*args, 0, 16);
  277. args++;
  278. if (*args == NULL)
  279. {
  280. if (pSrch->ulOp == 0)
  281. {
  282. Status = STATUS_INVALID_PARAMETER;
  283. }
  284. goto done;
  285. }
  286. }
  287. if (mystricmp(*args, "all") == 0)
  288. {
  289. pSrch->ulOp = TCPIP_SRCH_ALL;
  290. }
  291. else if (mystricmp(*args, "ipaddr") == 0)
  292. {
  293. CHAR szIP[20];
  294. CHAR *p;
  295. ULONG i;
  296. pSrch->ulOp = TCPIP_SRCH_IPADDR;
  297. pSrch->ipaddr = 0;
  298. args++;
  299. if (*args == NULL || strlen(*args) >= 15)
  300. {
  301. Status = STATUS_INVALID_PARAMETER;
  302. goto done;
  303. }
  304. strcpy(szIP, *args);
  305. p = mystrtok(szIP, ".");
  306. for (i = 0; i < 4; i++)
  307. {
  308. pSrch->ipaddr |= (atoi(p) << (i*8));
  309. p = mystrtok(NULL, ".");
  310. if (p == NULL)
  311. {
  312. break;
  313. }
  314. }
  315. if (i != 3)
  316. {
  317. Status = STATUS_INVALID_PARAMETER;
  318. goto done;
  319. }
  320. }
  321. else if (mystricmp(*args, "port") == 0)
  322. {
  323. pSrch->ulOp = TCPIP_SRCH_PORT;
  324. args++;
  325. if (*args == NULL)
  326. {
  327. Status = STATUS_INVALID_PARAMETER;
  328. goto done;
  329. }
  330. pSrch->port = (USHORT)atoi(*args);
  331. }
  332. else if (mystricmp(*args, "prot") == 0)
  333. {
  334. pSrch->ulOp = TCPIP_SRCH_PROT;
  335. args++;
  336. if (*args == NULL)
  337. {
  338. Status = STATUS_INVALID_PARAMETER;
  339. goto done;
  340. }
  341. if (mystricmp(*args, "raw") == 0)
  342. {
  343. pSrch->prot = PROTOCOL_RAW;
  344. }
  345. else if (mystricmp(*args, "udp") == 0)
  346. {
  347. pSrch->prot = PROTOCOL_UDP;
  348. }
  349. else if (mystricmp(*args, "tcp") == 0)
  350. {
  351. pSrch->prot = PROTOCOL_TCP;
  352. }
  353. else
  354. {
  355. Status = STATUS_INVALID_PARAMETER;
  356. goto done;
  357. }
  358. }
  359. else if (mystricmp(*args, "context") == 0)
  360. {
  361. pSrch->ulOp = TCPIP_SRCH_CONTEXT;
  362. args++;
  363. if (*args == NULL)
  364. {
  365. Status = STATUS_INVALID_PARAMETER;
  366. goto done;
  367. }
  368. pSrch->context = atoi(*args);
  369. }
  370. else if (mystricmp(*args, "stats") == 0)
  371. {
  372. pSrch->ulOp = TCPIP_SRCH_STATS;
  373. }
  374. else
  375. {
  376. // Invalid srch request. Fail.
  377. Status = STATUS_INVALID_PARAMETER;
  378. goto done;
  379. }
  380. // Now see if this is an expected type!!!
  381. if ((pSrch->ulOp & ulAllowedOps) == 0)
  382. {
  383. dprintf("invalid operation for current srch" ENDL);
  384. Status = STATUS_INVALID_PARAMETER;
  385. goto done;
  386. }
  387. done:
  388. return (Status);
  389. }
  390. #endif // TCPIPKD