title: how to do multiple read/write HDD/USB bytes in c
body: <p>First, here are a couple links i looked at...</p>
  
  <p><a href="https://stackoverflow.com/questions/20161208/read-and-write-hard-disk-sector-directly-and-efficiently">Read and write hard disk sector directly and efficiently</a></p>
  
  <p><a href="https://stackoverflow.com/questions/29219674/read-specific-sector-on-hard-drive-using-c-language-on-windows">Read specific sector on hard drive using C language on windows</a></p>
  
  <p>I'm trying to do almost the same thing. What I'm having trouble with is reading the device multiple times so I can store the read bytes from a DEVICE (USB) to writing them into a FILE.</p>
  
  <p>This is what I am trying to do...</p>
  
  <ol>
  <li>declare variables</li>
  <li>initialize variables</li>
  <li>SetFilePointer()</li>
  <li>ReadFile()</li>
  <li>output the read bytes to a file</li>
  <li>use ReadFile() to get more bytes</li>
  <li>output the read bytes to same file again</li>
  <li>repeat 6 and 7 (actually just repeating 4 and 5)</li>
  </ol>
  
  <p>This doesn't seem to be working. I would like to read x amount of bytes and store those values into a file then read more and store those values in the same file as last time. I would like it to repeat the process until it reads to the end of the device. I would like this program to work on any size of device. If I can put it in a loop then I can read and write infinite sized devices.</p>
  
  <p>This is a how to read/write so I would like to do this in reverse as well. Read the file for values then write them to the device.</p>
  
  <p>I'm using a 128MB USB. It contains 131858432 bytes. If any more info is needed then I will post it if I have it.</p>
  
  <p>My code:</p>
  
  <pre><code>#include &lt;windows.h&gt;
  #include &lt;stdio.h&gt;
  
  int main(int argc, char ** argv)
  {
      BYTE sector[0x400] = {0};
      DWORD bytesRead;
      HANDLE device = NULL;
      int numSector = 1;
      int maxRead = 1;
      FILE *readChar = fopen("G:\\usb_128MB_Dec2.txt", "w+");
  
      device = CreateFile("\\\\.\\L:",                        // Drive to open
                          GENERIC_READ|GENERIC_WRITE,         // Access mode
                          FILE_SHARE_READ|FILE_SHARE_WRITE,   // Share Mode
                          NULL,                               // Security Descriptor
                          OPEN_EXISTING,                      // How to create
                          0,                                  // File attributes
                          NULL);                              // Handle to template
  
      if(device == INVALID_HANDLE_VALUE)
      {
          printf("CreateFile: %u\n", GetLastError());
          system("pause");
          return 1;
      }
  
      //  set the file pointer for first time
      SetFilePointer(device, numSector, NULL, FILE_BEGIN);
  
      // Edit 1. Comment 2.
      if(GetLastError() != NO_ERROR)
      {
          printf("GetLastError: %d\n", GetLastError());
          goto end;       //  end: is before closing files or handles at end of main()
      }
  
      //  read device for maxRead number of bytes and store the reading into a file
      ReadFile(device, sector, maxRead, &amp;bytesRead, NULL);
      fprintf(readChar, "%d\n", sector[0]);
  
      //  This part of code does not act like expected
      SetFilePointer(device, numSector, NULL, FILE_CURRENT);
      if(!ReadFile(device, sector, maxRead, &amp;bytesRead, NULL))
           printf("err\n");
      else
          fprintf(readChar, "%d", sector[0]);
  
  end:    //  Edit 1. Comment 2.
      CloseHandle(device);
      fclose(readChar);
      system("pause");
      return 0;
  }
  </code></pre>
  
  <p>Screen ouput:</p>
  
  <pre><code>GetLastError: 87
  </code></pre>
  
  <p>File output:</p>
  
  <pre><code>Nothing is in the file.
  </code></pre>
  
  <p>The file should contain an 8 bit decimal value instead of nothing or a 0.</p>
  
  <p>Edit 1:</p>
  
  <blockquote>
    <p>87 means INVALID PARAMETER.</p>
    
    <p>Your reads have to be sector aligned so you can't seek to offset 1,
    but only 0, sector_size, 2*sector_size, ..., n*sector_size, Your reads
    have also be in multiplies of sector size, and your memory buffer has
    to be aligned to sector_size.</p>
    
    <p>Sector size could be retrieved with GetDiskFreeSpace and aligned
    memory can be obtained with VirtualAlloc.</p>
    
    <p>Maybe you should check also FSCTL_LOCK_VOLUME and
    FSCTL_DISMOUNT_VOLUME.</p>
  </blockquote>
  
  <p>Here's the other code that works for one time reading of the device</p>
  
  <pre><code>#include &lt;windows.h&gt;
  #include &lt;stdio.h&gt;
  
  int main(int argc, char ** argv)
  {
      BYTE sector[0x200] = {0};
      DWORD bytesRead;
      HANDLE device = NULL;
      int numSector = 1;
      int maxRead = 0x200;
      long long int i;
      FILE *readChar = fopen("G:\\usb_128MB_Dec.txt", "w+");
  
      device = CreateFile("\\\\.\\L:",                        // Drive to open
                          GENERIC_READ|GENERIC_WRITE,         // Access mode
                          FILE_SHARE_READ|FILE_SHARE_WRITE,   // Share Mode
                          NULL,                               // Security Descriptor
                          OPEN_EXISTING,                      // How to create
                          0,                                  // File attributes
                          NULL);                              // Handle to template
  
      if(device == INVALID_HANDLE_VALUE)
      {
          printf("CreateFile: %u\n", GetLastError());
          system("pause");
          return 1;
      }
  
      SetFilePointer(device, numSector, NULL, FILE_BEGIN);
  
      if (!ReadFile(device, sector, maxRead, &amp;bytesRead, NULL))
      {
          printf("ReadFile: %u\n", GetLastError());
          goto end;
      }
      else
      {
          printf("Success!\n");
      }
  
      if(readChar == NULL)
      {
          printf("Did not open file. Exit 2.");
          goto end;
      }
  
      for(i = 0; i &lt; maxRead - 1; i++)
      {
          fprintf(readChar, "%d\n", sector[i]);
      }
      fprintf(readChar, "%d", sector[i]);     // so the previous loop wont add \n to the last read wanted
  
  end:
      CloseHandle(device);
      fclose(readChar);
      system("pause");
      return 0;
  }
  </code></pre>
  
  <p>File contents:</p>
  
  <pre><code>235
  88
  ...
  </code></pre>
  
  <p>Each byte read is stored in decimal value on a new line.</p>
  
  <p>So it may be better understood what I'm trying to do, here it is in code:</p>
  
  <pre><code>//  What I want to do..
  //  This part works
  SetFilePointer(device, numSector, NULL, FILE_BEGIN);
  ReadFile(device, sector, maxRead, &amp;bytesRead, NULL);
  
  for(i = 0; i &lt; size_of_device - 0x200; i += 512)
  {
      for(j = 0; j &lt; maxRead; j++)
      {
          fprintf(readChar, "%d\n", sector[j]);
      }
  
      // stops working
      SetFilePointer(device, numSector, NULL, FILE_CURRENT);
      ReadFile(device, sector, maxRead, &amp;bytesRead, NULL);
  }
  
  for(j = 0; j &lt; maxRead - 1; j++)
  {
      fprintf(readChar, "%d\n", sector[j]);
  }
  fprintf(readChar, "%d", sector[j]);
  //  .. end of what i want to do
  </code></pre>
  
  <p>Edit 2: Working on reading multiple times now.</p>
  
  <pre><code>#include &lt;windows.h&gt;
  #include &lt;stdio.h&gt;
  
  int main(int argc, char ** argv)
  {
      BYTE sector[0x200] = {0};
      DWORD bytesRead;
      HANDLE device = NULL;
      //int numSector = 512;      //  original value was 1 not 512 but variable is not needed
      int maxRead = 512;
      int i, j, k = 0, l;             //  loop variables
  
      FILE *readChar = fopen("G:\\wii u hdd image\\usb_128MB_Dec3.txt", "w+");
  
      if(readChar == NULL)
      {
          printf("Error creating file.\n");
          goto end;
      }
  
      device = CreateFile("\\\\.\\L:",                        // Drive to open
                          GENERIC_READ|GENERIC_WRITE,         // Access mode
                          FILE_SHARE_READ|FILE_SHARE_WRITE,   // Share Mode
                          NULL,                               // Security Descriptor
                          OPEN_EXISTING,                      // How to create
                          0,                                  // File attributes
                          NULL);                              // Handle to template
  
      //  If device does not contain a handle value
      if(device == INVALID_HANDLE_VALUE)
      {
          printf("Error. GetLastError: %u\n", GetLastError());
          goto end;
      }
  
      for(i = 0; i &lt; maxRead*503; i++)    //  maxRead * 503 = 257536
      {
          //  If ReadFile() fails it will exit the program without adding a '\n' to the readChar file.
          if(!ReadFile(device, sector, maxRead, &amp;bytesRead, NULL))
          {
              printf("Error of ReadFile(). GetLastError(): %u\n", GetLastError());
              goto end;
          }
  
          //  If this is the first time through the loop then '\n' won't be added to the readChar file.
          if(i != 0)
          {
              fprintf(readChar, "\n");
              system("cls");
              printf("%.2f%%\n", (i / 257536));
          }
  
          //  Runs for 511 times. Then prints the 512th decimal value after the loop.
          for(j = 0; j &lt; maxRead - 1; j++)
          {
              fprintf(readChar, "%d\n", sector[j]);
          }
          fprintf(readChar, "%d", sector[j]);
      }
  
  end:
      CloseHandle(device);
      fclose(readChar);
      system("pause");
      return 0;
  }
  </code></pre>
  
  <p>Edit 3:</p>
  
  <p>This question has not been answered in another post. The posts stated that have the answers are not answers of the question in the title of this thread. Please read the title carefully. The "answers" provided are about SetFilePointer. The one answer that is here is also not an answer. This is all because none of the supposed answers contain how to read/write HDD/USB bytes in C.</p>