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.

491 lines
13 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. tnetcall.c
  5. Abstract:
  6. This module contains code which exercises the NetBIOS dll and driver.
  7. Author:
  8. Colin Watson (ColinW) 13-Mar-1991
  9. Environment:
  10. Application mode
  11. Revision History:
  12. Dave Beaver (DBeaver) 10 August 1991
  13. Modify to support multiple LAN numbers
  14. Jerome Nantel (w-jeromn) 23 August 1991
  15. Add Event Signaling testing
  16. --*/
  17. #include <nt.h>
  18. #include <ntrtl.h>
  19. #include <nturtl.h>
  20. #define WIN32_CONSOLE_APP
  21. #include <windows.h>
  22. #include <nb30.h>
  23. #include <stdio.h>
  24. // 1234567890123456
  25. #define SPACES " "
  26. #define TIMEOUT 60000 // Time out for wait, set at 1 minute
  27. #define Hi "Come here Dave, I need you"
  28. #define SEND 1
  29. #define RCV 0
  30. NCB myncb[2];
  31. CHAR Buffer[16384+1024];
  32. CHAR Buffer2[16384+1024];
  33. ULONG lanNumber=0;
  34. UCHAR lsn;
  35. HANDLE twoEvent[2];
  36. int count; // frame count
  37. BOOLEAN verbose=FALSE;
  38. BOOLEAN rxany=FALSE;
  39. BOOLEAN rxanyany=FALSE;
  40. BOOLEAN input=TRUE;
  41. BOOLEAN output=TRUE;
  42. int QuietCount = 50;
  43. UCHAR name_number;
  44. VOID
  45. usage (
  46. VOID
  47. )
  48. {
  49. printf("usage: tsrnetb -c|l [-[a|r]] [-[i|o]] [-n:lan number][-h] <remote computername> <my computername>\n");
  50. printf(" -c specifies calling, -l specifies listener\n");
  51. printf(" -a specifies rx any, any, -r specifies rx any\n");
  52. printf(" -i specifies rx only, -o specifies tx only\n");
  53. printf(" -d specifies delay with alerts on each tx/rx\n");
  54. printf(" -n specifies the lan number (0 is the default)\n");
  55. printf(" -h specifies that addresses are hexadecimal numbers \n");
  56. printf(" rather than strings.\n");
  57. printf(" -g use group name for the connection\n");
  58. printf(" -v verbose\n");
  59. printf(" -s silent\n");
  60. printf(" -t token ring, lan status alert (names ignored)\n");
  61. printf(" -q quiet (print r every 50 receives\n");
  62. printf(" final two arguments are the remote and local computer names.\n");
  63. }
  64. VOID
  65. ClearNcb( PNCB pncb ) {
  66. RtlZeroMemory( pncb , sizeof (NCB) );
  67. RtlMoveMemory( pncb->ncb_name, SPACES, sizeof(SPACES)-1 );
  68. RtlMoveMemory( pncb->ncb_callname, SPACES, sizeof(SPACES)-1 );
  69. }
  70. VOID StartSend()
  71. {
  72. ClearNcb( &(myncb[0]) );
  73. if ( output == FALSE ) {
  74. ResetEvent(twoEvent[SEND]);
  75. return;
  76. }
  77. myncb[0].ncb_command = NCBSEND | ASYNCH;
  78. myncb[0].ncb_lana_num = (UCHAR)lanNumber;
  79. myncb[0].ncb_buffer = Buffer;
  80. myncb[0].ncb_lsn = lsn;
  81. myncb[0].ncb_event = twoEvent[SEND];
  82. RtlMoveMemory( Buffer, Hi, sizeof( Hi ));
  83. sprintf( Buffer, "%s %d\n", Hi, count );
  84. if ( verbose == TRUE ) {
  85. printf( "Tx: %s", Buffer );
  86. }
  87. count++;
  88. myncb[0].ncb_length = (WORD)sizeof(Buffer);
  89. Netbios( &(myncb[0]) );
  90. }
  91. VOID StartRcv()
  92. {
  93. ClearNcb( &(myncb[1]) );
  94. if ( input == FALSE ) {
  95. ResetEvent(twoEvent[RCV]);
  96. return;
  97. }
  98. if ((rxany == FALSE) &&
  99. (rxanyany == FALSE)) {
  100. myncb[1].ncb_command = NCBRECV | ASYNCH;
  101. } else {
  102. myncb[1].ncb_command = NCBRECVANY | ASYNCH;
  103. }
  104. myncb[1].ncb_lana_num = (UCHAR)lanNumber;
  105. myncb[1].ncb_length = sizeof( Buffer2 );
  106. myncb[1].ncb_buffer = Buffer2;
  107. if ( rxany == FALSE ) {
  108. if ( rxanyany == FALSE ) {
  109. myncb[1].ncb_lsn = lsn;
  110. } else {
  111. myncb[1].ncb_num = 0xff;
  112. }
  113. } else{
  114. myncb[1].ncb_num = name_number;
  115. }
  116. myncb[1].ncb_lsn = lsn;
  117. myncb[1].ncb_event = twoEvent[RCV];
  118. Netbios( &(myncb[1]) );
  119. }
  120. int
  121. _cdecl
  122. main (argc, argv)
  123. int argc;
  124. char *argv[];
  125. {
  126. int i,j;
  127. int rcvCount=0;
  128. CHAR localName[17];
  129. CHAR remoteName[17];
  130. CHAR localTemp[32];
  131. CHAR remoteTemp[32];
  132. BOOLEAN gotFirst=FALSE;
  133. BOOLEAN asHex=FALSE;
  134. BOOLEAN listen=FALSE;
  135. BOOLEAN quiet=FALSE;
  136. BOOLEAN delay=FALSE;
  137. BOOLEAN group=FALSE;
  138. BOOLEAN silent=FALSE;
  139. BOOLEAN lanalert=FALSE;
  140. DWORD tevent;
  141. BOOLEAN ttwo=FALSE;
  142. if ( argc < 4 || argc > 9) {
  143. usage ();
  144. return 1;
  145. }
  146. //
  147. // dbeaver: added switch to allow 32 byte hex string as name to facilitate
  148. // testing under unusual circumstances
  149. //
  150. for (j=1;j<16;j++ ) {
  151. localTemp[j] = ' ';
  152. remoteTemp[j] = ' ';
  153. }
  154. //
  155. // parse the switches
  156. //
  157. for (i=1;i<argc ;i++ ) {
  158. if (argv[i][0] == '-') {
  159. switch (argv[i][1]) {
  160. case 'n':
  161. if (!NT_SUCCESS(RtlCharToInteger (&argv[i][3], 10, &lanNumber))) {
  162. usage ();
  163. return 1;
  164. }
  165. break;
  166. case 'h':
  167. asHex = TRUE;
  168. break;
  169. case 'c':
  170. listen = FALSE;
  171. break;
  172. case 'a':
  173. rxany = TRUE;
  174. break;
  175. case 'r':
  176. rxanyany = TRUE;
  177. break;
  178. case 'i':
  179. output = FALSE;
  180. break;
  181. case 'o':
  182. input = FALSE;
  183. break;
  184. case 'd':
  185. delay = FALSE;
  186. break;
  187. case 'l':
  188. listen = TRUE;
  189. break;
  190. case 'q':
  191. quiet = TRUE;
  192. silent = TRUE;
  193. break;
  194. case 'g':
  195. group = TRUE;
  196. break;
  197. case 'v':
  198. verbose = TRUE;
  199. break;
  200. case 's':
  201. silent = TRUE;
  202. break;
  203. case 't':
  204. lanalert = TRUE;
  205. break;
  206. default:
  207. usage ();
  208. return 1;
  209. break;
  210. }
  211. } else {
  212. //
  213. // not a switch must be a name
  214. //
  215. if (gotFirst != TRUE) {
  216. RtlMoveMemory (remoteTemp, argv[i], lstrlenA( argv[i] ));
  217. gotFirst = TRUE;
  218. } else {
  219. RtlMoveMemory (localTemp, argv[i], lstrlenA( argv[i] ));
  220. }
  221. }
  222. }
  223. if ((rxany == TRUE) &&
  224. (rxanyany == TRUE)) {
  225. usage();
  226. return 1;
  227. }
  228. if ((input == FALSE) &&
  229. (output == FALSE)) {
  230. usage();
  231. return 1;
  232. }
  233. if (asHex) {
  234. RtlZeroMemory (localName, 16);
  235. RtlZeroMemory (remoteName, 16);
  236. for (j=0;j<16 ;j+=4) {
  237. RtlCharToInteger (&localTemp[j*2], 16, (PULONG)&localName[j]);
  238. }
  239. for (j=0;j<16 ;j+=4) {
  240. RtlCharToInteger (&remoteTemp[j*2], 16, (PULONG)&remoteName[j]);
  241. }
  242. } else {
  243. for (j=1;j<16;j++ ) {
  244. localName[j] = ' ';
  245. remoteName[j] = ' ';
  246. }
  247. RtlMoveMemory( localName, localTemp, 16);
  248. RtlMoveMemory( remoteName, remoteTemp, 16);
  249. }
  250. for ( i=0; i<2; i++ ) {
  251. if (( twoEvent[i] = CreateEvent( NULL, TRUE, FALSE, NULL )) == NULL ) {
  252. /* Could not get event handle. Abort */
  253. printf("Could not test event signaling.\n");
  254. return 1;
  255. }
  256. }
  257. printf( "Starting NetBios\n" );
  258. // Reset
  259. ClearNcb( &(myncb[0]) );
  260. myncb[0].ncb_command = NCBRESET;
  261. myncb[0].ncb_lsn = 0; // Request resources
  262. myncb[0].ncb_lana_num = (UCHAR)lanNumber;
  263. myncb[0].ncb_callname[0] = 0; // 16 sessions
  264. myncb[0].ncb_callname[1] = 0; // 16 commands
  265. myncb[0].ncb_callname[2] = 0; // 8 names
  266. myncb[0].ncb_callname[3] = 0; // Don't want the reserved address
  267. Netbios( &(myncb[0]) );
  268. if ( lanalert == TRUE ) {
  269. ClearNcb( &(myncb[0]) );
  270. myncb[0].ncb_command = NCBLANSTALERT;
  271. myncb[0].ncb_lana_num = (UCHAR)lanNumber;
  272. Netbios( &(myncb[0]) );
  273. if ( myncb[0].ncb_retcode != NRC_GOODRET ) {
  274. printf( " LanStatusAlert failed %x", myncb[1].ncb_retcode);
  275. }
  276. return 0;
  277. }
  278. // Add name
  279. ClearNcb( &(myncb[0]) );
  280. if ( group == FALSE) {
  281. myncb[0].ncb_command = NCBADDNAME;
  282. } else {
  283. myncb[0].ncb_command = NCBADDGRNAME;
  284. }
  285. RtlMoveMemory( myncb[0].ncb_name, localName, 16);
  286. myncb[0].ncb_lana_num = (UCHAR)lanNumber;
  287. Netbios( &(myncb[0]) );
  288. name_number = myncb[0].ncb_num;
  289. if ( listen == FALSE ) {
  290. // Call
  291. printf( "\nStarting Call " );
  292. ClearNcb( &(myncb[0]) );
  293. myncb[0].ncb_command = NCBCALL | ASYNCH;
  294. RtlMoveMemory( myncb[0].ncb_name, localName, 16);
  295. RtlMoveMemory( myncb[0].ncb_callname,remoteName, 16);
  296. myncb[0].ncb_lana_num = (UCHAR)lanNumber;
  297. myncb[0].ncb_sto = myncb[0].ncb_rto = 120; // 120*500 milliseconds timeout
  298. myncb[0].ncb_num = name_number;
  299. myncb[0].ncb_event = twoEvent[0];
  300. while ( TRUE) {
  301. printf("\nStart NCB CALL ");
  302. Netbios( &(myncb[0]) );
  303. printf( " Call returned " );
  304. if ( myncb[0].ncb_cmd_cplt == NRC_PENDING ) {
  305. if ( WaitForSingleObject( twoEvent[0], TIMEOUT ) ) {
  306. // Wait timed out, no return
  307. printf("ERROR: Wait timed out, event not signaled.\n");
  308. }
  309. }
  310. printf( " Call completed\n" );
  311. lsn = myncb[0].ncb_lsn;
  312. if ( myncb[0].ncb_retcode == NRC_GOODRET ) {
  313. // Success
  314. break;
  315. }
  316. printf("Call completed with error %lx, retry", myncb[0].ncb_retcode );
  317. Sleep(5);
  318. }
  319. } else {
  320. printf( "\nStarting Listen " );
  321. // Listen
  322. ClearNcb( &(myncb[0]) );
  323. myncb[0].ncb_command = NCBLISTEN | ASYNCH;
  324. RtlMoveMemory( myncb[0].ncb_name, localName, 16);
  325. RtlMoveMemory( myncb[0].ncb_callname, remoteName, 16);
  326. myncb[0].ncb_lana_num = (UCHAR)lanNumber;
  327. myncb[0].ncb_sto = myncb[0].ncb_rto = 120; // 120*500 milliseconds timeout
  328. myncb[0].ncb_num = name_number;
  329. Netbios( &(myncb[0]) );
  330. printf( "Listen returned " );
  331. while ( myncb[0].ncb_cmd_cplt == NRC_PENDING ) {
  332. printf( "." );
  333. Sleep(500);
  334. }
  335. printf( " Listen completed\n" );
  336. if ( myncb[0].ncb_retcode != NRC_GOODRET ) {
  337. printf("ERROR: Could not establish session.\n");
  338. return 1;
  339. }
  340. lsn = myncb[0].ncb_lsn;
  341. }
  342. count = 0;
  343. StartSend();
  344. StartRcv();
  345. while ( TRUE ) {
  346. tevent = WaitForMultipleObjects(2, twoEvent, FALSE, TIMEOUT);
  347. switch ( tevent ) {
  348. case SEND :
  349. // Send completed, start a new one.
  350. if ( silent == FALSE ) {
  351. printf("S");
  352. }
  353. if ( myncb[0].ncb_retcode != NRC_GOODRET ) {
  354. printf( "Send failed %x", myncb[0].ncb_retcode);
  355. goto Cleanup;
  356. }
  357. if ( delay == TRUE ) {
  358. // Wait alertable - useful for debugging APC problems.
  359. NtWaitForSingleObject(
  360. twoEvent[SEND],
  361. TRUE,
  362. NULL );
  363. }
  364. StartSend();
  365. break;
  366. case RCV :
  367. if ( silent == FALSE ) {
  368. printf("R");
  369. }
  370. if ( (quiet == TRUE) && (QuietCount-- == 0) ) {
  371. printf("R");
  372. QuietCount = 50;
  373. }
  374. if ( myncb[1].ncb_retcode != NRC_GOODRET ) {
  375. printf( " Receive failed %x", myncb[1].ncb_retcode);
  376. goto Cleanup;
  377. } else {
  378. if ( verbose == TRUE ) {
  379. printf( "Rx: %s", Buffer2 );
  380. }
  381. }
  382. // Receive completed, start a new one.
  383. if ( delay == TRUE ) {
  384. // Wait alertable
  385. NtWaitForSingleObject(
  386. twoEvent[RCV],
  387. TRUE,
  388. NULL );
  389. }
  390. StartRcv();
  391. rcvCount++;
  392. break;
  393. default:
  394. printf("WARNING: Wait timed out, no event signaled.\n");
  395. break;
  396. }
  397. }
  398. Cleanup:
  399. // Hangup
  400. ClearNcb( &(myncb[0]) );
  401. myncb[0].ncb_command = NCBHANGUP;
  402. myncb[0].ncb_lana_num = (UCHAR)lanNumber;
  403. myncb[0].ncb_lsn = lsn;
  404. Netbios( &(myncb[0]) );
  405. if ( myncb[0].ncb_retcode != NRC_GOODRET ) {
  406. printf( " Hangup failed %x", myncb[1].ncb_retcode);
  407. }
  408. // Reset
  409. ClearNcb( &(myncb[0]) );
  410. myncb[0].ncb_command = NCBRESET;
  411. myncb[0].ncb_lsn = 1; // Free resources
  412. myncb[0].ncb_lana_num = (UCHAR)lanNumber;
  413. Netbios( &(myncb[0]) );
  414. printf( "Ending NetBios\n" );
  415. // Close handles
  416. CloseHandle( twoEvent[0] );
  417. CloseHandle( twoEvent[1] );
  418. return 0;
  419. }
  420.