Jump to content

DosListIO: Difference between revisions

From EDM2
Ak120 (talk | contribs)
m Ak120 moved page OS2 API:CPI:DosListIO to DosListIO
Ak120 (talk | contribs)
mNo edit summary
 
(One intermediate revision by the same user not shown)
Line 1: Line 1:
==Description==
DosListIO performs the specified number of seek/read and/or seek/write operations.
DosListIO performs the specified number of seek/read and/or seek/write operations.  


==Syntax==
==Syntax==
<PRE>
  DosListIO (CmdMode, NumEntries, pListIO)
#define INCL_DOSFILEMGR
#include <os2.h>
   
  APIRET DosListIO (ULONG CmdMode, ULONG NumEntries, PLISTIO pListIO)
</PRE>


==Parameters==
==Parameters==
; CmdMode (ULONG) input: This specifies the mode in which the operations should be performed. Valid modes are:
;CmdMode (ULONG) input: This specifies the mode in which the operations should be performed. Valid modes are:
::LISTIO_ORDERED: Operations are performed synchronously in the given order.
::LISTIO_ORDERED: Operations are performed synchronously in the given order.
::LISTIO_UNORDERED: Operations are performed independent of order.
::LISTIO_UNORDERED: Operations are performed independent of order.
; NumEntries (ULONG) input : The number of seek/read or seek/write operations in the list.
;NumEntries (ULONG) input: The number of seek/read or seek/write operations in the list.
; pListIO (PLISTIO) input/output: Pointer to an array of NumEntries LISTIO data structures which contain the information necessary to perform the seek/read and seek/write operations.
;pListIO (PLISTIO) input/output: Pointer to an array of NumEntries LISTIO data structures which contain the information necessary to perform the seek/read and seek/write operations.


==Return Code==
==Return Code==
ulrc (APIRET) returns
;ulrc (APIRET) returns:DosListIO returns one of the following values:
 
DosListIO returns one of the following values
* 0  NO_ERROR
* 0  NO_ERROR
*     ERROR_ACCESS_DENIED
* ERROR_ACCESS_DENIED
*     ERROR_INVALID_HANDLE
* ERROR_INVALID_HANDLE
* 19  ERROR_WRITE_PROTECT  
* 19  ERROR_WRITE_PROTECT  
* 26  ERROR_NOT_DOS_DISK
* 26  ERROR_NOT_DOS_DISK
Line 37: Line 29:
Each request control block contains fields for the Actual number of bytes read/written and the operation return code. These fields are updated upon completion of each request, therefore care must be taken that the memory containing the control block array not be deallocated or manipulated by another thread before the DosListIO request returns.
Each request control block contains fields for the Actual number of bytes read/written and the operation return code. These fields are updated upon completion of each request, therefore care must be taken that the memory containing the control block array not be deallocated or manipulated by another thread before the DosListIO request returns.


There are two valid modes for the list of I/O operations to be processed
There are two valid modes for the list of I/O operations to be processed:
* Ordered - This mode guarantees the order in which the operations will be performed. The API will return with an error code corresponding to the first failed request and will leave the following requests unissued. This provide a synchronous sequence of automatic seek/read and seek/write requests. This is the only mode that is compatible with file systems other than the raw file system.
* Ordered - This mode guarantees the order in which the operations will be performed. The API will return with an error code corresponding to the first failed request and will leave the following requests unissued. This provide a synchronous sequence of automatic seek/read and seek/write requests. This is the only mode that is compatible with file systems other than the raw file system.
* Unordered - This mode does not guarantee the order of issue or completion of the requests. The API will return with an error code if any request fails. Additionally, each request in the list will be issued, even those following a failed operation. This mode is valid for the raw file system only.
* Unordered - This mode does not guarantee the order of issue or completion of the requests. The API will return with an error code if any request fails. Additionally, each request in the list will be issued, even those following a failed operation. This mode is valid for the raw file system only.
This function was included as an addendum of the OS/2 Toolkit 4.5
This function was included as an addendum of the OS/2 Toolkit 4.5


Line 49: Line 40:


It is assumed that the size of each of the two disks is at least 10 megabytes.
It is assumed that the size of each of the two disks is at least 10 megabytes.
<PRE>
<PRE>
#define INCL_DOSFILEMGR     /* Include File Manager APIs */
#define INCL_DOSFILEMGR   /* Include File Manager APIs */
#define INCL_DOSMEMMGR       /* Includes Memory Management APIs */
#define INCL_DOSMEMMGR     /* Includes Memory Management APIs */
#define INCL_DOSERRORS       /* DOS Error values */
#define INCL_DOSERRORS     /* DOS Error values */
#include os2.h>
#include <os2.h>
#include stdio.h>
#include <stdio.h>
#include stdlib.h>
#include <stdlib.h>
#include string.h>
#include <string.h>


#define SIXTY_FOUR_K 0x10000
#define SIXTY_FOUR_K 0x10000
Line 72: Line 62:
   HFILE  hfDisk2        = 0;        /* Handle for disk #2 */
   HFILE  hfDisk2        = 0;        /* Handle for disk #2 */
   ULONG  ulAction      = 0;        /* Action taken by DosOpen */
   ULONG  ulAction      = 0;        /* Action taken by DosOpen */
   UCHAR  uchFileName1[20] = UNC_DISK1, /* UNC Name of disk 1 */
   UCHAR  uchFileName1[20] = UNC_DISK1, /* UNC Name of disk 1 */
           uchFileName2[20] = UNC_DISK2; /* UNC Name of disk 2 */
           uchFileName2[20] = UNC_DISK2; /* UNC Name of disk 2 */
   PBYTE  pBuffer        = 0;
   PBYTE  pBuffer        = 0;
   ULONG  cbTotal        = 0;
   ULONG  cbTotal        = 0;
Line 81: Line 71:
   /* Open a raw file system disk #1 for reading */
   /* Open a raw file system disk #1 for reading */
   rc = DosOpen(uchFileName1,              /* File name */
   rc = DosOpen(uchFileName1,              /* File name */
                hfDisk1,                  /* File handle */
                &hfDisk1,                  /* File handle */
                ulAction,                  /* Action taken by DosOpen */
                &ulAction,                  /* Action taken by DosOpen */
                 0L,                        /* no file size */
                 0L,                        /* no file size */
                 FILE_NORMAL,                /* File attribute */
                 FILE_NORMAL,                /* File attribute */
Line 88: Line 78:
                 OPEN_SHARE_DENYNONE |      /* Access mode */
                 OPEN_SHARE_DENYNONE |      /* Access mode */
                 OPEN_ACCESS_READONLY,
                 OPEN_ACCESS_READONLY,
                 0L);                        /* No extented attributes */
                 0L);                        /* No extended attributes */
   if (rc != NO_ERROR) {
   if (rc != NO_ERROR) {
       printf("DosOpen error rc = %u\n", rc);
       printf("DosOpen error rc = %u\n", rc);
Line 96: Line 86:
   /* Open a raw file system disk #2 for writing */
   /* Open a raw file system disk #2 for writing */
   rc = DosOpen(uchFileName2,              /* File name */
   rc = DosOpen(uchFileName2,              /* File name */
                hfDisk2,                  /* File handle */
                &hfDisk2,                  /* File handle */
                ulAction,                  /* Action taken by DosOpen */
                &ulAction,                  /* Action taken by DosOpen */
                 0L,                        /* no file size */
                 0L,                        /* no file size */
                 FILE_NORMAL,                /* File attribute */
                 FILE_NORMAL,                /* File attribute */
Line 103: Line 93:
                 OPEN_SHARE_DENYNONE |      /* Access mode */
                 OPEN_SHARE_DENYNONE |      /* Access mode */
                 OPEN_ACCESS_READWRITE,
                 OPEN_ACCESS_READWRITE,
                 0L);                        /* No extented attributes */
                 0L);                        /* No extended attributes */
   if (rc != NO_ERROR) {
   if (rc != NO_ERROR) {
       printf("DosOpen error rc = %u\n", rc);
       printf("DosOpen error rc = %u\n", rc);
       return(1);
       return(1);
   } /* endif */
   } /* endif */


   /* Allocate 64K of memory for transfer operations */
   /* Allocate 64K of memory for transfer operations */
Line 138: Line 127:
   listIOCtrlBlks[1].NumBytes = SIXTY_FOUR_K;
   listIOCtrlBlks[1].NumBytes = SIXTY_FOUR_K;


   while (cbTotal   TEN_MEG) {
   while (cbTotal < TEN_MEG) {
 


       ulNumCtrlBlks = 2;
       ulNumCtrlBlks = 2;

Latest revision as of 09:02, 29 November 2018

DosListIO performs the specified number of seek/read and/or seek/write operations.

Syntax

DosListIO (CmdMode, NumEntries, pListIO)

Parameters

CmdMode (ULONG) input
This specifies the mode in which the operations should be performed. Valid modes are:
LISTIO_ORDERED: Operations are performed synchronously in the given order.
LISTIO_UNORDERED: Operations are performed independent of order.
NumEntries (ULONG) input
The number of seek/read or seek/write operations in the list.
pListIO (PLISTIO) input/output
Pointer to an array of NumEntries LISTIO data structures which contain the information necessary to perform the seek/read and seek/write operations.

Return Code

ulrc (APIRET) returns
DosListIO returns one of the following values:
  • 0 NO_ERROR
  • 5 ERROR_ACCESS_DENIED
  • 6 ERROR_INVALID_HANDLE
  • 19 ERROR_WRITE_PROTECT
  • 26 ERROR_NOT_DOS_DISK
  • 29 ERROR_WRITE_FAULT
  • 33 ERROR_LOCK_VIOLATION
  • 87 ERROR_INVALID_PARAMETER
  • 109 ERROR_BROKEN_PIPE
  • 234 ERROR_MORE_DATA

Remarks

DosListIO applies the same restrictions for each seek/read and seek/write control block as would be applied if the requests were issued separately with DosSetFilePtr, DosRead, and DosWrite.

Each request control block contains fields for the Actual number of bytes read/written and the operation return code. These fields are updated upon completion of each request, therefore care must be taken that the memory containing the control block array not be deallocated or manipulated by another thread before the DosListIO request returns.

There are two valid modes for the list of I/O operations to be processed:

  • Ordered - This mode guarantees the order in which the operations will be performed. The API will return with an error code corresponding to the first failed request and will leave the following requests unissued. This provide a synchronous sequence of automatic seek/read and seek/write requests. This is the only mode that is compatible with file systems other than the raw file system.
  • Unordered - This mode does not guarantee the order of issue or completion of the requests. The API will return with an error code if any request fails. Additionally, each request in the list will be issued, even those following a failed operation. This mode is valid for the raw file system only.

This function was included as an addendum of the OS/2 Toolkit 4.5

Example Code

The following is NOT a complete usable program. It is simply intended to provide an idea of how to use Raw I/O File System APIs (e.g. DosOpen, DosListIO, and DosClose).

This example opens physical disk #1 for reading and physical disk #2 for writing. Using DosListIO, 10 megabytes of data is transferred disk #1 to disk #2. Finally, DosClosed is issued to close the disk handles.

It is assumed that the size of each of the two disks is at least 10 megabytes.

#define INCL_DOSFILEMGR    /* Include File Manager APIs */
#define INCL_DOSMEMMGR     /* Includes Memory Management APIs */
#define INCL_DOSERRORS     /* DOS Error values */
#include <os2.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIXTY_FOUR_K 0x10000
#define ONE_MEG     0x100000
#define TEN_MEG     10*ONE_MEG

#define UNC_DISK1  "\\\\.\\Physical_Disk1"
#define UNC_DISK2  "\\\\.\\Physical_Disk2"

int main(void) {
   LISTIO listIOCtrlBlks[2];          /* List IO control blocks   */
   ULONG  ulNumCtrlBlks;              /* Number of control blocks */
   HFILE  hfDisk1        = 0;         /* Handle for disk #1 */
   HFILE  hfDisk2        = 0;         /* Handle for disk #2 */
   ULONG  ulAction       = 0;         /* Action taken by DosOpen */
   UCHAR  uchFileName1[20] = UNC_DISK1, /* UNC Name of disk 1 */
          uchFileName2[20] = UNC_DISK2; /* UNC Name of disk 2 */
   PBYTE  pBuffer        = 0;
   ULONG  cbTotal        = 0;

   APIRET rc = NO_ERROR;              /* Return code */

   /* Open a raw file system disk #1 for reading */
   rc = DosOpen(uchFileName1,               /* File name */
                &hfDisk1,                   /* File handle */
                &ulAction,                  /* Action taken by DosOpen */
                0L,                         /* no file size */
                FILE_NORMAL,                /* File attribute */
                OPEN_ACTION_OPEN_IF_EXISTS, /* Open existing disk */
                OPEN_SHARE_DENYNONE |       /* Access mode */
                OPEN_ACCESS_READONLY,
                0L);                        /* No extended attributes */
   if (rc != NO_ERROR) {
      printf("DosOpen error rc = %u\n", rc);
      return(1);
   } /* endif */

   /* Open a raw file system disk #2 for writing */
   rc = DosOpen(uchFileName2,               /* File name */
                &hfDisk2,                   /* File handle */
                &ulAction,                  /* Action taken by DosOpen */
                0L,                         /* no file size */
                FILE_NORMAL,                /* File attribute */
                OPEN_ACTION_OPEN_IF_EXISTS, /* Open existing disk */
                OPEN_SHARE_DENYNONE |       /* Access mode */
                OPEN_ACCESS_READWRITE,
                0L);                        /* No extended attributes */
   if (rc != NO_ERROR) {
      printf("DosOpen error rc = %u\n", rc);
      return(1);
   } /* endif */

   /* Allocate 64K of memory for transfer operations */
   rc = DosAllocMem((PPVOID) pBuffer, /* Pointer to buffer */
                     SIXTY_FOUR_K,      /* Buffer size */
                     PAG_COMMIT |     /* Allocation flags */
                     PAG_READ |
                     PAG_WRITE);
   if (rc != NO_ERROR) {
      printf("DosAllocMem error rc = %u\n", rc);
      return(1);
   } /* endif */

   /* Initialize listIO control blocks */
   memset(listIOCtrlBlks, 0, sizeof(listIOCtrlBlks));

   listIOCtrlBlks[0].hFile = hfDisk1;       /* Handle for disk 1 */
   listIOCtrlBlks[0].CmdFlag = LISTIO_READ | /* Read operation */
                               FILE_CURRENT;
   listIOCtrlBlks[0].Offset = 0;
   listIOCtrlBlks[0].pBuffer = (PVOID)pBuffer;
   listIOCtrlBlks[0].NumBytes = SIXTY_FOUR_K;

   listIOCtrlBlks[1].hFile = hfDisk2;        /* Handle for disk 2 */
   listIOCtrlBlks[1].CmdFlag = LISTIO_WRITE | /* Write operation */
                               FILE_CURRENT;
   listIOCtrlBlks[1].Offset = 0;
   listIOCtrlBlks[1].pBuffer = (PVOID)pBuffer;
   listIOCtrlBlks[1].NumBytes = SIXTY_FOUR_K;

   while (cbTotal < TEN_MEG) {

      ulNumCtrlBlks = 2;
      rc = DosListIO(LISTIO_ORDERED,
                     ulNumCtrlBlks,
                     listIOCtrlBlks);
      if (rc != NO_ERROR) {
         printf("DosListIO error  rc = %u\n", rc);
         break;
      } else {

         /* Check return code from the read operation */
         if (listIOCtrlBlks[0].RetCode != NO_ERROR) {
            printf("DosListIO read operation failed, rc = %u\n",
                    listIOCtrlBlks[0].RetCode);
           return 1;
         }

         /* Check return code from the write operation */
         if (listIOCtrlBlks[0].RetCode != NO_ERROR) {
            printf("DosListIO write operation failed, rc = %u\n",
                    listIOCtrlBlks[0].RetCode);
            return 1;
         }
      }

      if (listIOCtrlBlks[0].Actual != listIOCtrlBlks[1].Actual) {
         printf("Bytes read (%u) does not equal bytes written (%u)\n",
                listIOCtrlBlks[0].Actual, listIOCtrlBlks[1].Actual);
         return 1;
      }

      cbTotal += SIXTY_FOUR_K; /* Update total transferred */

   } /* end while */

   printf("Transfer successfully %d bytes from disk #1 to disk #2.\n",
          cbTotal);

   /* Free allocated memmory */
   rc = DosFreeMem(pBuffer);
   if (rc != NO_ERROR) {
      printf("DosFreeMem error  return code = %u\n", rc);
      return 1;
   }

   rc = DosClose(hfDisk1);
   if (rc != NO_ERROR) {
      printf("DosClose error  return code = %u\n", rc);
      return 1;
   }

   rc = DosClose(hfDisk2);
   if (rc != NO_ERROR) {
      printf("DosClose error  return code = %u\n", rc);
      return 1;
   }
return NO_ERROR;
}

Related Functions