4 * Copyright (c) International Business Machines Corp., 2002
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 */
27 #include <linux/kernel.h>
28 #include <linux/vfs.h>
29 #include <asm/uaccess.h>
32 #include "cifsproto.h"
33 #include "cifs_unicode.h"
34 #include "cifs_debug.h"
41 CIFS_PROT
, "\2NT LM 0.12"}, {
46 smb_init(int smb_command
, int wct
, struct cifsTconInfo
*tcon
,
47 void **request_buf
/* returned */ ,
48 void **response_buf
/* returned */ )
52 if(tcon
&& (tcon
->tidStatus
== CifsNeedReconnect
)) {
55 struct nls_table
*nls_codepage
= load_nls_default();
56 if(tcon
->ses
->status
== CifsNeedReconnect
)
57 rc
= setup_session(0, tcon
->ses
, nls_codepage
);
59 rc
= CIFSTCon(0, tcon
->ses
, tcon
->treeName
, tcon
,
61 cFYI(1, ("reconnect tcon rc = %d", rc
));
63 reopen_files(tcon
,nls_codepage
);
70 *request_buf
= buf_get();
71 if (request_buf
== 0) {
74 /* Although the original thought was we needed the response buf for */
75 /* potential retries of smb operations it turns out we can determine */
76 /* from the mid flags when the request buffer can be resent without */
77 /* having to use a second distinct buffer for the response */
78 *response_buf
= *request_buf
;
80 header_assemble((struct smb_hdr
*) *request_buf
, smb_command
, tcon
,
86 CIFSSMBNegotiate(unsigned int xid
, struct cifsSesInfo
*ses
)
92 struct TCP_Server_Info
* server
;
101 rc
= smb_init(SMB_COM_NEGOTIATE
, 0, 0 /* no tcon yet */ ,
102 (void **) &pSMB
, (void **) &pSMBr
);
106 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
107 if (extended_security
)
108 pSMB
->hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
110 pSMB
->ByteCount
= strlen(protocols
[0].name
) + 1;
111 strncpy(pSMB
->DialectsArray
, protocols
[0].name
, 30);
112 /* null guaranteed to be at end of source and target buffers anyway */
114 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
115 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
117 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
118 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
120 server
->secMode
= pSMBr
->SecurityMode
;
121 server
->secType
= NTLM
; /* BB override default for NTLMv2 or krb*/
122 /* one byte - no need to convert this or EncryptionKeyLen from le,*/
123 server
->maxReq
= le16_to_cpu(pSMBr
->MaxMpxCount
);
124 /* probably no need to store and check maxvcs */
126 min(le32_to_cpu(pSMBr
->MaxBufferSize
),
127 (__u32
) CIFS_MAX_MSGSIZE
+ MAX_CIFS_HDR_SIZE
);
128 server
->maxRw
= le32_to_cpu(pSMBr
->MaxRawSize
);
129 cFYI(0, ("Max buf = %d ", ses
->server
->maxBuf
));
130 GETU32(ses
->server
->sessid
) = le32_to_cpu(pSMBr
->SessionKey
);
131 server
->capabilities
= le32_to_cpu(pSMBr
->Capabilities
);
132 server
->timeZone
= le16_to_cpu(pSMBr
->ServerTimeZone
);
133 /* BB with UTC do we ever need to be using srvr timezone? */
134 if (pSMBr
->EncryptionKeyLength
== CIFS_CRYPTO_KEY_SIZE
) {
135 memcpy(server
->cryptKey
, pSMBr
->u
.EncryptionKey
,
136 CIFS_CRYPTO_KEY_SIZE
);
137 } else if ((pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
)
138 && (pSMBr
->EncryptionKeyLength
== 0)) {
139 /* decode security blob */
143 /* BB might be helpful to save off the domain of server here */
145 if (pSMBr
->hdr
.Flags2
& SMBFLG2_EXT_SEC
) {
146 if (pSMBr
->ByteCount
< 16)
148 else if (pSMBr
->ByteCount
== 16) {
149 server
->secType
= RawNTLMSSP
;
150 if (server
->socketUseCount
.counter
> 1) {
152 (server
->server_GUID
,
153 pSMBr
->u
.extended_response
.
156 ("UID of server does not match previous connection to same ip address"));
164 memcpy(server
->server_GUID
,
165 pSMBr
->u
.extended_response
.
168 rc
= decode_negTokenInit(pSMBr
->u
.
172 16, &server
->secType
);
176 server
->capabilities
&= ~CAP_EXTENDED_SECURITY
;
177 if(sign_CIFS_PDUs
== FALSE
) {
178 if(server
->secMode
& SECMODE_SIGN_REQUIRED
)
180 ("Server requires /proc/fs/cifs/PacketSigningEnabled"));
181 server
->secMode
&= ~(SECMODE_SIGN_ENABLED
| SECMODE_SIGN_REQUIRED
);
190 CIFSSMBTDis(const int xid
, struct cifsTconInfo
*tcon
)
192 struct smb_hdr
*smb_buffer
;
193 struct smb_hdr
*smb_buffer_response
;
197 cFYI(1, ("In tree disconnect"));
199 * If last user of the connection and
200 * connection alive - disconnect it
201 * If this is the last connection on the server session disconnect it
202 * (and inside session disconnect we should check if tcp socket needs
203 * to be freed and kernel thread woken up).
206 down(&tcon
->tconSem
);
210 atomic_dec(&tcon
->useCount
);
211 if (atomic_read(&tcon
->useCount
) > 0) {
216 /* BB remove (from server) list of shares - but with smp safety BB */
217 /* BB is ses active - do we need to check here - but how? BB */
218 if((tcon
->ses
== 0) || (tcon
->ses
->server
== 0)) {
223 rc
= smb_init(SMB_COM_TREE_DISCONNECT
, 0, tcon
,
224 (void **) &smb_buffer
, (void **) &smb_buffer_response
);
229 rc
= SendReceive(xid
, tcon
->ses
, smb_buffer
, smb_buffer_response
,
232 cFYI(1, (" Tree disconnect failed %d", rc
));
235 buf_release(smb_buffer
);
241 CIFSSMBLogoff(const int xid
, struct cifsSesInfo
*ses
)
243 struct smb_hdr
*smb_buffer_response
;
244 LOGOFF_ANDX_REQ
*pSMB
;
248 cFYI(1, ("In SMBLogoff for session disconnect"));
251 down(&ses
->sesSem
); /* check this sem more places */
255 atomic_dec(&ses
->inUse
);
256 if (atomic_read(&ses
->inUse
) > 0) {
261 rc
= smb_init(SMB_COM_LOGOFF_ANDX
, 2, 0 /* no tcon anymore */,
262 (void **) &pSMB
, (void **) &smb_buffer_response
);
264 if(ses
->server
->secMode
& (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
))
265 pSMB
->hdr
.Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
272 pSMB
->hdr
.Uid
= ses
->Suid
;
274 pSMB
->AndXCommand
= 0xFF;
275 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
276 smb_buffer_response
, &length
, 0);
278 atomic_dec(&ses
->server
->socketUseCount
);
279 if (atomic_read(&ses
->server
->socketUseCount
) == 0)
280 ses
->server
->tcpStatus
= CifsExiting
;
289 CIFSSMBDelFile(const int xid
, struct cifsTconInfo
*tcon
,
290 const char *fileName
, const struct nls_table
*nls_codepage
)
292 DELETE_FILE_REQ
*pSMB
= NULL
;
293 DELETE_FILE_RSP
*pSMBr
= NULL
;
298 rc
= smb_init(SMB_COM_DELETE
, 1, tcon
, (void **) &pSMB
,
303 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
305 cifs_strtoUCS((wchar_t *) pSMB
->fileName
, fileName
, 530
306 /* find define for this maxpathcomponent */
308 name_len
++; /* trailing null */
310 } else { /* BB improve the check for buffer overruns BB */
311 name_len
= strnlen(fileName
, 530);
312 name_len
++; /* trailing null */
313 strncpy(pSMB
->fileName
, fileName
, name_len
);
315 pSMB
->SearchAttributes
=
316 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
);
317 pSMB
->ByteCount
= name_len
+ 1;
318 pSMB
->BufferFormat
= 0x04;
319 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
320 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
321 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
322 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
324 cFYI(1, ("Error in RMFile = %d", rc
));
332 CIFSSMBRmDir(const int xid
, struct cifsTconInfo
*tcon
,
333 const char *dirName
, const struct nls_table
*nls_codepage
)
335 DELETE_DIRECTORY_REQ
*pSMB
= NULL
;
336 DELETE_DIRECTORY_RSP
*pSMBr
= NULL
;
341 cFYI(1, ("In CIFSSMBRmDir"));
343 rc
= smb_init(SMB_COM_DELETE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
348 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
349 name_len
= cifs_strtoUCS((wchar_t *) pSMB
->DirName
, dirName
, 530
350 /* find define for this maxpathcomponent */
352 name_len
++; /* trailing null */
354 } else { /* BB improve the check for buffer overruns BB */
355 name_len
= strnlen(dirName
, 530);
356 name_len
++; /* trailing null */
357 strncpy(pSMB
->DirName
, dirName
, name_len
);
360 pSMB
->ByteCount
= name_len
+ 1;
361 pSMB
->BufferFormat
= 0x04;
362 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
363 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
364 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
365 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
367 cFYI(1, ("Error in RMDir = %d", rc
));
375 CIFSSMBMkDir(const int xid
, struct cifsTconInfo
*tcon
,
376 const char *name
, const struct nls_table
*nls_codepage
)
379 CREATE_DIRECTORY_REQ
*pSMB
= NULL
;
380 CREATE_DIRECTORY_RSP
*pSMBr
= NULL
;
384 cFYI(1, ("In CIFSSMBMkDir"));
386 rc
= smb_init(SMB_COM_CREATE_DIRECTORY
, 0, tcon
, (void **) &pSMB
,
391 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
392 name_len
= cifs_strtoUCS((wchar_t *) pSMB
->DirName
, name
, 530
393 /* find define for this maxpathcomponent */
395 name_len
++; /* trailing null */
397 } else { /* BB improve the check for buffer overruns BB */
398 name_len
= strnlen(name
, 530);
399 name_len
++; /* trailing null */
400 strncpy(pSMB
->DirName
, name
, name_len
);
403 pSMB
->ByteCount
= name_len
+ 1 /* for buf format */ ;
404 pSMB
->BufferFormat
= 0x04;
405 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
406 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
407 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
408 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
410 cFYI(1, ("Error in Mkdir = %d", rc
));
419 CIFSSMBOpen(const int xid
, struct cifsTconInfo
*tcon
,
420 const char *fileName
, const int openDisposition
,
421 const int access_flags
, const int create_options
, __u16
* netfid
,
422 int *pOplock
, const struct nls_table
*nls_codepage
)
425 OPEN_REQ
*pSMB
= NULL
;
426 OPEN_RSP
*pSMBr
= NULL
;
430 rc
= smb_init(SMB_COM_NT_CREATE_ANDX
, 24, tcon
, (void **) &pSMB
,
435 pSMB
->AndXCommand
= 0xFF; /* none */
437 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
438 pSMB
->ByteCount
= 1; /* account for one byte pad to word boundary */
440 cifs_strtoUCS((wchar_t *) (pSMB
->fileName
+ 1),
442 /* find define for this maxpathcomponent */
444 name_len
++; /* trailing null */
446 pSMB
->NameLength
= cpu_to_le16(name_len
);
447 } else { /* BB improve the check for buffer overruns BB */
448 pSMB
->ByteCount
= 0; /* no pad */
449 name_len
= strnlen(fileName
, 530);
450 name_len
++; /* trailing null */
451 pSMB
->NameLength
= cpu_to_le16(name_len
);
452 strncpy(pSMB
->fileName
, fileName
, name_len
);
454 if (*pOplock
& REQ_OPLOCK
)
455 pSMB
->OpenFlags
= cpu_to_le32(REQ_OPLOCK
);
456 else if (*pOplock
& REQ_BATCHOPLOCK
) {
457 pSMB
->OpenFlags
= cpu_to_le32(REQ_BATCHOPLOCK
);
459 pSMB
->DesiredAccess
= cpu_to_le32(access_flags
);
460 pSMB
->AllocationSize
= 0;
461 pSMB
->FileAttributes
= ATTR_NORMAL
; /* XP does not handle ATTR_POSIX_SEMANTICS */
462 /*if ((omode & S_IWUGO) == 0)
463 pSMB->FileAttributes |= ATTR_READONLY;*/
464 /* Above line causes problems due to vfs splitting create into two
465 pieces - need to set mode after file created not while it is
467 pSMB
->FileAttributes
= cpu_to_le32(pSMB
->FileAttributes
);
468 pSMB
->ShareAccess
= cpu_to_le32(FILE_SHARE_ALL
);
469 pSMB
->CreateDisposition
= cpu_to_le32(openDisposition
);
470 pSMB
->CreateOptions
= cpu_to_le32(create_options
);
471 pSMB
->ImpersonationLevel
= cpu_to_le32(SECURITY_IMPERSONATION
); /* BB ??*/
472 pSMB
->SecurityFlags
=
473 cpu_to_le32(SECURITY_CONTEXT_TRACKING
| SECURITY_EFFECTIVE_ONLY
);
475 pSMB
->ByteCount
+= name_len
;
476 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
478 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
479 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
480 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
482 cFYI(1, ("Error in Open = %d", rc
));
484 *pOplock
= pSMBr
->OplockLevel
; /* one byte no need to le_to_cpu */
485 *netfid
= pSMBr
->Fid
; /* cifs fid stays in le */
486 /* Do we care about the CreateAction in any cases? */
488 /* BB add code to update inode file sizes from create response */
496 /* If no buffer passed in, then caller wants to do the copy
497 as in the case of readpages so the SMB buffer must be
498 freed by the caller */
501 CIFSSMBRead(const int xid
, struct cifsTconInfo
*tcon
,
502 const int netfid
, const unsigned int count
,
503 const __u64 lseek
, unsigned int *nbytes
, char **buf
)
506 READ_REQ
*pSMB
= NULL
;
507 READ_RSP
*pSMBr
= NULL
;
508 char *pReadData
= NULL
;
512 rc
= smb_init(SMB_COM_READ_ANDX
, 12, tcon
, (void **) &pSMB
,
517 pSMB
->AndXCommand
= 0xFF; /* none */
519 pSMB
->OffsetLow
= cpu_to_le32(lseek
& 0xFFFFFFFF);
520 pSMB
->OffsetHigh
= cpu_to_le32(lseek
>> 32);
522 pSMB
->MaxCount
= cpu_to_le16(count
);
523 pSMB
->MaxCountHigh
= 0;
524 pSMB
->ByteCount
= 0; /* no need to do le conversion since it is 0 */
526 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
527 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
529 cERROR(1, ("Send error in read = %d", rc
));
531 pSMBr
->DataLength
= le16_to_cpu(pSMBr
->DataLength
);
532 *nbytes
= pSMBr
->DataLength
;
533 /*check that DataLength would not go beyond end of SMB */
534 if ((pSMBr
->DataLength
> CIFS_MAX_MSGSIZE
)
535 || (pSMBr
->DataLength
> count
)) {
536 cFYI(1,("bad length %d for count %d",pSMBr
->DataLength
,count
));
541 (char *) (&pSMBr
->hdr
.Protocol
) +
542 le16_to_cpu(pSMBr
->DataOffset
);
543 /* if(rc = copy_to_user(buf, pReadData, pSMBr->DataLength)) {
544 cERROR(1,("Faulting on read rc = %d",rc));
546 }*/ /* can not use copy_to_user when using page cache*/
548 memcpy(*buf
,pReadData
,pSMBr
->DataLength
);
561 CIFSSMBWrite(const int xid
, struct cifsTconInfo
*tcon
,
562 const int netfid
, const unsigned int count
,
563 const __u64 offset
, unsigned int *nbytes
, const char *buf
,
567 WRITE_REQ
*pSMB
= NULL
;
568 WRITE_RSP
*pSMBr
= NULL
;
571 rc
= smb_init(SMB_COM_WRITE_ANDX
, 14, tcon
, (void **) &pSMB
,
576 pSMB
->AndXCommand
= 0xFF; /* none */
578 pSMB
->OffsetLow
= cpu_to_le32(offset
& 0xFFFFFFFF);
579 pSMB
->OffsetHigh
= cpu_to_le32(offset
>> 32);
581 if (count
> ((tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
) & 0xFFFFFF00))
582 pSMB
->DataLengthLow
=
583 (tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
) & 0xFFFFFF00;
585 pSMB
->DataLengthLow
= count
;
586 pSMB
->DataLengthHigh
= 0;
588 cpu_to_le16(offsetof(struct smb_com_write_req
,Data
) - 4);
590 memcpy(pSMB
->Data
,buf
,pSMB
->DataLengthLow
);
592 pSMB
->ByteCount
+= pSMB
->DataLengthLow
+ 1 /* pad */ ;
593 pSMB
->DataLengthLow
= cpu_to_le16(pSMB
->DataLengthLow
);
594 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
595 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
597 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
598 (struct smb_hdr
*) pSMBr
, &bytes_returned
, long_op
);
600 cERROR(1, ("Send error in write = %d", rc
));
603 *nbytes
= le16_to_cpu(pSMBr
->Count
);
612 CIFSSMBLock(const int xid
, struct cifsTconInfo
*tcon
,
613 const __u16 smb_file_id
, const __u64 len
,
614 const __u64 offset
, const __u32 numUnlock
,
615 const __u32 numLock
, const __u8 lockType
, const int waitFlag
)
618 LOCK_REQ
*pSMB
= NULL
;
619 LOCK_RSP
*pSMBr
= NULL
;
622 cFYI(1, ("In CIFSSMBLock"));
624 rc
= smb_init(SMB_COM_LOCKING_ANDX
, 8, tcon
, (void **) &pSMB
,
629 pSMB
->NumberOfLocks
= cpu_to_le32(numLock
);
630 pSMB
->NumberOfUnlocks
= cpu_to_le32(numUnlock
);
631 pSMB
->LockType
= lockType
;
632 pSMB
->AndXCommand
= 0xFF; /* none */
633 pSMB
->Fid
= smb_file_id
; /* netfid stays le */
635 pSMB
->Locks
[0].Pid
= cpu_to_le16(current
->pid
);
636 pSMB
->Locks
[0].Length
= cpu_to_le64(len
);
637 pSMB
->Locks
[0].Offset
= cpu_to_le64(offset
);
638 pSMB
->ByteCount
= sizeof (LOCKING_ANDX_RANGE
);
639 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
640 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
642 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
643 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
646 cERROR(1, ("Send error in Lock = %d", rc
));
655 CIFSSMBClose(const int xid
, struct cifsTconInfo
*tcon
, int smb_file_id
)
658 CLOSE_REQ
*pSMB
= NULL
;
659 CLOSE_RSP
*pSMBr
= NULL
;
661 cFYI(1, ("In CIFSSMBClose"));
663 rc
= smb_init(SMB_COM_CLOSE
, 3, tcon
, (void **) &pSMB
,
668 pSMB
->FileID
= (__u16
) smb_file_id
;
669 pSMB
->LastWriteTime
= 0;
671 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
672 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
674 cERROR(1, ("Send error in Close = %d", rc
));
683 CIFSSMBRename(const int xid
, struct cifsTconInfo
*tcon
,
684 const char *fromName
, const char *toName
,
685 const struct nls_table
*nls_codepage
)
688 RENAME_REQ
*pSMB
= NULL
;
689 RENAME_RSP
*pSMBr
= NULL
;
691 int name_len
, name_len2
;
693 cFYI(1, ("In CIFSSMBRename"));
695 rc
= smb_init(SMB_COM_RENAME
, 1, tcon
, (void **) &pSMB
,
700 pSMB
->BufferFormat
= 0x04;
701 pSMB
->SearchAttributes
=
702 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
705 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
707 cifs_strtoUCS((wchar_t *) pSMB
->OldFileName
, fromName
, 530
708 /* find define for this maxpathcomponent */
710 name_len
++; /* trailing null */
712 pSMB
->OldFileName
[name_len
] = 0x04; /* pad */
713 /* protocol requires ASCII signature byte on Unicode string */
714 pSMB
->OldFileName
[name_len
+ 1] = 0x00;
716 cifs_strtoUCS((wchar_t *) & pSMB
->
717 OldFileName
[name_len
+ 2], toName
, 530,
719 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
720 name_len2
*= 2; /* convert to bytes */
721 } else { /* BB improve the check for buffer overruns BB */
722 name_len
= strnlen(fromName
, 530);
723 name_len
++; /* trailing null */
724 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
725 name_len2
= strnlen(toName
, 530);
726 name_len2
++; /* trailing null */
727 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
728 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
729 name_len2
++; /* trailing null */
730 name_len2
++; /* signature byte */
733 pSMB
->ByteCount
= 1 /* 1st signature byte */ + name_len
+ name_len2
;
734 /* we could also set search attributes but not needed */
735 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
736 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
738 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
739 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
741 cFYI(1, ("Send error in RMDir = %d", rc
));
750 CIFSUnixCreateSymLink(const int xid
, struct cifsTconInfo
*tcon
,
751 const char *fromName
, const char *toName
,
752 const struct nls_table
*nls_codepage
)
754 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
755 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
760 int bytes_returned
= 0;
762 cFYI(1, ("In Symlink Unix style"));
764 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
769 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
771 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, fromName
, 530
772 /* find define for this maxpathcomponent */
774 name_len
++; /* trailing null */
777 } else { /* BB improve the check for buffer overruns BB */
778 name_len
= strnlen(fromName
, 530);
779 name_len
++; /* trailing null */
780 strncpy(pSMB
->FileName
, fromName
, name_len
);
782 pSMB
->ParameterCount
= 6 + name_len
;
783 pSMB
->MaxSetupCount
= 0;
788 pSMB
->ParameterOffset
= offsetof(struct smb_com_transaction2_spi_req
,
789 InformationLevel
) - 4;
790 pSMB
->DataOffset
= pSMB
->ParameterOffset
+ pSMB
->ParameterCount
;
792 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + pSMB
->DataOffset
;
793 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
795 cifs_strtoUCS((wchar_t *) data_offset
, toName
, 530
796 /* find define for this maxpathcomponent */
798 name_len_target
++; /* trailing null */
799 name_len_target
*= 2;
800 } else { /* BB improve the check for buffer overruns BB */
801 name_len_target
= strnlen(toName
, 530);
802 name_len_target
++; /* trailing null */
803 strncpy(data_offset
, toName
, name_len_target
);
806 pSMB
->DataCount
= name_len_target
;
807 pSMB
->MaxParameterCount
= cpu_to_le16(2);
808 /* BB find exact max on data count below from sess */
809 pSMB
->MaxDataCount
= cpu_to_le16(1000);
810 pSMB
->SetupCount
= 1;
812 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
813 pSMB
->ByteCount
= 3 /* pad */ + pSMB
->ParameterCount
+ pSMB
->DataCount
;
814 pSMB
->DataCount
= cpu_to_le16(pSMB
->DataCount
);
815 pSMB
->ParameterCount
= cpu_to_le16(pSMB
->ParameterCount
);
816 pSMB
->TotalDataCount
= pSMB
->DataCount
;
817 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
818 pSMB
->ParameterOffset
= cpu_to_le16(pSMB
->ParameterOffset
);
819 pSMB
->DataOffset
= cpu_to_le16(pSMB
->DataOffset
);
820 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_LINK
);
822 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
823 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
824 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
825 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
828 ("Send error in SetPathInfo (create symlink) = %d",
838 CIFSUnixCreateHardLink(const int xid
, struct cifsTconInfo
*tcon
,
839 const char *fromName
, const char *toName
,
840 const struct nls_table
*nls_codepage
)
842 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
843 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
848 int bytes_returned
= 0;
850 cFYI(1, ("In Create Hard link Unix style"));
852 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
857 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
858 name_len
= cifs_strtoUCS((wchar_t *) pSMB
->FileName
, toName
, 530
859 /* find define for this maxpathcomponent */
861 name_len
++; /* trailing null */
864 } else { /* BB improve the check for buffer overruns BB */
865 name_len
= strnlen(toName
, 530);
866 name_len
++; /* trailing null */
867 strncpy(pSMB
->FileName
, toName
, name_len
);
869 pSMB
->ParameterCount
= 6 + name_len
;
870 pSMB
->MaxSetupCount
= 0;
875 pSMB
->ParameterOffset
= offsetof(struct smb_com_transaction2_spi_req
,
876 InformationLevel
) - 4;
877 pSMB
->DataOffset
= pSMB
->ParameterOffset
+ pSMB
->ParameterCount
;
879 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + pSMB
->DataOffset
;
880 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
882 cifs_strtoUCS((wchar_t *) data_offset
, fromName
, 530
883 /* find define for this maxpathcomponent */
885 name_len_target
++; /* trailing null */
886 name_len_target
*= 2;
887 } else { /* BB improve the check for buffer overruns BB */
888 name_len_target
= strnlen(fromName
, 530);
889 name_len_target
++; /* trailing null */
890 strncpy(data_offset
, fromName
, name_len_target
);
893 pSMB
->DataCount
= name_len_target
;
894 pSMB
->MaxParameterCount
= cpu_to_le16(2);
895 /* BB find exact max on data count below from sess*/
896 pSMB
->MaxDataCount
= cpu_to_le16(1000);
897 pSMB
->SetupCount
= 1;
899 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
900 pSMB
->ByteCount
= 3 /* pad */ + pSMB
->ParameterCount
+ pSMB
->DataCount
;
901 pSMB
->ParameterCount
= cpu_to_le16(pSMB
->ParameterCount
);
902 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
903 pSMB
->DataCount
= cpu_to_le16(pSMB
->DataCount
);
904 pSMB
->TotalDataCount
= pSMB
->DataCount
;
905 pSMB
->ParameterOffset
= cpu_to_le16(pSMB
->ParameterOffset
);
906 pSMB
->DataOffset
= cpu_to_le16(pSMB
->DataOffset
);
907 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_HLINK
);
909 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
910 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
911 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
912 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
914 cFYI(1, ("Send error in SetPathInfo (hard link) = %d", rc
));
923 CIFSCreateHardLink(const int xid
, struct cifsTconInfo
*tcon
,
924 const char *fromName
, const char *toName
,
925 const struct nls_table
*nls_codepage
)
928 NT_RENAME_REQ
*pSMB
= NULL
;
929 RENAME_RSP
*pSMBr
= NULL
;
931 int name_len
, name_len2
;
933 cFYI(1, ("In CIFSCreateHardLink"));
935 rc
= smb_init(SMB_COM_NT_RENAME
, 4, tcon
, (void **) &pSMB
,
940 pSMB
->SearchAttributes
=
941 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
943 pSMB
->Flags
= cpu_to_le16(CREATE_HARD_LINK
);
944 pSMB
->ClusterCount
= 0;
946 pSMB
->BufferFormat
= 0x04;
948 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
950 cifs_strtoUCS((wchar_t *) pSMB
->OldFileName
, fromName
, 530
951 /* find define for this maxpathcomponent */
953 name_len
++; /* trailing null */
955 pSMB
->OldFileName
[name_len
] = 0; /* pad */
956 pSMB
->OldFileName
[name_len
+ 1] = 0x04;
958 cifs_strtoUCS((wchar_t *) & pSMB
->
959 OldFileName
[name_len
+ 2], toName
, 530,
961 name_len2
+= 1 /* trailing null */ + 1 /* Signature word */ ;
962 name_len2
*= 2; /* convert to bytes */
963 } else { /* BB improve the check for buffer overruns BB */
964 name_len
= strnlen(fromName
, 530);
965 name_len
++; /* trailing null */
966 strncpy(pSMB
->OldFileName
, fromName
, name_len
);
967 name_len2
= strnlen(toName
, 530);
968 name_len2
++; /* trailing null */
969 pSMB
->OldFileName
[name_len
] = 0x04; /* 2nd buffer format */
970 strncpy(&pSMB
->OldFileName
[name_len
+ 1], toName
, name_len2
);
971 name_len2
++; /* trailing null */
972 name_len2
++; /* signature byte */
975 pSMB
->ByteCount
= 1 /* string type byte */ + name_len
+ name_len2
;
976 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
977 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
979 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
980 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
982 cFYI(1, ("Send error in hard link (NT rename) = %d", rc
));
991 CIFSSMBUnixQuerySymLink(const int xid
, struct cifsTconInfo
*tcon
,
992 const unsigned char *searchName
,
993 char *symlinkinfo
, const int buflen
,
994 const struct nls_table
*nls_codepage
)
996 /* SMB_QUERY_FILE_UNIX_LINK */
997 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
998 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
1003 cFYI(1, ("In QPathSymLinkInfo (Unix) for path %s", searchName
));
1004 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1009 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1011 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, searchName
, 530
1012 /* find define for this maxpathcomponent */
1014 name_len
++; /* trailing null */
1016 } else { /* BB improve the check for buffer overruns BB */
1017 name_len
= strnlen(searchName
, 530);
1018 name_len
++; /* trailing null */
1019 strncpy(pSMB
->FileName
, searchName
, name_len
);
1022 pSMB
->TotalParameterCount
=
1023 2 /* level */ + 4 /* rsrvd */ + name_len
/* incl null */ ;
1024 pSMB
->TotalDataCount
= 0;
1025 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1026 /* BB find exact max data count below from sess structure BB */
1027 pSMB
->MaxDataCount
= cpu_to_le16(4000);
1028 pSMB
->MaxSetupCount
= 0;
1032 pSMB
->Reserved2
= 0;
1033 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
1034 struct smb_com_transaction2_qpi_req
,InformationLevel
) - 4);
1035 pSMB
->DataCount
= 0;
1036 pSMB
->DataOffset
= 0;
1037 pSMB
->SetupCount
= 1;
1038 pSMB
->Reserved3
= 0;
1039 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
1040 pSMB
->ByteCount
= pSMB
->TotalParameterCount
+ 1 /* pad */ ;
1041 pSMB
->TotalParameterCount
= cpu_to_le16(pSMB
->TotalParameterCount
);
1042 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1043 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_LINK
);
1044 pSMB
->Reserved4
= 0;
1045 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
1046 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
1048 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1049 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1051 cFYI(1, ("Send error in QuerySymLinkInfo = %d", rc
));
1052 } else { /* decode response */
1053 pSMBr
->DataOffset
= le16_to_cpu(pSMBr
->DataOffset
);
1054 pSMBr
->DataCount
= le16_to_cpu(pSMBr
->DataCount
);
1055 if ((pSMBr
->ByteCount
< 2) || (pSMBr
->DataOffset
> 512))
1056 /* BB also check enough total bytes returned */
1057 rc
= -EIO
; /* bad smb */
1059 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1060 name_len
= UniStrnlen((wchar_t *) ((char *)
1061 &pSMBr
->hdr
.Protocol
+pSMBr
->DataOffset
),
1062 min_t(const int, buflen
,pSMBr
->DataCount
) / 2);
1063 cifs_strfromUCS_le(symlinkinfo
,
1064 (wchar_t *) ((char *)&pSMBr
->hdr
.Protocol
+
1066 name_len
, nls_codepage
);
1068 strncpy(symlinkinfo
,
1069 (char *) &pSMBr
->hdr
.Protocol
+
1071 min_t(const int, buflen
, pSMBr
->DataCount
));
1073 symlinkinfo
[buflen
] = 0;
1074 /* just in case so calling code does not go off the end of buffer */
1085 CIFSSMBQueryReparseLinkInfo(const int xid
, struct cifsTconInfo
*tcon
,
1086 const unsigned char *searchName
,
1087 char *symlinkinfo
, const int buflen
,__u16 fid
,
1088 const struct nls_table
*nls_codepage
)
1093 struct smb_com_transaction_ioctl_req
* pSMB
;
1094 struct smb_com_transaction_ioctl_rsp
* pSMBr
;
1096 cFYI(1, ("In Windows reparse style QueryLink for path %s", searchName
));
1097 rc
= smb_init(SMB_COM_NT_TRANSACT
, 23, tcon
, (void **) &pSMB
,
1102 pSMB
->TotalParameterCount
= 0 ;
1103 pSMB
->TotalDataCount
= 0;
1104 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1105 /* BB find exact data count max from sess structure BB */
1106 pSMB
->MaxDataCount
= cpu_to_le16(4000);
1107 pSMB
->MaxSetupCount
= 4;
1109 pSMB
->ParameterOffset
= 0;
1110 pSMB
->DataCount
= 0;
1111 pSMB
->DataOffset
= 0;
1112 pSMB
->SetupCount
= 4;
1113 pSMB
->SubCommand
= cpu_to_le16(NT_TRANSACT_IOCTL
);
1114 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1115 pSMB
->FunctionCode
= cpu_to_le32(FSCTL_GET_REPARSE_POINT
);
1116 pSMB
->IsFsctl
= 1; /* FSCTL */
1117 pSMB
->IsRootFlag
= 0;
1118 pSMB
->Fid
= fid
; /* file handle always le */
1119 pSMB
->ByteCount
= 0;
1121 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1122 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1124 cFYI(1, ("Send error in QueryReparseLinkInfo = %d", rc
));
1125 } else { /* decode response */
1126 pSMBr
->DataOffset
= le16_to_cpu(pSMBr
->DataOffset
);
1127 pSMBr
->DataCount
= le16_to_cpu(pSMBr
->DataCount
);
1128 if ((pSMBr
->ByteCount
< 2) || (pSMBr
->DataOffset
> 512))
1129 /* BB also check enough total bytes returned */
1130 rc
= -EIO
; /* bad smb */
1132 if(pSMBr
->DataCount
&& (pSMBr
->DataCount
< 2048)) {
1133 /* could also validate reparse tag && better check name length */
1134 struct reparse_data
* reparse_buf
= (struct reparse_data
*)
1135 ((char *)&pSMBr
->hdr
.Protocol
+ pSMBr
->DataOffset
);
1136 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1137 name_len
= UniStrnlen((wchar_t *)
1138 (reparse_buf
->LinkNamesBuf
+
1139 reparse_buf
->TargetNameOffset
),
1140 min(buflen
/2, reparse_buf
->TargetNameLen
/ 2));
1141 cifs_strfromUCS_le(symlinkinfo
,
1142 (wchar_t *) (reparse_buf
->LinkNamesBuf
+
1143 reparse_buf
->TargetNameOffset
),
1144 name_len
, nls_codepage
);
1145 } else { /* ASCII names */
1146 strncpy(symlinkinfo
,reparse_buf
->LinkNamesBuf
+
1147 reparse_buf
->TargetNameOffset
,
1148 min_t(const int, buflen
, reparse_buf
->TargetNameLen
));
1152 cFYI(1,("Invalid return data count on get reparse info ioctl"));
1154 symlinkinfo
[buflen
] = 0; /* just in case so the caller
1155 does not go off the end of the buffer */
1156 cFYI(1,("readlink result - %s ",symlinkinfo
));
1165 CIFSSMBQPathInfo(const int xid
, struct cifsTconInfo
*tcon
,
1166 const unsigned char *searchName
,
1167 FILE_ALL_INFO
* pFindData
,
1168 const struct nls_table
*nls_codepage
)
1170 /* level 263 SMB_QUERY_FILE_ALL_INFO */
1171 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
1172 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
1177 cFYI(1, ("In QPathInfo path %s", searchName
));
1178 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1183 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1185 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, searchName
, 530
1186 /* find define for this maxpathcomponent */
1188 name_len
++; /* trailing null */
1190 } else { /* BB improve the check for buffer overruns BB */
1191 name_len
= strnlen(searchName
, 530);
1192 name_len
++; /* trailing null */
1193 strncpy(pSMB
->FileName
, searchName
, name_len
);
1196 pSMB
->TotalParameterCount
= 2 /* level */ + 4 /* reserved */ +
1197 name_len
/* includes null */ ;
1198 pSMB
->TotalDataCount
= 0;
1199 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1200 pSMB
->MaxDataCount
= cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
1201 pSMB
->MaxSetupCount
= 0;
1205 pSMB
->Reserved2
= 0;
1206 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
1207 struct smb_com_transaction2_qpi_req
,InformationLevel
) - 4);
1208 pSMB
->DataCount
= 0;
1209 pSMB
->DataOffset
= 0;
1210 pSMB
->SetupCount
= 1;
1211 pSMB
->Reserved3
= 0;
1212 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
1213 pSMB
->ByteCount
= pSMB
->TotalParameterCount
+ 1 /* pad */ ;
1214 pSMB
->TotalParameterCount
= cpu_to_le16(pSMB
->TotalParameterCount
);
1215 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1216 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_ALL_INFO
);
1217 pSMB
->Reserved4
= 0;
1218 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
1219 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
1221 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1222 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1224 cFYI(1, ("Send error in QPathInfo = %d", rc
));
1225 } else { /* decode response */
1226 pSMBr
->DataOffset
= le16_to_cpu(pSMBr
->DataOffset
);
1227 /* BB also check enough total bytes returned */
1228 if ((pSMBr
->ByteCount
< 40) || (pSMBr
->DataOffset
> 512))
1229 rc
= -EIO
; /* bad smb */
1231 memcpy((char *) pFindData
,
1232 (char *) &pSMBr
->hdr
.Protocol
+
1233 pSMBr
->DataOffset
, sizeof (FILE_ALL_INFO
));
1242 CIFSSMBUnixQPathInfo(const int xid
, struct cifsTconInfo
*tcon
,
1243 const unsigned char *searchName
,
1244 FILE_UNIX_BASIC_INFO
* pFindData
,
1245 const struct nls_table
*nls_codepage
)
1247 /* SMB_QUERY_FILE_UNIX_BASIC */
1248 TRANSACTION2_QPI_REQ
*pSMB
= NULL
;
1249 TRANSACTION2_QPI_RSP
*pSMBr
= NULL
;
1254 cFYI(1, ("In QPathInfo (Unix) the path %s", searchName
));
1255 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1260 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1262 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, searchName
, 530
1263 /* find define for this maxpathcomponent */
1265 name_len
++; /* trailing null */
1267 } else { /* BB improve the check for buffer overruns BB */
1268 name_len
= strnlen(searchName
, 530);
1269 name_len
++; /* trailing null */
1270 strncpy(pSMB
->FileName
, searchName
, name_len
);
1273 pSMB
->TotalParameterCount
= 2 /* level */ + 4 /* reserved */ +
1274 name_len
/* includes null */ ;
1275 pSMB
->TotalDataCount
= 0;
1276 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1277 /* BB find exact max SMB PDU from sess structure BB */
1278 pSMB
->MaxDataCount
= cpu_to_le16(4000);
1279 pSMB
->MaxSetupCount
= 0;
1283 pSMB
->Reserved2
= 0;
1284 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
1285 struct smb_com_transaction2_qpi_req
,InformationLevel
) - 4);
1286 pSMB
->DataCount
= 0;
1287 pSMB
->DataOffset
= 0;
1288 pSMB
->SetupCount
= 1;
1289 pSMB
->Reserved3
= 0;
1290 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_PATH_INFORMATION
);
1291 pSMB
->ByteCount
= pSMB
->TotalParameterCount
+ 1 /* pad */ ;
1292 pSMB
->TotalParameterCount
= cpu_to_le16(pSMB
->TotalParameterCount
);
1293 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1294 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC
);
1295 pSMB
->Reserved4
= 0;
1296 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
1297 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
1299 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1300 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1302 cFYI(1, ("Send error in QPathInfo = %d", rc
));
1303 } else { /* decode response */
1304 pSMBr
->DataOffset
= le16_to_cpu(pSMBr
->DataOffset
);
1305 /* BB also check if enough total bytes returned */
1306 if ((pSMBr
->ByteCount
< 40) || (pSMBr
->DataOffset
> 512))
1307 rc
= -EIO
; /* bad smb */
1309 memcpy((char *) pFindData
,
1310 (char *) &pSMBr
->hdr
.Protocol
+
1312 sizeof (FILE_UNIX_BASIC_INFO
));
1321 CIFSFindSingle(const int xid
, struct cifsTconInfo
*tcon
,
1322 const char *searchName
, FILE_ALL_INFO
* findData
,
1323 const struct nls_table
*nls_codepage
)
1325 /* level 257 SMB_ */
1326 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
1327 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
1332 cFYI(1, ("In FindUnique"));
1333 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1338 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1340 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, searchName
, 530
1341 /* find define for this maxpathcomponent */
1343 name_len
++; /* trailing null */
1345 } else { /* BB improve the check for buffer overruns BB */
1346 name_len
= strnlen(searchName
, 530);
1347 name_len
++; /* trailing null */
1348 strncpy(pSMB
->FileName
, searchName
, name_len
);
1351 pSMB
->TotalParameterCount
= 12 + name_len
/* includes null */ ;
1352 pSMB
->TotalDataCount
= 0; /* no EAs */
1353 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1354 pSMB
->MaxDataCount
= cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
1355 pSMB
->MaxSetupCount
= 0;
1359 pSMB
->Reserved2
= 0;
1360 pSMB
->ParameterOffset
= cpu_to_le16(
1361 offsetof(struct smb_com_transaction2_ffirst_req
,InformationLevel
) - 4);
1362 pSMB
->DataCount
= 0;
1363 pSMB
->DataOffset
= 0;
1364 pSMB
->SetupCount
= 1; /* one byte, no need to le convert */
1365 pSMB
->Reserved3
= 0;
1366 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
1367 pSMB
->ByteCount
= pSMB
->TotalParameterCount
+ 1 /* pad */ ;
1368 pSMB
->TotalParameterCount
= cpu_to_le16(pSMB
->TotalDataCount
);
1369 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1370 pSMB
->SearchAttributes
=
1371 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
1373 pSMB
->SearchCount
= cpu_to_le16(16); /* BB increase */
1374 pSMB
->SearchFlags
= cpu_to_le16(1);
1375 pSMB
->InformationLevel
= cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO
);
1376 pSMB
->SearchStorageType
= 0; /* BB what should we set this to? BB */
1377 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
1378 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
1380 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1381 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1384 cFYI(1, ("Send error in FindFileDirInfo = %d", rc
));
1385 } else { /* decode response */
1395 CIFSFindFirst(const int xid
, struct cifsTconInfo
*tcon
,
1396 const char *searchName
, FILE_DIRECTORY_INFO
* findData
,
1397 T2_FFIRST_RSP_PARMS
* findParms
,
1398 const struct nls_table
*nls_codepage
, int *pUnicodeFlag
,
1401 /* level 257 SMB_ */
1402 TRANSACTION2_FFIRST_REQ
*pSMB
= NULL
;
1403 TRANSACTION2_FFIRST_RSP
*pSMBr
= NULL
;
1404 char *response_data
;
1409 cFYI(1, ("In FindFirst"));
1410 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1415 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1417 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, searchName
, 530
1418 /* find define for this maxpathcomponent */
1420 name_len
++; /* trailing null */
1422 } else { /* BB improve the check for buffer overruns BB */
1423 name_len
= strnlen(searchName
, 530);
1424 name_len
++; /* trailing null */
1425 strncpy(pSMB
->FileName
, searchName
, name_len
);
1428 pSMB
->TotalParameterCount
= 12 + name_len
/* includes null */ ;
1429 pSMB
->TotalDataCount
= 0; /* no EAs */
1430 pSMB
->MaxParameterCount
= cpu_to_le16(10);
1431 pSMB
->MaxDataCount
= cpu_to_le16((tcon
->ses
->server
->maxBuf
-
1432 MAX_CIFS_HDR_SIZE
) & 0xFFFFFF00);
1433 pSMB
->MaxSetupCount
= 0;
1437 pSMB
->Reserved2
= 0;
1438 pSMB
->ByteCount
= pSMB
->TotalParameterCount
+ 1 /* pad */ ;
1439 pSMB
->TotalParameterCount
= cpu_to_le16(pSMB
->TotalParameterCount
);
1440 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1441 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
1442 smb_com_transaction2_ffirst_req
, SearchAttributes
) - 4);
1443 pSMB
->DataCount
= 0;
1444 pSMB
->DataOffset
= 0;
1445 pSMB
->SetupCount
= 1; /* one byte no need to make endian neutral */
1446 pSMB
->Reserved3
= 0;
1447 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_FIRST
);
1448 pSMB
->SearchAttributes
=
1449 cpu_to_le16(ATTR_READONLY
| ATTR_HIDDEN
| ATTR_SYSTEM
|
1451 pSMB
->SearchCount
= cpu_to_le16(CIFS_MAX_MSGSIZE
/ sizeof (FILE_DIRECTORY_INFO
)); /* should this be shrunk even more ? */
1452 pSMB
->SearchFlags
= cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END
| CIFS_SEARCH_RETURN_RESUME
);
1454 /* test for Unix extensions */
1455 if (tcon
->ses
->capabilities
& CAP_UNIX
) {
1456 pSMB
->InformationLevel
= cpu_to_le16(SMB_FIND_FILE_UNIX
);
1459 pSMB
->InformationLevel
=
1460 cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO
);
1463 pSMB
->SearchStorageType
= 0; /* BB what should we set this to? It is not clear if it matters BB */
1464 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
1465 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
1467 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1468 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1470 if (rc
) { /* BB add logic to retry regular search if Unix search rejected unexpectedly by server */
1471 cFYI(1, ("Error in FindFirst = %d", rc
));
1472 } else { /* decode response */
1473 /* BB add safety checks for these memcpys */
1474 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
1475 *pUnicodeFlag
= TRUE
;
1477 *pUnicodeFlag
= FALSE
;
1479 (char *) &pSMBr
->hdr
.Protocol
+
1480 le16_to_cpu(pSMBr
->ParameterOffset
),
1481 sizeof (T2_FFIRST_RSP_PARMS
));
1482 /* search handle can stay LE and EAoffset not needed so not converted */
1483 findParms
->EndofSearch
= le16_to_cpu(findParms
->EndofSearch
);
1484 findParms
->LastNameOffset
=
1485 le16_to_cpu(findParms
->LastNameOffset
);
1486 findParms
->SearchCount
= le16_to_cpu(findParms
->SearchCount
);
1488 (char *) &pSMBr
->hdr
.Protocol
+
1489 le16_to_cpu(pSMBr
->DataOffset
);
1490 memcpy(findData
, response_data
, le16_to_cpu(pSMBr
->DataCount
));
1498 CIFSFindNext(const int xid
, struct cifsTconInfo
*tcon
,
1499 FILE_DIRECTORY_INFO
* findData
, T2_FNEXT_RSP_PARMS
* findParms
,
1500 const __u16 searchHandle
, char * resume_file_name
, int name_len
,
1501 __u32 resume_key
, int *pUnicodeFlag
, int *pUnixFlag
)
1503 /* level 257 SMB_ */
1504 TRANSACTION2_FNEXT_REQ
*pSMB
= NULL
;
1505 TRANSACTION2_FNEXT_RSP
*pSMBr
= NULL
;
1506 char *response_data
;
1510 cFYI(1, ("In FindNext"));
1511 if(resume_file_name
== NULL
) {
1514 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1519 pSMB
->TotalParameterCount
= 14; /* includes 2 bytes of null string, converted to LE below */
1520 pSMB
->TotalDataCount
= 0; /* no EAs */
1521 pSMB
->MaxParameterCount
= cpu_to_le16(8);
1522 pSMB
->MaxDataCount
=
1523 cpu_to_le16((tcon
->ses
->server
->maxBuf
- MAX_CIFS_HDR_SIZE
) & 0xFFFFFF00);
1524 pSMB
->MaxSetupCount
= 0;
1528 pSMB
->Reserved2
= 0;
1529 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
1530 struct smb_com_transaction2_fnext_req
,SearchHandle
) - 4);
1531 pSMB
->DataCount
= 0;
1532 pSMB
->DataOffset
= 0;
1533 pSMB
->SetupCount
= 1;
1534 pSMB
->Reserved3
= 0;
1535 pSMB
->SubCommand
= cpu_to_le16(TRANS2_FIND_NEXT
);
1536 pSMB
->SearchHandle
= searchHandle
; /* always kept as le */
1537 findParms
->SearchCount
= 0; /* set to zero in case of error */
1539 cpu_to_le16(CIFS_MAX_MSGSIZE
/ sizeof (FILE_DIRECTORY_INFO
));
1540 /* test for Unix extensions */
1541 if (tcon
->ses
->capabilities
& CAP_UNIX
) {
1542 pSMB
->InformationLevel
= cpu_to_le16(SMB_FIND_FILE_UNIX
);
1545 pSMB
->InformationLevel
=
1546 cpu_to_le16(SMB_FIND_FILE_DIRECTORY_INFO
);
1549 pSMB
->ResumeKey
= resume_key
;
1551 cpu_to_le16(CIFS_SEARCH_CLOSE_AT_END
| CIFS_SEARCH_RETURN_RESUME
);
1552 /* BB add check to make sure we do not cross end of smb */
1553 if(name_len
< CIFS_MAX_MSGSIZE
) {
1554 memcpy(pSMB
->ResumeFileName
, resume_file_name
, name_len
);
1555 pSMB
->ByteCount
+= name_len
;
1557 pSMB
->TotalParameterCount
+= name_len
;
1558 pSMB
->ByteCount
= pSMB
->TotalParameterCount
+ 1 /* pad */ ;
1559 pSMB
->TotalParameterCount
= cpu_to_le16(pSMB
->TotalParameterCount
);
1560 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1561 /* BB improve error handling here */
1562 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
1563 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
1565 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1566 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1570 rc
= 0; /* search probably was closed at end of search above */
1572 cFYI(1, ("FindNext returned = %d", rc
));
1573 } else { /* decode response */
1574 /* BB add safety checks for these memcpys */
1575 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
)
1576 *pUnicodeFlag
= TRUE
;
1578 *pUnicodeFlag
= FALSE
;
1580 (char *) &pSMBr
->hdr
.Protocol
+
1581 le16_to_cpu(pSMBr
->ParameterOffset
),
1582 sizeof (T2_FNEXT_RSP_PARMS
));
1583 findParms
->EndofSearch
= le16_to_cpu(findParms
->EndofSearch
);
1584 findParms
->LastNameOffset
=
1585 le16_to_cpu(findParms
->LastNameOffset
);
1586 findParms
->SearchCount
= le16_to_cpu(findParms
->SearchCount
);
1588 (char *) &pSMBr
->hdr
.Protocol
+
1589 le16_to_cpu(pSMBr
->DataOffset
);
1590 memcpy(findData
, response_data
, le16_to_cpu(pSMBr
->DataCount
));
1598 CIFSFindClose(const int xid
, struct cifsTconInfo
*tcon
, const __u16 searchHandle
)
1601 FINDCLOSE_REQ
*pSMB
= NULL
;
1602 CLOSE_RSP
*pSMBr
= NULL
;
1604 cFYI(1, ("In CIFSSMBFindClose"));
1606 rc
= smb_init(SMB_COM_FIND_CLOSE2
, 1, tcon
, (void **) &pSMB
,
1611 pSMB
->FileID
= searchHandle
;
1612 pSMB
->ByteCount
= 0;
1613 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1614 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1616 cERROR(1, ("Send error in FindClose = %d", rc
));
1625 CIFSGetDFSRefer(const int xid
, struct cifsSesInfo
*ses
,
1626 const unsigned char *searchName
,
1627 unsigned char **targetUNCs
,
1628 unsigned int *number_of_UNC_in_array
,
1629 const struct nls_table
*nls_codepage
)
1631 /* TRANS2_GET_DFS_REFERRAL */
1632 TRANSACTION2_GET_DFS_REFER_REQ
*pSMB
= NULL
;
1633 TRANSACTION2_GET_DFS_REFER_RSP
*pSMBr
= NULL
;
1634 struct dfs_referral_level_3
* referrals
= NULL
;
1640 *number_of_UNC_in_array
= 0;
1643 cFYI(1, ("In GetDFSRefer the path %s", searchName
));
1647 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, 0, (void **) &pSMB
,
1652 pSMB
->hdr
.Tid
= ses
->ipc_tid
;
1653 pSMB
->hdr
.Uid
= ses
->Suid
;
1654 if (ses
->capabilities
& CAP_STATUS32
) {
1655 pSMB
->hdr
.Flags2
|= SMBFLG2_ERR_STATUS
;
1657 if (ses
->capabilities
& CAP_DFS
) {
1658 pSMB
->hdr
.Flags2
|= SMBFLG2_DFS
;
1661 if (ses
->capabilities
& CAP_UNICODE
) {
1662 pSMB
->hdr
.Flags2
|= SMBFLG2_UNICODE
;
1664 cifs_strtoUCS((wchar_t *) pSMB
->RequestFileName
,
1666 /* find define for this maxpathcomponent */
1668 name_len
++; /* trailing null */
1670 } else { /* BB improve the check for buffer overruns BB */
1671 name_len
= strnlen(searchName
, 530);
1672 name_len
++; /* trailing null */
1673 strncpy(pSMB
->RequestFileName
, searchName
, name_len
);
1676 pSMB
->ParameterCount
= 2 /* level */ + name_len
/*includes null */ ;
1677 pSMB
->TotalDataCount
= 0;
1678 pSMB
->DataCount
= 0;
1679 pSMB
->DataOffset
= 0;
1680 pSMB
->MaxParameterCount
= 0;
1681 pSMB
->MaxDataCount
= cpu_to_le16(4000); /* BB find exact max SMB PDU from sess structure BB */
1682 pSMB
->MaxSetupCount
= 0;
1686 pSMB
->Reserved2
= 0;
1687 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
1688 struct smb_com_transaction2_get_dfs_refer_req
, MaxReferralLevel
) - 4);
1689 pSMB
->SetupCount
= 1;
1690 pSMB
->Reserved3
= 0;
1691 pSMB
->SubCommand
= cpu_to_le16(TRANS2_GET_DFS_REFERRAL
);
1692 pSMB
->ByteCount
= pSMB
->ParameterCount
+ 3 /* pad */ ;
1693 pSMB
->ParameterCount
= cpu_to_le16(pSMB
->ParameterCount
);
1694 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
1695 pSMB
->MaxReferralLevel
= cpu_to_le16(3);
1696 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
1697 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
1699 rc
= SendReceive(xid
, ses
, (struct smb_hdr
*) pSMB
,
1700 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1702 cFYI(1, ("Send error in GetDFSRefer = %d", rc
));
1703 } else { /* decode response */
1704 /* BB Add logic to parse referrals here */
1705 pSMBr
->DataOffset
= le16_to_cpu(pSMBr
->DataOffset
);
1706 pSMBr
->DataCount
= le16_to_cpu(pSMBr
->DataCount
);
1708 ("Decoding GetDFSRefer response. BCC: %d Offset %d",
1709 pSMBr
->ByteCount
, pSMBr
->DataOffset
));
1710 if ((pSMBr
->ByteCount
< 17) || (pSMBr
->DataOffset
> 512)) /* BB also check enough total bytes returned */
1711 rc
= -EIO
; /* bad smb */
1714 (struct dfs_referral_level_3
*)
1715 (8 /* sizeof start of data block */ +
1717 (char *) &pSMBr
->hdr
.Protocol
);
1718 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
));
1719 /* BB This field is actually two bytes in from start of
1720 data block so we could do safety check that DataBlock
1721 begins at address of pSMBr->NumberOfReferrals */
1722 *number_of_UNC_in_array
= le16_to_cpu(pSMBr
->NumberOfReferrals
);
1724 /* BB Fix below so can return more than one referral */
1725 if(*number_of_UNC_in_array
> 1)
1726 *number_of_UNC_in_array
= 1;
1728 /* get the length of the strings describing refs */
1730 for(i
=0;i
<*number_of_UNC_in_array
;i
++) {
1731 /* make sure that DfsPathOffset not past end */
1732 referrals
->DfsPathOffset
= le16_to_cpu(referrals
->DfsPathOffset
);
1733 if(referrals
->DfsPathOffset
> pSMBr
->DataCount
) {
1734 /* if invalid referral, stop here and do
1735 not try to copy any more */
1736 *number_of_UNC_in_array
= i
;
1739 temp
= ((char *)referrals
) + referrals
->DfsPathOffset
;
1741 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1742 name_len
+= UniStrnlen((wchar_t *)temp
,pSMBr
->DataCount
);
1744 name_len
+= strnlen(temp
,pSMBr
->DataCount
);
1747 /* BB add check that referral pointer does not fall off end PDU */
1750 /* BB add check for name_len bigger than bcc */
1752 kmalloc(name_len
+1+ (*number_of_UNC_in_array
),GFP_KERNEL
);
1753 /* copy the ref strings */
1755 (struct dfs_referral_level_3
*)
1756 (8 /* sizeof data hdr */ +
1758 (char *) &pSMBr
->hdr
.Protocol
);
1760 for(i
=0;i
<*number_of_UNC_in_array
;i
++) {
1761 temp
= ((char *)referrals
) + referrals
->DfsPathOffset
;
1762 if (pSMBr
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
1763 cifs_strfromUCS_le(*targetUNCs
,
1764 (wchar_t *) temp
, name_len
, nls_codepage
);
1766 strncpy(*targetUNCs
,temp
,name_len
);
1768 /* BB update target_uncs pointers */
1782 CIFSSMBQFSInfo(const int xid
, struct cifsTconInfo
*tcon
,
1783 struct kstatfs
*FSData
, const struct nls_table
*nls_codepage
)
1785 /* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
1786 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
1787 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
1788 FILE_SYSTEM_INFO
*response_data
;
1790 int bytes_returned
= 0;
1792 cFYI(1, ("In QFSInfo"));
1794 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1799 pSMB
->TotalParameterCount
= 2; /* level */
1800 pSMB
->TotalDataCount
= 0;
1801 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1802 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
1803 pSMB
->MaxSetupCount
= 0;
1807 pSMB
->Reserved2
= 0;
1808 pSMB
->ByteCount
= pSMB
->TotalParameterCount
+ 1 /* pad */ ;
1809 pSMB
->TotalParameterCount
= cpu_to_le16(pSMB
->TotalParameterCount
);
1810 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1811 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
1812 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
1813 pSMB
->DataCount
= 0;
1814 pSMB
->DataOffset
= 0;
1815 pSMB
->SetupCount
= 1;
1816 pSMB
->Reserved3
= 0;
1817 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
1818 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_SIZE_INFO
);
1819 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
1820 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
1822 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1823 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1825 cERROR(1, ("Send error in QFSInfo = %d", rc
));
1826 } else { /* decode response */
1827 pSMBr
->DataOffset
= le16_to_cpu(pSMBr
->DataOffset
);
1829 ("Decoding qfsinfo response. BCC: %d Offset %d",
1830 pSMBr
->ByteCount
, pSMBr
->DataOffset
));
1831 if ((pSMBr
->ByteCount
< 24) || (pSMBr
->DataOffset
> 512)) /* BB also check enough total bytes returned */
1832 rc
= -EIO
; /* bad smb */
1836 *) (((char *) &pSMBr
->hdr
.Protocol
) +
1839 le32_to_cpu(response_data
->BytesPerSector
) *
1840 le32_to_cpu(response_data
->
1841 SectorsPerAllocationUnit
);
1843 le64_to_cpu(response_data
->TotalAllocationUnits
);
1844 FSData
->f_bfree
= FSData
->f_bavail
=
1845 le64_to_cpu(response_data
->FreeAllocationUnits
);
1847 ("Blocks: %lld Free: %lld Block size %ld",
1848 (unsigned long long)FSData
->f_blocks
,
1849 (unsigned long long)FSData
->f_bfree
,
1859 CIFSSMBQFSAttributeInfo(int xid
, struct cifsTconInfo
*tcon
,
1860 const struct nls_table
*nls_codepage
)
1862 /* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
1863 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
1864 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
1865 FILE_SYSTEM_ATTRIBUTE_INFO
*response_data
;
1867 int bytes_returned
= 0;
1869 cFYI(1, ("In QFSAttributeInfo"));
1870 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1875 pSMB
->TotalParameterCount
= 2; /* level */
1876 pSMB
->TotalDataCount
= 0;
1877 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1878 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
1879 pSMB
->MaxSetupCount
= 0;
1883 pSMB
->Reserved2
= 0;
1884 pSMB
->ByteCount
= pSMB
->TotalParameterCount
+ 1 /* pad */ ;
1885 pSMB
->TotalParameterCount
= cpu_to_le16(pSMB
->TotalParameterCount
);
1886 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1887 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
1888 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
1889 pSMB
->DataCount
= 0;
1890 pSMB
->DataOffset
= 0;
1891 pSMB
->SetupCount
= 1;
1892 pSMB
->Reserved3
= 0;
1893 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
1894 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_ATTRIBUTE_INFO
);
1895 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
1896 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
1898 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1899 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1901 cERROR(1, ("Send error in QFSAttributeInfo = %d", rc
));
1902 } else { /* decode response */
1903 pSMBr
->DataOffset
= le16_to_cpu(pSMBr
->DataOffset
);
1904 if ((pSMBr
->ByteCount
< 13) || (pSMBr
->DataOffset
> 512)) { /* BB also check enough bytes returned */
1905 rc
= -EIO
; /* bad smb */
1908 (FILE_SYSTEM_ATTRIBUTE_INFO
1909 *) (((char *) &pSMBr
->hdr
.Protocol
) +
1911 memcpy(&tcon
->fsAttrInfo
, response_data
,
1912 sizeof (FILE_SYSTEM_ATTRIBUTE_INFO
));
1921 CIFSSMBQFSDeviceInfo(int xid
, struct cifsTconInfo
*tcon
,
1922 const struct nls_table
*nls_codepage
)
1924 /* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
1925 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
1926 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
1927 FILE_SYSTEM_DEVICE_INFO
*response_data
;
1929 int bytes_returned
= 0;
1931 cFYI(1, ("In QFSDeviceInfo"));
1933 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
1938 pSMB
->TotalParameterCount
= 2; /* level */
1939 pSMB
->TotalDataCount
= 0;
1940 pSMB
->MaxParameterCount
= cpu_to_le16(2);
1941 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
1942 pSMB
->MaxSetupCount
= 0;
1946 pSMB
->Reserved2
= 0;
1947 pSMB
->ByteCount
= pSMB
->TotalParameterCount
+ 1 /* pad */ ;
1948 pSMB
->TotalParameterCount
= cpu_to_le16(pSMB
->TotalParameterCount
);
1949 pSMB
->ParameterCount
= pSMB
->TotalParameterCount
;
1950 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(
1951 struct smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
1953 pSMB
->DataCount
= 0;
1954 pSMB
->DataOffset
= 0;
1955 pSMB
->SetupCount
= 1;
1956 pSMB
->Reserved3
= 0;
1957 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
1958 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_FS_DEVICE_INFO
);
1959 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
1960 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
1962 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
1963 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
1965 cERROR(1, ("Send error in QFSDeviceInfo = %d", rc
));
1966 } else { /* decode response */
1967 pSMBr
->DataOffset
= le16_to_cpu(pSMBr
->DataOffset
);
1968 if ((pSMBr
->ByteCount
< sizeof (FILE_SYSTEM_DEVICE_INFO
))
1969 || (pSMBr
->DataOffset
> 512))
1970 rc
= -EIO
; /* bad smb */
1973 (FILE_SYSTEM_DEVICE_INFO
1974 *) (((char *) &pSMBr
->hdr
.Protocol
) +
1976 memcpy(&tcon
->fsDevInfo
, response_data
,
1977 sizeof (FILE_SYSTEM_DEVICE_INFO
));
1986 CIFSSMBQFSUnixInfo(int xid
, struct cifsTconInfo
*tcon
,
1987 const struct nls_table
*nls_codepage
)
1989 /* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
1990 TRANSACTION2_QFSI_REQ
*pSMB
= NULL
;
1991 TRANSACTION2_QFSI_RSP
*pSMBr
= NULL
;
1992 FILE_SYSTEM_UNIX_INFO
*response_data
;
1994 int bytes_returned
= 0;
1996 cFYI(1, ("In QFSUnixInfo"));
1997 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2002 pSMB
->ParameterCount
= 2; /* level */
2003 pSMB
->TotalDataCount
= 0;
2004 pSMB
->DataCount
= 0;
2005 pSMB
->DataOffset
= 0;
2006 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2007 pSMB
->MaxDataCount
= cpu_to_le16(100); /* BB find exact max SMB PDU from sess structure BB */
2008 pSMB
->MaxSetupCount
= 0;
2012 pSMB
->Reserved2
= 0;
2013 pSMB
->ByteCount
= pSMB
->ParameterCount
+ 1 /* pad */ ;
2014 pSMB
->ParameterCount
= cpu_to_le16(pSMB
->ParameterCount
);
2015 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2016 pSMB
->ParameterOffset
= cpu_to_le16(offsetof(struct
2017 smb_com_transaction2_qfsi_req
, InformationLevel
) - 4);
2018 pSMB
->SetupCount
= 1;
2019 pSMB
->Reserved3
= 0;
2020 pSMB
->SubCommand
= cpu_to_le16(TRANS2_QUERY_FS_INFORMATION
);
2021 pSMB
->InformationLevel
= cpu_to_le16(SMB_QUERY_CIFS_UNIX_INFO
);
2022 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
2023 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
2025 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2026 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2028 cERROR(1, ("Send error in QFSUnixInfo = %d", rc
));
2029 } else { /* decode response */
2030 pSMBr
->DataOffset
= cpu_to_le16(pSMBr
->DataOffset
);
2031 if ((pSMBr
->ByteCount
< 13) || (pSMBr
->DataOffset
> 512)) {
2032 rc
= -EIO
; /* bad smb */
2035 (FILE_SYSTEM_UNIX_INFO
2036 *) (((char *) &pSMBr
->hdr
.Protocol
) +
2038 memcpy(&tcon
->fsUnixInfo
, response_data
,
2039 sizeof (FILE_SYSTEM_UNIX_INFO
));
2047 /* We can not use write of zero bytes trick to
2048 set file size due to need for large file support. Also note that
2049 this SetPathInfo is preferred to SetFileInfo based method in next
2050 routine which is only needed to work around a sharing violation bug
2051 in Samba which this routine can run into */
2054 CIFSSMBSetEOF(int xid
, struct cifsTconInfo
*tcon
, char *fileName
,
2055 __u64 size
, int SetAllocation
, const struct nls_table
*nls_codepage
)
2057 struct smb_com_transaction2_spi_req
*pSMB
= NULL
;
2058 struct smb_com_transaction2_spi_rsp
*pSMBr
= NULL
;
2059 struct file_end_of_file_info
*parm_data
;
2062 int bytes_returned
= 0;
2064 cFYI(1, ("In SetEOF"));
2066 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2071 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2073 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, fileName
, 530
2074 /* find define for this maxpathcomponent */
2076 name_len
++; /* trailing null */
2078 } else { /* BB improve the check for buffer overruns BB */
2079 name_len
= strnlen(fileName
, 530);
2080 name_len
++; /* trailing null */
2081 strncpy(pSMB
->FileName
, fileName
, name_len
);
2083 pSMB
->ParameterCount
= 6 + name_len
;
2084 pSMB
->DataCount
= sizeof (struct file_end_of_file_info
);
2085 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2086 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB size from sess */
2087 pSMB
->MaxSetupCount
= 0;
2091 pSMB
->Reserved2
= 0;
2092 pSMB
->ParameterOffset
= offsetof(struct smb_com_transaction2_spi_req
,
2093 InformationLevel
) - 4;
2094 pSMB
->DataOffset
= pSMB
->ParameterOffset
+ pSMB
->ParameterCount
;
2096 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
2097 pSMB
->InformationLevel
=
2098 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
2100 pSMB
->InformationLevel
=
2101 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
2102 } else /* Set File Size */ {
2103 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
2104 pSMB
->InformationLevel
=
2105 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
2107 pSMB
->InformationLevel
=
2108 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
2112 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
2114 pSMB
->ParameterOffset
= cpu_to_le16(pSMB
->ParameterOffset
);
2115 pSMB
->DataOffset
= cpu_to_le16(pSMB
->DataOffset
);
2116 pSMB
->SetupCount
= 1;
2117 pSMB
->Reserved3
= 0;
2118 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2119 pSMB
->ByteCount
= 3 /* pad */ + pSMB
->ParameterCount
+ pSMB
->DataCount
;
2120 pSMB
->DataCount
= cpu_to_le16(pSMB
->DataCount
);
2121 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2122 pSMB
->ParameterCount
= cpu_to_le16(pSMB
->ParameterCount
);
2123 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2124 pSMB
->Reserved4
= 0;
2125 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
2126 parm_data
->FileSize
= cpu_to_le64(size
);
2127 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
2128 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2129 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2131 cFYI(1, ("SetPathInfo (file size) returned %d", rc
));
2140 CIFSSMBSetFileSize(const int xid
, struct cifsTconInfo
*tcon
, __u64 size
,
2141 __u16 fid
, __u32 pid_of_opener
, int SetAllocation
)
2143 struct smb_com_transaction2_sfi_req
*pSMB
= NULL
;
2144 struct smb_com_transaction2_sfi_rsp
*pSMBr
= NULL
;
2146 struct file_end_of_file_info
*parm_data
;
2148 int bytes_returned
= 0;
2151 cFYI(1, ("SetFileSize (via SetFileInfo)"));
2153 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2158 tmp
= cpu_to_le32(pid_of_opener
); /* override pid of current process
2159 so network fid will be valid */
2160 pSMB
->hdr
.Pid
= tmp
& 0xFFFF;
2162 pSMB
->hdr
.PidHigh
= tmp
& 0xFFFF;
2164 pSMB
->ParameterCount
= 6;
2165 pSMB
->MaxSetupCount
= 0;
2169 pSMB
->Reserved2
= 0;
2170 pSMB
->ParameterOffset
= offsetof(struct smb_com_transaction2_sfi_req
,
2172 pSMB
->DataOffset
= pSMB
->ParameterOffset
+ pSMB
->ParameterCount
;
2174 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + pSMB
->DataOffset
;
2176 pSMB
->DataCount
= sizeof(struct file_end_of_file_info
);
2177 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2178 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find max SMB PDU from sess */
2179 pSMB
->SetupCount
= 1;
2180 pSMB
->Reserved3
= 0;
2181 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_FILE_INFORMATION
);
2182 pSMB
->ByteCount
= 3 /* pad */ + pSMB
->ParameterCount
+ pSMB
->DataCount
;
2183 pSMB
->DataCount
= cpu_to_le16(pSMB
->DataCount
);
2184 pSMB
->ParameterCount
= cpu_to_le16(pSMB
->ParameterCount
);
2185 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2186 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2187 pSMB
->ParameterOffset
= cpu_to_le16(pSMB
->ParameterOffset
);
2188 pSMB
->DataOffset
= cpu_to_le16(pSMB
->DataOffset
);
2190 (struct file_end_of_file_info
*) (((char *) &pSMB
->hdr
.Protocol
) +
2192 parm_data
->FileSize
= size
;
2195 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
2196 pSMB
->InformationLevel
=
2197 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO2
);
2199 pSMB
->InformationLevel
=
2200 cpu_to_le16(SMB_SET_FILE_ALLOCATION_INFO
);
2201 } else /* Set File Size */ {
2202 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
2203 pSMB
->InformationLevel
=
2204 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO2
);
2206 pSMB
->InformationLevel
=
2207 cpu_to_le16(SMB_SET_FILE_END_OF_FILE_INFO
);
2209 pSMB
->Reserved4
= 0;
2210 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
2211 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
2212 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2213 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2216 ("Send error in SetFileInfo (SetFileSize) = %d",
2226 CIFSSMBSetTimes(int xid
, struct cifsTconInfo
*tcon
, char *fileName
,
2227 FILE_BASIC_INFO
* data
, const struct nls_table
*nls_codepage
)
2229 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2230 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2233 int bytes_returned
= 0;
2236 cFYI(1, ("In SetTimes"));
2238 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2243 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2245 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, fileName
, 530
2246 /* find define for this maxpathcomponent */
2248 name_len
++; /* trailing null */
2250 } else { /* BB improve the check for buffer overruns BB */
2251 name_len
= strnlen(fileName
, 530);
2252 name_len
++; /* trailing null */
2253 strncpy(pSMB
->FileName
, fileName
, name_len
);
2256 pSMB
->ParameterCount
= 6 + name_len
;
2257 pSMB
->DataCount
= sizeof (FILE_BASIC_INFO
);
2258 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2259 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
2260 pSMB
->MaxSetupCount
= 0;
2264 pSMB
->Reserved2
= 0;
2265 pSMB
->ParameterOffset
= offsetof(struct smb_com_transaction2_spi_req
,
2266 InformationLevel
) - 4;
2267 pSMB
->DataOffset
= pSMB
->ParameterOffset
+ pSMB
->ParameterCount
;
2268 data_offset
= (char *) (&pSMB
->hdr
.Protocol
) + pSMB
->DataOffset
;
2269 pSMB
->ParameterOffset
= cpu_to_le16(pSMB
->ParameterOffset
);
2270 pSMB
->DataOffset
= cpu_to_le16(pSMB
->DataOffset
);
2271 pSMB
->SetupCount
= 1;
2272 pSMB
->Reserved3
= 0;
2273 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2274 pSMB
->ByteCount
= 3 /* pad */ + pSMB
->ParameterCount
+ pSMB
->DataCount
;
2276 pSMB
->DataCount
= cpu_to_le16(pSMB
->DataCount
);
2277 pSMB
->ParameterCount
= cpu_to_le16(pSMB
->ParameterCount
);
2278 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2279 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2280 if (tcon
->ses
->capabilities
& CAP_INFOLEVEL_PASSTHRU
)
2281 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO2
);
2283 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_BASIC_INFO
);
2284 pSMB
->Reserved4
= 0;
2285 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
2286 memcpy(data_offset
, data
, sizeof (FILE_BASIC_INFO
));
2287 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
2288 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2289 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2291 cFYI(1, ("SetPathInfo (times) returned %d", rc
));
2300 CIFSSMBUnixSetPerms(const int xid
, struct cifsTconInfo
*tcon
,
2301 char *fileName
, __u64 mode
, __u64 uid
, __u64 gid
,
2302 const struct nls_table
*nls_codepage
)
2304 TRANSACTION2_SPI_REQ
*pSMB
= NULL
;
2305 TRANSACTION2_SPI_RSP
*pSMBr
= NULL
;
2308 int bytes_returned
= 0;
2309 FILE_UNIX_BASIC_INFO
*data_offset
;
2311 cFYI(1, ("In SetUID/GID/Mode"));
2313 rc
= smb_init(SMB_COM_TRANSACTION2
, 15, tcon
, (void **) &pSMB
,
2318 if (pSMB
->hdr
.Flags2
& SMBFLG2_UNICODE
) {
2320 cifs_strtoUCS((wchar_t *) pSMB
->FileName
, fileName
, 530
2321 /* find define for this maxpathcomponent */
2323 name_len
++; /* trailing null */
2325 } else { /* BB improve the check for buffer overruns BB */
2326 name_len
= strnlen(fileName
, 530);
2327 name_len
++; /* trailing null */
2328 strncpy(pSMB
->FileName
, fileName
, name_len
);
2331 pSMB
->ParameterCount
= 6 + name_len
;
2332 pSMB
->DataCount
= sizeof (FILE_UNIX_BASIC_INFO
);
2333 pSMB
->MaxParameterCount
= cpu_to_le16(2);
2334 pSMB
->MaxDataCount
= cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */
2335 pSMB
->MaxSetupCount
= 0;
2339 pSMB
->Reserved2
= 0;
2340 pSMB
->ParameterOffset
= offsetof(struct smb_com_transaction2_spi_req
,
2341 InformationLevel
) - 4;
2342 pSMB
->DataOffset
= pSMB
->ParameterOffset
+ pSMB
->ParameterCount
;
2344 (FILE_UNIX_BASIC_INFO
*) ((char *) &pSMB
->hdr
.Protocol
+
2346 pSMB
->DataOffset
= cpu_to_le16(pSMB
->DataOffset
);
2347 pSMB
->ParameterOffset
= cpu_to_le16(pSMB
->ParameterOffset
);
2348 pSMB
->SetupCount
= 1;
2349 pSMB
->Reserved3
= 0;
2350 pSMB
->SubCommand
= cpu_to_le16(TRANS2_SET_PATH_INFORMATION
);
2351 pSMB
->ByteCount
= 3 /* pad */ + pSMB
->ParameterCount
+ pSMB
->DataCount
;
2352 pSMB
->ParameterCount
= cpu_to_le16(pSMB
->ParameterCount
);
2353 pSMB
->DataCount
= cpu_to_le16(pSMB
->DataCount
);
2354 pSMB
->TotalParameterCount
= pSMB
->ParameterCount
;
2355 pSMB
->TotalDataCount
= pSMB
->DataCount
;
2356 pSMB
->InformationLevel
= cpu_to_le16(SMB_SET_FILE_UNIX_BASIC
);
2357 pSMB
->Reserved4
= 0;
2358 pSMB
->hdr
.smb_buf_length
+= pSMB
->ByteCount
;
2359 data_offset
->Uid
= cpu_to_le64(uid
);
2360 data_offset
->Gid
= cpu_to_le64(gid
);
2361 data_offset
->Permissions
= cpu_to_le64(mode
);
2362 pSMB
->ByteCount
= cpu_to_le16(pSMB
->ByteCount
);
2363 rc
= SendReceive(xid
, tcon
->ses
, (struct smb_hdr
*) pSMB
,
2364 (struct smb_hdr
*) pSMBr
, &bytes_returned
, 0);
2366 cFYI(1, ("SetPathInfo (perms) returned %d", rc
));