IPX16A.ASM 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450
  1. ;
  2. ; Command & Conquer Red Alert(tm)
  3. ; Copyright 2025 Electronic Arts Inc.
  4. ;
  5. ; This program is free software: you can redistribute it and/or modify
  6. ; it under the terms of the GNU General Public License as published by
  7. ; the Free Software Foundation, either version 3 of the License, or
  8. ; (at your option) any later version.
  9. ;
  10. ; This program is distributed in the hope that it will be useful,
  11. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ; GNU General Public License for more details.
  14. ;
  15. ; You should have received a copy of the GNU General Public License
  16. ; along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. ;
  18. .8086
  19. .model large
  20. option segment:USE16
  21. option readonly
  22. option oldstructs
  23. assume ds:@data
  24. assume es:nothing
  25. RECEIVE_BUFFER_LENGTH =1024
  26. MAX_RECEIVE_BUFFERS =32
  27. externdef GLOBALDOSALLOC:far
  28. externdef GLOBALDOSFREE:far
  29. .data
  30. IPXCallOffset dw 0
  31. IPXCallSegment dw 0
  32. RealSegment dw 0
  33. PseudoES dw 0
  34. RegisterDump db 32h dup (0)
  35. MyNetworkNumber db 4 dup (?)
  36. MyNodeAddress db 6 dup (?)
  37. MySocket dw ?
  38. ReceiveBufferSegment dw ?
  39. ReceiveBufferSelector dw ?
  40. ReceiveECBOffset dw ?
  41. CurrentReceiveBuffer dw ?
  42. LastPassedReceiveBuffer dw ?
  43. RealModeCallbackSegment dw ?
  44. RealModeCallbackOffset dw ?
  45. CallbackRegisterDump db 32h dup (0)
  46. Listening db ?
  47. NoReenter db 0
  48. IPXHold db 0
  49. OFFS =0
  50. SEGM =2
  51. ;---------------------------------------------------------------------------
  52. ;These defines are for the IPX functions. The function number is specified
  53. ;by placing it in BX when IPX is called. There are two ways to invoke IPX:
  54. ;use interrupt 0x7a, or use a function whose address is obtained by calling
  55. ;interrupt 0x2f with AX=0x7a00; the function address is returned in ES:DI.
  56. ;This is the preferred method, since other apps are known to use int 0x7a.
  57. ;---------------------------------------------------------------------------
  58. IPX_OPEN_SOCKET = 0000h
  59. IPX_CLOSE_SOCKET = 0001h
  60. IPX_GET_LOCAL_TARGET = 0002h
  61. IPX_SEND_PACKET = 0003h
  62. IPX_LISTEN_FOR_PACKET = 0004h
  63. IPX_SCHEDULE_EVENT = 0005h
  64. IPX_CANCEL_EVENT = 0006h
  65. IPX_GET_INTERVAL_MARKER = 0008h
  66. IPX_GET_INTERNETWORK_ADDRESS = 0009h
  67. IPX_RELINQUISH_CONTROL = 000Ah
  68. IPX_DISCONNECT_FROM_TARGET = 000Bh
  69. ;/*---------------------------------------------------------------------------
  70. ;These defines are for various IPX error codes:
  71. ;---------------------------------------------------------------------------*/
  72. IPXERR_CONNECTION_SEVERED = 00ech
  73. IPXERR_CONNECTION_FAILED = 00edh
  74. IPXERR_NO_CONNECTION = 00eeh
  75. IPXERR_CONNECTION_TABLE_FULL = 00efh
  76. IPXERR_NO_CANCEL_ECB = 00f9h
  77. IPXERR_NO_PATH = 00fah
  78. IPXERR_ECB_INACTIVE = 00fch
  79. IPXERR_INVALID_PACKET_LENGTH = 00fdh
  80. IPXERR_SOCKET_TABLE_FULL = 00feh
  81. IPXERR_SOCKET_ERROR = 00ffh
  82. ;/*---------------------------------------------------------------------------
  83. ;These defines are for various interrupt vectors and DPMI functions:
  84. ;---------------------------------------------------------------------------*/
  85. IPX_INT = 007ah
  86. DPMI_INT = 0031h
  87. DPMI_ALLOC_DOS_MEM = 0100h
  88. DPMI_FREE_DOS_MEM = 0101h
  89. DPMI_CALL_REAL_INT = 0300h
  90. DPMI_CALL_REAL_PROC = 0301h
  91. DPMI_ALLOCATE_CALLBACK = 0303h
  92. DPMI_RELEASE_CALLBACK = 0304h
  93. DPMI_LOCK_MEM = 0600h
  94. DPMI_UNLOCK_MEM = 0601h
  95. request_buffer struct
  96. len word ?
  97. buffer_type byte ?
  98. connect_number byte ?
  99. request_buffer ends
  100. request_local_target_buffer struct
  101. lt_network_number db ?,?,?,?
  102. lt_physical_node db ?,?,?,?,?,?
  103. lt_socket dw ?
  104. request_local_target_buffer ends
  105. local_target_reply_buffer struct
  106. lt_local_target db ?,?,?,?,?,?
  107. local_target_reply_buffer ends
  108. reply_buffer struct
  109. lem word ?
  110. network_number byte ?,?,?,?
  111. physical_node byte ?,?,?,?,?,?
  112. server_socket word ?
  113. reply_buffer ends
  114. userid_buffer struct
  115. struct_len word ?
  116. object_id byte ?,?,?,?
  117. object_type byte ?,?
  118. object_name byte 48 dup(?)
  119. login_time byte 7 dup (?)
  120. reserved word ?
  121. userid_buffer ends
  122. .code
  123. .386
  124. include <pcmacro.16>
  125. externdef pascal _IPX_Initiialise:far16
  126. externdef pascal _IPX_Uninitialise:far16
  127. _IPX_Initialise proc far pascal
  128. push ebx
  129. push ecx
  130. push edx
  131. push esi
  132. push edi
  133. push ebp
  134. push ds
  135. push es
  136. push fs
  137. push gs
  138. mov ax,7a00h
  139. int 2fh
  140. and eax,0ffh
  141. cmp al,-1
  142. setz al
  143. test al,al
  144. jz @f
  145. mov bx,@data
  146. mov ds,bx
  147. mov [IPXCallSegment],es
  148. mov [IPXCallOffset],di
  149. @@: pop gs
  150. pop fs
  151. pop es
  152. pop ds
  153. pop ebp
  154. pop edi
  155. pop esi
  156. pop edx
  157. pop ecx
  158. pop ebx
  159. ret
  160. _IPX_Initialise endp
  161. _IPX_Open_Socket95 proc far pascal uses bx cx dx si di ds es fs gs,
  162. socket:word
  163. mov bx,@data
  164. mov ds,bx
  165. mov bx,IPX_OPEN_SOCKET ;open socket
  166. mov_w dx,[socket] ;socket number
  167. mov_w [MySocket],dx ;save it for later
  168. mov ax,0ffh ;long lived
  169. call Call_IPX
  170. ret
  171. _IPX_Open_Socket95 endp
  172. _IPX_Close_Socket95 proc far pascal uses ax bx cx dx si di ds es fs gs,
  173. socket:word
  174. mov bx,1
  175. mov_w dx,[socket]
  176. call Call_IPX
  177. ret
  178. _IPX_Close_Socket95 endp
  179. _IPX_Uninitialise proc far pascal
  180. ;int 3
  181. ret
  182. _IPX_Uninitialise endp
  183. _IPX_Get_Connection_Number95 proc far pascal uses bx cx dx si di ds es fs gs
  184. mov ax,0dc00h
  185. call Call_DOS
  186. and eax,255
  187. ret
  188. _IPX_Get_Connection_Number95 endp
  189. _IPX_Get_Internet_Address95 proc far pascal uses bx cx dx si di ds es fs gs,
  190. connection_number :dword,
  191. network_number_off :word,
  192. network_number_seg :word,
  193. physical_node_off :word,
  194. physical_node_seg :word
  195. local selector:word
  196. local segmento:word
  197. ret
  198. ifdef cuts ;(unfinished)
  199. ;
  200. ; Allocate DOS memory for buffers passed to interrupt
  201. ;
  202. int 3
  203. xor ax,ax
  204. mov bx,(sizeof reply_buffer + sizeof request_buffer + 15)
  205. save bp
  206. push ax
  207. push bx
  208. call GLOBALDOSALLOC
  209. restore bp
  210. test ax,ax
  211. jz @@dpmi_error
  212. mov [segmento],dx
  213. mov [selector],ax
  214. mov fs,dx
  215. xor di,di
  216. mov_w fs:[di.len],2
  217. mov_b fs:[di.buffer_type],13h
  218. mov_b al,[connection_number]
  219. mov_b fs:[di.connect_number],al
  220. mov di,sizeof request_buffer
  221. mov fs:[di.len],12
  222. mov ax,0e300h
  223. mov ds,[segmento]
  224. mov es,[segmento]
  225. xor si,si
  226. pusha
  227. call Call_DOS
  228. popa
  229. les di,dword ptr [network_number_off]
  230. mov ds,[selector]
  231. mov si,sizeof request_buffer + network_number
  232. movsd
  233. les di,dword ptr [physical_node_off]
  234. mov si,sizeof request_buffer + physical_node
  235. movsd
  236. movsw
  237. ;
  238. ; Save it here for posterity (or perhaps later use)
  239. ;
  240. mov di,offset MyNetworkNumber
  241. mov ax,@data
  242. mov es,ax
  243. mov ds,[selector]
  244. mov si,sizeof request_buffer + network_number
  245. movsd
  246. mov di,offset MyNodeAddress
  247. mov si,sizeof request_buffer + physical_node
  248. movsd
  249. movsw
  250. ;
  251. ; Free the DOS memory
  252. ;
  253. mov bx,@data
  254. mov ds,bx
  255. mov es,bx
  256. mov fs,bx
  257. mov gs,bx
  258. mov bx,[selector]
  259. push bx
  260. call GLOBALDOSFREE
  261. xor ax,ax
  262. ret
  263. @@dpmi_error: mov ax,-1
  264. ret
  265. endif
  266. _IPX_Get_Internet_Address95 endp
  267. ; Never called!!
  268. _IPX_Get_User_ID95 proc far pascal uses bx cx dx si di ds es fs gs,
  269. connection_number:dword,
  270. user_id_off:word,
  271. user_id_seg:word
  272. local segmento:word
  273. local selector:word
  274. cmp [connection_number],0
  275. jz @@return_error
  276. ;
  277. ; Allocate DOS memory for buffers passed to interrupt
  278. ;
  279. xor ax,ax
  280. mov bx,(sizeof reply_buffer + sizeof request_buffer + 15)
  281. save bp
  282. push ax
  283. push bx
  284. call GLOBALDOSALLOC
  285. restore bp
  286. test ax,ax
  287. jz @@return_error
  288. mov [segmento],dx
  289. mov [selector],ax
  290. mov fs,dx
  291. xor di,di
  292. mov ax,@data
  293. mov ds,ax
  294. mov_w fs:[di.len],2
  295. mov_b fs:[di.buffer_type],16h
  296. mov_b al,[connection_number]
  297. mov_b fs:[di.connect_number],al
  298. mov di,sizeof request_buffer
  299. mov fs:[di.struct_len],sizeof userid_buffer-2
  300. mov ax,0e300h
  301. mov ds,[segmento]
  302. mov es,[segmento]
  303. xor si,si
  304. pusha
  305. call Call_DOS
  306. popa
  307. les di,dword ptr [user_id_off]
  308. mov ds,[selector]
  309. mov si,sizeof request_buffer + object_name
  310. mov cx,48/4
  311. rep movsd
  312. ;
  313. ; Free the DOS memory
  314. ;
  315. mov bx,@data
  316. mov ds,bx
  317. mov es,bx
  318. mov fs,bx
  319. mov gs,bx
  320. mov bx,[selector]
  321. push bx
  322. call GLOBALDOSFREE
  323. xor ax,ax
  324. ret
  325. @@return_error: mov ax,-1
  326. ret
  327. _IPX_Get_User_ID95 endp
  328. ;---------------------------------------------------------------------------
  329. ;This is the IPX Packet structure. It's followed by the data itself, which
  330. ;can be up to 546 bytes long. Annotation of 'IPX' means IPX will set this
  331. ;field; annotation of 'APP' means the application must set the field.
  332. ;NOTE: All header fields are ordered high-byte,low-byte.
  333. ;---------------------------------------------------------------------------*/
  334. IPXHeaderType struct
  335. CheckSum dw ? ; IPX: Not used; always 0xffff
  336. IPXLength dw ? ; IPX: Total size, incl header & data
  337. TransportControl db ? ; IPX: # bridges message crossed
  338. PacketType db ? ; APP: Set to 4 for IPX (5 for SPX)
  339. DestNetworkNumber db ?,?,?,? ; APP: destination Network Number
  340. DestNetworkNode db ?,?,?,?,?,? ; APP: destination Node Address
  341. DestNetworkSocket dw ? ; APP: destination Socket Number
  342. SourceNetworkNumber db ?,?,?,? ; IPX: source Network Number
  343. SourceNetworkNode db ?,?,?,?,?,? ; IPX: source Node Address
  344. SourceNetworkSocket dw ? ; IPX: source Socket Number
  345. IPXHeaderType ends
  346. ;/*---------------------------------------------------------------------------
  347. ;This is the IPX Event Control Block. It serves as a communications area
  348. ;between IPX and the application for a single IPX operation. You should set
  349. ;up a separate ECB for each IPX operation you perform.
  350. ;---------------------------------------------------------------------------*/
  351. ECB struct
  352. Link_Address dd ?
  353. Event_Service_Routine dd ? ; APP: event handler (NULL=none)
  354. InUse db ? ; IPX: 0 = event complete
  355. CompletionCode db ? ; IPX: event's return code
  356. SocketNumber dw ? ; APP: socket to send data through
  357. ConnectionID dw ? ; returned by Listen (???)
  358. RestOfWorkspace dw ?
  359. DriverWorkspace db 12 dup (?)
  360. ImmediateAddress db 6 dup (?) ; returned by Get_Local_Target
  361. PacketCount dw ?
  362. PacketAddress0 dd ?
  363. PacketLength0 dw ?
  364. PacketAddress1 dd ?
  365. PacketLength1 dw ?
  366. ECB ends
  367. SEND_ECB_OFFSET =0
  368. SEND_HEADER_OFFSET =(sizeof ECB +3) AND 0fffch
  369. SEND_BUFFER_OFFSET =(SEND_HEADER_OFFSET + sizeof IPXHeaderType +3) AND 0fffch
  370. _IPX_Send_Packet95 proc far pascal uses ebx ecx edx esi edi ds es fs gs,
  371. send_address :far ptr byte,
  372. send_buffer :far ptr byte,
  373. send_buffer_len :word
  374. local selector :word
  375. local segmento :word
  376. local dos_send_ecb :far ptr ECB
  377. local dos_send_header :far ptr IPXHeaderType
  378. local dos_send_buffer :far ptr byte
  379. local completion_code :word
  380. ;
  381. ; Allocate required DOS memory
  382. ;
  383. xor ax,ax
  384. mov bx,(sizeof ECB + sizeof IPXHeaderType + 1024 +31)
  385. save bp
  386. push ax
  387. push bx
  388. call GLOBALDOSALLOC
  389. restore bp
  390. test ax,ax
  391. jz @@error
  392. mov [segmento],dx
  393. mov [selector],ax
  394. ;
  395. ; Set up the pointers to the dos memory
  396. ;
  397. mov_w [dos_send_ecb+OFFS],SEND_ECB_OFFSET
  398. mov_w [dos_send_ecb+SEGM],ax
  399. mov_w [dos_send_header+OFFS],SEND_HEADER_OFFSET
  400. mov_w [dos_send_header+SEGM],ax
  401. mov_w [dos_send_buffer+OFFS],SEND_BUFFER_OFFSET
  402. mov_w [dos_send_buffer+SEGM],ax
  403. ;
  404. ; Clear out the send ECB
  405. ;
  406. xor al,al
  407. mov cx,sizeof ECB
  408. les di,[dos_send_ecb]
  409. rep stosb
  410. ;
  411. ; Clear out the send header
  412. ;
  413. mov cx,sizeof IPXHeaderType
  414. les di,[dos_send_header]
  415. rep stosb
  416. ;
  417. ; Copy the data to be sent into the send buffer
  418. ;
  419. mov cx,546
  420. cmp_w cx,[send_buffer_len]
  421. jle @@got_buffer_len
  422. mov_w cx,[send_buffer_len]
  423. @@got_buffer_len:
  424. ; mov_w [send_buffer_len],546 ;always send same size packets (nice and big for Kali hehe)
  425. les di,[dos_send_buffer]
  426. lds si,[send_buffer]
  427. rep movsb
  428. ;
  429. ; Fill in the ECB
  430. ;
  431. mov ax,@data
  432. mov ds,ax
  433. mov fs,ax ;keep ptr to data seg in fs
  434. les di,[dos_send_ecb]
  435. mov ax,[MySocket]
  436. mov es:[di.SocketNumber],ax
  437. mov es:[di.PacketCount],2
  438. mov ax,[selector]
  439. shl eax,16
  440. mov_w ax,[dos_send_header+OFFS]
  441. mov_d es:[di.PacketAddress0],eax
  442. mov_w es:[di.PacketLength0],sizeof IPXHeaderType
  443. mov_w ax,[dos_send_buffer+OFFS]
  444. mov_d es:[di.PacketAddress1],eax
  445. mov_w ax,[send_buffer_len]
  446. mov_w es:[di.PacketLength1],ax
  447. ;
  448. ; Fill in the address field
  449. ;
  450. lds si,[send_address]
  451. mov eax,[si]
  452. mov_d es:[di.ImmediateAddress],eax
  453. mov ax,[si+4]
  454. mov_w es:[di.ImmediateAddress+4],ax
  455. ;
  456. ; Fill in the outgoing header
  457. ;
  458. les di,[dos_send_header]
  459. mov es:[di.PacketType],4
  460. push fs:[MySocket]
  461. pop es:[di.DestNetworkSocket]
  462. ;
  463. ; Fill in the nwtowrk number and node address
  464. ;
  465. mov_d eax,fs:[MyNetworkNumber]
  466. mov_d es:[di.DestNetworkNumber],eax
  467. mov_d eax,fs:[MyNodeAddress]
  468. mov_d es:[di.DestNetworkNode],eax
  469. mov_w ax,fs:[MyNodeAddress+4]
  470. mov_w es:[di.DestNetworkNode+4],ax
  471. ;
  472. ; Send that sucker!
  473. ;
  474. mov es,[selector]
  475. mov si,SEND_ECB_OFFSET
  476. mov bx,IPX_SEND_PACKET
  477. pusha
  478. push fs
  479. call Call_IPX
  480. pop fs
  481. popa
  482. mov fs:[PseudoES],0
  483. ;
  484. ; Wait for the send to finish
  485. ;
  486. @@wait_send_loop:
  487. lds si,[dos_send_ecb]
  488. cmp [si.InUse],0
  489. jz @@done
  490. mov bx,IPX_RELINQUISH_CONTROL
  491. save bp
  492. call Call_IPX
  493. restore bp
  494. jmp @@wait_send_loop
  495. ;
  496. ; Get the completion code
  497. ;
  498. @@done: lds si,[dos_send_ecb]
  499. mov al,[si.CompletionCode]
  500. xor ah,ah
  501. mov [completion_code],ax
  502. ;
  503. ; Free the DOS memory
  504. ;
  505. mov bx,@data
  506. mov ds,bx
  507. mov es,bx
  508. mov fs,bx
  509. mov gs,bx
  510. mov bx,[selector]
  511. save bp
  512. push bx
  513. call GLOBALDOSFREE
  514. restore bp
  515. cmp [completion_code],0
  516. jnz @@error
  517. @@success: mov ax,1
  518. ret
  519. @@error: xor ax,ax
  520. ret
  521. _IPX_Send_Packet95 endp
  522. _IPX_Broadcast_Packet95 proc far pascal uses ebx ecx edx esi edi ds es fs gs,
  523. send_buffer :far ptr byte,
  524. send_buffer_len :word
  525. local selector :word
  526. local segmento :word
  527. local dos_send_ecb :far ptr ECB
  528. local dos_send_header :far ptr IPXHeaderType
  529. local dos_send_buffer :far ptr byte
  530. local completion_code :word
  531. ;
  532. ; Allocate required DOS memory
  533. ;
  534. xor ax,ax
  535. mov bx,(sizeof ECB + sizeof IPXHeaderType + 1024 +31)
  536. save bp
  537. push ax
  538. push bx
  539. call GLOBALDOSALLOC
  540. restore bp
  541. test ax,ax
  542. jz @@error
  543. mov [segmento],dx
  544. mov [selector],ax
  545. ;
  546. ; Set up the pointers to the dos memory
  547. ;
  548. mov_w [dos_send_ecb+OFFS],SEND_ECB_OFFSET
  549. mov_w [dos_send_ecb+SEGM],ax
  550. mov_w [dos_send_header+OFFS],SEND_HEADER_OFFSET
  551. mov_w [dos_send_header+SEGM],ax
  552. mov_w [dos_send_buffer+OFFS],SEND_BUFFER_OFFSET
  553. mov_w [dos_send_buffer+SEGM],ax
  554. ;
  555. ; Clear out the send ECB
  556. ;
  557. xor al,al
  558. mov cx,sizeof ECB
  559. les di,[dos_send_ecb]
  560. rep stosb
  561. ;
  562. ; Clear out the send header
  563. ;
  564. mov cx,sizeof IPXHeaderType
  565. les di,[dos_send_header]
  566. rep stosb
  567. ;
  568. ; Copy the data to be sent into the send buffer
  569. ;
  570. mov cx,546
  571. cmp_w cx,[send_buffer_len]
  572. jle @@got_buffer_len
  573. mov_w cx,[send_buffer_len]
  574. @@got_buffer_len:
  575. ; mov_w [send_buffer_len],546 ;always send same size packets (nice and big for Kali hehe)
  576. les di,[dos_send_buffer]
  577. lds si,[send_buffer]
  578. rep movsb
  579. ;
  580. ; Fill in the ECB
  581. ;
  582. mov ax,@data
  583. mov ds,ax
  584. mov fs,ax ;keep ptr to data seg in fs
  585. les di,[dos_send_ecb]
  586. mov ax,[MySocket]
  587. mov es:[di.SocketNumber],ax
  588. mov es:[di.PacketCount],2
  589. mov ax,[selector]
  590. shl eax,16
  591. mov_w ax,[dos_send_header+OFFS]
  592. mov_d es:[di.PacketAddress0],eax
  593. mov_w es:[di.PacketLength0],sizeof IPXHeaderType
  594. mov_w ax,[dos_send_buffer+OFFS]
  595. mov_d es:[di.PacketAddress1],eax
  596. mov_w ax,[send_buffer_len]
  597. mov_w es:[di.PacketLength1],ax
  598. ;
  599. ; Fill in the address field
  600. ;
  601. mov_d es:[di.ImmediateAddress],0ffffffffh
  602. mov_w es:[di.ImmediateAddress+4],0ffffh
  603. ;
  604. ; Fill in the outgoing header
  605. ;
  606. les di,[dos_send_header]
  607. mov es:[di.PacketType],4
  608. push fs:[MySocket]
  609. pop es:[di.DestNetworkSocket]
  610. ;
  611. ; Fill in the nwtowrk number and node address
  612. ;
  613. mov_d es:[di.DestNetworkNumber],0ffffffffh
  614. mov_d es:[di.DestNetworkNode],0ffffffffh
  615. mov_w es:[di.DestNetworkNode+4],0ffffh
  616. ;
  617. ; Send that sucker!
  618. ;
  619. mov es,[selector]
  620. mov si,SEND_ECB_OFFSET
  621. mov bx,IPX_SEND_PACKET
  622. pusha
  623. push fs
  624. call Call_IPX
  625. pop fs
  626. popa
  627. mov fs:[PseudoES],0
  628. ;
  629. ; Wait for the send to finish
  630. ;
  631. @@wait_send_loop:
  632. lds si,[dos_send_ecb]
  633. cmp [si.InUse],0
  634. jz @@done
  635. mov bx,IPX_RELINQUISH_CONTROL
  636. save bp
  637. call Call_IPX
  638. restore bp
  639. jmp @@wait_send_loop
  640. ;
  641. ; Get the completion code
  642. ;
  643. @@done: lds si,[dos_send_ecb]
  644. mov al,[si.CompletionCode]
  645. xor ah,ah
  646. mov [completion_code],ax
  647. ;
  648. ; Free the DOS memory
  649. ;
  650. mov bx,@data
  651. mov ds,bx
  652. mov es,bx
  653. mov fs,bx
  654. mov gs,bx
  655. mov bx,[selector]
  656. save bp
  657. push bx
  658. call GLOBALDOSFREE
  659. restore bp
  660. cmp [completion_code],0
  661. jnz @@error
  662. @@success: mov ax,1
  663. ret
  664. @@error: xor ax,ax
  665. ret
  666. _IPX_Broadcast_Packet95 endp
  667. _IPX_Get_Local_Target95 proc far pascal uses ebx ecx edx esi edi ds es fs gs,
  668. dest_network :far ptr byte,
  669. dest_node :far ptr byte,
  670. socket :word,
  671. bridge_address :far ptr byte
  672. local segmento :word
  673. local selector :word
  674. local result_code :word
  675. ;
  676. ; Allocate DOS memory for buffers passed to interrupt
  677. ;
  678. xor ax,ax
  679. mov bx,(sizeof local_target_reply_buffer + \
  680. sizeof request_local_target_buffer + 15)
  681. save bp
  682. push ax
  683. push bx
  684. call GLOBALDOSALLOC
  685. restore bp
  686. test ax,ax
  687. jz @@return_error
  688. mov [segmento],dx
  689. mov [selector],ax
  690. mov fs,ax
  691. xor di,di
  692. ;
  693. ; Init the request structure
  694. ;
  695. lds si,[dest_network]
  696. mov_d eax,[si]
  697. mov_d fs:[di.lt_network_number],eax
  698. lds si,[dest_node]
  699. mov eax,[si]
  700. mov_d fs:[di.lt_physical_node],eax
  701. mov_w ax,[si+4]
  702. mov_w fs:[di.lt_physical_node+4],ax
  703. mov ax,[socket]
  704. mov fs:[di.lt_socket],ax
  705. mov bx,IPX_GET_LOCAL_TARGET
  706. mov ax,[selector]
  707. mov ds,ax
  708. xor si,si
  709. mov es,ax
  710. mov di,sizeof request_local_target_buffer
  711. push bp
  712. call Call_IPX
  713. pop bp
  714. mov [result_code],ax
  715. mov ds,[selector]
  716. mov si,sizeof request_local_target_buffer + lt_local_target
  717. les di,[bridge_address]
  718. movsd
  719. movsw
  720. ;
  721. ; Free the DOS memory
  722. ;
  723. mov bx,@data
  724. mov ds,bx
  725. mov es,bx
  726. mov fs,bx
  727. mov gs,bx
  728. mov bx,[selector]
  729. save bp
  730. push bx
  731. call GLOBALDOSFREE
  732. restore bp
  733. ;
  734. ; Return the IPX result code
  735. ;
  736. mov ax,[result_code]
  737. ret
  738. @@return_error: mov ax,-1
  739. ret
  740. _IPX_Get_Local_Target95 endp
  741. _IPX_Get_Outstanding_Buffer95 proc far pascal uses ebx ecx edx esi edi ebp ds es fs gs,
  742. copy_receive_buffer:far ptr byte
  743. mov ax,@data
  744. mov ds,ax
  745. xor ax,ax
  746. mov si,[LastPassedReceiveBuffer]
  747. cmp si,[CurrentReceiveBuffer]
  748. jz @@done
  749. push ds
  750. mov cx,RECEIVE_BUFFER_LENGTH/4
  751. mov ds,[ReceiveBufferSelector]
  752. les di,[copy_receive_buffer]
  753. rep movsd
  754. pop ds
  755. cmp si,RECEIVE_BUFFER_LENGTH*MAX_RECEIVE_BUFFERS
  756. jc @@no_wrap
  757. xor si,si
  758. @@no_wrap: mov [LastPassedReceiveBuffer],si
  759. mov ax,1
  760. @@done: ret
  761. _IPX_Get_Outstanding_Buffer95 endp
  762. Receive_Callback proc far
  763. pushf
  764. cli
  765. cld
  766. pushad
  767. push ds
  768. push es
  769. push fs
  770. push gs
  771. mov ax,@data
  772. mov ds,ax
  773. cmp [NoReenter],0
  774. jnz @@out
  775. mov [NoReenter],1
  776. mov ax,[CurrentReceiveBuffer]
  777. add ax,RECEIVE_BUFFER_LENGTH
  778. cmp ax,RECEIVE_BUFFER_LENGTH*MAX_RECEIVE_BUFFERS
  779. jc @@no_wrap
  780. xor ax,ax
  781. @@no_wrap: mov [CurrentReceiveBuffer],ax
  782. call Listen_For_Packet
  783. mov ax,@data
  784. mov ds,ax
  785. mov [NoReenter],0
  786. @@out: pop gs
  787. pop fs
  788. pop es
  789. pop ds
  790. popad
  791. popf
  792. ret
  793. Receive_Callback endp
  794. Init_Receive_ECB proc near uses eax ebx ecx edx esi edi ebp ds es
  795. mov ax,@data
  796. mov ds,ax
  797. mov es,[ReceiveBufferSelector]
  798. ;
  799. ; Clear out the ECB
  800. ;
  801. mov di,[ReceiveECBOffset]
  802. mov cx,sizeof ECB
  803. xor al,al
  804. rep stosb
  805. ;
  806. ; Set up the ECB
  807. ;
  808. ;
  809. ;General ECB data
  810. mov di,[ReceiveECBOffset]
  811. mov ax,[MySocket]
  812. mov es:[di.SocketNumber],ax
  813. mov es:[di.PacketCount],2
  814. ;
  815. ; Packet address for IPX header
  816. mov ax,[CurrentReceiveBuffer]
  817. mov bx,[ReceiveBufferSelector]
  818. mov_w es:[di.PacketAddress0+OFFS],ax
  819. mov_w es:[di.PacketAddress0+SEGM],bx
  820. mov es:[di.PacketLength0],sizeof IPXHeaderType
  821. ;
  822. ; Packet address for receive buffer
  823. mov ax,[CurrentReceiveBuffer]
  824. add ax,sizeof IPXHeaderType
  825. mov_w es:[di.PacketAddress1+OFFS],ax
  826. mov_w es:[di.PacketAddress1+SEGM],bx
  827. mov es:[di.PacketLength1],546
  828. ;
  829. ; Set up the callback address
  830. mov ax,[RealModeCallbackOffset]
  831. mov_w es:[di.Event_Service_Routine+OFFS],offset Receive_Callback ;ax
  832. mov ax,[RealModeCallbackSegment]
  833. mov_w es:[di.Event_Service_Routine+SEGM],cs ;ax
  834. ret
  835. Init_Receive_ECB endp
  836. _IPX_Start_Listening95 proc far pascal uses ebx ecx edx esi edi ebp ds es fs gs
  837. mov ax,@data
  838. mov ds,ax
  839. cmp [Listening],0
  840. jnz @@restart ;already listening
  841. ;
  842. ; Allocate and lock DOS memory for listen
  843. ; ECB and receive buffers
  844. ;
  845. mov bx,(RECEIVE_BUFFER_LENGTH*MAX_RECEIVE_BUFFERS + sizeof ECB + 15)
  846. xor ax,ax
  847. save bp,ds
  848. push ax
  849. push bx
  850. call GLOBALDOSALLOC
  851. restore bp,ds
  852. test ax,ax
  853. jz @@error
  854. mov [ReceiveBufferSegment],dx
  855. mov [ReceiveBufferSelector],ax
  856. ;
  857. ; Set up pointers to the DOS memory
  858. ;
  859. mov [ReceiveECBOffset],RECEIVE_BUFFER_LENGTH * MAX_RECEIVE_BUFFERS
  860. mov [CurrentReceiveBuffer],0 ;1st receive buffer
  861. mov [LastPassedReceiveBuffer],0
  862. ;
  863. ; Set up a real mode callback function
  864. ;
  865. ;mov ax,DPMI_ALLOCATE_CALLBACK
  866. ;mov si,offset Receive_Callback
  867. ;mov di,offset CallbackRegisterDump
  868. ;push cs
  869. ;pop ds
  870. ;mov bx,@data
  871. ;mov es,bx
  872. ;save bp
  873. ;int 31h
  874. ;restore bp
  875. ;bcs @@error
  876. mov ax,@data
  877. mov ds,ax
  878. mov [RealModeCallbackSegment],cx
  879. mov [RealModeCallbackOffset],dx
  880. @@restart: save ds
  881. call Listen_For_Packet
  882. restore ds
  883. mov [Listening],1
  884. @@out: mov ax,1
  885. ret
  886. @@error: xor ax,ax
  887. ret
  888. _IPX_Start_Listening95 endp
  889. _IPX_Shut_Down95 proc far pascal uses eax ebx ecx edx esi edi ebp ds es fs gs
  890. mov ax,@data
  891. mov ds,ax
  892. cmp [Listening],0
  893. jz @@out
  894. ;
  895. ; Stop listening for a packet
  896. ;
  897. mov es,[ReceiveBufferSelector]
  898. mov si,[ReceiveECBOffset]
  899. mov bx,IPX_CANCEL_EVENT
  900. save bp,ds
  901. call Call_IPX
  902. restore bp,ds
  903. ;
  904. ; Remove the real mode callback function
  905. ;
  906. ;mov cx,[RealModeCallbackSegment]
  907. ;mov dx,[RealModeCallbackOffset]
  908. ;mov ax,DPMI_RELEASE_CALLBACK
  909. ;save bp,ds
  910. ;int 31h
  911. ;restore bp,ds
  912. ;
  913. ; Free the DOS memory
  914. ;
  915. mov ax,@data
  916. mov ds,ax
  917. mov es,ax
  918. mov ax,[ReceiveBufferSelector]
  919. save bp,ds
  920. push ax
  921. call GLOBALDOSFREE
  922. restore bp,ds
  923. mov [Listening],0
  924. @@out: ret
  925. _IPX_Shut_Down95 endp
  926. Listen_For_Packet proc near uses ebx ecx edx esi edi ebp ds es fs gs
  927. call Init_Receive_ECB
  928. mov ax,@data
  929. mov ds,ax
  930. mov es,[ReceiveBufferSelector]
  931. mov si,[ReceiveECBOffset]
  932. mov bx,IPX_LISTEN_FOR_PACKET
  933. save ds
  934. call Call_IPX
  935. restore ds
  936. mov [PseudoES],0
  937. ret
  938. Listen_For_Packet endp
  939. Call_IPX proc far
  940. push gs
  941. push ax
  942. mov ax,@data
  943. mov gs,ax
  944. pop ax
  945. push bp
  946. mov bp,offset IPXCallOffset
  947. call dword ptr gs:[bp]
  948. pop bp
  949. pop gs
  950. ret
  951. push gs
  952. push ax
  953. mov ax,@data
  954. mov gs,ax
  955. pop ax
  956. ;
  957. ; Prevent reenterancy
  958. ;
  959. @@hold: ;cmp gs:[IPXHold],0
  960. ;jnz @@hold
  961. mov gs:[IPXHold],1
  962. ;
  963. ; Dump the registers first so we can use them
  964. ;
  965. mov_d gs:[RegisterDump+0ch],0
  966. mov_d gs:[RegisterDump],edi
  967. mov_d gs:[RegisterDump+4],esi
  968. mov_d gs:[RegisterDump+8],ebp
  969. mov_d gs:[RegisterDump+10h],ebx
  970. mov_d gs:[RegisterDump+14h],edx
  971. mov_d gs:[RegisterDump+18h],ecx
  972. mov_d gs:[RegisterDump+1ch],eax
  973. push gs
  974. xor ax,ax
  975. push ax
  976. mov ax,4096 ;4k real mode stack
  977. push ax
  978. call GLOBALDOSALLOC
  979. pop gs
  980. mov bx,4094 ;stack ptr
  981. test ax,ax
  982. jnz @f
  983. xor bx,bx
  984. ;
  985. ; Set up stack addr to zero - DPMI will supply a real mode stack
  986. ;
  987. @@: mov_w gs:[RegisterDump+2eh],bx ;sp
  988. mov_w gs:[RegisterDump+30h],dx ;ss
  989. save ax ;save selector so we can free the memory later
  990. ;
  991. ; Dump the flags
  992. ;
  993. pushf
  994. pop gs:[word ptr RegisterDump+20h]
  995. ;
  996. ; Set up all segment register areas to point to our real mode segment
  997. ;
  998. mov_w gs:[RegisterDump+22h],es
  999. mov_w gs:[RegisterDump+24h],ds
  1000. mov_w gs:[RegisterDump+26h],fs
  1001. mov_w gs:[RegisterDump+28h],gs
  1002. cmp gs:[PseudoES],0
  1003. jz @f
  1004. mov ax,gs:[PseudoES]
  1005. mov_w gs:[RegisterDump+22h],ax
  1006. @@:
  1007. ;
  1008. ; Set up the address to call
  1009. ;
  1010. mov ax,gs:[IPXCallSegment]
  1011. mov_w gs:[RegisterDump+2ch],ax
  1012. mov ax,gs:[IPXCallOffset]
  1013. mov_w gs:[RegisterDump+2ah],ax
  1014. mov ax,DPMI_CALL_REAL_INT ; Call real mode procedure with far return frame
  1015. xor bh,bh ; flags - should be zero
  1016. mov bl,07ah ; IPX interrupt
  1017. mov ecx,0 ;512 ; number of words to copy from the protected mode stack
  1018. mov di,offset RegisterDump
  1019. push gs
  1020. pop es
  1021. save gs
  1022. ;push ss
  1023. ;push sp
  1024. int 31h ;DPMI interrupt
  1025. ;pop ax
  1026. ;pop bx
  1027. ;pushf
  1028. ;pop cx
  1029. ;cli
  1030. ;mov sp,ax
  1031. ;mov ss,bx
  1032. ;add sp,2
  1033. ;push cx
  1034. ;popf
  1035. restore gs
  1036. mov ax,@data
  1037. mov ds,ax
  1038. mov es,ax
  1039. mov fs,ax
  1040. mov gs,ax
  1041. call GLOBALDOSFREE
  1042. mov_d eax,gs:[RegisterDump+1ch]
  1043. mov gs:[IPXHold],0
  1044. pop gs
  1045. ret
  1046. Call_IPX endp
  1047. Call_DOS proc far
  1048. push gs
  1049. push ax
  1050. mov ax,@data
  1051. mov gs,ax
  1052. pop ax
  1053. ;
  1054. ; Dump the registers first so we can use them
  1055. ;
  1056. mov_d gs:[RegisterDump],edi
  1057. mov_d gs:[RegisterDump+4],esi
  1058. mov_d gs:[RegisterDump+8],ebp
  1059. mov_d gs:[RegisterDump+10h],ebx
  1060. mov_d gs:[RegisterDump+14h],edx
  1061. mov_d gs:[RegisterDump+18h],ecx
  1062. mov_d gs:[RegisterDump+1ch],eax
  1063. ;
  1064. ; Dump the flags
  1065. ;
  1066. pushf
  1067. pop gs:[word ptr RegisterDump+20h]
  1068. ;
  1069. ; Set up all segment register areas to point to our real mode segment
  1070. ;
  1071. mov_w gs:[RegisterDump+22h],es
  1072. mov_w gs:[RegisterDump+24h],ds
  1073. mov_w gs:[RegisterDump+26h],fs
  1074. mov_w gs:[RegisterDump+28h],gs
  1075. ;
  1076. ; Set up stack addr to zero - DPMI will supply a real mode stack
  1077. ;
  1078. xor ax,ax
  1079. mov_w gs:[RegisterDump+2eh],ax ;sp
  1080. mov_w gs:[RegisterDump+30h],ax ;ss
  1081. mov ax,DPMI_CALL_REAL_INT; Simulate real mode interrupt
  1082. xor bh,bh ; flags - should be zero
  1083. mov bl,21h ; interrupt number
  1084. mov ecx,0 ;512 ; number of words to copy from the protected mode stack
  1085. mov di,offset RegisterDump
  1086. push gs
  1087. pop es
  1088. save gs
  1089. int 31h ;DPMI interrupt
  1090. restore gs
  1091. mov_d edi,gs:[RegisterDump]
  1092. mov_d esi,gs:[RegisterDump+4]
  1093. mov_d ebp,gs:[RegisterDump+8]
  1094. mov_d ebx,gs:[RegisterDump+10h]
  1095. mov_d edx,gs:[RegisterDump+14h]
  1096. mov_d ecx,gs:[RegisterDump+18h]
  1097. mov_d eax,gs:[RegisterDump+1ch]
  1098. mov_w es,gs:[RegisterDump+22h]
  1099. mov_w ds,gs:[RegisterDump+24h]
  1100. pop gs
  1101. ret
  1102. Call_DOS endp
  1103. end