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.

873 lines
26 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1994 - 1999
  6. //
  7. // File: dgnb.c
  8. //
  9. //--------------------------------------------------------------------------
  10. /////////////////////////////////////////////////////////////////////////
  11. //
  12. // Filename: dgnb.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 "dgnb.h"
  26. #include "nb.h"
  27. /************************************************************************/
  28. /*++
  29. This routine is responsible for adding a given name on a net.
  30. --*/
  31. UCHAR
  32. DGNetBIOS_AddName(
  33. IN PCHAR LocalName,
  34. IN UCHAR LanaNumber,
  35. OUT PUCHAR NameNumber)
  36. {
  37. NCB AddNameNCB;
  38. UCHAR RetCode;
  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. DGNetBIOS_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. DGNetBIOS_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. UCHAR
  99. DGNetBIOS_Receive(
  100. IN USHORT TIndex,
  101. IN PUCHAR RecvBuffer,
  102. IN USHORT RecvLen)
  103. {
  104. NCB ReceiveNCB;
  105. NTSTATUS rstatus;
  106. UCHAR RetCode;
  107. //DbgPrint("Entering Recv..");
  108. RetCode =0;
  109. ClearNCB(&ReceiveNCB); // does cleanup everything
  110. ReceiveNCB.ncb_command = NCBDGRECV | ASYNCH;
  111. ReceiveNCB.ncb_lana_num = (UCHAR) Clients[TIndex].c_NetB.c_LanaNumber;
  112. ReceiveNCB.ncb_num = Clients[TIndex].c_NetB.c_NameNum;
  113. ReceiveNCB.ncb_lsn = Clients[TIndex].c_NetB.c_LSN;
  114. ReceiveNCB.ncb_buffer = RecvBuffer;
  115. ReceiveNCB.ncb_length = RecvLen;
  116. ReceiveNCB.ncb_event = Clients[TIndex].c_NetB.c_RecvEvent;
  117. //DbgPrint("Posting Recv..");
  118. RetCode = Netbios(&ReceiveNCB); // submit to NetBIOS
  119. if (ReceiveNCB.ncb_cmd_cplt == NRC_PENDING){
  120. rstatus = WaitForSingleObjectEx(ReceiveNCB.ncb_event,
  121. INFINITE,
  122. TRUE);
  123. }
  124. if (ReceiveNCB.ncb_cmd_cplt != NRC_GOODRET) {
  125. //DbgPrint("NBSRV:NB:Receive failed %x\n", ReceiveNCB.ncb_cmd_cplt);
  126. }
  127. //DbgPrint("Exit Recv\n");
  128. return ReceiveNCB.ncb_cmd_cplt;
  129. }
  130. /************************************************************************/
  131. UCHAR
  132. DGNetBIOS_Send(
  133. IN USHORT TIndex,
  134. IN PUCHAR SendBuffer,
  135. IN USHORT SendLen)
  136. {
  137. NCB SendNCB;
  138. NTSTATUS rstatus;
  139. UCHAR RetCode;
  140. //DbgPrint("Enter Send\n");
  141. RetCode =0;
  142. ClearNCB(&SendNCB); // does cleanup everything
  143. SendNCB.ncb_command = NCBDGSEND | ASYNCH;
  144. SendNCB.ncb_lana_num = (UCHAR) Clients[TIndex].c_NetB.c_LanaNumber;
  145. SendNCB.ncb_num = Clients[TIndex].c_NetB.c_NameNum;
  146. SendNCB.ncb_lsn = Clients[TIndex].c_NetB.c_LSN;
  147. SendNCB.ncb_buffer = SendBuffer;
  148. SendNCB.ncb_length = SendLen;
  149. SendNCB.ncb_event = Clients[TIndex].c_NetB.c_SendEvent;
  150. RtlMoveMemory(SendNCB.ncb_callname,RemoteName,NCBNAMSZ);
  151. RetCode = Netbios(&SendNCB); // submit to NetBIOS
  152. if (SendNCB.ncb_cmd_cplt == NRC_PENDING){
  153. rstatus = WaitForSingleObjectEx(SendNCB.ncb_event,
  154. INFINITE,
  155. TRUE);
  156. }
  157. if (SendNCB.ncb_cmd_cplt != NRC_GOODRET) {
  158. //DbgPrint("NBSRV:NBS:Send failed %x RetCode:%x\n",SendNCB.ncb_cmd_cplt,RetCode);
  159. }
  160. //DbgPrint("Exit Send\n");
  161. return SendNCB.ncb_cmd_cplt;
  162. }
  163. /************************************************************************/
  164. NTSTATUS
  165. DGNB_Initialize(
  166. IN USHORT NClients,
  167. IN PCHAR IServerName,
  168. IN USHORT SrvCli)
  169. {
  170. NTSTATUS Istatus;
  171. UCHAR RetCode;
  172. USHORT LanaNum;
  173. CHAR Tmp[10]; // for holding numbers
  174. //
  175. // First Reset all the adapters
  176. // Add the server name if provided otherwise use the default name
  177. // To take care of TCP/IP and other Lana Bases
  178. LanaNum = LanaBase;
  179. // initialize all the named
  180. MyDbgPrint("Initialize both Local/Remote Names\n");
  181. if (SrvCli) { // for server copy the given name as a local
  182. RtlMoveMemory(RemoteName, ALL_CLIENTS, NCBNAMSZ);
  183. if (IServerName) {
  184. RtlMoveMemory(LocalName, IServerName, NCBNAMSZ);
  185. }
  186. else {
  187. RtlMoveMemory(LocalName, PERF_NETBIOS, NCBNAMSZ);
  188. }
  189. }
  190. else { // for a client copy the name as a remote name
  191. if (IServerName) {
  192. RtlMoveMemory(RemoteName, IServerName, NCBNAMSZ);
  193. }
  194. else {
  195. RtlMoveMemory(RemoteName, PERF_NETBIOS, NCBNAMSZ);
  196. }
  197. // copy local name for client
  198. // use Rtl routines
  199. strcpy(LocalName,CLINAME);
  200. strcat(LocalName,_itoa(MachineNumber,Tmp,10));
  201. }
  202. while (LanaNum < LanaCount*2) { // for Jet and TCP/IP
  203. RetCode = NetBIOS_Reset((UCHAR) LanaNum);
  204. if (RetCode) {
  205. MyDbgPrint("Error in Reset\n");
  206. return(Istatus = -1L);
  207. }
  208. // we could assign Lana Numbers to clients and do AddName here too
  209. RetCode = NetBIOS_AddName(
  210. LocalName,
  211. (UCHAR) LanaNum,
  212. &NameNumber);
  213. if (RetCode) {
  214. //MyDbgPrint("NB: Error in Add Name retc: %C \n", RetCode);
  215. return (STATUS_UNSUCCESSFUL);
  216. }
  217. // Add the Name number to Client's structure
  218. LanaNum = LanaNum+2;
  219. }
  220. //DbgPrint("NB: Reset Done\n");
  221. return (STATUS_SUCCESS);
  222. }
  223. /************************************************************************/
  224. /*++
  225. This routine is responsible adding a NetBIOS name for the given
  226. thread.
  227. --*/
  228. NTSTATUS
  229. DGNB_PerClientInit(
  230. IN USHORT CIndex, // client index
  231. IN USHORT SrvCli )
  232. {
  233. //NTSTATUS pstatus;
  234. //UCHAR RetCode;
  235. //CHAR Tmp[10]; // for holding numbers
  236. // initialize proper client data structures
  237. Clients[CIndex].c_client_num = CIndex;
  238. // distribute clients evenly on all net cards
  239. Clients[CIndex].c_NetB.c_LanaNumber = ((CIndex % LanaCount)*2)+LanaBase;
  240. // Add the Name number to Client's structure
  241. Clients[CIndex].c_NetB.c_NameNum = NameNumber;
  242. // Set all events to Null
  243. Clients[CIndex].c_NetB.c_SendEvent = NULL;
  244. Clients[CIndex].c_NetB.c_RecvEvent = NULL;
  245. Clients[CIndex].c_NetB.c_RecvEventG = NULL;
  246. // create events to associate with an NCB for this thread
  247. Clients[CIndex].c_NetB.c_SendEvent = CreateEvent(
  248. NULL,
  249. TRUE, // manual reset event
  250. FALSE, // initial state of the event
  251. NULL); // no event name
  252. Clients[CIndex].c_NetB.c_RecvEvent = CreateEvent(
  253. NULL,
  254. TRUE, // manual reset event
  255. FALSE, // initial state of the event
  256. NULL); // no event name
  257. Clients[CIndex].c_NetB.c_RecvEventG = CreateEvent(
  258. NULL,
  259. TRUE, // manual reset event
  260. FALSE, // initial state of the event
  261. NULL); // no event name
  262. /*
  263. pstatus = NtCreateEvent(
  264. &(Clients[CIndex].c_NetB.c_SendEvent),
  265. EVENT_ALL_ACCESS,
  266. NULL,
  267. NotificationEvent,
  268. (BOOLEAN)FALSE);
  269. if (!NT_SUCCESS(pstatus)) {
  270. MyDbgPrint ("Err: Create an Send Event:%d err=%lx\n",CIndex,pstatus);
  271. return(pstatus);
  272. }
  273. pstatus = NtCreateEvent(
  274. &(Clients[CIndex].c_NetB.c_RecvEvent),
  275. EVENT_ALL_ACCESS,
  276. NULL,
  277. NotificationEvent,
  278. (BOOLEAN)FALSE);
  279. if (!NT_SUCCESS(pstatus)) {
  280. MyDbgPrint ("Err: Create an Recv Event:%d err=%lx\n",CIndex,pstatus);
  281. return(pstatus);
  282. }
  283. pstatus = NtCreateEvent(
  284. &(Clients[CIndex].c_NetB.c_RecvEventG),
  285. EVENT_ALL_ACCESS,
  286. NULL,
  287. NotificationEvent,
  288. (BOOLEAN)FALSE);
  289. if (!NT_SUCCESS(pstatus)) {
  290. MyDbgPrint ("Err: Create GRecv Event:%d err=%lx\n",CIndex,pstatus);
  291. return(pstatus);
  292. }
  293. */
  294. return (STATUS_SUCCESS);
  295. }
  296. /************************************************************************/
  297. /*++
  298. This routine is responsible for issueing Listen and waiting till a
  299. client is connected. When this routine returns successfully we can
  300. assume that a connection is established.
  301. --*/
  302. NTSTATUS
  303. DGNB_Wait_For_Client(
  304. IN USHORT CIndex) // client index
  305. {
  306. //UCHAR RetCode;
  307. // post a listen
  308. return (STATUS_SUCCESS);
  309. }
  310. /************************************************************************/
  311. /*++
  312. This routine is responsible for issueing Disconnect to close the
  313. connection with a client.
  314. --*/
  315. NTSTATUS
  316. DGNB_Disconnect_Client(
  317. IN USHORT CIndex) // client index
  318. {
  319. //UCHAR RetCode;
  320. // post a Disconnect
  321. return (STATUS_SUCCESS);
  322. }
  323. /************************************************************************/
  324. /*++
  325. This routine is responsible for establishing a connection to the
  326. server side. When this routine returns successfully we can assume that
  327. a connection is established.
  328. --*/
  329. NTSTATUS
  330. DGNB_Connect_To_Server(
  331. IN USHORT CIndex) // client index
  332. {
  333. //UCHAR RetCode;
  334. return (STATUS_SUCCESS);
  335. }
  336. /************************************************************************/
  337. /*++
  338. This routine allocates memory required for all the buffers for a client.
  339. --*/
  340. NTSTATUS
  341. DGNB_Allocate_Memory(
  342. IN USHORT CIndex) // client index and namedpipe instance number
  343. {
  344. NTSTATUS astatus = 0;
  345. ULONG AllocSize;
  346. // AllocSize = Clients[CIndex].c_reqbuf.SendSize;
  347. AllocSize = MAXBUFSIZE;
  348. // Allocate memory for Send Buffer
  349. /*
  350. astatus = NtAllocateVirtualMemory(
  351. NtCurrentProcess(),
  352. (PVOID *) (&(Clients[CIndex].c_pSendBuf)),
  353. 0L,
  354. &(AllocSize),
  355. MEM_COMMIT,
  356. PAGE_READWRITE);
  357. if (!NT_SUCCESS(astatus)) {
  358. DbgPrint("Nmp SendBuf: Allocate memory failed: err: %lx \n", astatus);
  359. return astatus;
  360. }
  361. */
  362. (LPVOID) Clients[CIndex].c_pSendBuf = VirtualAlloc(
  363. (LPVOID) Clients[CIndex].c_pSendBuf,
  364. (DWORD)AllocSize,
  365. (DWORD)MEM_COMMIT,
  366. (DWORD)PAGE_READWRITE);
  367. sprintf(Clients[CIndex].c_pSendBuf,"Client%d Send Data", CIndex+1);
  368. // AllocSize = Clients[CIndex].c_reqbuf.RecvSize;
  369. AllocSize = MAXBUFSIZE;
  370. // Allocate memory for Receive Buffer
  371. /*
  372. astatus = NtAllocateVirtualMemory(
  373. NtCurrentProcess(),
  374. (PVOID *) (&(Clients[CIndex].c_pRecvBuf)),
  375. 0L,
  376. &(AllocSize),
  377. MEM_COMMIT,
  378. PAGE_READWRITE);
  379. if (!NT_SUCCESS(astatus)) {
  380. DbgPrint("Nmp RecvBuf :Allocate memory failed: err: %lx \n", astatus);
  381. return astatus;
  382. }
  383. */
  384. (LPVOID) Clients[CIndex].c_pRecvBuf = VirtualAlloc(
  385. (LPVOID) Clients[CIndex].c_pRecvBuf,
  386. (DWORD)AllocSize,
  387. (DWORD)MEM_COMMIT,
  388. (DWORD)PAGE_READWRITE);
  389. sprintf(Clients[CIndex].c_pRecvBuf,"Client%d Recv Data", CIndex+1);
  390. // AllocSize = Clients[CIndex].c_reqbuf.RecvSize;
  391. AllocSize = MAXBUFSIZE;
  392. // Allocate memory for Global Receive Buffer
  393. /*
  394. astatus = NtAllocateVirtualMemory(
  395. NtCurrentProcess(),
  396. (PVOID *) (&(Clients[CIndex].c_NetB.c_pRecvBufG)),
  397. 0L,
  398. &(AllocSize),
  399. MEM_COMMIT,
  400. PAGE_READWRITE);
  401. if (!NT_SUCCESS(astatus)) {
  402. DbgPrint("Nmp RecvBufG :Allocate memory failed: err: %lx \n", astatus);
  403. return astatus;
  404. }
  405. */
  406. (LPVOID) Clients[CIndex].c_NetB.c_pRecvBufG = VirtualAlloc(
  407. (LPVOID) Clients[CIndex].c_NetB.c_pRecvBufG,
  408. AllocSize,
  409. MEM_COMMIT,
  410. PAGE_READWRITE);
  411. sprintf(Clients[CIndex].c_NetB.c_pRecvBufG,"Client%d RecvG Data", CIndex+1);
  412. return astatus;
  413. }
  414. /************************************************************************/
  415. /*++
  416. This routine deallocates memory for a client.
  417. --*/
  418. NTSTATUS
  419. DGNB_Deallocate_Memory(
  420. IN USHORT CIndex) // client index and namedpipe instance number
  421. {
  422. NTSTATUS dstatus;
  423. ULONG DeallocSize;
  424. // Deallocate memory for Send Buffer
  425. // DeallocSize = Clients[CIndex].c_reqbuf.SendSize;
  426. DeallocSize = MAXBUFSIZE;
  427. /*
  428. dstatus = NtFreeVirtualMemory(
  429. NtCurrentProcess(),
  430. (PVOID *) (&(Clients[CIndex].c_pSendBuf)),
  431. &(DeallocSize),
  432. MEM_DECOMMIT);
  433. */
  434. dstatus = VirtualFree(
  435. (LPVOID) Clients[CIndex].c_pSendBuf,
  436. DeallocSize,
  437. MEM_DECOMMIT);
  438. if (!NT_SUCCESS(dstatus)) {
  439. //DbgPrint("Nmp SendBuf: Deallocate memory failed: err: %lx \n", dstatus);
  440. return dstatus;
  441. }
  442. // DeallocSize = Clients[CIndex].c_reqbuf.RecvSize;
  443. DeallocSize = MAXBUFSIZE;
  444. // Deallocate memory for Receive Buffer
  445. /*
  446. dstatus = NtFreeVirtualMemory(
  447. NtCurrentProcess(),
  448. (PVOID *) (&(Clients[CIndex].c_pRecvBuf)),
  449. &(DeallocSize),
  450. MEM_DECOMMIT);
  451. */
  452. dstatus = VirtualFree(
  453. (LPVOID) Clients[CIndex].c_pRecvBuf,
  454. DeallocSize,
  455. MEM_DECOMMIT);
  456. if (!NT_SUCCESS(dstatus)) {
  457. //DbgPrint("Nmp RecvBuf :Deallocate memory failed: err: %lx \n", dstatus);
  458. return dstatus;
  459. }
  460. // DeallocSize = Clients[CIndex].c_reqbuf.RecvSize;
  461. DeallocSize = MAXBUFSIZE;
  462. // Deallocate memory for Global Receive Buffer
  463. /*
  464. dstatus = NtFreeVirtualMemory(
  465. NtCurrentProcess(),
  466. (PVOID *) (&(Clients[CIndex].c_NetB.c_pRecvBufG)),
  467. &(DeallocSize),
  468. MEM_DECOMMIT);
  469. */
  470. dstatus = VirtualFree(
  471. (LPVOID) Clients[CIndex].c_NetB.c_pRecvBufG,
  472. DeallocSize,
  473. MEM_DECOMMIT);
  474. if (!NT_SUCCESS(dstatus)) {
  475. //DbgPrint("Nmp RecvBuf :Deallocate memory failed: err: %lx \n", dstatus);
  476. return dstatus;
  477. }
  478. return dstatus;
  479. }
  480. /************************************************************************/
  481. /*++
  482. This routine is responsible for disconnecting a session.
  483. --*/
  484. NTSTATUS
  485. DGNB_Disconnect_From_Server(
  486. IN USHORT CIndex) // client index and namedpipe instance number
  487. {
  488. //UCHAR RetCode;
  489. return (STATUS_SUCCESS);
  490. }
  491. /************************************************************************/
  492. /*++
  493. This routine does handshake with it's peer. For Server this means
  494. receiving request message from a client. For Client it means just the
  495. opposite.
  496. --*/
  497. NTSTATUS
  498. DGNB_DoHandshake(
  499. IN USHORT CIndex, // client index and namedpipe instance number
  500. IN USHORT SrvCli) // if it's a server or client
  501. {
  502. //NTSTATUS dstatus;
  503. //ULONG RWLen;
  504. ULONG RWreqLen;
  505. UCHAR RetCode;
  506. RWreqLen = sizeof(struct reqbuf);
  507. // for server do receive for a request buffer
  508. if (SrvCli) {
  509. RetCode = DGNetBIOS_Receive(
  510. CIndex,
  511. (PVOID) &(Clients[CIndex].c_reqbuf),
  512. (USHORT) RWreqLen);
  513. if (RetCode) {
  514. //MyDbgPrint("NB: Err in Receive HandShake retc: %C \n", RetCode);
  515. return (STATUS_UNSUCCESSFUL);
  516. }
  517. }
  518. else { // for Client do send of reqbuf size
  519. RetCode = DGNetBIOS_Send(
  520. CIndex,
  521. (PVOID) &(Clients[CIndex].c_reqbuf),
  522. (USHORT) RWreqLen);
  523. if (RetCode) {
  524. //MyDbgPrint("NB: Err in Send HandShake retc: %C \n", RetCode);
  525. return (STATUS_UNSUCCESSFUL);
  526. }
  527. }
  528. return (STATUS_SUCCESS);
  529. }
  530. /************************************************************************/
  531. /*++
  532. This routine Reads data from IPC. For server it means reading data
  533. NumSends times in SendBuffers and for a client NumRecvs times into
  534. RecvBuffer.
  535. --*/
  536. NTSTATUS
  537. DGNB_ReadFromIPC(
  538. IN USHORT CIndex, // client index and namedpipe instance number
  539. IN OUT PULONG pReadDone,
  540. IN USHORT SrvCli ) // if it's a server or client
  541. {
  542. ULONG NumReads;
  543. ULONG ReadLen;
  544. PCHAR ReadBuf;
  545. UCHAR RetCode;
  546. if (SrvCli) { // set proper iterations and buffer for Server
  547. NumReads = Clients[CIndex].c_reqbuf.NumSends;
  548. ReadBuf = Clients[CIndex].c_pSendBuf;
  549. ReadLen = Clients[CIndex].c_reqbuf.SendSize;
  550. }
  551. else { // for client do proper settings
  552. NumReads = Clients[CIndex].c_reqbuf.NumRecvs;
  553. ReadBuf = Clients[CIndex].c_pRecvBuf;
  554. ReadLen = Clients[CIndex].c_reqbuf.RecvSize;
  555. }
  556. while (NumReads--) {
  557. RetCode = DGNetBIOS_Receive(
  558. CIndex,
  559. (PVOID) ReadBuf,
  560. (USHORT) ReadLen);
  561. if (RetCode) {
  562. //MyDbgPrint("NB: Err in Recv ReadFromIPC retc: %C \n", RetCode);
  563. return (STATUS_UNSUCCESSFUL);
  564. }
  565. // Set Read data length; I should check this from NCB
  566. *pReadDone = ReadLen;
  567. }
  568. return (STATUS_SUCCESS);
  569. }
  570. /************************************************************************/
  571. /*++
  572. This routine Writes data to IPC. For server it means writing data
  573. NumRecvs times in RecvBuffers and for a client NumSends times into
  574. SendBuffer.
  575. --*/
  576. NTSTATUS
  577. DGNB_WriteToIPC(
  578. IN USHORT CIndex, // client index and namedpipe instance number
  579. IN OUT PULONG pWriteDone,
  580. IN USHORT SrvCli) // if it's a server or client
  581. {
  582. ULONG NumWrites;
  583. ULONG WriteLen;
  584. PCHAR WriteBuf;
  585. UCHAR RetCode;
  586. if (SrvCli) { // set proper iterations and buffer for Server
  587. NumWrites = Clients[CIndex].c_reqbuf.NumRecvs;
  588. WriteBuf = Clients[CIndex].c_pRecvBuf;
  589. WriteLen = Clients[CIndex].c_reqbuf.RecvSize;
  590. }
  591. else { // for client do proper settings
  592. NumWrites = Clients[CIndex].c_reqbuf.NumSends;
  593. WriteBuf = Clients[CIndex].c_pSendBuf;
  594. WriteLen = Clients[CIndex].c_reqbuf.SendSize;
  595. }
  596. while (NumWrites--) {
  597. RetCode = DGNetBIOS_Send(
  598. CIndex,
  599. (PVOID) WriteBuf,
  600. (USHORT) WriteLen);
  601. if (RetCode) {
  602. //MyDbgPrint("NB: Err in Send WritetoIPC retc: %C \n", RetCode);
  603. return (STATUS_UNSUCCESSFUL);
  604. }
  605. // Set written data length; I should check this from NCB
  606. *pWriteDone = WriteLen;
  607. }
  608. return (STATUS_SUCCESS);
  609. }
  610. /************************************************************************/
  611. /*++
  612. This routine does Transact I/O to IPC.
  613. --*/
  614. NTSTATUS
  615. DGNB_XactIO(
  616. IN USHORT CIndex, // client index and namedpipe instance number
  617. IN OUT PULONG pReadDone,
  618. IN OUT PULONG pWriteDone,
  619. IN USHORT SrvCli, // if it's a server or client
  620. IN BOOLEAN FirstIter)
  621. {
  622. ULONG NumReads;
  623. ULONG ReadLen;
  624. PCHAR ReadBuf;
  625. ULONG WriteLen;
  626. PCHAR WriteBuf;
  627. UCHAR RetCode;
  628. NumReads = Clients[CIndex].c_reqbuf.NumRecvs;
  629. if (SrvCli) { // set proper iterations and buffer for Server
  630. ReadBuf = Clients[CIndex].c_pSendBuf;
  631. ReadLen = Clients[CIndex].c_reqbuf.SendSize;
  632. WriteBuf = Clients[CIndex].c_pRecvBuf;
  633. WriteLen = Clients[CIndex].c_reqbuf.RecvSize;
  634. }
  635. else { // for client do proper settings
  636. ReadBuf = Clients[CIndex].c_pRecvBuf;
  637. ReadLen = Clients[CIndex].c_reqbuf.RecvSize;
  638. WriteBuf = Clients[CIndex].c_pSendBuf;
  639. WriteLen = Clients[CIndex].c_reqbuf.SendSize;
  640. }
  641. while (NumReads--) {
  642. // for Srv and First Iteration just post a receive
  643. if (SrvCli && FirstIter) {
  644. RetCode = DGNetBIOS_Receive(
  645. CIndex,
  646. (PVOID) ReadBuf,
  647. (USHORT) ReadLen);
  648. if (RetCode) {
  649. //MyDbgPrint("NB: Err in Recv ReadFromIPC retc: %C \n", RetCode);
  650. return (STATUS_UNSUCCESSFUL);
  651. }
  652. }
  653. else {
  654. RetCode = DGNetBIOS_RecvSend(
  655. CIndex,
  656. WriteBuf,
  657. (USHORT) WriteLen,
  658. ReadBuf,
  659. (USHORT) ReadLen);
  660. if (RetCode) {
  661. //MyDbgPrint("NB: Err in XactIO retc: %C \n", RetCode);
  662. return (STATUS_UNSUCCESSFUL);
  663. }
  664. }
  665. }
  666. return (STATUS_SUCCESS);
  667. }
  668. /************************************************************************/
  669. NTSTATUS
  670. DGNB_Cleanup(VOID)
  671. {
  672. //USHORT Cindex = 0; // client index
  673. //NTSTATUS cstatus;
  674. //NTSTATUS exitstatus = 0;
  675. /*
  676. for (Cindex = 0; Cindex < NClients; Cindex++) {
  677. }
  678. */
  679. return (STATUS_SUCCESS);
  680. }
  681. /************************************************************************/
  682. /*++
  683. This routine does a client specific cleanup work.
  684. --*/
  685. NTSTATUS
  686. DGNB_ThreadCleanUp(
  687. IN USHORT CIndex)
  688. {
  689. NTSTATUS tstatus;
  690. UCHAR RetCode;
  691. // Close all the events
  692. tstatus = CloseHandle(Clients[CIndex].c_NetB.c_SendEvent);
  693. tstatus = CloseHandle(Clients[CIndex].c_NetB.c_RecvEvent);
  694. tstatus = CloseHandle(Clients[CIndex].c_NetB.c_RecvEventG);
  695. // Delete the name Added
  696. RetCode = NetBIOS_DelName(
  697. LocalName,
  698. (UCHAR) Clients[CIndex].c_NetB.c_LanaNumber);
  699. if (RetCode) {
  700. //MyDbgPrint("NB: Error in DelName retc: %C \n", RetCode);
  701. return (STATUS_UNSUCCESSFUL);
  702. }
  703. return STATUS_SUCCESS;
  704. }
  705. /************************************************************************/
  706. UCHAR
  707. DGNetBIOS_RecvSend(
  708. IN USHORT TIndex,
  709. IN PUCHAR SendBuffer,
  710. IN USHORT SendLen,
  711. IN PUCHAR RecvBuffer,
  712. IN USHORT RecvLen)
  713. {
  714. NCB ReceiveNCB; // Make it a part of client
  715. NCB SendNCB; // Make it a part of client struc
  716. NTSTATUS rstatus, sstatus;
  717. UCHAR RRetCode, SRetCode;
  718. RRetCode = SRetCode = 0;
  719. ClearNCB(&ReceiveNCB); // cleanup everything
  720. ClearNCB(&SendNCB); // cleanup everything
  721. // First post Receive but don't wait as this is for the next
  722. // request block
  723. ReceiveNCB.ncb_command = NCBDGRECV | ASYNCH;
  724. ReceiveNCB.ncb_lana_num = (UCHAR) Clients[TIndex].c_NetB.c_LanaNumber;
  725. ReceiveNCB.ncb_lsn = Clients[TIndex].c_NetB.c_LSN;
  726. ReceiveNCB.ncb_buffer = RecvBuffer;
  727. ReceiveNCB.ncb_length = RecvLen;
  728. ReceiveNCB.ncb_event = Clients[TIndex].c_NetB.c_RecvEvent;
  729. RRetCode = Netbios(&ReceiveNCB); // submit to NetBIOS
  730. if (ReceiveNCB.ncb_cmd_cplt == NRC_PENDING){
  731. // now do all the send(s)
  732. SendNCB.ncb_command = NCBDGSEND | ASYNCH;
  733. SendNCB.ncb_lana_num = (UCHAR) Clients[TIndex].c_NetB.c_LanaNumber;
  734. SendNCB.ncb_lsn = Clients[TIndex].c_NetB.c_LSN;
  735. SendNCB.ncb_buffer = SendBuffer;
  736. SendNCB.ncb_length = SendLen;
  737. SendNCB.ncb_event = Clients[TIndex].c_NetB.c_SendEvent;
  738. SRetCode = Netbios(&SendNCB); // submit to NetBIOS
  739. // First wait on Send , if successful then wait on receive
  740. if (SendNCB.ncb_cmd_cplt == NRC_PENDING){
  741. // First wait for the Send to complete
  742. sstatus = WaitForSingleObjectEx(SendNCB.ncb_event,
  743. INFINITE,
  744. TRUE);
  745. }
  746. if (SendNCB.ncb_cmd_cplt != NRC_GOODRET) {
  747. //DbgPrint("NBSRV:NBSR:Send failed %x RetCode:%x\n",SendNCB.ncb_cmd_cplt,SRetCode);
  748. // Cancel the receive posted earlier
  749. return SendNCB.ncb_cmd_cplt;
  750. }
  751. // Now wait for the receive to complete
  752. rstatus = WaitForSingleObjectEx(ReceiveNCB.ncb_event,
  753. INFINITE,
  754. TRUE);
  755. // check for status success here
  756. }
  757. if (ReceiveNCB.ncb_cmd_cplt != NRC_GOODRET) {
  758. //DbgPrint("NBSRV:NBSR:Receive failed %x RetCode:%x\n",ReceiveNCB.ncb_cmd_cplt,RRetCode);
  759. }
  760. return ReceiveNCB.ncb_cmd_cplt;
  761. }
  762. /************************************************************************/