xref: /onnv-gate/usr/src/lib/libsmbfs/smb/file.c (revision 11332:ed3411181494)
16007Sthurlow /*
26007Sthurlow  * Copyright (c) 2000, Boris Popov
36007Sthurlow  * All rights reserved.
46007Sthurlow  *
56007Sthurlow  * Redistribution and use in source and binary forms, with or without
66007Sthurlow  * modification, are permitted provided that the following conditions
76007Sthurlow  * are met:
86007Sthurlow  * 1. Redistributions of source code must retain the above copyright
96007Sthurlow  *    notice, this list of conditions and the following disclaimer.
106007Sthurlow  * 2. Redistributions in binary form must reproduce the above copyright
116007Sthurlow  *    notice, this list of conditions and the following disclaimer in the
126007Sthurlow  *    documentation and/or other materials provided with the distribution.
136007Sthurlow  * 3. All advertising materials mentioning features or use of this software
146007Sthurlow  *    must display the following acknowledgement:
156007Sthurlow  *    This product includes software developed by Boris Popov.
166007Sthurlow  * 4. Neither the name of the author nor the names of any co-contributors
176007Sthurlow  *    may be used to endorse or promote products derived from this software
186007Sthurlow  *    without specific prior written permission.
196007Sthurlow  *
206007Sthurlow  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
216007Sthurlow  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
226007Sthurlow  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
236007Sthurlow  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
246007Sthurlow  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
256007Sthurlow  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
266007Sthurlow  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
276007Sthurlow  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
286007Sthurlow  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
296007Sthurlow  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
306007Sthurlow  * SUCH DAMAGE.
316007Sthurlow  *
326007Sthurlow  * $Id: file.c,v 1.4 2004/12/13 00:25:21 lindak Exp $
336007Sthurlow  */
346007Sthurlow 
358271SGordon.Ross@Sun.COM /*
3610023SGordon.Ross@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
378271SGordon.Ross@Sun.COM  * Use is subject to license terms.
388271SGordon.Ross@Sun.COM  */
396007Sthurlow 
406007Sthurlow #include <sys/param.h>
416007Sthurlow #include <sys/ioctl.h>
426007Sthurlow #include <sys/time.h>
436007Sthurlow #include <sys/mount.h>
446007Sthurlow #include <fcntl.h>
456007Sthurlow #include <ctype.h>
466007Sthurlow #include <errno.h>
476007Sthurlow #include <stdio.h>
486007Sthurlow #include <string.h>
496007Sthurlow #include <strings.h>
506007Sthurlow #include <stdlib.h>
516007Sthurlow #include <pwd.h>
526007Sthurlow #include <grp.h>
536007Sthurlow #include <unistd.h>
548271SGordon.Ross@Sun.COM #include <libintl.h>
556007Sthurlow 
566007Sthurlow #include <sys/types.h>
578271SGordon.Ross@Sun.COM #include <sys/file.h>
586007Sthurlow 
5910023SGordon.Ross@Sun.COM #include <netsmb/smb.h>
606007Sthurlow #include <netsmb/smb_lib.h>
616007Sthurlow 
628271SGordon.Ross@Sun.COM #include "private.h"
638271SGordon.Ross@Sun.COM 
646007Sthurlow int
smb_fh_close(struct smb_ctx * ctx,int fh)6510023SGordon.Ross@Sun.COM smb_fh_close(struct smb_ctx *ctx, int fh)
668271SGordon.Ross@Sun.COM {
678271SGordon.Ross@Sun.COM 	struct smb_rq	*rqp;
688271SGordon.Ross@Sun.COM 	struct mbdata	*mbp;
6910023SGordon.Ross@Sun.COM 	int error;
708271SGordon.Ross@Sun.COM 
7110023SGordon.Ross@Sun.COM 	error = smb_rq_init(ctx, SMB_COM_CLOSE, &rqp);
7210023SGordon.Ross@Sun.COM 	if (error != 0)
7310023SGordon.Ross@Sun.COM 		return (error);
748271SGordon.Ross@Sun.COM 	mbp = smb_rq_getrequest(rqp);
7510023SGordon.Ross@Sun.COM 	smb_rq_wstart(rqp);
7610023SGordon.Ross@Sun.COM 	mb_put_uint16le(mbp, (uint16_t)fh);
778271SGordon.Ross@Sun.COM 	mb_put_uint32le(mbp, 0);	/* time stamp */
788271SGordon.Ross@Sun.COM 	smb_rq_wend(rqp);
7910023SGordon.Ross@Sun.COM 	mb_put_uint16le(mbp, 0);	/* byte count */
8010023SGordon.Ross@Sun.COM 
8110023SGordon.Ross@Sun.COM 	error = smb_rq_simple(rqp);
828271SGordon.Ross@Sun.COM 	smb_rq_done(rqp);
838271SGordon.Ross@Sun.COM 
8410023SGordon.Ross@Sun.COM 	return (error);
858271SGordon.Ross@Sun.COM }
868271SGordon.Ross@Sun.COM 
878271SGordon.Ross@Sun.COM int
smb_fh_ntcreate(struct smb_ctx * ctx,char * path,int flags,int req_acc,int efattr,int share_acc,int open_disp,int create_opts,int impersonation,int * fhp,uint32_t * action_taken)888271SGordon.Ross@Sun.COM smb_fh_ntcreate(
898271SGordon.Ross@Sun.COM 	struct smb_ctx *ctx, char *path,
908271SGordon.Ross@Sun.COM 	int flags, int req_acc, int efattr,
918271SGordon.Ross@Sun.COM 	int share_acc, int open_disp,
928271SGordon.Ross@Sun.COM 	int create_opts, int impersonation,
9310023SGordon.Ross@Sun.COM 	int *fhp, uint32_t *action_taken)
948271SGordon.Ross@Sun.COM {
958271SGordon.Ross@Sun.COM 	struct smb_rq	*rqp;
968271SGordon.Ross@Sun.COM 	struct mbdata	*mbp;
9710023SGordon.Ross@Sun.COM 	char		*pathsizep;
9810023SGordon.Ross@Sun.COM 	int		pathstart, pathsize;
9910023SGordon.Ross@Sun.COM 	int		error, flags2, uc;
10010023SGordon.Ross@Sun.COM 	uint16_t	fh;
1018271SGordon.Ross@Sun.COM 	uint8_t		wc;
1028271SGordon.Ross@Sun.COM 
1038271SGordon.Ross@Sun.COM 	flags2 = smb_ctx_flags2(ctx);
1048271SGordon.Ross@Sun.COM 	if (flags2 == -1)
1058271SGordon.Ross@Sun.COM 		return (EIO);
10610023SGordon.Ross@Sun.COM 	uc = flags2 & SMB_FLAGS2_UNICODE;
1078271SGordon.Ross@Sun.COM 
10810023SGordon.Ross@Sun.COM 	error = smb_rq_init(ctx, SMB_COM_NT_CREATE_ANDX, &rqp);
1098271SGordon.Ross@Sun.COM 	if (error != 0)
1108271SGordon.Ross@Sun.COM 		return (error);
1118271SGordon.Ross@Sun.COM 
1128271SGordon.Ross@Sun.COM 	mbp = smb_rq_getrequest(rqp);
11310023SGordon.Ross@Sun.COM 	smb_rq_wstart(rqp);
11410023SGordon.Ross@Sun.COM 	mb_put_uint16le(mbp, 0xff);	/* secondary command */
1158271SGordon.Ross@Sun.COM 	mb_put_uint16le(mbp, 0);	/* offset to next command (none) */
11610023SGordon.Ross@Sun.COM 	mb_put_uint8(mbp, 0);		/* MBZ (pad?) */
117*11332SGordon.Ross@Sun.COM 	(void) mb_fit(mbp, 2, &pathsizep); /* path size - fill in below */
11810023SGordon.Ross@Sun.COM 	mb_put_uint32le(mbp, flags);	/* create flags (oplock) */
1198271SGordon.Ross@Sun.COM 	mb_put_uint32le(mbp, 0);	/* FID - basis for path if not root */
1208271SGordon.Ross@Sun.COM 	mb_put_uint32le(mbp, req_acc);
1218271SGordon.Ross@Sun.COM 	mb_put_uint64le(mbp, 0);		/* initial alloc. size */
1228271SGordon.Ross@Sun.COM 	mb_put_uint32le(mbp, efattr);		/* ext. file attributes */
1238271SGordon.Ross@Sun.COM 	mb_put_uint32le(mbp, share_acc);	/* share access mode */
1248271SGordon.Ross@Sun.COM 	mb_put_uint32le(mbp, open_disp);	/* open disposition */
1258271SGordon.Ross@Sun.COM 	mb_put_uint32le(mbp, create_opts);  /* create_options */
12610023SGordon.Ross@Sun.COM 	mb_put_uint32le(mbp, impersonation);
1278271SGordon.Ross@Sun.COM 	mb_put_uint8(mbp, 0);	/* security flags (?) */
1288271SGordon.Ross@Sun.COM 	smb_rq_wend(rqp);
12910023SGordon.Ross@Sun.COM 	smb_rq_bstart(rqp);
13010023SGordon.Ross@Sun.COM 	if (uc) {
13110023SGordon.Ross@Sun.COM 		/*
13210023SGordon.Ross@Sun.COM 		 * We're about to put a unicode string.  We know
13310023SGordon.Ross@Sun.COM 		 * we're misaligned at this point, and need to
13410023SGordon.Ross@Sun.COM 		 * save the mb_count at the start of the string,
13510023SGordon.Ross@Sun.COM 		 * not at the alignment padding placed before it.
13610023SGordon.Ross@Sun.COM 		 * So add the algnment padding by hand here.
13710023SGordon.Ross@Sun.COM 		 */
13810023SGordon.Ross@Sun.COM 		mb_put_uint8(mbp, 0);
13910023SGordon.Ross@Sun.COM 	}
14010023SGordon.Ross@Sun.COM 	pathstart = mbp->mb_count;
141*11332SGordon.Ross@Sun.COM 	mb_put_string(mbp, path, uc);
14210023SGordon.Ross@Sun.COM 	smb_rq_bend(rqp);
1438271SGordon.Ross@Sun.COM 
14410023SGordon.Ross@Sun.COM 	/* Now go back and fill in pathsizep */
14510023SGordon.Ross@Sun.COM 	pathsize = mbp->mb_count - pathstart;
14610023SGordon.Ross@Sun.COM 	pathsizep[0] = pathsize & 0xFF;
14710023SGordon.Ross@Sun.COM 	pathsizep[1] = (pathsize >> 8);
1488271SGordon.Ross@Sun.COM 
1498271SGordon.Ross@Sun.COM 	error = smb_rq_simple(rqp);
1508271SGordon.Ross@Sun.COM 	if (error)
1518271SGordon.Ross@Sun.COM 		goto out;
1528271SGordon.Ross@Sun.COM 
1538271SGordon.Ross@Sun.COM 	mbp = smb_rq_getreply(rqp);
1548271SGordon.Ross@Sun.COM 	/*
1558271SGordon.Ross@Sun.COM 	 * spec says 26 for word count, but 34 words are defined
1568271SGordon.Ross@Sun.COM 	 * and observed from win2000
1578271SGordon.Ross@Sun.COM 	 */
158*11332SGordon.Ross@Sun.COM 	error = md_get_uint8(mbp, &wc);
15910023SGordon.Ross@Sun.COM 	if (error || wc < 26) {
1608271SGordon.Ross@Sun.COM 		smb_error(dgettext(TEXT_DOMAIN,
1618271SGordon.Ross@Sun.COM 		    "%s: open failed, bad word count"), 0, path);
1628271SGordon.Ross@Sun.COM 		error = EBADRPC;
1638271SGordon.Ross@Sun.COM 		goto out;
1648271SGordon.Ross@Sun.COM 	}
165*11332SGordon.Ross@Sun.COM 	md_get_uint8(mbp, NULL);	/* secondary cmd */
166*11332SGordon.Ross@Sun.COM 	md_get_uint8(mbp, NULL);	/* mbz */
167*11332SGordon.Ross@Sun.COM 	md_get_uint16le(mbp, NULL);	/* andxoffset */
168*11332SGordon.Ross@Sun.COM 	md_get_uint8(mbp, NULL);	/* oplock lvl granted */
169*11332SGordon.Ross@Sun.COM 	md_get_uint16le(mbp, &fh);	/* FID */
170*11332SGordon.Ross@Sun.COM 	md_get_uint32le(mbp, action_taken);
1718271SGordon.Ross@Sun.COM #if 0	/* skip decoding the rest */
172*11332SGordon.Ross@Sun.COM 	md_get_uint64le(mbp, NULL);	/* creation time */
173*11332SGordon.Ross@Sun.COM 	md_get_uint64le(mbp, NULL);	/* access time */
174*11332SGordon.Ross@Sun.COM 	md_get_uint64le(mbp, NULL);	/* write time */
175*11332SGordon.Ross@Sun.COM 	md_get_uint64le(mbp, NULL);	/* change time */
176*11332SGordon.Ross@Sun.COM 	md_get_uint32le(mbp, NULL);	/* attributes */
177*11332SGordon.Ross@Sun.COM 	md_get_uint64le(mbp, NULL);	/* allocation size */
178*11332SGordon.Ross@Sun.COM 	md_get_uint64le(mbp, NULL);	/* EOF */
179*11332SGordon.Ross@Sun.COM 	md_get_uint16le(mbp, NULL);	/* file type */
180*11332SGordon.Ross@Sun.COM 	md_get_uint16le(mbp, NULL);	/* device state */
181*11332SGordon.Ross@Sun.COM 	md_get_uint8(mbp, NULL);	/* directory (boolean) */
18210023SGordon.Ross@Sun.COM #endif
18310023SGordon.Ross@Sun.COM 
18410023SGordon.Ross@Sun.COM 	/* success! */
18510023SGordon.Ross@Sun.COM 	*fhp = fh;
18610023SGordon.Ross@Sun.COM 	error = 0;
1878271SGordon.Ross@Sun.COM 
1888271SGordon.Ross@Sun.COM out:
1898271SGordon.Ross@Sun.COM 	smb_rq_done(rqp);
1908271SGordon.Ross@Sun.COM 
19110023SGordon.Ross@Sun.COM 	return (error);
1928271SGordon.Ross@Sun.COM }
1938271SGordon.Ross@Sun.COM 
1948271SGordon.Ross@Sun.COM /*
1958271SGordon.Ross@Sun.COM  * Conveinence wrapper for smb_fh_ntcreate
1968271SGordon.Ross@Sun.COM  * Converts Unix-style open call to NTCreate.
1978271SGordon.Ross@Sun.COM  */
1988271SGordon.Ross@Sun.COM int
smb_fh_open(struct smb_ctx * ctx,const char * path,int oflag,int * fhp)19910023SGordon.Ross@Sun.COM smb_fh_open(struct smb_ctx *ctx, const char *path, int oflag, int *fhp)
2008271SGordon.Ross@Sun.COM {
2018271SGordon.Ross@Sun.COM 	int error, mode, open_disp, req_acc, share_acc;
2028271SGordon.Ross@Sun.COM 	char *p, *ntpath = NULL;
2038271SGordon.Ross@Sun.COM 
2048271SGordon.Ross@Sun.COM 	/*
2058271SGordon.Ross@Sun.COM 	 * Map O_RDONLY, O_WRONLY, O_RDWR
2068271SGordon.Ross@Sun.COM 	 * to FREAD, FWRITE
2078271SGordon.Ross@Sun.COM 	 */
2088271SGordon.Ross@Sun.COM 	mode = (oflag & 3) + 1;
2098271SGordon.Ross@Sun.COM 
2108271SGordon.Ross@Sun.COM 	/*
2118271SGordon.Ross@Sun.COM 	 * Compute requested access, share access.
2128271SGordon.Ross@Sun.COM 	 */
2138271SGordon.Ross@Sun.COM 	req_acc = (
2148271SGordon.Ross@Sun.COM 	    STD_RIGHT_READ_CONTROL_ACCESS |
2158271SGordon.Ross@Sun.COM 	    STD_RIGHT_SYNCHRONIZE_ACCESS);
2168271SGordon.Ross@Sun.COM 	share_acc = NTCREATEX_SHARE_ACCESS_NONE;
2178271SGordon.Ross@Sun.COM 	if (mode & FREAD) {
2188271SGordon.Ross@Sun.COM 		req_acc |= (
2198271SGordon.Ross@Sun.COM 		    SA_RIGHT_FILE_READ_DATA |
2208271SGordon.Ross@Sun.COM 		    SA_RIGHT_FILE_READ_EA |
2218271SGordon.Ross@Sun.COM 		    SA_RIGHT_FILE_READ_ATTRIBUTES);
2228271SGordon.Ross@Sun.COM 		share_acc |= NTCREATEX_SHARE_ACCESS_READ;
2238271SGordon.Ross@Sun.COM 	}
2248271SGordon.Ross@Sun.COM 	if (mode & FWRITE) {
2258271SGordon.Ross@Sun.COM 		req_acc |= (
2268271SGordon.Ross@Sun.COM 		    SA_RIGHT_FILE_WRITE_DATA |
2278271SGordon.Ross@Sun.COM 		    SA_RIGHT_FILE_APPEND_DATA |
2288271SGordon.Ross@Sun.COM 		    SA_RIGHT_FILE_WRITE_EA |
2298271SGordon.Ross@Sun.COM 		    SA_RIGHT_FILE_WRITE_ATTRIBUTES);
2308271SGordon.Ross@Sun.COM 		share_acc |= NTCREATEX_SHARE_ACCESS_WRITE;
2318271SGordon.Ross@Sun.COM 	}
2328271SGordon.Ross@Sun.COM 
2338271SGordon.Ross@Sun.COM 	/*
2348271SGordon.Ross@Sun.COM 	 * Compute open disposition
2358271SGordon.Ross@Sun.COM 	 */
2368271SGordon.Ross@Sun.COM 	if (oflag & FCREAT) {
2378271SGordon.Ross@Sun.COM 		/* Creat if necessary. */
2388271SGordon.Ross@Sun.COM 		if (oflag & FEXCL) {
2398271SGordon.Ross@Sun.COM 			/* exclusive */
2408271SGordon.Ross@Sun.COM 			open_disp = NTCREATEX_DISP_CREATE;
2418271SGordon.Ross@Sun.COM 		} else if (oflag & FTRUNC)
2428271SGordon.Ross@Sun.COM 			open_disp = NTCREATEX_DISP_OVERWRITE_IF;
2438271SGordon.Ross@Sun.COM 		else
2448271SGordon.Ross@Sun.COM 			open_disp = NTCREATEX_DISP_OPEN_IF;
2458271SGordon.Ross@Sun.COM 	} else {
2468271SGordon.Ross@Sun.COM 		/* Not creating. */
2478271SGordon.Ross@Sun.COM 		if (oflag & FTRUNC)
2488271SGordon.Ross@Sun.COM 			open_disp = NTCREATEX_DISP_OVERWRITE;
2498271SGordon.Ross@Sun.COM 		else
2508271SGordon.Ross@Sun.COM 			open_disp = NTCREATEX_DISP_OPEN;
2518271SGordon.Ross@Sun.COM 	}
2528271SGordon.Ross@Sun.COM 
2538271SGordon.Ross@Sun.COM 	/*
2548271SGordon.Ross@Sun.COM 	 * Convert Unix path to NT (backslashes)
2558271SGordon.Ross@Sun.COM 	 */
2568271SGordon.Ross@Sun.COM 	ntpath = strdup(path);
2578271SGordon.Ross@Sun.COM 	if (ntpath == NULL)
2588271SGordon.Ross@Sun.COM 		return (ENOMEM);
2598271SGordon.Ross@Sun.COM 	for (p = ntpath; *p; p++)
2608271SGordon.Ross@Sun.COM 		if (*p == '/')
2618271SGordon.Ross@Sun.COM 			*p = '\\';
2628271SGordon.Ross@Sun.COM 
2638271SGordon.Ross@Sun.COM 	error = smb_fh_ntcreate(ctx, ntpath, 0, /* flags */
2648271SGordon.Ross@Sun.COM 	    req_acc, SMB_EFA_NORMAL, share_acc, open_disp,
2658271SGordon.Ross@Sun.COM 	    NTCREATEX_OPTIONS_NON_DIRECTORY_FILE,
2668271SGordon.Ross@Sun.COM 	    NTCREATEX_IMPERSONATION_IMPERSONATION,
2678271SGordon.Ross@Sun.COM 	    fhp, NULL);
2688271SGordon.Ross@Sun.COM 	free(ntpath);
2698271SGordon.Ross@Sun.COM 
2708271SGordon.Ross@Sun.COM 	return (error);
2718271SGordon.Ross@Sun.COM }
2728271SGordon.Ross@Sun.COM 
2738271SGordon.Ross@Sun.COM int
smb_fh_read(struct smb_ctx * ctx,int fh,off_t offset,size_t count,char * dst)27410023SGordon.Ross@Sun.COM smb_fh_read(struct smb_ctx *ctx, int fh, off_t offset, size_t count,
2758271SGordon.Ross@Sun.COM 	char *dst)
2766007Sthurlow {
2776007Sthurlow 	struct smbioc_rw rwrq;
2786007Sthurlow 
2796007Sthurlow 	bzero(&rwrq, sizeof (rwrq));
2806007Sthurlow 	rwrq.ioc_fh = fh;
2816007Sthurlow 	rwrq.ioc_base = dst;
2826007Sthurlow 	rwrq.ioc_cnt = count;
2836007Sthurlow 	rwrq.ioc_offset = offset;
28410023SGordon.Ross@Sun.COM 	if (ioctl(ctx->ct_dev_fd, SMBIOC_READ, &rwrq) == -1) {
2856007Sthurlow 		return (-1);
2866007Sthurlow 	}
2876007Sthurlow 	return (rwrq.ioc_cnt);
2886007Sthurlow }
2896007Sthurlow 
2906007Sthurlow int
smb_fh_write(struct smb_ctx * ctx,int fh,off_t offset,size_t count,const char * src)29110023SGordon.Ross@Sun.COM smb_fh_write(struct smb_ctx *ctx, int fh, off_t offset, size_t count,
2926007Sthurlow 	const char *src)
2936007Sthurlow {
2946007Sthurlow 	struct smbioc_rw rwrq;
2956007Sthurlow 
2966007Sthurlow 	bzero(&rwrq, sizeof (rwrq));
2976007Sthurlow 	rwrq.ioc_fh = fh;
2986007Sthurlow 	rwrq.ioc_base = (char *)src;
2996007Sthurlow 	rwrq.ioc_cnt = count;
3006007Sthurlow 	rwrq.ioc_offset = offset;
30110023SGordon.Ross@Sun.COM 	if (ioctl(ctx->ct_dev_fd, SMBIOC_WRITE, &rwrq) == -1) {
3026007Sthurlow 		return (-1);
3036007Sthurlow 	}
3046007Sthurlow 	return (rwrq.ioc_cnt);
3056007Sthurlow }
3068271SGordon.Ross@Sun.COM 
3078271SGordon.Ross@Sun.COM /*
3088271SGordon.Ross@Sun.COM  * Do a TRANSACT_NAMED_PIPE, which is basically just a
3098271SGordon.Ross@Sun.COM  * pipe write and pipe read, all in one round trip.
3108271SGordon.Ross@Sun.COM  *
3118271SGordon.Ross@Sun.COM  * tdlen, tdata describe the data to send.
3128271SGordon.Ross@Sun.COM  * rdlen, rdata on input describe the receive buffer,
3138271SGordon.Ross@Sun.COM  * and on output *rdlen is the received length.
3148271SGordon.Ross@Sun.COM  */
3158271SGordon.Ross@Sun.COM int
smb_fh_xactnp(struct smb_ctx * ctx,int fh,int tdlen,const char * tdata,int * rdlen,char * rdata,int * more)31610023SGordon.Ross@Sun.COM smb_fh_xactnp(struct smb_ctx *ctx, int fh,
3178271SGordon.Ross@Sun.COM 	int tdlen, const char *tdata,	/* transmit */
3188271SGordon.Ross@Sun.COM 	int *rdlen, char *rdata,	/* receive */
3198271SGordon.Ross@Sun.COM 	int *more)
3208271SGordon.Ross@Sun.COM {
3218271SGordon.Ross@Sun.COM 	int		err, rparamcnt;
3228271SGordon.Ross@Sun.COM 	uint16_t	setup[2];
3238271SGordon.Ross@Sun.COM 
3248271SGordon.Ross@Sun.COM 	setup[0] = TRANS_TRANSACT_NAMED_PIPE;
3258271SGordon.Ross@Sun.COM 	setup[1] = fh;
3268271SGordon.Ross@Sun.COM 	rparamcnt = 0;
3278271SGordon.Ross@Sun.COM 
3288271SGordon.Ross@Sun.COM 	err = smb_t2_request(ctx, 2, setup, "\\PIPE\\",
3298271SGordon.Ross@Sun.COM 	    0, NULL,	/* TX paramcnt, params */
3308271SGordon.Ross@Sun.COM 	    tdlen, (void *)tdata,
3318271SGordon.Ross@Sun.COM 	    &rparamcnt, NULL,	/* no RX params */
3328271SGordon.Ross@Sun.COM 	    rdlen, rdata, more);
3338271SGordon.Ross@Sun.COM 
3348271SGordon.Ross@Sun.COM 	if (err)
3358271SGordon.Ross@Sun.COM 		*rdlen = 0;
3368271SGordon.Ross@Sun.COM 
3378271SGordon.Ross@Sun.COM 	return (err);
3388271SGordon.Ross@Sun.COM }
339