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;
188 server = ses->server;
193 rc = smb_init(SMB_COM_NEGOTIATE, 0, 0 /* no tcon yet */ ,
194 (void **) &pSMB, (void **) &pSMBr);
198 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
199 if (extended_security)
200 pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC;
202 pSMB->ByteCount = strlen(protocols[0].name) + 1;
203 strncpy(pSMB->DialectsArray, protocols[0].name, 30);
204 /* null guaranteed to be at end of source and target buffers anyway */
206 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
207 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
209 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
210 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
212 server->secMode = pSMBr->SecurityMode;
213 server->secType = NTLM; /* BB override default for NTLMv2 or krb*/
214 /* one byte - no need to convert this or EncryptionKeyLen from le,*/
215 server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount);
216 /* probably no need to store and check maxvcs */
218 min(le32_to_cpu(pSMBr->MaxBufferSize),
219 (__u32) CIFS_MAX_MSGSIZE + MAX_CIFS_HDR_SIZE);
220 server->maxRw = le32_to_cpu(pSMBr->MaxRawSize);
221 cFYI(0, ("Max buf = %d ", ses->server->maxBuf));
222 GETU32(ses->server->sessid) = le32_to_cpu(pSMBr->SessionKey);
223 server->capabilities = le32_to_cpu(pSMBr->Capabilities);
224 server->timeZone = le16_to_cpu(pSMBr->ServerTimeZone);
225 /* BB with UTC do we ever need to be using srvr timezone? */
226 if (pSMBr->EncryptionKeyLength == CIFS_CRYPTO_KEY_SIZE) {
227 memcpy(server->cryptKey, pSMBr->u.EncryptionKey,
228 CIFS_CRYPTO_KEY_SIZE);
229 } else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC)
230 && (pSMBr->EncryptionKeyLength == 0)) {
231 /* decode security blob */
235 /* BB might be helpful to save off the domain of server here */
237 if (pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) {
238 if (pSMBr->ByteCount < 16)
240 else if (pSMBr->ByteCount == 16) {
241 server->secType = RawNTLMSSP;
242 if (server->socketUseCount.counter > 1) {
244 (server->server_GUID,
245 pSMBr->u.extended_response.
248 ("UID of server does not match previous connection to same ip address"));
256 memcpy(server->server_GUID,
257 pSMBr->u.extended_response.
260 rc = decode_negTokenInit(pSMBr->u.
264 16, &server->secType);
267 server->capabilities &= ~CAP_EXTENDED_SECURITY;
268 if(sign_CIFS_PDUs == FALSE) {
269 if(server->secMode & SECMODE_SIGN_REQUIRED)
271 ("Server requires /proc/fs/cifs/PacketSigningEnabled"));
272 server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
273 } else if(sign_CIFS_PDUs == 1) {
274 if((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
275 server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
280 cifs_buf_release(pSMB);
285 CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
287 struct smb_hdr *smb_buffer;
288 struct smb_hdr *smb_buffer_response;
292 cFYI(1, ("In tree disconnect"));
294 * If last user of the connection and
295 * connection alive - disconnect it
296 * If this is the last connection on the server session disconnect it
297 * (and inside session disconnect we should check if tcp socket needs
298 * to be freed and kernel thread woken up).
301 down(&tcon->tconSem);
305 atomic_dec(&tcon->useCount);
306 if (atomic_read(&tcon->useCount) > 0) {
311 /* No need to return error on this operation if tid invalidated and
312 closed on server already e.g. due to tcp session crashing */
313 if(tcon->tidStatus == CifsNeedReconnect) {
318 /* BB remove (from server) list of shares - but with smp safety BB */
319 /* BB is ses active - do we need to check here - but how? BB */
320 if((tcon->ses == 0) || (tcon->ses->server == 0)) {
325 rc = smb_init(SMB_COM_TREE_DISCONNECT, 0, tcon,
326 (void **) &smb_buffer, (void **) &smb_buffer_response);
331 rc = SendReceive(xid, tcon->ses, smb_buffer, smb_buffer_response,
334 cFYI(1, (" Tree disconnect failed %d", rc));
337 cifs_buf_release(smb_buffer);
340 /* No need to return error on this operation if tid invalidated and
341 closed on server already e.g. due to tcp session crashing */
349 CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
351 struct smb_hdr *smb_buffer_response;
352 LOGOFF_ANDX_REQ *pSMB;
356 cFYI(1, ("In SMBLogoff for session disconnect"));
362 atomic_dec(&ses->inUse);
363 if (atomic_read(&ses->inUse) > 0) {
368 rc = smb_init(SMB_COM_LOGOFF_ANDX, 2, 0 /* no tcon anymore */,
369 (void **) &pSMB, (void **) &smb_buffer_response);
371 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
372 pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
379 pSMB->hdr.Uid = ses->Suid;
381 pSMB->AndXCommand = 0xFF;
382 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
383 smb_buffer_response, &length, 0);
385 atomic_dec(&ses->server->socketUseCount);
386 if (atomic_read(&ses->server->socketUseCount) == 0) {
387 spin_lock(&GlobalMid_Lock);
388 ses->server->tcpStatus = CifsExiting;
389 spin_unlock(&GlobalMid_Lock);
393 cifs_buf_release(pSMB);
396 /* if session dead then we do not need to do ulogoff,
397 since server closed smb session, no sense reporting
405 CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
406 const char *fileName, const struct nls_table *nls_codepage)
408 DELETE_FILE_REQ *pSMB = NULL;
409 DELETE_FILE_RSP *pSMBr = NULL;
415 rc = smb_init(SMB_COM_DELETE, 1, tcon, (void **) &pSMB,
420 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
422 cifs_strtoUCS((wchar_t *) pSMB->fileName, fileName, 530
423 /* find define for this maxpathcomponent */
425 name_len++; /* trailing null */
427 } else { /* BB improve the check for buffer overruns BB */
428 name_len = strnlen(fileName, 530);
429 name_len++; /* trailing null */
430 strncpy(pSMB->fileName, fileName, name_len);
432 pSMB->SearchAttributes =
433 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM);
434 pSMB->ByteCount = name_len + 1;
435 pSMB->BufferFormat = 0x04;
436 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
437 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
438 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
439 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
441 cFYI(1, ("Error in RMFile = %d", rc));
443 #ifdef CONFIG_CIFS_STATS
445 atomic_inc(&tcon->num_deletes);
450 cifs_buf_release(pSMB);
458 CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon,
459 const char *dirName, const struct nls_table *nls_codepage)
461 DELETE_DIRECTORY_REQ *pSMB = NULL;
462 DELETE_DIRECTORY_RSP *pSMBr = NULL;
467 cFYI(1, ("In CIFSSMBRmDir"));
469 rc = smb_init(SMB_COM_DELETE_DIRECTORY, 0, tcon, (void **) &pSMB,
474 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
475 name_len = cifs_strtoUCS((wchar_t *) pSMB->DirName, dirName, 530
476 /* find define for this maxpathcomponent */
478 name_len++; /* trailing null */
480 } else { /* BB improve the check for buffer overruns BB */
481 name_len = strnlen(dirName, 530);
482 name_len++; /* trailing null */
483 strncpy(pSMB->DirName, dirName, name_len);
486 pSMB->ByteCount = name_len + 1;
487 pSMB->BufferFormat = 0x04;
488 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
489 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
490 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
491 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
493 cFYI(1, ("Error in RMDir = %d", rc));
495 #ifdef CONFIG_CIFS_STATS
497 atomic_inc(&tcon->num_rmdirs);
502 cifs_buf_release(pSMB);
509 CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
510 const char *name, const struct nls_table *nls_codepage)
513 CREATE_DIRECTORY_REQ *pSMB = NULL;
514 CREATE_DIRECTORY_RSP *pSMBr = NULL;
518 cFYI(1, ("In CIFSSMBMkDir"));
520 rc = smb_init(SMB_COM_CREATE_DIRECTORY, 0, tcon, (void **) &pSMB,
525 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
526 name_len = cifs_strtoUCS((wchar_t *) pSMB->DirName, name, 530
527 /* find define for this maxpathcomponent */
529 name_len++; /* trailing null */
531 } else { /* BB improve the check for buffer overruns BB */
532 name_len = strnlen(name, 530);
533 name_len++; /* trailing null */
534 strncpy(pSMB->DirName, name, name_len);
537 pSMB->ByteCount = name_len + 1 /* for buf format */ ;
538 pSMB->BufferFormat = 0x04;
539 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
540 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
541 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
542 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
544 cFYI(1, ("Error in Mkdir = %d", rc));
546 #ifdef CONFIG_CIFS_STATS
548 atomic_inc(&tcon->num_mkdirs);
552 cifs_buf_release(pSMB);
559 CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
560 const char *fileName, const int openDisposition,
561 const int access_flags, const int create_options, __u16 * netfid,
562 int *pOplock, FILE_ALL_INFO * pfile_info,
563 const struct nls_table *nls_codepage)
566 OPEN_REQ *pSMB = NULL;
567 OPEN_RSP *pSMBr = NULL;
572 rc = smb_init(SMB_COM_NT_CREATE_ANDX, 24, tcon, (void **) &pSMB,
577 pSMB->AndXCommand = 0xFF; /* none */
579 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
580 pSMB->ByteCount = 1; /* account for one byte pad to word boundary */
582 cifs_strtoUCS((wchar_t *) (pSMB->fileName + 1),
584 /* find define for this maxpathcomponent */
586 name_len++; /* trailing null */
588 pSMB->NameLength = cpu_to_le16(name_len);
589 } else { /* BB improve the check for buffer overruns BB */
590 pSMB->ByteCount = 0; /* no pad */
591 name_len = strnlen(fileName, 530);
592 name_len++; /* trailing null */
593 pSMB->NameLength = cpu_to_le16(name_len);
594 strncpy(pSMB->fileName, fileName, name_len);
596 if (*pOplock & REQ_OPLOCK)
597 pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK);
598 else if (*pOplock & REQ_BATCHOPLOCK) {
599 pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK);
601 pSMB->DesiredAccess = cpu_to_le32(access_flags);
602 pSMB->AllocationSize = 0;
603 pSMB->FileAttributes = ATTR_NORMAL;
604 /* XP does not handle ATTR_POSIX_SEMANTICS */
605 /* but it helps speed up case sensitive checks for other
606 servers such as Samba */
607 if (tcon->ses->capabilities & CAP_UNIX)
608 pSMB->FileAttributes |= ATTR_POSIX_SEMANTICS;
610 /* if ((omode & S_IWUGO) == 0)
611 pSMB->FileAttributes |= ATTR_READONLY;*/
612 /* Above line causes problems due to vfs splitting create into two
613 pieces - need to set mode after file created not while it is
615 pSMB->FileAttributes = cpu_to_le32(pSMB->FileAttributes);
616 pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL);
617 pSMB->CreateDisposition = cpu_to_le32(openDisposition);
618 pSMB->CreateOptions = cpu_to_le32(create_options);
619 pSMB->ImpersonationLevel = cpu_to_le32(SECURITY_IMPERSONATION); /* BB ??*/
620 pSMB->SecurityFlags =
621 cpu_to_le32(SECURITY_CONTEXT_TRACKING | SECURITY_EFFECTIVE_ONLY);
623 pSMB->ByteCount += name_len;
624 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
626 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
627 /* long_op set to 1 to allow for oplock break timeouts */
628 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
629 (struct smb_hdr *) pSMBr, &bytes_returned, 1);
631 cFYI(1, ("Error in Open = %d", rc));
633 *pOplock = pSMBr->OplockLevel; /* one byte no need to le_to_cpu */
634 *netfid = pSMBr->Fid; /* cifs fid stays in le */
635 /* Let caller know file was created so we can set the mode. */
636 /* Do we care about the CreateAction in any other cases? */
637 if(cpu_to_le32(FILE_CREATE) == pSMBr->CreateAction)
638 *pOplock |= CIFS_CREATE_ACTION;
640 memcpy((char *)pfile_info,(char *)&pSMBr->CreationTime,
641 36 /* CreationTime to Attributes */);
642 /* the file_info buf is endian converted by caller */
643 pfile_info->AllocationSize = pSMBr->AllocationSize;
644 pfile_info->EndOfFile = pSMBr->EndOfFile;
645 pfile_info->NumberOfLinks = cpu_to_le32(1);
648 #ifdef CONFIG_CIFS_STATS
649 atomic_inc(&tcon->num_opens);
653 cifs_buf_release(pSMB);
659 /* If no buffer passed in, then caller wants to do the copy
660 as in the case of readpages so the SMB buffer must be
661 freed by the caller */
664 CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
665 const int netfid, const unsigned int count,
666 const __u64 lseek, unsigned int *nbytes, char **buf)
669 READ_REQ *pSMB = NULL;
670 READ_RSP *pSMBr = NULL;
671 char *pReadData = NULL;
675 rc = smb_init(SMB_COM_READ_ANDX, 12, tcon, (void **) &pSMB,
680 /* tcon and ses pointer are checked in smb_init */
681 if (tcon->ses->server == NULL)
682 return -ECONNABORTED;
684 pSMB->AndXCommand = 0xFF; /* none */
686 pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
687 pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
689 pSMB->MaxCount = cpu_to_le16(count);
690 pSMB->MaxCountHigh = 0;
691 pSMB->ByteCount = 0; /* no need to do le conversion since it is 0 */
693 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
694 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
696 cERROR(1, ("Send error in read = %d", rc));
698 pSMBr->DataLength = le16_to_cpu(pSMBr->DataLength);
699 *nbytes = pSMBr->DataLength;
700 /*check that DataLength would not go beyond end of SMB */
701 if ((pSMBr->DataLength > CIFS_MAX_MSGSIZE)
702 || (pSMBr->DataLength > count)) {
703 cFYI(1,("bad length %d for count %d",pSMBr->DataLength,count));
708 (char *) (&pSMBr->hdr.Protocol) +
709 le16_to_cpu(pSMBr->DataOffset);
710 /* if(rc = copy_to_user(buf, pReadData, pSMBr->DataLength)) {
711 cERROR(1,("Faulting on read rc = %d",rc));
713 }*/ /* can not use copy_to_user when using page cache*/
715 memcpy(*buf,pReadData,pSMBr->DataLength);
720 cifs_buf_release(pSMB);
725 /* Note: On -EAGAIN error only caller can retry on handle based calls
726 since file handle passed in no longer valid */
731 CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
732 const int netfid, const unsigned int count,
733 const __u64 offset, unsigned int *nbytes, const char *buf,
737 WRITE_REQ *pSMB = NULL;
738 WRITE_RSP *pSMBr = NULL;
741 rc = smb_init(SMB_COM_WRITE_ANDX, 14, tcon, (void **) &pSMB,
745 /* tcon and ses pointer are checked in smb_init */
746 if (tcon->ses->server == NULL)
747 return -ECONNABORTED;
749 pSMB->AndXCommand = 0xFF; /* none */
751 pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
752 pSMB->OffsetHigh = cpu_to_le32(offset >> 32);
754 if (count > ((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00))
755 pSMB->DataLengthLow =
756 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00;
758 pSMB->DataLengthLow = count;
759 pSMB->DataLengthHigh = 0;
761 cpu_to_le16(offsetof(struct smb_com_write_req,Data) - 4);
763 memcpy(pSMB->Data,buf,pSMB->DataLengthLow);
765 pSMB->ByteCount += pSMB->DataLengthLow + 1 /* pad */ ;
766 pSMB->DataLengthLow = cpu_to_le16(pSMB->DataLengthLow);
767 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
768 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
770 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
771 (struct smb_hdr *) pSMBr, &bytes_returned, long_op);
773 cFYI(1, ("Send error in write = %d", rc));
776 *nbytes = le16_to_cpu(pSMBr->Count);
779 cifs_buf_release(pSMB);
781 /* Note: On -EAGAIN error only caller can retry on handle based calls
782 since file handle passed in no longer valid */
788 CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
789 const __u16 smb_file_id, const __u64 len,
790 const __u64 offset, const __u32 numUnlock,
791 const __u32 numLock, const __u8 lockType, const int waitFlag)
794 LOCK_REQ *pSMB = NULL;
795 LOCK_RSP *pSMBr = NULL;
800 cFYI(1, ("In CIFSSMBLock - timeout %d numLock %d",waitFlag,numLock));
801 rc = smb_init(SMB_COM_LOCKING_ANDX, 8, tcon, (void **) &pSMB,
806 if(lockType == LOCKING_ANDX_OPLOCK_RELEASE) {
807 timeout = -1; /* no response expected */
809 } else if (waitFlag == TRUE) {
810 timeout = 3; /* blocking operation, no timeout */
811 pSMB->Timeout = -1; /* blocking - do not time out */
816 pSMB->NumberOfLocks = cpu_to_le32(numLock);
817 pSMB->NumberOfUnlocks = cpu_to_le32(numUnlock);
818 pSMB->LockType = lockType;
819 pSMB->AndXCommand = 0xFF; /* none */
820 pSMB->Fid = smb_file_id; /* netfid stays le */
822 pSMB->Locks[0].Pid = cpu_to_le16(current->tgid);
823 temp = cpu_to_le64(len);
824 pSMB->Locks[0].LengthLow = (__u32)(len & 0xFFFFFFFF);
825 pSMB->Locks[0].LengthHigh = (__u32)(len>>32);
826 temp = cpu_to_le64(offset);
827 pSMB->Locks[0].OffsetLow = (__u32)(offset & 0xFFFFFFFF);
828 pSMB->Locks[0].OffsetHigh = (__u32)(offset>>32);
829 pSMB->ByteCount = sizeof (LOCKING_ANDX_RANGE);
830 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
831 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
833 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
834 (struct smb_hdr *) pSMBr, &bytes_returned, timeout);
837 cFYI(1, ("Send error in Lock = %d", rc));
840 cifs_buf_release(pSMB);
842 /* Note: On -EAGAIN error only caller can retry on handle based calls
843 since file handle passed in no longer valid */
848 CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
851 CLOSE_REQ *pSMB = NULL;
852 CLOSE_RSP *pSMBr = NULL;
854 cFYI(1, ("In CIFSSMBClose"));
856 /* do not retry on dead session on close */
857 rc = smb_init(SMB_COM_CLOSE, 3, tcon, (void **) &pSMB,
864 pSMB->FileID = (__u16) smb_file_id;
865 pSMB->LastWriteTime = 0;
867 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
868 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
871 /* EINTR is expected when user ctl-c to kill app */
872 cERROR(1, ("Send error in Close = %d", rc));
876 cifs_buf_release(pSMB);
878 /* Since session is dead, file will be closed on server already */
886 CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
887 const char *fromName, const char *toName,
888 const struct nls_table *nls_codepage)
891 RENAME_REQ *pSMB = NULL;
892 RENAME_RSP *pSMBr = NULL;
894 int name_len, name_len2;
896 cFYI(1, ("In CIFSSMBRename"));
898 rc = smb_init(SMB_COM_RENAME, 1, tcon, (void **) &pSMB,
903 pSMB->BufferFormat = 0x04;
904 pSMB->SearchAttributes =
905 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
908 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
910 cifs_strtoUCS((wchar_t *) pSMB->OldFileName, fromName, 530
911 /* find define for this maxpathcomponent */
913 name_len++; /* trailing null */
915 pSMB->OldFileName[name_len] = 0x04; /* pad */
916 /* protocol requires ASCII signature byte on Unicode string */
917 pSMB->OldFileName[name_len + 1] = 0x00;
919 cifs_strtoUCS((wchar_t *) & pSMB->
920 OldFileName[name_len + 2], toName, 530,
922 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
923 name_len2 *= 2; /* convert to bytes */
924 } else { /* BB improve the check for buffer overruns BB */
925 name_len = strnlen(fromName, 530);
926 name_len++; /* trailing null */
927 strncpy(pSMB->OldFileName, fromName, name_len);
928 name_len2 = strnlen(toName, 530);
929 name_len2++; /* trailing null */
930 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
931 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
932 name_len2++; /* trailing null */
933 name_len2++; /* signature byte */
936 pSMB->ByteCount = 1 /* 1st signature byte */ + name_len + name_len2;
937 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
938 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
940 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
941 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
943 cFYI(1, ("Send error in rename = %d", rc));
946 cifs_buf_release(pSMB);
954 int CIFSSMBRenameOpenFile(const int xid,struct cifsTconInfo *pTcon,
955 int netfid, char * target_name, const struct nls_table * nls_codepage)
957 struct smb_com_transaction2_sfi_req *pSMB = NULL;
958 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
959 struct set_file_rename * rename_info;
961 char dummy_string[30];
963 int bytes_returned = 0;
966 cFYI(1, ("Rename to File by handle"));
967 rc = smb_init(SMB_COM_TRANSACTION2, 15, pTcon, (void **) &pSMB,
972 pSMB->ParameterCount = 6;
973 pSMB->MaxSetupCount = 0;
978 pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_sfi_req,
980 pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
982 data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset;
983 rename_info = (struct set_file_rename *) data_offset;
984 pSMB->MaxParameterCount = cpu_to_le16(2);
985 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
986 pSMB->SetupCount = 1;
988 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
989 pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount;
990 pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
991 pSMB->TotalParameterCount = pSMB->ParameterCount;
992 pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
993 pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
994 /* construct random name ".cifs_tmp<inodenum><mid>" */
995 rename_info->overwrite = cpu_to_le32(1);
996 rename_info->root_fid = 0;
997 /* unicode only call */
998 if(target_name == NULL) {
999 sprintf(dummy_string,"cifs%x",pSMB->hdr.Mid);
1000 len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, dummy_string, 24, nls_codepage);
1002 len_of_str = cifs_strtoUCS((wchar_t *) rename_info->target_name, target_name, 530, nls_codepage);
1004 rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
1005 pSMB->DataCount = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str) + 2;
1006 pSMB->ByteCount += pSMB->DataCount;
1007 pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
1008 pSMB->TotalDataCount = pSMB->DataCount;
1010 pSMB->InformationLevel =
1011 cpu_to_le16(SMB_SET_FILE_RENAME_INFORMATION);
1012 pSMB->Reserved4 = 0;
1013 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
1014 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
1015 rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
1016 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1018 cFYI(1,("Send error in Rename (by file handle) = %d", rc));
1022 cifs_buf_release(pSMB);
1024 /* Note: On -EAGAIN error only caller can retry on handle based calls
1025 since file handle passed in no longer valid */
1031 CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char * fromName,
1032 const __u16 target_tid, const char *toName, const int flags,
1033 const struct nls_table *nls_codepage)
1036 COPY_REQ *pSMB = NULL;
1037 COPY_RSP *pSMBr = NULL;
1039 int name_len, name_len2;
1041 cFYI(1, ("In CIFSSMBCopy"));
1043 rc = smb_init(SMB_COM_COPY, 1, tcon, (void **) &pSMB,
1048 pSMB->BufferFormat = 0x04;
1049 pSMB->Tid2 = target_tid;
1051 if(flags & COPY_TREE)
1052 pSMB->Flags |= COPY_TREE;
1053 pSMB->Flags = cpu_to_le16(pSMB->Flags);
1055 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1056 name_len = cifs_strtoUCS((wchar_t *) pSMB->OldFileName,
1058 530 /* find define for this maxpathcomponent */,
1060 name_len++; /* trailing null */
1062 pSMB->OldFileName[name_len] = 0x04; /* pad */
1063 /* protocol requires ASCII signature byte on Unicode string */
1064 pSMB->OldFileName[name_len + 1] = 0x00;
1065 name_len2 = cifs_strtoUCS((wchar_t *) & pSMB->
1066 OldFileName[name_len + 2], toName, 530,
1068 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
1069 name_len2 *= 2; /* convert to bytes */
1070 } else { /* BB improve the check for buffer overruns BB */
1071 name_len = strnlen(fromName, 530);
1072 name_len++; /* trailing null */
1073 strncpy(pSMB->OldFileName, fromName, name_len);
1074 name_len2 = strnlen(toName, 530);
1075 name_len2++; /* trailing null */
1076 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
1077 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
1078 name_len2++; /* trailing null */
1079 name_len2++; /* signature byte */
1082 pSMB->ByteCount = 1 /* 1st signature byte */ + name_len + name_len2;
1083 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
1084 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
1086 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1087 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1089 cFYI(1, ("Send error in copy = %d with %d files copied",
1090 rc, pSMBr->CopyCount));
1093 cifs_buf_release(pSMB);
1102 CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
1103 const char *fromName, const char *toName,
1104 const struct nls_table *nls_codepage)
1106 TRANSACTION2_SPI_REQ *pSMB = NULL;
1107 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1110 int name_len_target;
1112 int bytes_returned = 0;
1114 cFYI(1, ("In Symlink Unix style"));
1116 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1121 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1123 cifs_strtoUCS((wchar_t *) pSMB->FileName, fromName, 530
1124 /* find define for this maxpathcomponent */
1126 name_len++; /* trailing null */
1129 } else { /* BB improve the check for buffer overruns BB */
1130 name_len = strnlen(fromName, 530);
1131 name_len++; /* trailing null */
1132 strncpy(pSMB->FileName, fromName, name_len);
1134 pSMB->ParameterCount = 6 + name_len;
1135 pSMB->MaxSetupCount = 0;
1139 pSMB->Reserved2 = 0;
1140 pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_spi_req,
1141 InformationLevel) - 4;
1142 pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
1144 data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset;
1145 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1147 cifs_strtoUCS((wchar_t *) data_offset, toName, 530
1148 /* find define for this maxpathcomponent */
1150 name_len_target++; /* trailing null */
1151 name_len_target *= 2;
1152 } else { /* BB improve the check for buffer overruns BB */
1153 name_len_target = strnlen(toName, 530);
1154 name_len_target++; /* trailing null */
1155 strncpy(data_offset, toName, name_len_target);
1158 pSMB->DataCount = name_len_target;
1159 pSMB->MaxParameterCount = cpu_to_le16(2);
1160 /* BB find exact max on data count below from sess */
1161 pSMB->MaxDataCount = cpu_to_le16(1000);
1162 pSMB->SetupCount = 1;
1163 pSMB->Reserved3 = 0;
1164 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1165 pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount + pSMB->DataCount;
1166 pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
1167 pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
1168 pSMB->TotalDataCount = pSMB->DataCount;
1169 pSMB->TotalParameterCount = pSMB->ParameterCount;
1170 pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
1171 pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
1172 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_LINK);
1173 pSMB->Reserved4 = 0;
1174 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
1175 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
1176 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1177 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1180 ("Send error in SetPathInfo (create symlink) = %d",
1185 cifs_buf_release(pSMB);
1188 goto createSymLinkRetry;
1194 CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon,
1195 const char *fromName, const char *toName,
1196 const struct nls_table *nls_codepage)
1198 TRANSACTION2_SPI_REQ *pSMB = NULL;
1199 TRANSACTION2_SPI_RSP *pSMBr = NULL;
1202 int name_len_target;
1204 int bytes_returned = 0;
1206 cFYI(1, ("In Create Hard link Unix style"));
1207 createHardLinkRetry:
1208 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1213 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1214 name_len = cifs_strtoUCS((wchar_t *) pSMB->FileName, toName, 530
1215 /* find define for this maxpathcomponent */
1217 name_len++; /* trailing null */
1220 } else { /* BB improve the check for buffer overruns BB */
1221 name_len = strnlen(toName, 530);
1222 name_len++; /* trailing null */
1223 strncpy(pSMB->FileName, toName, name_len);
1225 pSMB->ParameterCount = 6 + name_len;
1226 pSMB->MaxSetupCount = 0;
1230 pSMB->Reserved2 = 0;
1231 pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_spi_req,
1232 InformationLevel) - 4;
1233 pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
1235 data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset;
1236 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1238 cifs_strtoUCS((wchar_t *) data_offset, fromName, 530
1239 /* find define for this maxpathcomponent */
1241 name_len_target++; /* trailing null */
1242 name_len_target *= 2;
1243 } else { /* BB improve the check for buffer overruns BB */
1244 name_len_target = strnlen(fromName, 530);
1245 name_len_target++; /* trailing null */
1246 strncpy(data_offset, fromName, name_len_target);
1249 pSMB->DataCount = name_len_target;
1250 pSMB->MaxParameterCount = cpu_to_le16(2);
1251 /* BB find exact max on data count below from sess*/
1252 pSMB->MaxDataCount = cpu_to_le16(1000);
1253 pSMB->SetupCount = 1;
1254 pSMB->Reserved3 = 0;
1255 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
1256 pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount + pSMB->DataCount;
1257 pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
1258 pSMB->TotalParameterCount = pSMB->ParameterCount;
1259 pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
1260 pSMB->TotalDataCount = pSMB->DataCount;
1261 pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
1262 pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
1263 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_HLINK);
1264 pSMB->Reserved4 = 0;
1265 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
1266 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
1267 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1268 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1270 cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc));
1274 cifs_buf_release(pSMB);
1276 goto createHardLinkRetry;
1282 CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon,
1283 const char *fromName, const char *toName,
1284 const struct nls_table *nls_codepage)
1287 NT_RENAME_REQ *pSMB = NULL;
1288 RENAME_RSP *pSMBr = NULL;
1290 int name_len, name_len2;
1292 cFYI(1, ("In CIFSCreateHardLink"));
1293 winCreateHardLinkRetry:
1295 rc = smb_init(SMB_COM_NT_RENAME, 4, tcon, (void **) &pSMB,
1300 pSMB->SearchAttributes =
1301 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
1303 pSMB->Flags = cpu_to_le16(CREATE_HARD_LINK);
1304 pSMB->ClusterCount = 0;
1306 pSMB->BufferFormat = 0x04;
1308 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1310 cifs_strtoUCS((wchar_t *) pSMB->OldFileName, fromName, 530
1311 /* find define for this maxpathcomponent */
1313 name_len++; /* trailing null */
1315 pSMB->OldFileName[name_len] = 0; /* pad */
1316 pSMB->OldFileName[name_len + 1] = 0x04;
1318 cifs_strtoUCS((wchar_t *) & pSMB->
1319 OldFileName[name_len + 2], toName, 530,
1321 name_len2 += 1 /* trailing null */ + 1 /* Signature word */ ;
1322 name_len2 *= 2; /* convert to bytes */
1323 } else { /* BB improve the check for buffer overruns BB */
1324 name_len = strnlen(fromName, 530);
1325 name_len++; /* trailing null */
1326 strncpy(pSMB->OldFileName, fromName, name_len);
1327 name_len2 = strnlen(toName, 530);
1328 name_len2++; /* trailing null */
1329 pSMB->OldFileName[name_len] = 0x04; /* 2nd buffer format */
1330 strncpy(&pSMB->OldFileName[name_len + 1], toName, name_len2);
1331 name_len2++; /* trailing null */
1332 name_len2++; /* signature byte */
1335 pSMB->ByteCount = 1 /* string type byte */ + name_len + name_len2;
1336 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
1337 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
1339 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1340 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1342 cFYI(1, ("Send error in hard link (NT rename) = %d", rc));
1345 cifs_buf_release(pSMB);
1347 goto winCreateHardLinkRetry;
1353 CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
1354 const unsigned char *searchName,
1355 char *symlinkinfo, const int buflen,
1356 const struct nls_table *nls_codepage)
1358 /* SMB_QUERY_FILE_UNIX_LINK */
1359 TRANSACTION2_QPI_REQ *pSMB = NULL;
1360 TRANSACTION2_QPI_RSP *pSMBr = NULL;
1365 cFYI(1, ("In QPathSymLinkInfo (Unix) for path %s", searchName));
1368 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1373 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1375 cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
1376 /* find define for this maxpathcomponent */
1378 name_len++; /* trailing null */
1380 } else { /* BB improve the check for buffer overruns BB */
1381 name_len = strnlen(searchName, 530);
1382 name_len++; /* trailing null */
1383 strncpy(pSMB->FileName, searchName, name_len);
1386 pSMB->TotalParameterCount =
1387 2 /* level */ + 4 /* rsrvd */ + name_len /* incl null */ ;
1388 pSMB->TotalDataCount = 0;
1389 pSMB->MaxParameterCount = cpu_to_le16(2);
1390 /* BB find exact max data count below from sess structure BB */
1391 pSMB->MaxDataCount = cpu_to_le16(4000);
1392 pSMB->MaxSetupCount = 0;
1396 pSMB->Reserved2 = 0;
1397 pSMB->ParameterOffset = cpu_to_le16(offsetof(
1398 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4);
1399 pSMB->DataCount = 0;
1400 pSMB->DataOffset = 0;
1401 pSMB->SetupCount = 1;
1402 pSMB->Reserved3 = 0;
1403 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
1404 pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
1405 pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
1406 pSMB->ParameterCount = pSMB->TotalParameterCount;
1407 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK);
1408 pSMB->Reserved4 = 0;
1409 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
1410 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
1412 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1413 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1415 cFYI(1, ("Send error in QuerySymLinkInfo = %d", rc));
1416 } else { /* decode response */
1417 pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
1418 pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount);
1419 if ((pSMBr->ByteCount < 2) || (pSMBr->DataOffset > 512))
1420 /* BB also check enough total bytes returned */
1421 rc = -EIO; /* bad smb */
1423 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
1424 name_len = UniStrnlen((wchar_t *) ((char *)
1425 &pSMBr->hdr.Protocol +pSMBr->DataOffset),
1426 min_t(const int, buflen,pSMBr->DataCount) / 2);
1427 cifs_strfromUCS_le(symlinkinfo,
1428 (wchar_t *) ((char *)&pSMBr->hdr.Protocol +
1430 name_len, nls_codepage);
1432 strncpy(symlinkinfo,
1433 (char *) &pSMBr->hdr.Protocol +
1435 min_t(const int, buflen, pSMBr->DataCount));
1437 symlinkinfo[buflen] = 0;
1438 /* just in case so calling code does not go off the end of buffer */
1442 cifs_buf_release(pSMB);
1444 goto querySymLinkRetry;
1451 CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
1452 const unsigned char *searchName,
1453 char *symlinkinfo, const int buflen,__u16 fid,
1454 const struct nls_table *nls_codepage)
1459 struct smb_com_transaction_ioctl_req * pSMB;
1460 struct smb_com_transaction_ioctl_rsp * pSMBr;
1462 cFYI(1, ("In Windows reparse style QueryLink for path %s", searchName));
1463 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
1468 pSMB->TotalParameterCount = 0 ;
1469 pSMB->TotalDataCount = 0;
1470 pSMB->MaxParameterCount = cpu_to_le32(2);
1471 /* BB find exact data count max from sess structure BB */
1472 pSMB->MaxDataCount = cpu_to_le32(4000);
1473 pSMB->MaxSetupCount = 4;
1475 pSMB->ParameterOffset = 0;
1476 pSMB->DataCount = 0;
1477 pSMB->DataOffset = 0;
1478 pSMB->SetupCount = 4;
1479 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_IOCTL);
1480 pSMB->ParameterCount = pSMB->TotalParameterCount;
1481 pSMB->FunctionCode = cpu_to_le32(FSCTL_GET_REPARSE_POINT);
1482 pSMB->IsFsctl = 1; /* FSCTL */
1483 pSMB->IsRootFlag = 0;
1484 pSMB->Fid = fid; /* file handle always le */
1485 pSMB->ByteCount = 0;
1487 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1488 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1490 cFYI(1, ("Send error in QueryReparseLinkInfo = %d", rc));
1491 } else { /* decode response */
1492 pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
1493 pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount);
1494 if ((pSMBr->ByteCount < 2) || (pSMBr->DataOffset > 512))
1495 /* BB also check enough total bytes returned */
1496 rc = -EIO; /* bad smb */
1498 if(pSMBr->DataCount && (pSMBr->DataCount < 2048)) {
1499 /* could also validate reparse tag && better check name length */
1500 struct reparse_data * reparse_buf = (struct reparse_data *)
1501 ((char *)&pSMBr->hdr.Protocol + pSMBr->DataOffset);
1502 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
1503 name_len = UniStrnlen((wchar_t *)
1504 (reparse_buf->LinkNamesBuf +
1505 reparse_buf->TargetNameOffset),
1506 min(buflen/2, reparse_buf->TargetNameLen / 2));
1507 cifs_strfromUCS_le(symlinkinfo,
1508 (wchar_t *) (reparse_buf->LinkNamesBuf +
1509 reparse_buf->TargetNameOffset),
1510 name_len, nls_codepage);
1511 } else { /* ASCII names */
1512 strncpy(symlinkinfo,reparse_buf->LinkNamesBuf +
1513 reparse_buf->TargetNameOffset,
1514 min_t(const int, buflen, reparse_buf->TargetNameLen));
1518 cFYI(1,("Invalid return data count on get reparse info ioctl"));
1520 symlinkinfo[buflen] = 0; /* just in case so the caller
1521 does not go off the end of the buffer */
1522 cFYI(1,("readlink result - %s ",symlinkinfo));
1526 cifs_buf_release(pSMB);
1528 /* Note: On -EAGAIN error only caller can retry on handle based calls
1529 since file handle passed in no longer valid */
1535 CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
1536 const unsigned char *searchName,
1537 FILE_ALL_INFO * pFindData,
1538 const struct nls_table *nls_codepage)
1540 /* level 263 SMB_QUERY_FILE_ALL_INFO */
1541 TRANSACTION2_QPI_REQ *pSMB = NULL;
1542 TRANSACTION2_QPI_RSP *pSMBr = NULL;
1547 cFYI(1, ("In QPathInfo path %s", searchName));
1549 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1554 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1556 cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
1557 /* find define for this maxpathcomponent */
1559 name_len++; /* trailing null */
1561 } else { /* BB improve the check for buffer overruns BB */
1562 name_len = strnlen(searchName, 530);
1563 name_len++; /* trailing null */
1564 strncpy(pSMB->FileName, searchName, name_len);
1567 pSMB->TotalParameterCount = 2 /* level */ + 4 /* reserved */ +
1568 name_len /* includes null */ ;
1569 pSMB->TotalDataCount = 0;
1570 pSMB->MaxParameterCount = cpu_to_le16(2);
1571 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
1572 pSMB->MaxSetupCount = 0;
1576 pSMB->Reserved2 = 0;
1577 pSMB->ParameterOffset = cpu_to_le16(offsetof(
1578 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4);
1579 pSMB->DataCount = 0;
1580 pSMB->DataOffset = 0;
1581 pSMB->SetupCount = 1;
1582 pSMB->Reserved3 = 0;
1583 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
1584 pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
1585 pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
1586 pSMB->ParameterCount = pSMB->TotalParameterCount;
1587 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
1588 pSMB->Reserved4 = 0;
1589 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
1590 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
1592 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1593 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1595 cFYI(1, ("Send error in QPathInfo = %d", rc));
1596 } else { /* decode response */
1597 pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
1598 /* BB also check enough total bytes returned */
1599 /* BB we need to improve the validity checking
1600 of these trans2 responses */
1601 if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512))
1602 rc = -EIO; /* bad smb */
1603 else if (pFindData){
1604 memcpy((char *) pFindData,
1605 (char *) &pSMBr->hdr.Protocol +
1606 pSMBr->DataOffset, sizeof (FILE_ALL_INFO));
1611 cifs_buf_release(pSMB);
1613 goto QPathInfoRetry;
1619 CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
1620 const unsigned char *searchName,
1621 FILE_UNIX_BASIC_INFO * pFindData,
1622 const struct nls_table *nls_codepage)
1624 /* SMB_QUERY_FILE_UNIX_BASIC */
1625 TRANSACTION2_QPI_REQ *pSMB = NULL;
1626 TRANSACTION2_QPI_RSP *pSMBr = NULL;
1628 int bytes_returned = 0;
1631 cFYI(1, ("In QPathInfo (Unix) the path %s", searchName));
1633 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1638 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1640 cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
1641 /* find define for this maxpathcomponent */
1643 name_len++; /* trailing null */
1645 } else { /* BB improve the check for buffer overruns BB */
1646 name_len = strnlen(searchName, 530);
1647 name_len++; /* trailing null */
1648 strncpy(pSMB->FileName, searchName, name_len);
1651 pSMB->TotalParameterCount = 2 /* level */ + 4 /* reserved */ +
1652 name_len /* includes null */ ;
1653 pSMB->TotalDataCount = 0;
1654 pSMB->MaxParameterCount = cpu_to_le16(2);
1655 /* BB find exact max SMB PDU from sess structure BB */
1656 pSMB->MaxDataCount = cpu_to_le16(4000);
1657 pSMB->MaxSetupCount = 0;
1661 pSMB->Reserved2 = 0;
1662 pSMB->ParameterOffset = cpu_to_le16(offsetof(
1663 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4);
1664 pSMB->DataCount = 0;
1665 pSMB->DataOffset = 0;
1666 pSMB->SetupCount = 1;
1667 pSMB->Reserved3 = 0;
1668 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
1669 pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
1670 pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
1671 pSMB->ParameterCount = pSMB->TotalParameterCount;
1672 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC);
1673 pSMB->Reserved4 = 0;
1674 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
1675 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
1677 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1678 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1680 cFYI(1, ("Send error in QPathInfo = %d", rc));
1681 } else { /* decode response */
1682 pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
1683 /* BB also check if enough total bytes returned */
1684 if ((pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO)) ||
1685 (pSMBr->DataOffset > 512) ||
1686 (pSMBr->DataOffset < sizeof(struct smb_hdr))) {
1687 cFYI(1,("UnixQPathinfo invalid data offset %d bytes returned %d",
1688 (int)pSMBr->DataOffset,bytes_returned));
1689 rc = -EIO; /* bad smb */
1691 memcpy((char *) pFindData,
1692 (char *) &pSMBr->hdr.Protocol +
1694 sizeof (FILE_UNIX_BASIC_INFO));
1698 cifs_buf_release(pSMB);
1700 goto UnixQPathInfoRetry;
1706 CIFSFindSingle(const int xid, struct cifsTconInfo *tcon,
1707 const char *searchName, FILE_ALL_INFO * findData,
1708 const struct nls_table *nls_codepage)
1710 /* level 257 SMB_ */
1711 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
1712 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
1717 cFYI(1, ("In FindUnique"));
1719 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1724 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1726 cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
1727 /* find define for this maxpathcomponent */
1729 name_len++; /* trailing null */
1731 } else { /* BB improve the check for buffer overruns BB */
1732 name_len = strnlen(searchName, 530);
1733 name_len++; /* trailing null */
1734 strncpy(pSMB->FileName, searchName, name_len);
1737 pSMB->TotalParameterCount = 12 + name_len /* includes null */ ;
1738 pSMB->TotalDataCount = 0; /* no EAs */
1739 pSMB->MaxParameterCount = cpu_to_le16(2);
1740 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
1741 pSMB->MaxSetupCount = 0;
1745 pSMB->Reserved2 = 0;
1746 pSMB->ParameterOffset = cpu_to_le16(
1747 offsetof(struct smb_com_transaction2_ffirst_req,InformationLevel) - 4);
1748 pSMB->DataCount = 0;
1749 pSMB->DataOffset = 0;
1750 pSMB->SetupCount = 1; /* one byte, no need to le convert */
1751 pSMB->Reserved3 = 0;
1752 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
1753 pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
1754 pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalDataCount);
1755 pSMB->ParameterCount = pSMB->TotalParameterCount;
1756 pSMB->SearchAttributes =
1757 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
1759 pSMB->SearchCount = cpu_to_le16(16); /* BB increase */
1760 pSMB->SearchFlags = cpu_to_le16(1);
1761 pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
1762 pSMB->SearchStorageType = 0; /* BB what should we set this to? BB */
1763 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
1764 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
1766 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1767 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1770 cFYI(1, ("Send error in FindFileDirInfo = %d", rc));
1771 } else { /* decode response */
1776 cifs_buf_release(pSMB);
1778 goto findUniqueRetry;
1784 CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
1785 const char *searchName, FILE_DIRECTORY_INFO * findData,
1786 T2_FFIRST_RSP_PARMS * findParms,
1787 const struct nls_table *nls_codepage, int *pUnicodeFlag,
1790 /* level 257 SMB_ */
1791 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
1792 TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
1793 char *response_data;
1798 cFYI(1, ("In FindFirst"));
1800 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1805 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
1807 cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
1808 /* find define for this maxpathcomponent */
1810 name_len++; /* trailing null */
1812 } else { /* BB improve the check for buffer overruns BB */
1813 name_len = strnlen(searchName, 530);
1814 name_len++; /* trailing null */
1815 strncpy(pSMB->FileName, searchName, name_len);
1818 pSMB->TotalParameterCount = 12 + name_len /* includes null */ ;
1819 pSMB->TotalDataCount = 0; /* no EAs */
1820 pSMB->MaxParameterCount = cpu_to_le16(10);
1821 pSMB->MaxDataCount = cpu_to_le16((tcon->ses->server->maxBuf -
1822 MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
1823 pSMB->MaxSetupCount = 0;
1827 pSMB->Reserved2 = 0;
1828 pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
1829 pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
1830 pSMB->ParameterCount = pSMB->TotalParameterCount;
1831 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
1832 smb_com_transaction2_ffirst_req, SearchAttributes) - 4);
1833 pSMB->DataCount = 0;
1834 pSMB->DataOffset = 0;
1835 pSMB->SetupCount = 1; /* one byte no need to make endian neutral */
1836 pSMB->Reserved3 = 0;
1837 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_FIRST);
1838 pSMB->SearchAttributes =
1839 cpu_to_le16(ATTR_READONLY | ATTR_HIDDEN | ATTR_SYSTEM |
1841 pSMB->SearchCount = cpu_to_le16(CIFS_MAX_MSGSIZE / sizeof (FILE_DIRECTORY_INFO)); /* should this be shrunk even more ? */
1842 pSMB->SearchFlags = cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
1844 /* test for Unix extensions */
1845 if (tcon->ses->capabilities & CAP_UNIX) {
1846 pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);
1849 pSMB->InformationLevel =
1850 cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
1853 pSMB->SearchStorageType = 0; /* BB what should we set this to? It is not clear if it matters BB */
1854 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
1855 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
1857 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1858 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1860 if (rc) { /* BB add logic to retry regular search if Unix search rejected unexpectedly by server */
1861 cFYI(1, ("Error in FindFirst = %d", rc));
1862 } else { /* decode response */
1863 /* BB add safety checks for these memcpys */
1864 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
1865 *pUnicodeFlag = TRUE;
1867 *pUnicodeFlag = FALSE;
1869 (char *) &pSMBr->hdr.Protocol +
1870 le16_to_cpu(pSMBr->ParameterOffset),
1871 sizeof (T2_FFIRST_RSP_PARMS));
1872 /* search handle can stay LE and EAoffset not needed so not converted */
1873 findParms->EndofSearch = le16_to_cpu(findParms->EndofSearch);
1874 findParms->LastNameOffset =
1875 le16_to_cpu(findParms->LastNameOffset);
1876 findParms->SearchCount = le16_to_cpu(findParms->SearchCount);
1878 (char *) &pSMBr->hdr.Protocol +
1879 le16_to_cpu(pSMBr->DataOffset);
1880 memcpy(findData, response_data, le16_to_cpu(pSMBr->DataCount));
1883 cifs_buf_release(pSMB);
1886 goto findFirstRetry;
1892 CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
1893 FILE_DIRECTORY_INFO * findData, T2_FNEXT_RSP_PARMS * findParms,
1894 const __u16 searchHandle, char * resume_file_name, int name_len,
1895 __u32 resume_key, int *pUnicodeFlag, int *pUnixFlag)
1897 /* level 257 SMB_ */
1898 TRANSACTION2_FNEXT_REQ *pSMB = NULL;
1899 TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
1900 char *response_data;
1904 cFYI(1, ("In FindNext"));
1906 if(resume_file_name == NULL) {
1909 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
1914 pSMB->TotalParameterCount = 14; /* includes 2 bytes of null string, converted to LE below */
1915 pSMB->TotalDataCount = 0; /* no EAs */
1916 pSMB->MaxParameterCount = cpu_to_le16(8);
1917 pSMB->MaxDataCount =
1918 cpu_to_le16((tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
1919 pSMB->MaxSetupCount = 0;
1923 pSMB->Reserved2 = 0;
1924 pSMB->ParameterOffset = cpu_to_le16(offsetof(
1925 struct smb_com_transaction2_fnext_req,SearchHandle) - 4);
1926 pSMB->DataCount = 0;
1927 pSMB->DataOffset = 0;
1928 pSMB->SetupCount = 1;
1929 pSMB->Reserved3 = 0;
1930 pSMB->SubCommand = cpu_to_le16(TRANS2_FIND_NEXT);
1931 pSMB->SearchHandle = searchHandle; /* always kept as le */
1932 findParms->SearchCount = 0; /* set to zero in case of error */
1934 cpu_to_le16(CIFS_MAX_MSGSIZE / sizeof (FILE_DIRECTORY_INFO));
1935 /* test for Unix extensions */
1936 if (tcon->ses->capabilities & CAP_UNIX) {
1937 pSMB->InformationLevel = cpu_to_le16(SMB_FIND_FILE_UNIX);
1940 pSMB->InformationLevel =
1941 cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO);
1944 pSMB->ResumeKey = resume_key;
1946 cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END | CIFS_SEARCH_RETURN_RESUME);
1947 /* BB add check to make sure we do not cross end of smb */
1948 if(name_len < CIFS_MAX_MSGSIZE) {
1949 memcpy(pSMB->ResumeFileName, resume_file_name, name_len);
1950 pSMB->ByteCount += name_len;
1952 pSMB->TotalParameterCount += name_len;
1953 pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
1954 pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
1955 pSMB->ParameterCount = pSMB->TotalParameterCount;
1956 /* BB improve error handling here */
1957 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
1958 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
1960 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1961 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1965 rc = 0; /* search probably was closed at end of search above */
1967 cFYI(1, ("FindNext returned = %d", rc));
1968 } else { /* decode response */
1969 /* BB add safety checks for these memcpys */
1970 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
1971 *pUnicodeFlag = TRUE;
1973 *pUnicodeFlag = FALSE;
1975 (char *) &pSMBr->hdr.Protocol +
1976 le16_to_cpu(pSMBr->ParameterOffset),
1977 sizeof (T2_FNEXT_RSP_PARMS));
1978 findParms->EndofSearch = le16_to_cpu(findParms->EndofSearch);
1979 findParms->LastNameOffset =
1980 le16_to_cpu(findParms->LastNameOffset);
1981 findParms->SearchCount = le16_to_cpu(findParms->SearchCount);
1983 (char *) &pSMBr->hdr.Protocol +
1984 le16_to_cpu(pSMBr->DataOffset);
1985 memcpy(findData, response_data, le16_to_cpu(pSMBr->DataCount));
1988 cifs_buf_release(pSMB);
1990 /* Note: On -EAGAIN error only caller can retry on handle based calls
1991 since file handle passed in no longer valid */
1997 CIFSFindClose(const int xid, struct cifsTconInfo *tcon, const __u16 searchHandle)
2000 FINDCLOSE_REQ *pSMB = NULL;
2001 CLOSE_RSP *pSMBr = NULL;
2004 cFYI(1, ("In CIFSSMBFindClose"));
2005 rc = smb_init(SMB_COM_FIND_CLOSE2, 1, tcon, (void **) &pSMB,
2007 /* no sense returning error if session restarted
2008 file handle has been closed */
2014 pSMB->FileID = searchHandle;
2015 pSMB->ByteCount = 0;
2016 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2017 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2019 cERROR(1, ("Send error in FindClose = %d", rc));
2022 cifs_buf_release(pSMB);
2024 /* Since session is dead, search handle closed on server already */
2032 CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
2033 const unsigned char *searchName,
2034 unsigned char **targetUNCs,
2035 unsigned int *number_of_UNC_in_array,
2036 const struct nls_table *nls_codepage)
2038 /* TRANS2_GET_DFS_REFERRAL */
2039 TRANSACTION2_GET_DFS_REFER_REQ *pSMB = NULL;
2040 TRANSACTION2_GET_DFS_REFER_RSP *pSMBr = NULL;
2041 struct dfs_referral_level_3 * referrals = NULL;
2047 *number_of_UNC_in_array = 0;
2050 cFYI(1, ("In GetDFSRefer the path %s", searchName));
2054 rc = smb_init(SMB_COM_TRANSACTION2, 15, 0, (void **) &pSMB,
2059 pSMB->hdr.Tid = ses->ipc_tid;
2060 pSMB->hdr.Uid = ses->Suid;
2061 if (ses->capabilities & CAP_STATUS32) {
2062 pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS;
2064 if (ses->capabilities & CAP_DFS) {
2065 pSMB->hdr.Flags2 |= SMBFLG2_DFS;
2068 if (ses->capabilities & CAP_UNICODE) {
2069 pSMB->hdr.Flags2 |= SMBFLG2_UNICODE;
2071 cifs_strtoUCS((wchar_t *) pSMB->RequestFileName,
2073 /* find define for this maxpathcomponent */
2075 name_len++; /* trailing null */
2077 } else { /* BB improve the check for buffer overruns BB */
2078 name_len = strnlen(searchName, 530);
2079 name_len++; /* trailing null */
2080 strncpy(pSMB->RequestFileName, searchName, name_len);
2083 pSMB->ParameterCount = 2 /* level */ + name_len /*includes null */ ;
2084 pSMB->TotalDataCount = 0;
2085 pSMB->DataCount = 0;
2086 pSMB->DataOffset = 0;
2087 pSMB->MaxParameterCount = 0;
2088 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
2089 pSMB->MaxSetupCount = 0;
2093 pSMB->Reserved2 = 0;
2094 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2095 struct smb_com_transaction2_get_dfs_refer_req, MaxReferralLevel) - 4);
2096 pSMB->SetupCount = 1;
2097 pSMB->Reserved3 = 0;
2098 pSMB->SubCommand = cpu_to_le16(TRANS2_GET_DFS_REFERRAL);
2099 pSMB->ByteCount = pSMB->ParameterCount + 3 /* pad */ ;
2100 pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
2101 pSMB->TotalParameterCount = pSMB->ParameterCount;
2102 pSMB->MaxReferralLevel = cpu_to_le16(3);
2103 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
2104 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
2106 rc = SendReceive(xid, ses, (struct smb_hdr *) pSMB,
2107 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2109 cFYI(1, ("Send error in GetDFSRefer = %d", rc));
2110 } else { /* decode response */
2111 /* BB Add logic to parse referrals here */
2112 pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
2113 pSMBr->DataCount = le16_to_cpu(pSMBr->DataCount);
2115 ("Decoding GetDFSRefer response. BCC: %d Offset %d",
2116 pSMBr->ByteCount, pSMBr->DataOffset));
2117 if ((pSMBr->ByteCount < 17) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */
2118 rc = -EIO; /* bad smb */
2121 (struct dfs_referral_level_3 *)
2122 (8 /* sizeof start of data block */ +
2124 (char *) &pSMBr->hdr.Protocol);
2125 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",pSMBr->NumberOfReferrals,pSMBr->DFSFlags, referrals->ReferralSize,referrals->ServerType,referrals->ReferralFlags,referrals->TimeToLive));
2126 /* BB This field is actually two bytes in from start of
2127 data block so we could do safety check that DataBlock
2128 begins at address of pSMBr->NumberOfReferrals */
2129 *number_of_UNC_in_array = le16_to_cpu(pSMBr->NumberOfReferrals);
2131 /* BB Fix below so can return more than one referral */
2132 if(*number_of_UNC_in_array > 1)
2133 *number_of_UNC_in_array = 1;
2135 /* get the length of the strings describing refs */
2137 for(i=0;i<*number_of_UNC_in_array;i++) {
2138 /* make sure that DfsPathOffset not past end */
2139 referrals->DfsPathOffset = le16_to_cpu(referrals->DfsPathOffset);
2140 if(referrals->DfsPathOffset > pSMBr->DataCount) {
2141 /* if invalid referral, stop here and do
2142 not try to copy any more */
2143 *number_of_UNC_in_array = i;
2146 temp = ((char *)referrals) + referrals->DfsPathOffset;
2148 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
2149 name_len += UniStrnlen((wchar_t *)temp,pSMBr->DataCount);
2151 name_len += strnlen(temp,pSMBr->DataCount);
2154 /* BB add check that referral pointer does not fall off end PDU */
2157 /* BB add check for name_len bigger than bcc */
2159 kmalloc(name_len+1+ (*number_of_UNC_in_array),GFP_KERNEL);
2160 /* copy the ref strings */
2162 (struct dfs_referral_level_3 *)
2163 (8 /* sizeof data hdr */ +
2165 (char *) &pSMBr->hdr.Protocol);
2167 for(i=0;i<*number_of_UNC_in_array;i++) {
2168 temp = ((char *)referrals) + referrals->DfsPathOffset;
2169 if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE) {
2170 cifs_strfromUCS_le(*targetUNCs,
2171 (wchar_t *) temp, name_len, nls_codepage);
2173 strncpy(*targetUNCs,temp,name_len);
2175 /* BB update target_uncs pointers */
2184 cifs_buf_release(pSMB);
2193 CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
2194 struct kstatfs *FSData, const struct nls_table *nls_codepage)
2196 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
2197 TRANSACTION2_QFSI_REQ *pSMB = NULL;
2198 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
2199 FILE_SYSTEM_INFO *response_data;
2201 int bytes_returned = 0;
2203 cFYI(1, ("In QFSInfo"));
2205 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2210 pSMB->TotalParameterCount = 2; /* level */
2211 pSMB->TotalDataCount = 0;
2212 pSMB->MaxParameterCount = cpu_to_le16(2);
2213 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
2214 pSMB->MaxSetupCount = 0;
2218 pSMB->Reserved2 = 0;
2219 pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
2220 pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
2221 pSMB->ParameterCount = pSMB->TotalParameterCount;
2222 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2223 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
2224 pSMB->DataCount = 0;
2225 pSMB->DataOffset = 0;
2226 pSMB->SetupCount = 1;
2227 pSMB->Reserved3 = 0;
2228 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
2229 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_SIZE_INFO);
2230 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
2231 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
2233 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2234 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2236 cERROR(1, ("Send error in QFSInfo = %d", rc));
2237 } else { /* decode response */
2238 pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
2240 ("Decoding qfsinfo response. BCC: %d Offset %d",
2241 pSMBr->ByteCount, pSMBr->DataOffset));
2242 if ((pSMBr->ByteCount < 24) || (pSMBr->DataOffset > 512)) /* BB also check enough total bytes returned */
2243 rc = -EIO; /* bad smb */
2247 *) (((char *) &pSMBr->hdr.Protocol) +
2250 le32_to_cpu(response_data->BytesPerSector) *
2251 le32_to_cpu(response_data->
2252 SectorsPerAllocationUnit);
2254 le64_to_cpu(response_data->TotalAllocationUnits);
2255 FSData->f_bfree = FSData->f_bavail =
2256 le64_to_cpu(response_data->FreeAllocationUnits);
2258 ("Blocks: %lld Free: %lld Block size %ld",
2259 (unsigned long long)FSData->f_blocks,
2260 (unsigned long long)FSData->f_bfree,
2265 cifs_buf_release(pSMB);
2274 CIFSSMBQFSAttributeInfo(int xid, struct cifsTconInfo *tcon,
2275 const struct nls_table *nls_codepage)
2277 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
2278 TRANSACTION2_QFSI_REQ *pSMB = NULL;
2279 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
2280 FILE_SYSTEM_ATTRIBUTE_INFO *response_data;
2282 int bytes_returned = 0;
2284 cFYI(1, ("In QFSAttributeInfo"));
2286 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2291 pSMB->TotalParameterCount = 2; /* level */
2292 pSMB->TotalDataCount = 0;
2293 pSMB->MaxParameterCount = cpu_to_le16(2);
2294 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
2295 pSMB->MaxSetupCount = 0;
2299 pSMB->Reserved2 = 0;
2300 pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
2301 pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
2302 pSMB->ParameterCount = pSMB->TotalParameterCount;
2303 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2304 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
2305 pSMB->DataCount = 0;
2306 pSMB->DataOffset = 0;
2307 pSMB->SetupCount = 1;
2308 pSMB->Reserved3 = 0;
2309 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
2310 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO);
2311 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
2312 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
2314 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2315 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2317 cERROR(1, ("Send error in QFSAttributeInfo = %d", rc));
2318 } else { /* decode response */
2319 pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
2320 if ((pSMBr->ByteCount < 13) || (pSMBr->DataOffset > 512)) { /* BB also check enough bytes returned */
2321 rc = -EIO; /* bad smb */
2324 (FILE_SYSTEM_ATTRIBUTE_INFO
2325 *) (((char *) &pSMBr->hdr.Protocol) +
2327 response_data->Attributes = le32_to_cpu(response_data->Attributes);
2328 response_data->MaxPathNameComponentLength =
2329 le32_to_cpu(response_data->MaxPathNameComponentLength);
2330 response_data->FileSystemNameLen =
2331 le32_to_cpu(response_data->FileSystemNameLen);
2332 memcpy(&tcon->fsAttrInfo, response_data,
2333 sizeof (FILE_SYSTEM_ATTRIBUTE_INFO));
2337 cifs_buf_release(pSMB);
2340 goto QFSAttributeRetry;
2346 CIFSSMBQFSDeviceInfo(int xid, struct cifsTconInfo *tcon,
2347 const struct nls_table *nls_codepage)
2349 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
2350 TRANSACTION2_QFSI_REQ *pSMB = NULL;
2351 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
2352 FILE_SYSTEM_DEVICE_INFO *response_data;
2354 int bytes_returned = 0;
2356 cFYI(1, ("In QFSDeviceInfo"));
2358 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2363 pSMB->TotalParameterCount = 2; /* level */
2364 pSMB->TotalDataCount = 0;
2365 pSMB->MaxParameterCount = cpu_to_le16(2);
2366 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
2367 pSMB->MaxSetupCount = 0;
2371 pSMB->Reserved2 = 0;
2372 pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
2373 pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
2374 pSMB->ParameterCount = pSMB->TotalParameterCount;
2375 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2376 struct smb_com_transaction2_qfsi_req, InformationLevel) - 4);
2378 pSMB->DataCount = 0;
2379 pSMB->DataOffset = 0;
2380 pSMB->SetupCount = 1;
2381 pSMB->Reserved3 = 0;
2382 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
2383 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO);
2384 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
2385 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
2387 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2388 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2390 cFYI(1, ("Send error in QFSDeviceInfo = %d", rc));
2391 } else { /* decode response */
2392 pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
2393 if ((pSMBr->ByteCount < sizeof (FILE_SYSTEM_DEVICE_INFO))
2394 || (pSMBr->DataOffset > 512))
2395 rc = -EIO; /* bad smb */
2398 (FILE_SYSTEM_DEVICE_INFO
2399 *) (((char *) &pSMBr->hdr.Protocol) +
2401 response_data->DeviceType =
2402 le32_to_cpu(response_data->DeviceType);
2403 response_data->DeviceCharacteristics =
2404 le32_to_cpu(response_data->DeviceCharacteristics);
2405 memcpy(&tcon->fsDevInfo, response_data,
2406 sizeof (FILE_SYSTEM_DEVICE_INFO));
2410 cifs_buf_release(pSMB);
2413 goto QFSDeviceRetry;
2419 CIFSSMBQFSUnixInfo(int xid, struct cifsTconInfo *tcon,
2420 const struct nls_table *nls_codepage)
2422 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
2423 TRANSACTION2_QFSI_REQ *pSMB = NULL;
2424 TRANSACTION2_QFSI_RSP *pSMBr = NULL;
2425 FILE_SYSTEM_UNIX_INFO *response_data;
2427 int bytes_returned = 0;
2429 cFYI(1, ("In QFSUnixInfo"));
2431 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2436 pSMB->ParameterCount = 2; /* level */
2437 pSMB->TotalDataCount = 0;
2438 pSMB->DataCount = 0;
2439 pSMB->DataOffset = 0;
2440 pSMB->MaxParameterCount = cpu_to_le16(2);
2441 pSMB->MaxDataCount = cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */
2442 pSMB->MaxSetupCount = 0;
2446 pSMB->Reserved2 = 0;
2447 pSMB->ByteCount = pSMB->ParameterCount + 1 /* pad */ ;
2448 pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
2449 pSMB->TotalParameterCount = pSMB->ParameterCount;
2450 pSMB->ParameterOffset = cpu_to_le16(offsetof(struct
2451 smb_com_transaction2_qfsi_req, InformationLevel) - 4);
2452 pSMB->SetupCount = 1;
2453 pSMB->Reserved3 = 0;
2454 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FS_INFORMATION);
2455 pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO);
2456 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
2457 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
2459 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2460 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2462 cERROR(1, ("Send error in QFSUnixInfo = %d", rc));
2463 } else { /* decode response */
2464 pSMBr->DataOffset = cpu_to_le16(pSMBr->DataOffset);
2465 if ((pSMBr->ByteCount < 13) || (pSMBr->DataOffset > 512)) {
2466 rc = -EIO; /* bad smb */
2469 (FILE_SYSTEM_UNIX_INFO
2470 *) (((char *) &pSMBr->hdr.Protocol) +
2472 response_data->MajorVersionNumber =
2473 le16_to_cpu(response_data->MajorVersionNumber);
2474 response_data->MinorVersionNumber =
2475 le16_to_cpu(response_data->MinorVersionNumber);
2476 response_data->Capability =
2477 le64_to_cpu(response_data->Capability);
2478 memcpy(&tcon->fsUnixInfo, response_data,
2479 sizeof (FILE_SYSTEM_UNIX_INFO));
2483 cifs_buf_release(pSMB);
2492 /* We can not use write of zero bytes trick to
2493 set file size due to need for large file support. Also note that
2494 this SetPathInfo is preferred to SetFileInfo based method in next
2495 routine which is only needed to work around a sharing violation bug
2496 in Samba which this routine can run into */
2499 CIFSSMBSetEOF(int xid, struct cifsTconInfo *tcon, char *fileName,
2500 __u64 size, int SetAllocation, const struct nls_table *nls_codepage)
2502 struct smb_com_transaction2_spi_req *pSMB = NULL;
2503 struct smb_com_transaction2_spi_rsp *pSMBr = NULL;
2504 struct file_end_of_file_info *parm_data;
2507 int bytes_returned = 0;
2509 cFYI(1, ("In SetEOF"));
2511 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2516 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2518 cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, 530
2519 /* find define for this maxpathcomponent */
2521 name_len++; /* trailing null */
2523 } else { /* BB improve the check for buffer overruns BB */
2524 name_len = strnlen(fileName, 530);
2525 name_len++; /* trailing null */
2526 strncpy(pSMB->FileName, fileName, name_len);
2528 pSMB->ParameterCount = 6 + name_len;
2529 pSMB->DataCount = sizeof (struct file_end_of_file_info);
2530 pSMB->MaxParameterCount = cpu_to_le16(2);
2531 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB size from sess */
2532 pSMB->MaxSetupCount = 0;
2536 pSMB->Reserved2 = 0;
2537 pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_spi_req,
2538 InformationLevel) - 4;
2539 pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
2541 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
2542 pSMB->InformationLevel =
2543 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
2545 pSMB->InformationLevel =
2546 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
2547 } else /* Set File Size */ {
2548 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
2549 pSMB->InformationLevel =
2550 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
2552 pSMB->InformationLevel =
2553 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
2557 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
2559 pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
2560 pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
2561 pSMB->SetupCount = 1;
2562 pSMB->Reserved3 = 0;
2563 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2564 pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount + pSMB->DataCount;
2565 pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
2566 pSMB->TotalDataCount = pSMB->DataCount;
2567 pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
2568 pSMB->TotalParameterCount = pSMB->ParameterCount;
2569 pSMB->Reserved4 = 0;
2570 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
2571 parm_data->FileSize = cpu_to_le64(size);
2572 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
2573 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2574 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2576 cFYI(1, ("SetPathInfo (file size) returned %d", rc));
2580 cifs_buf_release(pSMB);
2589 CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
2590 __u16 fid, __u32 pid_of_opener, int SetAllocation)
2592 struct smb_com_transaction2_sfi_req *pSMB = NULL;
2593 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
2595 struct file_end_of_file_info *parm_data;
2597 int bytes_returned = 0;
2600 cFYI(1, ("SetFileSize (via SetFileInfo) %lld",
2602 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2607 tmp = cpu_to_le32(pid_of_opener); /* override pid of current process
2608 so network fid will be valid */
2609 pSMB->hdr.Pid = tmp & 0xFFFF;
2611 pSMB->hdr.PidHigh = tmp & 0xFFFF;
2613 pSMB->ParameterCount = 6;
2614 pSMB->MaxSetupCount = 0;
2618 pSMB->Reserved2 = 0;
2619 pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_sfi_req,
2621 pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
2623 data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset;
2625 pSMB->DataCount = sizeof(struct file_end_of_file_info);
2626 pSMB->MaxParameterCount = cpu_to_le16(2);
2627 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
2628 pSMB->SetupCount = 1;
2629 pSMB->Reserved3 = 0;
2630 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
2631 pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount + pSMB->DataCount;
2632 pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
2633 pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
2634 pSMB->TotalDataCount = pSMB->DataCount;
2635 pSMB->TotalParameterCount = pSMB->ParameterCount;
2636 pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
2638 (struct file_end_of_file_info *) (((char *) &pSMB->hdr.Protocol) +
2640 pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset); /* now safe to change to le */
2641 parm_data->FileSize = cpu_to_le64(size);
2644 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
2645 pSMB->InformationLevel =
2646 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2);
2648 pSMB->InformationLevel =
2649 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO);
2650 } else /* Set File Size */ {
2651 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
2652 pSMB->InformationLevel =
2653 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2);
2655 pSMB->InformationLevel =
2656 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO);
2658 pSMB->Reserved4 = 0;
2659 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
2660 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
2661 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2662 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2665 ("Send error in SetFileInfo (SetFileSize) = %d",
2670 cifs_buf_release(pSMB);
2672 /* Note: On -EAGAIN error only caller can retry on handle based calls
2673 since file handle passed in no longer valid */
2679 CIFSSMBSetTimes(int xid, struct cifsTconInfo *tcon, char *fileName,
2680 FILE_BASIC_INFO * data, const struct nls_table *nls_codepage)
2682 TRANSACTION2_SPI_REQ *pSMB = NULL;
2683 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2686 int bytes_returned = 0;
2689 cFYI(1, ("In SetTimes"));
2692 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2697 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2699 cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, 530
2700 /* find define for this maxpathcomponent */
2702 name_len++; /* trailing null */
2704 } else { /* BB improve the check for buffer overruns BB */
2705 name_len = strnlen(fileName, 530);
2706 name_len++; /* trailing null */
2707 strncpy(pSMB->FileName, fileName, name_len);
2710 pSMB->ParameterCount = 6 + name_len;
2711 pSMB->DataCount = sizeof (FILE_BASIC_INFO);
2712 pSMB->MaxParameterCount = cpu_to_le16(2);
2713 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
2714 pSMB->MaxSetupCount = 0;
2718 pSMB->Reserved2 = 0;
2719 pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_spi_req,
2720 InformationLevel) - 4;
2721 pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
2722 data_offset = (char *) (&pSMB->hdr.Protocol) + pSMB->DataOffset;
2723 pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
2724 pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
2725 pSMB->SetupCount = 1;
2726 pSMB->Reserved3 = 0;
2727 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2728 pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount + pSMB->DataCount;
2730 pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
2731 pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
2732 pSMB->TotalDataCount = pSMB->DataCount;
2733 pSMB->TotalParameterCount = pSMB->ParameterCount;
2734 if (tcon->ses->capabilities & CAP_INFOLEVEL_PASSTHRU)
2735 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO2);
2737 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO);
2738 pSMB->Reserved4 = 0;
2739 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
2740 memcpy(data_offset, data, sizeof (FILE_BASIC_INFO));
2741 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
2742 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2743 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2745 cFYI(1, ("SetPathInfo (times) returned %d", rc));
2749 cifs_buf_release(pSMB);
2758 CIFSSMBUnixSetPerms(const int xid, struct cifsTconInfo *tcon,
2759 char *fileName, __u64 mode, __u64 uid, __u64 gid,
2760 dev_t device, const struct nls_table *nls_codepage)
2762 TRANSACTION2_SPI_REQ *pSMB = NULL;
2763 TRANSACTION2_SPI_RSP *pSMBr = NULL;
2766 int bytes_returned = 0;
2767 FILE_UNIX_BASIC_INFO *data_offset;
2769 cFYI(1, ("In SetUID/GID/Mode"));
2771 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2776 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2778 cifs_strtoUCS((wchar_t *) pSMB->FileName, fileName, 530
2779 /* find define for this maxpathcomponent */
2781 name_len++; /* trailing null */
2783 } else { /* BB improve the check for buffer overruns BB */
2784 name_len = strnlen(fileName, 530);
2785 name_len++; /* trailing null */
2786 strncpy(pSMB->FileName, fileName, name_len);
2789 pSMB->ParameterCount = 6 + name_len;
2790 pSMB->DataCount = sizeof (FILE_UNIX_BASIC_INFO);
2791 pSMB->MaxParameterCount = cpu_to_le16(2);
2792 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
2793 pSMB->MaxSetupCount = 0;
2797 pSMB->Reserved2 = 0;
2798 pSMB->ParameterOffset = offsetof(struct smb_com_transaction2_spi_req,
2799 InformationLevel) - 4;
2800 pSMB->DataOffset = pSMB->ParameterOffset + pSMB->ParameterCount;
2802 (FILE_UNIX_BASIC_INFO *) ((char *) &pSMB->hdr.Protocol +
2804 pSMB->DataOffset = cpu_to_le16(pSMB->DataOffset);
2805 pSMB->ParameterOffset = cpu_to_le16(pSMB->ParameterOffset);
2806 pSMB->SetupCount = 1;
2807 pSMB->Reserved3 = 0;
2808 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_PATH_INFORMATION);
2809 pSMB->ByteCount = 3 /* pad */ + pSMB->ParameterCount + pSMB->DataCount;
2810 pSMB->ParameterCount = cpu_to_le16(pSMB->ParameterCount);
2811 pSMB->DataCount = cpu_to_le16(pSMB->DataCount);
2812 pSMB->TotalParameterCount = pSMB->ParameterCount;
2813 pSMB->TotalDataCount = pSMB->DataCount;
2814 pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_UNIX_BASIC);
2815 pSMB->Reserved4 = 0;
2816 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
2817 data_offset->Uid = cpu_to_le64(uid);
2818 data_offset->Gid = cpu_to_le64(gid);
2819 /* better to leave device as zero when it is */
2820 data_offset->DevMajor = cpu_to_le64(MAJOR(device));
2821 data_offset->DevMinor = cpu_to_le64(MINOR(device));
2822 data_offset->Permissions = cpu_to_le64(mode);
2823 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
2824 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2825 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2827 cFYI(1, ("SetPathInfo (perms) returned %d", rc));
2831 cifs_buf_release(pSMB);
2837 int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
2838 const int notify_subdirs, const __u16 netfid,
2839 __u32 filter, const struct nls_table *nls_codepage)
2842 struct smb_com_transaction_change_notify_req * pSMB = NULL;
2843 struct smb_com_transaction_change_notify_rsp * pSMBr = NULL;
2846 cFYI(1, ("In CIFSSMBNotify for file handle %d",(int)netfid));
2847 rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
2852 pSMB->TotalParameterCount = 0 ;
2853 pSMB->TotalDataCount = 0;
2854 pSMB->MaxParameterCount = cpu_to_le32(2);
2855 /* BB find exact data count max from sess structure BB */
2856 pSMB->MaxDataCount = 0; /* same in little endian or be */
2857 pSMB->MaxSetupCount = 4;
2859 pSMB->ParameterOffset = 0;
2860 pSMB->DataCount = 0;
2861 pSMB->DataOffset = 0;
2862 pSMB->SetupCount = 4; /* single byte does not need le conversion */
2863 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
2864 pSMB->ParameterCount = pSMB->TotalParameterCount;
2866 pSMB->WatchTree = 1; /* one byte - no le conversion needed */
2867 pSMB->Reserved2 = 0;
2868 pSMB->CompletionFilter = cpu_to_le32(filter);
2869 pSMB->Fid = netfid; /* file handle always le */
2870 pSMB->ByteCount = 0;
2872 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
2873 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2874 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2876 cFYI(1, ("Error in Notify = %d", rc));
2879 cifs_buf_release(pSMB);
2880 /* if (rc == -EAGAIN)
2881 goto NotifyRetry; */
2884 #ifdef CONFIG_CIFS_XATTR
2886 CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
2887 const unsigned char *searchName,
2888 char * EAData, size_t size,
2889 const struct nls_table *nls_codepage)
2891 /* BB assumes one setup word */
2892 TRANSACTION2_QPI_REQ *pSMB = NULL;
2893 TRANSACTION2_QPI_RSP *pSMBr = NULL;
2898 cFYI(1, ("In Query All EAs path %s", searchName));
2900 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
2905 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2907 cifs_strtoUCS((wchar_t *) pSMB->FileName, searchName, 530
2908 /* find define for this maxpathcomponent */
2910 name_len++; /* trailing null */
2912 } else { /* BB improve the check for buffer overruns BB */
2913 name_len = strnlen(searchName, 530);
2914 name_len++; /* trailing null */
2915 strncpy(pSMB->FileName, searchName, name_len);
2918 pSMB->TotalParameterCount = 2 /* level */ + 4 /* reserved */ +
2919 name_len /* includes null */ ;
2920 pSMB->TotalDataCount = 0;
2921 pSMB->MaxParameterCount = cpu_to_le16(2);
2922 pSMB->MaxDataCount = cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
2923 pSMB->MaxSetupCount = 0;
2927 pSMB->Reserved2 = 0;
2928 pSMB->ParameterOffset = cpu_to_le16(offsetof(
2929 struct smb_com_transaction2_qpi_req ,InformationLevel) - 4);
2930 pSMB->DataCount = 0;
2931 pSMB->DataOffset = 0;
2932 pSMB->SetupCount = 1;
2933 pSMB->Reserved3 = 0;
2934 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION);
2935 pSMB->ByteCount = pSMB->TotalParameterCount + 1 /* pad */ ;
2936 pSMB->TotalParameterCount = cpu_to_le16(pSMB->TotalParameterCount);
2937 pSMB->ParameterCount = pSMB->TotalParameterCount;
2938 pSMB->InformationLevel = cpu_to_le16(SMB_INFO_QUERY_ALL_EAS);
2939 pSMB->Reserved4 = 0;
2940 pSMB->hdr.smb_buf_length += pSMB->ByteCount;
2941 pSMB->ByteCount = cpu_to_le16(pSMB->ByteCount);
2943 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2944 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2946 cFYI(1, ("Send error in QueryAllEAs = %d", rc));
2947 } else { /* decode response */
2948 pSMBr->DataOffset = le16_to_cpu(pSMBr->DataOffset);
2949 /* BB also check enough total bytes returned */
2950 /* BB we need to improve the validity checking
2951 of these trans2 responses */
2952 if ((pSMBr->ByteCount < 4) || (pSMBr->DataOffset > 512))
2953 rc = -EIO; /* bad smb */
2954 /* else if (pFindData){
2955 memcpy((char *) pFindData,
2956 (char *) &pSMBr->hdr.Protocol +
2957 pSMBr->DataOffset, kl);
2959 /* check that length of list is not more than bcc */
2960 /* check that each entry does not go beyond length
2962 /* check that each element of each entry does not
2963 go beyond end of list */
2964 struct fealist * ea_response_data;
2966 /* validate_trans2_offsets() */
2967 /* BB to check if(start of smb + pSMBr->DataOffset > &bcc+ bcc)*/
2968 ea_response_data = (struct fealist *)
2969 (((char *) &pSMBr->hdr.Protocol) +
2971 cFYI(1,("ea length %d",ea_response_data->list_len));
2975 cifs_buf_release(pSMB);