4 * Copyright (C) International Business Machines Corp., 2002,2003
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * Contains the routines for constructing the SMB PDUs themselves
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 /* SMB/CIFS PDU handling routines here - except for leftovers in connect.c */
25 /* These are mostly routines that operate on a pathname, or on a tree id */
26 /* (mounted volume), but there are eight handle based routines which must be */
27 /* treated slightly different for reconnection purposes since we never want */
28 /* to reuse a stale file handle and the caller knows the file handle */
31 #include <linux/kernel.h>
32 #include <linux/vfs.h>
33 #include <asm/uaccess.h>
36 #include "cifsproto.h"
37 #include "cifs_unicode.h"
38 #include "cifs_debug.h"
40 #ifdef CONFIG_CIFS_POSIX
45 {CIFS_PROT
, "\2NT LM 0.12"},
46 {CIFS_PROT
, "\2POSIX 2"},
54 {CIFS_PROT
, "\2NT LM 0.12"},
60 /* Mark as invalid, all open files on tree connections since they
61 were closed when session to server was lost */
62 static void mark_open_files_invalid(struct cifsTconInfo
* pTcon
)
64 struct cifsFileInfo
*open_file
= NULL
;
65 struct list_head
* tmp
;
66 struct list_head
* tmp1
;
68 /* list all files open on tree connection and mark them invalid */
69 write_lock(&GlobalSMBSeslock
);
70 list_for_each_safe(tmp
, tmp1
, &pTcon
->openFileList
) {
71 open_file
= list_entry(tmp
,struct cifsFileInfo
, tlist
);
73 open_file
->invalidHandle
= TRUE
;
76 write_unlock(&GlobalSMBSeslock
);
77 /* BB Add call to invalidate_inodes(sb) for all superblocks mounted to this tcon */
81 smb_init(int smb_command
, int wct
, struct cifsTconInfo
*tcon
,
82 void **request_buf
/* returned */ ,
83 void **response_buf
/* returned */ )
87 /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so
88 check for tcp and smb session status done differently
89 for those three - in the calling routine */
91 if((tcon
->ses
) && (tcon
->ses
->server
)){
92 struct nls_table
*nls_codepage
;
93 /* Give Demultiplex thread up to 10 seconds to
94 reconnect, should be greater than cifs socket
95 timeout which is 7 seconds */
96 while(tcon
->ses
->server
->tcpStatus
== CifsNeedReconnect
) {
97 wait_event_interruptible_timeout(tcon
->ses
->server
->response_q
,
98 (tcon
->ses
->server
->tcpStatus
== CifsGood
), 10 * HZ
);
99 if(tcon
->ses
->server
->tcpStatus
== CifsNeedReconnect
) {
100 /* on "soft" mounts we wait once */
101 if((tcon
->retry
== FALSE
) ||
102 (tcon
->ses
->status
== CifsExiting
)) {
103 cFYI(1,("gave up waiting on reconnect in smb_init"));
105 } /* else "hard" mount - keep retrying until
106 process is killed or server comes back up */
107 } else /* TCP session is reestablished now */
112 nls_codepage
= load_nls_default();
113 /* need to prevent multiple threads trying to
114 simultaneously reconnect the same SMB session */
115 down(&tcon
->ses
->sesSem
);
116 if(tcon
->ses
->status
== CifsNeedReconnect
)
117 rc
= cifs_setup_session(0, tcon
->ses
, nls_codepage
);
118 if(!rc
&& (tcon
->tidStatus
== CifsNeedReconnect
)) {
119 mark_open_files_invalid(tcon
);
120 rc
= CIFSTCon(0, tcon
->ses
, tcon
->treeName
, tcon
,
122 up(&tcon
->ses
->sesSem
);
124 atomic_inc(&tconInfoReconnectCount
);
126 cFYI(1, ("reconnect tcon rc = %d", rc
));
127 /* Removed call to reopen open files here -
128 it is safer (and faster) to reopen files
129 one at a time as needed in read and write */
131 /* Check if handle based operation so we
132 know whether we can continue or not without
133 returning to caller to reset file handle */
134 switch(smb_command
) {
135 case SMB_COM_READ_ANDX
:
136 case SMB_COM_WRITE_ANDX
:
138 case SMB_COM_FIND_CLOSE2
:
139 case SMB_COM_LOCKING_ANDX
: {
140 unload_nls(nls_codepage
);
145 up(&tcon
->ses
->sesSem
);
147 unload_nls(nls_codepage
);
156 *request_buf
= cifs_buf_get();
157 if (*request_buf
== 0) {
158 /* BB should we add a retry in here if not a writepage? */
161 /* Although the original thought was we needed the response buf for */
162 /* potential retries of smb operations it turns out we can determine */
163 /* from the mid flags when the request buffer can be resent without */
164 /* having to use a second distinct buffer for the response */
165 *response_buf
= *request_buf
;
167 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
170 #ifdef CONFIG_CIFS_STATS
172 atomic_inc(&tcon
->num_smbs_sent
);
179 CIFSSMBNegotiate(unsigned int xid
, struct cifsSesInfo
*ses
)
182 NEGOTIATE_RSP
*pSMBr
;
185 struct TCP_Server_Info
* server
;
189 server
= ses
->server
;
194 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, NULL
/* no tcon yet */ ,
195 (void **) &pSMB
, (void **) &pSMBr
);
199 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
200 if (extended_security
)
201 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
203 count
= strlen(protocols
[0].name
) + 1;
204 strncpy(pSMB
->DialectsArray
, protocols
[0].name
, 30);
205 /* null guaranteed to be at end of source and target buffers anyway */
207 pSMB
->hdr
.smb_buf_length
+= count
;
208 pSMB
->ByteCount
= cpu_to_le16(count
);
210 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
211 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
213 server
->secMode
= pSMBr
->SecurityMode
;
214 server
->secType
= NTLM
; /* BB override default for NTLMv2 or krb*/
215 /* one byte - no need to convert this or EncryptionKeyLen from le,*/
216 server
->maxReq
= le16_to_cpu(pSMBr
->MaxMpxCount
);
217 /* probably no need to store and check maxvcs */
219 min(le32_to_cpu(pSMBr
->MaxBufferSize
),
220 (__u32
) CIFS_MAX_MSGSIZE
+ MAX_CIFS_HDR_SIZE
);
221 server
->maxRw
= le32_to_cpu(pSMBr
->MaxRawSize
);
222 cFYI(0, ("Max buf = %d ", ses
->server
->maxBuf
));
223 GETU32(ses
->server
->sessid
) = le32_to_cpu(pSMBr
->SessionKey
);
224 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
225 server
->timeZone
= le16_to_cpu(pSMBr
->ServerTimeZone
);
226 /* BB with UTC do we ever need to be using srvr timezone? */
227 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
228 memcpy(server
->cryptKey
, pSMBr
->u
.EncryptionKey
,
229 CIFS_CRYPTO_KEY_SIZE
);
230 } else if ((pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
)
231 && (pSMBr
->EncryptionKeyLength
== 0)) {
232 /* decode security blob */
236 /* BB might be helpful to save off the domain of server here */
238 if ((pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
) &&
239 (server
->capabilities
& CAP_EXTENDED_SECURITY
)) {
240 count
= pSMBr
->ByteCount
;
243 else if (count
== 16) {
244 server
->secType
= RawNTLMSSP
;
245 if (server
->socketUseCount
.counter
> 1) {
247 (server
->server_GUID
,
248 pSMBr
->u
.extended_response
.
251 ("UID of server does not match previous connection to same ip address"));
259 memcpy(server
->server_GUID
,
260 pSMBr
->u
.extended_response
.
263 rc
= decode_negTokenInit(pSMBr
->u
.
270 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
271 if(sign_CIFS_PDUs
== FALSE
) {
272 if(server
->secMode
& SECMODE_SIGN_REQUIRED
)
274 ("Server requires /proc/fs/cifs/PacketSigningEnabled"));
275 server
->secMode
&= ~(SECMODE_SIGN_ENABLED
| SECMODE_SIGN_REQUIRED
);
276 } else if(sign_CIFS_PDUs
== 1) {
277 if((server
->secMode
& SECMODE_SIGN_REQUIRED
) == 0)
278 server
->secMode
&= ~(SECMODE_SIGN_ENABLED
| SECMODE_SIGN_REQUIRED
);
283 cifs_buf_release(pSMB
);
288 CIFSSMBTDis(const int xid
, struct cifsTconInfo
*tcon
)
290 struct smb_hdr
*smb_buffer
;
291 struct smb_hdr
*smb_buffer_response
;
295 cFYI(1, ("In tree disconnect"));
297 * If last user of the connection and
298 * connection alive - disconnect it
299 * If this is the last connection on the server session disconnect it
300 * (and inside session disconnect we should check if tcp socket needs
301 * to be freed and kernel thread woken up).
304 down(&tcon
->tconSem
);
308 atomic_dec(&tcon
->useCount
);
309 if (atomic_read(&tcon
->useCount
) > 0) {
314 /* No need to return error on this operation if tid invalidated and
315 closed on server already e.g. due to tcp session crashing */
316 if(tcon
->tidStatus
== CifsNeedReconnect
) {
321 if((tcon
->ses
== 0) || (tcon
->ses
->server
== 0)) {
326 rc
= smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
327 (void **) &smb_buffer
, (void **) &smb_buffer_response
);
332 rc
= SendReceive(xid
, tcon
->ses
, smb_buffer
, smb_buffer_response
,
335 cFYI(1, (" Tree disconnect failed %d", rc
));
338 cifs_buf_release(smb_buffer
);
341 /* No need to return error on this operation if tid invalidated and
342 closed on server already e.g. due to tcp session crashing */
350 CIFSSMBLogoff(const int xid
, struct cifsSesInfo
*ses
)
352 struct smb_hdr
*smb_buffer_response
;
353 LOGOFF_ANDX_REQ
*pSMB
;
357 cFYI(1, ("In SMBLogoff for session disconnect"));
363 atomic_dec(&ses
->inUse
);
364 if (atomic_read(&ses
->inUse
) > 0) {
369 rc
= smb_init(SMB_COM_LOGOFF_ANDX
, 2, NULL
/* no tcon anymore */,
370 (void **) &pSMB
, (void **) &smb_buffer_response
);
373 if(ses
->server
->secMode
&
374 (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
))
375 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
383 pSMB
->hdr
.Uid
= ses
->Suid
;
385 pSMB
->AndXCommand
= 0xFF;
386 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
387 smb_buffer_response
, &length
, 0);
389 atomic_dec(&ses
->server
->socketUseCount
);
390 if (atomic_read(&ses
->server
->socketUseCount
) == 0) {
391 spin_lock(&GlobalMid_Lock
);
392 ses
->server
->tcpStatus
= CifsExiting
;
393 spin_unlock(&GlobalMid_Lock
);
398 cifs_buf_release(pSMB
);
401 /* if session dead then we do not need to do ulogoff,
402 since server closed smb session, no sense reporting
410 CIFSSMBDelFile(const int xid
, struct cifsTconInfo
*tcon
,
411 const char *fileName
, const struct nls_table
*nls_codepage
)
413 DELETE_FILE_REQ
*pSMB
= NULL
;
414 DELETE_FILE_RSP
*pSMBr
= NULL
;
420 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
425 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
427 cifs_strtoUCS((wchar_t *) pSMB
->fileName
, fileName
, 530
428 /* find define for this maxpathcomponent */
430 name_len
++; /* trailing null */
432 } else { /* BB improve the check for buffer overruns BB */
433 name_len
= strnlen(fileName
, 530);
434 name_len
++; /* trailing null */
435 strncpy(pSMB
->fileName
, fileName
, name_len
);
437 pSMB
->SearchAttributes
=
438 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
439 pSMB
->BufferFormat
= 0x04;
440 pSMB
->hdr
.smb_buf_length
+= name_len
+ 1;
441 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
442 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
443 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
445 cFYI(1, ("Error in RMFile = %d", rc
));
447 #ifdef CONFIG_CIFS_STATS
449 atomic_inc(&tcon
->num_deletes
);
454 cifs_buf_release(pSMB
);
462 CIFSSMBRmDir(const int xid
, struct cifsTconInfo
*tcon
,
463 const char *dirName
, const struct nls_table
*nls_codepage
)
465 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
466 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
471 cFYI(1, ("In CIFSSMBRmDir"));
473 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
478 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
479 name_len
= cifs_strtoUCS((wchar_t *) pSMB
->DirName
, dirName
, 530
480 /* find define for this maxpathcomponent */
482 name_len
++; /* trailing null */
484 } else { /* BB improve the check for buffer overruns BB */
485 name_len
= strnlen(dirName
, 530);
486 name_len
++; /* trailing null */
487 strncpy(pSMB
->DirName
, dirName
, name_len
);
490 pSMB
->BufferFormat
= 0x04;
491 pSMB
->hdr
.smb_buf_length
+= name_len
+ 1;
492 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
493 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
494 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
496 cFYI(1, ("Error in RMDir = %d", rc
));
498 #ifdef CONFIG_CIFS_STATS
500 atomic_inc(&tcon
->num_rmdirs
);
505 cifs_buf_release(pSMB
);
512 CIFSSMBMkDir(const int xid
, struct cifsTconInfo
*tcon
,
513 const char *name
, const struct nls_table
*nls_codepage
)
516 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
517 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
521 cFYI(1, ("In CIFSSMBMkDir"));
523 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
528 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
529 name_len
= cifs_strtoUCS((wchar_t *) pSMB
->DirName
, name
, 530
530 /* find define for this maxpathcomponent */
532 name_len
++; /* trailing null */
534 } else { /* BB improve the check for buffer overruns BB */
535 name_len
= strnlen(name
, 530);
536 name_len
++; /* trailing null */
537 strncpy(pSMB
->DirName
, name
, name_len
);
540 pSMB
->BufferFormat
= 0x04;
541 pSMB
->hdr
.smb_buf_length
+= name_len
+ 1;
542 pSMB
->ByteCount
= cpu_to_le16(name_len
+ 1);
543 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
544 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
546 cFYI(1, ("Error in Mkdir = %d", rc
));
548 #ifdef CONFIG_CIFS_STATS
550 atomic_inc(&tcon
->num_mkdirs
);
554 cifs_buf_release(pSMB
);
561 CIFSSMBOpen(const int xid
, struct cifsTconInfo
*tcon
,
562 const char *fileName
, const int openDisposition
,
563 const int access_flags
, const int create_options
, __u16
* netfid
,
564 int *pOplock
, FILE_ALL_INFO
* pfile_info
,
565 const struct nls_table
*nls_codepage
)
568 OPEN_REQ
*pSMB
= NULL
;
569 OPEN_RSP
*pSMBr
= NULL
;
575 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **) &pSMB
,
580 pSMB
->AndXCommand
= 0xFF; /* none */
582 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
583 count
= 1; /* account for one byte pad to word boundary */
585 cifs_strtoUCS((wchar_t *) (pSMB
->fileName
+ 1),
587 /* find define for this maxpathcomponent */
589 name_len
++; /* trailing null */
591 pSMB
->NameLength
= cpu_to_le16(name_len
);
592 } else { /* BB improve the check for buffer overruns BB */
593 count
= 0; /* no pad */
594 name_len
= strnlen(fileName
, 530);
595 name_len
++; /* trailing null */
596 pSMB
->NameLength
= cpu_to_le16(name_len
);
597 strncpy(pSMB
->fileName
, fileName
, name_len
);
599 if (*pOplock
& REQ_OPLOCK
)
600 pSMB
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
601 else if (*pOplock
& REQ_BATCHOPLOCK
) {
602 pSMB
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
604 pSMB
->DesiredAccess
= cpu_to_le32(access_flags
);
605 pSMB
->AllocationSize
= 0;
606 pSMB
->FileAttributes
= cpu_to_le32(ATTR_NORMAL
);
607 /* XP does not handle ATTR_POSIX_SEMANTICS */
608 /* but it helps speed up case sensitive checks for other
609 servers such as Samba */
610 if (tcon
->ses
->capabilities
& CAP_UNIX
)
611 pSMB
->FileAttributes
|= cpu_to_le32(ATTR_POSIX_SEMANTICS
);
613 /* if ((omode & S_IWUGO) == 0)
614 pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/
615 /* Above line causes problems due to vfs splitting create into two
616 pieces - need to set mode after file created not while it is
618 pSMB
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
619 pSMB
->CreateDisposition
= cpu_to_le32(openDisposition
);
620 pSMB
->CreateOptions
= cpu_to_le32(create_options
);
621 pSMB
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
); /* BB ??*/
622 pSMB
->SecurityFlags
=
623 SECURITY_CONTEXT_TRACKING
| SECURITY_EFFECTIVE_ONLY
;
626 pSMB
->hdr
.smb_buf_length
+= count
;
628 pSMB
->ByteCount
= cpu_to_le16(count
);
629 /* long_op set to 1 to allow for oplock break timeouts */
630 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
631 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 1);
633 cFYI(1, ("Error in Open = %d", rc
));
635 *pOplock
= pSMBr
->OplockLevel
; /* one byte no need to le_to_cpu */
636 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
637 /* Let caller know file was created so we can set the mode. */
638 /* Do we care about the CreateAction in any other cases? */
639 if(cpu_to_le32(FILE_CREATE
) == pSMBr
->CreateAction
)
640 *pOplock
|= CIFS_CREATE_ACTION
;
642 memcpy((char *)pfile_info
,(char *)&pSMBr
->CreationTime
,
643 36 /* CreationTime to Attributes */);
644 /* the file_info buf is endian converted by caller */
645 pfile_info
->AllocationSize
= pSMBr
->AllocationSize
;
646 pfile_info
->EndOfFile
= pSMBr
->EndOfFile
;
647 pfile_info
->NumberOfLinks
= cpu_to_le32(1);
650 #ifdef CONFIG_CIFS_STATS
651 atomic_inc(&tcon
->num_opens
);
655 cifs_buf_release(pSMB
);
661 /* If no buffer passed in, then caller wants to do the copy
662 as in the case of readpages so the SMB buffer must be
663 freed by the caller */
666 CIFSSMBRead(const int xid
, struct cifsTconInfo
*tcon
,
667 const int netfid
, const unsigned int count
,
668 const __u64 lseek
, unsigned int *nbytes
, char **buf
)
671 READ_REQ
*pSMB
= NULL
;
672 READ_RSP
*pSMBr
= NULL
;
673 char *pReadData
= NULL
;
677 rc
= smb_init(SMB_COM_READ_ANDX
, 12, tcon
, (void **) &pSMB
,
682 /* tcon and ses pointer are checked in smb_init */
683 if (tcon
->ses
->server
== NULL
)
684 return -ECONNABORTED
;
686 pSMB
->AndXCommand
= 0xFF; /* none */
688 pSMB
->OffsetLow
= cpu_to_le32(lseek
& 0xFFFFFFFF);
689 pSMB
->OffsetHigh
= cpu_to_le32(lseek
>> 32);
691 pSMB
->MaxCount
= cpu_to_le16(count
);
692 pSMB
->MaxCountHigh
= 0;
693 pSMB
->ByteCount
= 0; /* no need to do le conversion since it is 0 */
695 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
696 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
698 cERROR(1, ("Send error in read = %d", rc
));
700 __u16 data_length
= le16_to_cpu(pSMBr
->DataLength
);
701 *nbytes
= data_length
;
702 /*check that DataLength would not go beyond end of SMB */
703 if ((data_length
> CIFS_MAX_MSGSIZE
)
704 || (data_length
> count
)) {
705 cFYI(1,("bad length %d for count %d",data_length
,count
));
710 (char *) (&pSMBr
->hdr
.Protocol
) +
711 le16_to_cpu(pSMBr
->DataOffset
);
712 /* if(rc = copy_to_user(buf, pReadData, data_length)) {
713 cERROR(1,("Faulting on read rc = %d",rc));
715 }*/ /* can not use copy_to_user when using page cache*/
717 memcpy(*buf
,pReadData
,data_length
);
722 cifs_buf_release(pSMB
);
727 /* Note: On -EAGAIN error only caller can retry on handle based calls
728 since file handle passed in no longer valid */
733 CIFSSMBWrite(const int xid
, struct cifsTconInfo
*tcon
,
734 const int netfid
, const unsigned int count
,
735 const __u64 offset
, unsigned int *nbytes
, const char *buf
,
739 WRITE_REQ
*pSMB
= NULL
;
740 WRITE_RSP
*pSMBr
= NULL
;
745 rc
= smb_init(SMB_COM_WRITE_ANDX
, 14, tcon
, (void **) &pSMB
,
749 /* tcon and ses pointer are checked in smb_init */
750 if (tcon
->ses
->server
== NULL
)
751 return -ECONNABORTED
;
753 pSMB
->AndXCommand
= 0xFF; /* none */
755 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
756 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
758 bytes_sent
= (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
) & ~0xFF;
759 if (bytes_sent
> count
)
761 pSMB
->DataLengthHigh
= 0;
763 cpu_to_le16(offsetof(struct smb_com_write_req
,Data
) - 4);
765 memcpy(pSMB
->Data
,buf
,bytes_sent
);
767 byte_count
= bytes_sent
+ 1 /* pad */ ;
768 pSMB
->DataLengthLow
= cpu_to_le16(bytes_sent
);
769 pSMB
->DataLengthHigh
= 0;
770 pSMB
->hdr
.smb_buf_length
+= byte_count
;
771 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
773 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
774 (struct smb_hdr
*) pSMBr
, &bytes_returned
, long_op
);
776 cFYI(1, ("Send error in write = %d", rc
));
779 *nbytes
= le16_to_cpu(pSMBr
->Count
);
782 cifs_buf_release(pSMB
);
784 /* Note: On -EAGAIN error only caller can retry on handle based calls
785 since file handle passed in no longer valid */
791 CIFSSMBLock(const int xid
, struct cifsTconInfo
*tcon
,
792 const __u16 smb_file_id
, const __u64 len
,
793 const __u64 offset
, const __u32 numUnlock
,
794 const __u32 numLock
, const __u8 lockType
, const int waitFlag
)
797 LOCK_REQ
*pSMB
= NULL
;
798 LOCK_RSP
*pSMBr
= NULL
;
803 cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d",waitFlag
,numLock
));
804 rc
= smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
,
809 if(lockType
== LOCKING_ANDX_OPLOCK_RELEASE
) {
810 timeout
= -1; /* no response expected */
812 } else if (waitFlag
== TRUE
) {
813 timeout
= 3; /* blocking operation, no timeout */
814 pSMB
->Timeout
= cpu_to_le32(-1);/* blocking - do not time out */
819 pSMB
->NumberOfLocks
= cpu_to_le16(numLock
);
820 pSMB
->NumberOfUnlocks
= cpu_to_le16(numUnlock
);
821 pSMB
->LockType
= lockType
;
822 pSMB
->AndXCommand
= 0xFF; /* none */
823 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
825 if((numLock
!= 0) || (numUnlock
!= 0)) {
826 pSMB
->Locks
[0].Pid
= cpu_to_le16(current
->tgid
);
827 /* BB where to store pid high? */
828 pSMB
->Locks
[0].LengthLow
= cpu_to_le32((u32
)len
);
829 pSMB
->Locks
[0].LengthHigh
= cpu_to_le32((u32
)(len
>>32));
830 pSMB
->Locks
[0].OffsetLow
= cpu_to_le32((u32
)offset
);
831 pSMB
->Locks
[0].OffsetHigh
= cpu_to_le32((u32
)(offset
>>32));
832 count
= sizeof(LOCKING_ANDX_RANGE
);
837 pSMB
->hdr
.smb_buf_length
+= count
;
838 pSMB
->ByteCount
= cpu_to_le16(count
);
840 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
841 (struct smb_hdr
*) pSMBr
, &bytes_returned
, timeout
);
844 cFYI(1, ("Send error in Lock = %d", rc
));
847 cifs_buf_release(pSMB
);
849 /* Note: On -EAGAIN error only caller can retry on handle based calls
850 since file handle passed in no longer valid */
855 CIFSSMBClose(const int xid
, struct cifsTconInfo
*tcon
, int smb_file_id
)
858 CLOSE_REQ
*pSMB
= NULL
;
859 CLOSE_RSP
*pSMBr
= NULL
;
861 cFYI(1, ("In CIFSSMBClose"));
863 /* do not retry on dead session on close */
864 rc
= smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
,
871 pSMB
->FileID
= (__u16
) smb_file_id
;
872 pSMB
->LastWriteTime
= 0;
874 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
875 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
878 /* EINTR is expected when user ctl-c to kill app */
879 cERROR(1, ("Send error in Close = %d", rc
));
883 cifs_buf_release(pSMB
);
885 /* Since session is dead, file will be closed on server already */
893 CIFSSMBRename(const int xid
, struct cifsTconInfo
*tcon
,
894 const char *fromName
, const char *toName
,
895 const struct nls_table
*nls_codepage
)
898 RENAME_REQ
*pSMB
= NULL
;
899 RENAME_RSP
*pSMBr
= NULL
;
901 int name_len
, name_len2
;
904 cFYI(1, ("In CIFSSMBRename"));
906 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
911 pSMB
->BufferFormat
= 0x04;
912 pSMB
->SearchAttributes
=
913 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
916 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
918 cifs_strtoUCS((wchar_t *) pSMB
->OldFileName
, fromName
, 530
919 /* find define for this maxpathcomponent */
921 name_len
++; /* trailing null */
923 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
924 /* protocol requires ASCII signature byte on Unicode string */
925 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
927 cifs_strtoUCS((wchar_t *) & pSMB
->
928 OldFileName
[name_len
+ 2], toName
, 530,
930 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
931 name_len2
*= 2; /* convert to bytes */
932 } else { /* BB improve the check for buffer overruns BB */
933 name_len
= strnlen(fromName
, 530);
934 name_len
++; /* trailing null */
935 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
936 name_len2
= strnlen(toName
, 530);
937 name_len2
++; /* trailing null */
938 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
939 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
940 name_len2
++; /* trailing null */
941 name_len2
++; /* signature byte */
944 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
945 pSMB
->hdr
.smb_buf_length
+= count
;
946 pSMB
->ByteCount
= cpu_to_le16(count
);
948 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
949 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
951 cFYI(1, ("Send error in rename = %d", rc
));
954 #ifdef CONFIG_CIFS_STATS
956 atomic_inc(&tcon
->num_renames
);
961 cifs_buf_release(pSMB
);
969 int CIFSSMBRenameOpenFile(const int xid
,struct cifsTconInfo
*pTcon
,
970 int netfid
, char * target_name
, const struct nls_table
* nls_codepage
)
972 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
973 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
974 struct set_file_rename
* rename_info
;
976 char dummy_string
[30];
978 int bytes_returned
= 0;
980 __u16 params
, param_offset
, offset
, count
, byte_count
;
982 cFYI(1, ("Rename to File by handle"));
983 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, pTcon
, (void **) &pSMB
,
989 pSMB
->MaxSetupCount
= 0;
994 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
995 offset
= param_offset
+ params
;
997 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
998 rename_info
= (struct set_file_rename
*) data_offset
;
999 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1000 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB PDU from sess */
1001 pSMB
->SetupCount
= 1;
1002 pSMB
->Reserved3
= 0;
1003 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
1004 byte_count
= 3 /* pad */ + params
;
1005 pSMB
->ParameterCount
= cpu_to_le16(params
);
1006 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1007 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1008 pSMB
->DataOffset
= cpu_to_le16(offset
);
1009 /* construct random name ".cifs_tmp<inodenum><mid>" */
1010 rename_info
->overwrite
= cpu_to_le32(1);
1011 rename_info
->root_fid
= 0;
1012 /* unicode only call */
1013 if(target_name
== NULL
) {
1014 sprintf(dummy_string
,"cifs%x",pSMB
->hdr
.Mid
);
1015 len_of_str
= cifs_strtoUCS((wchar_t *) rename_info
->target_name
, dummy_string
, 24, nls_codepage
);
1017 len_of_str
= cifs_strtoUCS((wchar_t *) rename_info
->target_name
, target_name
, 530, nls_codepage
);
1019 rename_info
->target_name_len
= cpu_to_le32(2 * len_of_str
);
1020 count
= 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str
) + 2;
1021 byte_count
+= count
;
1022 pSMB
->DataCount
= cpu_to_le16(count
);
1023 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1025 pSMB
->InformationLevel
=
1026 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION
);
1027 pSMB
->Reserved4
= 0;
1028 pSMB
->hdr
.smb_buf_length
+= byte_count
;
1029 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1030 rc
= SendReceive(xid
, pTcon
->ses
, (struct smb_hdr
*) pSMB
,
1031 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1033 cFYI(1,("Send error in Rename (by file handle) = %d", rc
));
1035 #ifdef CONFIG_CIFS_STATS
1037 atomic_inc(&pTcon
->num_t2renames
);
1041 cifs_buf_release(pSMB
);
1043 /* Note: On -EAGAIN error only caller can retry on handle based calls
1044 since file handle passed in no longer valid */
1050 CIFSSMBCopy(const int xid
, struct cifsTconInfo
*tcon
, const char * fromName
,
1051 const __u16 target_tid
, const char *toName
, const int flags
,
1052 const struct nls_table
*nls_codepage
)
1055 COPY_REQ
*pSMB
= NULL
;
1056 COPY_RSP
*pSMBr
= NULL
;
1058 int name_len
, name_len2
;
1061 cFYI(1, ("In CIFSSMBCopy"));
1063 rc
= smb_init(SMB_COM_COPY
, 1, tcon
, (void **) &pSMB
,
1068 pSMB
->BufferFormat
= 0x04;
1069 pSMB
->Tid2
= target_tid
;
1071 pSMB
->Flags
= cpu_to_le16(flags
& COPY_TREE
);
1073 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1074 name_len
= cifs_strtoUCS((wchar_t *) pSMB
->OldFileName
,
1076 530 /* find define for this maxpathcomponent */,
1078 name_len
++; /* trailing null */
1080 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
1081 /* protocol requires ASCII signature byte on Unicode string */
1082 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
1083 name_len2
= cifs_strtoUCS((wchar_t *) & pSMB
->
1084 OldFileName
[name_len
+ 2], toName
, 530,
1086 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
1087 name_len2
*= 2; /* convert to bytes */
1088 } else { /* BB improve the check for buffer overruns BB */
1089 name_len
= strnlen(fromName
, 530);
1090 name_len
++; /* trailing null */
1091 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
1092 name_len2
= strnlen(toName
, 530);
1093 name_len2
++; /* trailing null */
1094 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
1095 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
1096 name_len2
++; /* trailing null */
1097 name_len2
++; /* signature byte */
1100 count
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
1101 pSMB
->hdr
.smb_buf_length
+= count
;
1102 pSMB
->ByteCount
= cpu_to_le16(count
);
1104 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1105 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1107 cFYI(1, ("Send error in copy = %d with %d files copied",
1108 rc
, le16_to_cpu(pSMBr
->CopyCount
)));
1111 cifs_buf_release(pSMB
);
1120 CIFSUnixCreateSymLink(const int xid
, struct cifsTconInfo
*tcon
,
1121 const char *fromName
, const char *toName
,
1122 const struct nls_table
*nls_codepage
)
1124 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1125 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1128 int name_len_target
;
1130 int bytes_returned
= 0;
1131 __u16 params
, param_offset
, offset
, byte_count
;
1133 cFYI(1, ("In Symlink Unix style"));
1135 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1140 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1142 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, fromName
, 530
1143 /* find define for this maxpathcomponent */
1145 name_len
++; /* trailing null */
1148 } else { /* BB improve the check for buffer overruns BB */
1149 name_len
= strnlen(fromName
, 530);
1150 name_len
++; /* trailing null */
1151 strncpy(pSMB
->FileName
, fromName
, name_len
);
1153 params
= 6 + name_len
;
1154 pSMB
->MaxSetupCount
= 0;
1158 pSMB
->Reserved2
= 0;
1159 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1160 InformationLevel
) - 4;
1161 offset
= param_offset
+ params
;
1163 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
1164 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1166 cifs_strtoUCS((wchar_t *) data_offset
, toName
, 530
1167 /* find define for this maxpathcomponent */
1169 name_len_target
++; /* trailing null */
1170 name_len_target
*= 2;
1171 } else { /* BB improve the check for buffer overruns BB */
1172 name_len_target
= strnlen(toName
, 530);
1173 name_len_target
++; /* trailing null */
1174 strncpy(data_offset
, toName
, name_len_target
);
1177 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1178 /* BB find exact max on data count below from sess */
1179 pSMB
->MaxDataCount
= cpu_to_le16(1000);
1180 pSMB
->SetupCount
= 1;
1181 pSMB
->Reserved3
= 0;
1182 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1183 byte_count
= 3 /* pad */ + params
+ name_len_target
;
1184 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
1185 pSMB
->ParameterCount
= cpu_to_le16(params
);
1186 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1187 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1188 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1189 pSMB
->DataOffset
= cpu_to_le16(offset
);
1190 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
1191 pSMB
->Reserved4
= 0;
1192 pSMB
->hdr
.smb_buf_length
+= byte_count
;
1193 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1194 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1195 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1198 ("Send error in SetPathInfo (create symlink) = %d",
1203 cifs_buf_release(pSMB
);
1206 goto createSymLinkRetry
;
1212 CIFSUnixCreateHardLink(const int xid
, struct cifsTconInfo
*tcon
,
1213 const char *fromName
, const char *toName
,
1214 const struct nls_table
*nls_codepage
)
1216 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
1217 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
1220 int name_len_target
;
1222 int bytes_returned
= 0;
1223 __u16 params
, param_offset
, offset
, byte_count
;
1225 cFYI(1, ("In Create Hard link Unix style"));
1226 createHardLinkRetry
:
1227 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1232 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1233 name_len
= cifs_strtoUCS((wchar_t *) pSMB
->FileName
, toName
, 530
1234 /* find define for this maxpathcomponent */
1236 name_len
++; /* trailing null */
1239 } else { /* BB improve the check for buffer overruns BB */
1240 name_len
= strnlen(toName
, 530);
1241 name_len
++; /* trailing null */
1242 strncpy(pSMB
->FileName
, toName
, name_len
);
1244 params
= 6 + name_len
;
1245 pSMB
->MaxSetupCount
= 0;
1249 pSMB
->Reserved2
= 0;
1250 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
1251 InformationLevel
) - 4;
1252 offset
= param_offset
+ params
;
1254 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
1255 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1257 cifs_strtoUCS((wchar_t *) data_offset
, fromName
, 530
1258 /* find define for this maxpathcomponent */
1260 name_len_target
++; /* trailing null */
1261 name_len_target
*= 2;
1262 } else { /* BB improve the check for buffer overruns BB */
1263 name_len_target
= strnlen(fromName
, 530);
1264 name_len_target
++; /* trailing null */
1265 strncpy(data_offset
, fromName
, name_len_target
);
1268 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1269 /* BB find exact max on data count below from sess*/
1270 pSMB
->MaxDataCount
= cpu_to_le16(1000);
1271 pSMB
->SetupCount
= 1;
1272 pSMB
->Reserved3
= 0;
1273 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
1274 byte_count
= 3 /* pad */ + params
+ name_len_target
;
1275 pSMB
->ParameterCount
= cpu_to_le16(params
);
1276 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1277 pSMB
->DataCount
= cpu_to_le16(name_len_target
);
1278 pSMB
->TotalDataCount
= pSMB
->DataCount
;
1279 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
1280 pSMB
->DataOffset
= cpu_to_le16(offset
);
1281 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
1282 pSMB
->Reserved4
= 0;
1283 pSMB
->hdr
.smb_buf_length
+= byte_count
;
1284 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1285 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1286 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1288 cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc
));
1292 cifs_buf_release(pSMB
);
1294 goto createHardLinkRetry
;
1300 CIFSCreateHardLink(const int xid
, struct cifsTconInfo
*tcon
,
1301 const char *fromName
, const char *toName
,
1302 const struct nls_table
*nls_codepage
)
1305 NT_RENAME_REQ
*pSMB
= NULL
;
1306 RENAME_RSP
*pSMBr
= NULL
;
1308 int name_len
, name_len2
;
1311 cFYI(1, ("In CIFSCreateHardLink"));
1312 winCreateHardLinkRetry
:
1314 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
1319 pSMB
->SearchAttributes
=
1320 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
1322 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
1323 pSMB
->ClusterCount
= 0;
1325 pSMB
->BufferFormat
= 0x04;
1327 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1329 cifs_strtoUCS((wchar_t *) pSMB
->OldFileName
, fromName
, 530
1330 /* find define for this maxpathcomponent */
1332 name_len
++; /* trailing null */
1334 pSMB
->OldFileName
[name_len
] = 0; /* pad */
1335 pSMB
->OldFileName
[name_len
+ 1] = 0x04;
1337 cifs_strtoUCS((wchar_t *) & pSMB
->
1338 OldFileName
[name_len
+ 2], toName
, 530,
1340 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
1341 name_len2
*= 2; /* convert to bytes */
1342 } else { /* BB improve the check for buffer overruns BB */
1343 name_len
= strnlen(fromName
, 530);
1344 name_len
++; /* trailing null */
1345 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
1346 name_len2
= strnlen(toName
, 530);
1347 name_len2
++; /* trailing null */
1348 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
1349 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
1350 name_len2
++; /* trailing null */
1351 name_len2
++; /* signature byte */
1354 count
= 1 /* string type byte */ + name_len
+ name_len2
;
1355 pSMB
->hdr
.smb_buf_length
+= count
;
1356 pSMB
->ByteCount
= cpu_to_le16(count
);
1358 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1359 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1361 cFYI(1, ("Send error in hard link (NT rename) = %d", rc
));
1364 cifs_buf_release(pSMB
);
1366 goto winCreateHardLinkRetry
;
1372 CIFSSMBUnixQuerySymLink(const int xid
, struct cifsTconInfo
*tcon
,
1373 const unsigned char *searchName
,
1374 char *symlinkinfo
, const int buflen
,
1375 const struct nls_table
*nls_codepage
)
1377 /* SMB_QUERY_FILE_UNIX_LINK */
1378 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
1379 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
1383 __u16 params
, byte_count
;
1385 cFYI(1, ("In QPathSymLinkInfo (Unix) for path %s", searchName
));
1388 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1393 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1395 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, searchName
, 530
1396 /* find define for this maxpathcomponent */
1398 name_len
++; /* trailing null */
1400 } else { /* BB improve the check for buffer overruns BB */
1401 name_len
= strnlen(searchName
, 530);
1402 name_len
++; /* trailing null */
1403 strncpy(pSMB
->FileName
, searchName
, name_len
);
1406 params
= 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
1407 pSMB
->TotalDataCount
= 0;
1408 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1409 /* BB find exact max data count below from sess structure BB */
1410 pSMB
->MaxDataCount
= cpu_to_le16(4000);
1411 pSMB
->MaxSetupCount
= 0;
1415 pSMB
->Reserved2
= 0;
1416 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
1417 struct smb_com_transaction2_qpi_req
,InformationLevel
) - 4);
1418 pSMB
->DataCount
= 0;
1419 pSMB
->DataOffset
= 0;
1420 pSMB
->SetupCount
= 1;
1421 pSMB
->Reserved3
= 0;
1422 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
1423 byte_count
= params
+ 1 /* pad */ ;
1424 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
1425 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1426 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
1427 pSMB
->Reserved4
= 0;
1428 pSMB
->hdr
.smb_buf_length
+= byte_count
;
1429 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1431 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1432 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1434 cFYI(1, ("Send error in QuerySymLinkInfo = %d", rc
));
1435 } else { /* decode response */
1436 __u16 data_offset
= le16_to_cpu(pSMBr
->DataOffset
);
1437 __u16 count
= le16_to_cpu(pSMBr
->DataCount
);
1438 if ((pSMBr
->ByteCount
< 2) || (data_offset
> 512))
1439 /* BB also check enough total bytes returned */
1440 rc
= -EIO
; /* bad smb */
1442 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1443 name_len
= UniStrnlen((wchar_t *) ((char *)
1444 &pSMBr
->hdr
.Protocol
+data_offset
),
1445 min_t(const int, buflen
,count
) / 2);
1446 cifs_strfromUCS_le(symlinkinfo
,
1447 (wchar_t *) ((char *)&pSMBr
->hdr
.Protocol
+
1449 name_len
, nls_codepage
);
1451 strncpy(symlinkinfo
,
1452 (char *) &pSMBr
->hdr
.Protocol
+
1454 min_t(const int, buflen
, count
));
1456 symlinkinfo
[buflen
] = 0;
1457 /* just in case so calling code does not go off the end of buffer */
1461 cifs_buf_release(pSMB
);
1463 goto querySymLinkRetry
;
1470 CIFSSMBQueryReparseLinkInfo(const int xid
, struct cifsTconInfo
*tcon
,
1471 const unsigned char *searchName
,
1472 char *symlinkinfo
, const int buflen
,__u16 fid
,
1473 const struct nls_table
*nls_codepage
)
1478 struct smb_com_transaction_ioctl_req
* pSMB
;
1479 struct smb_com_transaction_ioctl_rsp
* pSMBr
;
1481 cFYI(1, ("In Windows reparse style QueryLink for path %s", searchName
));
1482 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
1487 pSMB
->TotalParameterCount
= 0 ;
1488 pSMB
->TotalDataCount
= 0;
1489 pSMB
->MaxParameterCount
= cpu_to_le32(2);
1490 /* BB find exact data count max from sess structure BB */
1491 pSMB
->MaxDataCount
= cpu_to_le32(4000);
1492 pSMB
->MaxSetupCount
= 4;
1494 pSMB
->ParameterOffset
= 0;
1495 pSMB
->DataCount
= 0;
1496 pSMB
->DataOffset
= 0;
1497 pSMB
->SetupCount
= 4;
1498 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
1499 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1500 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
1501 pSMB
->IsFsctl
= 1; /* FSCTL */
1502 pSMB
->IsRootFlag
= 0;
1503 pSMB
->Fid
= fid
; /* file handle always le */
1504 pSMB
->ByteCount
= 0;
1506 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1507 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1509 cFYI(1, ("Send error in QueryReparseLinkInfo = %d", rc
));
1510 } else { /* decode response */
1511 __u32 data_offset
= le32_to_cpu(pSMBr
->DataOffset
);
1512 __u32 data_count
= le32_to_cpu(pSMBr
->DataCount
);
1513 if ((pSMBr
->ByteCount
< 2) || (data_offset
> 512))
1514 /* BB also check enough total bytes returned */
1515 rc
= -EIO
; /* bad smb */
1517 if(data_count
&& (data_count
< 2048)) {
1518 /* could also validate reparse tag && better check name length */
1519 struct reparse_data
* reparse_buf
= (struct reparse_data
*)
1520 ((char *)&pSMBr
->hdr
.Protocol
+ data_offset
);
1521 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1522 name_len
= UniStrnlen((wchar_t *)
1523 (reparse_buf
->LinkNamesBuf
+
1524 reparse_buf
->TargetNameOffset
),
1525 min(buflen
/2, reparse_buf
->TargetNameLen
/ 2));
1526 cifs_strfromUCS_le(symlinkinfo
,
1527 (wchar_t *) (reparse_buf
->LinkNamesBuf
+
1528 reparse_buf
->TargetNameOffset
),
1529 name_len
, nls_codepage
);
1530 } else { /* ASCII names */
1531 strncpy(symlinkinfo
,reparse_buf
->LinkNamesBuf
+
1532 reparse_buf
->TargetNameOffset
,
1533 min_t(const int, buflen
, reparse_buf
->TargetNameLen
));
1537 cFYI(1,("Invalid return data count on get reparse info ioctl"));
1539 symlinkinfo
[buflen
] = 0; /* just in case so the caller
1540 does not go off the end of the buffer */
1541 cFYI(1,("readlink result - %s ",symlinkinfo
));
1545 cifs_buf_release(pSMB
);
1547 /* Note: On -EAGAIN error only caller can retry on handle based calls
1548 since file handle passed in no longer valid */
1554 CIFSSMBQPathInfo(const int xid
, struct cifsTconInfo
*tcon
,
1555 const unsigned char *searchName
,
1556 FILE_ALL_INFO
* pFindData
,
1557 const struct nls_table
*nls_codepage
)
1559 /* level 263 SMB_QUERY_FILE_ALL_INFO */
1560 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
1561 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
1565 __u16 params
, byte_count
;
1567 cFYI(1, ("In QPathInfo path %s", searchName
));
1569 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1574 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1576 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, searchName
, 530
1577 /* find define for this maxpathcomponent */
1579 name_len
++; /* trailing null */
1581 } else { /* BB improve the check for buffer overruns BB */
1582 name_len
= strnlen(searchName
, 530);
1583 name_len
++; /* trailing null */
1584 strncpy(pSMB
->FileName
, searchName
, name_len
);
1587 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */ ;
1588 pSMB
->TotalDataCount
= 0;
1589 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1590 pSMB
->MaxDataCount
= cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
1591 pSMB
->MaxSetupCount
= 0;
1595 pSMB
->Reserved2
= 0;
1596 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
1597 struct smb_com_transaction2_qpi_req
,InformationLevel
) - 4);
1598 pSMB
->DataCount
= 0;
1599 pSMB
->DataOffset
= 0;
1600 pSMB
->SetupCount
= 1;
1601 pSMB
->Reserved3
= 0;
1602 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
1603 byte_count
= params
+ 1 /* pad */ ;
1604 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
1605 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1606 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
1607 pSMB
->Reserved4
= 0;
1608 pSMB
->hdr
.smb_buf_length
+= byte_count
;
1609 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1611 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1612 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1614 cFYI(1, ("Send error in QPathInfo = %d", rc
));
1615 } else { /* decode response */
1616 __u16 data_offset
= le16_to_cpu(pSMBr
->DataOffset
);
1617 /* BB also check enough total bytes returned */
1618 /* BB we need to improve the validity checking
1619 of these trans2 responses */
1620 if ((pSMBr
->ByteCount
< 40) || (data_offset
> 512))
1621 rc
= -EIO
; /* bad smb */
1622 else if (pFindData
){
1623 memcpy((char *) pFindData
,
1624 (char *) &pSMBr
->hdr
.Protocol
+
1625 data_offset
, sizeof (FILE_ALL_INFO
));
1630 cifs_buf_release(pSMB
);
1632 goto QPathInfoRetry
;
1638 CIFSSMBUnixQPathInfo(const int xid
, struct cifsTconInfo
*tcon
,
1639 const unsigned char *searchName
,
1640 FILE_UNIX_BASIC_INFO
* pFindData
,
1641 const struct nls_table
*nls_codepage
)
1643 /* SMB_QUERY_FILE_UNIX_BASIC */
1644 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
1645 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
1647 int bytes_returned
= 0;
1649 __u16 params
, byte_count
;
1651 cFYI(1, ("In QPathInfo (Unix) the path %s", searchName
));
1653 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1658 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1660 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, searchName
, 530
1661 /* find define for this maxpathcomponent */
1663 name_len
++; /* trailing null */
1665 } else { /* BB improve the check for buffer overruns BB */
1666 name_len
= strnlen(searchName
, 530);
1667 name_len
++; /* trailing null */
1668 strncpy(pSMB
->FileName
, searchName
, name_len
);
1671 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */ ;
1672 pSMB
->TotalDataCount
= 0;
1673 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1674 /* BB find exact max SMB PDU from sess structure BB */
1675 pSMB
->MaxDataCount
= cpu_to_le16(4000);
1676 pSMB
->MaxSetupCount
= 0;
1680 pSMB
->Reserved2
= 0;
1681 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
1682 struct smb_com_transaction2_qpi_req
,InformationLevel
) - 4);
1683 pSMB
->DataCount
= 0;
1684 pSMB
->DataOffset
= 0;
1685 pSMB
->SetupCount
= 1;
1686 pSMB
->Reserved3
= 0;
1687 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
1688 byte_count
= params
+ 1 /* pad */ ;
1689 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
1690 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1691 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1692 pSMB
->Reserved4
= 0;
1693 pSMB
->hdr
.smb_buf_length
+= byte_count
;
1694 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1696 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1697 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1699 cFYI(1, ("Send error in QPathInfo = %d", rc
));
1700 } else { /* decode response */
1701 __u16 data_offset
= le16_to_cpu(pSMBr
->DataOffset
);
1702 /* BB also check if enough total bytes returned */
1703 if ((pSMBr
->ByteCount
< sizeof(FILE_UNIX_BASIC_INFO
)) ||
1704 (data_offset
> 512) ||
1705 (data_offset
< sizeof(struct smb_hdr
))) {
1706 cFYI(1,("UnixQPathinfo invalid data offset %d bytes returned %d",
1707 (int)data_offset
,bytes_returned
));
1708 rc
= -EIO
; /* bad smb */
1710 memcpy((char *) pFindData
,
1711 (char *) &pSMBr
->hdr
.Protocol
+
1713 sizeof (FILE_UNIX_BASIC_INFO
));
1717 cifs_buf_release(pSMB
);
1719 goto UnixQPathInfoRetry
;
1725 CIFSFindSingle(const int xid
, struct cifsTconInfo
*tcon
,
1726 const char *searchName
, FILE_ALL_INFO
* findData
,
1727 const struct nls_table
*nls_codepage
)
1729 /* level 257 SMB_ */
1730 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
1731 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
1735 __u16 params
, byte_count
;
1737 cFYI(1, ("In FindUnique"));
1739 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1744 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1746 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, searchName
, 530
1747 /* find define for this maxpathcomponent */
1749 name_len
++; /* trailing null */
1751 } else { /* BB improve the check for buffer overruns BB */
1752 name_len
= strnlen(searchName
, 530);
1753 name_len
++; /* trailing null */
1754 strncpy(pSMB
->FileName
, searchName
, name_len
);
1757 params
= 12 + name_len
/* includes null */ ;
1758 pSMB
->TotalDataCount
= 0; /* no EAs */
1759 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1760 pSMB
->MaxDataCount
= cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
1761 pSMB
->MaxSetupCount
= 0;
1765 pSMB
->Reserved2
= 0;
1766 pSMB
->ParameterOffset
= cpu_to_le16(
1767 offsetof(struct smb_com_transaction2_ffirst_req
,InformationLevel
) - 4);
1768 pSMB
->DataCount
= 0;
1769 pSMB
->DataOffset
= 0;
1770 pSMB
->SetupCount
= 1; /* one byte, no need to le convert */
1771 pSMB
->Reserved3
= 0;
1772 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
1773 byte_count
= params
+ 1 /* pad */ ;
1774 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
1775 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1776 pSMB
->SearchAttributes
=
1777 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
1779 pSMB
->SearchCount
= cpu_to_le16(16); /* BB increase */
1780 pSMB
->SearchFlags
= cpu_to_le16(1);
1781 pSMB
->InformationLevel
= cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO
);
1782 pSMB
->SearchStorageType
= 0; /* BB what should we set this to? BB */
1783 pSMB
->hdr
.smb_buf_length
+= byte_count
;
1784 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1786 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1787 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1790 cFYI(1, ("Send error in FindFileDirInfo = %d", rc
));
1791 } else { /* decode response */
1796 cifs_buf_release(pSMB
);
1798 goto findUniqueRetry
;
1804 CIFSFindFirst(const int xid
, struct cifsTconInfo
*tcon
,
1805 const char *searchName
, FILE_DIRECTORY_INFO
* findData
,
1806 T2_FFIRST_RSP_PARMS
* findParms
,
1807 const struct nls_table
*nls_codepage
, int *pUnicodeFlag
,
1810 /* level 257 SMB_ */
1811 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
1812 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
1813 char *response_data
;
1817 __u16 params
, byte_count
;
1819 cFYI(1, ("In FindFirst"));
1821 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1826 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1828 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, searchName
, 530
1829 /* find define for this maxpathcomponent */
1831 name_len
++; /* trailing null */
1833 } else { /* BB improve the check for buffer overruns BB */
1834 name_len
= strnlen(searchName
, 530);
1835 name_len
++; /* trailing null */
1836 strncpy(pSMB
->FileName
, searchName
, name_len
);
1839 params
= 12 + name_len
/* includes null */ ;
1840 pSMB
->TotalDataCount
= 0; /* no EAs */
1841 pSMB
->MaxParameterCount
= cpu_to_le16(10);
1842 pSMB
->MaxDataCount
= cpu_to_le16((tcon
->ses
->server
->maxBuf
-
1843 MAX_CIFS_HDR_SIZE
) & 0xFFFFFF00);
1844 pSMB
->MaxSetupCount
= 0;
1848 pSMB
->Reserved2
= 0;
1849 byte_count
= params
+ 1 /* pad */ ;
1850 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
1851 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1852 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
1853 smb_com_transaction2_ffirst_req
, SearchAttributes
) - 4);
1854 pSMB
->DataCount
= 0;
1855 pSMB
->DataOffset
= 0;
1856 pSMB
->SetupCount
= 1; /* one byte no need to make endian neutral */
1857 pSMB
->Reserved3
= 0;
1858 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
1859 pSMB
->SearchAttributes
=
1860 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
1862 pSMB
->SearchCount
= cpu_to_le16(CIFS_MAX_MSGSIZE
/ sizeof (FILE_DIRECTORY_INFO
)); /* should this be shrunk even more ? */
1863 pSMB
->SearchFlags
= cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END
| CIFS_SEARCH_RETURN_RESUME
);
1865 /* test for Unix extensions */
1866 if (tcon
->ses
->capabilities
& CAP_UNIX
) {
1867 pSMB
->InformationLevel
= cpu_to_le16(SMB_FIND_FILE_UNIX
);
1870 pSMB
->InformationLevel
=
1871 cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO
);
1874 pSMB
->SearchStorageType
= 0; /* BB what should we set this to? It is not clear if it matters BB */
1875 pSMB
->hdr
.smb_buf_length
+= byte_count
;
1876 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1878 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1879 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1881 if (rc
) { /* BB add logic to retry regular search if Unix search rejected unexpectedly by server */
1882 cFYI(1, ("Error in FindFirst = %d", rc
));
1883 } else { /* decode response */
1884 /* BB add safety checks for these memcpys */
1885 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
1886 *pUnicodeFlag
= TRUE
;
1888 *pUnicodeFlag
= FALSE
;
1890 (char *) &pSMBr
->hdr
.Protocol
+
1891 le16_to_cpu(pSMBr
->ParameterOffset
),
1892 sizeof (T2_FFIRST_RSP_PARMS
));
1894 (char *) &pSMBr
->hdr
.Protocol
+
1895 le16_to_cpu(pSMBr
->DataOffset
);
1896 memcpy(findData
, response_data
, le16_to_cpu(pSMBr
->DataCount
));
1899 cifs_buf_release(pSMB
);
1902 goto findFirstRetry
;
1908 CIFSFindNext(const int xid
, struct cifsTconInfo
*tcon
,
1909 FILE_DIRECTORY_INFO
* findData
, T2_FNEXT_RSP_PARMS
* findParms
,
1910 const __u16 searchHandle
, char * resume_file_name
, int name_len
,
1911 __u32 resume_key
, int *pUnicodeFlag
, int *pUnixFlag
)
1913 /* level 257 SMB_ */
1914 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
1915 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
1916 char *response_data
;
1919 __u16 params
, byte_count
;
1921 cFYI(1, ("In FindNext"));
1923 if(resume_file_name
== NULL
) {
1926 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1931 params
= 14; /* includes 2 bytes of null string, converted to LE below */
1933 pSMB
->TotalDataCount
= 0; /* no EAs */
1934 pSMB
->MaxParameterCount
= cpu_to_le16(8);
1935 pSMB
->MaxDataCount
=
1936 cpu_to_le16((tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
) & 0xFFFFFF00);
1937 pSMB
->MaxSetupCount
= 0;
1941 pSMB
->Reserved2
= 0;
1942 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
1943 struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
1944 pSMB
->DataCount
= 0;
1945 pSMB
->DataOffset
= 0;
1946 pSMB
->SetupCount
= 1;
1947 pSMB
->Reserved3
= 0;
1948 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
1949 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
1950 findParms
->SearchCount
= 0; /* set to zero in case of error */
1952 cpu_to_le16(CIFS_MAX_MSGSIZE
/ sizeof (FILE_DIRECTORY_INFO
));
1953 /* test for Unix extensions */
1954 if (tcon
->ses
->capabilities
& CAP_UNIX
) {
1955 pSMB
->InformationLevel
= cpu_to_le16(SMB_FIND_FILE_UNIX
);
1958 pSMB
->InformationLevel
=
1959 cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO
);
1962 pSMB
->ResumeKey
= resume_key
;
1964 cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END
| CIFS_SEARCH_RETURN_RESUME
);
1965 /* BB add check to make sure we do not cross end of smb */
1966 if(name_len
< CIFS_MAX_MSGSIZE
) {
1967 memcpy(pSMB
->ResumeFileName
, resume_file_name
, name_len
);
1968 byte_count
+= name_len
;
1971 byte_count
= params
+ 1 /* pad */ ;
1972 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
1973 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1974 /* BB improve error handling here */
1975 pSMB
->hdr
.smb_buf_length
+= byte_count
;
1976 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
1978 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1979 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1983 rc
= 0; /* search probably was closed at end of search above */
1985 cFYI(1, ("FindNext returned = %d", rc
));
1986 } else { /* decode response */
1987 /* BB add safety checks for these memcpys */
1988 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
1989 *pUnicodeFlag
= TRUE
;
1991 *pUnicodeFlag
= FALSE
;
1993 (char *) &pSMBr
->hdr
.Protocol
+
1994 le16_to_cpu(pSMBr
->ParameterOffset
),
1995 sizeof (T2_FNEXT_RSP_PARMS
));
1997 (char *) &pSMBr
->hdr
.Protocol
+
1998 le16_to_cpu(pSMBr
->DataOffset
);
1999 memcpy(findData
, response_data
, le16_to_cpu(pSMBr
->DataCount
));
2002 cifs_buf_release(pSMB
);
2004 /* Note: On -EAGAIN error only caller can retry on handle based calls
2005 since file handle passed in no longer valid */
2011 CIFSFindClose(const int xid
, struct cifsTconInfo
*tcon
, const __u16 searchHandle
)
2014 FINDCLOSE_REQ
*pSMB
= NULL
;
2015 CLOSE_RSP
*pSMBr
= NULL
;
2018 cFYI(1, ("In CIFSSMBFindClose"));
2019 rc
= smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **) &pSMB
,
2021 /* no sense returning error if session restarted
2022 file handle has been closed */
2028 pSMB
->FileID
= searchHandle
;
2029 pSMB
->ByteCount
= 0;
2030 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2031 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2033 cERROR(1, ("Send error in FindClose = %d", rc
));
2036 cifs_buf_release(pSMB
);
2038 /* Since session is dead, search handle closed on server already */
2046 CIFSGetDFSRefer(const int xid
, struct cifsSesInfo
*ses
,
2047 const unsigned char *searchName
,
2048 unsigned char **targetUNCs
,
2049 unsigned int *number_of_UNC_in_array
,
2050 const struct nls_table
*nls_codepage
)
2052 /* TRANS2_GET_DFS_REFERRAL */
2053 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
2054 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
2055 struct dfs_referral_level_3
* referrals
= NULL
;
2061 __u16 params
, byte_count
;
2062 *number_of_UNC_in_array
= 0;
2065 cFYI(1, ("In GetDFSRefer the path %s", searchName
));
2069 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, NULL
, (void **) &pSMB
,
2074 pSMB
->hdr
.Tid
= ses
->ipc_tid
;
2075 pSMB
->hdr
.Uid
= ses
->Suid
;
2076 if (ses
->capabilities
& CAP_STATUS32
) {
2077 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
2079 if (ses
->capabilities
& CAP_DFS
) {
2080 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
2083 if (ses
->capabilities
& CAP_UNICODE
) {
2084 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
2086 cifs_strtoUCS((wchar_t *) pSMB
->RequestFileName
,
2088 /* find define for this maxpathcomponent */
2090 name_len
++; /* trailing null */
2092 } else { /* BB improve the check for buffer overruns BB */
2093 name_len
= strnlen(searchName
, 530);
2094 name_len
++; /* trailing null */
2095 strncpy(pSMB
->RequestFileName
, searchName
, name_len
);
2098 params
= 2 /* level */ + name_len
/*includes null */ ;
2099 pSMB
->TotalDataCount
= 0;
2100 pSMB
->DataCount
= 0;
2101 pSMB
->DataOffset
= 0;
2102 pSMB
->MaxParameterCount
= 0;
2103 pSMB
->MaxDataCount
= cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
2104 pSMB
->MaxSetupCount
= 0;
2108 pSMB
->Reserved2
= 0;
2109 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
2110 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
2111 pSMB
->SetupCount
= 1;
2112 pSMB
->Reserved3
= 0;
2113 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
2114 byte_count
= params
+ 3 /* pad */ ;
2115 pSMB
->ParameterCount
= cpu_to_le16(params
);
2116 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2117 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
2118 pSMB
->hdr
.smb_buf_length
+= byte_count
;
2119 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2121 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
2122 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2124 cFYI(1, ("Send error in GetDFSRefer = %d", rc
));
2125 } else { /* decode response */
2126 /* BB Add logic to parse referrals here */
2127 __u16 data_offset
= le16_to_cpu(pSMBr
->DataOffset
);
2128 __u16 data_count
= le16_to_cpu(pSMBr
->DataCount
);
2130 ("Decoding GetDFSRefer response. BCC: %d Offset %d",
2131 pSMBr
->ByteCount
, data_offset
));
2132 if ((pSMBr
->ByteCount
< 17) || (data_offset
> 512)) /* BB also check enough total bytes returned */
2133 rc
= -EIO
; /* bad smb */
2136 (struct dfs_referral_level_3
*)
2137 (8 /* sizeof start of data block */ +
2139 (char *) &pSMBr
->hdr
.Protocol
);
2140 cFYI(1,("num_referrals: %d dfs flags: 0x%x ... \nfor referral one refer size: 0x%x srv type: 0x%x refer flags: 0x%x ttl: 0x%x",
2141 le16_to_cpu(pSMBr
->NumberOfReferrals
),le16_to_cpu(pSMBr
->DFSFlags
), le16_to_cpu(referrals
->ReferralSize
),le16_to_cpu(referrals
->ServerType
),le16_to_cpu(referrals
->ReferralFlags
),le16_to_cpu(referrals
->TimeToLive
)));
2142 /* BB This field is actually two bytes in from start of
2143 data block so we could do safety check that DataBlock
2144 begins at address of pSMBr->NumberOfReferrals */
2145 *number_of_UNC_in_array
= le16_to_cpu(pSMBr
->NumberOfReferrals
);
2147 /* BB Fix below so can return more than one referral */
2148 if(*number_of_UNC_in_array
> 1)
2149 *number_of_UNC_in_array
= 1;
2151 /* get the length of the strings describing refs */
2153 for(i
=0;i
<*number_of_UNC_in_array
;i
++) {
2154 /* make sure that DfsPathOffset not past end */
2155 __u16 offset
= le16_to_cpu(referrals
->DfsPathOffset
);
2156 if (offset
> data_count
) {
2157 /* if invalid referral, stop here and do
2158 not try to copy any more */
2159 *number_of_UNC_in_array
= i
;
2162 temp
= ((char *)referrals
) + offset
;
2164 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2165 name_len
+= UniStrnlen((wchar_t *)temp
,data_count
);
2167 name_len
+= strnlen(temp
,data_count
);
2170 /* BB add check that referral pointer does not fall off end PDU */
2173 /* BB add check for name_len bigger than bcc */
2175 kmalloc(name_len
+1+ (*number_of_UNC_in_array
),GFP_KERNEL
);
2176 if(*targetUNCs
== NULL
) {
2180 /* copy the ref strings */
2182 (struct dfs_referral_level_3
*)
2183 (8 /* sizeof data hdr */ +
2185 (char *) &pSMBr
->hdr
.Protocol
);
2187 for(i
=0;i
<*number_of_UNC_in_array
;i
++) {
2188 temp
= ((char *)referrals
) + le16_to_cpu(referrals
->DfsPathOffset
);
2189 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2190 cifs_strfromUCS_le(*targetUNCs
,
2191 (wchar_t *) temp
, name_len
, nls_codepage
);
2193 strncpy(*targetUNCs
,temp
,name_len
);
2195 /* BB update target_uncs pointers */
2205 cifs_buf_release(pSMB
);
2214 CIFSSMBQFSInfo(const int xid
, struct cifsTconInfo
*tcon
,
2215 struct kstatfs
*FSData
, const struct nls_table
*nls_codepage
)
2217 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
2218 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
2219 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
2220 FILE_SYSTEM_INFO
*response_data
;
2222 int bytes_returned
= 0;
2223 __u16 params
, byte_count
;
2225 cFYI(1, ("In QFSInfo"));
2227 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2232 params
= 2; /* level */
2233 pSMB
->TotalDataCount
= 0;
2234 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2235 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
2236 pSMB
->MaxSetupCount
= 0;
2240 pSMB
->Reserved2
= 0;
2241 byte_count
= params
+ 1 /* pad */ ;
2242 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
2243 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
2244 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
2245 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
2246 pSMB
->DataCount
= 0;
2247 pSMB
->DataOffset
= 0;
2248 pSMB
->SetupCount
= 1;
2249 pSMB
->Reserved3
= 0;
2250 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
2251 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
2252 pSMB
->hdr
.smb_buf_length
+= byte_count
;
2253 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2255 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2256 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2258 cERROR(1, ("Send error in QFSInfo = %d", rc
));
2259 } else { /* decode response */
2260 __u16 data_offset
= le16_to_cpu(pSMBr
->DataOffset
);
2262 ("Decoding qfsinfo response. BCC: %d Offset %d",
2263 pSMBr
->ByteCount
, data_offset
));
2264 if ((pSMBr
->ByteCount
< 24) || (data_offset
> 512)) /* BB also check enough total bytes returned */
2265 rc
= -EIO
; /* bad smb */
2269 *) (((char *) &pSMBr
->hdr
.Protocol
) +
2272 le32_to_cpu(response_data
->BytesPerSector
) *
2273 le32_to_cpu(response_data
->
2274 SectorsPerAllocationUnit
);
2276 le64_to_cpu(response_data
->TotalAllocationUnits
);
2277 FSData
->f_bfree
= FSData
->f_bavail
=
2278 le64_to_cpu(response_data
->FreeAllocationUnits
);
2280 ("Blocks: %lld Free: %lld Block size %ld",
2281 (unsigned long long)FSData
->f_blocks
,
2282 (unsigned long long)FSData
->f_bfree
,
2287 cifs_buf_release(pSMB
);
2296 CIFSSMBQFSAttributeInfo(const int xid
, struct cifsTconInfo
*tcon
,
2297 const struct nls_table
*nls_codepage
)
2299 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
2300 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
2301 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
2302 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
2304 int bytes_returned
= 0;
2305 __u16 params
, byte_count
;
2307 cFYI(1, ("In QFSAttributeInfo"));
2309 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2314 params
= 2; /* level */
2315 pSMB
->TotalDataCount
= 0;
2316 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2317 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
2318 pSMB
->MaxSetupCount
= 0;
2322 pSMB
->Reserved2
= 0;
2323 byte_count
= params
+ 1 /* pad */ ;
2324 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
2325 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
2326 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
2327 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
2328 pSMB
->DataCount
= 0;
2329 pSMB
->DataOffset
= 0;
2330 pSMB
->SetupCount
= 1;
2331 pSMB
->Reserved3
= 0;
2332 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
2333 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
2334 pSMB
->hdr
.smb_buf_length
+= byte_count
;
2335 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2337 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2338 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2340 cERROR(1, ("Send error in QFSAttributeInfo = %d", rc
));
2341 } else { /* decode response */
2342 __u16 data_offset
= le16_to_cpu(pSMBr
->DataOffset
);
2343 if ((pSMBr
->ByteCount
< 13) || (data_offset
> 512)) { /* BB also check enough bytes returned */
2344 rc
= -EIO
; /* bad smb */
2347 (FILE_SYSTEM_ATTRIBUTE_INFO
2348 *) (((char *) &pSMBr
->hdr
.Protocol
) +
2350 memcpy(&tcon
->fsAttrInfo
, response_data
,
2351 sizeof (FILE_SYSTEM_ATTRIBUTE_INFO
));
2355 cifs_buf_release(pSMB
);
2358 goto QFSAttributeRetry
;
2364 CIFSSMBQFSDeviceInfo(const int xid
, struct cifsTconInfo
*tcon
,
2365 const struct nls_table
*nls_codepage
)
2367 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
2368 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
2369 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
2370 FILE_SYSTEM_DEVICE_INFO
*response_data
;
2372 int bytes_returned
= 0;
2373 __u16 params
, byte_count
;
2375 cFYI(1, ("In QFSDeviceInfo"));
2377 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2382 params
= 2; /* level */
2383 pSMB
->TotalDataCount
= 0;
2384 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2385 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
2386 pSMB
->MaxSetupCount
= 0;
2390 pSMB
->Reserved2
= 0;
2391 byte_count
= params
+ 1 /* pad */ ;
2392 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
2393 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
2394 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
2395 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
2397 pSMB
->DataCount
= 0;
2398 pSMB
->DataOffset
= 0;
2399 pSMB
->SetupCount
= 1;
2400 pSMB
->Reserved3
= 0;
2401 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
2402 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
2403 pSMB
->hdr
.smb_buf_length
+= byte_count
;
2404 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2406 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2407 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2409 cFYI(1, ("Send error in QFSDeviceInfo = %d", rc
));
2410 } else { /* decode response */
2411 __u16 data_offset
= le16_to_cpu(pSMBr
->DataOffset
);
2412 if ((pSMBr
->ByteCount
< sizeof (FILE_SYSTEM_DEVICE_INFO
))
2413 || (data_offset
> 512))
2414 rc
= -EIO
; /* bad smb */
2417 (FILE_SYSTEM_DEVICE_INFO
2418 *) (((char *) &pSMBr
->hdr
.Protocol
) +
2420 memcpy(&tcon
->fsDevInfo
, response_data
,
2421 sizeof (FILE_SYSTEM_DEVICE_INFO
));
2425 cifs_buf_release(pSMB
);
2428 goto QFSDeviceRetry
;
2434 CIFSSMBQFSUnixInfo(const int xid
, struct cifsTconInfo
*tcon
,
2435 const struct nls_table
*nls_codepage
)
2437 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
2438 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
2439 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
2440 FILE_SYSTEM_UNIX_INFO
*response_data
;
2442 int bytes_returned
= 0;
2443 __u16 params
, byte_count
;
2445 cFYI(1, ("In QFSUnixInfo"));
2447 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2452 params
= 2; /* level */
2453 pSMB
->TotalDataCount
= 0;
2454 pSMB
->DataCount
= 0;
2455 pSMB
->DataOffset
= 0;
2456 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2457 pSMB
->MaxDataCount
= cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */
2458 pSMB
->MaxSetupCount
= 0;
2462 pSMB
->Reserved2
= 0;
2463 byte_count
= params
+ 1 /* pad */ ;
2464 pSMB
->ParameterCount
= cpu_to_le16(params
);
2465 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2466 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
2467 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
2468 pSMB
->SetupCount
= 1;
2469 pSMB
->Reserved3
= 0;
2470 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
2471 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
2472 pSMB
->hdr
.smb_buf_length
+= byte_count
;
2473 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2475 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2476 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2478 cERROR(1, ("Send error in QFSUnixInfo = %d", rc
));
2479 } else { /* decode response */
2480 __u16 data_offset
= le16_to_cpu(pSMBr
->DataOffset
);
2481 if ((pSMBr
->ByteCount
< 13) || (data_offset
> 512)) {
2482 rc
= -EIO
; /* bad smb */
2485 (FILE_SYSTEM_UNIX_INFO
2486 *) (((char *) &pSMBr
->hdr
.Protocol
) +
2488 memcpy(&tcon
->fsUnixInfo
, response_data
,
2489 sizeof (FILE_SYSTEM_UNIX_INFO
));
2493 cifs_buf_release(pSMB
);
2502 /* We can not use write of zero bytes trick to
2503 set file size due to need for large file support. Also note that
2504 this SetPathInfo is preferred to SetFileInfo based method in next
2505 routine which is only needed to work around a sharing violation bug
2506 in Samba which this routine can run into */
2509 CIFSSMBSetEOF(const int xid
, struct cifsTconInfo
*tcon
, const char *fileName
,
2510 __u64 size
, int SetAllocation
, const struct nls_table
*nls_codepage
)
2512 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
2513 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
2514 struct file_end_of_file_info
*parm_data
;
2517 int bytes_returned
= 0;
2518 __u16 params
, byte_count
, data_count
, param_offset
, offset
;
2520 cFYI(1, ("In SetEOF"));
2522 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2527 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2529 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, fileName
, 530
2530 /* find define for this maxpathcomponent */
2532 name_len
++; /* trailing null */
2534 } else { /* BB improve the check for buffer overruns BB */
2535 name_len
= strnlen(fileName
, 530);
2536 name_len
++; /* trailing null */
2537 strncpy(pSMB
->FileName
, fileName
, name_len
);
2539 params
= 6 + name_len
;
2540 data_count
= sizeof (struct file_end_of_file_info
);
2541 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2542 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB size from sess */
2543 pSMB
->MaxSetupCount
= 0;
2547 pSMB
->Reserved2
= 0;
2548 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2549 InformationLevel
) - 4;
2550 offset
= param_offset
+ params
;
2552 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
2553 pSMB
->InformationLevel
=
2554 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
2556 pSMB
->InformationLevel
=
2557 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
2558 } else /* Set File Size */ {
2559 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
2560 pSMB
->InformationLevel
=
2561 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
2563 pSMB
->InformationLevel
=
2564 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
2568 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
2570 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2571 pSMB
->DataOffset
= cpu_to_le16(offset
);
2572 pSMB
->SetupCount
= 1;
2573 pSMB
->Reserved3
= 0;
2574 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2575 byte_count
= 3 /* pad */ + params
+ data_count
;
2576 pSMB
->DataCount
= cpu_to_le16(data_count
);
2577 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2578 pSMB
->ParameterCount
= cpu_to_le16(params
);
2579 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2580 pSMB
->Reserved4
= 0;
2581 pSMB
->hdr
.smb_buf_length
+= byte_count
;
2582 parm_data
->FileSize
= cpu_to_le64(size
);
2583 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2584 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2585 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2587 cFYI(1, ("SetPathInfo (file size) returned %d", rc
));
2591 cifs_buf_release(pSMB
);
2600 CIFSSMBSetFileSize(const int xid
, struct cifsTconInfo
*tcon
, __u64 size
,
2601 __u16 fid
, __u32 pid_of_opener
, int SetAllocation
)
2603 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2604 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2606 struct file_end_of_file_info
*parm_data
;
2608 int bytes_returned
= 0;
2609 __u16 params
, param_offset
, offset
, byte_count
, count
;
2611 cFYI(1, ("SetFileSize (via SetFileInfo) %lld",
2613 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2618 pSMB
->hdr
.Pid
= cpu_to_le16((__u16
)pid_of_opener
);
2619 pSMB
->hdr
.PidHigh
= cpu_to_le16((__u16
)(pid_of_opener
>> 16));
2622 pSMB
->MaxSetupCount
= 0;
2626 pSMB
->Reserved2
= 0;
2627 param_offset
= offsetof(struct smb_com_transaction2_sfi_req
, Fid
) - 4;
2628 offset
= param_offset
+ params
;
2630 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2632 count
= sizeof(struct file_end_of_file_info
);
2633 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2634 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB PDU from sess */
2635 pSMB
->SetupCount
= 1;
2636 pSMB
->Reserved3
= 0;
2637 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2638 byte_count
= 3 /* pad */ + params
+ count
;
2639 pSMB
->DataCount
= cpu_to_le16(count
);
2640 pSMB
->ParameterCount
= cpu_to_le16(params
);
2641 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2642 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2643 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2645 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
2647 pSMB
->DataOffset
= cpu_to_le16(offset
);
2648 parm_data
->FileSize
= cpu_to_le64(size
);
2651 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
2652 pSMB
->InformationLevel
=
2653 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
2655 pSMB
->InformationLevel
=
2656 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
2657 } else /* Set File Size */ {
2658 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
2659 pSMB
->InformationLevel
=
2660 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
2662 pSMB
->InformationLevel
=
2663 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
2665 pSMB
->Reserved4
= 0;
2666 pSMB
->hdr
.smb_buf_length
+= byte_count
;
2667 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2668 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2669 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2672 ("Send error in SetFileInfo (SetFileSize) = %d",
2677 cifs_buf_release(pSMB
);
2679 /* Note: On -EAGAIN error only caller can retry on handle based calls
2680 since file handle passed in no longer valid */
2686 CIFSSMBSetTimes(const int xid
, struct cifsTconInfo
*tcon
, const char *fileName
,
2687 const FILE_BASIC_INFO
* data
,
2688 const struct nls_table
*nls_codepage
)
2690 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2691 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2694 int bytes_returned
= 0;
2696 __u16 params
, param_offset
, offset
, byte_count
, count
;
2698 cFYI(1, ("In SetTimes"));
2701 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2706 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2708 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, fileName
, 530
2709 /* find define for this maxpathcomponent */
2711 name_len
++; /* trailing null */
2713 } else { /* BB improve the check for buffer overruns BB */
2714 name_len
= strnlen(fileName
, 530);
2715 name_len
++; /* trailing null */
2716 strncpy(pSMB
->FileName
, fileName
, name_len
);
2719 params
= 6 + name_len
;
2720 count
= sizeof (FILE_BASIC_INFO
);
2721 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2722 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
2723 pSMB
->MaxSetupCount
= 0;
2727 pSMB
->Reserved2
= 0;
2728 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2729 InformationLevel
) - 4;
2730 offset
= param_offset
+ params
;
2731 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2732 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2733 pSMB
->DataOffset
= cpu_to_le16(offset
);
2734 pSMB
->SetupCount
= 1;
2735 pSMB
->Reserved3
= 0;
2736 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2737 byte_count
= 3 /* pad */ + params
+ count
;
2739 pSMB
->DataCount
= cpu_to_le16(count
);
2740 pSMB
->ParameterCount
= cpu_to_le16(params
);
2741 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2742 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2743 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
2744 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
2746 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
2747 pSMB
->Reserved4
= 0;
2748 pSMB
->hdr
.smb_buf_length
+= byte_count
;
2749 memcpy(data_offset
, data
, sizeof (FILE_BASIC_INFO
));
2750 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2751 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2752 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2754 cFYI(1, ("SetPathInfo (times) returned %d", rc
));
2758 cifs_buf_release(pSMB
);
2767 CIFSSMBSetTimesLegacy(int xid
, struct cifsTconInfo
*tcon
, char *fileName
,
2768 FILE_INFO_STANDARD
* data
, const struct nls_table
*nls_codepage
)
2770 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2771 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2774 int bytes_returned
= 0;
2776 __u16 params
, param_offset
, count
, offset
, byte_count
;
2778 cFYI(1, ("In SetTimesLegacy"));
2780 SetTimesRetryLegacy
:
2781 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2786 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2788 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, fileName
, 530
2789 /* find define for this maxpathcomponent */
2791 name_len
++; /* trailing null */
2793 } else { /* BB improve the check for buffer overruns BB */
2794 name_len
= strnlen(fileName
, 530);
2795 name_len
++; /* trailing null */
2796 strncpy(pSMB
->FileName
, fileName
, name_len
);
2798 /* BB fixme - we have to map to FILE_STANDARD_INFO (level 1 info
2799 in parent function, from the better and ususal FILE_BASIC_INFO */
2800 params
= 6 + name_len
;
2801 count
= sizeof (FILE_INFO_STANDARD
);
2802 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2803 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
2804 pSMB
->MaxSetupCount
= 0;
2808 pSMB
->Reserved2
= 0;
2809 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2810 InformationLevel
) - 4;
2811 offset
= param_offset
+ params
;
2812 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + offset
;
2813 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2814 pSMB
->DataOffset
= cpu_to_le16(offset
);
2815 pSMB
->SetupCount
= 1;
2816 pSMB
->Reserved3
= 0;
2817 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2818 byte_count
= 3 /* pad */ + params
+ count
;
2820 pSMB
->DataCount
= cpu_to_le16(count
);
2821 pSMB
->ParameterCount
= cpu_to_le16(params
);
2822 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2823 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2824 /* I doubt that passthrough levels apply to this old
2826 /* if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
2827 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
2829 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_STANDARD
);
2830 pSMB
->Reserved4
= 0;
2831 pSMB
->hdr
.smb_buf_length
+= byte_count
;
2832 memcpy(data_offset
, data
, sizeof (FILE_INFO_STANDARD
));
2833 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2834 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2835 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2837 cFYI(1, ("SetPathInfo (times legacy) returned %d", rc
));
2841 cifs_buf_release(pSMB
);
2844 goto SetTimesRetryLegacy
;
2850 CIFSSMBUnixSetPerms(const int xid
, struct cifsTconInfo
*tcon
,
2851 char *fileName
, __u64 mode
, __u64 uid
, __u64 gid
,
2852 dev_t device
, const struct nls_table
*nls_codepage
)
2854 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2855 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2858 int bytes_returned
= 0;
2859 FILE_UNIX_BASIC_INFO
*data_offset
;
2860 __u16 params
, param_offset
, offset
, count
, byte_count
;
2862 cFYI(1, ("In SetUID/GID/Mode"));
2864 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2869 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2871 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, fileName
, 530
2872 /* find define for this maxpathcomponent */
2874 name_len
++; /* trailing null */
2876 } else { /* BB improve the check for buffer overruns BB */
2877 name_len
= strnlen(fileName
, 530);
2878 name_len
++; /* trailing null */
2879 strncpy(pSMB
->FileName
, fileName
, name_len
);
2882 params
= 6 + name_len
;
2883 count
= sizeof (FILE_UNIX_BASIC_INFO
);
2884 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2885 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
2886 pSMB
->MaxSetupCount
= 0;
2890 pSMB
->Reserved2
= 0;
2891 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
2892 InformationLevel
) - 4;
2893 offset
= param_offset
+ params
;
2895 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
2897 pSMB
->DataOffset
= cpu_to_le16(offset
);
2898 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
2899 pSMB
->SetupCount
= 1;
2900 pSMB
->Reserved3
= 0;
2901 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2902 byte_count
= 3 /* pad */ + params
+ count
;
2903 pSMB
->ParameterCount
= cpu_to_le16(params
);
2904 pSMB
->DataCount
= cpu_to_le16(count
);
2905 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2906 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2907 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
2908 pSMB
->Reserved4
= 0;
2909 pSMB
->hdr
.smb_buf_length
+= byte_count
;
2910 data_offset
->Uid
= cpu_to_le64(uid
);
2911 data_offset
->Gid
= cpu_to_le64(gid
);
2912 /* better to leave device as zero when it is */
2913 data_offset
->DevMajor
= cpu_to_le64(MAJOR(device
));
2914 data_offset
->DevMinor
= cpu_to_le64(MINOR(device
));
2915 data_offset
->Permissions
= cpu_to_le64(mode
);
2918 data_offset
->Type
= cpu_to_le32(UNIX_FILE
);
2919 else if(S_ISDIR(mode
))
2920 data_offset
->Type
= cpu_to_le32(UNIX_DIR
);
2921 else if(S_ISLNK(mode
))
2922 data_offset
->Type
= cpu_to_le32(UNIX_SYMLINK
);
2923 else if(S_ISCHR(mode
))
2924 data_offset
->Type
= cpu_to_le32(UNIX_CHARDEV
);
2925 else if(S_ISBLK(mode
))
2926 data_offset
->Type
= cpu_to_le32(UNIX_BLOCKDEV
);
2927 else if(S_ISFIFO(mode
))
2928 data_offset
->Type
= cpu_to_le32(UNIX_FIFO
);
2929 else if(S_ISSOCK(mode
))
2930 data_offset
->Type
= cpu_to_le32(UNIX_SOCKET
);
2933 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
2934 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2935 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2937 cFYI(1, ("SetPathInfo (perms) returned %d", rc
));
2941 cifs_buf_release(pSMB
);
2947 int CIFSSMBNotify(const int xid
, struct cifsTconInfo
*tcon
,
2948 const int notify_subdirs
, const __u16 netfid
,
2949 __u32 filter
, const struct nls_table
*nls_codepage
)
2952 struct smb_com_transaction_change_notify_req
* pSMB
= NULL
;
2953 struct smb_com_transaction_change_notify_rsp
* pSMBr
= NULL
;
2956 cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid
));
2957 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
2962 pSMB
->TotalParameterCount
= 0 ;
2963 pSMB
->TotalDataCount
= 0;
2964 pSMB
->MaxParameterCount
= cpu_to_le32(2);
2965 /* BB find exact data count max from sess structure BB */
2966 pSMB
->MaxDataCount
= 0; /* same in little endian or be */
2967 pSMB
->MaxSetupCount
= 4;
2969 pSMB
->ParameterOffset
= 0;
2970 pSMB
->DataCount
= 0;
2971 pSMB
->DataOffset
= 0;
2972 pSMB
->SetupCount
= 4; /* single byte does not need le conversion */
2973 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE
);
2974 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
2976 pSMB
->WatchTree
= 1; /* one byte - no le conversion needed */
2977 pSMB
->Reserved2
= 0;
2978 pSMB
->CompletionFilter
= cpu_to_le32(filter
);
2979 pSMB
->Fid
= netfid
; /* file handle always le */
2980 pSMB
->ByteCount
= 0;
2982 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2983 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2985 cFYI(1, ("Error in Notify = %d", rc
));
2988 cifs_buf_release(pSMB
);
2989 /* if (rc == -EAGAIN)
2990 goto NotifyRetry; */
2993 #ifdef CONFIG_CIFS_XATTR
2995 CIFSSMBQAllEAs(const int xid
, struct cifsTconInfo
*tcon
,
2996 const unsigned char *searchName
,
2997 char * EAData
, size_t buf_size
,
2998 const struct nls_table
*nls_codepage
)
3000 /* BB assumes one setup word */
3001 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3002 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3006 struct fea
* temp_fea
;
3008 __u16 params
, byte_count
;
3010 cFYI(1, ("In Query All EAs path %s", searchName
));
3012 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3017 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3019 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, searchName
, 530
3020 /* find define for this maxpathcomponent */
3022 name_len
++; /* trailing null */
3024 } else { /* BB improve the check for buffer overruns BB */
3025 name_len
= strnlen(searchName
, 530);
3026 name_len
++; /* trailing null */
3027 strncpy(pSMB
->FileName
, searchName
, name_len
);
3030 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */ ;
3031 pSMB
->TotalDataCount
= 0;
3032 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3033 pSMB
->MaxDataCount
= cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
3034 pSMB
->MaxSetupCount
= 0;
3038 pSMB
->Reserved2
= 0;
3039 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3040 struct smb_com_transaction2_qpi_req
,InformationLevel
) - 4);
3041 pSMB
->DataCount
= 0;
3042 pSMB
->DataOffset
= 0;
3043 pSMB
->SetupCount
= 1;
3044 pSMB
->Reserved3
= 0;
3045 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3046 byte_count
= params
+ 1 /* pad */ ;
3047 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3048 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3049 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
3050 pSMB
->Reserved4
= 0;
3051 pSMB
->hdr
.smb_buf_length
+= byte_count
;
3052 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3054 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3055 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3057 cFYI(1, ("Send error in QueryAllEAs = %d", rc
));
3058 } else { /* decode response */
3059 __u16 data_offset
= le16_to_cpu(pSMBr
->DataOffset
);
3060 /* BB also check enough total bytes returned */
3061 /* BB we need to improve the validity checking
3062 of these trans2 responses */
3063 if ((pSMBr
->ByteCount
< 4) || (data_offset
> 512))
3064 rc
= -EIO
; /* bad smb */
3065 /* else if (pFindData){
3066 memcpy((char *) pFindData,
3067 (char *) &pSMBr->hdr.Protocol +
3070 /* check that length of list is not more than bcc */
3071 /* check that each entry does not go beyond length
3073 /* check that each element of each entry does not
3074 go beyond end of list */
3075 struct fealist
* ea_response_data
;
3077 /* validate_trans2_offsets() */
3078 /* BB to check if(start of smb + data_offset > &bcc+ bcc)*/
3079 ea_response_data
= (struct fealist
*)
3080 (((char *) &pSMBr
->hdr
.Protocol
) +
3082 name_len
= le32_to_cpu(ea_response_data
->list_len
);
3083 cFYI(1,("ea length %d", name_len
));
3085 /* returned EA size zeroed at top of function */
3086 cFYI(1,("empty EA list returned from server"));
3088 /* account for ea list len */
3090 temp_fea
= ea_response_data
->list
;
3091 temp_ptr
= (char *)temp_fea
;
3092 while(name_len
> 0) {
3096 rc
+= temp_fea
->name_len
;
3097 /* account for prefix user. and trailing null */
3099 if(rc
<(int)buf_size
) {
3100 memcpy(EAData
,"user.",5);
3102 memcpy(EAData
,temp_ptr
,temp_fea
->name_len
);
3103 EAData
+=temp_fea
->name_len
;
3104 /* null terminate name */
3106 EAData
= EAData
+ 1;
3107 } else if(buf_size
== 0) {
3108 /* skip copy - calc size only */
3110 /* stop before overrun buffer */
3114 name_len
-= temp_fea
->name_len
;
3115 temp_ptr
+= temp_fea
->name_len
;
3116 /* account for trailing null */
3119 value_len
= le16_to_cpu(temp_fea
->value_len
);
3120 name_len
-= value_len
;
3121 temp_ptr
+= value_len
;
3122 /* BB check that temp_ptr is still within smb BB*/
3123 /* no trailing null to account for in value len */
3124 /* go on to next EA */
3125 temp_fea
= (struct fea
*)temp_ptr
;
3131 cifs_buf_release(pSMB
);
3138 ssize_t
CIFSSMBQueryEA(const int xid
,struct cifsTconInfo
* tcon
,
3139 const unsigned char * searchName
,const unsigned char * ea_name
,
3140 unsigned char * ea_value
, size_t buf_size
,
3141 const struct nls_table
*nls_codepage
)
3143 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
3144 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
3148 struct fea
* temp_fea
;
3150 __u16 params
, byte_count
;
3152 cFYI(1, ("In Query EA path %s", searchName
));
3154 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3159 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3161 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, searchName
, 530
3162 /* find define for this maxpathcomponent */
3164 name_len
++; /* trailing null */
3166 } else { /* BB improve the check for buffer overruns BB */
3167 name_len
= strnlen(searchName
, 530);
3168 name_len
++; /* trailing null */
3169 strncpy(pSMB
->FileName
, searchName
, name_len
);
3172 params
= 2 /* level */ + 4 /* reserved */ + name_len
/* includes NUL */ ;
3173 pSMB
->TotalDataCount
= 0;
3174 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3175 pSMB
->MaxDataCount
= cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
3176 pSMB
->MaxSetupCount
= 0;
3180 pSMB
->Reserved2
= 0;
3181 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
3182 struct smb_com_transaction2_qpi_req
,InformationLevel
) - 4);
3183 pSMB
->DataCount
= 0;
3184 pSMB
->DataOffset
= 0;
3185 pSMB
->SetupCount
= 1;
3186 pSMB
->Reserved3
= 0;
3187 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
3188 byte_count
= params
+ 1 /* pad */ ;
3189 pSMB
->TotalParameterCount
= cpu_to_le16(params
);
3190 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
3191 pSMB
->InformationLevel
= cpu_to_le16(SMB_INFO_QUERY_ALL_EAS
);
3192 pSMB
->Reserved4
= 0;
3193 pSMB
->hdr
.smb_buf_length
+= byte_count
;
3194 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3196 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3197 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3199 cFYI(1, ("Send error in Query EA = %d", rc
));
3200 } else { /* decode response */
3201 __u16 data_offset
= le16_to_cpu(pSMBr
->DataOffset
);
3202 /* BB also check enough total bytes returned */
3203 /* BB we need to improve the validity checking
3204 of these trans2 responses */
3205 if ((pSMBr
->ByteCount
< 4) || (data_offset
> 512))
3206 rc
= -EIO
; /* bad smb */
3207 /* else if (pFindData){
3208 memcpy((char *) pFindData,
3209 (char *) &pSMBr->hdr.Protocol +
3212 /* check that length of list is not more than bcc */
3213 /* check that each entry does not go beyond length
3215 /* check that each element of each entry does not
3216 go beyond end of list */
3217 struct fealist
* ea_response_data
;
3219 /* validate_trans2_offsets() */
3220 /* BB to check if(start of smb + data_offset > &bcc+ bcc)*/
3221 ea_response_data
= (struct fealist
*)
3222 (((char *) &pSMBr
->hdr
.Protocol
) +
3224 name_len
= le32_to_cpu(ea_response_data
->list_len
);
3225 cFYI(1,("ea length %d", name_len
));
3227 /* returned EA size zeroed at top of function */
3228 cFYI(1,("empty EA list returned from server"));
3230 /* account for ea list len */
3232 temp_fea
= ea_response_data
->list
;
3233 temp_ptr
= (char *)temp_fea
;
3234 /* loop through checking if we have a matching
3235 name and then return the associated value */
3236 while(name_len
> 0) {
3240 value_len
= le16_to_cpu(temp_fea
->value_len
);
3241 /* BB validate that value_len falls within SMB,
3242 even though maximum for name_len is 255 */
3243 if(memcmp(temp_fea
->name
,ea_name
,
3244 temp_fea
->name_len
) == 0) {
3247 /* account for prefix user. and trailing null */
3248 if(rc
<=(int)buf_size
) {
3250 temp_fea
->name
+temp_fea
->name_len
+1,
3252 /* ea values, unlike ea names,
3253 are not null terminated */
3254 } else if(buf_size
== 0) {
3255 /* skip copy - calc size only */
3257 /* stop before overrun buffer */
3262 name_len
-= temp_fea
->name_len
;
3263 temp_ptr
+= temp_fea
->name_len
;
3264 /* account for trailing null */
3267 name_len
-= value_len
;
3268 temp_ptr
+= value_len
;
3269 /* no trailing null to account for in value len */
3270 /* go on to next EA */
3271 temp_fea
= (struct fea
*)temp_ptr
;
3277 cifs_buf_release(pSMB
);
3285 CIFSSMBSetEA(const int xid
, struct cifsTconInfo
*tcon
, const char *fileName
,
3286 const char * ea_name
, const void * ea_value
,
3287 const __u16 ea_value_len
, const struct nls_table
*nls_codepage
)
3289 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
3290 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
3291 struct fealist
*parm_data
;
3294 int bytes_returned
= 0;
3295 __u16 params
, param_offset
, byte_count
, offset
, count
;
3297 cFYI(1, ("In SetEA"));
3299 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
3304 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
3306 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, fileName
, 530
3307 /* find define for this maxpathcomponent */
3309 name_len
++; /* trailing null */
3311 } else { /* BB improve the check for buffer overruns BB */
3312 name_len
= strnlen(fileName
, 530);
3313 name_len
++; /* trailing null */
3314 strncpy(pSMB
->FileName
, fileName
, name_len
);
3317 params
= 6 + name_len
;
3319 /* done calculating parms using name_len of file name,
3320 now use name_len to calculate length of ea name
3321 we are going to create in the inode xattrs */
3325 name_len
= strnlen(ea_name
,255);
3327 count
= sizeof(*parm_data
) + ea_value_len
+ name_len
+ 1;
3328 pSMB
->MaxParameterCount
= cpu_to_le16(2);
3329 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB size from sess */
3330 pSMB
->MaxSetupCount
= 0;
3334 pSMB
->Reserved2
= 0;
3335 param_offset
= offsetof(struct smb_com_transaction2_spi_req
,
3336 InformationLevel
) - 4;
3337 offset
= param_offset
+ params
;
3338 pSMB
->InformationLevel
=
3339 cpu_to_le16(SMB_SET_FILE_EA
);
3342 (struct fealist
*) (((char *) &pSMB
->hdr
.Protocol
) +
3344 pSMB
->ParameterOffset
= cpu_to_le16(param_offset
);
3345 pSMB
->DataOffset
= cpu_to_le16(offset
);
3346 pSMB
->SetupCount
= 1;
3347 pSMB
->Reserved3
= 0;
3348 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
3349 byte_count
= 3 /* pad */ + params
+ count
;
3350 pSMB
->DataCount
= cpu_to_le16(count
);
3351 parm_data
->list_len
= cpu_to_le32(count
);
3352 parm_data
->list
[0].EA_flags
= 0;
3353 /* we checked above that name len is less than 255 */
3354 parm_data
->list
[0].name_len
= (__u8
)name_len
;;
3355 /* EA names are always ASCII */
3356 strncpy(parm_data
->list
[0].name
,ea_name
,name_len
);
3357 parm_data
->list
[0].name
[name_len
] = 0;
3358 parm_data
->list
[0].value_len
= cpu_to_le16(ea_value_len
);
3359 /* caller ensures that ea_value_len is less than 64K but
3360 we need to ensure that it fits within the smb */
3362 /*BB add length check that it would fit in negotiated SMB buffer size BB */
3363 /* if(ea_value_len > buffer_size - 512 (enough for header)) */
3365 memcpy(parm_data
->list
[0].name
+name_len
+1,ea_value
,ea_value_len
);
3367 pSMB
->TotalDataCount
= pSMB
->DataCount
;
3368 pSMB
->ParameterCount
= cpu_to_le16(params
);
3369 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
3370 pSMB
->Reserved4
= 0;
3371 pSMB
->hdr
.smb_buf_length
+= byte_count
;
3372 pSMB
->ByteCount
= cpu_to_le16(byte_count
);
3373 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
3374 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
3376 cFYI(1, ("SetPathInfo (EA) returned %d", rc
));
3380 cifs_buf_release(pSMB
);