2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Copyright (C) Jeremy Allison 1994
7 Extensively modified by Andrew Tridgell, 1995
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program 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 the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 extern int DEBUGLEVEL
;
29 extern connection_struct Connections
[];
30 extern files_struct Files
[];
31 extern BOOL case_sensitive
;
34 /****************************************************************************
35 Send the required number of replies back.
36 We assume all fields other than the data fields are
37 set correctly for the type of call.
38 HACK ! Always assumes smb_setup field is zero.
39 ****************************************************************************/
40 static int send_trans2_replies(char *outbuf
, int bufsize
, char *params
,
41 int paramsize
, char *pdata
, int datasize
)
43 /* As we are using a protocol > LANMAN1 then the maxxmit
44 variable must have been set in the sessetupX call.
45 This takes precedence over the max_xmit field in the
46 global struct. These different max_xmit variables should
47 be merged as this is now too confusing */
50 int data_to_send
= datasize
;
51 int params_to_send
= paramsize
;
55 int params_sent_thistime
, data_sent_thistime
, total_sent_thistime
;
56 int alignment_offset
= 1;
58 /* Initially set the wcnt area to be 10 - this is true for all
60 set_message(outbuf
,10,0,True
);
62 /* If there genuinely are no parameters or data to send just send
64 if(params_to_send
== 0 && data_to_send
== 0)
66 send_smb(Client
,outbuf
);
70 /* Space is bufsize minus Netbios over TCP header minus SMB header */
71 /* The alignment_offset is to align the param and data bytes on an even byte
72 boundary. NT 4.0 Beta needs this to work correctly. */
73 useable_space
= bufsize
- ((smb_buf(outbuf
)+alignment_offset
) - outbuf
);
74 /* useable_space can never be more than maxxmit minus the
76 useable_space
= MIN(useable_space
, maxxmit
- alignment_offset
);
78 while( params_to_send
|| data_to_send
)
80 /* Calculate whether we will totally or partially fill this packet */
81 total_sent_thistime
= params_to_send
+ data_to_send
+ alignment_offset
;
82 /* We can never send more than maxxmit */
83 total_sent_thistime
= MIN(total_sent_thistime
, maxxmit
);
85 set_message(outbuf
, 10, total_sent_thistime
, True
);
87 /* Set total params and data to be sent */
88 SSVAL(outbuf
,smb_tprcnt
,paramsize
);
89 SSVAL(outbuf
,smb_tdrcnt
,datasize
);
91 /* Calculate how many parameters and data we can fit into
92 this packet. Parameters get precedence */
94 params_sent_thistime
= MIN(params_to_send
,useable_space
);
95 data_sent_thistime
= useable_space
- params_sent_thistime
;
96 data_sent_thistime
= MIN(data_sent_thistime
,data_to_send
);
98 SSVAL(outbuf
,smb_prcnt
, params_sent_thistime
);
99 if(params_sent_thistime
== 0)
101 SSVAL(outbuf
,smb_proff
,0);
102 SSVAL(outbuf
,smb_prdisp
,0);
104 /* smb_proff is the offset from the start of the SMB header to the
105 parameter bytes, however the first 4 bytes of outbuf are
106 the Netbios over TCP header. Thus use smb_base() to subtract
107 them from the calculation */
108 SSVAL(outbuf
,smb_proff
,((smb_buf(outbuf
)+alignment_offset
) - smb_base(outbuf
)));
109 /* Absolute displacement of param bytes sent in this packet */
110 SSVAL(outbuf
,smb_prdisp
,pp
- params
);
113 SSVAL(outbuf
,smb_drcnt
, data_sent_thistime
);
114 if(data_sent_thistime
== 0)
116 SSVAL(outbuf
,smb_droff
,0);
117 SSVAL(outbuf
,smb_drdisp
, 0);
119 /* The offset of the data bytes is the offset of the
120 parameter bytes plus the number of parameters being sent this time */
121 SSVAL(outbuf
,smb_droff
,((smb_buf(outbuf
)+alignment_offset
) -
122 smb_base(outbuf
)) + params_sent_thistime
);
123 SSVAL(outbuf
,smb_drdisp
, pd
- pdata
);
126 /* Copy the param bytes into the packet */
127 if(params_sent_thistime
)
128 memcpy((smb_buf(outbuf
)+alignment_offset
),pp
,params_sent_thistime
);
129 /* Copy in the data bytes */
130 if(data_sent_thistime
)
131 memcpy(smb_buf(outbuf
)+alignment_offset
+params_sent_thistime
,pd
,data_sent_thistime
);
133 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
134 params_sent_thistime
, data_sent_thistime
, useable_space
));
135 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
136 params_to_send
, data_to_send
, paramsize
, datasize
));
138 /* Send the packet */
139 send_smb(Client
,outbuf
);
141 pp
+= params_sent_thistime
;
142 pd
+= data_sent_thistime
;
144 params_to_send
-= params_sent_thistime
;
145 data_to_send
-= data_sent_thistime
;
148 if(params_to_send
< 0 || data_to_send
< 0)
150 DEBUG(2,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
151 params_to_send
, data_to_send
));
160 /****************************************************************************
161 reply to a TRANSACT2_OPEN
162 ****************************************************************************/
163 static int call_trans2open(char *inbuf
, char *outbuf
, int bufsize
, int cnum
,
164 char **pparams
, char **ppdata
)
166 char *params
= *pparams
;
167 int16 open_mode
= SVAL(params
, 2);
168 int16 open_attr
= SVAL(params
,6);
169 BOOL oplock_request
= BITSETW(params
,1);
171 BOOL return_additional_info
= BITSETW(params
,0);
172 int16 open_sattr
= SVAL(params
, 4);
173 time_t open_time
= make_unix_date3(params
+8);
175 int16 open_ofun
= SVAL(params
,12);
176 int32 open_size
= IVAL(params
,14);
177 char *pname
= ¶ms
[28];
178 int16 namelen
= strlen(pname
)+1;
183 int size
=0,fmode
=0,mtime
=0,rmode
;
188 StrnCpy(fname
,pname
,namelen
);
190 DEBUG(3,("trans2open %s cnum=%d mode=%d attr=%d ofun=%d size=%d\n",
191 fname
,cnum
,open_mode
, open_attr
, open_ofun
, open_size
));
193 /* XXXX we need to handle passed times, sattr and flags */
195 unix_convert(fname
,cnum
,0);
197 fnum
= find_free_file();
199 return(ERROR(ERRSRV
,ERRnofids
));
201 if (!check_name(fname
,cnum
))
202 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
204 unixmode
= unix_mode(cnum
,open_attr
| aARCH
);
207 open_file_shared(fnum
,cnum
,fname
,open_mode
,open_ofun
,unixmode
,
210 if (!Files
[fnum
].open
)
211 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
213 if (fstat(Files
[fnum
].fd_ptr
->fd
,&sbuf
) != 0) {
215 return(ERROR(ERRDOS
,ERRnoaccess
));
219 fmode
= dos_mode(cnum
,fname
,&sbuf
);
220 mtime
= sbuf
.st_mtime
;
224 return(ERROR(ERRDOS
,ERRnoaccess
));
227 /* Realloc the size of parameters and data we will return */
228 params
= *pparams
= Realloc(*pparams
, 28);
230 return(ERROR(ERRDOS
,ERRnomem
));
233 SSVAL(params
,0,fnum
);
234 SSVAL(params
,2,fmode
);
235 put_dos_date2(params
,4, mtime
);
236 SIVAL(params
,8, size
);
237 SSVAL(params
,12,rmode
);
239 if (oplock_request
&& lp_fake_oplocks(SNUM(cnum
))) {
240 smb_action
|= (1<<15);
243 SSVAL(params
,18,smb_action
);
244 SIVAL(params
,20,inode
);
246 /* Send the required number of replies */
247 send_trans2_replies(outbuf
, bufsize
, params
, 28, *ppdata
, 0);
252 /****************************************************************************
253 get a level dependent lanman2 dir entry.
254 ****************************************************************************/
255 static int get_lanman2_dir_entry(int cnum
,char *path_mask
,int dirtype
,int info_level
,
256 int requires_resume_key
,
257 BOOL dont_descend
,char **ppdata
,
258 char *base_data
, int space_remaining
,
269 char *p
, *pdata
= *ppdata
;
270 int reskey
=0, prev_dirpos
=0;
273 uint32 mdate
=0, adate
=0, cdate
=0;
275 BOOL isrootdir
= (strequal(Connections
[cnum
].dirpath
,"./") ||
276 strequal(Connections
[cnum
].dirpath
,".") ||
277 strequal(Connections
[cnum
].dirpath
,"/"));
281 *out_of_space
= False
;
283 if (!Connections
[cnum
].dirptr
)
286 p
= strrchr(path_mask
,'/');
295 strcpy(mask
, path_mask
);
299 /* Needed if we run out of space */
300 prev_dirpos
= TellDir(Connections
[cnum
].dirptr
);
301 dname
= ReadDirName(Connections
[cnum
].dirptr
);
303 reskey
= TellDir(Connections
[cnum
].dirptr
);
305 DEBUG(6,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
306 Connections
[cnum
].dirptr
,TellDir(Connections
[cnum
].dirptr
)));
315 if(mask_match(fname
, mask
, case_sensitive
, True
))
317 BOOL isdots
= (strequal(fname
,"..") || strequal(fname
,"."));
318 if (dont_descend
&& !isdots
)
321 if (isrootdir
&& isdots
)
324 strcpy(pathreal
,Connections
[cnum
].dirpath
);
325 strcat(pathreal
,"/");
326 strcat(pathreal
,fname
);
327 if (sys_stat(pathreal
,&sbuf
) != 0)
329 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal
,strerror(errno
)));
333 mode
= dos_mode(cnum
,pathreal
,&sbuf
);
335 if (!dir_check_ftype(cnum
,mode
,&sbuf
,dirtype
)) {
336 DEBUG(5,("[%s] attribs didn't match %x\n",fname
,dirtype
));
341 mdate
= sbuf
.st_mtime
;
342 adate
= sbuf
.st_atime
;
343 cdate
= sbuf
.st_ctime
;
347 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal
,fname
));
358 name_map_mangle(fname
,False
,SNUM(cnum
));
363 if(requires_resume_key
) {
367 put_dos_date2(p
,l1_fdateCreation
,cdate
);
368 put_dos_date2(p
,l1_fdateLastAccess
,adate
);
369 put_dos_date2(p
,l1_fdateLastWrite
,mdate
);
370 SIVAL(p
,l1_cbFile
,size
);
371 SIVAL(p
,l1_cbFileAlloc
,ROUNDUP(size
,1024));
372 SSVAL(p
,l1_attrFile
,mode
);
373 SCVAL(p
,l1_cchName
,strlen(fname
));
374 strcpy(p
+ l1_achName
, fname
);
375 nameptr
= p
+ l1_achName
;
376 p
+= l1_achName
+ strlen(fname
) + 1;
381 if(requires_resume_key
) {
385 put_dos_date2(p
,l2_fdateCreation
,cdate
);
386 put_dos_date2(p
,l2_fdateLastAccess
,adate
);
387 put_dos_date2(p
,l2_fdateLastWrite
,mdate
);
388 SIVAL(p
,l2_cbFile
,size
);
389 SIVAL(p
,l2_cbFileAlloc
,ROUNDUP(size
,1024));
390 SSVAL(p
,l2_attrFile
,mode
);
391 SIVAL(p
,l2_cbList
,0); /* No extended attributes */
392 SCVAL(p
,l2_cchName
,strlen(fname
));
393 strcpy(p
+ l2_achName
, fname
);
394 nameptr
= p
+ l2_achName
;
395 p
+= l2_achName
+ strlen(fname
) + 1;
400 put_dos_date2(p
,4,cdate
);
401 put_dos_date2(p
,8,adate
);
402 put_dos_date2(p
,12,mdate
);
404 SIVAL(p
,20,ROUNDUP(size
,1024));
407 CVAL(p
,30) = strlen(fname
);
410 p
+= 31 + strlen(fname
) + 1;
414 if(requires_resume_key
) {
418 SIVAL(p
,0,33+strlen(fname
)+1);
419 put_dos_date2(p
,4,cdate
);
420 put_dos_date2(p
,8,adate
);
421 put_dos_date2(p
,12,mdate
);
423 SIVAL(p
,20,ROUNDUP(size
,1024));
425 CVAL(p
,32) = strlen(fname
);
426 strcpy(p
+ 33, fname
);
428 p
+= 33 + strlen(fname
) + 1;
431 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
432 was_8_3
= is_8_3(fname
);
433 len
= 94+strlen(fname
);
434 len
= (len
+ 3) & ~3;
435 SIVAL(p
,0,len
); p
+= 4;
436 SIVAL(p
,0,reskey
); p
+= 4;
437 put_long_date(p
,cdate
); p
+= 8;
438 put_long_date(p
,adate
); p
+= 8;
439 put_long_date(p
,mdate
); p
+= 8;
440 put_long_date(p
,mdate
); p
+= 8;
441 SIVAL(p
,0,size
); p
+= 8;
442 SIVAL(p
,0,size
); p
+= 8;
443 SIVAL(p
,0,mode
); p
+= 4;
444 SIVAL(p
,0,strlen(fname
)); p
+= 4;
445 SIVAL(p
,0,0); p
+= 4;
448 if (!name_map_mangle(p
+2,True
,SNUM(cnum
)))
453 SSVAL(p
,0,strlen(p
+2));
456 strcpy(p
,fname
); p
+= strlen(p
);
460 case SMB_FIND_FILE_DIRECTORY_INFO
:
461 len
= 64+strlen(fname
);
462 len
= (len
+ 3) & ~3;
463 SIVAL(p
,0,len
); p
+= 4;
464 SIVAL(p
,0,reskey
); p
+= 4;
465 put_long_date(p
,cdate
); p
+= 8;
466 put_long_date(p
,adate
); p
+= 8;
467 put_long_date(p
,mdate
); p
+= 8;
468 put_long_date(p
,mdate
); p
+= 8;
469 SIVAL(p
,0,size
); p
+= 8;
470 SIVAL(p
,0,size
); p
+= 8;
471 SIVAL(p
,0,mode
); p
+= 4;
472 SIVAL(p
,0,strlen(fname
)); p
+= 4;
478 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
479 len
= 68+strlen(fname
);
480 len
= (len
+ 3) & ~3;
481 SIVAL(p
,0,len
); p
+= 4;
482 SIVAL(p
,0,reskey
); p
+= 4;
483 put_long_date(p
,cdate
); p
+= 8;
484 put_long_date(p
,adate
); p
+= 8;
485 put_long_date(p
,mdate
); p
+= 8;
486 put_long_date(p
,mdate
); p
+= 8;
487 SIVAL(p
,0,size
); p
+= 8;
488 SIVAL(p
,0,size
); p
+= 8;
489 SIVAL(p
,0,mode
); p
+= 4;
490 SIVAL(p
,0,strlen(fname
)); p
+= 4;
491 SIVAL(p
,0,0); p
+= 4;
496 case SMB_FIND_FILE_NAMES_INFO
:
497 len
= 12+strlen(fname
);
498 len
= (len
+ 3) & ~3;
499 SIVAL(p
,0,len
); p
+= 4;
500 SIVAL(p
,0,reskey
); p
+= 4;
501 SIVAL(p
,0,strlen(fname
)); p
+= 4;
511 if (PTR_DIFF(p
,pdata
) > space_remaining
) {
512 /* Move the dirptr back to prev_dirpos */
513 SeekDir(Connections
[cnum
].dirptr
, prev_dirpos
);
514 *out_of_space
= True
;
515 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
516 return False
; /* Not finished - just out of space */
519 /* Setup the last_filename pointer, as an offset from base_data */
520 *last_name_off
= PTR_DIFF(nameptr
,base_data
);
521 /* Advance the data pointer to the next slot */
526 /****************************************************************************
527 reply to a TRANS2_FINDFIRST
528 ****************************************************************************/
529 static int call_trans2findfirst(char *inbuf
, char *outbuf
, int bufsize
, int cnum
,
530 char **pparams
, char **ppdata
)
532 /* We must be careful here that we don't return more than the
533 allowed number of data bytes. If this means returning fewer than
534 maxentries then so be it. We assume that the redirector has
535 enough room for the fixed number of parameter bytes it has
537 uint32 max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
538 char *params
= *pparams
;
539 char *pdata
= *ppdata
;
540 int dirtype
= SVAL(params
,0);
541 int maxentries
= SVAL(params
,2);
542 BOOL close_after_first
= BITSETW(params
+4,0);
543 BOOL close_if_end
= BITSETW(params
+4,1);
544 BOOL requires_resume_key
= BITSETW(params
+4,2);
545 int info_level
= SVAL(params
,6);
553 BOOL finished
= False
;
554 BOOL dont_descend
= False
;
555 BOOL out_of_space
= False
;
558 *directory
= *mask
= 0;
560 DEBUG(3,("call_trans2findfirst: dirtype = %d, maxentries = %d, close_after_first=%d, close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n",
561 dirtype
, maxentries
, close_after_first
, close_if_end
, requires_resume_key
,
562 info_level
, max_data_bytes
));
570 case SMB_FIND_FILE_DIRECTORY_INFO
:
571 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
572 case SMB_FIND_FILE_NAMES_INFO
:
573 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
576 return(ERROR(ERRDOS
,ERRunknownlevel
));
579 strcpy(directory
, params
+ 12); /* Complete directory path with
580 wildcard mask appended */
582 DEBUG(5,("path=%s\n",directory
));
584 unix_convert(directory
,cnum
,0);
585 if(!check_name(directory
,cnum
)) {
586 return(ERROR(ERRDOS
,ERRbadpath
));
589 p
= strrchr(directory
,'/');
591 strcpy(mask
,directory
);
592 strcpy(directory
,"./");
598 DEBUG(5,("dir=%s, mask = %s\n",directory
, mask
));
600 pdata
= *ppdata
= Realloc(*ppdata
, max_data_bytes
+ 1024);
602 return(ERROR(ERRDOS
,ERRnomem
));
603 bzero(pdata
,max_data_bytes
);
605 /* Realloc the params space */
606 params
= *pparams
= Realloc(*pparams
, 10);
608 return(ERROR(ERRDOS
,ERRnomem
));
610 dptr_num
= dptr_create(cnum
,directory
, True
,SVAL(inbuf
,smb_pid
));
612 return(ERROR(ERRDOS
,ERRbadpath
));
614 /* convert the formatted masks */
618 if (*p
== '<') *p
= '*';
619 if (*p
== '>') *p
= '?';
620 if (*p
== '"') *p
= '.';
625 /* a special case for 16 bit apps */
626 if (strequal(mask
,"????????.???")) strcpy(mask
,"*");
628 /* handle broken clients that send us old 8.3 format */
629 string_sub(mask
,"????????","*");
630 string_sub(mask
,".???",".*");
632 /* Save the wildcard match and attribs we are using on this directory -
633 needed as lanman2 assumes these are being saved between calls */
635 if(!(wcard
= strdup(mask
))) {
636 dptr_close(dptr_num
);
637 return(ERROR(ERRDOS
,ERRnomem
));
640 dptr_set_wcard(dptr_num
, wcard
);
641 dptr_set_attr(dptr_num
, dirtype
);
643 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num
, wcard
, dirtype
));
645 /* We don't need to check for VOL here as this is returned by
646 a different TRANS2 call. */
648 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
649 Connections
[cnum
].dirpath
,lp_dontdescend(SNUM(cnum
))));
650 if (in_list(Connections
[cnum
].dirpath
,lp_dontdescend(SNUM(cnum
)),case_sensitive
))
654 space_remaining
= max_data_bytes
;
655 out_of_space
= False
;
657 for (i
=0;(i
<maxentries
) && !finished
&& !out_of_space
;i
++)
660 /* this is a heuristic to avoid seeking the dirptr except when
661 absolutely necessary. It allows for a filename of about 40 chars */
662 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0)
670 !get_lanman2_dir_entry(cnum
,mask
,dirtype
,info_level
,
671 requires_resume_key
,dont_descend
,
672 &p
,pdata
,space_remaining
, &out_of_space
,
676 if (finished
&& out_of_space
)
679 if (!finished
&& !out_of_space
)
681 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
684 /* Check if we can close the dirptr */
685 if(close_after_first
|| (finished
&& close_if_end
))
687 dptr_close(dptr_num
);
688 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num
));
692 /* At this point pdata points to numentries directory entries. */
694 /* Set up the return parameter block */
695 SSVAL(params
,0,dptr_num
);
696 SSVAL(params
,2,numentries
);
697 SSVAL(params
,4,finished
);
698 SSVAL(params
,6,0); /* Never an EA error */
699 SSVAL(params
,8,last_name_off
);
701 send_trans2_replies( outbuf
, bufsize
, params
, 10, pdata
, PTR_DIFF(p
,pdata
));
703 if ((! *directory
) && dptr_path(dptr_num
))
704 sprintf(directory
,"(%s)",dptr_path(dptr_num
));
706 DEBUG(4,("%s %s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n",
708 smb_fn_name(CVAL(inbuf
,smb_com
)),
709 mask
,directory
,cnum
,dirtype
,numentries
));
715 /****************************************************************************
716 reply to a TRANS2_FINDNEXT
717 ****************************************************************************/
718 static int call_trans2findnext(char *inbuf
, char *outbuf
, int length
, int bufsize
,
719 int cnum
, char **pparams
, char **ppdata
)
721 /* We must be careful here that we don't return more than the
722 allowed number of data bytes. If this means returning fewer than
723 maxentries then so be it. We assume that the redirector has
724 enough room for the fixed number of parameter bytes it has
726 int max_data_bytes
= SVAL(inbuf
, smb_mdrcnt
);
727 char *params
= *pparams
;
728 char *pdata
= *ppdata
;
729 int16 dptr_num
= SVAL(params
,0);
730 int maxentries
= SVAL(params
,2);
731 uint16 info_level
= SVAL(params
,4);
732 uint32 resume_key
= IVAL(params
,6);
733 BOOL close_after_request
= BITSETW(params
+10,0);
734 BOOL close_if_end
= BITSETW(params
+10,1);
735 BOOL requires_resume_key
= BITSETW(params
+10,2);
736 BOOL continue_bit
= BITSETW(params
+10,3);
742 int i
, last_name_off
=0;
743 BOOL finished
= False
;
744 BOOL dont_descend
= False
;
745 BOOL out_of_space
= False
;
748 *mask
= *directory
= 0;
750 DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, close_after_request=%d, close_if_end = %d requires_resume_key = %d resume_key = %d continue=%d level = %d\n",
751 dptr_num
, max_data_bytes
, maxentries
, close_after_request
, close_if_end
,
752 requires_resume_key
, resume_key
, continue_bit
, info_level
));
760 case SMB_FIND_FILE_DIRECTORY_INFO
:
761 case SMB_FIND_FILE_FULL_DIRECTORY_INFO
:
762 case SMB_FIND_FILE_NAMES_INFO
:
763 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO
:
766 return(ERROR(ERRDOS
,ERRunknownlevel
));
769 pdata
= *ppdata
= Realloc( *ppdata
, max_data_bytes
+ 1024);
771 return(ERROR(ERRDOS
,ERRnomem
));
772 bzero(pdata
,max_data_bytes
);
774 /* Realloc the params space */
775 params
= *pparams
= Realloc(*pparams
, 6*SIZEOFWORD
);
777 return(ERROR(ERRDOS
,ERRnomem
));
779 /* Check that the dptr is valid */
780 if(!(Connections
[cnum
].dirptr
= dptr_fetch_lanman2(params
, dptr_num
)))
781 return(ERROR(ERRDOS
,ERRnofiles
));
783 string_set(&Connections
[cnum
].dirpath
,dptr_path(dptr_num
));
785 /* Get the wildcard mask from the dptr */
786 if((p
= dptr_wcard(dptr_num
))== NULL
) {
787 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num
));
788 return (ERROR(ERRDOS
,ERRnofiles
));
791 strcpy(directory
,Connections
[cnum
].dirpath
);
793 /* Get the attr mask from the dptr */
794 dirtype
= dptr_attr(dptr_num
);
796 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%X,%d)\n",
797 dptr_num
, mask
, dirtype
,
798 Connections
[cnum
].dirptr
,
799 TellDir(Connections
[cnum
].dirptr
)));
801 /* We don't need to check for VOL here as this is returned by
802 a different TRANS2 call. */
804 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",Connections
[cnum
].dirpath
,lp_dontdescend(SNUM(cnum
))));
805 if (in_list(Connections
[cnum
].dirpath
,lp_dontdescend(SNUM(cnum
)),case_sensitive
))
809 space_remaining
= max_data_bytes
;
810 out_of_space
= False
;
812 /* If we have a resume key - seek to the correct position. */
813 if(requires_resume_key
&& !continue_bit
)
814 SeekDir(Connections
[cnum
].dirptr
, resume_key
);
816 for (i
=0;(i
<(int)maxentries
) && !finished
&& !out_of_space
;i
++)
818 /* this is a heuristic to avoid seeking the dirptr except when
819 absolutely necessary. It allows for a filename of about 40 chars */
820 if (space_remaining
< DIRLEN_GUESS
&& numentries
> 0)
828 !get_lanman2_dir_entry(cnum
,mask
,dirtype
,info_level
,
829 requires_resume_key
,dont_descend
,
830 &p
,pdata
,space_remaining
, &out_of_space
,
834 if (finished
&& out_of_space
)
837 if (!finished
&& !out_of_space
)
839 space_remaining
= max_data_bytes
- PTR_DIFF(p
,pdata
);
842 /* Check if we can close the dirptr */
843 if(close_after_request
|| (finished
&& close_if_end
))
845 dptr_close(dptr_num
); /* This frees up the saved mask */
846 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num
));
851 /* Set up the return parameter block */
852 SSVAL(params
,0,numentries
);
853 SSVAL(params
,2,finished
);
854 SSVAL(params
,4,0); /* Never an EA error */
855 SSVAL(params
,6,last_name_off
);
857 send_trans2_replies( outbuf
, bufsize
, params
, 8, pdata
, PTR_DIFF(p
,pdata
));
859 if ((! *directory
) && dptr_path(dptr_num
))
860 sprintf(directory
,"(%s)",dptr_path(dptr_num
));
862 DEBUG(3,("%s %s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n",
864 smb_fn_name(CVAL(inbuf
,smb_com
)),
865 mask
,directory
,cnum
,dirtype
,numentries
));
870 /****************************************************************************
871 reply to a TRANS2_QFSINFO (query filesystem info)
872 ****************************************************************************/
873 static int call_trans2qfsinfo(char *inbuf
, char *outbuf
, int length
, int bufsize
,
874 int cnum
, char **pparams
, char **ppdata
)
876 char *pdata
= *ppdata
;
877 char *params
= *pparams
;
878 uint16 info_level
= SVAL(params
,0);
881 char *vname
= volume_label(SNUM(cnum
));
883 DEBUG(3,("call_trans2qfsinfo: cnum = %d, level = %d\n", cnum
, info_level
));
885 if(sys_stat(".",&st
)!=0) {
886 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno
)));
887 return (ERROR(ERRSRV
,ERRinvdevice
));
890 pdata
= *ppdata
= Realloc(*ppdata
, 1024); bzero(pdata
,1024);
896 int dfree
,dsize
,bsize
;
898 sys_disk_free(".",&bsize
,&dfree
,&dsize
);
899 SIVAL(pdata
,l1_idFileSystem
,st
.st_dev
);
900 SIVAL(pdata
,l1_cSectorUnit
,bsize
/512);
901 SIVAL(pdata
,l1_cUnit
,dsize
);
902 SIVAL(pdata
,l1_cUnitAvail
,dfree
);
903 SSVAL(pdata
,l1_cbSector
,512);
904 DEBUG(5,("call_trans2qfsinfo : bsize=%d, id=%x, cSectorUnit=%d, cUnit=%d, cUnitAvail=%d, cbSector=%d\n",
905 bsize
, st
.st_dev
, bsize
/512, dsize
, dfree
, 512));
910 /* Return volume name */
911 int volname_len
= MIN(strlen(vname
),11);
912 data_len
= l2_vol_szVolLabel
+ volname_len
+ 1;
913 put_dos_date2(pdata
,l2_vol_fdateCreation
,st
.st_ctime
);
914 SCVAL(pdata
,l2_vol_cch
,volname_len
);
915 StrnCpy(pdata
+l2_vol_szVolLabel
,vname
,volname_len
);
916 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",st
.st_ctime
,volname_len
,
917 pdata
+l2_vol_szVolLabel
));
920 case SMB_QUERY_FS_ATTRIBUTE_INFO
:
921 data_len
= 12 + 2*strlen(FSTYPE_STRING
);
922 SIVAL(pdata
,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
923 SIVAL(pdata
,4,128); /* Max filename component length */
924 SIVAL(pdata
,8,2*strlen(FSTYPE_STRING
));
925 PutUniCode(pdata
+12,FSTYPE_STRING
);
927 case SMB_QUERY_FS_LABEL_INFO
:
928 data_len
= 4 + strlen(vname
);
929 SIVAL(pdata
,0,strlen(vname
));
930 strcpy(pdata
+4,vname
);
932 case SMB_QUERY_FS_VOLUME_INFO
:
933 data_len
= 18 + 2*strlen(vname
);
934 SIVAL(pdata
,12,2*strlen(vname
));
935 PutUniCode(pdata
+18,vname
);
936 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", strlen(vname
),
940 case SMB_QUERY_FS_SIZE_INFO
:
942 int dfree
,dsize
,bsize
;
944 sys_disk_free(".",&bsize
,&dfree
,&dsize
);
945 SIVAL(pdata
,0,dsize
);
946 SIVAL(pdata
,8,dfree
);
947 SIVAL(pdata
,16,bsize
/512);
951 case SMB_QUERY_FS_DEVICE_INFO
:
953 SIVAL(pdata
,0,0); /* dev type */
954 SIVAL(pdata
,4,0); /* characteristics */
957 return(ERROR(ERRDOS
,ERRunknownlevel
));
961 send_trans2_replies( outbuf
, bufsize
, params
, 0, pdata
, data_len
);
963 DEBUG(4,("%s %s info_level =%d\n",timestring(),smb_fn_name(CVAL(inbuf
,smb_com
)), info_level
));
968 /****************************************************************************
969 reply to a TRANS2_SETFSINFO (set filesystem info)
970 ****************************************************************************/
971 static int call_trans2setfsinfo(char *inbuf
, char *outbuf
, int length
, int bufsize
,
972 int cnum
, char **pparams
, char **ppdata
)
974 /* Just say yes we did it - there is nothing that
975 can be set here so it doesn't matter. */
977 DEBUG(3,("call_trans2setfsinfo\n"));
979 if (!CAN_WRITE(cnum
))
980 return(ERROR(ERRSRV
,ERRaccess
));
982 outsize
= set_message(outbuf
,10,0,True
);
987 /****************************************************************************
988 reply to a TRANS2_QFILEINFO (query file info by fileid)
989 ****************************************************************************/
990 static int call_trans2qfilepathinfo(char *inbuf
, char *outbuf
, int length
,
991 int bufsize
,int cnum
,
992 char **pparams
,char **ppdata
,
995 char *params
= *pparams
;
996 char *pdata
= *ppdata
;
997 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
1001 unsigned int data_size
;
1009 if (tran_call
== TRANSACT2_QFILEINFO
) {
1010 int16 fnum
= SVALS(params
,0);
1011 info_level
= SVAL(params
,2);
1013 CHECK_FNUM(fnum
,cnum
);
1016 fname
= Files
[fnum
].name
;
1017 if (fstat(Files
[fnum
].fd_ptr
->fd
,&sbuf
) != 0) {
1018 DEBUG(3,("fstat of fnum %d failed (%s)\n",fnum
, strerror(errno
)));
1019 return(UNIXERROR(ERRDOS
,ERRbadfid
));
1021 pos
= lseek(Files
[fnum
].fd_ptr
->fd
,0,SEEK_CUR
);
1024 info_level
= SVAL(params
,0);
1026 strcpy(fname
,¶ms
[6]);
1027 unix_convert(fname
,cnum
,0);
1028 if (!check_name(fname
,cnum
) || sys_stat(fname
,&sbuf
)) {
1029 DEBUG(3,("fileinfo of %s failed (%s)\n",fname
,strerror(errno
)));
1030 return(UNIXERROR(ERRDOS
,ERRbadpath
));
1036 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1037 fname
,info_level
,tran_call
,total_data
));
1039 p
= strrchr(fname
,'/');
1045 mode
= dos_mode(cnum
,fname
,&sbuf
);
1046 size
= sbuf
.st_size
;
1047 if (mode
& aDIR
) size
= 0;
1049 params
= *pparams
= Realloc(*pparams
,2); bzero(params
,2);
1051 pdata
= *ppdata
= Realloc(*ppdata
, data_size
);
1053 if (total_data
> 0 && IVAL(pdata
,0) == total_data
) {
1054 /* uggh, EAs for OS2 */
1055 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data
));
1057 SSVAL(params
,0,ERROR_EAS_NOT_SUPPORTED
);
1058 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
1061 return(ERROR(ERRDOS
,ERROR_EAS_NOT_SUPPORTED
));
1065 bzero(pdata
,data_size
);
1071 data_size
= (info_level
==1?22:26);
1072 put_dos_date2(pdata
,l1_fdateCreation
,sbuf
.st_ctime
);
1073 put_dos_date2(pdata
,l1_fdateLastAccess
,sbuf
.st_atime
);
1074 put_dos_date2(pdata
,l1_fdateLastWrite
,sbuf
.st_mtime
);
1075 SIVAL(pdata
,l1_cbFile
,size
);
1076 SIVAL(pdata
,l1_cbFileAlloc
,ROUNDUP(size
,1024));
1077 SSVAL(pdata
,l1_attrFile
,mode
);
1078 SIVAL(pdata
,l1_attrFile
+2,4); /* this is what OS2 does */
1083 put_dos_date2(pdata
,0,sbuf
.st_ctime
);
1084 put_dos_date2(pdata
,4,sbuf
.st_atime
);
1085 put_dos_date2(pdata
,8,sbuf
.st_mtime
);
1086 SIVAL(pdata
,12,size
);
1087 SIVAL(pdata
,16,ROUNDUP(size
,1024));
1088 SIVAL(pdata
,20,mode
);
1093 SIVAL(pdata
,0,data_size
);
1097 return(ERROR(ERRDOS
,ERRbadfunc
)); /* os/2 needs this */
1099 case SMB_QUERY_FILE_BASIC_INFO
:
1101 put_long_date(pdata
,sbuf
.st_ctime
);
1102 put_long_date(pdata
+8,sbuf
.st_atime
);
1103 put_long_date(pdata
+16,sbuf
.st_mtime
);
1104 put_long_date(pdata
+24,sbuf
.st_mtime
);
1105 SIVAL(pdata
,32,mode
);
1108 case SMB_QUERY_FILE_STANDARD_INFO
:
1110 SIVAL(pdata
,0,size
);
1111 SIVAL(pdata
,8,size
);
1112 SIVAL(pdata
,16,sbuf
.st_nlink
);
1114 CVAL(pdata
,21) = (mode
&aDIR
)?1:0;
1117 case SMB_QUERY_FILE_EA_INFO
:
1121 case SMB_QUERY_FILE_NAME_INFO
:
1122 case SMB_QUERY_FILE_ALT_NAME_INFO
:
1125 strcpy(pdata
+4,fname
);
1127 case SMB_QUERY_FILE_ALLOCATION_INFO
:
1128 case SMB_QUERY_FILE_END_OF_FILEINFO
:
1130 SIVAL(pdata
,0,size
);
1133 case SMB_QUERY_FILE_ALL_INFO
:
1134 put_long_date(pdata
,sbuf
.st_ctime
);
1135 put_long_date(pdata
+8,sbuf
.st_atime
);
1136 put_long_date(pdata
+16,sbuf
.st_mtime
);
1137 put_long_date(pdata
+24,sbuf
.st_mtime
);
1138 SIVAL(pdata
,32,mode
);
1140 SIVAL(pdata
,0,size
);
1141 SIVAL(pdata
,8,size
);
1142 SIVAL(pdata
,16,sbuf
.st_nlink
);
1144 CVAL(pdata
,21) = (mode
&aDIR
)?1:0;
1146 pdata
+= 8; /* index number */
1147 pdata
+= 4; /* EA info */
1149 SIVAL(pdata
,0,0xA9);
1151 SIVAL(pdata
,0,0xd01BF);
1153 SIVAL(pdata
,0,pos
); /* current offset */
1155 SIVAL(pdata
,0,mode
); /* is this the right sort of mode info? */
1157 pdata
+= 4; /* alignment */
1159 strcpy(pdata
+4,fname
);
1161 data_size
= PTR_DIFF(pdata
,(*ppdata
));
1164 case SMB_QUERY_FILE_STREAM_INFO
:
1167 SIVAL(pdata
,4,size
);
1168 SIVAL(pdata
,12,size
);
1170 strcpy(pdata
+24,fname
);
1173 return(ERROR(ERRDOS
,ERRunknownlevel
));
1176 send_trans2_replies( outbuf
, bufsize
, params
, 2, *ppdata
, data_size
);
1181 /****************************************************************************
1182 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1183 ****************************************************************************/
1184 static int call_trans2setfilepathinfo(char *inbuf
, char *outbuf
, int length
,
1185 int bufsize
, int cnum
, char **pparams
,
1186 char **ppdata
, int total_data
)
1188 char *params
= *pparams
;
1189 char *pdata
= *ppdata
;
1190 uint16 tran_call
= SVAL(inbuf
, smb_setup0
);
1200 if (!CAN_WRITE(cnum
))
1201 return(ERROR(ERRSRV
,ERRaccess
));
1203 if (tran_call
== TRANSACT2_SETFILEINFO
) {
1204 int16 fnum
= SVALS(params
,0);
1205 info_level
= SVAL(params
,2);
1207 CHECK_FNUM(fnum
,cnum
);
1210 fname
= Files
[fnum
].name
;
1211 fd
= Files
[fnum
].fd_ptr
->fd
;
1213 if(fstat(fd
,&st
)!=0) {
1214 DEBUG(3,("fstat of %s failed (%s)\n", fname
, strerror(errno
)));
1215 return(ERROR(ERRDOS
,ERRbadpath
));
1219 info_level
= SVAL(params
,0);
1221 strcpy(fname
,¶ms
[6]);
1222 unix_convert(fname
,cnum
,0);
1223 if(!check_name(fname
, cnum
))
1224 return(ERROR(ERRDOS
,ERRbadpath
));
1226 if(sys_stat(fname
,&st
)!=0) {
1227 DEBUG(3,("stat of %s failed (%s)\n", fname
, strerror(errno
)));
1228 return(ERROR(ERRDOS
,ERRbadpath
));
1232 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1233 tran_call
,fname
,info_level
,total_data
));
1235 /* Realloc the parameter and data sizes */
1236 params
= *pparams
= Realloc(*pparams
,2); SSVAL(params
,0,0);
1238 return(ERROR(ERRDOS
,ERRnomem
));
1241 tvs
.modtime
= st
.st_mtime
;
1242 tvs
.actime
= st
.st_atime
;
1243 mode
= dos_mode(cnum
,fname
,&st
);
1245 if (total_data
> 0 && IVAL(pdata
,0) == total_data
) {
1246 /* uggh, EAs for OS2 */
1247 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data
));
1248 SSVAL(params
,0,ERROR_EAS_NOT_SUPPORTED
);
1250 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
1258 tvs
.actime
= make_unix_date2(pdata
+l1_fdateLastAccess
);
1259 tvs
.modtime
= make_unix_date2(pdata
+l1_fdateLastWrite
);
1260 mode
= SVAL(pdata
,l1_attrFile
);
1261 size
= IVAL(pdata
,l1_cbFile
);
1265 tvs
.actime
= make_unix_date2(pdata
+l1_fdateLastAccess
);
1266 tvs
.modtime
= make_unix_date2(pdata
+l1_fdateLastWrite
);
1267 mode
= SVAL(pdata
,l1_attrFile
);
1268 size
= IVAL(pdata
,l1_cbFile
);
1272 tvs
.actime
= make_unix_date2(pdata
+8);
1273 tvs
.modtime
= make_unix_date2(pdata
+12);
1274 size
= IVAL(pdata
,16);
1275 mode
= IVAL(pdata
,24);
1279 tvs
.actime
= make_unix_date2(pdata
+8);
1280 tvs
.modtime
= make_unix_date2(pdata
+12);
1281 size
= IVAL(pdata
,16);
1282 mode
= IVAL(pdata
,24);
1285 case SMB_SET_FILE_BASIC_INFO
:
1286 pdata
+= 8; /* create time */
1287 tvs
.actime
= interpret_long_date(pdata
); pdata
+= 8;
1288 tvs
.modtime
=MAX(interpret_long_date(pdata
),interpret_long_date(pdata
+8));
1290 mode
= IVAL(pdata
,0);
1293 case SMB_SET_FILE_END_OF_FILE_INFO
:
1294 if (IVAL(pdata
,4) != 0) /* more than 32 bits? */
1295 return(ERROR(ERRDOS
,ERRunknownlevel
));
1296 size
= IVAL(pdata
,0);
1299 case SMB_SET_FILE_DISPOSITION_INFO
: /* not supported yet */
1300 case SMB_SET_FILE_ALLOCATION_INFO
: /* not supported yet */
1302 return(ERROR(ERRDOS
,ERRunknownlevel
));
1306 if (!tvs
.actime
) tvs
.actime
= st
.st_atime
;
1307 if (!tvs
.modtime
) tvs
.modtime
= st
.st_mtime
;
1308 if (!size
) size
= st
.st_size
;
1310 /* Try and set the times, size and mode of this file - if they are different
1311 from the current values */
1312 if(st
.st_mtime
!= tvs
.modtime
|| st
.st_atime
!= tvs
.actime
) {
1313 if(sys_utime(fname
, &tvs
)!=0)
1314 return(ERROR(ERRDOS
,ERRnoaccess
));
1316 if(mode
!= dos_mode(cnum
,fname
,&st
) && dos_chmod(cnum
,fname
,mode
,NULL
)) {
1317 DEBUG(2,("chmod of %s failed (%s)\n", fname
, strerror(errno
)));
1318 return(ERROR(ERRDOS
,ERRnoaccess
));
1320 if(size
!= st
.st_size
) {
1322 fd
= sys_open(fname
,O_RDWR
,0);
1324 return(ERROR(ERRDOS
,ERRbadpath
));
1325 set_filelen(fd
, size
);
1328 set_filelen(fd
, size
);
1334 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
1339 /****************************************************************************
1340 reply to a TRANS2_MKDIR (make directory with extended attributes).
1341 ****************************************************************************/
1342 static int call_trans2mkdir(char *inbuf
, char *outbuf
, int length
, int bufsize
,
1343 int cnum
, char **pparams
, char **ppdata
)
1345 char *params
= *pparams
;
1349 if (!CAN_WRITE(cnum
))
1350 return(ERROR(ERRSRV
,ERRaccess
));
1352 strcpy(directory
, ¶ms
[4]);
1354 DEBUG(3,("call_trans2mkdir : name = %s\n", directory
));
1356 unix_convert(directory
,cnum
,0);
1357 if (check_name(directory
,cnum
))
1358 ret
= sys_mkdir(directory
,unix_mode(cnum
,aDIR
));
1362 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno
)));
1363 return(UNIXERROR(ERRDOS
,ERRnoaccess
));
1366 /* Realloc the parameter and data sizes */
1367 params
= *pparams
= Realloc(*pparams
,2);
1369 return(ERROR(ERRDOS
,ERRnomem
));
1373 send_trans2_replies(outbuf
, bufsize
, params
, 2, *ppdata
, 0);
1378 /****************************************************************************
1379 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
1380 We don't actually do this - we just send a null response.
1381 ****************************************************************************/
1382 static int call_trans2findnotifyfirst(char *inbuf
, char *outbuf
, int length
, int bufsize
,
1383 int cnum
, char **pparams
, char **ppdata
)
1385 static uint16 fnf_handle
= 257;
1386 char *params
= *pparams
;
1387 uint16 info_level
= SVAL(params
,4);
1389 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level
));
1397 return(ERROR(ERRDOS
,ERRunknownlevel
));
1400 /* Realloc the parameter and data sizes */
1401 params
= *pparams
= Realloc(*pparams
,6);
1403 return(ERROR(ERRDOS
,ERRnomem
));
1405 SSVAL(params
,0,fnf_handle
);
1406 SSVAL(params
,2,0); /* No changes */
1407 SSVAL(params
,4,0); /* No EA errors */
1414 send_trans2_replies(outbuf
, bufsize
, params
, 6, *ppdata
, 0);
1419 /****************************************************************************
1420 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
1421 changes). Currently this does nothing.
1422 ****************************************************************************/
1423 static int call_trans2findnotifynext(char *inbuf
, char *outbuf
, int length
, int bufsize
,
1424 int cnum
, char **pparams
, char **ppdata
)
1426 char *params
= *pparams
;
1428 DEBUG(3,("call_trans2findnotifynext\n"));
1430 /* Realloc the parameter and data sizes */
1431 params
= *pparams
= Realloc(*pparams
,4);
1433 return(ERROR(ERRDOS
,ERRnomem
));
1435 SSVAL(params
,0,0); /* No changes */
1436 SSVAL(params
,2,0); /* No EA errors */
1438 send_trans2_replies(outbuf
, bufsize
, params
, 4, *ppdata
, 0);
1443 /****************************************************************************
1444 reply to a SMBfindclose (stop trans2 directory search)
1445 ****************************************************************************/
1446 int reply_findclose(char *inbuf
,char *outbuf
,int length
,int bufsize
)
1450 int16 dptr_num
=SVALS(inbuf
,smb_vwv0
);
1452 cnum
= SVAL(inbuf
,smb_tid
);
1454 DEBUG(3,("reply_findclose, cnum = %d, dptr_num = %d\n", cnum
, dptr_num
));
1456 dptr_close(dptr_num
);
1458 outsize
= set_message(outbuf
,0,0,True
);
1460 DEBUG(3,("%s SMBfindclose cnum=%d, dptr_num = %d\n",timestring(),cnum
,dptr_num
));
1465 /****************************************************************************
1466 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
1467 ****************************************************************************/
1468 int reply_findnclose(char *inbuf
,char *outbuf
,int length
,int bufsize
)
1474 cnum
= SVAL(inbuf
,smb_tid
);
1475 dptr_num
= SVAL(inbuf
,smb_vwv0
);
1477 DEBUG(3,("reply_findnclose, cnum = %d, dptr_num = %d\n", cnum
, dptr_num
));
1479 /* We never give out valid handles for a
1480 findnotifyfirst - so any dptr_num is ok here.
1483 outsize
= set_message(outbuf
,0,0,True
);
1485 DEBUG(3,("%s SMB_findnclose cnum=%d, dptr_num = %d\n",timestring(),cnum
,dptr_num
));
1491 /****************************************************************************
1492 reply to a SMBtranss2 - just ignore it!
1493 ****************************************************************************/
1494 int reply_transs2(char *inbuf
,char *outbuf
,int length
,int bufsize
)
1496 DEBUG(4,("Ignoring transs2 of length %d\n",length
));
1500 /****************************************************************************
1501 reply to a SMBtrans2
1502 ****************************************************************************/
1503 int reply_trans2(char *inbuf
,char *outbuf
,int length
,int bufsize
)
1506 int cnum
= SVAL(inbuf
,smb_tid
);
1507 unsigned int total_params
= SVAL(inbuf
, smb_tpscnt
);
1508 unsigned int total_data
=SVAL(inbuf
, smb_tdscnt
);
1510 unsigned int max_param_reply
= SVAL(inbuf
, smb_mprcnt
);
1511 unsigned int max_data_reply
= SVAL(inbuf
, smb_mdrcnt
);
1512 unsigned int max_setup_fields
= SVAL(inbuf
, smb_msrcnt
);
1513 BOOL close_tid
= BITSETW(inbuf
+smb_flags
,0);
1514 BOOL no_final_response
= BITSETW(inbuf
+smb_flags
,1);
1515 int32 timeout
= IVALS(inbuf
,smb_timeout
);
1517 unsigned int suwcnt
= SVAL(inbuf
, smb_suwcnt
);
1518 unsigned int tran_call
= SVAL(inbuf
, smb_setup0
);
1519 char *params
= NULL
, *data
= NULL
;
1520 int num_params
, num_params_sofar
, num_data
, num_data_sofar
;
1522 outsize
= set_message(outbuf
,0,0,True
);
1524 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
1525 is so as a sanity check */
1528 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
1529 return(ERROR(ERRSRV
,ERRerror
));
1532 /* Allocate the space for the maximum needed parameters and data */
1533 if (total_params
> 0)
1534 params
= (char *)malloc(total_params
);
1536 data
= (char *)malloc(total_data
);
1538 if ((total_params
&& !params
) || (total_data
&& !data
))
1540 DEBUG(2,("Out of memory in reply_trans2\n"));
1541 return(ERROR(ERRDOS
,ERRnomem
));
1544 /* Copy the param and data bytes sent with this request into
1545 the params buffer */
1546 num_params
= num_params_sofar
= SVAL(inbuf
,smb_pscnt
);
1547 num_data
= num_data_sofar
= SVAL(inbuf
, smb_dscnt
);
1549 memcpy( params
, smb_base(inbuf
) + SVAL(inbuf
, smb_psoff
), num_params
);
1550 memcpy( data
, smb_base(inbuf
) + SVAL(inbuf
, smb_dsoff
), num_data
);
1552 if(num_data_sofar
< total_data
|| num_params_sofar
< total_params
)
1554 /* We need to send an interim response then receive the rest
1555 of the parameter/data bytes */
1556 outsize
= set_message(outbuf
,0,0,True
);
1557 send_smb(Client
,outbuf
);
1559 while( num_data_sofar
< total_data
|| num_params_sofar
< total_params
)
1561 if(!receive_smb(Client
,inbuf
, SMB_SECONDARY_WAIT
) ||
1562 CVAL(inbuf
, smb_com
) != SMBtranss2
)
1564 outsize
= set_message(outbuf
,0,0,True
);
1565 DEBUG(2,("Invalid secondary trans2 packet\n"));
1568 return(ERROR(ERRSRV
,ERRerror
));
1571 /* Revise total_params and total_data in case they have changed downwards */
1572 total_params
= SVAL(inbuf
, smb_tpscnt
);
1573 total_data
= SVAL(inbuf
, smb_tdscnt
);
1574 num_params_sofar
+= (num_params
= SVAL(inbuf
,smb_spscnt
));
1575 num_data_sofar
+= ( num_data
= SVAL(inbuf
, smb_sdscnt
));
1576 memcpy( ¶ms
[ SVAL(inbuf
, smb_spsdisp
)],
1577 smb_base(inbuf
) + SVAL(inbuf
, smb_spsoff
), num_params
);
1578 memcpy( &data
[SVAL(inbuf
, smb_sdsdisp
)],
1579 smb_base(inbuf
)+ SVAL(inbuf
, smb_sdsoff
), num_data
);
1583 if (Protocol
>= PROTOCOL_NT1
) {
1584 uint16 flg2
= SVAL(outbuf
,smb_flg2
);
1585 SSVAL(outbuf
,smb_flg2
,flg2
| 0x40); /* IS_LONG_NAME */
1588 /* Now we must call the relevant TRANS2 function */
1591 case TRANSACT2_OPEN
:
1592 outsize
= call_trans2open(inbuf
, outbuf
, bufsize
, cnum
, ¶ms
, &data
);
1594 case TRANSACT2_FINDFIRST
:
1595 outsize
= call_trans2findfirst(inbuf
, outbuf
, bufsize
, cnum
, ¶ms
, &data
);
1597 case TRANSACT2_FINDNEXT
:
1598 outsize
= call_trans2findnext(inbuf
, outbuf
, length
, bufsize
, cnum
, ¶ms
, &data
);
1600 case TRANSACT2_QFSINFO
:
1601 outsize
= call_trans2qfsinfo(inbuf
, outbuf
, length
, bufsize
, cnum
, ¶ms
, &data
);
1603 case TRANSACT2_SETFSINFO
:
1604 outsize
= call_trans2setfsinfo(inbuf
, outbuf
, length
, bufsize
, cnum
, ¶ms
, &data
);
1606 case TRANSACT2_QPATHINFO
:
1607 case TRANSACT2_QFILEINFO
:
1608 outsize
= call_trans2qfilepathinfo(inbuf
, outbuf
, length
, bufsize
, cnum
, ¶ms
, &data
, total_data
);
1610 case TRANSACT2_SETPATHINFO
:
1611 case TRANSACT2_SETFILEINFO
:
1612 outsize
= call_trans2setfilepathinfo(inbuf
, outbuf
, length
, bufsize
, cnum
, ¶ms
, &data
, total_data
);
1614 case TRANSACT2_FINDNOTIFYFIRST
:
1615 outsize
= call_trans2findnotifyfirst(inbuf
, outbuf
, length
, bufsize
, cnum
, ¶ms
, &data
);
1617 case TRANSACT2_FINDNOTIFYNEXT
:
1618 outsize
= call_trans2findnotifynext(inbuf
, outbuf
, length
, bufsize
, cnum
, ¶ms
, &data
);
1620 case TRANSACT2_MKDIR
:
1621 outsize
= call_trans2mkdir(inbuf
, outbuf
, length
, bufsize
, cnum
, ¶ms
, &data
);
1624 /* Error in request */
1625 DEBUG(2,("%s Unknown request %d in trans2 call\n",timestring(), tran_call
));
1630 return (ERROR(ERRSRV
,ERRerror
));
1633 /* As we do not know how many data packets will need to be
1634 returned here the various call_trans2xxxx calls
1635 must send their own. Thus a call_trans2xxx routine only
1636 returns a value other than -1 when it wants to send
1644 return outsize
; /* If a correct response was needed the call_trans2xxx
1645 calls have already sent it. If outsize != -1 then it is
1646 returning an error packet. */