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.

1067 lines
30 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1994 - 1999
  6. //
  7. // File: nb.c
  8. //
  9. //--------------------------------------------------------------------------
  10. /////////////////////////////////////////////////////////////////////////
  11. //
  12. // Filename: nb.c
  13. //
  14. // Description: This file contains common routines for NetBios I/O
  15. // routines for use with IPC raw network performance
  16. // tests.
  17. // This module is written using win32 API calls.
  18. //
  19. // Authors: Scott Holden (Translator from NT API to win32 API)
  20. // Mahesh Keni (Mahesh wrote this application using mostly
  21. // NT native API calls)
  22. //
  23. /////////////////////////////////////////////////////////////////////////
  24. #include "rawcom.h"
  25. #include "nb.h"
  26. /************************************************************************/
  27. /*++
  28. This routine is responsible for adding a given name on a net.
  29. --*/
  30. UCHAR
  31. NetBIOS_AddName(
  32. IN PCHAR LocalName,
  33. IN UCHAR LanaNumber,
  34. OUT PUCHAR NameNumber)
  35. {
  36. NCB AddNameNCB;
  37. UCHAR RetCode;
  38. //printf("\n\nNetBIOS_AddName::\n LocalName: %s\n LanaNumber: %uc \n\n", LocalName, LanaNumber);
  39. RetCode =0;
  40. ClearNCB(&AddNameNCB); // does cleanup everything
  41. AddNameNCB.ncb_command = NCBADDNAME;
  42. RtlMoveMemory(AddNameNCB.ncb_name,LocalName,NCBNAMSZ);
  43. AddNameNCB.ncb_lana_num = LanaNumber;
  44. RetCode = Netbios(&AddNameNCB); // submit to NetBIOS
  45. if (AddNameNCB.ncb_retcode != NRC_GOODRET) {
  46. printf("Addname failed %x\n", AddNameNCB.ncb_retcode);
  47. return RetCode;
  48. }
  49. *NameNumber = AddNameNCB.ncb_num;
  50. return RetCode;
  51. }
  52. /************************************************************************/
  53. /*++
  54. This routine is responsible for deleting a given name on a net.
  55. --*/
  56. UCHAR
  57. NetBIOS_DelName(
  58. IN PCHAR LocalName,
  59. IN UCHAR LanaNumber)
  60. {
  61. NCB DelNameNCB;
  62. UCHAR RetCode;
  63. RetCode =0;
  64. ClearNCB(&DelNameNCB); // does cleanup everything
  65. DelNameNCB.ncb_command = NCBDELNAME;
  66. RtlMoveMemory(DelNameNCB.ncb_name,LocalName,NCBNAMSZ);
  67. DelNameNCB.ncb_lana_num = LanaNumber;
  68. RetCode = Netbios(&DelNameNCB); // submit to NetBIOS
  69. if (DelNameNCB.ncb_retcode != NRC_GOODRET) {
  70. printf("Delname failed %x\n", DelNameNCB.ncb_retcode);
  71. return RetCode;
  72. }
  73. return RetCode;
  74. }
  75. /************************************************************************/
  76. UCHAR
  77. NetBIOS_Reset(
  78. IN UCHAR LanaNumber)
  79. {
  80. NCB ResetNCB;
  81. UCHAR RetCode;
  82. RetCode =0;
  83. ClearNCB(&ResetNCB); // does cleanup everything
  84. ResetNCB.ncb_command = NCBRESET;
  85. ResetNCB.ncb_lana_num = LanaNumber;
  86. ResetNCB.ncb_lsn = 0;
  87. ResetNCB.ncb_callname[0] = 0; //16 sessions
  88. ResetNCB.ncb_callname[1] = 0; //16 commands
  89. ResetNCB.ncb_callname[2] = 0; //8 names
  90. RetCode = Netbios(&ResetNCB); // submit to NetBIOS
  91. if (ResetNCB.ncb_retcode != NRC_GOODRET) {
  92. printf("Reset failed %x\n", ResetNCB.ncb_retcode);
  93. return RetCode;
  94. }
  95. return RetCode;
  96. }
  97. /************************************************************************/
  98. // Used only by NetBIOS Client
  99. UCHAR
  100. NetBIOS_Call(
  101. IN USHORT CIndex, // Client Index
  102. IN PCHAR LocalName,
  103. IN PCHAR RemoteName)
  104. {
  105. NCB CallNCB;
  106. NTSTATUS cstatus;
  107. UCHAR RetCode;
  108. RetCode = 0;
  109. ClearNCB(&CallNCB); // does cleanup everything
  110. //printf("\n\nNetBIOS_Call::\n LocalName: %s , RemoteName: %s \n LanaNumber: %c\n\n", \
  111. // LocalName, RemoteName, Clients[CIndex].c_NetB.c_LanaNumber);
  112. CallNCB.ncb_command = NCBCALL | ASYNCH;
  113. CallNCB.ncb_lana_num = (UCHAR) Clients[CIndex].c_NetB.c_LanaNumber;
  114. CallNCB.ncb_lsn = 0Xff;
  115. CallNCB.ncb_sto = CallNCB.ncb_rto = (UCHAR) 1000; // 1000*500 ms timeout
  116. CallNCB.ncb_post = NULL;
  117. // associate an event with this NCB
  118. CallNCB.ncb_event = Clients[CIndex].c_NetB.c_SendEvent;
  119. RtlMoveMemory(CallNCB.ncb_name,LocalName,NCBNAMSZ);
  120. RtlMoveMemory(CallNCB.ncb_callname,RemoteName,NCBNAMSZ);
  121. RetCode = Netbios(&CallNCB); // submit to NetBIOS
  122. if (CallNCB.ncb_cmd_cplt == NRC_PENDING){
  123. cstatus = WaitForSingleObjectEx(CallNCB.ncb_event, // handle of the object to wait for
  124. INFINITE, // wait forever
  125. TRUE); // Alertable
  126. }
  127. if (CallNCB.ncb_cmd_cplt != NRC_GOODRET) {
  128. // MyDbgPrint("NBSRV:Call failed %x\n", CallNCB.ncb_cmd_cplt);
  129. printf("Command completion returns %08x\n", CallNCB.ncb_cmd_cplt);
  130. return CallNCB.ncb_cmd_cplt;
  131. }
  132. // get value for LSN
  133. Clients[CIndex].c_NetB.c_LSN = CallNCB.ncb_lsn;
  134. return CallNCB.ncb_cmd_cplt;
  135. //return STATUS_SUCCESS;
  136. }
  137. /************************************************************************/
  138. UCHAR
  139. NetBIOS_Listen(
  140. IN USHORT TIndex, // Client Index
  141. IN PCHAR LocalName,
  142. IN PCHAR RemoteName,
  143. IN UCHAR NameNumber)
  144. {
  145. NCB ListenNCB;
  146. NTSTATUS lstatus;
  147. UCHAR RetCode;
  148. RetCode =0;
  149. ClearNCB(&ListenNCB); // does cleanup everything
  150. ListenNCB.ncb_command = NCBLISTEN | ASYNCH;
  151. ListenNCB.ncb_lana_num = (UCHAR) Clients[TIndex].c_NetB.c_LanaNumber;
  152. ListenNCB.ncb_sto = ListenNCB.ncb_rto = (UCHAR) 1000;
  153. // 1000*500 ms timeout
  154. ListenNCB.ncb_num = NameNumber;
  155. ListenNCB.ncb_post = NULL;
  156. // associate an event with this NCB
  157. ListenNCB.ncb_event = Clients[TIndex].c_NetB.c_SendEvent;
  158. RtlMoveMemory(ListenNCB.ncb_name,LocalName,NCBNAMSZ);
  159. RtlMoveMemory(ListenNCB.ncb_callname,RemoteName,NCBNAMSZ);
  160. RetCode = Netbios(&ListenNCB); // submit to NetBIOS
  161. if (ListenNCB.ncb_cmd_cplt == NRC_PENDING){
  162. lstatus = WaitForSingleObjectEx(ListenNCB.ncb_event, // handle of the object
  163. INFINITE, // default timeout
  164. TRUE); // alertable
  165. }
  166. if (ListenNCB.ncb_cmd_cplt != NRC_GOODRET) {
  167. //MyDbgPrint("NBSRV:Listen failed %x\n", ListenNCB.ncb_cmd_cplt);
  168. return ListenNCB.ncb_cmd_cplt;
  169. }
  170. // get value for LSN
  171. Clients[TIndex].c_NetB.c_LSN = ListenNCB.ncb_lsn;
  172. return ListenNCB.ncb_cmd_cplt;
  173. }
  174. /************************************************************************/
  175. UCHAR
  176. NetBIOS_Receive(
  177. IN USHORT TIndex,
  178. IN PUCHAR RecvBuffer,
  179. IN USHORT RecvLen)
  180. {
  181. NCB ReceiveNCB;
  182. NTSTATUS rstatus;
  183. UCHAR RetCode;
  184. RetCode =0;
  185. ClearNCB(&ReceiveNCB); // does cleanup everything
  186. ReceiveNCB.ncb_command = NCBRECV | ASYNCH;
  187. ReceiveNCB.ncb_lana_num = (UCHAR) Clients[TIndex].c_NetB.c_LanaNumber;
  188. ReceiveNCB.ncb_lsn = Clients[TIndex].c_NetB.c_LSN;
  189. ReceiveNCB.ncb_buffer = RecvBuffer;
  190. ReceiveNCB.ncb_length = RecvLen;
  191. ReceiveNCB.ncb_event = Clients[TIndex].c_NetB.c_RecvEvent;
  192. RetCode = Netbios(&ReceiveNCB); // submit to NetBIOS
  193. if (ReceiveNCB.ncb_cmd_cplt == NRC_PENDING){
  194. rstatus = WaitForSingleObjectEx(ReceiveNCB.ncb_event, // handle to object
  195. INFINITE, // default timeout
  196. TRUE); // alertable
  197. }
  198. if (ReceiveNCB.ncb_cmd_cplt != NRC_GOODRET) {
  199. //MyDbgPrint("NBSRV:NB:Receive failed %x\n", ReceiveNCB.ncb_cmd_cplt);
  200. }
  201. return ReceiveNCB.ncb_cmd_cplt;
  202. }
  203. /************************************************************************/
  204. UCHAR
  205. NetBIOS_Send(
  206. IN USHORT TIndex,
  207. IN PUCHAR SendBuffer,
  208. IN USHORT SendLen)
  209. {
  210. NCB SendNCB;
  211. NTSTATUS rstatus;
  212. UCHAR RetCode;
  213. RetCode =0;
  214. ClearNCB(&SendNCB); // does cleanup everything
  215. SendNCB.ncb_command = NCBSEND | ASYNCH;
  216. SendNCB.ncb_lana_num = (UCHAR) Clients[TIndex].c_NetB.c_LanaNumber;
  217. SendNCB.ncb_lsn = Clients[TIndex].c_NetB.c_LSN;
  218. SendNCB.ncb_buffer = SendBuffer;
  219. SendNCB.ncb_length = SendLen;
  220. SendNCB.ncb_event = Clients[TIndex].c_NetB.c_SendEvent;
  221. RetCode = Netbios(&SendNCB); // submit to NetBIOS
  222. if (SendNCB.ncb_cmd_cplt == NRC_PENDING){
  223. rstatus = WaitForSingleObjectEx(SendNCB.ncb_event, // handle to object
  224. INFINITE, // default timeout
  225. TRUE); // alertable
  226. }
  227. if (SendNCB.ncb_cmd_cplt != NRC_GOODRET) {
  228. //MyDbgPrint("NBSRV:NBS:Send failed %x RetCode:%x\n",SendNCB.ncb_cmd_cplt,RetCode);
  229. }
  230. return SendNCB.ncb_cmd_cplt;
  231. }
  232. /************************************************************************/
  233. UCHAR
  234. NetBIOS_HangUP(
  235. IN USHORT TIndex)
  236. {
  237. NCB HangUPNCB;
  238. //NTSTATUS rstatus;
  239. UCHAR RetCode;
  240. RetCode = 0;
  241. ClearNCB(&HangUPNCB); // does cleanup everything
  242. HangUPNCB.ncb_command = NCBHANGUP;
  243. HangUPNCB.ncb_lana_num = (UCHAR) Clients[TIndex].c_NetB.c_LanaNumber;
  244. HangUPNCB.ncb_lsn = Clients[TIndex].c_NetB.c_LSN;
  245. RetCode = Netbios(&HangUPNCB); // submit to NetBIOS
  246. if (HangUPNCB.ncb_cmd_cplt != NRC_GOODRET) {
  247. //MyDbgPrint("NBSRV:HangUP failed %x\n", HangUPNCB.ncb_cmd_cplt);
  248. }
  249. return HangUPNCB.ncb_cmd_cplt;
  250. }
  251. /************************************************************************/
  252. UCHAR
  253. NetBIOS_RecvSend(
  254. IN USHORT TIndex,
  255. IN PUCHAR SendBuffer,
  256. IN USHORT SendLen,
  257. IN PUCHAR RecvBuffer,
  258. IN USHORT RecvLen)
  259. {
  260. NCB ReceiveNCB; // Make it a part of client
  261. NCB SendNCB; // Make it a part of client struc
  262. NTSTATUS rstatus, sstatus;
  263. UCHAR RRetCode, SRetCode;
  264. RRetCode = SRetCode = 0;
  265. ClearNCB(&ReceiveNCB); // cleanup everything
  266. ClearNCB(&SendNCB); // cleanup everything
  267. // First post Receive but don't wait as this is for the next
  268. // request block
  269. ReceiveNCB.ncb_command = NCBRECV | ASYNCH;
  270. ReceiveNCB.ncb_lana_num = (UCHAR) Clients[TIndex].c_NetB.c_LanaNumber;
  271. ReceiveNCB.ncb_lsn = Clients[TIndex].c_NetB.c_LSN;
  272. ReceiveNCB.ncb_buffer = RecvBuffer;
  273. ReceiveNCB.ncb_length = RecvLen;
  274. ReceiveNCB.ncb_event = Clients[TIndex].c_NetB.c_RecvEvent;
  275. RRetCode = Netbios(&ReceiveNCB); // submit to NetBIOS
  276. if (ReceiveNCB.ncb_cmd_cplt == NRC_PENDING){
  277. // now do all the send(s)
  278. SendNCB.ncb_command = NCBSEND | ASYNCH;
  279. SendNCB.ncb_lana_num = (UCHAR) Clients[TIndex].c_NetB.c_LanaNumber;
  280. SendNCB.ncb_lsn = Clients[TIndex].c_NetB.c_LSN;
  281. SendNCB.ncb_buffer = SendBuffer;
  282. SendNCB.ncb_length = SendLen;
  283. SendNCB.ncb_event = Clients[TIndex].c_NetB.c_SendEvent;
  284. SRetCode = Netbios(&SendNCB); // submit to NetBIOS
  285. // First wait on Send , if successful then wait on receive
  286. if (SendNCB.ncb_cmd_cplt == NRC_PENDING){
  287. // First wait for the Send to complete
  288. sstatus = WaitForSingleObjectEx(SendNCB.ncb_event,
  289. INFINITE,
  290. TRUE);
  291. }
  292. if (SendNCB.ncb_cmd_cplt != NRC_GOODRET) {
  293. //MyDbgPrint("NBSRV:NBSR:Send failed %x RetCode:%x\n",SendNCB.ncb_cmd_cplt,SRetCode);
  294. // Cancel the receive posted earlier
  295. return SendNCB.ncb_cmd_cplt;
  296. }
  297. // Now wait for the receive to complete
  298. rstatus = WaitForSingleObjectEx(ReceiveNCB.ncb_event,
  299. INFINITE,
  300. TRUE);
  301. // check for status success here
  302. }
  303. if (ReceiveNCB.ncb_cmd_cplt != NRC_GOODRET) {
  304. //MyDbgPrint("NBSRV:NBSR:Receive failed %x RetCode:%x\n",ReceiveNCB.ncb_cmd_cplt,RRetCode);
  305. }
  306. return ReceiveNCB.ncb_cmd_cplt;
  307. }
  308. /************************************************************************/
  309. UCHAR
  310. NetBIOS_SPReceive(
  311. IN USHORT TIndex,
  312. IN NCB *PRecvNCB,
  313. IN USHORT Global, // global= 1 or local = 0
  314. IN PUCHAR RecvBuffer,
  315. IN USHORT RecvLen)
  316. {
  317. UCHAR RetCode;
  318. RetCode =0;
  319. ClearNCB(PRecvNCB); // does cleanup everything
  320. PRecvNCB->ncb_command = NCBRECV | ASYNCH;
  321. PRecvNCB->ncb_lana_num = (UCHAR) Clients[TIndex].c_NetB.c_LanaNumber;
  322. PRecvNCB->ncb_lsn = Clients[TIndex].c_NetB.c_LSN;
  323. PRecvNCB->ncb_buffer = RecvBuffer;
  324. PRecvNCB->ncb_length = RecvLen;
  325. if (Global) {
  326. PRecvNCB->ncb_event = Clients[TIndex].c_NetB.c_RecvEventG;
  327. }
  328. else {
  329. PRecvNCB->ncb_event = Clients[TIndex].c_NetB.c_RecvEvent;
  330. }
  331. RetCode = Netbios(PRecvNCB); // submit to NetBIOS
  332. return RetCode;
  333. }
  334. /************************************************************************/
  335. NTSTATUS
  336. NB_Initialize(
  337. IN USHORT NClients,
  338. IN PCHAR IServerName,
  339. IN USHORT SrvCli)
  340. {
  341. NTSTATUS Istatus;
  342. UCHAR RetCode;
  343. USHORT LanaNum;
  344. CHAR Tmp[10]; // for holding numbers
  345. //
  346. // First Reset all the adapters
  347. // Add the server name if provided otherwise use the default name
  348. // To take care of TCP/IP and other Lana Bases
  349. LanaNum = LanaBase;
  350. // initialize all the named
  351. MyDbgPrint("Initialize both Local/Remote Names\n");
  352. if (SrvCli) { // for server copy the given name as a local
  353. RtlMoveMemory(RemoteName, ALL_CLIENTS, NCBNAMSZ);
  354. if (IServerName) {
  355. RtlMoveMemory(LocalName, IServerName, NCBNAMSZ);
  356. }
  357. else {
  358. RtlMoveMemory(LocalName, PERF_NETBIOS, NCBNAMSZ);
  359. }
  360. }
  361. else { // for a client copy the name as a remote name
  362. if (IServerName) {
  363. RtlMoveMemory(RemoteName, IServerName, NCBNAMSZ);
  364. }
  365. else {
  366. RtlMoveMemory(RemoteName, PERF_NETBIOS, NCBNAMSZ);
  367. }
  368. // copy local name for client
  369. // use Rtl routines
  370. strcpy(LocalName,CLINAME);
  371. strcat(LocalName,_itoa(MachineNumber,Tmp,10));
  372. }
  373. while (LanaNum < LanaCount*2) { // for Jet and TCP/IP
  374. RetCode = NetBIOS_Reset((UCHAR) LanaNum);
  375. if (RetCode) {
  376. MyDbgPrint("Error in Reset\n");
  377. return(Istatus = -1L);
  378. }
  379. // we could assign Lana Numbers to clients and do AddName here too
  380. RetCode = NetBIOS_AddName(LocalName,
  381. (UCHAR) LanaNum,
  382. &NameNumber);
  383. if (RetCode) {
  384. //MyDbgPrint("NB: Error in Add Name retc: %C \n", RetCode);
  385. return (STATUS_UNSUCCESSFUL);
  386. }
  387. // Add the Name number to Client's structure
  388. LanaNum = LanaNum+2;
  389. }
  390. OutputDebugString("NB: Reset Done\n");
  391. return (STATUS_SUCCESS);
  392. }
  393. /************************************************************************/
  394. /*++
  395. This routine is responsible adding a NetBIOS name for the given
  396. thread.
  397. --*/
  398. NTSTATUS
  399. NB_PerClientInit(
  400. IN USHORT CIndex, // client index
  401. IN USHORT SrvCli )
  402. {
  403. //NTSTATUS pstatus;
  404. //UCHAR RetCode;
  405. //CHAR Tmp[10]; // for holding numbers
  406. // initialize proper client data structures
  407. Clients[CIndex].c_client_num = CIndex;
  408. // distribute clients evenly on all net cards
  409. Clients[CIndex].c_NetB.c_LanaNumber = ((CIndex % LanaCount)*2)+LanaBase;
  410. // Add the Name number to Client's structure
  411. Clients[CIndex].c_NetB.c_NameNum = NameNumber;
  412. // Set all events to Null
  413. Clients[CIndex].c_NetB.c_SendEvent = NULL;
  414. Clients[CIndex].c_NetB.c_RecvEvent = NULL;
  415. Clients[CIndex].c_NetB.c_RecvEventG = NULL;
  416. // create events to associate with an NCB for this thread
  417. Clients[CIndex].c_NetB.c_SendEvent = CreateEvent(
  418. NULL,
  419. TRUE, // manual reset event
  420. FALSE, // initial state of the event
  421. NULL); // no event name
  422. Clients[CIndex].c_NetB.c_RecvEvent = CreateEvent(
  423. NULL,
  424. TRUE, // manual reset event
  425. FALSE, // initial state of the event
  426. NULL); // no event name
  427. Clients[CIndex].c_NetB.c_RecvEventG = CreateEvent(
  428. NULL,
  429. TRUE, // manual reset event
  430. FALSE, // initial state of the event
  431. NULL); // no event name
  432. /*
  433. // Create appropriate Name and do Add Name
  434. // For server do Nothing
  435. // for client make a name using machine+Client number
  436. if (!SrvCli) {
  437. // use Rtl routines
  438. strcpy(LocalName,CLINAME);
  439. strcat(LocalName,_itoa(MachineNumber,Tmp,10));
  440. strcat(LocalName,_itoa(CIndex,Tmp,10));
  441. }
  442. RetCode = NetBIOS_AddName(
  443. LocalName,
  444. (UCHAR) Clients[CIndex].c_NetB.c_LanaNumber,
  445. &NameNum);
  446. if (RetCode) {
  447. // MyDbgPrint("NB: Error in Add Name retc: %C \n", RetCode);
  448. return (STATUS_UNSUCCESSFUL);
  449. }
  450. */
  451. return (STATUS_SUCCESS);
  452. }
  453. /************************************************************************/
  454. /*++
  455. This routine is responsible for issueing Listen and waiting till a
  456. client is connected. When this routine returns successfully we can
  457. assume that a connection is established.
  458. --*/
  459. NTSTATUS
  460. NB_Wait_For_Client(
  461. IN USHORT CIndex) // client index
  462. {
  463. UCHAR RetCode;
  464. // post a listen
  465. RetCode = NetBIOS_Listen(
  466. CIndex,
  467. LocalName,
  468. RemoteName,
  469. (UCHAR)Clients[CIndex].c_NetB.c_NameNum);
  470. if (RetCode) {
  471. //MyDbgPrint("NB: Err in Listen retc: %C \n", RetCode);
  472. return (STATUS_UNSUCCESSFUL);
  473. }
  474. return (STATUS_SUCCESS);
  475. }
  476. /************************************************************************/
  477. /*++
  478. This routine is responsible for issueing Disconnect to close the
  479. connection with a client.
  480. --*/
  481. NTSTATUS
  482. NB_Disconnect_Client(
  483. IN USHORT CIndex) // client index
  484. {
  485. UCHAR RetCode;
  486. // post a Disconnect
  487. RetCode = NetBIOS_HangUP(CIndex);
  488. if (RetCode) {
  489. // MyDbgPrint("NB: Err in Disconnect retc: %C \n", RetCode);
  490. // return (STATUS_UNSUCCESSFUL);
  491. // just ignore the error for the time being
  492. }
  493. return (STATUS_SUCCESS);
  494. }
  495. /************************************************************************/
  496. /*++
  497. This routine is responsible for establishing a connection to the
  498. server side. When this routine returns successfully we can assume that
  499. a connection is established.
  500. --*/
  501. NTSTATUS
  502. NB_Connect_To_Server(
  503. IN USHORT CIndex) // client index
  504. {
  505. UCHAR RetCode;
  506. RetCode = NetBIOS_Call(
  507. CIndex,
  508. LocalName,
  509. RemoteName);
  510. if (RetCode) {
  511. //MyDbgPrint("NB: Err in Call retc: %C \n", RetCode);
  512. return (STATUS_UNSUCCESSFUL);
  513. }
  514. return (STATUS_SUCCESS);
  515. }
  516. /************************************************************************/
  517. /*++
  518. This routine allocates memory required for all the buffers for a client.
  519. --*/
  520. NTSTATUS
  521. NB_Allocate_Memory(
  522. IN USHORT CIndex) // client index and namedpipe instance number
  523. {
  524. NTSTATUS astatus = STATUS_SUCCESS;
  525. ULONG AllocSize;
  526. // AllocSize = Clients[CIndex].c_reqbuf.SendSize;
  527. AllocSize = MAXBUFSIZE;
  528. // Allocate memory for Send Buffer
  529. (LPVOID) Clients[CIndex].c_pSendBuf = VirtualAlloc(
  530. (LPVOID) Clients[CIndex].c_pSendBuf,
  531. (DWORD)AllocSize,
  532. (DWORD)MEM_COMMIT,
  533. (DWORD)PAGE_READWRITE);
  534. sprintf(Clients[CIndex].c_pSendBuf,"Client%d Send Data", CIndex+1);
  535. if (Clients[CIndex].c_pSendBuf == NULL) {
  536. astatus = GetLastError();
  537. printf("\nVirtual Alloc error\n");
  538. }
  539. // AllocSize = Clients[CIndex].c_reqbuf.RecvSize;
  540. AllocSize = MAXBUFSIZE;
  541. // Allocate memory for Receive Buffer
  542. (LPVOID) Clients[CIndex].c_pRecvBuf = VirtualAlloc(
  543. (LPVOID) Clients[CIndex].c_pRecvBuf,
  544. (DWORD)AllocSize,
  545. (DWORD)MEM_COMMIT,
  546. (DWORD)PAGE_READWRITE);
  547. sprintf(Clients[CIndex].c_pRecvBuf,"Client%d Recv Data", CIndex+1);
  548. if (Clients[CIndex].c_pRecvBuf == NULL) {
  549. astatus = GetLastError();
  550. printf("\nVirtual Alloc error\n");
  551. }
  552. // AllocSize = Clients[CIndex].c_reqbuf.RecvSize;
  553. AllocSize = MAXBUFSIZE;
  554. // Allocate memory for Global Receive Buffer
  555. (LPVOID) Clients[CIndex].c_NetB.c_pRecvBufG = VirtualAlloc(
  556. (LPVOID) Clients[CIndex].c_NetB.c_pRecvBufG,
  557. AllocSize,
  558. MEM_COMMIT,
  559. PAGE_READWRITE);
  560. sprintf(Clients[CIndex].c_NetB.c_pRecvBufG,"Client%d RecvG Data", CIndex+1);
  561. if (Clients[CIndex].c_NetB.c_pRecvBufG == NULL) {
  562. astatus = GetLastError();
  563. printf("\nVirtual Alloc error\n");
  564. }
  565. return astatus;
  566. }
  567. /************************************************************************/
  568. /*++
  569. This routine deallocates memory for a client.
  570. --*/
  571. NTSTATUS
  572. NB_Deallocate_Memory(
  573. IN USHORT CIndex) // client index and namedpipe instance number
  574. {
  575. NTSTATUS dstatus;
  576. ULONG DeallocSize;
  577. // Deallocate memory for Send Buffer
  578. // DeallocSize = Clients[CIndex].c_reqbuf.SendSize;
  579. DeallocSize = MAXBUFSIZE;
  580. dstatus = VirtualFree(
  581. (LPVOID) Clients[CIndex].c_pSendBuf,
  582. DeallocSize,
  583. MEM_DECOMMIT);
  584. /*
  585. dstatus = NtFreeVirtualMemory(
  586. NtCurrentProcess(),
  587. (PVOID *) (&(Clients[CIndex].c_pSendBuf)),
  588. &(DeallocSize),
  589. MEM_DECOMMIT);
  590. */
  591. if (!NT_SUCCESS(dstatus)) {
  592. // DbgPrint("Nmp SendBuf: Deallocate memory failed: err: %lx \n", dstatus);
  593. return dstatus;
  594. }
  595. // DeallocSize = Clients[CIndex].c_reqbuf.RecvSize;
  596. DeallocSize = MAXBUFSIZE;
  597. // Deallocate memory for Receive Buffer
  598. dstatus = VirtualFree(
  599. (LPVOID) Clients[CIndex].c_pRecvBuf,
  600. DeallocSize,
  601. MEM_DECOMMIT);
  602. /*
  603. dstatus = NtFreeVirtualMemory(
  604. NtCurrentProcess(),
  605. (PVOID *) (&(Clients[CIndex].c_pRecvBuf)),
  606. &(DeallocSize),
  607. MEM_DECOMMIT);
  608. */
  609. if (!NT_SUCCESS(dstatus)) {
  610. // DbgPrint("Nmp RecvBuf :Deallocate memory failed: err: %lx \n", dstatus);
  611. return dstatus;
  612. }
  613. // DeallocSize = Clients[CIndex].c_reqbuf.RecvSize;
  614. DeallocSize = MAXBUFSIZE;
  615. // Deallocate memory for Global Receive Buffer
  616. dstatus = VirtualFree(
  617. (LPVOID) Clients[CIndex].c_NetB.c_pRecvBufG,
  618. DeallocSize,
  619. MEM_DECOMMIT);
  620. /*
  621. dstatus = NtFreeVirtualMemory(
  622. NtCurrentProcess(),
  623. (PVOID *) (&(Clients[CIndex].c_NetB.c_pRecvBufG)),
  624. &(DeallocSize),
  625. MEM_DECOMMIT);
  626. */
  627. if (!NT_SUCCESS(dstatus)) {
  628. // DbgPrint("Nmp RecvBuf :Deallocate memory failed: err: %lx \n", dstatus);
  629. return dstatus;
  630. }
  631. return dstatus;
  632. }
  633. /************************************************************************/
  634. /*++
  635. This routine is responsible for disconnecting a session.
  636. --*/
  637. NTSTATUS
  638. NB_Disconnect_From_Server(
  639. IN USHORT CIndex) // client index and namedpipe instance number
  640. {
  641. UCHAR RetCode;
  642. RetCode = NetBIOS_HangUP(CIndex);
  643. /*
  644. // Session could be closed; check for errc=a
  645. if (RetCode) {
  646. // MyDbgPrint("NB: Err in Hang Up retc: %C \n", RetCode);
  647. return (STATUS_UNSUCCESSFUL);
  648. }
  649. */
  650. return (STATUS_SUCCESS);
  651. }
  652. /************************************************************************/
  653. /*++
  654. This routine does handshake with it's peer. For Server this means
  655. receiving request message from a client. For Client it means just the
  656. opposite.
  657. --*/
  658. NTSTATUS
  659. NB_DoHandshake(
  660. IN USHORT CIndex, // client index and namedpipe instance number
  661. IN USHORT SrvCli) // if it's a server or client
  662. {
  663. //NTSTATUS dstatus;
  664. //ULONG RWLen;
  665. USHORT RWreqLen;
  666. UCHAR RetCode;
  667. RWreqLen = sizeof(struct reqbuf);
  668. // for server do receive for a request buffer
  669. if (SrvCli) {
  670. RetCode = NetBIOS_Receive(
  671. CIndex,
  672. (PVOID) &(Clients[CIndex].c_reqbuf),
  673. RWreqLen);
  674. if (RetCode) {
  675. // MyDbgPrint("NB: Err in Receive HandShake retc: %C \n", RetCode);
  676. return (STATUS_UNSUCCESSFUL);
  677. }
  678. }
  679. else { // for Client do send of reqbuf size
  680. RetCode = NetBIOS_Send(
  681. CIndex,
  682. (PVOID) &(Clients[CIndex].c_reqbuf),
  683. RWreqLen);
  684. if (RetCode) {
  685. // MyDbgPrint("NB: Err in Send HandShake retc: %C \n", RetCode);
  686. return (STATUS_UNSUCCESSFUL);
  687. }
  688. }
  689. return (STATUS_SUCCESS);
  690. }
  691. /************************************************************************/
  692. /*++
  693. This routine Reads data from IPC. For server it means reading data
  694. NumSends times in SendBuffers and for a client NumRecvs times into
  695. RecvBuffer.
  696. --*/
  697. NTSTATUS
  698. NB_ReadFromIPC(
  699. IN USHORT CIndex, // client index and namedpipe instance number
  700. IN OUT PULONG pReadDone,
  701. IN USHORT SrvCli // if it's a server or client
  702. )
  703. {
  704. ULONG NumReads;
  705. ULONG ReadLen;
  706. PCHAR ReadBuf;
  707. UCHAR RetCode;
  708. if (SrvCli) { // set proper iterations and buffer for Server
  709. NumReads = Clients[CIndex].c_reqbuf.NumSends;
  710. ReadBuf = Clients[CIndex].c_pSendBuf;
  711. ReadLen = Clients[CIndex].c_reqbuf.SendSize;
  712. }
  713. else { // for client do proper settings
  714. NumReads = Clients[CIndex].c_reqbuf.NumRecvs;
  715. ReadBuf = Clients[CIndex].c_pRecvBuf;
  716. ReadLen = Clients[CIndex].c_reqbuf.RecvSize;
  717. }
  718. while (NumReads--) {
  719. RetCode = NetBIOS_Receive(
  720. CIndex,
  721. (PVOID) ReadBuf,
  722. (USHORT) ReadLen);
  723. if (RetCode) {
  724. // MyDbgPrint("NB: Err in Recv ReadFromIPC retc: %C \n", RetCode);
  725. return (STATUS_UNSUCCESSFUL);
  726. }
  727. // Set Read data length; I should check this from NCB
  728. *pReadDone = ReadLen;
  729. }
  730. return (STATUS_SUCCESS);
  731. }
  732. /************************************************************************/
  733. /*++
  734. This routine Writes data to IPC. For server it means writing data
  735. NumRecvs times in RecvBuffers and for a client NumSends times into
  736. SendBuffer.
  737. --*/
  738. NTSTATUS
  739. NB_WriteToIPC(
  740. IN USHORT CIndex, // client index and namedpipe instance number
  741. IN OUT PULONG pWriteDone,
  742. IN USHORT SrvCli // if it's a server or client
  743. )
  744. {
  745. ULONG NumWrites;
  746. ULONG WriteLen;
  747. PCHAR WriteBuf;
  748. UCHAR RetCode;
  749. if (SrvCli) { // set proper iterations and buffer for Server
  750. NumWrites = Clients[CIndex].c_reqbuf.NumRecvs;
  751. WriteBuf = Clients[CIndex].c_pRecvBuf;
  752. WriteLen = Clients[CIndex].c_reqbuf.RecvSize;
  753. }
  754. else { // for client do proper settings
  755. NumWrites = Clients[CIndex].c_reqbuf.NumSends;
  756. WriteBuf = Clients[CIndex].c_pSendBuf;
  757. WriteLen = Clients[CIndex].c_reqbuf.SendSize;
  758. }
  759. while (NumWrites--) {
  760. RetCode = NetBIOS_Send(
  761. CIndex,
  762. (PVOID) WriteBuf,
  763. (USHORT) WriteLen);
  764. if (RetCode) {
  765. // MyDbgPrint("NB: Err in Send WritetoIPC retc: %C \n", RetCode);
  766. return (STATUS_UNSUCCESSFUL);
  767. }
  768. // Set written data length; I should check this from NCB
  769. *pWriteDone = WriteLen;
  770. }
  771. return (STATUS_SUCCESS);
  772. }
  773. /************************************************************************/
  774. /*++
  775. This routine does Transact I/O to IPC.
  776. --*/
  777. NTSTATUS
  778. NB_XactIO(
  779. IN USHORT CIndex, // client index and namedpipe instance number
  780. IN OUT PULONG pReadDone,
  781. IN OUT PULONG pWriteDone,
  782. IN USHORT SrvCli, // if it's a server or client
  783. IN BOOLEAN FirstIter
  784. )
  785. {
  786. ULONG NumReads;
  787. ULONG ReadLen;
  788. PCHAR ReadBuf;
  789. ULONG WriteLen;
  790. PCHAR WriteBuf;
  791. UCHAR RetCode;
  792. NumReads = Clients[CIndex].c_reqbuf.NumRecvs;
  793. if (SrvCli) { // set proper iterations and buffer for Server
  794. ReadBuf = Clients[CIndex].c_pSendBuf;
  795. ReadLen = Clients[CIndex].c_reqbuf.SendSize;
  796. WriteBuf = Clients[CIndex].c_pRecvBuf;
  797. WriteLen = Clients[CIndex].c_reqbuf.RecvSize;
  798. }
  799. else { // for client do proper settings
  800. ReadBuf = Clients[CIndex].c_pRecvBuf;
  801. ReadLen = Clients[CIndex].c_reqbuf.RecvSize;
  802. WriteBuf = Clients[CIndex].c_pSendBuf;
  803. WriteLen = Clients[CIndex].c_reqbuf.SendSize;
  804. }
  805. while (NumReads--) {
  806. // for Srv and First Iteration just post a receive
  807. if (SrvCli && FirstIter) {
  808. RetCode = NetBIOS_Receive(
  809. CIndex,
  810. (PVOID) ReadBuf,
  811. (USHORT) ReadLen);
  812. if (RetCode) {
  813. // MyDbgPrint("NB: Err in Recv ReadFromIPC retc: %C \n", RetCode);
  814. return (STATUS_UNSUCCESSFUL);
  815. }
  816. }
  817. else {
  818. RetCode = NetBIOS_RecvSend(
  819. CIndex,
  820. WriteBuf,
  821. (USHORT) WriteLen,
  822. ReadBuf,
  823. (USHORT) ReadLen);
  824. if (RetCode) {
  825. // MyDbgPrint("NB: Err in XactIO retc: %C \n", RetCode);
  826. return (STATUS_UNSUCCESSFUL);
  827. }
  828. }
  829. }
  830. return (STATUS_SUCCESS);
  831. }
  832. /************************************************************************/
  833. NTSTATUS
  834. NB_Cleanup(VOID)
  835. {
  836. USHORT Cindex = 0; // client index
  837. //NTSTATUS cstatus;
  838. NTSTATUS exitstatus = 0;
  839. /*
  840. for (Cindex = 0; Cindex < NClients; Cindex++) {
  841. }
  842. */
  843. return (STATUS_SUCCESS);
  844. }
  845. /************************************************************************/
  846. /*++
  847. This routine does a client specific cleanup work.
  848. --*/
  849. NTSTATUS
  850. NB_ThreadCleanUp(
  851. IN USHORT CIndex
  852. )
  853. {
  854. NTSTATUS tstatus;
  855. UCHAR RetCode;
  856. // Close all the events
  857. tstatus = CloseHandle(Clients[CIndex].c_NetB.c_SendEvent);
  858. tstatus = CloseHandle(Clients[CIndex].c_NetB.c_RecvEvent);
  859. tstatus = CloseHandle(Clients[CIndex].c_NetB.c_RecvEventG);
  860. // Delete the name Added
  861. RetCode = NetBIOS_DelName(
  862. LocalName,
  863. (UCHAR) Clients[CIndex].c_NetB.c_LanaNumber);
  864. if (RetCode) {
  865. // MyDbgPrint("NB: Error in DelName retc: %C \n", RetCode);
  866. return (STATUS_UNSUCCESSFUL);
  867. }
  868. return STATUS_SUCCESS;
  869. }
  870. /************************************************************************/