2 Unix SMB/Netbios implementation.
4 SMB transaction2 handling
5 Copyright (C) Jeremy Allison 1994-1997
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 max_send
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 max_send minus the
76 useable_space = MIN(useable_space, max_send - 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 useable_space */
83 total_sent_thistime = MIN(total_sent_thistime, useable_space);
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,"/"));
279 int nt_extmode; /* Used for NT connections instead of mode */
280 BOOL needslash = ( Connections[cnum].dirpath[strlen(Connections[cnum].dirpath) -1] != '/');
283 *out_of_space = False;
285 if (!Connections[cnum].dirptr)
288 p = strrchr(path_mask,'/');
297 strcpy(mask, path_mask);
301 /* Needed if we run out of space */
302 prev_dirpos = TellDir(Connections[cnum].dirptr);
303 dname = ReadDirName(Connections[cnum].dirptr);
305 reskey = TellDir(Connections[cnum].dirptr);
307 DEBUG(6,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n",
308 Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr)));
317 if(mask_match(fname, mask, case_sensitive, True))
319 BOOL isdots = (strequal(fname,"..") || strequal(fname,"."));
320 if (dont_descend && !isdots)
323 if (isrootdir && isdots)
326 strcpy(pathreal,Connections[cnum].dirpath);
328 strcat(pathreal,"/");
329 strcat(pathreal,fname);
330 if (sys_stat(pathreal,&sbuf) != 0)
332 DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno)));
336 mode = dos_mode(cnum,pathreal,&sbuf);
338 if (!dir_check_ftype(cnum,mode,&sbuf,dirtype)) {
339 DEBUG(5,("[%s] attribs didn't match %x\n",fname,dirtype));
344 mdate = sbuf.st_mtime;
345 adate = sbuf.st_atime;
346 cdate = sbuf.st_ctime;
350 DEBUG(5,("get_lanman2_dir_entry found %s fname=%s\n",pathreal,fname));
361 name_map_mangle(fname,False,SNUM(cnum));
363 nt_extmode = mode ? mode : NT_FILE_ATTRIBUTE_NORMAL;
368 if(requires_resume_key) {
372 put_dos_date2(p,l1_fdateCreation,cdate);
373 put_dos_date2(p,l1_fdateLastAccess,adate);
374 put_dos_date2(p,l1_fdateLastWrite,mdate);
375 SIVAL(p,l1_cbFile,size);
376 SIVAL(p,l1_cbFileAlloc,ROUNDUP(size,1024));
377 SSVAL(p,l1_attrFile,mode);
378 SCVAL(p,l1_cchName,strlen(fname));
379 strcpy(p + l1_achName, fname);
380 nameptr = p + l1_achName;
381 p += l1_achName + strlen(fname) + 1;
386 if(requires_resume_key) {
390 put_dos_date2(p,l2_fdateCreation,cdate);
391 put_dos_date2(p,l2_fdateLastAccess,adate);
392 put_dos_date2(p,l2_fdateLastWrite,mdate);
393 SIVAL(p,l2_cbFile,size);
394 SIVAL(p,l2_cbFileAlloc,ROUNDUP(size,1024));
395 SSVAL(p,l2_attrFile,mode);
396 SIVAL(p,l2_cbList,0); /* No extended attributes */
397 SCVAL(p,l2_cchName,strlen(fname));
398 strcpy(p + l2_achName, fname);
399 nameptr = p + l2_achName;
400 p += l2_achName + strlen(fname) + 1;
405 put_dos_date2(p,4,cdate);
406 put_dos_date2(p,8,adate);
407 put_dos_date2(p,12,mdate);
409 SIVAL(p,20,ROUNDUP(size,1024));
412 CVAL(p,30) = strlen(fname);
415 p += 31 + strlen(fname) + 1;
419 if(requires_resume_key) {
423 SIVAL(p,0,33+strlen(fname)+1);
424 put_dos_date2(p,4,cdate);
425 put_dos_date2(p,8,adate);
426 put_dos_date2(p,12,mdate);
428 SIVAL(p,20,ROUNDUP(size,1024));
430 CVAL(p,32) = strlen(fname);
431 strcpy(p + 33, fname);
433 p += 33 + strlen(fname) + 1;
436 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
437 was_8_3 = is_8_3(fname, True);
438 len = 94+strlen(fname);
439 len = (len + 3) & ~3;
440 SIVAL(p,0,len); p += 4;
441 SIVAL(p,0,reskey); p += 4;
442 put_long_date(p,cdate); p += 8;
443 put_long_date(p,adate); p += 8;
444 put_long_date(p,mdate); p += 8;
445 put_long_date(p,mdate); p += 8;
446 SIVAL(p,0,size); p += 8;
447 SIVAL(p,0,size); p += 8;
448 SIVAL(p,0,nt_extmode); p += 4;
449 SIVAL(p,0,strlen(fname)); p += 4;
450 SIVAL(p,0,0); p += 4;
453 if (!name_map_mangle(p+2,True,SNUM(cnum)))
458 SSVAL(p,0,strlen(p+2));
461 strcpy(p,fname); p += strlen(p);
465 case SMB_FIND_FILE_DIRECTORY_INFO:
466 len = 64+strlen(fname);
467 len = (len + 3) & ~3;
468 SIVAL(p,0,len); p += 4;
469 SIVAL(p,0,reskey); p += 4;
470 put_long_date(p,cdate); p += 8;
471 put_long_date(p,adate); p += 8;
472 put_long_date(p,mdate); p += 8;
473 put_long_date(p,mdate); p += 8;
474 SIVAL(p,0,size); p += 8;
475 SIVAL(p,0,size); p += 8;
476 SIVAL(p,0,nt_extmode); p += 4;
477 SIVAL(p,0,strlen(fname)); p += 4;
483 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
484 len = 68+strlen(fname);
485 len = (len + 3) & ~3;
486 SIVAL(p,0,len); p += 4;
487 SIVAL(p,0,reskey); p += 4;
488 put_long_date(p,cdate); p += 8;
489 put_long_date(p,adate); p += 8;
490 put_long_date(p,mdate); p += 8;
491 put_long_date(p,mdate); p += 8;
492 SIVAL(p,0,size); p += 8;
493 SIVAL(p,0,size); p += 8;
494 SIVAL(p,0,nt_extmode); p += 4;
495 SIVAL(p,0,strlen(fname)); p += 4;
496 SIVAL(p,0,0); p += 4;
501 case SMB_FIND_FILE_NAMES_INFO:
502 len = 12+strlen(fname);
503 len = (len + 3) & ~3;
504 SIVAL(p,0,len); p += 4;
505 SIVAL(p,0,reskey); p += 4;
506 SIVAL(p,0,strlen(fname)); p += 4;
516 if (PTR_DIFF(p,pdata) > space_remaining) {
517 /* Move the dirptr back to prev_dirpos */
518 SeekDir(Connections[cnum].dirptr, prev_dirpos);
519 *out_of_space = True;
520 DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
521 return False; /* Not finished - just out of space */
524 /* Setup the last_filename pointer, as an offset from base_data */
525 *last_name_off = PTR_DIFF(nameptr,base_data);
526 /* Advance the data pointer to the next slot */
531 /****************************************************************************
532 reply to a TRANS2_FINDFIRST
533 ****************************************************************************/
534 static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum,
535 char **pparams, char **ppdata)
537 /* We must be careful here that we don't return more than the
538 allowed number of data bytes. If this means returning fewer than
539 maxentries then so be it. We assume that the redirector has
540 enough room for the fixed number of parameter bytes it has
542 uint32 max_data_bytes = SVAL(inbuf, smb_mdrcnt);
543 char *params = *pparams;
544 char *pdata = *ppdata;
545 int dirtype = SVAL(params,0);
546 int maxentries = SVAL(params,2);
547 BOOL close_after_first = BITSETW(params+4,0);
548 BOOL close_if_end = BITSETW(params+4,1);
549 BOOL requires_resume_key = BITSETW(params+4,2);
550 int info_level = SVAL(params,6);
558 BOOL finished = False;
559 BOOL dont_descend = False;
560 BOOL out_of_space = False;
563 *directory = *mask = 0;
565 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",
566 dirtype, maxentries, close_after_first, close_if_end, requires_resume_key,
567 info_level, max_data_bytes));
575 case SMB_FIND_FILE_DIRECTORY_INFO:
576 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
577 case SMB_FIND_FILE_NAMES_INFO:
578 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
581 return(ERROR(ERRDOS,ERRunknownlevel));
584 strcpy(directory, params + 12); /* Complete directory path with
585 wildcard mask appended */
587 DEBUG(5,("path=%s\n",directory));
589 unix_convert(directory,cnum,0);
590 if(!check_name(directory,cnum)) {
591 return(ERROR(ERRDOS,ERRbadpath));
594 p = strrchr(directory,'/');
596 strcpy(mask,directory);
597 strcpy(directory,"./");
603 DEBUG(5,("dir=%s, mask = %s\n",directory, mask));
605 pdata = *ppdata = Realloc(*ppdata, max_data_bytes + 1024);
607 return(ERROR(ERRDOS,ERRnomem));
608 bzero(pdata,max_data_bytes);
610 /* Realloc the params space */
611 params = *pparams = Realloc(*pparams, 10);
613 return(ERROR(ERRDOS,ERRnomem));
615 dptr_num = dptr_create(cnum,directory, True ,SVAL(inbuf,smb_pid));
619 return (UNIXERROR(ERRDOS,ERRbadpath));
620 return(ERROR(ERRDOS,ERRbadpath));
623 /* convert the formatted masks */
627 if (*p == '<') *p = '*';
628 if (*p == '>') *p = '?';
629 if (*p == '"') *p = '.';
634 /* a special case for 16 bit apps */
635 if (strequal(mask,"????????.???")) strcpy(mask,"*");
637 /* handle broken clients that send us old 8.3 format */
638 string_sub(mask,"????????","*");
639 string_sub(mask,".???",".*");
641 /* Save the wildcard match and attribs we are using on this directory -
642 needed as lanman2 assumes these are being saved between calls */
644 if(!(wcard = strdup(mask))) {
645 dptr_close(dptr_num);
646 return(ERROR(ERRDOS,ERRnomem));
649 dptr_set_wcard(dptr_num, wcard);
650 dptr_set_attr(dptr_num, dirtype);
652 DEBUG(4,("dptr_num is %d, wcard = %s, attr = %d\n",dptr_num, wcard, dirtype));
654 /* We don't need to check for VOL here as this is returned by
655 a different TRANS2 call. */
657 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",
658 Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum))));
659 if (in_list(Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)),case_sensitive))
663 space_remaining = max_data_bytes;
664 out_of_space = False;
666 for (i=0;(i<maxentries) && !finished && !out_of_space;i++)
669 /* this is a heuristic to avoid seeking the dirptr except when
670 absolutely necessary. It allows for a filename of about 40 chars */
671 if (space_remaining < DIRLEN_GUESS && numentries > 0)
679 !get_lanman2_dir_entry(cnum,mask,dirtype,info_level,
680 requires_resume_key,dont_descend,
681 &p,pdata,space_remaining, &out_of_space,
685 if (finished && out_of_space)
688 if (!finished && !out_of_space)
690 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
693 /* Check if we can close the dirptr */
694 if(close_after_first || (finished && close_if_end))
696 dptr_close(dptr_num);
697 DEBUG(5,("call_trans2findfirst - (2) closing dptr_num %d\n", dptr_num));
701 /* At this point pdata points to numentries directory entries. */
703 /* Set up the return parameter block */
704 SSVAL(params,0,dptr_num);
705 SSVAL(params,2,numentries);
706 SSVAL(params,4,finished);
707 SSVAL(params,6,0); /* Never an EA error */
708 SSVAL(params,8,last_name_off);
710 send_trans2_replies( outbuf, bufsize, params, 10, pdata, PTR_DIFF(p,pdata));
712 if ((! *directory) && dptr_path(dptr_num))
713 sprintf(directory,"(%s)",dptr_path(dptr_num));
715 DEBUG(4,("%s %s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n",
717 smb_fn_name(CVAL(inbuf,smb_com)),
718 mask,directory,cnum,dirtype,numentries));
724 /****************************************************************************
725 reply to a TRANS2_FINDNEXT
726 ****************************************************************************/
727 static int call_trans2findnext(char *inbuf, char *outbuf, int length, int bufsize,
728 int cnum, char **pparams, char **ppdata)
730 /* We must be careful here that we don't return more than the
731 allowed number of data bytes. If this means returning fewer than
732 maxentries then so be it. We assume that the redirector has
733 enough room for the fixed number of parameter bytes it has
735 int max_data_bytes = SVAL(inbuf, smb_mdrcnt);
736 char *params = *pparams;
737 char *pdata = *ppdata;
738 int16 dptr_num = SVAL(params,0);
739 int maxentries = SVAL(params,2);
740 uint16 info_level = SVAL(params,4);
741 uint32 resume_key = IVAL(params,6);
742 BOOL close_after_request = BITSETW(params+10,0);
743 BOOL close_if_end = BITSETW(params+10,1);
744 BOOL requires_resume_key = BITSETW(params+10,2);
745 BOOL continue_bit = BITSETW(params+10,3);
751 int i, last_name_off=0;
752 BOOL finished = False;
753 BOOL dont_descend = False;
754 BOOL out_of_space = False;
757 *mask = *directory = 0;
759 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",
760 dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
761 requires_resume_key, resume_key, continue_bit, info_level));
769 case SMB_FIND_FILE_DIRECTORY_INFO:
770 case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
771 case SMB_FIND_FILE_NAMES_INFO:
772 case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
775 return(ERROR(ERRDOS,ERRunknownlevel));
778 pdata = *ppdata = Realloc( *ppdata, max_data_bytes + 1024);
780 return(ERROR(ERRDOS,ERRnomem));
781 bzero(pdata,max_data_bytes);
783 /* Realloc the params space */
784 params = *pparams = Realloc(*pparams, 6*SIZEOFWORD);
786 return(ERROR(ERRDOS,ERRnomem));
788 /* Check that the dptr is valid */
789 if(!(Connections[cnum].dirptr = dptr_fetch_lanman2(params, dptr_num)))
790 return(ERROR(ERRDOS,ERRnofiles));
792 string_set(&Connections[cnum].dirpath,dptr_path(dptr_num));
794 /* Get the wildcard mask from the dptr */
795 if((p = dptr_wcard(dptr_num))== NULL) {
796 DEBUG(2,("dptr_num %d has no wildcard\n", dptr_num));
797 return (ERROR(ERRDOS,ERRnofiles));
800 strcpy(directory,Connections[cnum].dirpath);
802 /* Get the attr mask from the dptr */
803 dirtype = dptr_attr(dptr_num);
805 DEBUG(3,("dptr_num is %d, mask = %s, attr = %x, dirptr=(0x%X,%d)\n",
806 dptr_num, mask, dirtype,
807 Connections[cnum].dirptr,
808 TellDir(Connections[cnum].dirptr)));
810 /* We don't need to check for VOL here as this is returned by
811 a different TRANS2 call. */
813 DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum))));
814 if (in_list(Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum)),case_sensitive))
818 space_remaining = max_data_bytes;
819 out_of_space = False;
821 /* If we have a resume key - seek to the correct position. */
822 if(requires_resume_key && !continue_bit)
823 SeekDir(Connections[cnum].dirptr, resume_key);
825 for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++)
827 /* this is a heuristic to avoid seeking the dirptr except when
828 absolutely necessary. It allows for a filename of about 40 chars */
829 if (space_remaining < DIRLEN_GUESS && numentries > 0)
837 !get_lanman2_dir_entry(cnum,mask,dirtype,info_level,
838 requires_resume_key,dont_descend,
839 &p,pdata,space_remaining, &out_of_space,
843 if (finished && out_of_space)
846 if (!finished && !out_of_space)
848 space_remaining = max_data_bytes - PTR_DIFF(p,pdata);
851 /* Check if we can close the dirptr */
852 if(close_after_request || (finished && close_if_end))
854 dptr_close(dptr_num); /* This frees up the saved mask */
855 DEBUG(5,("call_trans2findnext: closing dptr_num = %d\n", dptr_num));
860 /* Set up the return parameter block */
861 SSVAL(params,0,numentries);
862 SSVAL(params,2,finished);
863 SSVAL(params,4,0); /* Never an EA error */
864 SSVAL(params,6,last_name_off);
866 send_trans2_replies( outbuf, bufsize, params, 8, pdata, PTR_DIFF(p,pdata));
868 if ((! *directory) && dptr_path(dptr_num))
869 sprintf(directory,"(%s)",dptr_path(dptr_num));
871 DEBUG(3,("%s %s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n",
873 smb_fn_name(CVAL(inbuf,smb_com)),
874 mask,directory,cnum,dirtype,numentries));
879 /****************************************************************************
880 reply to a TRANS2_QFSINFO (query filesystem info)
881 ****************************************************************************/
882 static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize,
883 int cnum, char **pparams, char **ppdata)
885 char *pdata = *ppdata;
886 char *params = *pparams;
887 uint16 info_level = SVAL(params,0);
890 char *vname = volume_label(SNUM(cnum));
892 DEBUG(3,("call_trans2qfsinfo: cnum = %d, level = %d\n", cnum, info_level));
894 if(sys_stat(".",&st)!=0) {
895 DEBUG(2,("call_trans2qfsinfo: stat of . failed (%s)\n", strerror(errno)));
896 return (ERROR(ERRSRV,ERRinvdevice));
899 pdata = *ppdata = Realloc(*ppdata, 1024); bzero(pdata,1024);
905 int dfree,dsize,bsize;
907 sys_disk_free(".",&bsize,&dfree,&dsize);
908 SIVAL(pdata,l1_idFileSystem,st.st_dev);
909 SIVAL(pdata,l1_cSectorUnit,bsize/512);
910 SIVAL(pdata,l1_cUnit,dsize);
911 SIVAL(pdata,l1_cUnitAvail,dfree);
912 SSVAL(pdata,l1_cbSector,512);
913 DEBUG(5,("call_trans2qfsinfo : bsize=%d, id=%x, cSectorUnit=%d, cUnit=%d, cUnitAvail=%d, cbSector=%d\n",
914 bsize, st.st_dev, bsize/512, dsize, dfree, 512));
919 /* Return volume name */
920 int volname_len = MIN(strlen(vname),11);
921 data_len = l2_vol_szVolLabel + volname_len + 1;
922 put_dos_date2(pdata,l2_vol_fdateCreation,st.st_ctime);
923 SCVAL(pdata,l2_vol_cch,volname_len);
924 StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len);
925 DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",st.st_ctime, volname_len,
926 pdata+l2_vol_szVolLabel));
929 case SMB_QUERY_FS_ATTRIBUTE_INFO:
930 data_len = 12 + 2*strlen(FSTYPE_STRING);
931 SIVAL(pdata,0,0x4006); /* FS ATTRIBUTES == long filenames supported? */
932 SIVAL(pdata,4,128); /* Max filename component length */
933 SIVAL(pdata,8,2*strlen(FSTYPE_STRING));
934 PutUniCode(pdata+12,FSTYPE_STRING);
936 case SMB_QUERY_FS_LABEL_INFO:
937 data_len = 4 + strlen(vname);
938 SIVAL(pdata,0,strlen(vname));
939 strcpy(pdata+4,vname);
941 case SMB_QUERY_FS_VOLUME_INFO:
942 data_len = 18 + 2*strlen(vname);
943 SIVAL(pdata,12,2*strlen(vname));
944 PutUniCode(pdata+18,vname);
945 DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", strlen(vname),
948 case SMB_QUERY_FS_SIZE_INFO:
950 int dfree,dsize,bsize;
952 sys_disk_free(".",&bsize,&dfree,&dsize);
953 SIVAL(pdata,0,dsize);
954 SIVAL(pdata,8,dfree);
955 SIVAL(pdata,16,bsize/512);
959 case SMB_QUERY_FS_DEVICE_INFO:
961 SIVAL(pdata,0,0); /* dev type */
962 SIVAL(pdata,4,0); /* characteristics */
965 return(ERROR(ERRDOS,ERRunknownlevel));
969 send_trans2_replies( outbuf, bufsize, params, 0, pdata, data_len);
971 DEBUG(4,("%s %s info_level =%d\n",timestring(),smb_fn_name(CVAL(inbuf,smb_com)), info_level));
976 /****************************************************************************
977 reply to a TRANS2_SETFSINFO (set filesystem info)
978 ****************************************************************************/
979 static int call_trans2setfsinfo(char *inbuf, char *outbuf, int length, int bufsize,
980 int cnum, char **pparams, char **ppdata)
982 /* Just say yes we did it - there is nothing that
983 can be set here so it doesn't matter. */
985 DEBUG(3,("call_trans2setfsinfo\n"));
987 if (!CAN_WRITE(cnum))
988 return(ERROR(ERRSRV,ERRaccess));
990 outsize = set_message(outbuf,10,0,True);
995 /****************************************************************************
996 reply to a TRANS2_QFILEINFO (query file info by fileid)
997 ****************************************************************************/
998 static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length,
999 int bufsize,int cnum,
1000 char **pparams,char **ppdata,
1003 char *params = *pparams;
1004 char *pdata = *ppdata;
1005 uint16 tran_call = SVAL(inbuf, smb_setup0);
1009 unsigned int data_size;
1017 if (tran_call == TRANSACT2_QFILEINFO) {
1018 int16 fnum = SVALS(params,0);
1019 info_level = SVAL(params,2);
1021 CHECK_FNUM(fnum,cnum);
1024 fname = Files[fnum].name;
1025 if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) {
1026 DEBUG(3,("fstat of fnum %d failed (%s)\n",fnum, strerror(errno)));
1027 return(UNIXERROR(ERRDOS,ERRbadfid));
1029 pos = lseek(Files[fnum].fd_ptr->fd,0,SEEK_CUR);
1032 info_level = SVAL(params,0);
1034 strcpy(fname,¶ms[6]);
1035 unix_convert(fname,cnum,0);
1036 if (!check_name(fname,cnum) || sys_stat(fname,&sbuf)) {
1037 DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
1038 return(UNIXERROR(ERRDOS,ERRbadpath));
1044 DEBUG(3,("call_trans2qfilepathinfo %s level=%d call=%d total_data=%d\n",
1045 fname,info_level,tran_call,total_data));
1047 p = strrchr(fname,'/');
1053 mode = dos_mode(cnum,fname,&sbuf);
1054 size = sbuf.st_size;
1055 if (mode & aDIR) size = 0;
1057 params = *pparams = Realloc(*pparams,2); bzero(params,2);
1059 pdata = *ppdata = Realloc(*ppdata, data_size);
1061 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1062 /* uggh, EAs for OS2 */
1063 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1065 SSVAL(params,0,ERROR_EAS_NOT_SUPPORTED);
1066 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1069 return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED));
1073 bzero(pdata,data_size);
1077 case SMB_INFO_STANDARD:
1078 case SMB_INFO_QUERY_EA_SIZE:
1079 data_size = (info_level==1?22:26);
1080 put_dos_date2(pdata,l1_fdateCreation,sbuf.st_ctime); /* create = inode mod */
1081 put_dos_date2(pdata,l1_fdateLastAccess,sbuf.st_atime); /* access time */
1082 put_dos_date2(pdata,l1_fdateLastWrite,sbuf.st_mtime); /* write time */
1083 SIVAL(pdata,l1_cbFile,size);
1084 SIVAL(pdata,l1_cbFileAlloc,ROUNDUP(size,1024));
1085 SSVAL(pdata,l1_attrFile,mode);
1086 SIVAL(pdata,l1_attrFile+2,4); /* this is what OS2 does */
1089 case SMB_INFO_QUERY_EAS_FROM_LIST:
1091 put_dos_date2(pdata,0,sbuf.st_ctime); /* create time = inode mod time */
1092 put_dos_date2(pdata,4,sbuf.st_atime);
1093 put_dos_date2(pdata,8,sbuf.st_mtime);
1094 SIVAL(pdata,12,size);
1095 SIVAL(pdata,16,ROUNDUP(size,1024));
1096 SIVAL(pdata,20,mode);
1099 case SMB_INFO_QUERY_ALL_EAS:
1101 SIVAL(pdata,0,data_size);
1105 return(ERROR(ERRDOS,ERRbadfunc)); /* os/2 needs this */
1107 case SMB_QUERY_FILE_BASIC_INFO:
1108 data_size = 36; /* w95 returns 40 bytes not 36 - why ?. */
1109 put_long_date(pdata,sbuf.st_ctime); /* create time = inode mod time */
1110 put_long_date(pdata+8,sbuf.st_atime); /* access time */
1111 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1112 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1113 SIVAL(pdata,32,mode);
1115 DEBUG(5,("SMB_QFBI - "));
1116 DEBUG(5,("create: %s ", ctime(&sbuf.st_ctime)));
1117 DEBUG(5,("access: %s ", ctime(&sbuf.st_atime)));
1118 DEBUG(5,("write: %s ", ctime(&sbuf.st_mtime)));
1119 DEBUG(5,("change: %s ", ctime(&sbuf.st_mtime)));
1120 DEBUG(5,("mode: %x\n", mode));
1124 case SMB_QUERY_FILE_STANDARD_INFO:
1126 SIVAL(pdata,0,size);
1127 SIVAL(pdata,8,size);
1128 SIVAL(pdata,16,sbuf.st_nlink);
1130 CVAL(pdata,21) = (mode&aDIR)?1:0;
1133 case SMB_QUERY_FILE_EA_INFO:
1137 case SMB_QUERY_FILE_NAME_INFO:
1138 case SMB_QUERY_FILE_ALT_NAME_INFO:
1141 strcpy(pdata+4,fname);
1143 case SMB_QUERY_FILE_ALLOCATION_INFO:
1144 case SMB_QUERY_FILE_END_OF_FILEINFO:
1146 SIVAL(pdata,0,size);
1149 case SMB_QUERY_FILE_ALL_INFO:
1150 put_long_date(pdata,sbuf.st_ctime); /* create time = inode mod time */
1151 put_long_date(pdata+8,sbuf.st_atime); /* access time */
1152 put_long_date(pdata+16,sbuf.st_mtime); /* write time */
1153 put_long_date(pdata+24,sbuf.st_mtime); /* change time */
1154 SIVAL(pdata,32,mode);
1156 SIVAL(pdata,0,size);
1157 SIVAL(pdata,8,size);
1158 SIVAL(pdata,16,sbuf.st_nlink);
1160 CVAL(pdata,21) = (mode&aDIR)?1:0;
1162 pdata += 8; /* index number */
1163 pdata += 4; /* EA info */
1165 SIVAL(pdata,0,0xA9);
1167 SIVAL(pdata,0,0xd01BF);
1169 SIVAL(pdata,0,pos); /* current offset */
1171 SIVAL(pdata,0,mode); /* is this the right sort of mode info? */
1173 pdata += 4; /* alignment */
1175 strcpy(pdata+4,fname);
1177 data_size = PTR_DIFF(pdata,(*ppdata));
1180 case SMB_QUERY_FILE_STREAM_INFO:
1183 SIVAL(pdata,4,size);
1184 SIVAL(pdata,12,size);
1186 strcpy(pdata+24,fname);
1189 return(ERROR(ERRDOS,ERRunknownlevel));
1192 send_trans2_replies( outbuf, bufsize, params, 2, *ppdata, data_size);
1197 /****************************************************************************
1198 reply to a TRANS2_SETFILEINFO (set file info by fileid)
1199 ****************************************************************************/
1200 static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length,
1201 int bufsize, int cnum, char **pparams,
1202 char **ppdata, int total_data)
1204 char *params = *pparams;
1205 char *pdata = *ppdata;
1206 uint16 tran_call = SVAL(inbuf, smb_setup0);
1216 if (!CAN_WRITE(cnum))
1217 return(ERROR(ERRSRV,ERRaccess));
1219 if (tran_call == TRANSACT2_SETFILEINFO) {
1220 int16 fnum = SVALS(params,0);
1221 info_level = SVAL(params,2);
1223 CHECK_FNUM(fnum,cnum);
1226 fname = Files[fnum].name;
1227 fd = Files[fnum].fd_ptr->fd;
1229 if(fstat(fd,&st)!=0) {
1230 DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno)));
1231 return(ERROR(ERRDOS,ERRbadpath));
1235 info_level = SVAL(params,0);
1237 strcpy(fname,¶ms[6]);
1238 unix_convert(fname,cnum,0);
1239 if(!check_name(fname, cnum))
1240 return(ERROR(ERRDOS,ERRbadpath));
1242 if(sys_stat(fname,&st)!=0) {
1243 DEBUG(3,("stat of %s failed (%s)\n", fname, strerror(errno)));
1244 return(ERROR(ERRDOS,ERRbadpath));
1248 DEBUG(3,("call_trans2setfilepathinfo(%d) %s info_level=%d totdata=%d\n",
1249 tran_call,fname,info_level,total_data));
1251 /* Realloc the parameter and data sizes */
1252 params = *pparams = Realloc(*pparams,2); SSVAL(params,0,0);
1254 return(ERROR(ERRDOS,ERRnomem));
1257 tvs.modtime = st.st_mtime;
1258 tvs.actime = st.st_atime;
1259 mode = dos_mode(cnum,fname,&st);
1261 if (total_data > 0 && IVAL(pdata,0) == total_data) {
1262 /* uggh, EAs for OS2 */
1263 DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data));
1264 SSVAL(params,0,ERROR_EAS_NOT_SUPPORTED);
1266 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1273 case SMB_INFO_STANDARD:
1274 case SMB_INFO_QUERY_EA_SIZE:
1277 tvs.actime = make_unix_date2(pdata+l1_fdateLastAccess);
1280 tvs.modtime = make_unix_date2(pdata+l1_fdateLastWrite);
1282 mode = SVAL(pdata,l1_attrFile);
1283 size = IVAL(pdata,l1_cbFile);
1287 /* XXXX um, i don't think this is right.
1288 it's also not in the cifs6.txt spec.
1290 case SMB_INFO_QUERY_EAS_FROM_LIST:
1291 tvs.actime = make_unix_date2(pdata+8);
1292 tvs.modtime = make_unix_date2(pdata+12);
1293 size = IVAL(pdata,16);
1294 mode = IVAL(pdata,24);
1297 /* XXXX nor this. not in cifs6.txt, either. */
1298 case SMB_INFO_QUERY_ALL_EAS:
1299 tvs.actime = make_unix_date2(pdata+8);
1300 tvs.modtime = make_unix_date2(pdata+12);
1301 size = IVAL(pdata,16);
1302 mode = IVAL(pdata,24);
1305 case SMB_SET_FILE_BASIC_INFO:
1307 /* Ignore create time at offset pdata. */
1310 tvs.actime = interpret_long_date(pdata+8);
1312 /* write time + changed time, combined. */
1313 tvs.modtime=MAX(interpret_long_date(pdata+16),
1314 interpret_long_date(pdata+24));
1317 mode = IVAL(pdata,32);
1321 case SMB_SET_FILE_END_OF_FILE_INFO:
1323 if (IVAL(pdata,4) != 0) /* more than 32 bits? */
1324 return(ERROR(ERRDOS,ERRunknownlevel));
1325 size = IVAL(pdata,0);
1329 case SMB_SET_FILE_DISPOSITION_INFO: /* not supported yet */
1330 case SMB_SET_FILE_ALLOCATION_INFO: /* not supported yet */
1333 return(ERROR(ERRDOS,ERRunknownlevel));
1337 DEBUG(6,("actime: %s " , ctime(&tvs.actime)));
1338 DEBUG(6,("modtime: %s ", ctime(&tvs.modtime)));
1339 DEBUG(6,("size: %x " , size));
1340 DEBUG(6,("mode: %x\n" , mode));
1342 /* get some defaults (no modifications) if any info is zero. */
1343 if (!tvs.actime) tvs.actime = st.st_atime;
1344 if (!tvs.modtime) tvs.modtime = st.st_mtime;
1345 if (!size) size = st.st_size;
1347 /* Try and set the times, size and mode of this file -
1348 if they are different from the current values
1350 if (st.st_mtime != tvs.modtime || st.st_atime != tvs.actime)
1352 if(sys_utime(fname, &tvs)!=0)
1354 return(ERROR(ERRDOS,ERRnoaccess));
1358 /* check the mode isn't different, before changing it */
1359 if (mode != dos_mode(cnum, fname, &st) && dos_chmod(cnum, fname, mode, NULL))
1361 DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
1362 return(ERROR(ERRDOS,ERRnoaccess));
1365 if(size != st.st_size)
1369 fd = sys_open(fname,O_RDWR,0);
1372 return(ERROR(ERRDOS,ERRbadpath));
1374 set_filelen(fd, size);
1379 set_filelen(fd, size);
1385 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1390 /****************************************************************************
1391 reply to a TRANS2_MKDIR (make directory with extended attributes).
1392 ****************************************************************************/
1393 static int call_trans2mkdir(char *inbuf, char *outbuf, int length, int bufsize,
1394 int cnum, char **pparams, char **ppdata)
1396 char *params = *pparams;
1400 if (!CAN_WRITE(cnum))
1401 return(ERROR(ERRSRV,ERRaccess));
1403 strcpy(directory, ¶ms[4]);
1405 DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
1407 unix_convert(directory,cnum,0);
1408 if (check_name(directory,cnum))
1409 ret = sys_mkdir(directory,unix_mode(cnum,aDIR));
1413 DEBUG(5,("call_trans2mkdir error (%s)\n", strerror(errno)));
1414 return(UNIXERROR(ERRDOS,ERRnoaccess));
1417 /* Realloc the parameter and data sizes */
1418 params = *pparams = Realloc(*pparams,2);
1420 return(ERROR(ERRDOS,ERRnomem));
1424 send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0);
1429 /****************************************************************************
1430 reply to a TRANS2_FINDNOTIFYFIRST (start monitoring a directory for changes)
1431 We don't actually do this - we just send a null response.
1432 ****************************************************************************/
1433 static int call_trans2findnotifyfirst(char *inbuf, char *outbuf, int length, int bufsize,
1434 int cnum, char **pparams, char **ppdata)
1436 static uint16 fnf_handle = 257;
1437 char *params = *pparams;
1438 uint16 info_level = SVAL(params,4);
1440 DEBUG(3,("call_trans2findnotifyfirst - info_level %d\n", info_level));
1448 return(ERROR(ERRDOS,ERRunknownlevel));
1451 /* Realloc the parameter and data sizes */
1452 params = *pparams = Realloc(*pparams,6);
1454 return(ERROR(ERRDOS,ERRnomem));
1456 SSVAL(params,0,fnf_handle);
1457 SSVAL(params,2,0); /* No changes */
1458 SSVAL(params,4,0); /* No EA errors */
1465 send_trans2_replies(outbuf, bufsize, params, 6, *ppdata, 0);
1470 /****************************************************************************
1471 reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
1472 changes). Currently this does nothing.
1473 ****************************************************************************/
1474 static int call_trans2findnotifynext(char *inbuf, char *outbuf, int length, int bufsize,
1475 int cnum, char **pparams, char **ppdata)
1477 char *params = *pparams;
1479 DEBUG(3,("call_trans2findnotifynext\n"));
1481 /* Realloc the parameter and data sizes */
1482 params = *pparams = Realloc(*pparams,4);
1484 return(ERROR(ERRDOS,ERRnomem));
1486 SSVAL(params,0,0); /* No changes */
1487 SSVAL(params,2,0); /* No EA errors */
1489 send_trans2_replies(outbuf, bufsize, params, 4, *ppdata, 0);
1494 /****************************************************************************
1495 reply to a SMBfindclose (stop trans2 directory search)
1496 ****************************************************************************/
1497 int reply_findclose(char *inbuf,char *outbuf,int length,int bufsize)
1501 int16 dptr_num=SVALS(inbuf,smb_vwv0);
1503 cnum = SVAL(inbuf,smb_tid);
1505 DEBUG(3,("reply_findclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num));
1507 dptr_close(dptr_num);
1509 outsize = set_message(outbuf,0,0,True);
1511 DEBUG(3,("%s SMBfindclose cnum=%d, dptr_num = %d\n",timestring(),cnum,dptr_num));
1516 /****************************************************************************
1517 reply to a SMBfindnclose (stop FINDNOTIFYFIRST directory search)
1518 ****************************************************************************/
1519 int reply_findnclose(char *inbuf,char *outbuf,int length,int bufsize)
1525 cnum = SVAL(inbuf,smb_tid);
1526 dptr_num = SVAL(inbuf,smb_vwv0);
1528 DEBUG(3,("reply_findnclose, cnum = %d, dptr_num = %d\n", cnum, dptr_num));
1530 /* We never give out valid handles for a
1531 findnotifyfirst - so any dptr_num is ok here.
1534 outsize = set_message(outbuf,0,0,True);
1536 DEBUG(3,("%s SMB_findnclose cnum=%d, dptr_num = %d\n",timestring(),cnum,dptr_num));
1542 /****************************************************************************
1543 reply to a SMBtranss2 - just ignore it!
1544 ****************************************************************************/
1545 int reply_transs2(char *inbuf,char *outbuf,int length,int bufsize)
1547 DEBUG(4,("Ignoring transs2 of length %d\n",length));
1551 /****************************************************************************
1552 reply to a SMBtrans2
1553 ****************************************************************************/
1554 int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize)
1557 int cnum = SVAL(inbuf,smb_tid);
1558 unsigned int total_params = SVAL(inbuf, smb_tpscnt);
1559 unsigned int total_data =SVAL(inbuf, smb_tdscnt);
1561 unsigned int max_param_reply = SVAL(inbuf, smb_mprcnt);
1562 unsigned int max_data_reply = SVAL(inbuf, smb_mdrcnt);
1563 unsigned int max_setup_fields = SVAL(inbuf, smb_msrcnt);
1564 BOOL close_tid = BITSETW(inbuf+smb_flags,0);
1565 BOOL no_final_response = BITSETW(inbuf+smb_flags,1);
1566 int32 timeout = IVALS(inbuf,smb_timeout);
1568 unsigned int suwcnt = SVAL(inbuf, smb_suwcnt);
1569 unsigned int tran_call = SVAL(inbuf, smb_setup0);
1570 char *params = NULL, *data = NULL;
1571 int num_params, num_params_sofar, num_data, num_data_sofar;
1573 outsize = set_message(outbuf,0,0,True);
1575 /* All trans2 messages we handle have smb_sucnt == 1 - ensure this
1576 is so as a sanity check */
1579 DEBUG(2,("Invalid smb_sucnt in trans2 call\n"));
1580 return(ERROR(ERRSRV,ERRerror));
1583 /* Allocate the space for the maximum needed parameters and data */
1584 if (total_params > 0)
1585 params = (char *)malloc(total_params);
1587 data = (char *)malloc(total_data);
1589 if ((total_params && !params) || (total_data && !data))
1591 DEBUG(2,("Out of memory in reply_trans2\n"));
1592 return(ERROR(ERRDOS,ERRnomem));
1595 /* Copy the param and data bytes sent with this request into
1596 the params buffer */
1597 num_params = num_params_sofar = SVAL(inbuf,smb_pscnt);
1598 num_data = num_data_sofar = SVAL(inbuf, smb_dscnt);
1600 memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params);
1601 memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data);
1603 if(num_data_sofar < total_data || num_params_sofar < total_params)
1605 /* We need to send an interim response then receive the rest
1606 of the parameter/data bytes */
1607 outsize = set_message(outbuf,0,0,True);
1608 send_smb(Client,outbuf);
1610 while( num_data_sofar < total_data || num_params_sofar < total_params)
1612 if(!receive_smb(Client,inbuf, SMB_SECONDARY_WAIT) ||
1613 CVAL(inbuf, smb_com) != SMBtranss2)
1615 outsize = set_message(outbuf,0,0,True);
1616 DEBUG(2,("Invalid secondary trans2 packet\n"));
1619 return(ERROR(ERRSRV,ERRerror));
1622 /* Revise total_params and total_data in case they have changed downwards */
1623 total_params = SVAL(inbuf, smb_tpscnt);
1624 total_data = SVAL(inbuf, smb_tdscnt);
1625 num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt));
1626 num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt));
1627 memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)],
1628 smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params);
1629 memcpy( &data[SVAL(inbuf, smb_sdsdisp)],
1630 smb_base(inbuf)+ SVAL(inbuf, smb_sdsoff), num_data);
1634 if (Protocol >= PROTOCOL_NT1) {
1635 uint16 flg2 = SVAL(outbuf,smb_flg2);
1636 SSVAL(outbuf,smb_flg2,flg2 | 0x40); /* IS_LONG_NAME */
1639 /* Now we must call the relevant TRANS2 function */
1642 case TRANSACT2_OPEN:
1643 outsize = call_trans2open(inbuf, outbuf, bufsize, cnum, ¶ms, &data);
1645 case TRANSACT2_FINDFIRST:
1646 outsize = call_trans2findfirst(inbuf, outbuf, bufsize, cnum, ¶ms, &data);
1648 case TRANSACT2_FINDNEXT:
1649 outsize = call_trans2findnext(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1651 case TRANSACT2_QFSINFO:
1652 outsize = call_trans2qfsinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1654 case TRANSACT2_SETFSINFO:
1655 outsize = call_trans2setfsinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1657 case TRANSACT2_QPATHINFO:
1658 case TRANSACT2_QFILEINFO:
1659 outsize = call_trans2qfilepathinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data, total_data);
1661 case TRANSACT2_SETPATHINFO:
1662 case TRANSACT2_SETFILEINFO:
1663 outsize = call_trans2setfilepathinfo(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data, total_data);
1665 case TRANSACT2_FINDNOTIFYFIRST:
1666 outsize = call_trans2findnotifyfirst(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1668 case TRANSACT2_FINDNOTIFYNEXT:
1669 outsize = call_trans2findnotifynext(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1671 case TRANSACT2_MKDIR:
1672 outsize = call_trans2mkdir(inbuf, outbuf, length, bufsize, cnum, ¶ms, &data);
1675 /* Error in request */
1676 DEBUG(2,("%s Unknown request %d in trans2 call\n",timestring(), tran_call));
1681 return (ERROR(ERRSRV,ERRerror));
1684 /* As we do not know how many data packets will need to be
1685 returned here the various call_trans2xxxx calls
1686 must send their own. Thus a call_trans2xxx routine only
1687 returns a value other than -1 when it wants to send
1695 return outsize; /* If a correct response was needed the call_trans2xxx
1696 calls have already sent it. If outsize != -1 then it is
1697 returning an error packet. */