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.
28 extern int DEBUGLEVEL;
30 extern connection_struct Connections[];
31 extern files_struct Files[];
32 extern BOOL case_sensitive;
35 /****************************************************************************
36 Send the required number of replies back.
37 We assume all fields other than the data fields are
38 set correctly for the type of call.
39 HACK ! Always assumes smb_setup field is zero.
40 ****************************************************************************/
41 static int send_trans2_replies(char *outbuf, int bufsize, char *params,
42 int paramsize, char *pdata, int datasize)
44 /* As we are using a protocol > LANMAN1 then the maxxmit
45 variable must have been set in the sessetupX call.
46 This takes precedence over the max_xmit field in the
47 global struct. These different max_xmit variables should
48 be merged as this is now too confusing */
51 int data_to_send = datasize;
52 int params_to_send = paramsize;
56 int params_sent_thistime, data_sent_thistime, total_sent_thistime;
57 int alignment_offset = 1;
59 /* Initially set the wcnt area to be 10 - this is true for all
61 set_message(outbuf,10,0,True);
63 /* If there genuinely are no parameters or data to send just send
65 if(params_to_send == 0 && data_to_send == 0)
67 send_smb(Client,outbuf);
71 /* Space is bufsize minus Netbios over TCP header minus SMB header */
72 /* The + 1 is to align the param and data bytes on an even byte
73 boundary. NT 4.0 Beta needs this to work correctly. */
74 useable_space = bufsize - ((smb_buf(outbuf)+alignment_offset) - outbuf);
75 useable_space = MIN(useable_space, maxxmit); /* XXX is this needed? correct? */
77 while( params_to_send || data_to_send)
79 /* Calculate whether we will totally or partially fill this packet */
80 total_sent_thistime = params_to_send + data_to_send + alignment_offset;
81 total_sent_thistime = MIN(total_sent_thistime, useable_space);
83 set_message(outbuf, 10, total_sent_thistime, True);
85 /* Set total params and data to be sent */
86 SSVAL(outbuf,smb_tprcnt,paramsize);
87 SSVAL(outbuf,smb_tdrcnt,datasize);
89 /* Calculate how many parameters and data we can fit into
90 this packet. Parameters get precedence */
92 params_sent_thistime = MIN(params_to_send,useable_space);
93 data_sent_thistime = useable_space - params_sent_thistime;
94 data_sent_thistime = MIN(data_sent_thistime,data_to_send);
96 SSVAL(outbuf,smb_prcnt, params_sent_thistime);
97 if(params_sent_thistime == 0)
99 SSVAL(outbuf,smb_proff,0);
100 SSVAL(outbuf,smb_prdisp,0);
102 /* smb_proff is the offset from the start of the SMB header to the
103 parameter bytes, however the first 4 bytes of outbuf are
104 the Netbios over TCP header. Thus use smb_base() to subtract
105 them from the calculation */
106 SSVAL(outbuf,smb_proff,((smb_buf(outbuf)+alignment_offset) - smb_base(outbuf)));
107 /* Absolute displacement of param bytes sent in this packet */
108 SSVAL(outbuf,smb_prdisp,pp - params);
111 SSVAL(outbuf,smb_drcnt, data_sent_thistime);
112 if(data_sent_thistime == 0)
114 SSVAL(outbuf,smb_droff,0);
115 SSVAL(outbuf,smb_drdisp, 0);
117 /* The offset of the data bytes is the offset of the
118 parameter bytes plus the number of parameters being sent this time */
119 SSVAL(outbuf,smb_droff,((smb_buf(outbuf)+alignment_offset) -
120 smb_base(outbuf)) + params_sent_thistime);
121 SSVAL(outbuf,smb_drdisp, pd - pdata);
124 /* Copy the param bytes into the packet */
125 if(params_sent_thistime)
126 memcpy((smb_buf(outbuf)+alignment_offset),pp,params_sent_thistime);
127 /* Copy in the data bytes */
128 if(data_sent_thistime)
129 memcpy(smb_buf(outbuf)+alignment_offset+params_sent_thistime,pd,data_sent_thistime);
131 DEBUG(9,("t2_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
132 params_sent_thistime, data_sent_thistime, useable_space));
133 DEBUG(9,("t2_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
134 params_to_send, data_to_send, paramsize, datasize));
136 /* Send the packet */
137 send_smb(Client,outbuf);
139 pp += params_sent_thistime;
140 pd += data_sent_thistime;
142 params_to_send -= params_sent_thistime;
143 data_to_send -= data_sent_thistime;
146 if(params_to_send < 0 || data_to_send < 0)
148 DEBUG(2,("send_trans2_replies failed sanity check pts = %d, dts = %d\n!!!",
149 params_to_send, data_to_send));
158 /****************************************************************************
159 reply to a TRANSACT2_OPEN
160 ****************************************************************************/
161 static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum,
162 char **pparams, char **ppdata)
164 char *params = *pparams;
165 int16 open_mode = SVAL(params, 2);
166 int16 open_attr = SVAL(params,6);
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 SSVAL(params,18,smb_action);
237 SIVAL(params,20,inode);
239 /* Send the required number of replies */
240 send_trans2_replies(outbuf, bufsize, params, 28, *ppdata, 0);
245 /****************************************************************************
246 get a level dependent lanman2 dir entry.
247 ****************************************************************************/
248 static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_level,
249 int requires_resume_key,
250 BOOL dont_descend,char **ppdata,
251 char *base_data, int space_remaining,
262 char *p, *pdata = *ppdata;
263 int reskey=0, prev_dirpos=0;
266 uint32 mdate=0, adate=0, cdate=0;
268 BOOL isrootdir = (strequal(Connections[cnum].dirpath,"./") ||
269 strequal(Connections[cnum].dirpath,".") ||
270 strequal(Connections[cnum].dirpath,"/"));
274 *out_of_space = False;
276 if (!Connections[cnum].dirptr)
279 p = strrchr(path_mask,'/');
288 strcpy(mask, path_mask);
292 /* Needed if we run out of space */
293 prev_dirpos = TellDir(Connections[cnum].dirptr);
294 dname = ReadDirName(Connections[cnum].dirptr);
296 reskey = TellDir(Connections[cnum].dirptr);
298 DEBUG(6,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
299 Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr)));
308 if(mask_match(fname, mask, case_sensitive, True))
310 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
311 if (dont_descend && !isdots)
314 if (isrootdir && isdots)
317 strcpy(pathreal,Connections[cnum].dirpath);
318 strcat(pathreal,"/");
319 strcat(pathreal,fname);
320 if (sys_stat(pathreal,&sbuf) != 0)
322 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
326 mode = dos_mode(cnum,pathreal,&sbuf);
328 if (((mode & ~dirtype) & (aHIDDEN | aSYSTEM | aDIR)) != 0)
330 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
334 mdate = sbuf.st_mtime;
335 adate = sbuf.st_atime;
336 cdate = sbuf.st_ctime;
340 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
348 unix2dos_format(fname, True);
354 name_map_mangle(fname,False,SNUM(cnum));
359 if(requires_resume_key) {
363 put_dos_date2(p,l1_fdateCreation,cdate);
364 put_dos_date2(p,l1_fdateLastAccess,adate);
365 put_dos_date2(p,l1_fdateLastWrite,mdate);
366 SIVAL(p,l1_cbFile,size);
367 SIVAL(p,l1_cbFileAlloc,ROUNDUP(size,1024));
368 SSVAL(p,l1_attrFile,mode);
369 SCVAL(p,l1_cchName,strlen(fname));
370 strcpy(p + l1_achName, fname);
371 name_ptr = p + l1_achName;
372 p += l1_achName + strlen(fname) + 1;
377 if(requires_resume_key) {
381 put_dos_date2(p,l2_fdateCreation,cdate);
382 put_dos_date2(p,l2_fdateLastAccess,adate);
383 put_dos_date2(p,l2_fdateLastWrite,mdate);
384 SIVAL(p,l2_cbFile,size);
385 SIVAL(p,l2_cbFileAlloc,ROUNDUP(size,1024));
386 SSVAL(p,l2_attrFile,mode);
387 SIVAL(p,l2_cbList,0); /* No extended attributes */
388 SCVAL(p,l2_cchName,strlen(fname));
389 strcpy(p + l2_achName, fname);
390 name_ptr = p + l2_achName;
391 p += l2_achName + strlen(fname) + 1;
396 put_dos_date2(p,4,cdate);
397 put_dos_date2(p,8,adate);
398 put_dos_date2(p,12,mdate);
400 SIVAL(p,20,ROUNDUP(size,1024));
403 CVAL(p,30) = strlen(fname);
406 p += 31 + strlen(fname) + 1;
410 if(requires_resume_key) {
414 SIVAL(p,0,33+strlen(fname)+1);
415 put_dos_date2(p,4,cdate);
416 put_dos_date2(p,8,adate);
417 put_dos_date2(p,12,mdate);
419 SIVAL(p,20,ROUNDUP(size,1024));
421 CVAL(p,32) = strlen(fname);
422 strcpy(p + 33, fname);
424 p += 33 + strlen(fname) + 1;
427 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
428 was_8_3 = is_8_3(fname);
429 len = 94+strlen(fname);
430 len = (len + 3) & ~3;
431 SIVAL(p,0,len); p += 4;
432 SIVAL(p,0,reskey); p += 4;
433 put_long_date(p,cdate); p += 8;
434 put_long_date(p,adate); p += 8;
435 put_long_date(p,mdate); p += 8;
436 put_long_date(p,mdate); p += 8;
437 SIVAL(p,0,size); p += 8;
438 SIVAL(p,0,size); p += 8;
439 SIVAL(p,0,mode); p += 4;
440 SIVAL(p,0,strlen(fname)); p += 4;
441 SIVAL(p,0,0); p += 4;
444 strcpy(p+2,unix2dos_format(fname,False));
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(name_ptr,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);
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 = 17 + strlen(vname);
934 SIVAL(pdata,12,strlen(vname));
935 strcpy(pdata+17,vname);
937 case SMB_QUERY_FS_SIZE_INFO:
939 int dfree,dsize,bsize;
941 sys_disk_free(".",&bsize,&dfree,&dsize);
942 SIVAL(pdata,0,dsize);
943 SIVAL(pdata,8,dfree);
944 SIVAL(pdata,16,bsize/512);
948 case SMB_QUERY_FS_DEVICE_INFO:
950 SIVAL(pdata,0,0); /* dev type */
951 SIVAL(pdata,4,0); /* characteristics */
954 return(ERROR(ERRDOS,ERRunknownlevel));
958 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
960 DEBUG(4,("%s %s info_level =%d\n",timestring(),smb_fn_name(CVAL(inbuf,smb_com)), info_level));
965 /****************************************************************************
966 reply to a TRANS2_SETFSINFO (set filesystem info)
967 ****************************************************************************/
968 static int call_trans2setfsinfo(char *inbuf, char *outbuf, int length, int bufsize,
969 int cnum, char **pparams, char **ppdata)
971 /* Just say yes we did it - there is nothing that
972 can be set here so it doesn't matter. */
974 DEBUG(3,("call_trans2setfsinfo\n"));
976 if (!CAN_WRITE(cnum))
977 return(ERROR(ERRSRV,ERRaccess));
979 outsize = set_message(outbuf,10,0,True);
984 /****************************************************************************
985 reply to a TRANS2_QFILEINFO (query file info by fileid)
986 ****************************************************************************/
987 static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length,
988 int bufsize,int cnum,
989 char **pparams,char **ppdata,
992 char *params = *pparams;
993 char *pdata = *ppdata;
994 uint16 tran_call = SVAL(inbuf, smb_setup0);
998 unsigned int data_size;
1006 if (tran_call == TRANSACT2_QFILEINFO) {
1007 int16 fnum = SVAL(params,0);
1008 info_level = SVAL(params,2);
1010 CHECK_FNUM(fnum,cnum);
1013 fname = Files[fnum].name;
1014 if (fstat(Files[fnum].fd,&sbuf) != 0) {
1015 DEBUG(3,("fstat of fnum %d failed (%s)\n",fnum, strerror(errno)));
1016 return(UNIXERROR(ERRDOS,ERRbadfid));
1018 pos = lseek(Files[fnum].fd,0,SEEK_CUR);
1021 info_level = SVAL(params,0);
1023 strcpy(fname,¶ms[6]);
1024 unix_convert(fname,cnum);
1025 if (!check_name(fname,cnum) || sys_stat(fname,&sbuf)) {
1026 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1027 return(UNIXERROR(ERRDOS,ERRbadpath));
1033 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1034 fname,info_level,tran_call,total_data));
1036 p = strrchr(fname,'/');
1042 mode = dos_mode(cnum,fname,&sbuf);
1043 size = sbuf.st_size;
1044 if (mode & aDIR) size = 0;
1046 params = *pparams = Realloc(*pparams,2); bzero(params,2);
1048 pdata = *ppdata = Realloc(*ppdata, data_size);
1050 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1051 /* uggh, EAs for OS2 */
1052 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1054 SSVAL(params,0,ERROR_EAS_NOT_SUPPORTED);
1055 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1058 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1062 bzero(pdata,data_size);
1068 data_size = (info_level==1?22:26);
1069 put_dos_date2(pdata,l1_fdateCreation,sbuf.st_ctime);
1070 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime);
1071 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime);
1072 SIVAL(pdata,l1_cbFile,size);
1073 SIVAL(pdata,l1_cbFileAlloc,ROUNDUP(size,1024));
1074 SSVAL(pdata,l1_attrFile,mode);
1075 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1080 put_dos_date2(pdata,0,sbuf.st_ctime);
1081 put_dos_date2(pdata,4,sbuf.st_atime);
1082 put_dos_date2(pdata,8,sbuf.st_mtime);
1083 SIVAL(pdata,12,size);
1084 SIVAL(pdata,16,ROUNDUP(size,1024));
1085 SIVAL(pdata,20,mode);
1090 SIVAL(pdata,0,data_size);
1094 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1096 case SMB_QUERY_FILE_BASIC_INFO:
1098 put_long_date(pdata,sbuf.st_ctime);
1099 put_long_date(pdata+8,sbuf.st_atime);
1100 put_long_date(pdata+16,sbuf.st_mtime);
1101 put_long_date(pdata+24,sbuf.st_mtime);
1102 SIVAL(pdata,32,mode);
1105 case SMB_QUERY_FILE_STANDARD_INFO:
1107 SIVAL(pdata,0,size);
1108 SIVAL(pdata,8,size);
1109 SIVAL(pdata,16,sbuf.st_nlink);
1111 CVAL(pdata,21) = (mode&aDIR)?1:0;
1114 case SMB_QUERY_FILE_EA_INFO:
1118 case SMB_QUERY_FILE_NAME_INFO:
1119 case SMB_QUERY_FILE_ALT_NAME_INFO:
1122 strcpy(pdata+4,fname);
1124 case SMB_QUERY_FILE_ALLOCATION_INFO:
1125 case SMB_QUERY_FILE_END_OF_FILEINFO:
1127 SIVAL(pdata,0,size);
1130 case SMB_QUERY_FILE_ALL_INFO:
1131 put_long_date(pdata,sbuf.st_ctime);
1132 put_long_date(pdata+8,sbuf.st_atime);
1133 put_long_date(pdata+16,sbuf.st_mtime);
1134 put_long_date(pdata+24,sbuf.st_mtime);
1135 SIVAL(pdata,32,mode);
1137 SIVAL(pdata,0,size);
1138 SIVAL(pdata,8,size);
1139 SIVAL(pdata,16,sbuf.st_nlink);
1141 CVAL(pdata,21) = (mode&aDIR)?1:0;
1143 pdata += 8; /* index number */
1144 pdata += 4; /* EA info */
1146 SIVAL(pdata,0,0xA9);
1148 SIVAL(pdata,0,0xd01BF);
1150 SIVAL(pdata,0,pos); /* current offset */
1152 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1154 pdata += 4; /* alignment */
1156 strcpy(pdata+4,fname);
1158 data_size = PTR_DIFF(pdata,(*ppdata));
1161 case SMB_QUERY_FILE_STREAM_INFO:
1164 SIVAL(pdata,4,size);
1165 SIVAL(pdata,12,size);
1167 strcpy(pdata+24,fname);
1170 return(ERROR(ERRDOS,ERRunknownlevel));
1173 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1178 /****************************************************************************
1179 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1180 ****************************************************************************/
1181 static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length,
1182 int bufsize, int cnum, char **pparams,
1183 char **ppdata, int total_data)
1185 char *params = *pparams;
1186 char *pdata = *ppdata;
1187 uint16 tran_call = SVAL(inbuf, smb_setup0);
1197 if (!CAN_WRITE(cnum))
1198 return(ERROR(ERRSRV,ERRaccess));
1200 if (tran_call == TRANSACT2_SETFILEINFO) {
1201 int16 fnum = SVAL(params,0);
1202 info_level = SVAL(params,2);
1204 CHECK_FNUM(fnum,cnum);
1207 fname = Files[fnum].name;
1208 fd = Files[fnum].fd;
1210 if(fstat(fd,&st)!=0) {
1211 DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno)));
1212 return(ERROR(ERRDOS,ERRbadpath));
1216 info_level = SVAL(params,0);
1218 strcpy(fname,¶ms[6]);
1219 unix_convert(fname,cnum);
1220 if(!check_name(fname, cnum))
1221 return(ERROR(ERRDOS,ERRbadpath));
1223 if(sys_stat(fname,&st)!=0) {
1224 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1225 return(ERROR(ERRDOS,ERRbadpath));
1229 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1230 tran_call,fname,info_level,total_data));
1232 /* Realloc the parameter and data sizes */
1233 params = *pparams = Realloc(*pparams,2); SSVAL(params,0,0);
1235 return(ERROR(ERRDOS,ERRnomem));
1238 tvs.modtime = st.st_mtime;
1239 tvs.actime = st.st_atime;
1240 mode = dos_mode(cnum,fname,&st);
1242 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1243 /* uggh, EAs for OS2 */
1244 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1245 SSVAL(params,0,ERROR_EAS_NOT_SUPPORTED);
1247 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1255 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1256 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1257 mode = SVAL(pdata,l1_attrFile);
1258 size = IVAL(pdata,l1_cbFile);
1262 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1263 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1264 mode = SVAL(pdata,l1_attrFile);
1265 size = IVAL(pdata,l1_cbFile);
1269 tvs.actime = make_unix_date2(pdata+8);
1270 tvs.modtime = make_unix_date2(pdata+12);
1271 size = IVAL(pdata,16);
1272 mode = IVAL(pdata,24);
1276 tvs.actime = make_unix_date2(pdata+8);
1277 tvs.modtime = make_unix_date2(pdata+12);
1278 size = IVAL(pdata,16);
1279 mode = IVAL(pdata,24);
1282 case SMB_SET_FILE_BASIC_INFO:
1283 pdata += 8; /* create time */
1284 tvs.actime = interpret_long_date(pdata); pdata += 8;
1285 tvs.modtime=MAX(interpret_long_date(pdata),interpret_long_date(pdata+8));
1287 mode = IVAL(pdata,0);
1290 case SMB_SET_FILE_END_OF_FILE_INFO:
1291 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1292 return(ERROR(ERRDOS,ERRunknownlevel));
1293 size = IVAL(pdata,0);
1296 case SMB_SET_FILE_DISPOSITION_INFO: /* not supported yet */
1297 case SMB_SET_FILE_ALLOCATION_INFO: /* not supported yet */
1299 return(ERROR(ERRDOS,ERRunknownlevel));
1303 if (!tvs.actime) tvs.actime = st.st_atime;
1304 if (!tvs.modtime) tvs.modtime = st.st_mtime;
1305 if (!size) size = st.st_size;
1307 /* Try and set the times, size and mode of this file - if they are different
1308 from the current values */
1309 if(st.st_mtime != tvs.modtime || st.st_atime != tvs.actime) {
1310 if(sys_utime(fname, &tvs)!=0)
1311 return(ERROR(ERRDOS,ERRnoaccess));
1313 if(mode != dos_mode(cnum,fname,&st) && dos_chmod(cnum,fname,mode,NULL)) {
1314 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1315 return(ERROR(ERRDOS,ERRnoaccess));
1317 if(size != st.st_size) {
1319 fd = sys_open(fname,O_RDWR,0);
1321 return(ERROR(ERRDOS,ERRbadpath));
1322 set_filelen(fd, size);
1325 set_filelen(fd, size);
1331 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1336 /****************************************************************************
1337 reply to a TRANS2_MKDIR (make directory with extended attributes).
1338 ****************************************************************************/
1339 static int call_trans2mkdir(char *inbuf, char *outbuf, int length, int bufsize,
1340 int cnum, char **pparams, char **ppdata)
1342 char *params = *pparams;
1346 if (!CAN_WRITE(cnum))
1347 return(ERROR(ERRSRV,ERRaccess));
1349 strcpy(directory, ¶ms[4]);
1351 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
1353 unix_convert(directory,cnum);
1354 if (check_name(directory,cnum))
1355 ret = sys_mkdir(directory,unix_mode(cnum,aDIR));
1359 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
1360 return(UNIXERROR(ERRDOS,ERRnoaccess));
1363 /* Realloc the parameter and data sizes */
1364 params = *pparams = Realloc(*pparams,2);
1366 return(ERROR(ERRDOS,ERRnomem));
1370 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1375 /****************************************************************************
1376 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
1377 We don't actually do this - we just send a null response.
1378 ****************************************************************************/
1379 static int call_trans2findnotifyfirst(char *inbuf, char *outbuf, int length, int bufsize,
1380 int cnum, char **pparams, char **ppdata)
1382 static uint16 fnf_handle = 257;
1383 char *params = *pparams;
1384 uint16 info_level = SVAL(params,4);
1386 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
1394 return(ERROR(ERRDOS,ERRunknownlevel));
1397 /* Realloc the parameter and data sizes */
1398 params = *pparams = Realloc(*pparams,6);
1400 return(ERROR(ERRDOS,ERRnomem));
1402 SSVAL(params,0,fnf_handle);
1403 SSVAL(params,2,0); /* No changes */
1404 SSVAL(params,4,0); /* No EA errors */
1411 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
1416 /****************************************************************************
1417 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
1418 changes). Currently this does nothing.
1419 ****************************************************************************/
1420 static int call_trans2findnotifynext(char *inbuf, char *outbuf, int length, int bufsize,
1421 int cnum, char **pparams, char **ppdata)
1423 char *params = *pparams;
1425 DEBUG(3,("call_trans2findnotifynext\n"));
1427 /* Realloc the parameter and data sizes */
1428 params = *pparams = Realloc(*pparams,4);
1430 return(ERROR(ERRDOS,ERRnomem));
1432 SSVAL(params,0,0); /* No changes */
1433 SSVAL(params,2,0); /* No EA errors */
1435 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
1440 /****************************************************************************
1441 reply to a SMBfindclose (stop trans2 directory search)
1442 ****************************************************************************/
1443 int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize)
1447 uint16 dptr_num=SVAL(inbuf,smb_vwv0);
1449 cnum = SVAL(inbuf,smb_tid);
1451 DEBUG(3,("reply_findclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num));
1453 dptr_close(dptr_num);
1455 outsize = set_message(outbuf,0,0,True);
1457 DEBUG(3,("%s SMBfindclose cnum=%d, dptr_num = %d\n",timestring(),cnum,dptr_num));
1462 /****************************************************************************
1463 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
1464 ****************************************************************************/
1465 int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize)
1471 cnum = SVAL(inbuf,smb_tid);
1472 dptr_num = SVAL(inbuf,smb_vwv0);
1474 DEBUG(3,("reply_findnclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num));
1476 /* We never give out valid handles for a
1477 findnotifyfirst - so any dptr_num is ok here.
1480 outsize = set_message(outbuf,0,0,True);
1482 DEBUG(3,("%s SMB_findnclose cnum=%d, dptr_num = %d\n",timestring(),cnum,dptr_num));
1488 /****************************************************************************
1489 reply to a SMBtranss2 - just ignore it!
1490 ****************************************************************************/
1491 int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize)
1493 DEBUG(4,("Ignoring transs2 of length %d\n",length));
1497 /****************************************************************************
1498 reply to a SMBtrans2
1499 ****************************************************************************/
1500 int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize)
1503 int cnum = SVAL(inbuf,smb_tid);
1504 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
1505 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
1507 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
1508 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
1509 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
1510 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
1511 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
1512 int32 timeout = IVALS(inbuf,smb_timeout);
1514 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
1515 unsigned int tran_call = SVAL(inbuf, smb_setup0);
1516 char *params = NULL, *data = NULL;
1517 int num_params, num_params_sofar, num_data, num_data_sofar;
1519 outsize = set_message(outbuf,0,0,True);
1521 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
1522 is so as a sanity check */
1525 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
1526 return(ERROR(ERRSRV,ERRerror));
1529 /* Allocate the space for the maximum needed parameters and data */
1530 if (total_params > 0)
1531 params = (char *)malloc(total_params);
1533 data = (char *)malloc(total_data);
1535 if ((total_params && !params) || (total_data && !data))
1537 DEBUG(2,("Out of memory in reply_trans2\n"));
1538 return(ERROR(ERRDOS,ERRnomem));
1541 /* Copy the param and data bytes sent with this request into
1542 the params buffer */
1543 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
1544 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
1546 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
1547 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
1549 if(num_data_sofar < total_data || num_params_sofar < total_params)
1551 /* We need to send an interim response then receive the rest
1552 of the parameter/data bytes */
1553 outsize = set_message(outbuf,0,0,True);
1554 send_smb(Client,outbuf);
1556 while( num_data_sofar < total_data || num_params_sofar < total_params)
1558 receive_smb(Client,inbuf, 0);
1560 /* Ensure this is still a trans2 packet (sanity check) */
1561 if(CVAL(inbuf, smb_com) != SMBtranss2)
1563 outsize = set_message(outbuf,0,0,True);
1564 DEBUG(2,("Invalid secondary trans2 packet\n"));
1567 return(ERROR(ERRSRV,ERRerror));
1570 /* Revise total_params and total_data in case they have changed downwards */
1571 total_params = SVAL(inbuf, smb_tpscnt);
1572 total_data = SVAL(inbuf, smb_tdscnt);
1573 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
1574 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
1575 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
1576 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
1577 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
1578 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
1582 if (Protocol >= PROTOCOL_NT1) {
1583 uint16 flg2 = SVAL(outbuf,smb_flg2);
1584 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
1587 /* Now we must call the relevant TRANS2 function */
1590 case TRANSACT2_OPEN:
1591 outsize = call_trans2open(inbuf, outbuf, bufsize, cnum, ¶ms, &data);
1593 case TRANSACT2_FINDFIRST:
1594 outsize = call_trans2findfirst(inbuf, outbuf, bufsize, cnum, ¶ms, &data);
1596 case TRANSACT2_FINDNEXT:
1597 outsize = call_trans2findnext(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1599 case TRANSACT2_QFSINFO:
1600 outsize = call_trans2qfsinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1602 case TRANSACT2_SETFSINFO:
1603 outsize = call_trans2setfsinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1605 case TRANSACT2_QPATHINFO:
1606 case TRANSACT2_QFILEINFO:
1607 outsize = call_trans2qfilepathinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data, total_data);
1609 case TRANSACT2_SETPATHINFO:
1610 case TRANSACT2_SETFILEINFO:
1611 outsize = call_trans2setfilepathinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data, total_data);
1613 case TRANSACT2_FINDNOTIFYFIRST:
1614 outsize = call_trans2findnotifyfirst(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1616 case TRANSACT2_FINDNOTIFYNEXT:
1617 outsize = call_trans2findnotifynext(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1619 case TRANSACT2_MKDIR:
1620 outsize = call_trans2mkdir(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1623 /* Error in request */
1624 DEBUG(2,("%s Unknown request %d in trans2 call\n",timestring(), tran_call));
1629 return (ERROR(ERRSRV,ERRerror));
1632 /* As we do not know how many data packets will need to be
1633 returned here the various call_trans2xxxx calls
1634 must send their own. Thus a call_trans2xxx routine only
1635 returns a value other than -1 when it wants to send
1643 return outsize; /* If a correct response was needed the call_trans2xxx
1644 calls have already sent it. If outsize != -1 then it is
1645 returning an error packet. */