2 Copyright 2009, jimmikaelkael
3 Licenced under Academic Free License version 3.0
4 Review OpenUsbLd README & LICENSE files for further details.
20 static int io_sema
= -1;
22 #define WAITIOSEMA(x) WaitSema(x)
23 #define SIGNALIOSEMA(x) SignalSema(x)
27 #define SIGNALIOSEMA(x)
31 #define DMA_ADDR 0x000cff00
32 #define UNCACHEDSEG(vaddr) (0x20000000 | vaddr)
34 // !!! ps2ip exports functions pointers !!!
35 extern int (*plwip_close
)(int s
); // #6
36 extern int (*plwip_connect
)(int s
, struct sockaddr
*name
, socklen_t namelen
); // #7
37 extern int (*plwip_recvfrom
)(int s
, void *header
, int hlen
, void *payload
, int plen
, unsigned int flags
, struct sockaddr
*from
, socklen_t
*fromlen
); // #10
38 extern int (*plwip_send
)(int s
, void *dataptr
, int size
, unsigned int flags
); // #11
39 extern int (*plwip_socket
)(int domain
, int type
, int protocol
); // #13
40 extern u32 (*pinet_addr
)(const char *cp
); // #24
42 extern int *p_part_start
;
44 #define SMB_MAGIC 0x424d53ff
46 struct SMBHeader_t
{ //size = 36
59 } __attribute__((packed
));
61 struct NegociateProtocolRequest_t
{
62 struct SMBHeader_t smbH
; // 0
63 u8 smbWordcount
; // 36
65 u8 DialectFormat
; // 39
66 char DialectName
[0]; // 40
67 } __attribute__((packed
));
69 struct NegociateProtocolResponse_t
{
70 struct SMBHeader_t smbH
; // 0
71 u8 smbWordcount
; // 36
72 u16 DialectIndex
; // 37
73 u8 SecurityMode
; // 39
74 u16 MaxMpxCount
; // 40
76 u32 MaxBufferSize
; // 44
77 u32 MaxRawBuffer
; // 48
79 u32 Capabilities
; // 56
81 u16 ServerTimeZone
; // 68
84 u8 ByteField
[0]; // 73
85 } __attribute__((packed
));
87 struct SessionSetupAndXRequest_t
{
88 struct SMBHeader_t smbH
; // 0
89 u8 smbWordcount
; // 36
91 u8 smbAndxReserved
; // 38
92 u16 smbAndxOffset
; // 39
93 u16 MaxBufferSize
; // 41
94 u16 MaxMpxCount
; // 43
97 u16 AnsiPasswordLength
; // 51
98 u16 UnicodePasswordLength
; // 53
100 u32 Capabilities
; // 59
102 u8 ByteField
[0]; // 65
103 } __attribute__((packed
));
105 struct SessionSetupAndXResponse_t
{
106 struct SMBHeader_t smbH
; // 0
107 u8 smbWordcount
; // 36
109 u8 smbAndxReserved
; // 38
110 u16 smbAndxOffset
; // 39
113 u8 ByteField
[0]; // 45
114 } __attribute__((packed
));
116 struct TreeConnectAndXRequest_t
{
117 struct SMBHeader_t smbH
; // 0
118 u8 smbWordcount
; // 36
120 u8 smbAndxReserved
; // 38
121 u16 smbAndxOffset
; // 39
123 u16 PasswordLength
; // 43
125 u8 ByteField
[0]; // 47
126 } __attribute__((packed
));
128 struct TreeConnectAndXResponse_t
{
129 struct SMBHeader_t smbH
; // 0
130 u8 smbWordcount
; // 36
132 u8 smbAndxReserved
; // 38
133 u16 smbAndxOffset
; // 39
134 u16 OptionalSupport
; // 41
136 } __attribute__((packed
));
138 struct OpenAndXRequest_t
{
139 struct SMBHeader_t smbH
; // 0
140 u8 smbWordcount
; // 36
142 u8 smbAndxReserved
; // 38
143 u16 smbAndxOffset
; // 39
145 u16 AccessMask
; // 43
146 u16 SearchAttributes
; // 45
147 u16 FileAttributes
; // 47
148 u8 CreationTime
[4]; // 49
149 u16 CreateOptions
; // 53
150 u32 AllocationSize
; // 55
151 u32 reserved
[2]; // 59
153 u8 ByteField
[0]; // 69
154 } __attribute__((packed
));
156 struct OpenAndXResponse_t
{
157 struct SMBHeader_t smbH
; // 0
158 u8 smbWordcount
; // 36
160 u8 smbAndxReserved
; // 38
161 u16 smbAndxOffset
; // 39
163 u16 FileAttributes
; // 43
164 u8 LastWriteTime
[4]; // 45
166 u16 GrantedAccess
; // 53
173 } __attribute__((packed
));
175 struct ReadAndXRequest_t
{ // size = 63
176 struct SMBHeader_t smbH
; // 0
177 u8 smbWordcount
; // 36
179 u8 smbAndxReserved
; // 38
180 u16 smbAndxOffset
; // 39
183 u16 MaxCountLow
; // 47
185 u32 MaxCountHigh
; // 51
187 u32 OffsetHigh
; // 57
189 } __attribute__((packed
));
191 struct ReadAndXResponse_t
{
192 struct SMBHeader_t smbH
; // 0
193 u8 smbWordcount
; // 36
195 u8 smbAndxReserved
; // 38
196 u16 smbAndxOffset
; // 39
198 u16 DataCompactionMode
; // 43
200 u16 DataLengthLow
; // 47
201 u16 DataOffset
; // 49
202 u32 DataLengthHigh
; // 51
203 u8 reserved2
[6]; // 55
205 } __attribute__((packed
));
207 struct WriteAndXRequest_t
{ // size = 63
208 struct SMBHeader_t smbH
; // 0
209 u8 smbWordcount
; // 36
211 u8 smbAndxReserved
; // 38
212 u16 smbAndxOffset
; // 39
218 u16 DataLengthHigh
; // 55
219 u16 DataLengthLow
; // 57
220 u16 DataOffset
; // 59
221 u32 OffsetHigh
; // 61
223 } __attribute__((packed
));
230 u8 PrimaryDomainServerName
[32];
232 int SecurityMode
; // 0 = share level, 1 = user level
233 int PasswordType
; // 0 = PlainText passwords, 1 = use challenge/response
235 u8 Password
[48]; // either PlainText, either hashed
241 static server_specs_t server_specs
__attribute__((aligned(64))); // this must still on this alignment, as it's used for DMA
243 #define SERVER_SHARE_SECURITY_LEVEL 0
244 #define SERVER_USER_SECURITY_LEVEL 1
245 #define SERVER_USE_PLAINTEXT_PASSWORD 0
246 #define SERVER_USE_ENCRYPTED_PASSWORD 1
250 struct ReadAndXRequest_t smb_Read_Request
= {
254 0, 0, 0, 0, "\0", 0, 0, 0, 0
258 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
262 struct WriteAndXRequest_t smb_Write_Request
= {
266 0, 0, 0, 0, "\0", 0, 0, 0, 0
270 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
275 static int main_socket
;
277 static u8 SMB_buf
[1024] __attribute__((aligned(64)));
279 extern unsigned int ReadPos
;
281 //-------------------------------------------------------------------------
282 int rawTCP_SetSessionHeader(u32 size
) // Write Session Service header: careful it's raw TCP transport here and not NBT transport
284 // maximum for raw TCP transport (24 bits) !!!
286 SMB_buf
[1] = (size
>> 16) & 0xff;
287 SMB_buf
[2] = (size
>> 8) & 0xff;
293 //-------------------------------------------------------------------------
294 int rawTCP_GetSessionHeader(void) // Read Session Service header: careful it's raw TCP transport here and not NBT transport
298 // maximum for raw TCP transport (24 bits) !!!
300 size
|= SMB_buf
[2] << 8;
301 size
|= SMB_buf
[1] << 16;
306 //-------------------------------------------------------------------------
307 int OpenTCPSession(struct in_addr dst_IP
, u16 dst_port
)
309 register int sock
, ret
;
310 struct sockaddr_in sock_addr
;
313 sock
= plwip_socket(PF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
317 mips_memset(&sock_addr
, 0, sizeof(sock_addr
));
318 sock_addr
.sin_addr
= dst_IP
;
319 sock_addr
.sin_family
= AF_INET
;
320 sock_addr
.sin_port
= htons(dst_port
);
323 ret
= plwip_connect(sock
, (struct sockaddr
*)&sock_addr
, sizeof(sock_addr
));
332 //-------------------------------------------------------------------------
333 int GetSMBServerReply(void)
335 register int rcv_size
, totalpkt_size
, pkt_size
;
337 rcv_size
= plwip_send(main_socket
, SMB_buf
, rawTCP_GetSessionHeader() + 4, 0);
342 rcv_size
= plwip_recvfrom(main_socket
, NULL
, 0, SMB_buf
, sizeof(SMB_buf
), 0, NULL
, NULL
);
346 if (SMB_buf
[0] != 0) // dropping NBSS Session Keep alive
349 // Handle fragmented packets
350 totalpkt_size
= rawTCP_GetSessionHeader() + 4;
352 while (rcv_size
< totalpkt_size
) {
353 pkt_size
= plwip_recvfrom(main_socket
, NULL
, 0, &SMB_buf
[rcv_size
], sizeof(SMB_buf
) - rcv_size
, 0, NULL
, NULL
);
356 rcv_size
+= pkt_size
;
362 //-------------------------------------------------------------------------
363 int smb_NegociateProtocol(char *SMBServerIP
, int SMBServerPort
, char *Username
, char *Password
)
365 char *dialect
= "NT LM 0.12";
366 struct NegociateProtocolRequest_t
*NPR
= (struct NegociateProtocolRequest_t
*)SMB_buf
;
368 struct in_addr dst_addr
;
376 io_sema
= CreateSema(&smp
);
378 dst_addr
.s_addr
= pinet_addr(SMBServerIP
);
380 // Opening TCP session
381 main_socket
= OpenTCPSession(dst_addr
, SMBServerPort
);
385 mips_memset(SMB_buf
, 0, sizeof(SMB_buf
));
387 NPR
->smbH
.Magic
= SMB_MAGIC
;
388 NPR
->smbH
.Cmd
= SMB_COM_NEGOCIATE
;
389 NPR
->smbH
.Flags
= SMB_FLAGS_CASELESS_PATHNAMES
;
390 NPR
->smbH
.Flags2
= SMB_FLAGS2_KNOWS_LONG_NAMES
;
391 length
= strlen(dialect
);
392 NPR
->ByteCount
= length
+2;
393 NPR
->DialectFormat
= 0x02;
394 strcpy(NPR
->DialectName
, dialect
);
396 rawTCP_SetSessionHeader(37+length
);
399 struct NegociateProtocolResponse_t
*NPRsp
= (struct NegociateProtocolResponse_t
*)SMB_buf
;
401 // check sanity of SMB header
402 if (NPRsp
->smbH
.Magic
!= SMB_MAGIC
)
403 goto negociate_retry
;
405 // check there's no error
406 if (NPRsp
->smbH
.Eclass
!= STATUS_SUCCESS
)
407 goto negociate_retry
;
409 if (NPRsp
->smbWordcount
!= 17)
410 goto negociate_retry
;
412 if (NPRsp
->Capabilities
& SERVER_CAP_UNICODE
)
413 server_specs
.StringsCF
= 2;
415 server_specs
.StringsCF
= 1;
417 if (NPRsp
->SecurityMode
& NEGOCIATE_SECURITY_USER_LEVEL
)
418 server_specs
.SecurityMode
= SERVER_USER_SECURITY_LEVEL
;
420 server_specs
.SecurityMode
= SERVER_SHARE_SECURITY_LEVEL
;
422 if (NPRsp
->SecurityMode
& NEGOCIATE_SECURITY_CHALLENGE_RESPONSE
)
423 server_specs
.PasswordType
= SERVER_USE_ENCRYPTED_PASSWORD
;
425 server_specs
.PasswordType
= SERVER_USE_PLAINTEXT_PASSWORD
;
427 // copy to global struct to keep needed information for further communication
428 server_specs
.MaxBufferSize
= NPRsp
->MaxBufferSize
;
429 server_specs
.MaxMpxCount
= NPRsp
->MaxMpxCount
;
430 server_specs
.SessionKey
= NPRsp
->SessionKey
;
431 mips_memcpy(&server_specs
.EncryptionKey
[0], &NPRsp
->ByteField
[0], NPRsp
->KeyLength
);
432 mips_memcpy(&server_specs
.PrimaryDomainServerName
[0], &NPRsp
->ByteField
[NPRsp
->KeyLength
], 32);
433 mips_memcpy(&server_specs
.Username
[0], Username
, 16);
434 mips_memcpy(&server_specs
.Password
[0], Password
, 16);
435 server_specs
.IOPaddr
= (void *)&server_specs
;
436 server_specs
.HashedFlag
= (server_specs
.PasswordType
== SERVER_USE_ENCRYPTED_PASSWORD
) ? 0 : -1;
438 // doing DMA to EE with server_specs
439 SifDmaTransfer_t dmat
[2];
443 dmat
[0].dest
= (void *)UNCACHEDSEG((DMA_ADDR
+ 0x40));
444 dmat
[0].size
= sizeof(server_specs_t
);
445 dmat
[0].src
= (void *)&server_specs
;
446 dmat
[0].attr
= dmat
[1].attr
= SIF_DMA_INT_O
;
447 dmat
[1].dest
= (void *)UNCACHEDSEG(DMA_ADDR
);
449 dmat
[1].src
= (void *)&flag
;
453 CpuSuspendIntr(&oldstate
);
454 id
= sceSifSetDma(&dmat
[0], 2);
455 CpuResumeIntr(oldstate
);
457 while (sceSifDmaStat(id
) >= 0);
459 // wait smbauth code on EE hashed the password
460 while (!(server_specs
.HashedFlag
== 1))
466 //-------------------------------------------------------------------------
467 int smb_SessionSetupAndX(void)
469 struct SessionSetupAndXRequest_t
*SSR
= (struct SessionSetupAndXRequest_t
*)SMB_buf
;
470 register int i
, offset
, CF
;
471 int AuthType
= NTLM_AUTH
;
472 int password_len
= 0;
475 mips_memset(SMB_buf
, 0, sizeof(SMB_buf
));
477 CF
= server_specs
.StringsCF
;
479 SSR
->smbH
.Magic
= SMB_MAGIC
;
480 SSR
->smbH
.Cmd
= SMB_COM_SESSION_SETUP_ANDX
;
481 SSR
->smbH
.Flags
= SMB_FLAGS_CASELESS_PATHNAMES
;
482 SSR
->smbH
.Flags2
= SMB_FLAGS2_KNOWS_LONG_NAMES
| SMB_FLAGS2_32BIT_STATUS
;
484 SSR
->smbH
.Flags2
|= SMB_FLAGS2_UNICODE_STRING
;
485 SSR
->smbWordcount
= 13;
486 SSR
->smbAndxCmd
= SMB_COM_NONE
; // no ANDX command
487 SSR
->MaxBufferSize
= server_specs
.MaxBufferSize
> 65535 ? 65535 : (u16
)server_specs
.MaxBufferSize
;
488 SSR
->MaxMpxCount
= server_specs
.MaxMpxCount
>= 2 ? 2 : (u16
)server_specs
.MaxMpxCount
;
490 SSR
->SessionKey
= server_specs
.SessionKey
;
491 SSR
->Capabilities
= CLIENT_CAP_LARGE_READX
| CLIENT_CAP_UNICODE
| CLIENT_CAP_LARGE_FILES
| CLIENT_CAP_STATUS32
;
496 if (server_specs
.SecurityMode
== SERVER_USER_SECURITY_LEVEL
) {
497 password_len
= server_specs
.PasswordLen
;
498 // Copy the password accordingly to auth type
499 mips_memcpy(&SSR
->ByteField
[offset
], &server_specs
.Password
[(AuthType
<< 4) + (AuthType
<< 3)], password_len
);
500 // fill SSR->AnsiPasswordLength or SSR->UnicodePasswordLength accordingly to auth type
501 if (AuthType
== LM_AUTH
)
502 SSR
->AnsiPasswordLength
= password_len
;
504 SSR
->UnicodePasswordLength
= password_len
;
505 offset
+= password_len
;
508 if ((CF
== 2) && (!(password_len
& 1)))
509 offset
+= 1; // pad needed only for unicode as aligment fix if password length is even
511 for (i
= 0; i
< strlen(server_specs
.Username
); i
++) {
512 SSR
->ByteField
[offset
] = server_specs
.Username
[i
]; // add User name
515 offset
+= CF
; // null terminator
517 for (i
= 0; server_specs
.PrimaryDomainServerName
[i
] != 0; i
+=CF
) {
518 SSR
->ByteField
[offset
] = server_specs
.PrimaryDomainServerName
[i
]; // PrimaryDomain, acquired from Negociate Protocol Response Datas
521 offset
+= CF
; // null terminator
523 for (i
= 0; i
< (CF
<< 1); i
++)
524 SSR
->ByteField
[offset
++] = 0; // NativeOS, NativeLanMan
526 SSR
->ByteCount
= offset
;
528 rawTCP_SetSessionHeader(61+offset
);
531 struct SessionSetupAndXResponse_t
*SSRsp
= (struct SessionSetupAndXResponse_t
*)SMB_buf
;
533 // check sanity of SMB header
534 if (SSRsp
->smbH
.Magic
!= SMB_MAGIC
)
537 // check there's no auth failure
538 if ((server_specs
.SecurityMode
== SERVER_USER_SECURITY_LEVEL
)
539 && ((SSRsp
->smbH
.Eclass
| (SSRsp
->smbH
.Ecode
<< 16)) == STATUS_LOGON_FAILURE
)
540 && (AuthType
== NTLM_AUTH
)) {
542 goto lbl_session_setup
;
545 // check there's no error (NT STATUS error type!)
546 if ((SSRsp
->smbH
.Eclass
| SSRsp
->smbH
.Ecode
) != STATUS_SUCCESS
)
550 UID
= SSRsp
->smbH
.UID
;
555 //-------------------------------------------------------------------------
556 int smb_TreeConnectAndX(char *ShareName
)
558 struct TreeConnectAndXRequest_t
*TCR
= (struct TreeConnectAndXRequest_t
*)SMB_buf
;
559 register int i
, offset
, CF
;
560 int AuthType
= NTLM_AUTH
;
561 int password_len
= 0;
563 mips_memset(SMB_buf
, 0, sizeof(SMB_buf
));
565 CF
= server_specs
.StringsCF
;
567 TCR
->smbH
.Magic
= SMB_MAGIC
;
568 TCR
->smbH
.Cmd
= SMB_COM_TREE_CONNECT_ANDX
;
569 TCR
->smbH
.Flags
= SMB_FLAGS_CASELESS_PATHNAMES
;
570 TCR
->smbH
.Flags2
= SMB_FLAGS2_KNOWS_LONG_NAMES
| SMB_FLAGS2_32BIT_STATUS
;
572 TCR
->smbH
.Flags2
|= SMB_FLAGS2_UNICODE_STRING
;
574 TCR
->smbWordcount
= 4;
575 TCR
->smbAndxCmd
= SMB_COM_NONE
; // no ANDX command
581 if (server_specs
.SecurityMode
== SERVER_SHARE_SECURITY_LEVEL
) {
582 password_len
= server_specs
.PasswordLen
;
583 // Copy the password accordingly to auth type
584 mips_memcpy(&TCR
->ByteField
[offset
], &server_specs
.Password
[(AuthType
<< 4) + (AuthType
<< 3)], password_len
);
586 TCR
->PasswordLength
= password_len
;
587 offset
+= password_len
;
589 if ((CF
== 2) && (!(password_len
& 1)))
590 offset
+= 1; // pad needed only for unicode as aligment fix is password len is even
592 for (i
= 0; i
< strlen(ShareName
); i
++) {
593 TCR
->ByteField
[offset
] = ShareName
[i
]; // add Share name
596 offset
+= CF
; // null terminator
598 mips_memcpy(&TCR
->ByteField
[offset
], "?????\0", 6); // Service, any type of device
601 TCR
->ByteCount
= offset
;
603 rawTCP_SetSessionHeader(43+offset
);
606 struct TreeConnectAndXResponse_t
*TCRsp
= (struct TreeConnectAndXResponse_t
*)SMB_buf
;
608 // check sanity of SMB header
609 if (TCRsp
->smbH
.Magic
!= SMB_MAGIC
)
612 // check there's no error (NT STATUS error type!)
613 if ((TCRsp
->smbH
.Eclass
| TCRsp
->smbH
.Ecode
) != STATUS_SUCCESS
)
617 TID
= TCRsp
->smbH
.TID
;
622 //-------------------------------------------------------------------------
623 int smb_OpenAndX(char *filename
, u16
*FID
, int Write
)
625 struct OpenAndXRequest_t
*OR
= (struct OpenAndXRequest_t
*)SMB_buf
;
626 register int i
, offset
, CF
;
630 mips_memset(SMB_buf
, 0, sizeof(SMB_buf
));
632 CF
= server_specs
.StringsCF
;
634 OR
->smbH
.Magic
= SMB_MAGIC
;
635 OR
->smbH
.Cmd
= SMB_COM_OPEN_ANDX
;
636 OR
->smbH
.Flags
= SMB_FLAGS_CANONICAL_PATHNAMES
; //| SMB_FLAGS_CASELESS_PATHNAMES;
637 OR
->smbH
.Flags2
= SMB_FLAGS2_KNOWS_LONG_NAMES
;
639 OR
->smbH
.Flags2
|= SMB_FLAGS2_UNICODE_STRING
;
642 OR
->smbWordcount
= 15;
643 OR
->smbAndxCmd
= SMB_COM_NONE
; // no ANDX command
644 OR
->AccessMask
= (Write
&& (SMBWRITE
)) ? 2 : 0;
645 OR
->FileAttributes
= (Write
&& (SMBWRITE
)) ? EXT_ATTR_NORMAL
: EXT_ATTR_READONLY
;
646 OR
->CreateOptions
= 1;
650 offset
++; // pad needed only for unicode as aligment fix
652 for (i
= 0; i
< strlen(filename
); i
++) {
653 OR
->ByteField
[offset
] = filename
[i
]; // add filename
658 OR
->ByteCount
= offset
;
660 rawTCP_SetSessionHeader(66+offset
);
663 struct OpenAndXResponse_t
*ORsp
= (struct OpenAndXResponse_t
*)SMB_buf
;
665 // check sanity of SMB header
666 if (ORsp
->smbH
.Magic
!= SMB_MAGIC
)
669 // check there's no error
670 if (ORsp
->smbH
.Eclass
!= STATUS_SUCCESS
)
675 // Prepare header of Read/Write Request by advance
676 smb_Read_Request
.smbH
.UID
= UID
;
677 smb_Read_Request
.smbH
.TID
= TID
;
680 smb_Write_Request
.smbH
.UID
= UID
;
681 smb_Write_Request
.smbH
.TID
= TID
;
684 SIGNALIOSEMA(io_sema
);
689 //-------------------------------------------------------------------------
690 int smb_ReadFile(u16 FID
, u32 offsetlow
, u32 offsethigh
, void *readbuf
, u16 nbytes
)
692 register int rcv_size
, pkt_size
, expected_size
;
694 struct ReadAndXRequest_t
*RR
= (struct ReadAndXRequest_t
*)SMB_buf
;
698 mips_memcpy(RR
, &smb_Read_Request
.smbH
.sessionHeader
, sizeof(struct ReadAndXRequest_t
));
700 RR
->smbH
.sessionHeader
= 0x3b000000;
703 RR
->OffsetLow
= offsetlow
;
704 RR
->OffsetHigh
= offsethigh
;
705 RR
->MaxCountLow
= nbytes
;
709 plwip_send(main_socket
, SMB_buf
, 63, 0);
711 rcv_size
= plwip_recvfrom(main_socket
, SMB_buf
, 49, readbuf
, nbytes
, 0, NULL
, NULL
);
712 expected_size
= rawTCP_GetSessionHeader() + 4;
714 if (SMB_buf
[0] != 0) // dropping NBSS Session Keep alive
717 // Handle fragmented packets
718 while (rcv_size
< expected_size
) {
719 pkt_size
= plwip_recvfrom(main_socket
, NULL
, 0, &((u8
*)readbuf
)[rcv_size
- SMB_buf
[49] - 4], expected_size
- rcv_size
, 0, NULL
, NULL
); // - rcv_size
720 rcv_size
+= pkt_size
;
723 SIGNALIOSEMA(io_sema
);
729 //-------------------------------------------------------------------------
730 int smb_WriteFile(u16 FID
, u32 offsetlow
, u32 offsethigh
, void *writebuf
, u16 nbytes
)
732 struct WriteAndXRequest_t
*WR
= (struct WriteAndXRequest_t
*)SMB_buf
;
736 mips_memcpy(WR
, &smb_Write_Request
.smbH
.sessionHeader
, sizeof(struct WriteAndXRequest_t
));
741 WR
->OffsetLow
= offsetlow
;
742 WR
->OffsetHigh
= offsethigh
;
743 WR
->Remaining
= nbytes
;
744 WR
->DataLengthLow
= nbytes
;
745 WR
->DataOffset
= 0x3b;
746 WR
->ByteCount
= nbytes
;
748 mips_memcpy((void *)(&SMB_buf
[4 + WR
->DataOffset
]), writebuf
, nbytes
);
750 rawTCP_SetSessionHeader(59+nbytes
);
753 SIGNALIOSEMA(io_sema
);
759 //-------------------------------------------------------------------------
760 int smb_ReadCD(unsigned int lsn
, unsigned int nsectors
, void *buf
, int part_num
)
762 register u32 sectors
, offset
, nbytes
;
767 while (nsectors
> 0) {
769 if (sectors
> MAX_SMB_SECTORS
)
770 sectors
= MAX_SMB_SECTORS
;
772 nbytes
= sectors
<< 11;
774 smb_ReadFile((u16
)p_part_start
[part_num
], offset
<< 11, offset
>> 21, p
, nbytes
);
785 //-------------------------------------------------------------------------
786 int smb_Disconnect(void)
788 plwip_close(main_socket
);