14bff34e3Sthurlow /*
24bff34e3Sthurlow * Copyright (c) 2000-2001, Boris Popov
34bff34e3Sthurlow * All rights reserved.
44bff34e3Sthurlow *
54bff34e3Sthurlow * Redistribution and use in source and binary forms, with or without
64bff34e3Sthurlow * modification, are permitted provided that the following conditions
74bff34e3Sthurlow * are met:
84bff34e3Sthurlow * 1. Redistributions of source code must retain the above copyright
94bff34e3Sthurlow * notice, this list of conditions and the following disclaimer.
104bff34e3Sthurlow * 2. Redistributions in binary form must reproduce the above copyright
114bff34e3Sthurlow * notice, this list of conditions and the following disclaimer in the
124bff34e3Sthurlow * documentation and/or other materials provided with the distribution.
134bff34e3Sthurlow * 3. All advertising materials mentioning features or use of this software
144bff34e3Sthurlow * must display the following acknowledgement:
154bff34e3Sthurlow * This product includes software developed by Boris Popov.
164bff34e3Sthurlow * 4. Neither the name of the author nor the names of any co-contributors
174bff34e3Sthurlow * may be used to endorse or promote products derived from this software
184bff34e3Sthurlow * without specific prior written permission.
194bff34e3Sthurlow *
204bff34e3Sthurlow * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
214bff34e3Sthurlow * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
224bff34e3Sthurlow * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
234bff34e3Sthurlow * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
244bff34e3Sthurlow * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
254bff34e3Sthurlow * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
264bff34e3Sthurlow * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
274bff34e3Sthurlow * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
284bff34e3Sthurlow * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
294bff34e3Sthurlow * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
304bff34e3Sthurlow * SUCH DAMAGE.
314bff34e3Sthurlow *
324bff34e3Sthurlow * $Id: smbfs_subr.c,v 1.18 2005/02/02 00:22:23 lindak Exp $
334bff34e3Sthurlow */
344bff34e3Sthurlow
354bff34e3Sthurlow /*
36613a2f6bSGordon Ross * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
374bff34e3Sthurlow * Use is subject to license terms.
38adee6784SGordon Ross *
39adee6784SGordon Ross * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
404bff34e3Sthurlow */
414bff34e3Sthurlow
424bff34e3Sthurlow #include <sys/param.h>
434bff34e3Sthurlow #include <sys/systm.h>
444bff34e3Sthurlow #include <sys/time.h>
454bff34e3Sthurlow #include <sys/vnode.h>
464bff34e3Sthurlow #include <sys/sunddi.h>
474bff34e3Sthurlow
484bff34e3Sthurlow #include <netsmb/smb_osdep.h>
494bff34e3Sthurlow
504bff34e3Sthurlow #include <netsmb/smb.h>
51adee6784SGordon Ross #include <netsmb/smb2.h>
524bff34e3Sthurlow #include <netsmb/smb_conn.h>
534bff34e3Sthurlow #include <netsmb/smb_subr.h>
544bff34e3Sthurlow #include <netsmb/smb_rq.h>
554bff34e3Sthurlow
564bff34e3Sthurlow #include <smbfs/smbfs.h>
574bff34e3Sthurlow #include <smbfs/smbfs_node.h>
584bff34e3Sthurlow #include <smbfs/smbfs_subr.h>
594bff34e3Sthurlow
604bff34e3Sthurlow /*
614bff34e3Sthurlow * In the Darwin code, this function used to compute the full path
624bff34e3Sthurlow * by following the chain of n_parent pointers back to the root.
634bff34e3Sthurlow * In the Solaris port we found the n_parent pointers inconvenient
644bff34e3Sthurlow * because they hold parent nodes busy. We now keep the full path
654bff34e3Sthurlow * in every node, so this function need only marshall the directory
664bff34e3Sthurlow * path, and (if provided) the separator and last component name.
674bff34e3Sthurlow *
684bff34e3Sthurlow * Note that this logic must match that in smbfs_getino
694bff34e3Sthurlow */
704bff34e3Sthurlow int
smbfs_fullpath(struct mbchain * mbp,struct smb_vc * vcp,struct smbnode * dnp,const char * name,int nmlen,u_int8_t sep)714bff34e3Sthurlow smbfs_fullpath(struct mbchain *mbp, struct smb_vc *vcp, struct smbnode *dnp,
72430b4c46SGordon Ross const char *name, int nmlen, u_int8_t sep)
734bff34e3Sthurlow {
744bff34e3Sthurlow int caseopt = SMB_CS_NONE;
754bff34e3Sthurlow int unicode = (SMB_UNICODE_STRINGS(vcp)) ? 1 : 0;
76430b4c46SGordon Ross int error;
774bff34e3Sthurlow
78adee6784SGordon Ross /*
79adee6784SGordon Ross * SMB1 may need an alignment pad before (not SMB2)
80adee6784SGordon Ross */
81adee6784SGordon Ross if (((vcp)->vc_flags & SMBV_SMB2) == 0 &&
82adee6784SGordon Ross ((vcp)->vc_hflags2 & SMB_FLAGS2_UNICODE) != 0) {
834bff34e3Sthurlow error = mb_put_padbyte(mbp);
844bff34e3Sthurlow if (error)
854bff34e3Sthurlow return (error);
864bff34e3Sthurlow }
8791d632c8Sgwr
884bff34e3Sthurlow error = smb_put_dmem(mbp, vcp,
894bff34e3Sthurlow dnp->n_rpath, dnp->n_rplen,
90430b4c46SGordon Ross caseopt, NULL);
914bff34e3Sthurlow if (name) {
9291d632c8Sgwr /*
9391d632c8Sgwr * Special case at share root:
9491d632c8Sgwr * Don't put another slash.
9591d632c8Sgwr */
9691d632c8Sgwr if (dnp->n_rplen <= 1 && sep == '\\')
9791d632c8Sgwr sep = 0;
9891d632c8Sgwr /*
9991d632c8Sgwr * More special cases, now for XATTR:
10091d632c8Sgwr * Our "faked up" XATTR directories use a
10191d632c8Sgwr * full path name ending with ":" so as to
10291d632c8Sgwr * avoid conflicts with any real paths.
10391d632c8Sgwr * (It is not a valid CIFS path name.)
10491d632c8Sgwr * Therefore, when we're composing a full
10591d632c8Sgwr * path name from an XATTR directory, we
10691d632c8Sgwr * need to _ommit_ the ":" separator and
10791d632c8Sgwr * instead copy the one from the "fake"
10891d632c8Sgwr * parent node's path name.
10991d632c8Sgwr */
11091d632c8Sgwr if (dnp->n_flag & N_XATTR)
11191d632c8Sgwr sep = 0;
11291d632c8Sgwr
11391d632c8Sgwr if (sep) {
11491d632c8Sgwr /* Put the separator */
1154bff34e3Sthurlow if (unicode)
1164bff34e3Sthurlow error = mb_put_uint16le(mbp, sep);
1174bff34e3Sthurlow else
1184bff34e3Sthurlow error = mb_put_uint8(mbp, sep);
1194bff34e3Sthurlow if (error)
1204bff34e3Sthurlow return (error);
1214bff34e3Sthurlow }
1224bff34e3Sthurlow /* Put the name */
1234bff34e3Sthurlow error = smb_put_dmem(mbp, vcp,
124430b4c46SGordon Ross name, nmlen, caseopt, NULL);
1254bff34e3Sthurlow if (error)
1264bff34e3Sthurlow return (error);
1274bff34e3Sthurlow }
128adee6784SGordon Ross
129adee6784SGordon Ross /* SMB1 wants NULL termination. */
130adee6784SGordon Ross if (((vcp)->vc_flags & SMBV_SMB2) == 0) {
131adee6784SGordon Ross if (unicode)
132adee6784SGordon Ross error = mb_put_uint16le(mbp, 0);
133adee6784SGordon Ross else
134adee6784SGordon Ross error = mb_put_uint8(mbp, 0);
135adee6784SGordon Ross }
1364bff34e3Sthurlow
1374bff34e3Sthurlow return (error);
1384bff34e3Sthurlow }
1394bff34e3Sthurlow
140613a2f6bSGordon Ross /*
141613a2f6bSGordon Ross * Convert a Unicode directory entry to UTF-8
142613a2f6bSGordon Ross */
1434bff34e3Sthurlow void
smbfs_fname_tolocal(struct smbfs_fctx * ctx)1444bff34e3Sthurlow smbfs_fname_tolocal(struct smbfs_fctx *ctx)
1454bff34e3Sthurlow {
146613a2f6bSGordon Ross uchar_t tmpbuf[SMB_MAXFNAMELEN+1];
1474bff34e3Sthurlow struct smb_vc *vcp = SSTOVC(ctx->f_ssp);
1484bff34e3Sthurlow uchar_t *dst;
1494bff34e3Sthurlow const ushort_t *src;
1504bff34e3Sthurlow size_t inlen, outlen;
151613a2f6bSGordon Ross int flags;
1524bff34e3Sthurlow
1534bff34e3Sthurlow if (ctx->f_nmlen == 0)
1544bff34e3Sthurlow return;
1554bff34e3Sthurlow
1564bff34e3Sthurlow if (!SMB_UNICODE_STRINGS(vcp))
1574bff34e3Sthurlow return;
1584bff34e3Sthurlow
159613a2f6bSGordon Ross if (ctx->f_namesz < sizeof (tmpbuf)) {
160613a2f6bSGordon Ross ASSERT(0);
161613a2f6bSGordon Ross goto errout;
162613a2f6bSGordon Ross }
163613a2f6bSGordon Ross
1644bff34e3Sthurlow /*
165613a2f6bSGordon Ross * In-place conversions are not supported,
166613a2f6bSGordon Ross * so convert into tmpbuf and copy.
1674bff34e3Sthurlow */
168613a2f6bSGordon Ross dst = tmpbuf;
169613a2f6bSGordon Ross outlen = SMB_MAXFNAMELEN;
1704bff34e3Sthurlow /*LINTED*/
1714bff34e3Sthurlow src = (const ushort_t *)ctx->f_name;
172613a2f6bSGordon Ross inlen = ctx->f_nmlen / 2; /* number of UCS-2 characters */
173613a2f6bSGordon Ross flags = UCONV_IN_LITTLE_ENDIAN;
174613a2f6bSGordon Ross
175613a2f6bSGordon Ross if (uconv_u16tou8(src, &inlen, dst, &outlen, flags) != 0)
176613a2f6bSGordon Ross goto errout;
177613a2f6bSGordon Ross
178613a2f6bSGordon Ross ASSERT(outlen < sizeof (tmpbuf));
179613a2f6bSGordon Ross tmpbuf[outlen] = '\0';
180613a2f6bSGordon Ross bcopy(tmpbuf, ctx->f_name, outlen + 1);
181613a2f6bSGordon Ross ctx->f_nmlen = (int)outlen;
182613a2f6bSGordon Ross return;
183613a2f6bSGordon Ross
184613a2f6bSGordon Ross errout:
185613a2f6bSGordon Ross /*
186613a2f6bSGordon Ross * Conversion failed, but our caller does not
18702d09e03SGordon Ross * deal with errors here, so just put a "?".
188613a2f6bSGordon Ross * Don't expect to ever see this.
189613a2f6bSGordon Ross */
190ab415d94SGordon Ross (void) strlcpy(ctx->f_name, "?", ctx->f_namesz);
1914bff34e3Sthurlow }
192adee6784SGordon Ross
193adee6784SGordon Ross /*
194adee6784SGordon Ross * Decode a directory entry from OtW form into ctx->f_attr
195adee6784SGordon Ross *
196adee6784SGordon Ross * Caller already put some (wire-format) directory entries
197adee6784SGordon Ross * into ctx->f_mdchain and we expect to find one.
198adee6784SGordon Ross *
199adee6784SGordon Ross * Advancing correctly through the buffer can be tricky if one
200adee6784SGordon Ross * tries to add up the size of an entry as you go (which is how
201adee6784SGordon Ross * the darwin code this is derived from did it). The easiest way
202adee6784SGordon Ross * to correctly advance the position is to get a whole dirent
203adee6784SGordon Ross * into another mdchain (entry_mdc) based on NextEntryOffset,
204adee6784SGordon Ross * and then scan the data from that mdchain. On the last entry,
205adee6784SGordon Ross * we don't know the entire length, so just scan directly from
206adee6784SGordon Ross * what remains of the multi-entry buffer instead of trying to
207adee6784SGordon Ross * figure out the length to copy into a separate mdchain.
208adee6784SGordon Ross */
209adee6784SGordon Ross int
smbfs_decode_dirent(struct smbfs_fctx * ctx)210adee6784SGordon Ross smbfs_decode_dirent(struct smbfs_fctx *ctx)
211adee6784SGordon Ross {
212adee6784SGordon Ross struct mdchain entry_mdc;
213adee6784SGordon Ross struct mdchain *mdp = &ctx->f_mdchain;
214adee6784SGordon Ross size_t nmlen;
215adee6784SGordon Ross uint64_t llongint;
216adee6784SGordon Ross uint32_t nmsize, dattr;
217adee6784SGordon Ross uint32_t nextoff = 0;
218adee6784SGordon Ross int error;
219adee6784SGordon Ross
220adee6784SGordon Ross /* In case we error out... */
221adee6784SGordon Ross ctx->f_nmlen = 0;
222adee6784SGordon Ross ctx->f_rkey = (uint32_t)-1;
223adee6784SGordon Ross bzero(&entry_mdc, sizeof (entry_mdc));
224adee6784SGordon Ross
225adee6784SGordon Ross /*
226adee6784SGordon Ross * Setup mdp to point to an mbchain holding
227adee6784SGordon Ross * what should be a single directory entry.
228adee6784SGordon Ross */
229adee6784SGordon Ross error = md_get_uint32le(mdp, &nextoff);
230adee6784SGordon Ross if (error != 0)
231adee6784SGordon Ross goto errout;
232adee6784SGordon Ross if (nextoff >= 4) {
233adee6784SGordon Ross /*
234adee6784SGordon Ross * More entries follow. Make a new mbchain
235adee6784SGordon Ross * holding just this one entry, then advance.
236adee6784SGordon Ross */
237adee6784SGordon Ross mblk_t *m = NULL;
238adee6784SGordon Ross error = md_get_mbuf(mdp, nextoff - 4, &m);
239adee6784SGordon Ross if (error != 0)
240adee6784SGordon Ross goto errout;
241adee6784SGordon Ross md_initm(&entry_mdc, m);
242adee6784SGordon Ross mdp = &entry_mdc;
243adee6784SGordon Ross ctx->f_eofs += nextoff;
244adee6784SGordon Ross } else {
245adee6784SGordon Ross /* Scan directly from ctx->f_mdchain */
246adee6784SGordon Ross ctx->f_eofs = ctx->f_left;
247adee6784SGordon Ross }
248adee6784SGordon Ross
249adee6784SGordon Ross /*
250adee6784SGordon Ross * Decode the fixed-size parts
251adee6784SGordon Ross */
252adee6784SGordon Ross switch (ctx->f_infolevel) {
253adee6784SGordon Ross case FileFullDirectoryInformation:
254adee6784SGordon Ross case SMB_FIND_FULL_DIRECTORY_INFO:
255adee6784SGordon Ross md_get_uint32le(mdp, &ctx->f_rkey); /* resume key (idx) */
256adee6784SGordon Ross md_get_uint64le(mdp, &llongint); /* creation time */
257adee6784SGordon Ross smb_time_NT2local(llongint, &ctx->f_attr.fa_createtime);
258adee6784SGordon Ross md_get_uint64le(mdp, &llongint);
259adee6784SGordon Ross smb_time_NT2local(llongint, &ctx->f_attr.fa_atime);
260adee6784SGordon Ross md_get_uint64le(mdp, &llongint);
261adee6784SGordon Ross smb_time_NT2local(llongint, &ctx->f_attr.fa_mtime);
262adee6784SGordon Ross md_get_uint64le(mdp, &llongint);
263adee6784SGordon Ross smb_time_NT2local(llongint, &ctx->f_attr.fa_ctime);
264adee6784SGordon Ross md_get_uint64le(mdp, &llongint); /* file size */
265adee6784SGordon Ross ctx->f_attr.fa_size = llongint;
266adee6784SGordon Ross md_get_uint64le(mdp, &llongint); /* alloc. size */
267adee6784SGordon Ross ctx->f_attr.fa_allocsz = llongint;
268adee6784SGordon Ross md_get_uint32le(mdp, &dattr); /* ext. file attributes */
269adee6784SGordon Ross ctx->f_attr.fa_attr = dattr;
270adee6784SGordon Ross error = md_get_uint32le(mdp, &nmsize); /* name size (otw) */
271adee6784SGordon Ross if (error)
272adee6784SGordon Ross goto errout;
273adee6784SGordon Ross md_get_uint32le(mdp, NULL); /* Ea size */
274adee6784SGordon Ross break;
275adee6784SGordon Ross
276adee6784SGordon Ross case FileStreamInformation:
277adee6784SGordon Ross error = md_get_uint32le(mdp, &nmsize); /* name size (otw) */
278adee6784SGordon Ross md_get_uint64le(mdp, &llongint); /* file size */
279adee6784SGordon Ross ctx->f_attr.fa_size = llongint;
280adee6784SGordon Ross md_get_uint64le(mdp, &llongint); /* alloc. size */
281adee6784SGordon Ross ctx->f_attr.fa_allocsz = llongint;
282adee6784SGordon Ross /*
283adee6784SGordon Ross * Stream names start with a ':' that we want to skip.
284adee6784SGordon Ross * This is the easiest place to take care of that.
285adee6784SGordon Ross * Always unicode here.
286adee6784SGordon Ross */
287adee6784SGordon Ross if (nmsize >= 2) {
288adee6784SGordon Ross struct mdchain save_mdc;
289adee6784SGordon Ross uint16_t wch;
290adee6784SGordon Ross save_mdc = *mdp;
291adee6784SGordon Ross md_get_uint16le(mdp, &wch);
292adee6784SGordon Ross if (wch == ':') {
293adee6784SGordon Ross /* OK, we skipped the ':' */
294adee6784SGordon Ross nmsize -= 2;
295adee6784SGordon Ross } else {
296adee6784SGordon Ross SMBVDEBUG("No leading : in stream?\n");
297adee6784SGordon Ross /* restore position */
298adee6784SGordon Ross *mdp = save_mdc;
299adee6784SGordon Ross }
300adee6784SGordon Ross }
301adee6784SGordon Ross break;
302adee6784SGordon Ross
303adee6784SGordon Ross default:
304adee6784SGordon Ross SMBVDEBUG("unexpected info level %d\n", ctx->f_infolevel);
305adee6784SGordon Ross error = EINVAL;
306adee6784SGordon Ross goto errout;
307adee6784SGordon Ross }
308adee6784SGordon Ross
309adee6784SGordon Ross /*
310adee6784SGordon Ross * Get the filename, and convert to utf-8
311adee6784SGordon Ross * Allocated f_name in findopen
312adee6784SGordon Ross */
313adee6784SGordon Ross nmlen = ctx->f_namesz;
314adee6784SGordon Ross error = smb_get_dstring(mdp, SSTOVC(ctx->f_ssp),
315adee6784SGordon Ross ctx->f_name, &nmlen, nmsize);
316adee6784SGordon Ross if (error != 0)
317adee6784SGordon Ross goto errout;
318adee6784SGordon Ross ctx->f_nmlen = (int)nmlen;
319adee6784SGordon Ross md_done(&entry_mdc);
320adee6784SGordon Ross return (0);
321adee6784SGordon Ross
322adee6784SGordon Ross errout:
323adee6784SGordon Ross /*
324adee6784SGordon Ross * Something bad has happened and we ran out of data
325adee6784SGordon Ross * before we could parse all f_ecnt entries expected.
326adee6784SGordon Ross * Give up on the current buffer.
327adee6784SGordon Ross */
328adee6784SGordon Ross SMBVDEBUG("ran out of data\n");
329adee6784SGordon Ross ctx->f_eofs = ctx->f_left;
330adee6784SGordon Ross md_done(&entry_mdc);
331adee6784SGordon Ross return (error);
332adee6784SGordon Ross }
333adee6784SGordon Ross
334adee6784SGordon Ross /*
335adee6784SGordon Ross * Decode FileAllInformation
336adee6784SGordon Ross *
337adee6784SGordon Ross * The data is a concatenation of:
338adee6784SGordon Ross * FileBasicInformation
339adee6784SGordon Ross * FileStandardInformation
340adee6784SGordon Ross * FileInternalInformation
341adee6784SGordon Ross * FileEaInformation
342*bb936843SToomas Soome * FileAccessInformation
343adee6784SGordon Ross * FilePositionInformation
344adee6784SGordon Ross * FileModeInformation
345adee6784SGordon Ross * FileAlignmentInformation
346adee6784SGordon Ross * FileNameInformation
347adee6784SGordon Ross */
348adee6784SGordon Ross /*ARGSUSED*/
349adee6784SGordon Ross int
smbfs_decode_file_all_info(struct smb_share * ssp,struct mdchain * mdp,struct smbfattr * fap)350adee6784SGordon Ross smbfs_decode_file_all_info(struct smb_share *ssp,
351adee6784SGordon Ross struct mdchain *mdp, struct smbfattr *fap)
352adee6784SGordon Ross {
353adee6784SGordon Ross uint64_t llongint, lsize;
354adee6784SGordon Ross uint32_t dattr;
355adee6784SGordon Ross int error;
356adee6784SGordon Ross
357adee6784SGordon Ross /*
358adee6784SGordon Ross * This part is: FileBasicInformation
359adee6784SGordon Ross */
360adee6784SGordon Ross
361adee6784SGordon Ross /* creation time */
362adee6784SGordon Ross md_get_uint64le(mdp, &llongint);
363adee6784SGordon Ross smb_time_NT2local(llongint, &fap->fa_createtime);
364adee6784SGordon Ross
365adee6784SGordon Ross /* last access time */
366adee6784SGordon Ross md_get_uint64le(mdp, &llongint);
367adee6784SGordon Ross smb_time_NT2local(llongint, &fap->fa_atime);
368adee6784SGordon Ross
369adee6784SGordon Ross /* last write time */
370adee6784SGordon Ross md_get_uint64le(mdp, &llongint);
371adee6784SGordon Ross smb_time_NT2local(llongint, &fap->fa_mtime);
372adee6784SGordon Ross
373adee6784SGordon Ross /* last change time */
374adee6784SGordon Ross md_get_uint64le(mdp, &llongint);
375adee6784SGordon Ross smb_time_NT2local(llongint, &fap->fa_ctime);
376adee6784SGordon Ross
377adee6784SGordon Ross /* attributes */
378adee6784SGordon Ross md_get_uint32le(mdp, &dattr);
379adee6784SGordon Ross fap->fa_attr = dattr;
380adee6784SGordon Ross
381adee6784SGordon Ross /* reserved */
382adee6784SGordon Ross md_get_uint32le(mdp, NULL);
383adee6784SGordon Ross
384adee6784SGordon Ross /*
385adee6784SGordon Ross * This part is: FileStandardInformation
386adee6784SGordon Ross */
387adee6784SGordon Ross
388adee6784SGordon Ross /* allocation size */
389adee6784SGordon Ross md_get_uint64le(mdp, &lsize);
390adee6784SGordon Ross fap->fa_allocsz = lsize;
391adee6784SGordon Ross
392adee6784SGordon Ross /* File size */
393adee6784SGordon Ross error = md_get_uint64le(mdp, &lsize);
394adee6784SGordon Ross fap->fa_size = lsize;
395adee6784SGordon Ross
396adee6784SGordon Ross /*
397adee6784SGordon Ross * There's more after this but we don't need it:
398adee6784SGordon Ross * Remainder of FileStandardInformation
399adee6784SGordon Ross * NumLlinks, DeletOnClose, IsDir, reserved.
400adee6784SGordon Ross * Then:
401adee6784SGordon Ross * FileInternalInformation
402adee6784SGordon Ross * FileEaInformation
403*bb936843SToomas Soome * FileAccessInformation
404adee6784SGordon Ross * FilePositionInformation
405adee6784SGordon Ross * FileModeInformation
406adee6784SGordon Ross * FileAlignmentInformation
407adee6784SGordon Ross * FileNameInformation
408adee6784SGordon Ross */
409adee6784SGordon Ross
410adee6784SGordon Ross return (error);
411adee6784SGordon Ross }
412adee6784SGordon Ross
413adee6784SGordon Ross /*
414adee6784SGordon Ross * Decode FileFsAttributeInformation
415adee6784SGordon Ross *
416adee6784SGordon Ross * ULONG FileSystemAttributes;
417adee6784SGordon Ross * LONG MaximumComponentNameLength;
418adee6784SGordon Ross * ULONG FileSystemNameLength;
419adee6784SGordon Ross * WCHAR FileSystemName[1];
420adee6784SGordon Ross */
421adee6784SGordon Ross int
smbfs_decode_fs_attr_info(struct smb_share * ssp,struct mdchain * mdp,struct smb_fs_attr_info * fsa)422adee6784SGordon Ross smbfs_decode_fs_attr_info(struct smb_share *ssp,
423adee6784SGordon Ross struct mdchain *mdp, struct smb_fs_attr_info *fsa)
424adee6784SGordon Ross {
425adee6784SGordon Ross struct smb_vc *vcp = SSTOVC(ssp);
426adee6784SGordon Ross uint32_t nlen;
427adee6784SGordon Ross int error;
428adee6784SGordon Ross
429adee6784SGordon Ross md_get_uint32le(mdp, &fsa->fsa_aflags);
430adee6784SGordon Ross md_get_uint32le(mdp, &fsa->fsa_maxname);
431adee6784SGordon Ross error = md_get_uint32le(mdp, &nlen); /* fs name length */
432adee6784SGordon Ross if (error)
433adee6784SGordon Ross goto out;
434adee6784SGordon Ross
435adee6784SGordon Ross /*
436adee6784SGordon Ross * Get the FS type name.
437adee6784SGordon Ross */
438adee6784SGordon Ross bzero(fsa->fsa_tname, FSTYPSZ);
439adee6784SGordon Ross if (SMB_UNICODE_STRINGS(vcp)) {
440adee6784SGordon Ross uint16_t tmpbuf[FSTYPSZ];
441adee6784SGordon Ross size_t tmplen, outlen;
442adee6784SGordon Ross
443adee6784SGordon Ross if (nlen > sizeof (tmpbuf))
444adee6784SGordon Ross nlen = sizeof (tmpbuf);
445adee6784SGordon Ross error = md_get_mem(mdp, tmpbuf, nlen, MB_MSYSTEM);
446adee6784SGordon Ross if (error != 0)
447adee6784SGordon Ross goto out;
448adee6784SGordon Ross tmplen = nlen / 2; /* UCS-2 chars */
449adee6784SGordon Ross outlen = FSTYPSZ - 1;
450adee6784SGordon Ross error = uconv_u16tou8(tmpbuf, &tmplen,
451adee6784SGordon Ross (uchar_t *)fsa->fsa_tname, &outlen,
452adee6784SGordon Ross UCONV_IN_LITTLE_ENDIAN);
453adee6784SGordon Ross } else {
454adee6784SGordon Ross if (nlen > (FSTYPSZ - 1))
455adee6784SGordon Ross nlen = FSTYPSZ - 1;
456adee6784SGordon Ross error = md_get_mem(mdp, fsa->fsa_tname, nlen, MB_MSYSTEM);
457adee6784SGordon Ross }
458adee6784SGordon Ross
459adee6784SGordon Ross out:
460adee6784SGordon Ross return (error);
461adee6784SGordon Ross }
462