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 + 1 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 = MIN(useable_space, maxxmit); /* XXX is this needed? correct? */
76 while( params_to_send || data_to_send)
78 /* Calculate whether we will totally or partially fill this packet */
79 total_sent_thistime = params_to_send + data_to_send + alignment_offset;
80 total_sent_thistime = MIN(total_sent_thistime, useable_space);
82 set_message(outbuf, 10, total_sent_thistime, True);
84 /* Set total params and data to be sent */
85 SSVAL(outbuf,smb_tprcnt,paramsize);
86 SSVAL(outbuf,smb_tdrcnt,datasize);
88 /* Calculate how many parameters and data we can fit into
89 this packet. Parameters get precedence */
91 params_sent_thistime = MIN(params_to_send,useable_space);
92 data_sent_thistime = useable_space - params_sent_thistime;
93 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
95 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
96 if(params_sent_thistime == 0)
98 SSVAL(outbuf,smb_proff,0);
99 SSVAL(outbuf,smb_prdisp,0);
101 /* smb_proff is the offset from the start of the SMB header to the
102 parameter bytes, however the first 4 bytes of outbuf are
103 the Netbios over TCP header. Thus use smb_base() to subtract
104 them from the calculation */
105 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
106 /* Absolute displacement of param bytes sent in this packet */
107 SSVAL(outbuf,smb_prdisp,pp - params);
110 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
111 if(data_sent_thistime == 0)
113 SSVAL(outbuf,smb_droff,0);
114 SSVAL(outbuf,smb_drdisp, 0);
116 /* The offset of the data bytes is the offset of the
117 parameter bytes plus the number of parameters being sent this time */
118 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
119 smb_base(outbuf)) + params_sent_thistime);
120 SSVAL(outbuf,smb_drdisp, pd - pdata);
123 /* Copy the param bytes into the packet */
124 if(params_sent_thistime)
125 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
126 /* Copy in the data bytes */
127 if(data_sent_thistime)
128 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime,pd,data_sent_thistime);
130 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
131 params_sent_thistime, data_sent_thistime, useable_space));
132 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
133 params_to_send, data_to_send, paramsize, datasize));
135 /* Send the packet */
136 send_smb(Client,outbuf);
138 pp += params_sent_thistime;
139 pd += data_sent_thistime;
141 params_to_send -= params_sent_thistime;
142 data_to_send -= data_sent_thistime;
145 if(params_to_send < 0 || data_to_send < 0)
147 DEBUG(2,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
148 params_to_send, data_to_send));
157 /****************************************************************************
158 reply to a TRANSACT2_OPEN
159 ****************************************************************************/
160 static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
161 char **pparams, char **ppdata)
163 char *params = *pparams;
164 int16 open_mode = SVAL(params, 2);
165 int16 open_attr = SVAL(params,6);
166 BOOL oplock_request = BITSETW(params,1);
168 BOOL return_additional_info = BITSETW(params,0);
169 int16 open_sattr = SVAL(params, 4);
170 time_t open_time = make_unix_date3(params+8);
172 int16 open_ofun = SVAL(params,12);
173 int32 open_size = IVAL(params,14);
174 char *pname = ¶ms[28];
175 int16 namelen = strlen(pname)+1;
180 int size=0,fmode=0,mtime=0,rmode;
185 StrnCpy(fname,pname,namelen);
187 DEBUG(3,("trans2open %s cnum=%d mode=%d attr=%d ofun=%d size=%d\n",
188 fname,cnum,open_mode, open_attr, open_ofun, open_size));
190 /* XXXX we need to handle passed times, sattr and flags */
192 unix_convert(fname,cnum);
194 fnum = find_free_file();
196 return(ERROR(ERRSRV,ERRnofids));
198 if (!check_name(fname,cnum))
199 return(UNIXERROR(ERRDOS,ERRnoaccess));
201 unixmode = unix_mode(cnum,open_attr | aARCH);
204 open_file_shared(fnum,cnum,fname,open_mode,open_ofun,unixmode,
207 if (!Files[fnum].open)
208 return(UNIXERROR(ERRDOS,ERRnoaccess));
210 if (fstat(Files[fnum].fd,&sbuf) != 0) {
212 return(ERROR(ERRDOS,ERRnoaccess));
216 fmode = dos_mode(cnum,fname,&sbuf);
217 mtime = sbuf.st_mtime;
221 return(ERROR(ERRDOS,ERRnoaccess));
224 /* Realloc the size of parameters and data we will return */
225 params = *pparams = Realloc(*pparams, 28);
227 return(ERROR(ERRDOS,ERRnomem));
230 SSVAL(params,0,fnum);
231 SSVAL(params,2,fmode);
232 put_dos_date2(params,4, mtime);
233 SIVAL(params,8, size);
234 SSVAL(params,12,rmode);
236 if (oplock_request && lp_fake_oplocks(SNUM(cnum))) {
237 smb_action |= (1<<15);
240 SSVAL(params,18,smb_action);
241 SIVAL(params,20,inode);
243 /* Send the required number of replies */
244 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
249 /****************************************************************************
250 get a level dependent lanman2 dir entry.
251 ****************************************************************************/
252 static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_level,
253 int requires_resume_key,
254 BOOL dont_descend,char **ppdata,
255 char *base_data, int space_remaining,
266 char *p, *pdata = *ppdata;
267 int reskey=0, prev_dirpos=0;
270 uint32 mdate=0, adate=0, cdate=0;
272 BOOL isrootdir = (strequal(Connections[cnum].dirpath,"./") ||
273 strequal(Connections[cnum].dirpath,".") ||
274 strequal(Connections[cnum].dirpath,"/"));
278 *out_of_space = False;
280 if (!Connections[cnum].dirptr)
283 p = strrchr(path_mask,'/');
292 strcpy(mask, path_mask);
296 /* Needed if we run out of space */
297 prev_dirpos = TellDir(Connections[cnum].dirptr);
298 dname = ReadDirName(Connections[cnum].dirptr);
300 reskey = TellDir(Connections[cnum].dirptr);
302 DEBUG(6,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
303 Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr)));
312 if(mask_match(fname, mask, case_sensitive, True))
314 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
315 if (dont_descend && !isdots)
318 if (isrootdir && isdots)
321 strcpy(pathreal,Connections[cnum].dirpath);
322 strcat(pathreal,"/");
323 strcat(pathreal,fname);
324 if (sys_stat(pathreal,&sbuf) != 0)
326 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
330 mode = dos_mode(cnum,pathreal,&sbuf);
332 if (!dir_check_ftype(cnum,mode,&sbuf,dirtype)) {
333 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
338 mdate = sbuf.st_mtime;
339 adate = sbuf.st_atime;
340 cdate = sbuf.st_ctime;
344 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
352 unix2dos_format(fname, True);
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 strcpy(p+2,unix2dos_format(fname,False));
452 if (!name_map_mangle(p+2,True,SNUM(cnum)))
457 SSVAL(p,0,strlen(p+2));
460 strcpy(p,fname); p += strlen(p);
464 case SMB_FIND_FILE_DIRECTORY_INFO:
465 len = 64+strlen(fname);
466 len = (len + 3) & ~3;
467 SIVAL(p,0,len); p += 4;
468 SIVAL(p,0,reskey); p += 4;
469 put_long_date(p,cdate); p += 8;
470 put_long_date(p,adate); p += 8;
471 put_long_date(p,mdate); p += 8;
472 put_long_date(p,mdate); p += 8;
473 SIVAL(p,0,size); p += 8;
474 SIVAL(p,0,size); p += 8;
475 SIVAL(p,0,mode); p += 4;
476 SIVAL(p,0,strlen(fname)); p += 4;
482 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
483 len = 68+strlen(fname);
484 len = (len + 3) & ~3;
485 SIVAL(p,0,len); p += 4;
486 SIVAL(p,0,reskey); p += 4;
487 put_long_date(p,cdate); p += 8;
488 put_long_date(p,adate); p += 8;
489 put_long_date(p,mdate); p += 8;
490 put_long_date(p,mdate); p += 8;
491 SIVAL(p,0,size); p += 8;
492 SIVAL(p,0,size); p += 8;
493 SIVAL(p,0,mode); p += 4;
494 SIVAL(p,0,strlen(fname)); p += 4;
495 SIVAL(p,0,0); p += 4;
500 case SMB_FIND_FILE_NAMES_INFO:
501 len = 12+strlen(fname);
502 len = (len + 3) & ~3;
503 SIVAL(p,0,len); p += 4;
504 SIVAL(p,0,reskey); p += 4;
505 SIVAL(p,0,strlen(fname)); p += 4;
515 if (PTR_DIFF(p,pdata) > space_remaining) {
516 /* Move the dirptr back to prev_dirpos */
517 SeekDir(Connections[cnum].dirptr, prev_dirpos);
518 *out_of_space = True;
519 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
520 return False; /* Not finished - just out of space */
523 /* Setup the last_filename pointer, as an offset from base_data */
524 *last_name_off = PTR_DIFF(nameptr,base_data);
525 /* Advance the data pointer to the next slot */
530 /****************************************************************************
531 reply to a TRANS2_FINDFIRST
532 ****************************************************************************/
533 static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum,
534 char **pparams, char **ppdata)
536 /* We must be careful here that we don't return more than the
537 allowed number of data bytes. If this means returning fewer than
538 maxentries then so be it. We assume that the redirector has
539 enough room for the fixed number of parameter bytes it has
541 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
542 char *params = *pparams;
543 char *pdata = *ppdata;
544 int dirtype = SVAL(params,0);
545 int maxentries = SVAL(params,2);
546 BOOL close_after_first = BITSETW(params+4,0);
547 BOOL close_if_end = BITSETW(params+4,1);
548 BOOL requires_resume_key = BITSETW(params+4,2);
549 int info_level = SVAL(params,6);
557 BOOL finished = False;
558 BOOL dont_descend = False;
559 BOOL out_of_space = False;
562 *directory = *mask = 0;
564 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",
565 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
566 info_level, max_data_bytes));
574 case SMB_FIND_FILE_DIRECTORY_INFO:
575 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
576 case SMB_FIND_FILE_NAMES_INFO:
577 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
580 return(ERROR(ERRDOS,ERRunknownlevel));
583 strcpy(directory, params + 12); /* Complete directory path with
584 wildcard mask appended */
586 DEBUG(5,("path=%s\n",directory));
588 unix_convert(directory,cnum);
589 if(!check_name(directory,cnum)) {
590 return(ERROR(ERRDOS,ERRbadpath));
593 p = strrchr(directory,'/');
595 strcpy(mask,directory);
596 strcpy(directory,"./");
602 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
604 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
606 return(ERROR(ERRDOS,ERRnomem));
607 bzero(pdata,max_data_bytes);
609 /* Realloc the params space */
610 params = *pparams = Realloc(*pparams, 10);
612 return(ERROR(ERRDOS,ERRnomem));
614 dptr_num = dptr_create(cnum,directory, True ,SVAL(inbuf,smb_pid));
616 return(ERROR(ERRDOS,ERRbadpath));
618 /* convert the formatted masks */
622 if (*p == '<') *p = '*';
623 if (*p == '>') *p = '?';
624 if (*p == '"') *p = '.';
629 /* a special case for 16 bit apps */
630 if (strequal(mask,"????????.???")) strcpy(mask,"*");
632 /* handle broken clients that send us old 8.3 format */
633 string_sub(mask,"????????","*");
634 string_sub(mask,".???",".*");
636 /* Save the wildcard match and attribs we are using on this directory -
637 needed as lanman2 assumes these are being saved between calls */
639 if(!(wcard = strdup(mask))) {
640 dptr_close(dptr_num);
641 return(ERROR(ERRDOS,ERRnomem));
644 dptr_set_wcard(dptr_num, wcard);
645 dptr_set_attr(dptr_num, dirtype);
647 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
649 /* We don't need to check for VOL here as this is returned by
650 a different TRANS2 call. */
652 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
653 Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum))));
654 if (in_list(Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)),case_sensitive))
658 space_remaining = max_data_bytes;
659 out_of_space = False;
661 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
664 /* this is a heuristic to avoid seeking the dirptr except when
665 absolutely necessary. It allows for a filename of about 40 chars */
666 if (space_remaining < DIRLEN_GUESS && numentries > 0)
674 !get_lanman2_dir_entry(cnum,mask,dirtype,info_level,
675 requires_resume_key,dont_descend,
676 &p,pdata,space_remaining, &out_of_space,
680 if (finished && out_of_space)
683 if (!finished && !out_of_space)
685 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
688 /* Check if we can close the dirptr */
689 if(close_after_first || (finished && close_if_end))
691 dptr_close(dptr_num);
692 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
696 /* At this point pdata points to numentries directory entries. */
698 /* Set up the return parameter block */
699 SSVAL(params,0,dptr_num);
700 SSVAL(params,2,numentries);
701 SSVAL(params,4,finished);
702 SSVAL(params,6,0); /* Never an EA error */
703 SSVAL(params,8,last_name_off);
705 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
707 if ((! *directory) && dptr_path(dptr_num))
708 sprintf(directory,"(%s)",dptr_path(dptr_num));
710 DEBUG(4,("%s %s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n",
712 smb_fn_name(CVAL(inbuf,smb_com)),
713 mask,directory,cnum,dirtype,numentries));
719 /****************************************************************************
720 reply to a TRANS2_FINDNEXT
721 ****************************************************************************/
722 static int call_trans2findnext(char *inbuf, char *outbuf, int length, int bufsize,
723 int cnum, char **pparams, char **ppdata)
725 /* We must be careful here that we don't return more than the
726 allowed number of data bytes. If this means returning fewer than
727 maxentries then so be it. We assume that the redirector has
728 enough room for the fixed number of parameter bytes it has
730 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
731 char *params = *pparams;
732 char *pdata = *ppdata;
733 int16 dptr_num = SVAL(params,0);
734 int maxentries = SVAL(params,2);
735 uint16 info_level = SVAL(params,4);
736 uint32 resume_key = IVAL(params,6);
737 BOOL close_after_request = BITSETW(params+10,0);
738 BOOL close_if_end = BITSETW(params+10,1);
739 BOOL requires_resume_key = BITSETW(params+10,2);
740 BOOL continue_bit = BITSETW(params+10,3);
746 int i, last_name_off=0;
747 BOOL finished = False;
748 BOOL dont_descend = False;
749 BOOL out_of_space = False;
752 *mask = *directory = 0;
754 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",
755 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
756 requires_resume_key, resume_key, continue_bit, info_level));
764 case SMB_FIND_FILE_DIRECTORY_INFO:
765 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
766 case SMB_FIND_FILE_NAMES_INFO:
767 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
770 return(ERROR(ERRDOS,ERRunknownlevel));
773 pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
775 return(ERROR(ERRDOS,ERRnomem));
776 bzero(pdata,max_data_bytes);
778 /* Realloc the params space */
779 params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
781 return(ERROR(ERRDOS,ERRnomem));
783 /* Check that the dptr is valid */
784 if(!(Connections[cnum].dirptr = dptr_fetch_lanman2(params, dptr_num)))
785 return(ERROR(ERRDOS,ERRnofiles));
787 string_set(&Connections[cnum].dirpath,dptr_path(dptr_num));
789 /* Get the wildcard mask from the dptr */
790 if((p = dptr_wcard(dptr_num))== NULL) {
791 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
792 return (ERROR(ERRDOS,ERRnofiles));
795 strcpy(directory,Connections[cnum].dirpath);
797 /* Get the attr mask from the dptr */
798 dirtype = dptr_attr(dptr_num);
800 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%X,%d)\n",
801 dptr_num, mask, dirtype,
802 Connections[cnum].dirptr,
803 TellDir(Connections[cnum].dirptr)));
805 /* We don't need to check for VOL here as this is returned by
806 a different TRANS2 call. */
808 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum))));
809 if (in_list(Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)),case_sensitive))
813 space_remaining = max_data_bytes;
814 out_of_space = False;
816 /* If we have a resume key - seek to the correct position. */
817 if(requires_resume_key && !continue_bit)
818 SeekDir(Connections[cnum].dirptr, resume_key);
820 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
822 /* this is a heuristic to avoid seeking the dirptr except when
823 absolutely necessary. It allows for a filename of about 40 chars */
824 if (space_remaining < DIRLEN_GUESS && numentries > 0)
832 !get_lanman2_dir_entry(cnum,mask,dirtype,info_level,
833 requires_resume_key,dont_descend,
834 &p,pdata,space_remaining, &out_of_space,
838 if (finished && out_of_space)
841 if (!finished && !out_of_space)
843 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
846 /* Check if we can close the dirptr */
847 if(close_after_request || (finished && close_if_end))
849 dptr_close(dptr_num); /* This frees up the saved mask */
850 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
855 /* Set up the return parameter block */
856 SSVAL(params,0,numentries);
857 SSVAL(params,2,finished);
858 SSVAL(params,4,0); /* Never an EA error */
859 SSVAL(params,6,last_name_off);
861 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
863 if ((! *directory) && dptr_path(dptr_num))
864 sprintf(directory,"(%s)",dptr_path(dptr_num));
866 DEBUG(3,("%s %s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n",
868 smb_fn_name(CVAL(inbuf,smb_com)),
869 mask,directory,cnum,dirtype,numentries));
874 /****************************************************************************
875 reply to a TRANS2_QFSINFO (query filesystem info)
876 ****************************************************************************/
877 static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize,
878 int cnum, char **pparams, char **ppdata)
880 char *pdata = *ppdata;
881 char *params = *pparams;
882 uint16 info_level = SVAL(params,0);
885 char *vname = volume_label(SNUM(cnum));
887 DEBUG(3,("call_trans2qfsinfo: cnum = %d, level = %d\n", cnum, info_level));
889 if(sys_stat(".",&st)!=0) {
890 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
891 return (ERROR(ERRSRV,ERRinvdevice));
894 pdata = *ppdata = Realloc(*ppdata, 1024); bzero(pdata,1024);
900 int dfree,dsize,bsize;
902 sys_disk_free(".",&bsize,&dfree,&dsize);
903 SIVAL(pdata,l1_idFileSystem,st.st_dev);
904 SIVAL(pdata,l1_cSectorUnit,bsize/512);
905 SIVAL(pdata,l1_cUnit,dsize);
906 SIVAL(pdata,l1_cUnitAvail,dfree);
907 SSVAL(pdata,l1_cbSector,512);
908 DEBUG(5,("call_trans2qfsinfo : bsize=%d, id=%x, cSectorUnit=%d, cUnit=%d, cUnitAvail=%d, cbSector=%d\n",
909 bsize, st.st_dev, bsize/512, dsize, dfree, 512));
914 /* Return volume name */
915 int volname_len = MIN(strlen(vname),11);
916 data_len = l2_vol_szVolLabel + volname_len + 1;
917 put_dos_date2(pdata,l2_vol_fdateCreation,st.st_ctime);
918 SCVAL(pdata,l2_vol_cch,volname_len);
919 StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
920 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",st.st_ctime,volname_len,
921 pdata+l2_vol_szVolLabel));
924 case SMB_QUERY_FS_ATTRIBUTE_INFO:
925 data_len = 12 + 2*strlen(FSTYPE_STRING);
926 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
927 SIVAL(pdata,4,128); /* Max filename component length */
928 SIVAL(pdata,8,2*strlen(FSTYPE_STRING));
929 PutUniCode(pdata+12,FSTYPE_STRING);
931 case SMB_QUERY_FS_LABEL_INFO:
932 data_len = 4 + strlen(vname);
933 SIVAL(pdata,0,strlen(vname));
934 strcpy(pdata+4,vname);
936 case SMB_QUERY_FS_VOLUME_INFO:
937 data_len = 17 + strlen(vname);
938 SIVAL(pdata,12,strlen(vname));
939 strcpy(pdata+17,vname);
941 case SMB_QUERY_FS_SIZE_INFO:
943 int dfree,dsize,bsize;
945 sys_disk_free(".",&bsize,&dfree,&dsize);
946 SIVAL(pdata,0,dsize);
947 SIVAL(pdata,8,dfree);
948 SIVAL(pdata,16,bsize/512);
952 case SMB_QUERY_FS_DEVICE_INFO:
954 SIVAL(pdata,0,0); /* dev type */
955 SIVAL(pdata,4,0); /* characteristics */
958 return(ERROR(ERRDOS,ERRunknownlevel));
962 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
964 DEBUG(4,("%s %s info_level =%d\n",timestring(),smb_fn_name(CVAL(inbuf,smb_com)), info_level));
969 /****************************************************************************
970 reply to a TRANS2_SETFSINFO (set filesystem info)
971 ****************************************************************************/
972 static int call_trans2setfsinfo(char *inbuf, char *outbuf, int length, int bufsize,
973 int cnum, char **pparams, char **ppdata)
975 /* Just say yes we did it - there is nothing that
976 can be set here so it doesn't matter. */
978 DEBUG(3,("call_trans2setfsinfo\n"));
980 if (!CAN_WRITE(cnum))
981 return(ERROR(ERRSRV,ERRaccess));
983 outsize = set_message(outbuf,10,0,True);
988 /****************************************************************************
989 reply to a TRANS2_QFILEINFO (query file info by fileid)
990 ****************************************************************************/
991 static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length,
992 int bufsize,int cnum,
993 char **pparams,char **ppdata,
996 char *params = *pparams;
997 char *pdata = *ppdata;
998 uint16 tran_call = SVAL(inbuf, smb_setup0);
1002 unsigned int data_size;
1010 if (tran_call == TRANSACT2_QFILEINFO) {
1011 int16 fnum = SVALS(params,0);
1012 info_level = SVAL(params,2);
1014 CHECK_FNUM(fnum,cnum);
1017 fname = Files[fnum].name;
1018 if (fstat(Files[fnum].fd,&sbuf) != 0) {
1019 DEBUG(3,("fstat of fnum %d failed (%s)\n",fnum, strerror(errno)));
1020 return(UNIXERROR(ERRDOS,ERRbadfid));
1022 pos = lseek(Files[fnum].fd,0,SEEK_CUR);
1025 info_level = SVAL(params,0);
1027 strcpy(fname,¶ms[6]);
1028 unix_convert(fname,cnum);
1029 if (!check_name(fname,cnum) || sys_stat(fname,&sbuf)) {
1030 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1031 return(UNIXERROR(ERRDOS,ERRbadpath));
1037 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1038 fname,info_level,tran_call,total_data));
1040 p = strrchr(fname,'/');
1046 mode = dos_mode(cnum,fname,&sbuf);
1047 size = sbuf.st_size;
1048 if (mode & aDIR) size = 0;
1050 params = *pparams = Realloc(*pparams,2); bzero(params,2);
1052 pdata = *ppdata = Realloc(*ppdata, data_size);
1054 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1055 /* uggh, EAs for OS2 */
1056 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1058 SSVAL(params,0,ERROR_EAS_NOT_SUPPORTED);
1059 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1062 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1066 bzero(pdata,data_size);
1072 data_size = (info_level==1?22:26);
1073 put_dos_date2(pdata,l1_fdateCreation,sbuf.st_ctime);
1074 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1075 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime);
1076 SIVAL(pdata,l1_cbFile,size);
1077 SIVAL(pdata,l1_cbFileAlloc,ROUNDUP(size,1024));
1078 SSVAL(pdata,l1_attrFile,mode);
1079 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1084 put_dos_date2(pdata,0,sbuf.st_ctime);
1085 put_dos_date2(pdata,4,sbuf.st_atime);
1086 put_dos_date2(pdata,8,sbuf.st_mtime);
1087 SIVAL(pdata,12,size);
1088 SIVAL(pdata,16,ROUNDUP(size,1024));
1089 SIVAL(pdata,20,mode);
1094 SIVAL(pdata,0,data_size);
1098 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1100 case SMB_QUERY_FILE_BASIC_INFO:
1102 put_long_date(pdata,sbuf.st_ctime);
1103 put_long_date(pdata+8,sbuf.st_atime);
1104 put_long_date(pdata+16,sbuf.st_mtime);
1105 put_long_date(pdata+24,sbuf.st_mtime);
1106 SIVAL(pdata,32,mode);
1109 case SMB_QUERY_FILE_STANDARD_INFO:
1111 SIVAL(pdata,0,size);
1112 SIVAL(pdata,8,size);
1113 SIVAL(pdata,16,sbuf.st_nlink);
1115 CVAL(pdata,21) = (mode&aDIR)?1:0;
1118 case SMB_QUERY_FILE_EA_INFO:
1122 case SMB_QUERY_FILE_NAME_INFO:
1123 case SMB_QUERY_FILE_ALT_NAME_INFO:
1126 strcpy(pdata+4,fname);
1128 case SMB_QUERY_FILE_ALLOCATION_INFO:
1129 case SMB_QUERY_FILE_END_OF_FILEINFO:
1131 SIVAL(pdata,0,size);
1134 case SMB_QUERY_FILE_ALL_INFO:
1135 put_long_date(pdata,sbuf.st_ctime);
1136 put_long_date(pdata+8,sbuf.st_atime);
1137 put_long_date(pdata+16,sbuf.st_mtime);
1138 put_long_date(pdata+24,sbuf.st_mtime);
1139 SIVAL(pdata,32,mode);
1141 SIVAL(pdata,0,size);
1142 SIVAL(pdata,8,size);
1143 SIVAL(pdata,16,sbuf.st_nlink);
1145 CVAL(pdata,21) = (mode&aDIR)?1:0;
1147 pdata += 8; /* index number */
1148 pdata += 4; /* EA info */
1150 SIVAL(pdata,0,0xA9);
1152 SIVAL(pdata,0,0xd01BF);
1154 SIVAL(pdata,0,pos); /* current offset */
1156 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1158 pdata += 4; /* alignment */
1160 strcpy(pdata+4,fname);
1162 data_size = PTR_DIFF(pdata,(*ppdata));
1165 case SMB_QUERY_FILE_STREAM_INFO:
1168 SIVAL(pdata,4,size);
1169 SIVAL(pdata,12,size);
1171 strcpy(pdata+24,fname);
1174 return(ERROR(ERRDOS,ERRunknownlevel));
1177 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1182 /****************************************************************************
1183 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1184 ****************************************************************************/
1185 static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length,
1186 int bufsize, int cnum, char **pparams,
1187 char **ppdata, int total_data)
1189 char *params = *pparams;
1190 char *pdata = *ppdata;
1191 uint16 tran_call = SVAL(inbuf, smb_setup0);
1201 if (!CAN_WRITE(cnum))
1202 return(ERROR(ERRSRV,ERRaccess));
1204 if (tran_call == TRANSACT2_SETFILEINFO) {
1205 int16 fnum = SVALS(params,0);
1206 info_level = SVAL(params,2);
1208 CHECK_FNUM(fnum,cnum);
1211 fname = Files[fnum].name;
1212 fd = Files[fnum].fd;
1214 if(fstat(fd,&st)!=0) {
1215 DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno)));
1216 return(ERROR(ERRDOS,ERRbadpath));
1220 info_level = SVAL(params,0);
1222 strcpy(fname,¶ms[6]);
1223 unix_convert(fname,cnum);
1224 if(!check_name(fname, cnum))
1225 return(ERROR(ERRDOS,ERRbadpath));
1227 if(sys_stat(fname,&st)!=0) {
1228 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1229 return(ERROR(ERRDOS,ERRbadpath));
1233 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1234 tran_call,fname,info_level,total_data));
1236 /* Realloc the parameter and data sizes */
1237 params = *pparams = Realloc(*pparams,2); SSVAL(params,0,0);
1239 return(ERROR(ERRDOS,ERRnomem));
1242 tvs.modtime = st.st_mtime;
1243 tvs.actime = st.st_atime;
1244 mode = dos_mode(cnum,fname,&st);
1246 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1247 /* uggh, EAs for OS2 */
1248 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1249 SSVAL(params,0,ERROR_EAS_NOT_SUPPORTED);
1251 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1259 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1260 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1261 mode = SVAL(pdata,l1_attrFile);
1262 size = IVAL(pdata,l1_cbFile);
1266 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1267 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1268 mode = SVAL(pdata,l1_attrFile);
1269 size = IVAL(pdata,l1_cbFile);
1273 tvs.actime = make_unix_date2(pdata+8);
1274 tvs.modtime = make_unix_date2(pdata+12);
1275 size = IVAL(pdata,16);
1276 mode = IVAL(pdata,24);
1280 tvs.actime = make_unix_date2(pdata+8);
1281 tvs.modtime = make_unix_date2(pdata+12);
1282 size = IVAL(pdata,16);
1283 mode = IVAL(pdata,24);
1286 case SMB_SET_FILE_BASIC_INFO:
1287 pdata += 8; /* create time */
1288 tvs.actime = interpret_long_date(pdata); pdata += 8;
1289 tvs.modtime=MAX(interpret_long_date(pdata),interpret_long_date(pdata+8));
1291 mode = IVAL(pdata,0);
1294 case SMB_SET_FILE_END_OF_FILE_INFO:
1295 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1296 return(ERROR(ERRDOS,ERRunknownlevel));
1297 size = IVAL(pdata,0);
1300 case SMB_SET_FILE_DISPOSITION_INFO: /* not supported yet */
1301 case SMB_SET_FILE_ALLOCATION_INFO: /* not supported yet */
1303 return(ERROR(ERRDOS,ERRunknownlevel));
1307 if (!tvs.actime) tvs.actime = st.st_atime;
1308 if (!tvs.modtime) tvs.modtime = st.st_mtime;
1309 if (!size) size = st.st_size;
1311 /* Try and set the times, size and mode of this file - if they are different
1312 from the current values */
1313 if(st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
1314 if(sys_utime(fname, &tvs)!=0)
1315 return(ERROR(ERRDOS,ERRnoaccess));
1317 if(mode != dos_mode(cnum,fname,&st) && dos_chmod(cnum,fname,mode,NULL)) {
1318 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1319 return(ERROR(ERRDOS,ERRnoaccess));
1321 if(size != st.st_size) {
1323 fd = sys_open(fname,O_RDWR,0);
1325 return(ERROR(ERRDOS,ERRbadpath));
1326 set_filelen(fd, size);
1329 set_filelen(fd, size);
1335 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1340 /****************************************************************************
1341 reply to a TRANS2_MKDIR (make directory with extended attributes).
1342 ****************************************************************************/
1343 static int call_trans2mkdir(char *inbuf, char *outbuf, int length, int bufsize,
1344 int cnum, char **pparams, char **ppdata)
1346 char *params = *pparams;
1350 if (!CAN_WRITE(cnum))
1351 return(ERROR(ERRSRV,ERRaccess));
1353 strcpy(directory, ¶ms[4]);
1355 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
1357 unix_convert(directory,cnum);
1358 if (check_name(directory,cnum))
1359 ret = sys_mkdir(directory,unix_mode(cnum,aDIR));
1363 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
1364 return(UNIXERROR(ERRDOS,ERRnoaccess));
1367 /* Realloc the parameter and data sizes */
1368 params = *pparams = Realloc(*pparams,2);
1370 return(ERROR(ERRDOS,ERRnomem));
1374 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1379 /****************************************************************************
1380 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
1381 We don't actually do this - we just send a null response.
1382 ****************************************************************************/
1383 static int call_trans2findnotifyfirst(char *inbuf, char *outbuf, int length, int bufsize,
1384 int cnum, char **pparams, char **ppdata)
1386 static uint16 fnf_handle = 257;
1387 char *params = *pparams;
1388 uint16 info_level = SVAL(params,4);
1390 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
1398 return(ERROR(ERRDOS,ERRunknownlevel));
1401 /* Realloc the parameter and data sizes */
1402 params = *pparams = Realloc(*pparams,6);
1404 return(ERROR(ERRDOS,ERRnomem));
1406 SSVAL(params,0,fnf_handle);
1407 SSVAL(params,2,0); /* No changes */
1408 SSVAL(params,4,0); /* No EA errors */
1415 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
1420 /****************************************************************************
1421 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
1422 changes). Currently this does nothing.
1423 ****************************************************************************/
1424 static int call_trans2findnotifynext(char *inbuf, char *outbuf, int length, int bufsize,
1425 int cnum, char **pparams, char **ppdata)
1427 char *params = *pparams;
1429 DEBUG(3,("call_trans2findnotifynext\n"));
1431 /* Realloc the parameter and data sizes */
1432 params = *pparams = Realloc(*pparams,4);
1434 return(ERROR(ERRDOS,ERRnomem));
1436 SSVAL(params,0,0); /* No changes */
1437 SSVAL(params,2,0); /* No EA errors */
1439 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
1444 /****************************************************************************
1445 reply to a SMBfindclose (stop trans2 directory search)
1446 ****************************************************************************/
1447 int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize)
1451 int16 dptr_num=SVALS(inbuf,smb_vwv0);
1453 cnum = SVAL(inbuf,smb_tid);
1455 DEBUG(3,("reply_findclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num));
1457 dptr_close(dptr_num);
1459 outsize = set_message(outbuf,0,0,True);
1461 DEBUG(3,("%s SMBfindclose cnum=%d, dptr_num = %d\n",timestring(),cnum,dptr_num));
1466 /****************************************************************************
1467 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
1468 ****************************************************************************/
1469 int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize)
1475 cnum = SVAL(inbuf,smb_tid);
1476 dptr_num = SVAL(inbuf,smb_vwv0);
1478 DEBUG(3,("reply_findnclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num));
1480 /* We never give out valid handles for a
1481 findnotifyfirst - so any dptr_num is ok here.
1484 outsize = set_message(outbuf,0,0,True);
1486 DEBUG(3,("%s SMB_findnclose cnum=%d, dptr_num = %d\n",timestring(),cnum,dptr_num));
1492 /****************************************************************************
1493 reply to a SMBtranss2 - just ignore it!
1494 ****************************************************************************/
1495 int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize)
1497 DEBUG(4,("Ignoring transs2 of length %d\n",length));
1501 /****************************************************************************
1502 reply to a SMBtrans2
1503 ****************************************************************************/
1504 int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize)
1507 int cnum = SVAL(inbuf,smb_tid);
1508 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
1509 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
1511 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
1512 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
1513 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
1514 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
1515 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
1516 int32 timeout = IVALS(inbuf,smb_timeout);
1518 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
1519 unsigned int tran_call = SVAL(inbuf, smb_setup0);
1520 char *params = NULL, *data = NULL;
1521 int num_params, num_params_sofar, num_data, num_data_sofar;
1523 outsize = set_message(outbuf,0,0,True);
1525 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
1526 is so as a sanity check */
1529 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
1530 return(ERROR(ERRSRV,ERRerror));
1533 /* Allocate the space for the maximum needed parameters and data */
1534 if (total_params > 0)
1535 params = (char *)malloc(total_params);
1537 data = (char *)malloc(total_data);
1539 if ((total_params && !params) || (total_data && !data))
1541 DEBUG(2,("Out of memory in reply_trans2\n"));
1542 return(ERROR(ERRDOS,ERRnomem));
1545 /* Copy the param and data bytes sent with this request into
1546 the params buffer */
1547 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
1548 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
1550 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
1551 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
1553 if(num_data_sofar < total_data || num_params_sofar < total_params)
1555 /* We need to send an interim response then receive the rest
1556 of the parameter/data bytes */
1557 outsize = set_message(outbuf,0,0,True);
1558 send_smb(Client,outbuf);
1560 while( num_data_sofar < total_data || num_params_sofar < total_params)
1562 if(!receive_smb(Client,inbuf, SMB_SECONDARY_WAIT) ||
1563 CVAL(inbuf, smb_com) != SMBtranss2)
1565 outsize = set_message(outbuf,0,0,True);
1566 DEBUG(2,("Invalid secondary trans2 packet\n"));
1569 return(ERROR(ERRSRV,ERRerror));
1572 /* Revise total_params and total_data in case they have changed downwards */
1573 total_params = SVAL(inbuf, smb_tpscnt);
1574 total_data = SVAL(inbuf, smb_tdscnt);
1575 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
1576 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
1577 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
1578 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
1579 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
1580 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
1584 if (Protocol >= PROTOCOL_NT1) {
1585 uint16 flg2 = SVAL(outbuf,smb_flg2);
1586 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
1589 /* Now we must call the relevant TRANS2 function */
1592 case TRANSACT2_OPEN:
1593 outsize = call_trans2open(inbuf, outbuf, bufsize, cnum, ¶ms, &data);
1595 case TRANSACT2_FINDFIRST:
1596 outsize = call_trans2findfirst(inbuf, outbuf, bufsize, cnum, ¶ms, &data);
1598 case TRANSACT2_FINDNEXT:
1599 outsize = call_trans2findnext(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1601 case TRANSACT2_QFSINFO:
1602 outsize = call_trans2qfsinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1604 case TRANSACT2_SETFSINFO:
1605 outsize = call_trans2setfsinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1607 case TRANSACT2_QPATHINFO:
1608 case TRANSACT2_QFILEINFO:
1609 outsize = call_trans2qfilepathinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data, total_data);
1611 case TRANSACT2_SETPATHINFO:
1612 case TRANSACT2_SETFILEINFO:
1613 outsize = call_trans2setfilepathinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data, total_data);
1615 case TRANSACT2_FINDNOTIFYFIRST:
1616 outsize = call_trans2findnotifyfirst(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1618 case TRANSACT2_FINDNOTIFYNEXT:
1619 outsize = call_trans2findnotifynext(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1621 case TRANSACT2_MKDIR:
1622 outsize = call_trans2mkdir(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1625 /* Error in request */
1626 DEBUG(2,("%s Unknown request %d in trans2 call\n",timestring(), tran_call));
1631 return (ERROR(ERRSRV,ERRerror));
1634 /* As we do not know how many data packets will need to be
1635 returned here the various call_trans2xxxx calls
1636 must send their own. Thus a call_trans2xxx routine only
1637 returns a value other than -1 when it wants to send
1645 return outsize; /* If a correct response was needed the call_trans2xxx
1646 calls have already sent it. If outsize != -1 then it is
1647 returning an error packet. */