NWSMTSReadDataSets (Obsolete)

Reads data sets on the Target Service, formats the data according to SIDF, and returns it in a buffer.

Syntax

  #include <smstsapi.h> 
   
  CCODE NWSMTSReadDataSets (
     UINT32      connection, 
     UINT32	     scanSequence, 
     UINT32      openMode, 
     UINT32	     bytesToRead, 
     BUFFERPTR	  buffer, 
     UINT32     	*bytesRead, 
     UINT32     	*done, 
     UINT32	     *readHandle);
  

Parameters

connection

(IN) Specifies the connection information returned by NWSMTSConnectToTargetService or NWSMTSConnectToTargetServiceEx.

scanSequence

(IN) Specifies the scanning sequence value returned by NWSMTSScanDataSetBegin.

openMode

(IN) Specifies the generic and TSA-specific open mode to apply to all the data sets that can fit the buffer (see Open Modes for possible values).

bytesToRead

(IN) Specifies the amount of free space in the buffer.

buffer

(OUT) Points to the buffer to contain the data (must be at least bytesToRead bytes).

bytesRead

(OUT) Points to the number of bytes read into buffer.

done

(OUT) Points to a boolean value indicating if NWSMTSReadDataSets should be called again:

  • TRUE Finished; no need to call NWSMTSReadDataSets again
  • FALSE Call NWSMTSReadDataSets again
readHandle

(IN/OUT) Points to the iteration handle (should be zero the first time NWSMTSReadDataSets is called).

Return Values

See Section 9.3, Target Service Return Values for more information.

The following table lists the return values associated with the function.

0x00000000

Successful

0xFFFEFFFF

NWSMDR_INVALID_CONNECTION

0xFFFEFFFE

NWSMDR_INVALID_PARAMETER

Engine Developer

ReadDataSets is an enhanced version of ReadDataSet which helps in backing up small files faster. It is used during backup to collect all requested information about possibly more than one data set. Eventually, the OUT buffer will contain the data in System Independent Data Format (SIDF).

In the cases when the data set data is larger than the size of the buffer, it behaves similar to the ReadDataSet wherein it has to be called repeatedly as it returns portions of the data set at a time.

For instances when the data for more than one data set is able to fit within the buffer, it shall be appended one after another. It formats the File Headers (or Record Headers) and File Continuation Headers (or Sub-Record Headers) in the buffer. This facilitates reading more than one data set on a single call to ReadDataSets.

This call takes care of open/reading/closing of data sets (OpenDataSetForBackup, ReadDataSet and CloseDataSet as well as calling ScanNextDataSet).

The data returned in the buffer does not include unused bytes at the end. The unused value will be bytesToRead - *bytesRead. The unused part of the buffer will not become zero by this call. NWSMPadBlankSpace can be used to fill the unused space in buffer with zeroes.

Remarks

Before NWSMTSReadDataSets is called, NWSMTSScanDataSetBegin must be called to initiate the scan.

done will be freed on the last successful read.

NWSMTSReadDataSets reads the data for a set of data sets into buffer (if SIDF is used). If the buffer cannot contain all of the data set’s data, NWSMTSReadDataSets must be called repeatedly to retrieve all data.

If buffer can accommodate data for more than one data set, all data for those data sets will be returned. done indicates if data for all data sets have been read. Normally when done is FALSE, bytesRead will be equal to bytesToRead except when some intermediate data sets were not read.

IMPORTANT:This API is not supported in NetWare 6.5.

See Also

NWSMTSCloseDataSet, NWSMTSOpenDataSetForBackup, NWSMTSReadDataSet, NWSMTSScanDataSetBegin, NWSMTSScanDataSetEnd, NWSMTSScanNextDataSet

Example

  #include <smsutapi.h> 
  #include <smstsapi.h> 
   
  NWSM_DATA_SET_NAME_LIST *resourceName; 
  NWSM_DATA_SET_NAME name; 
  NWSM_SCAN_CONTROL scanControl; 
  NWSM_SCAN_INFORMATION *scanInformation=NULL; 
  NWSM_SELECTION_LIST *selectionList; 
  UINT32 sequence, openModes, bytesRead, transferBufferSpaceLeft, 
       bytesWritten, transferBufferOffset, maxTransferBufferSize; 
  NWSM_RECORD_HEADER_INFO recordHeaderInfo = {0}; 
  BUFFERPTR transferBuffer; 
   
  /* Setup resource name - see NWSMListTSResources and NWSMTSScanTargetServiceResource. */ 
  /* Gather the TSA options and get the user’s input*/ 
  /* Setup scanControl */ 
  /* Setup selectionList - see NWSMTSGetTargetSelectionTypeStr */ 
  /* Begin the backup session. */ 
   
  NWSMTSScanDataSetBegin(connection, resourceName, &scanControl, 
      selectionList, &sequence, &scanInformation, &dataSetName); 
   
  /*Set the open modes from the user’s selection. The modes were 
         received when the TSA options were gathered. */ 
  openModes = user selected modes; 
   
  /* Create Transfer Buffer. The larger the TB, the faster it backs up */ 
  transferBuffer = (BUFFERPTR) calloc(1, maxTransferBufferSize); 
  /* Initialize the current transferBuffer space to maximum.*/	 
  currentTBSpace = initialTBSpace = 
  session.transferBufferInfo.maxTransferBufferSize - 
  session.transferBufferInfo.transferBufferDataOffset; 
  /* It will be nice to start using NWSMTSReadDataSets now. */ 
  do 
    { 
    /* Check for user intervention. Hopefully he won’t. */ 
    if ((ccode = CheckForOperatorAbort()) != 0) 
      goto Return; 
    /* Read as many data sets as possible in one shot. Depends on 
           buffer size though. */ 
      NWSMTSReadDataSets (connection, sequence, openModes, 
                          currentTBSpace, transferBufferPtr, &bytesRead, &done, 
                          &readHandle) ; 
    /* Display number of bytes written to TB. */ 
            StatusTotalWritten(bytesRead); 
    myHeaderSize = transferBufferData ; 
    /* Update the TB data */	 
    transferBufferData += bytesRead ; 
    myBufferSize = transferBufferData - myHeaderSize ; 
    myBufferPtr = transferBufferPtr ; 
    /* We are not sure which data sets got backed up with the call to 
       NWSMTSReadDataSets. So get and display all data set info for all 
       data sets contained in TB. User will again be happy to know. */ 
   while (myBufferSize)  
      { 
      /* While there is data in the TB, get the record/subrecord header 
            from TB */ 
      ccode = NWSMGetRecordHeaderOnly (&myBufferPtr, &myBufferSize, 
  &recordHeaderInfo) ; 
      
      if (!ccode) 
        { 
        /* If we have a record/subrecord, get the data from the 
                   transfer buffer. */ 
                if ((recordHeaderInfo.dataSetInfoRetrieved == 
                                     DATA_SET_INFO_NOT_STARTED)|| 
                    (recordHeaderInfo.dataSetInfoRetrieved == DATA_SET_INFO_SPANNED)) 
   NWSMGetDataSetInfo (&myBufferPtr, &myBufferSize, 
                         &recordHeaderInfo) ; 
        /* If all data retrieved from current transfer buffer, break 
                  and get the next transfer buffer. */ 
        if (!myBufferSize) 
  break; 
                if (recordHeaderInfo.dataSetInfoRetrieved == DATA_SET_INFO_COMPLETE) 
  { 
  /* Data in the recordHeaderInfo.dataSetName and 
                     recordHeaderInfo.scanInformation can now be used. */ 
  if ((_ccode = NWSMGetOneName ((recordHeaderInfo.dataSetName, &name)) != 0) 
    { 
    if (NWSMConvertError (connection, _ccode, errorMessage)) 
      sprintf (errorMessage, GetMessage (EM_UNDEFINED_ERROR), _ccode); 
    StatusDisplayError (TRUE, GET_ONE_NAME_ERR, _ccode); 
    } 
  else 
    { 
    /* Display the data set name to the user. */ 
    if (recordHeaderInfo.scanInformation->parentFlag) 
      { 
      /* Display name.name as a parent (e.g., directory) */ 
      StatusDirectoryName (name.nameSpaceType, name.name); 
      recordHeaderInfo.pathIsFullyQualified = TRUE; 
      } 
    else 
      { 
      /* Display name.name as a child (e.g., file) */ 
      StatusFileName (name.name); 
     if (withParentHandle) 
  recordHeaderInfo.pathIsFullyQualified = FALSE; 
      else 
  recordHeaderInfo.pathIsFullyQualified = TRUE; 
      } 
    } 
  } 
       /* Check again if all data retrieved from current transfer buffer, break and get the next transfer buffer. */ 
        if (!myBufferSize) 
  break; 
        /* Update TB information. */ 
        myBufferPtr += recordHeaderInfo.recordSize ; 
        myBufferSize -= recordHeaderInfo.recordSize ; 
        } 
      else 
        break; 
      } 
    transferBufferPtr  += bytesRead ; 
    if (done) 
      { 
      NWSMPadBlankSpace ( transferBufferPtr, currentTBSpace-bytesRead)); 
      ccode = WriteTransferBufferToMedia ( &bufferIndex, isFirstBuffer,  
  &transferBufferData, FALSE, &transferBufferPtr); 
      } 
     else 
      { 
      ccode = WriteTransferBufferToMedia ( &bufferIndex, isFirstBuffer,  
  &transferBufferData, TRUE, &transferBufferPtr); 
      } 
    if (ccode != 0) 
      { 
      #if defined (DEBUG_CODE) 
  DEBUG_BEGIN 
    printf ("BkTgt: WTBToMedia = 0x%X (%s:%u)\n", 
  ccode, __FILE__, __LINE__); 
  DEBUG_END 
     #endif 
      goto Return; 
      }	 
    break; 
    } 
  if (isFirstBuffer) 
    isFirstBuffer = FALSE; 
          currentTBSpace = initialTBSpace; 
  } 
        }while (!done) ;  
        /* We’ve reached the end and that was real fast. It will be nice to 
          clean up. */ 
        /* Cleaning up is normally a pain but its so easy here*/
  

Returns NWSMTSEndReadDataSets (connection, &readHandle);