/*
                                  NETWOX
                             Network toolbox
                Copyright(c) 1999-2005 Laurent Constantin
                                  -----

  Main server    : http://www.laurentconstantin.com/
  Backup servers : http://go.to/laurentconstantin/
                   http://laurentconstantin.est-la.com/
                   http://laurentconstantin.free.fr/
                   http://membres.lycos.fr/lauconstantin/
  [my current email address is on the web servers]

                                  -----
  This file is part of Netwox.

  Netwox is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  version 2 as published by the Free Software Foundation.

  Netwox is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  General Public License for more details (http://www.gnu.org/).

------------------------------------------------------------------------
*/

/*-------------------------------------------------------------*/
#include "../netwox.h"

/*-------------------------------------------------------------*/
netwib_err netwox_smbcmdtsc2q_init(netwox_smbcmdtsc2q *psmbcmdtsc2q)
{
  psmbcmdtsc2q->type = NETWOX_SMBCMDTSC2Q_TYPE_UNKNOWN;
  return(NETWIB_ERR_OK);
}

/*-------------------------------------------------------------*/
netwib_err netwox_smbcmdtsc2q_selecttype(netwox_smbcmdtsc2q *psmbcmdtsc2q,
                                         netwox_smbcmdtsc2q_type type)
{

  if (psmbcmdtsc2q->type != NETWOX_SMBCMDTSC2Q_TYPE_UNKNOWN) {
    return(NETWOX_ERR_INTERNALERROR);
  }

  psmbcmdtsc2q->type = type;
  switch(type) {
  case NETWOX_SMBCMDTSC2Q_TYPE_FINDFIRST2 :
    netwib_er(netwox_smbcmdcmn_data_initdefault(&psmbcmdtsc2q->value.findfirst2.searchpattern));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_FINDNEXT2 :
    netwib_er(netwox_smbcmdcmn_data_initdefault(&psmbcmdtsc2q->value.findnext2.filename));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYFSINFO :
    netwib_er(netwox_smbcmdcmn_data_initdefault(&psmbcmdtsc2q->value.queryfsinfo.sharename));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYPATHINFO :
    netwib_er(netwox_smbcmdcmn_data_initdefault(&psmbcmdtsc2q->value.querypathinfo.filename));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYFILEINFO :
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_BASIC :
    netwib_er(netwox_smbcmdtsc2_fmt_file_basic_init(&psmbcmdtsc2q->value.setfileinfo_basic.basic));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_NAME :
    netwib_er(netwox_smbcmdtsc2_fmt_file_name_init(&psmbcmdtsc2q->value.setfileinfo_name.name));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EA :
    netwib_er(netwox_smbcmdtsc2_fmt_file_ea_init(&psmbcmdtsc2q->value.setfileinfo_ea.ea));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EBASIC :
    netwib_er(netwox_smbcmdtsc2_fmt_file_ebasic_init(&psmbcmdtsc2q->value.setfileinfo_ebasic.ebasic));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EALLOCATION :
    netwib_er(netwox_smbcmdtsc2_fmt_file_eallocation_init(&psmbcmdtsc2q->value.setfileinfo_eallocation.eallocation));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EEOF :
    netwib_er(netwox_smbcmdtsc2_fmt_file_eeof_init(&psmbcmdtsc2q->value.setfileinfo_eeof.eeof));
    break;
  default :
    psmbcmdtsc2q->type = NETWOX_SMBCMDTSC2Q_TYPE_UNKNOWN;
    return(NETWIB_ERR_PAINVALIDTYPE);
  }

  return(NETWIB_ERR_OK);
}

/*-------------------------------------------------------------*/
netwib_err netwox_smbcmdtsc2q_setdefault(netwox_smbcmdtsc2q *psmbcmdtsc2q)
{

  switch(psmbcmdtsc2q->type) {
  case NETWOX_SMBCMDTSC2Q_TYPE_FINDFIRST2 :
    netwox__smbcmdcmn_fileattr16_initdefault(psmbcmdtsc2q->value.findfirst2.searchattr);
    psmbcmdtsc2q->value.findfirst2.maxinfo = 0;
    psmbcmdtsc2q->value.findfirst2.flags = 0;
    psmbcmdtsc2q->value.findfirst2.fmt = 0;
    psmbcmdtsc2q->value.findfirst2.storagetype = 0;
    netwib_er(netwox_smbcmdcmn_data_setdefault(&psmbcmdtsc2q->value.findfirst2.searchpattern));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_FINDNEXT2 :
    psmbcmdtsc2q->value.findnext2.sid = 0;
    psmbcmdtsc2q->value.findnext2.maxinfo = 0;
    psmbcmdtsc2q->value.findnext2.fmt = 0;
    psmbcmdtsc2q->value.findnext2.resumekey = 0;
    psmbcmdtsc2q->value.findnext2.flags = 0;
    netwib_er(netwox_smbcmdcmn_data_setdefault(&psmbcmdtsc2q->value.findnext2.filename));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYFSINFO :
    psmbcmdtsc2q->value.queryfsinfo.fmt = 0;
    netwib_er(netwox_smbcmdcmn_data_setdefault(&psmbcmdtsc2q->value.queryfsinfo.sharename));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYPATHINFO :
    psmbcmdtsc2q->value.querypathinfo.fmt = 0;
    netwib_er(netwox_smbcmdcmn_data_setdefault(&psmbcmdtsc2q->value.querypathinfo.filename));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYFILEINFO :
    psmbcmdtsc2q->value.queryfileinfo.fid = 0;
    psmbcmdtsc2q->value.queryfileinfo.fmt = 0;
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_BASIC :
    psmbcmdtsc2q->value.setfileinfo_basic.fid = 0;
    netwib_er(netwox_smbcmdtsc2_fmt_file_basic_setdefault(&psmbcmdtsc2q->value.setfileinfo_basic.basic));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_NAME :
    psmbcmdtsc2q->value.setfileinfo_name.fid = 0;
    netwib_er(netwox_smbcmdtsc2_fmt_file_name_setdefault(&psmbcmdtsc2q->value.setfileinfo_name.name));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EA :
    psmbcmdtsc2q->value.setfileinfo_ea.fid = 0;
    netwib_er(netwox_smbcmdtsc2_fmt_file_ea_setdefault(&psmbcmdtsc2q->value.setfileinfo_ea.ea));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EBASIC :
    psmbcmdtsc2q->value.setfileinfo_ebasic.fid = 0;
    netwib_er(netwox_smbcmdtsc2_fmt_file_ebasic_setdefault(&psmbcmdtsc2q->value.setfileinfo_ebasic.ebasic));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EALLOCATION :
    psmbcmdtsc2q->value.setfileinfo_eallocation.fid = 0;
    netwib_er(netwox_smbcmdtsc2_fmt_file_eallocation_setdefault(&psmbcmdtsc2q->value.setfileinfo_eallocation.eallocation));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EEOF :
    psmbcmdtsc2q->value.setfileinfo_eeof.fid = 0;
    netwib_er(netwox_smbcmdtsc2_fmt_file_eeof_setdefault(&psmbcmdtsc2q->value.setfileinfo_eeof.eeof));
    break;
  default :
    return(NETWIB_ERR_PAINVALIDTYPE);
  }

  return(NETWIB_ERR_OK);
}

/*-------------------------------------------------------------*/
netwib_err netwox_smbcmdtsc2q_close(netwox_smbcmdtsc2q *psmbcmdtsc2q)
{

  switch(psmbcmdtsc2q->type) {
  case NETWOX_SMBCMDTSC2Q_TYPE_UNKNOWN :
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_FINDFIRST2 :
    netwib_er(netwox_smbcmdcmn_data_close(&psmbcmdtsc2q->value.findfirst2.searchpattern));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_FINDNEXT2 :
    netwib_er(netwox_smbcmdcmn_data_close(&psmbcmdtsc2q->value.findnext2.filename));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYFSINFO :
    netwib_er(netwox_smbcmdcmn_data_close(&psmbcmdtsc2q->value.queryfsinfo.sharename));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYPATHINFO :
    netwib_er(netwox_smbcmdcmn_data_close(&psmbcmdtsc2q->value.querypathinfo.filename));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYFILEINFO :
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_BASIC :
    netwib_er(netwox_smbcmdtsc2_fmt_file_basic_close(&psmbcmdtsc2q->value.setfileinfo_basic.basic));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_NAME :
    netwib_er(netwox_smbcmdtsc2_fmt_file_name_close(&psmbcmdtsc2q->value.setfileinfo_name.name));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EA :
    netwib_er(netwox_smbcmdtsc2_fmt_file_ea_close(&psmbcmdtsc2q->value.setfileinfo_ea.ea));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EBASIC :
    netwib_er(netwox_smbcmdtsc2_fmt_file_ebasic_close(&psmbcmdtsc2q->value.setfileinfo_ebasic.ebasic));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EALLOCATION :
    netwib_er(netwox_smbcmdtsc2_fmt_file_eallocation_close(&psmbcmdtsc2q->value.setfileinfo_eallocation.eallocation));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EEOF :
    netwib_er(netwox_smbcmdtsc2_fmt_file_eeof_close(&psmbcmdtsc2q->value.setfileinfo_eeof.eeof));
    break;
  default :
    return(NETWIB_ERR_PAINVALIDTYPE);
  }

  return(NETWIB_ERR_OK);
}

/*-------------------------------------------------------------*/
typedef enum {
  NETWOX_SMBCMDTSC2Q_SUBCMD_FINDFIRST2 = 1,
  NETWOX_SMBCMDTSC2Q_SUBCMD_FINDNEXT2 = 2,
  NETWOX_SMBCMDTSC2Q_SUBCMD_QUERYFSINFO = 3,
  NETWOX_SMBCMDTSC2Q_SUBCMD_QUERYPATHINFO = 5,
  NETWOX_SMBCMDTSC2Q_SUBCMD_QUERYFILEINFO = 7,
  NETWOX_SMBCMDTSC2Q_SUBCMD_SETFILEINFO = 8,
  NETWOX_SMBCMDTSC2Q_SUBCMD_GETDFSREFERRAL = 16 /* not implemented */
} netwox_smbcmdtsc2q_subcmd;

/*-------------------------------------------------------------*/
netwib_err netwox_smbcmdtsc2q_encode_smbcmd(netwox_constsmbcmd *psmbcmd,
                                            netwox_smbcmdtsc2q *psmbcmdtsc2q)
{
  netwib_data para, data;
  netwib_uint32 parasize, datasize;
  netwox_smbcmdtsc2q_subcmd subcmd;

  if (psmbcmd->type != NETWOX_SMBCMD_TYPE_TRANSACTION2_Q) {
    return(NETWIB_ERR_PAINVALIDTYPE);
  }
  if (netwib__buf_ref_data_size(&psmbcmd->value.transaction2_q.para) != psmbcmd->value.transaction2_q.totalparasize) {
    return(NETWIB_ERR_NOTCONVERTED);
  }
  if (netwib__buf_ref_data_size(&psmbcmd->value.transaction2_q.data) != psmbcmd->value.transaction2_q.totaldatasize) {
    return(NETWIB_ERR_NOTCONVERTED);
  }
  if (psmbcmd->value.transaction2_q.setupcount > NETWOX_SMBCMD_TRANSACTION2_SETUP_MAX) {
    return(NETWIB_ERR_NOTCONVERTED);
  }

  para = netwib__buf_ref_data_ptr(&psmbcmd->value.transaction2_q.para);
  parasize = netwib__buf_ref_data_size(&psmbcmd->value.transaction2_q.para);
  data = netwib__buf_ref_data_ptr(&psmbcmd->value.transaction2_q.data);
  datasize = netwib__buf_ref_data_size(&psmbcmd->value.transaction2_q.data);

  if (psmbcmd->value.transaction2_q.setupcount == 0) {
    return(NETWIB_ERR_NOTCONVERTED);
  }
  subcmd = psmbcmd->value.transaction2_q.setup[0];

  switch(subcmd) {
  case NETWOX_SMBCMDTSC2Q_SUBCMD_FINDFIRST2 :
    netwib_er(netwox_smbcmdtsc2q_selecttype(psmbcmdtsc2q,
                                         NETWOX_SMBCMDTSC2Q_TYPE_FINDFIRST2));
    if (datasize) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    if (psmbcmd->value.transaction2_q.setupcount != 1) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    if (parasize < 12) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    netwox__smbcmdcmn_fileattr16_decode(para, psmbcmdtsc2q->value.findfirst2.searchattr);
    netwib__data_decode_uint16_le(para, psmbcmdtsc2q->value.findfirst2.maxinfo);
    netwib__data_decode_uint16_le(para, psmbcmdtsc2q->value.findfirst2.flags);
    netwib__data_decode_uint16_le(para, psmbcmdtsc2q->value.findfirst2.fmt);
    netwib__data_decode_uint32_le(para, psmbcmdtsc2q->value.findfirst2.storagetype);
    parasize -= 12;
    netwib_er(netwox_smbcmdcmn_data_decodestr(&para, &parasize, psmbcmd->value.transaction2_q.isunicode, &psmbcmdtsc2q->value.findfirst2.searchpattern));
    if (parasize != 0) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    break;
  case NETWOX_SMBCMDTSC2Q_SUBCMD_FINDNEXT2 :
    netwib_er(netwox_smbcmdtsc2q_selecttype(psmbcmdtsc2q,
                                         NETWOX_SMBCMDTSC2Q_TYPE_FINDNEXT2));
    if (datasize) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    if (psmbcmd->value.transaction2_q.setupcount != 1) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    if (parasize < 12) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    netwib__data_decode_uint16_le(para, psmbcmdtsc2q->value.findnext2.sid);
    netwib__data_decode_uint16_le(para, psmbcmdtsc2q->value.findnext2.maxinfo);
    netwib__data_decode_uint16_le(para, psmbcmdtsc2q->value.findnext2.fmt);
    netwib__data_decode_uint32_le(para, psmbcmdtsc2q->value.findnext2.resumekey);
    netwib__data_decode_uint16_le(para, psmbcmdtsc2q->value.findnext2.flags);
    parasize -= 12;
    netwib_er(netwox_smbcmdcmn_data_decodestr(&para, &parasize, psmbcmd->value.transaction2_q.isunicode, &psmbcmdtsc2q->value.findnext2.filename));
    if (parasize != 0) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    break;
  case NETWOX_SMBCMDTSC2Q_SUBCMD_QUERYFSINFO :
    netwib_er(netwox_smbcmdtsc2q_selecttype(psmbcmdtsc2q,
                                         NETWOX_SMBCMDTSC2Q_TYPE_QUERYFSINFO));
    if (datasize) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    if (psmbcmd->value.transaction2_q.setupcount != 1) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    if (parasize < 2) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    netwib__data_decode_uint16_le(para, psmbcmdtsc2q->value.queryfsinfo.fmt);
    parasize -= 2;
    if (parasize) {
      /* because sometimes it is not present */
      para += 4; /* reserved */
      parasize -= 4;
      if (parasize) {
        /* because sometimes it is not present */
        netwib_er(netwox_smbcmdcmn_data_decodestr(&para, &parasize, psmbcmd->value.transaction2_q.isunicode, &psmbcmdtsc2q->value.queryfsinfo.sharename));
        if (parasize != 0) {
          return(NETWIB_ERR_NOTCONVERTED);
        }
      }
    }
    break;
  case NETWOX_SMBCMDTSC2Q_SUBCMD_QUERYPATHINFO :
    netwib_er(netwox_smbcmdtsc2q_selecttype(psmbcmdtsc2q, NETWOX_SMBCMDTSC2Q_TYPE_QUERYPATHINFO));
    if (datasize) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    if (psmbcmd->value.transaction2_q.setupcount != 1) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    if (parasize < 6) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    netwib__data_decode_uint16_le(para, psmbcmdtsc2q->value.querypathinfo.fmt);
    parasize -= 2;
    para += 4; /* reserved */
    parasize -= 4;
    netwib_er(netwox_smbcmdcmn_data_decodestr(&para, &parasize, psmbcmd->value.transaction2_q.isunicode, &psmbcmdtsc2q->value.querypathinfo.filename));
    if (parasize != 0) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    break;
  case NETWOX_SMBCMDTSC2Q_SUBCMD_QUERYFILEINFO :
    netwib_er(netwox_smbcmdtsc2q_selecttype(psmbcmdtsc2q, NETWOX_SMBCMDTSC2Q_TYPE_QUERYFILEINFO));
    if (datasize) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    if (psmbcmd->value.transaction2_q.setupcount != 1) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    if (parasize < 4) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    netwib__data_decode_uint16_le(para, psmbcmdtsc2q->value.queryfileinfo.fid);
    netwib__data_decode_uint16_le(para, psmbcmdtsc2q->value.queryfileinfo.fmt);
    parasize -= 4;
    if (parasize != 0) {
      return(NETWIB_ERR_NOTCONVERTED);
    }
    break;
  case NETWOX_SMBCMDTSC2Q_SUBCMD_SETFILEINFO :
    {
      netwib_uint16 fid;
      netwox_smbcmdtsc2_fmt_file fmt;
      if (psmbcmd->value.transaction2_q.setupcount != 1) {
        return(NETWIB_ERR_NOTCONVERTED);
      }
      if (parasize < 4) {
        return(NETWIB_ERR_NOTCONVERTED);
      }
      netwib__data_decode_uint16_le(para, fid);
      netwib__data_decode_uint16_le(para, fmt);
      parasize -= 4;
      switch(fmt) {
      case NETWOX_SMBCMDTSC2_FMT_FILE_BASIC :
        netwib_er(netwox_smbcmdtsc2q_selecttype(psmbcmdtsc2q, NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_BASIC));
        psmbcmdtsc2q->value.setfileinfo_basic.fid = fid;
        para += 2; parasize -= 2; /* reserved */
        if (parasize != 0) {
          return(NETWIB_ERR_NOTCONVERTED);
        }
        netwib_er(netwox_smbcmdtsc2_fmt_file_basic_decode(&data, &datasize, &psmbcmdtsc2q->value.setfileinfo_basic.basic));
        if (datasize != 6/* unknown padding */) {
          return(NETWIB_ERR_NOTCONVERTED);
        }
        break;
      case NETWOX_SMBCMDTSC2_FMT_FILE_NAME :
        netwib_er(netwox_smbcmdtsc2q_selecttype(psmbcmdtsc2q, NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_NAME));
        psmbcmdtsc2q->value.setfileinfo_name.fid = fid;
        para += 2; parasize -= 2; /* reserved */
        if (parasize != 0) {
          return(NETWIB_ERR_NOTCONVERTED);
        }
        netwib_er(netwox_smbcmdtsc2_fmt_file_name_decode(&data, &datasize, &psmbcmdtsc2q->value.setfileinfo_name.name));
        if (datasize != 2/* unknown padding */) {
          return(NETWIB_ERR_NOTCONVERTED);
        }
        break;
      case NETWOX_SMBCMDTSC2_FMT_FILE_EA :
        netwib_er(netwox_smbcmdtsc2q_selecttype(psmbcmdtsc2q, NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EA));
        psmbcmdtsc2q->value.setfileinfo_ea.fid = fid;
        para += 2; parasize -= 2; /* reserved */
        if (parasize != 0) {
          return(NETWIB_ERR_NOTCONVERTED);
        }
        netwib_er(netwox_smbcmdtsc2_fmt_file_ea_decode(&data, &datasize, &psmbcmdtsc2q->value.setfileinfo_ea.ea));
        if (datasize != 4/* unknown padding */) {
          return(NETWIB_ERR_NOTCONVERTED);
        }
        break;
      case NETWOX_SMBCMDTSC2_FMT_FILE_EBASIC :
        netwib_er(netwox_smbcmdtsc2q_selecttype(psmbcmdtsc2q, NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EBASIC));
        psmbcmdtsc2q->value.setfileinfo_ebasic.fid = fid;
        para += 2; parasize -= 2; /* reserved */
        if (parasize != 0) {
          return(NETWIB_ERR_NOTCONVERTED);
        }
        netwib_er(netwox_smbcmdtsc2_fmt_file_ebasic_decode(&data, &datasize, &psmbcmdtsc2q->value.setfileinfo_ebasic.ebasic));
        if (datasize != 6/* unknown padding */) {
          return(NETWIB_ERR_NOTCONVERTED);
        }
        break;
      case NETWOX_SMBCMDTSC2_FMT_FILE_EALLOCATION :
        netwib_er(netwox_smbcmdtsc2q_selecttype(psmbcmdtsc2q, NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EALLOCATION));
        psmbcmdtsc2q->value.setfileinfo_eallocation.fid = fid;
        para += 2; parasize -= 2; /* reserved */
        if (parasize != 0) {
          return(NETWIB_ERR_NOTCONVERTED);
        }
        netwib_er(netwox_smbcmdtsc2_fmt_file_eallocation_decode(&data, &datasize, &psmbcmdtsc2q->value.setfileinfo_eallocation.eallocation));
        if (datasize != 0) {
          return(NETWIB_ERR_NOTCONVERTED);
        }
        break;
      case NETWOX_SMBCMDTSC2_FMT_FILE_EEOF :
        netwib_er(netwox_smbcmdtsc2q_selecttype(psmbcmdtsc2q, NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EEOF));
        psmbcmdtsc2q->value.setfileinfo_eeof.fid = fid;
        para += 2; parasize -= 2; /* reserved */
        if (parasize != 0) {
          return(NETWIB_ERR_NOTCONVERTED);
        }
        netwib_er(netwox_smbcmdtsc2_fmt_file_eeof_decode(&data, &datasize, &psmbcmdtsc2q->value.setfileinfo_eeof.eeof));
        if (datasize != 0) {
          return(NETWIB_ERR_NOTCONVERTED);
        }
        break;
      default :
        return(NETWIB_ERR_NOTCONVERTED);
      }
    }
    break;
  case NETWOX_SMBCMDTSC2Q_SUBCMD_GETDFSREFERRAL :
    return(NETWOX_ERR_NOTIMPLEMENTED);
  default :
    return(NETWIB_ERR_NOTCONVERTED);
  }

  return(NETWIB_ERR_OK);
}

/*-------------------------------------------------------------*/
netwib_err netwox_smbcmdtsc2q_decode_smbcmd(netwox_constsmbcmdtsc2q *psmbcmdtsc2q,
                                            netwox_smbcmd *psmbcmd)
{
  netwib_data para, data;

  switch(psmbcmdtsc2q->type) {
  case NETWOX_SMBCMDTSC2Q_TYPE_FINDFIRST2 :
    psmbcmd->value.transaction2_q.setupcount = 1;
    psmbcmd->value.transaction2_q.setup[0] = NETWOX_SMBCMDTSC2Q_SUBCMD_FINDFIRST2;
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.para, 12, &para));
    netwox__smbcmdcmn_fileattr16_append(para, psmbcmdtsc2q->value.findfirst2.searchattr);
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.findfirst2.maxinfo);
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.findfirst2.flags);
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.findfirst2.fmt);
    netwib__data_append_uint32_le(para, psmbcmdtsc2q->value.findfirst2.storagetype);
    psmbcmd->value.transaction2_q.para.endoffset += 12;
    netwib_er(netwox_smbcmdcmn_data_appendstr(&psmbcmdtsc2q->value.findfirst2.searchpattern, psmbcmd->value.transaction2_q.isunicode, &psmbcmd->value.transaction2_q.para));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_FINDNEXT2 :
    psmbcmd->value.transaction2_q.setupcount = 1;
    psmbcmd->value.transaction2_q.setup[0] = NETWOX_SMBCMDTSC2Q_SUBCMD_FINDNEXT2;
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.para, 12, &para));
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.findnext2.sid);
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.findnext2.maxinfo);
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.findnext2.fmt);
    netwib__data_append_uint32_le(para, psmbcmdtsc2q->value.findnext2.resumekey);
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.findnext2.flags);
    psmbcmd->value.transaction2_q.para.endoffset += 12;
    netwib_er(netwox_smbcmdcmn_data_appendstr(&psmbcmdtsc2q->value.findnext2.filename, psmbcmd->value.transaction2_q.isunicode, &psmbcmd->value.transaction2_q.para));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYFSINFO :
    psmbcmd->value.transaction2_q.setupcount = 1;
    psmbcmd->value.transaction2_q.setup[0] = NETWOX_SMBCMDTSC2Q_SUBCMD_QUERYFSINFO;
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.para, 6, &para));
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.queryfsinfo.fmt);
    netwib_c_memset(para, 0, 4); /* reserved */
    psmbcmd->value.transaction2_q.para.endoffset += 6;
    if (netwib__buf_ref_data_size(&psmbcmdtsc2q->value.queryfsinfo.sharename)){
      /* only put it if user set it (has a size) */
      netwib_er(netwox_smbcmdcmn_data_appendstr(&psmbcmdtsc2q->value.queryfsinfo.sharename, psmbcmd->value.transaction2_q.isunicode, &psmbcmd->value.transaction2_q.para));
    }
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYPATHINFO :
    psmbcmd->value.transaction2_q.setupcount = 1;
    psmbcmd->value.transaction2_q.setup[0] = NETWOX_SMBCMDTSC2Q_SUBCMD_QUERYPATHINFO;
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.para, 6, &para));
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.querypathinfo.fmt);
    netwib_c_memset(para, 0, 4); /* reserved */
    psmbcmd->value.transaction2_q.para.endoffset += 6;
    netwib_er(netwox_smbcmdcmn_data_appendstr(&psmbcmdtsc2q->value.querypathinfo.filename, psmbcmd->value.transaction2_q.isunicode, &psmbcmd->value.transaction2_q.para));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYFILEINFO :
    psmbcmd->value.transaction2_q.setupcount = 1;
    psmbcmd->value.transaction2_q.setup[0] = NETWOX_SMBCMDTSC2Q_SUBCMD_QUERYFILEINFO;
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.para, 4, &para));
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.queryfileinfo.fid);
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.queryfileinfo.fmt);
    psmbcmd->value.transaction2_q.para.endoffset += 4;
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_BASIC :
    psmbcmd->value.transaction2_q.setupcount = 1;
    psmbcmd->value.transaction2_q.setup[0] = NETWOX_SMBCMDTSC2Q_SUBCMD_SETFILEINFO;
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.para, 6, &para));
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.setfileinfo_basic.fid);
    netwib__data_append_uint16_le(para, NETWOX_SMBCMDTSC2_FMT_FILE_BASIC);
    netwib_c_memset(para, 0, 2); /* reserved */
    psmbcmd->value.transaction2_q.para.endoffset += 6;
    netwib_er(netwox_smbcmdtsc2_fmt_file_basic_append(&psmbcmdtsc2q->value.setfileinfo_basic.basic, &psmbcmd->value.transaction2_q.data));
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.data, 6, &data));
    netwib_c_memset(data, 0, 6); /* unknown */
    psmbcmd->value.transaction2_q.data.endoffset += 6;
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_NAME :
    psmbcmd->value.transaction2_q.setupcount = 1;
    psmbcmd->value.transaction2_q.setup[0] = NETWOX_SMBCMDTSC2Q_SUBCMD_SETFILEINFO;
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.para, 6, &para));
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.setfileinfo_name.fid);
    netwib__data_append_uint16_le(para, NETWOX_SMBCMDTSC2_FMT_FILE_NAME);
    netwib_c_memset(para, 0, 2); /* reserved */
    psmbcmd->value.transaction2_q.para.endoffset += 6;
    netwib_er(netwox_smbcmdtsc2_fmt_file_name_append(&psmbcmdtsc2q->value.setfileinfo_name.name, &psmbcmd->value.transaction2_q.data));
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.data, 2, &data));
    netwib_c_memset(data, 0, 2); /* unknown */
    psmbcmd->value.transaction2_q.data.endoffset += 2;
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EA :
    psmbcmd->value.transaction2_q.setupcount = 1;
    psmbcmd->value.transaction2_q.setup[0] = NETWOX_SMBCMDTSC2Q_SUBCMD_SETFILEINFO;
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.para, 6, &para));
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.setfileinfo_ea.fid);
    netwib__data_append_uint16_le(para, NETWOX_SMBCMDTSC2_FMT_FILE_EA);
    netwib_c_memset(para, 0, 2); /* reserved */
    psmbcmd->value.transaction2_q.para.endoffset += 6;
    netwib_er(netwox_smbcmdtsc2_fmt_file_ea_append(&psmbcmdtsc2q->value.setfileinfo_ea.ea, &psmbcmd->value.transaction2_q.data));
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.data, 4, &data));
    netwib_c_memset(data, 0, 4); /* unknown */
    psmbcmd->value.transaction2_q.data.endoffset += 4;
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EBASIC :
    psmbcmd->value.transaction2_q.setupcount = 1;
    psmbcmd->value.transaction2_q.setup[0] = NETWOX_SMBCMDTSC2Q_SUBCMD_SETFILEINFO;
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.para, 6, &para));
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.setfileinfo_ebasic.fid);
    netwib__data_append_uint16_le(para, NETWOX_SMBCMDTSC2_FMT_FILE_EBASIC);
    netwib_c_memset(para, 0, 2); /* reserved */
    psmbcmd->value.transaction2_q.para.endoffset += 6;
    netwib_er(netwox_smbcmdtsc2_fmt_file_ebasic_append(&psmbcmdtsc2q->value.setfileinfo_ebasic.ebasic, &psmbcmd->value.transaction2_q.data));
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.data, 6, &data));
    netwib_c_memset(data, 0, 6); /* unknown */
    psmbcmd->value.transaction2_q.data.endoffset += 6;
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EALLOCATION :
    psmbcmd->value.transaction2_q.setupcount = 1;
    psmbcmd->value.transaction2_q.setup[0] = NETWOX_SMBCMDTSC2Q_SUBCMD_SETFILEINFO;
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.para, 6, &para));
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.setfileinfo_eallocation.fid);
    netwib__data_append_uint16_le(para, NETWOX_SMBCMDTSC2_FMT_FILE_EALLOCATION);
    netwib_c_memset(para, 0, 2); /* reserved */
    psmbcmd->value.transaction2_q.para.endoffset += 6;
    netwib_er(netwox_smbcmdtsc2_fmt_file_eallocation_append(&psmbcmdtsc2q->value.setfileinfo_eallocation.eallocation, &psmbcmd->value.transaction2_q.data));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EEOF :
    psmbcmd->value.transaction2_q.setupcount = 1;
    psmbcmd->value.transaction2_q.setup[0] = NETWOX_SMBCMDTSC2Q_SUBCMD_SETFILEINFO;
    netwib_er(netwib_buf_wantspace(&psmbcmd->value.transaction2_q.para, 6, &para));
    netwib__data_append_uint16_le(para, psmbcmdtsc2q->value.setfileinfo_eeof.fid);
    netwib__data_append_uint16_le(para, NETWOX_SMBCMDTSC2_FMT_FILE_EEOF);
    netwib_c_memset(para, 0, 2); /* reserved */
    psmbcmd->value.transaction2_q.para.endoffset += 6;
    netwib_er(netwox_smbcmdtsc2_fmt_file_eeof_append(&psmbcmdtsc2q->value.setfileinfo_eeof.eeof, &psmbcmd->value.transaction2_q.data));
    break;
  default :
    return(NETWIB_ERR_PAINVALIDTYPE);
  }

  psmbcmd->value.transaction2_q.totalparasize = (netwib_uint16)netwib__buf_ref_data_size(&psmbcmd->value.transaction2_q.para);
  psmbcmd->value.transaction2_q.totaldatasize = (netwib_uint16)netwib__buf_ref_data_size(&psmbcmd->value.transaction2_q.data);

  return(NETWIB_ERR_OK);
}

/*-------------------------------------------------------------*/
netwib_err netwox_smbcmdtsc2q_show(netwox_constsmbcmdtsc2q *psmbcmdtsc2q,
                                   netwib_buf *pbuf)
{

  switch(psmbcmdtsc2q->type) {
  case NETWOX_SMBCMDTSC2Q_TYPE_FINDFIRST2 :
    netwib_er(netwib_show_array_fmt32(pbuf, " FINDFIRST2 Query"));
    netwib_er(netwox_smbcmdcmn_fileattr32_show(" searchattr", psmbcmdtsc2q->value.findfirst2.searchattr, pbuf));
    netwib_er(netwib_show_array_fmt32(pbuf, " maxinfo=%{uint16}", psmbcmdtsc2q->value.findfirst2.maxinfo));
    netwib_er(netwib_show_array_fmt32(pbuf, " flags=%{uint16}", psmbcmdtsc2q->value.findfirst2.flags));
    netwib_er(netwib_show_array_fmt32(pbuf, " fmt=%{uint16}", psmbcmdtsc2q->value.findfirst2.fmt));
    netwib_er(netwib_show_array_fmt32(pbuf, " storagetype=%{uint32}", psmbcmdtsc2q->value.findfirst2.storagetype));
    netwib_er(netwox_smbcmdcmn_data_show(" searchpattern", NETWOX_SMBCMDCMN_DATATYPE_STRINGONLY, &psmbcmdtsc2q->value.findfirst2.searchpattern, pbuf));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_FINDNEXT2 :
    netwib_er(netwib_show_array_fmt32(pbuf, " FINDNEXT2 Query"));
    netwib_er(netwib_show_array_fmt32(pbuf, " maxinfo=%{uint16}", psmbcmdtsc2q->value.findnext2.maxinfo));
    netwib_er(netwib_show_array_fmt32(pbuf, " fmt=%{uint16}", psmbcmdtsc2q->value.findnext2.fmt));
    netwib_er(netwib_show_array_fmt32(pbuf, " resumekey=%{uint32}", psmbcmdtsc2q->value.findnext2.resumekey));
    netwib_er(netwib_show_array_fmt32(pbuf, " flags=%{uint16}", psmbcmdtsc2q->value.findnext2.flags));
    netwib_er(netwox_smbcmdcmn_data_show(" filename", NETWOX_SMBCMDCMN_DATATYPE_STRINGONLY, &psmbcmdtsc2q->value.findnext2.filename, pbuf));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYFSINFO :
    netwib_er(netwib_show_array_fmt32(pbuf, " QUERYFSINFO Query"));
    netwib_er(netwib_show_array_fmt32(pbuf, " fmt=%{uint16}", psmbcmdtsc2q->value.queryfsinfo.fmt));
    netwib_er(netwox_smbcmdcmn_data_show(" sharename", NETWOX_SMBCMDCMN_DATATYPE_STRINGONLY, &psmbcmdtsc2q->value.queryfsinfo.sharename, pbuf));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYPATHINFO :
    netwib_er(netwib_show_array_fmt32(pbuf, " QUERYPATHINFO Query"));
    netwib_er(netwib_show_array_fmt32(pbuf, " fmt=%{uint16}", psmbcmdtsc2q->value.querypathinfo.fmt));
    netwib_er(netwox_smbcmdcmn_data_show(" filename", NETWOX_SMBCMDCMN_DATATYPE_STRINGONLY, &psmbcmdtsc2q->value.querypathinfo.filename, pbuf));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_QUERYFILEINFO :
    netwib_er(netwib_show_array_fmt32(pbuf, " QUERYFILEINFO Query"));
    netwib_er(netwib_show_array_fmt32(pbuf, " fid=%{uint16}", psmbcmdtsc2q->value.queryfileinfo.fid));
    netwib_er(netwib_show_array_fmt32(pbuf, " fmt=%{uint16}", psmbcmdtsc2q->value.queryfileinfo.fmt));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_BASIC :
    netwib_er(netwib_show_array_fmt32(pbuf, " SETFILEINFO_BASIC Query"));
    netwib_er(netwib_show_array_fmt32(pbuf, " fid=%{uint16}", psmbcmdtsc2q->value.setfileinfo_basic.fid));
    netwib_er(netwox_smbcmdtsc2_fmt_file_basic_show(&psmbcmdtsc2q->value.setfileinfo_basic.basic, pbuf));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_NAME :
    netwib_er(netwib_show_array_fmt32(pbuf, " SETFILEINFO_NAME Query"));
    netwib_er(netwib_show_array_fmt32(pbuf, " fid=%{uint16}", psmbcmdtsc2q->value.setfileinfo_name.fid));
    netwib_er(netwox_smbcmdtsc2_fmt_file_name_show(&psmbcmdtsc2q->value.setfileinfo_name.name, pbuf));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EA :
    netwib_er(netwib_show_array_fmt32(pbuf, " SETFILEINFO_EA Query"));
    netwib_er(netwib_show_array_fmt32(pbuf, " fid=%{uint16}", psmbcmdtsc2q->value.setfileinfo_ea.fid));
    netwib_er(netwox_smbcmdtsc2_fmt_file_ea_show(&psmbcmdtsc2q->value.setfileinfo_ea.ea, pbuf));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EBASIC :
    netwib_er(netwib_show_array_fmt32(pbuf, " SETFILEINFO_EBASIC Query"));
    netwib_er(netwib_show_array_fmt32(pbuf, " fid=%{uint16}", psmbcmdtsc2q->value.setfileinfo_ebasic.fid));
    netwib_er(netwox_smbcmdtsc2_fmt_file_ebasic_show(&psmbcmdtsc2q->value.setfileinfo_ebasic.ebasic, pbuf));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EALLOCATION :
    netwib_er(netwib_show_array_fmt32(pbuf, " SETFILEINFO_EALLOCATION Query"));
    netwib_er(netwib_show_array_fmt32(pbuf, " fid=%{uint16}", psmbcmdtsc2q->value.setfileinfo_eallocation.fid));
    netwib_er(netwox_smbcmdtsc2_fmt_file_eallocation_show(&psmbcmdtsc2q->value.setfileinfo_eallocation.eallocation, pbuf));
    break;
  case NETWOX_SMBCMDTSC2Q_TYPE_SETFILEINFO_EEOF :
    netwib_er(netwib_show_array_fmt32(pbuf, " SETFILEINFO_EEOF Query"));
    netwib_er(netwib_show_array_fmt32(pbuf, " fid=%{uint16}", psmbcmdtsc2q->value.setfileinfo_eeof.fid));
    netwib_er(netwox_smbcmdtsc2_fmt_file_eeof_show(&psmbcmdtsc2q->value.setfileinfo_eeof.eeof, pbuf));
    break;
  default :
    return(NETWIB_ERR_PAINVALIDTYPE);
  }

  return(NETWIB_ERR_OK);
}
