0

I have a Windows 7 VM with floppy drive (A:) configured. I am trying to read a boot sector of floppy drive into structure. However, every time I run this program, it fails to find the floppy drive. I can confirm that it's accessible.

Code:

#include "stdafx.h"
#include<Windows.h>
#include<stdio.h>
#include<conio.h>
#include<WinBase.h>

#pragma pack(1)

struct boot
{
    BYTE jump[3];   
    char bsOemName[8];
    WORD bytesperSector;    
    BYTE sectorpercluster;
    WORD sectorsreservedarea;
    BYTE copiesFAT;
    WORD maxrootdirentries;
    WORD totalSectors;
    BYTE mediaDescriptor;
    WORD sectorsperFAT;
    WORD sectorsperTrack;
    WORD sides;
    WORD hiddenSectors;
    char reserve[480];


};

void ReadSector(char *src, int ss, int num, void* buff);

void main()
{
    struct boot b;
    ReadSector("\\\\.\\A:", 0, 1, &b);  

    printf("\nBoot sector Name: %s\n", b.bsOemName); 
    printf("Bytes per sector: %d\n", b.bytesperSector);
    printf("Sectors per Cluster: %d\n", b.sectorpercluster);
    printf("Total Sectors: %d\n", b.totalSectors);
}

void ReadSector(char *src, int ss, int num, void* buff)
{
    HANDLE h;       //HANDLE is a typedef of void *HANDLE
    unsigned int br;
    h = CreateFile(src, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
    DWORD dw = GetLastError();
    printf("\nLast Error: %d", dw);
    if (h != NULL)
    {
        printf("\nError reading floppy disk '%s'", src);
        printf("\nReturn value for handle = %d", h);

    }   

    else
    {
        printf("\nSuccess..");
    }

    SetFilePointer(h, (ss * 512), NULL,FILE_BEGIN );
    ReadFile(h, buff, num, &br, NULL);
    CloseHandle(h);
}

Output/Error:

 C:\Users\IEUser\Desktop>Hardware.exe

Last Error: 2
Error reading floppy disk '\\.\A:'
Return value for handle = -1
Boot sector Name:
Bytes per sector: 14336
Sectors per Cluster: 248
Total Sectors: 0

Output Screenshot

The error code returned from system is 2: The system cannot find the file specified.

As it fails to open floppy drive, structure variables hold garbage values.

Can someone please help?

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
shellcode
  • 31
  • 5
  • 1
    Paste the error as _text_ please. – Lightness Races in Orbit Oct 04 '16 at 11:28
  • I bet "A:" is not the device name. Find your drive in Device Manager and try some other other "names" listed for that device. There are also some constraints listed in [the documentation](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx) for accessing floppy disks; for example, you're currently not using `FILE_SHARE_WRITE` but it looks like you must. – Lightness Races in Orbit Oct 04 '16 at 11:33
  • 1
    Note that the [documentation](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx) states: "When opening a volume or floppy disk, the dwShareMode parameter must have the FILE_SHARE_WRITEflag." – nos Oct 04 '16 at 11:39
  • @KlasLindbäck That is just escaping the backslash , as is needed in a C string literal. When compiled, the string is, as suggested by the documentation, correct: `\\.\A:` – nos Oct 04 '16 at 17:07
  • @LightnessRacesinOrbit: Thanks for your response mate. I did try other names that I found in Device Manager but that did not help. I also tried using "FILE_SHARE_WRITE" but that did not work either (though that's the one I should use per the documentation). – shellcode Oct 05 '16 at 07:49

1 Answers1

1

It looks like there was a problem with the arguments passed to ReadSector() function (which in turn passes arguments to CreateFile() function) and ReadFile() function calls.

Code in question: ReadSector("\\\\.\\A:", 0, 1, &b);

I just had to add 'L' to the first argument:ReadSector(L"\\\\.\\A:", 0, 1, &b);

That fixed the file handle issue but then it could not read the file.I then realized that it was the ReadFile() function that was not working.

Code in question:ReadFile(h, buff, num, &br, NULL);

I just had to replace 'num' with 512 as this function needs to know how many bytes it needs to read. The 'num' here was set to 1 and that's the reason it wasn't working as expected.

ReadFile(h, buff, 512, &br, NULL)

I've modified the original code little bit to check for CreateFile() and ReadFile() return values.

Here is the modified code:

#include "stdafx.h"
#include<Windows.h>
#include<stdio.h>
#include<conio.h>
#include<WinBase.h>

#pragma pack(1)

struct boot
{
    BYTE jump[3];   //BYTE is a typedef for unsigned char
    char bsOemName[8];
    WORD bytesperSector;    //WORD is a typdef for unisigned short
    BYTE sectorpercluster;
    WORD sectorsreservedarea;
    BYTE copiesFAT;
    WORD maxrootdirentries;
    WORD totalSectors;
    BYTE mediaDescriptor;
    WORD sectorsperFAT;
    WORD sectorsperTrack;
    WORD sides;
    WORD hiddenSectors;
    char reserve[480];


};

void ReadSector(char *src, int ss, int num, void* buff);

void main()
{
    struct boot b;

    ReadSector(L"\\\\.\\A:", 0, 1, &b); //Machinename.drive, 0 = read 0th logical sector(that is Boot Sector), 1 = Read 1 sector, &b = Read it into Structure b

    printf("\nOEM Name: %s", b.bsOemName); 
    printf("\nBytes per sector: %d", b.bytesperSector);
    printf("\nSectors per Cluster: %d", b.sectorpercluster);
    printf("\nTotal Sectors: %d\n", b.totalSectors);

void ReadSector(char *src, int ss, int num, void* buff)
{
    HANDLE h ;      //HANDLE is a typedef of void *HANDLE
    unsigned int br;
    h = CreateFile(src, 
                   GENERIC_READ,
                   FILE_SHARE_READ,
                   0, 
                   OPEN_EXISTING,
                   0,
                   0);

    if (h == INVALID_HANDLE_VALUE)
    {
        printf("\nError reading disk '%s'", src);
        //printf("\nReturn value for handle = %d", h);
        printf("\nLast Error: %ld", dw);

    }

    else
    {
        printf("\nReturn value for handle = %d", h);
    }

    SetFilePointer(h, (ss * 512), NULL,FILE_BEGIN );
    if (!ReadFile(h, buff, 512, &br, NULL))
    {
        printf("\nReadFile: %u\n", GetLastError());
    }
    else
    {
        printf("\nRead File Success!\n");
    }


    CloseHandle(h);
}

Program Output:

C:\Users\IEUser\Desktop>Hardware.exe

Return value for handle = 36
Read File Success!

OEM Name: *-v4VIHC
Bytes per sector: 512
Sectors per Cluster: 1
Total Sectors: 2880

C:\Users\IEUser\Desktop>

Reference: read-and-write-hard-disk-sector-directly-and-efficiently

Community
  • 1
  • 1
shellcode
  • 31
  • 5