/* Copyright 1998 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
*
*  SMB.H  -- Header for SMB functions
*
*  26-02-94 INH  Original
*
*
*/

#define DIRENTRY_SIZE 22

typedef err_t (*ENUM_DIR_FN) ( BYTE *entry, int format, void *private );

struct disk_size_response
{
  uint blksize;
  uint freeblks;
  uint totalblks;
};

#define MODE_RD   0x20  /* Read, deny write to others */
#define MODE_WR   0x11  /* Write, deny read/write to others */
#define MODE_RDWR 0x12  /* Read/Write, deny read/write to others */

#ifdef LONGNAMES
/* Note.  As per the June 19 1990 document (doc vsn 1.11, prot vsn 3.0),
 * the maximum value for this needs to be 4 + (maximum route name length
 * + 2)/2 for the TRANSACT2_FSCTL call (6.0.1.1.10, page 41).  However,
 * TRANSACT2_IOCTL needs this to be 4 too, so it is left at four for the
 * moment.  You will get a debug output message if you try to add too
 * many setup words.
 */
#define MAX_SETUPWORDS	(4)
#endif

typedef union Transact_SearchContext Transact_SearchContext;


struct TransactParms
{
  int   parms_in_len;
  BYTE *parms_in;
  int   data_in_len;
  BYTE *data_in;

  int   parms_out_maxlen;
  BYTE *parms_out_buf;
  int   parms_out_len;

  int   data_out_maxlen;
  BYTE *data_out_buf;
  int   data_out_len;
#ifdef LONGNAMES
  /* WARNING:  These fields MUST lie at the end because LanManFS provides
   *           a SWI call which takes a pointer to one of these structures.
   *           The user structure is now copied to a local variable, the
   *           size of which is given by the #define just below.
   */
  int   setup_in_len;
  WORD  setup_in[MAX_SETUPWORDS];
  int   setup_out_len;
  int   setup_out_maxlen;
  WORD  setup_out[MAX_SETUPWORDS];
#endif
};

#ifdef LONGNAMES
#  define sizeof_TransactParms_external (offsetof(struct TransactParms, setup_in_len))
#else
#  define sizeof_TransactParms_external (sizeof(struct TransactParms))
#endif

/* Exported routines ================ */



/* Directory functions */

extern err_t SMB_ChkPath ( char *path );
extern err_t SMB_MkDir ( char *path );
extern err_t SMB_RmDir ( char *path );
extern err_t SMB_Delete ( char *path );
extern err_t SMB_Rename ( char *oldpath, char *newpath );
extern err_t SMB_GetAttribs ( char *filename, DOS_ATTRIBS *pAttr );
extern err_t SMB_SetAttribs ( char *filename, DOS_ATTRIBS *pAttr );
extern err_t SMB_ReadDirEntries ( char *path, int max_count,
               ENUM_DIR_FN dirfn, void *private, Transact_SearchContext *);
extern err_t SMB_GetFreeSpace ( char lettr, struct disk_size_response
                                              * pDSR );

/* File functions */

extern err_t SMB_Create ( char *filename, DOS_ATTRIBS *pInAttr,
     int *pOutFH );

extern err_t SMB_Open ( int mode, char *filename,
      DOS_ATTRIBS *pOutAttr, int *pOutFH, int *pOutMode  );

extern err_t SMB_GetLength ( int fh, int *pOutLen );

extern err_t SMB_Read ( int fh, int offset, int len, BYTE *where,
    int *pOutLen ) ;
extern err_t SMB_Write ( int fh, int offset, int len, BYTE *where,
    int *pOutLen ) ;
extern err_t SMB_Truncate ( int fh, int length );
extern err_t SMB_Flush ( int fh ) ;
extern err_t SMB_Close ( int fh, DOS_ATTRIBS *pAttr );

/* Printer functions */

extern err_t SMB_OpenPrinter ( char drvlettr, char *printid, int *ph_out );
extern err_t SMB_WritePrinter ( int PH, BYTE *data, int datalen );
extern err_t SMB_ClosePrinter ( int PH );

/* Transaction (RPC) functions */


extern err_t SMB_Transact ( char drvlettr, char *trans_name,
                              struct TransactParms *pT );

/* Connect/disconnect functions  ----------------------- */

extern err_t SMB_CreateShare ( int service_type,
                               int style,
                        char *serv_name, char *drv_name,
                        char *user_name, char *passwd,
                        char *share_lettr_out );
#define SHR_DISK    0
#define SHR_PRINTER 1
#define SHR_COMM    2
#define SHR_IPC     3

#define CREATE_NORMAL      0
#define CREATE_NEW_SHARE   1
#define CREATE_NEW_USER    2

/*
   CreateShare() is a monster routine to cope with everything
     related to connecting to the server. The main input variables
     are server name, share name and user name; CreateShare will
     attempt to create a share matching all of these parameters, doing
     all the necessary jiggering to make it work. The precise actions
     depend on whether these strings are the same as or different to
     previous values:

     Server Name -

     if a new server name, a new connection to the server will be
       created, the given user will be logged on & the given share
       will be connected. If any of this fails, the connections are
       closed.

     if the same as a server which is already connected:
       i ) if the user name is different to the user currently logged
            on at the server, the current user is logged off and the
            new one is logged on. This will only happen if CREATE_NEW_
            USER is set in the 'style' parameter, otherwise the user
            name is ignored.

       ii) if the share name is a different to any currently connected
            shares on the server, a new 'drive letter' is allocated
            and the new share is connected. If the CREATE_NEW_SHARE
            bit is set and the share name *isn't* new, the error
            ECONNEXISTS will be returned and *share_lettr_out will
            be set to the drive letter of this drive.

       if an error occurs during (i), we've lost the connection to
       the server and all other shares on the server will give
       failure errors when we try to use them. If an error occurs
       during ii), the new share is not created and an error is
       returned.

   The user name and password may optionally be NULL. If the user name
     is blank (NULL pointer, null string or white space), the re-logon
     process in (i) above will not happen, equivalent to CREATE_NEW_USER
     being clear. If a new server is being connected, and both the
     user name and password fields are blank, the user name and password
     fields are taken from LM_Vars. This might theoretically create a
     problem if a server insists on both these fields being blank, but
     in practice NT won't put up with blank user names and WFWG can't be
     made to insist on a blank password.
*/

extern err_t SMB_DeleteShare ( char share_lettr );

extern char * SMB_GetConnInfo ( char drvlettr, int type );
#define GCI_SERVER 0     /* Server name */
#define GCI_SHARE  1
#define GCI_LOGONTYPE 2
/* Returns "User" or "Share" */
#define GCI_SHARETYPE 3
/* Returns "Disk" "Printer" "Comms" or "IPC" */

#define GCI_SERVERINFO 4 /* Description of server */
#define GCI_USER   5     /* User name */

#define GCIF_USERLOGON  'U'
#define GCIF_SHARELOGON 'S'
#define GCIF_DISKTYPE   'D'
#define GCIF_PRNTYPE    'P'
#define GCIF_COMMTYPE   'C'
#define GCIF_IPCTYPE    'I'


/* Test if we're connected to a given server */
extern bool SMB_ConnectedTo ( char *server );

/* Implement idle out protection for broken Microsoft servers */
extern void SMB_AntiIdle ( void );


/* Startup/shutdown */

extern bool  SMB_Init(void);
extern err_t SMB_Shutdown ( void );

/* SMB_WorkBuf **** */

/* This is a temporary buffer, made public on the following strict
   conditions:

   (i) Its contents may become corrupted across any SMB_xxxx calls.
       The main exception is the SMB_Transact call: this buffer is
      intended for use as the return parameter/data buffer.

   (ii) It must not be used by anything which may be called during
          an SMB call (transmit/receive processing functions, timer
          callbacks, SMB_EnumerateDir callbacks etc). This probably
          means anything in Network, LLC, and NetBIOS.

   (iii) Any other module (=C source file) may use it freely. In
          general, it should be assumed corrupted across calls
          between modules.
*/
#ifdef LONGNAMES
/* Need a much larger buffer */
#define SMBWORKBUF_SIZE 16384
#define SMBXMITMEM_SIZE SMBWORKBUF_SIZE
#else
#define SMBWORKBUF_SIZE 1500
#endif
extern BYTE SMB_WorkBuf[SMBWORKBUF_SIZE];

#ifdef LONGNAMES
extern bool SMB_IsLongNameFS( const char * path);
#endif