Listing 3.1
SMBtrans Messages


typedef struct
  {
  ushort  SetupCount;        /* Setup word count          */
  ushort *Setup;             /* Setup words               */
  ushort  Flags;             /* 0x1=Disconnect;0x2=oneway */
  ulong   Timeout;           /* Server timeout in ms      */
  ushort  MaxParameterCount; /* Max param bytes to return */
  ushort  MaxDataCount;      /* Max data bytes to return  */
  ushort  MaxSetupCount;     /* Max setup words to return */
  ushort  TotalParamCount;   /* Total param bytes to send */
  ushort  TotalDataCount;    /* Total data bytes to send  */
  ushort  ParamsSent;        /* Parameters already sent   */
  ushort  DataSent;          /* Data already sent         */
  uchar  *Name;              /* Transaction service name  */
  uchar  *Parameters;        /* Parameter bytes           */
  uchar  *Data;              /* Data bytes                */
  } smb_Transaction_Request;


int SetStr( uchar *dst, int offset, char *src )
  /* ---------------------------------------------------- **
   * Quick function to copy a string into a buffer and
   * return the *total* length, including the terminating
   * nul byte.  Does *no* limit checking (bad).
   * Input:  dst    - Destination buffer.
   *         offset - Starting point within destination.
   *         src    - Source string.
   * Output: Number of bytes transferred.
   * ---------------------------------------------------- **
   */
  {
  int i;

  for( i = 0; '\0' != src[i]; i++ )
    dst[offset+i] = src[i];
  dst[offset+i] = '\0';

  return( i+1 );
  } /* SetStr */


int smb_TransRequest( uchar                   *bufr,
                      int                      bSize,
                      smb_Transaction_Request *Request )
  /* ---------------------------------------------------- **
   * Format an SMBtrans request message.
   * ---------------------------------------------------- **
   */
  {
  int    offset = 0;
  int    keep_offset;
  int    bcc_offset;
  int    result;
  int    i;

  /* See that we have enough room for the SMB-level params.
   * Setup + 14 bytes of SMB params + 2 bytes for Bytecount.
   */
  if( bSize < (Request->SetupCount + 14 + 2) )
    Fail( "Transaction buffer too small.\n" );

  /* Fill the SMB-level parameter block.
   */
  bufr[offset++] = (uchar)(Request->SetupCount + 14);
  smb_SetShort( bufr, offset, Request->TotalParamCount );
  offset += 2;
  smb_SetShort( bufr, offset, Request->TotalDataCount );
  offset += 2;
  smb_SetShort( bufr, offset, Request->MaxParameterCount);
  offset += 2;
  smb_SetShort( bufr, offset, Request->MaxDataCount );
  offset += 2;
  smb_SetShort( bufr, offset, Request->MaxSetupCount );
  offset += 2;
  smb_SetShort( bufr, offset, (Request->Flags & 0x0003) );
  offset += 2;
  smb_SetLong(  bufr, offset, Request->Timeout );
  offset += 4;
  smb_SetShort( bufr, offset, 0 );       /* Reserved word */
  offset += 2;
  keep_offset = offset;   /* Remember ParamCount location */
  offset += 8;               /* Skip ahead to SetupCount. */
  smb_SetShort( bufr, offset, Request->SetupCount );
  offset += 2;
  for( i = 0; i < Request->SetupCount; i++ )
    {
    smb_SetShort( bufr, offset, Request->Setup[i] );
    offset += 2;
    }

  /* Fill the SMB-level data block...
   * We skip the ByteCount field until the end.
   */
  bcc_offset = offset;  /* Keep the Bytecount offset. */
  offset += 2;

  /* We need to have enough room to specify the
   * pipe or mailslot.
   */
  if( strlen( Request->Name ) >= (bSize - offset) )
    Fail( "No room for Transaction Name: %s\n",
          Request->Name );

  /* Start with the pipe or mailslot name.
   */
  offset += SetStr( bufr, offset, Request->Name );

  /* Now figure out how many SMBtrans parameter bytes
   * we can copy, and copy them.
   */
  result = bSize - offset;
  if( result > Request->TotalParamCount )
    result = Request->TotalParamCount;
  Request->ParamsSent = result;
  if( result > 0 )
    (void)memcpy( &bufr[offset],
                  Request->Parameters,
                  result );
  /* Go back and fill in Param Count and Param Offset.
   */
  smb_SetShort( bufr, keep_offset, result );
  keep_offset += 2;
  smb_SetShort( bufr, keep_offset, SMB_HDR_SIZE + offset );
  keep_offset += 2;
  offset += result;

  /* Now figure out how many SMBtrans data bytes we
   * can copy, and copy them.
   */
  result = bSize - offset;
  if( result > Request->TotalDataCount )
    result = Request->TotalDataCount;
  Request->DataSent = result;
  if( result > 0 )
    (void)memcpy( &bufr[offset],
                  Request->Data,
                  result );
  /* Go back and fill in Data Count and Data Offset.
   */
  smb_SetShort( bufr, keep_offset, result );
  keep_offset += 2;
  smb_SetShort( bufr, keep_offset, SMB_HDR_SIZE + offset );
  keep_offset += 2;         /* not really needed any more */
  offset += result;

  /* Go back and fill in the byte count.
   */
  smb_SetShort( bufr, bcc_offset, offset - (bcc_offset+2) );

  /* Done.
   */
  return( offset );
  } /* smb_TransRequest */


$Revision: 1.4 $
$Date: 2003/04/14 12:03:28 $
[W3C Validated] Copyright © 1999-2003 Christopher R. Hertel 
Released under the terms of the LGPL