#include <windows.h>
#include <stdio.h>

#define BUFFERSIZE 4*1024*1024           /* Try to use reads this big. */
#define TAPE_NAME "\\\\.\\TAPE0"
#define DEFAULT_OUTPUT_NAME "tape.dat"

/* copytape [ disk_output_file_name [ tape_file_number ] ] */

int main(int argc, char ** argv) {
  SECURITY_ATTRIBUTES sa;
  FILE * ofile = NULL;
  char * ofname = DEFAULT_OUTPUT_NAME;
  int which_file = 1;
  HANDLE h;
  DWORD rc;

  if (argc >= 3) {
    int rc = sscanf(argv[2], "%d", &which_file);
    if (rc < 1) {
      fprintf(stderr,
	      "Second parameter should be a number (>0) specifying which tape file to read\n");
      fprintf(stderr,
	      "Saw '%s' instead of a number\n", argv[2]);
      
    }
  }
  
  fprintf(stderr, "Opening tape\n");
  h = CreateFile(
		 TAPE_NAME,
		 GENERIC_READ,
		 FILE_SHARE_READ,
		 NULL,
		 OPEN_EXISTING,
		 FILE_ATTRIBUTE_READONLY,
		 NULL);
  
  if (h == INVALID_HANDLE_VALUE) {
    fprintf(stderr,
	    "Could not open tape drive, GLE = %d\n",
	    GetLastError());
    return 1;
  }
  

  fprintf(stderr, "Preparing tape\n");
  rc = PrepareTape(h, TAPE_LOAD, FALSE);
  if (rc != NO_ERROR) {
    int gle = GetLastError();
    fprintf(stderr, "Could not prepare tape drive, rc = %d, gle = %d, h = 0x%x\n",
	    rc, gle, h);
    return 1;
  }
  
  fprintf(stderr, "Rewinding tape\n");
  rc = SetTapePosition(h, TAPE_REWIND, 0, 0, 0, FALSE);
  if (rc != NO_ERROR) {
    fprintf(stderr, "Could not rewind tape drive, rc = %d\n",
	    rc);
    return 1;
  }
  
  if (which_file > 1) {
    fprintf(stderr, "Skipping forward %d filemarks\n", which_file - 1);
    rc = SetTapePosition(h, TAPE_SPACE_FILEMARKS, 0, which_file - 1, 0, FALSE);
    if (rc != NO_ERROR) {
      fprintf(stderr, "Could not position tape drive, rc = %d\n",
	      rc);
      return 1;
    }
  }

  if (argc >= 2) {
    ofname = argv[1];
  }

  ofile = fopen(ofname, "wb");

  if (ofile == NULL) {
    fprintf(stderr, "Error opening file\n");
    return 1;
  }

  {
    BOOL rc;
    char * buffer = (char *) VirtualAlloc(NULL, 
					  BUFFERSIZE,
					  MEM_COMMIT,
					  PAGE_READWRITE);
    int nread = 0;

    fprintf(stderr, "Beginning read into buffer 0x%x\n", buffer);

    rc = ReadFile(h,
		  buffer,
		  BUFFERSIZE,
		  &nread,
		  NULL);
    
    while (rc) {
      if (nread == 0) return 0;
      fprintf(stderr, "Read %d bytes\n", nread);
      fwrite(buffer, sizeof(byte), nread, ofile);
      nread = 0;
      rc = ReadFile(h,
		    buffer,
		    BUFFERSIZE,
		    &nread,
		    NULL);
    }
    if (nread != 0) {
      fwrite(buffer, sizeof(byte), nread, ofile);
      nread = 0;
    }
    if (!rc) {
      fprintf(stderr, "I/O failed with rc = %d, last error %d\n", rc, GetLastError());
    }
    
    fflush(stdout);

  }
 
}
