/**
   * Process a NetShareGetInfo transaction request.
   *
   * @param sess Server session that received the request.
   * @param tbuf Transaction buffer
   * @param prmDesc Parameter descriptor string.
   * @param dataDesc Data descriptor string.
   * @param tpkt Transaction reply packet
   * @return true if the transaction has been processed, else false.
   */
  protected static final boolean procNetShareGetInfo(
      SMBSrvSession sess,
      TransactBuffer tbuf,
      String prmDesc,
      String dataDesc,
      SMBSrvTransPacket tpkt)
      throws IOException, SMBSrvException {

    // Validate the parameter string

    if (prmDesc.compareTo("zWrLh") != 0)
      throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);

    // Unpack the share get information specific parameters

    DataBuffer paramBuf = tbuf.getParameterBuffer();

    String shareName = paramBuf.getString(32, false);
    int infoLevel = paramBuf.getShort();
    int bufSize = paramBuf.getShort();

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln("NetShareGetInfo - " + shareName + ", infoLevel=" + infoLevel);

    // Check if the information level requested and data descriptor string match

    if (infoLevel == 1 && dataDesc.compareTo("B13BWz") == 0) {

      // Find the required share information

      SharedDevice share = null;

      try {

        // Get the shared device details

        share = sess.getSMBServer().findShare(null, shareName, ShareType.UNKNOWN, sess, false);
      } catch (Exception ex) {
      }

      if (share == null) {
        sess.sendErrorResponseSMB(tpkt, SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);
        return true;
      }

      // Create the transaction reply data buffer

      TransactBuffer replyBuf = new TransactBuffer(tbuf.isType(), 0, 6, 1024);

      // Pack the parameter block

      paramBuf = replyBuf.getParameterBuffer();

      paramBuf.putShort(0); // status code
      paramBuf.putShort(0); // converter for strings
      paramBuf.putShort(1); // number of entries

      // Pack the data block, calculate the size of the fixed data block

      DataBuffer dataBuf = replyBuf.getDataBuffer();
      int strPos = SMBSrvTransPacket.CalculateDataItemSize("B13BWz");

      // Pack the share name

      dataBuf.putStringPointer(strPos);
      strPos = dataBuf.putFixedStringAt(share.getName(), 13, strPos);

      // Pack unknown byte, alignment ?

      dataBuf.putByte(0);

      // Pack the share type flags

      dataBuf.putShort(share.getType());

      // Pack the share comment

      dataBuf.putStringPointer(strPos);

      if (share.getComment() != null)
        strPos = dataBuf.putStringAt(share.getComment(), strPos, false, true);
      else strPos = dataBuf.putStringAt("", strPos, false, true);

      // Set the data block length

      dataBuf.setLength(strPos);

      // Send the transaction response

      tpkt.doTransactionResponse(sess, replyBuf);
    } else {

      // Debug

      if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
        sess.debugPrintln(
            "NetShareGetInfo - UNSUPPORTED "
                + shareName
                + ", infoLevel="
                + infoLevel
                + ", dataDesc="
                + dataDesc);

      // Server error

      throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);
    }

    // We processed the request

    return true;
  }
  /**
   * Process a NetShareEnum transaction request.
   *
   * @param sess Server session that received the request.
   * @param tbuf Transaction buffer
   * @param prmDesc Parameter descriptor string.
   * @param dataDesc Data descriptor string.
   * @param tpkt Transaction reply packet
   * @return true if the transaction has been processed, else false.
   */
  protected static final boolean procNetShareEnum(
      SMBSrvSession sess,
      TransactBuffer tbuf,
      String prmDesc,
      String dataDesc,
      SMBSrvTransPacket tpkt)
      throws IOException, SMBSrvException {

    // Validate the parameter string

    if (prmDesc.compareTo("WrLeh") != 0)
      throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);

    // Unpack the server get information specific parameters

    DataBuffer paramBuf = tbuf.getParameterBuffer();

    int infoLevel = paramBuf.getShort();
    int bufSize = paramBuf.getShort();

    // Debug

    if (Debug.EnableInfo && sess.hasDebug(SMBSrvSession.DBG_IPC))
      sess.debugPrintln("NetShareEnum infoLevel=" + infoLevel);

    // Check if the information level requested and data descriptor string match

    if (infoLevel == 1 && dataDesc.compareTo("B13BWz") == 0) {

      // Get the share list from the server

      SharedDeviceList shrList = sess.getSMBServer().getShareList(null, sess);
      int shrCount = 0;
      int strPos = 0;

      if (shrList != null) {

        // Calculate the fixed data length

        shrCount = shrList.numberOfShares();
        strPos = SMBSrvTransPacket.CalculateDataItemSize("B13BWz") * shrCount;
      }

      // Create the transaction reply data buffer

      TransactBuffer replyBuf = new TransactBuffer(tbuf.isType(), 0, 6, bufSize);

      // Pack the parameter block

      paramBuf = replyBuf.getParameterBuffer();

      paramBuf.putShort(0); // status code
      paramBuf.putShort(0); // converter for strings
      paramBuf.putShort(shrCount); // number of entries
      paramBuf.putShort(shrCount); // total number of entries

      // Pack the data block

      DataBuffer dataBuf = replyBuf.getDataBuffer();
      Enumeration<SharedDevice> enm = shrList.enumerateShares();

      while (enm.hasMoreElements()) {

        // Get the current share

        SharedDevice shrDev = enm.nextElement();

        // Pack the share name, share type and comment pointer

        dataBuf.putFixedString(shrDev.getName(), 13);
        dataBuf.putByte(0);
        dataBuf.putShort(ShareType.asShareInfoType(shrDev.getType()));
        dataBuf.putStringPointer(strPos);

        if (shrDev.getComment() != null)
          strPos = dataBuf.putStringAt(shrDev.getComment(), strPos, false, true);
        else strPos = dataBuf.putStringAt("", strPos, false, true);
      }

      // Set the data block length

      dataBuf.setLength(strPos);

      // Send the transaction response

      tpkt.doTransactionResponse(sess, replyBuf);
    } else throw new SMBSrvException(SMBStatus.SRVInternalServerError, SMBStatus.ErrSrv);

    // We processed the request

    return true;
  }