Solved

Read (and) write discsectors in a Win32-application

Posted on 1997-10-17
1
246 Views
Last Modified: 2013-12-03
How do I read (and write) discsectors with DeviceIOControl ? I need the source written in C++ or Delphi.
0
Comment
Question by:Beefs
1 Comment
 
LVL 2

Accepted Solution

by:
amartin030297 earned 50 total points
ID: 1407662
You CANNOT to it exclusivly with DeviceIOCTL..you must also
have a VxD backing you which responds to your IOCTL and operates as requested...Thus you need ALSO a VxD which
performs Ring 0 file io.  I'll include for you the entire
code necessary to build a VxD which performs the
file IO you asked about.  You'll need VToolsD and MSVC 4.0 or
greater to build the VxD.
   Enjoy,
     Aaron





Begin VXDFILE.H

/*************************************************************************************
// NOT FOR COMMERCIAL USE WITHOUT SIGNED LICENSE AGREEMENT.
// By using this file, you agree to the Copying agreement and terms.
//
// CopyRight 1996,1997  Aaron Martin.  All Rights Reserved.
// To request license, write:  amartin@texas.net
*************************************************************************************/

#ifndef VXDFile_h
#define VXDFile_h

#include <vtoolscp.h>
#define VXDFILE_SEEKBEGIN 1
#define VXDFILE_SEEKCURRENT    2
#define VXDFILE_SEEKEND    4

class VXDFile
{
      private:
            HANDLE fh;
        unsigned long offset;
        unsigned long fileSize;
            R0_Open(char *fileName, unsigned long flags);

    protected:
        _WIN32_FIND_DATA_BCS findData;
        HANDLE findHandle;

      public:
            ~VXDFile();
            VXDFile();
        void close();

//Methods used to open a file.
            BOOL create(char *fileName);
        BOOL readOpen(char *fileName);
        BOOL randomOpen(char *fileName);

//Accessing Data
        unsigned long seek(unsigned long pos);
        unsigned long seekC(signed long pos, unsigned long from=VXDFILE_SEEKBEGIN);
        unsigned long read(void *buffer, unsigned long bytes);
        unsigned long write(void *buffer, unsigned long bytes);

//Misc information
        unsigned long getFileSize() { return fileSize; }
        unsigned long getCurrentPosition() { return offset; }

//Find Methods
        BOOL findFirst(char *path);
        BOOL findNext();
        void     stopFind();
        _WIN32_FIND_DATA_BCS getFindData() { return findData; }  //ifs.h
        char *  getFindName() { return (char *)&findData.cFileName; }

//Static functions
        static BOOL deleteFile(char *fileName);
        static unsigned long getFreeDiskSpace(char driveAIS0=2);  
        static BOOL rename(char *oldName, char *newName);
        static BOOL exists(char *fileName);
        static BOOL removeDir( char *dirName );
        static BOOL createDir( char *dirName );

//Absolute disk reads.
        static BOOL ABSRead (unsigned char driveAIS0, void * buffer, unsigned long sectorNumber);
        static BOOL ABSWrite(unsigned char driveAIS0, void * buffer, unsigned long sectorNumber);
};

/*
Special Thanks:
    Thomas F. Divine  --  for createDir and removeDir.

*/


#endif

END VXDFILE.H

BEGIN VXDFILE.CPP
/*************************************************************************************
// NOT FOR COMMERCIAL USE WITHOUT SIGNED LICENSE AGREEMENT.
// By using this file, you agree to the Copying agreement and terms.
//
// CopyRight 1996,1997  Aaron Martin.  All Rights Reserved.
// To request license, write:  amartin@texas.net
*************************************************************************************/
#include "VXDFile.h"

#define VXDFILE_READ      1
#define VXDFILE_WRITE     2
#define VXDFILE_CREATE  4
#define VXDFILE_OPEN       8
#define VXDFILE_APPEND  16
#define VXDFILE_READWRITE 32

VXDFile::VXDFile() : fh(NULL), findHandle(NULL)
{
      
}

void VXDFile::close()
{
    unsigned short error;
    fileSize=0;
    offset=0;
    if (fh)
        R0_CloseFile(fh, &error);

}
            
VXDFile::~VXDFile()
{
    close();
    stopFind();
}

void VXDFile::stopFind()
{
    unsigned short error;
    if (findHandle)
    {
        R0_FindCloseFile(findHandle, &error);
        findHandle=NULL;
    }
}

BOOL VXDFile::R0_Open(char *fileName, unsigned long flags)
{
    close();
    unsigned long buildFlags=0, action=0, result=FALSE;
    buildFlags=OPEN_SHARE_DENYREADWRITE | OPEN_FLAGS_COMMIT;

    if (flags & VXDFILE_WRITE)
    {
        buildFlags |= OPEN_ACCESS_WRITEONLY;
    }
    if (flags & VXDFILE_READ)
    {
        buildFlags |= OPEN_ACCESS_READONLY;
    }
    if (flags & VXDFILE_READWRITE)
    {
        buildFlags |= OPEN_ACCESS_READWRITE;
    }

    if (flags & VXDFILE_CREATE)
    {
        action |= ACTION_CREATEALWAYS;
    }

    if (flags & VXDFILE_OPEN)
    {
        action |=  ACTION_OPENEXISTING;
    }
    if (flags & VXDFILE_APPEND)
    {
        action |= ACTION_OPENALWAYS;
    }

    unsigned short error;
    unsigned char actionTaken;

                    fh = R0_OpenCreateFile(
                                FALSE,  /*bInContext*/  
                                fileName,
                                buildFlags,
                                ATTR_NORMAL,
                                action,
                                0,  /*flags, optinally: R0_NO_CACHE      */              
                                &error,
                                &actionTaken
                                );

    unsigned short error2;
    if (fh)
        fileSize=R0_GetFileSize(fh, &error2);
    if (fh)
        result=TRUE;
    return result;
}


BOOL VXDFile::create(char *fileName)
{
    return R0_Open(fileName,VXDFILE_READWRITE | VXDFILE_CREATE);
}

BOOL VXDFile::readOpen(char *fileName)
{
    return R0_Open(fileName,VXDFILE_READ | VXDFILE_OPEN);
}

BOOL VXDFile::randomOpen(char *fileName)
{
    return R0_Open(fileName,VXDFILE_READWRITE | VXDFILE_APPEND);
}

unsigned long VXDFile::seek(unsigned long pos)
{
    if (pos > fileSize)
        pos=fileSize;
    offset=pos;
    return offset;
}

unsigned long VXDFile::seekC(signed long pos, unsigned long from)
{
    unsigned long relOff=0;
    if (from == VXDFILE_SEEKCURRENT)
    {
        relOff=offset;
    }
    if (from == VXDFILE_SEEKEND)
    {
        relOff=fileSize;
    }
    pos+=relOff;
    return seek(pos);
}

unsigned long VXDFile::read(void *buffer, unsigned long bytes)
{
    unsigned short error=1;
    unsigned long distance=0;
    if (fh)
    {
        distance=R0_ReadFile(FALSE, fh, buffer, bytes, offset, &error);
    }
    offset+=distance;
    return distance;
}

unsigned long VXDFile::write(void *buffer, unsigned long bytes)
{
    unsigned short error=1;
    unsigned long distance=0;
    if (fh)
    {
        distance=R0_WriteFile(FALSE, fh, buffer, bytes, offset, &error);
    }
    offset+=distance;
    if (offset > fileSize)
        fileSize=offset;
    return distance;
}

BOOL VXDFile::deleteFile(char *fileName)
{
    unsigned short error;
    return R0_DeleteFile(fileName, 0, &error);
}

unsigned long VXDFile::getFreeDiskSpace(char driveAIS0)
{
    unsigned short spc, freecl, bps, tc, error;

    //R0_GetDiskFreeSpace(driverNumber, PWORD pnSectorsPerCluster, PWORD pnFreeClusters,
                                        //PWORD pnBytesPerSector, PWORD pTotalClusters, PWORD pError);

    R0_GetDiskFreeSpace(driveAIS0+1, &spc, &freecl, &bps, &tc, &error);
    unsigned long bytes=bps*spc*freecl;
    return bytes;
}

BOOL VXDFile::rename(char *oldName, char *newName)
{
    unsigned short error;
    return R0_RenameFile(oldName, newName, &error);
}

BOOL VXDFile::exists(char *fileName)
{
    HANDLE tfh;
    unsigned long buildFlags=0, action=0, result=FALSE;
    buildFlags=SHARE_COMPATIBILITY;
    buildFlags |= OPEN_ACCESS_READONLY;
    action |=  ACTION_OPENEXISTING;

    unsigned short error;
    unsigned char actionTaken;

    tfh = R0_OpenCreateFile(
                FALSE,  /*bInContext*/  
                fileName,
                buildFlags,
                ATTR_NORMAL,
                action,
                0,  /*flags, optinally: R0_NO_CACHE      */              
                &error,
                &actionTaken
                );

    if (tfh)
    {
        result=TRUE;
        R0_CloseFile(tfh, &error);
    }
    return result;
}


BOOL VXDFile::findFirst(char *path)
{
    unsigned short error;
    stopFind();
    findHandle=R0_FindFirstFile(path, FILE_ATTRIBUTE_EVERYTHING, &findData, &error);
    if (!findHandle)
    {
        return FALSE;
    }
    return TRUE;
}
BOOL VXDFile::findNext()
{
    BOOL result=FALSE;
    unsigned short error;
    result=R0_FindNextFile(findHandle,&findData, &error);
    if (!result)
    {
            stopFind();
    }    
    return result;
}


/////////////////////////////////////////////////////////////////////////////
//// R0_CreateDir
//
// Purpose
// Make a new directory.
//
// Parameters
//
// Return Value
// Returns TRUE on success.
//
// Remarks
//

BOOL VXDFile::createDir( char *dirName )
{
        BOOL                            bResult;
        CLIENT_STRUCT   saveRegs;
        ALLREGS                 Registers;

        /* Save The Client State
        ------------------------ */
        Save_Client_State(&saveRegs);

        Registers.REDX = (DWORD )dirName;
        Registers.REAX = 0x7139;                // Create Directory

        /* Make The DOS Call
        -------------------- */
        Exec_VxD_Int( 0x21, &Registers );

        if( Registers.RFLAGS & 1 )
        {
                bResult = FALSE;                // Failure
        }
        else
        {
                bResult = TRUE;         // Success
        }

        /* Restore The Client State
        --------------------------- */
        Restore_Client_State( &saveRegs );      // restore client registers

        return( bResult );
}


/////////////////////////////////////////////////////////////////////////////
//// R0_RemoveDir
//
// Purpose
// Remove an existing directory.
//
// Parameters
//
// Return Value
// Returns 0 on success. Otherwise, error code from AX
//
// Remarks
//

BOOL VXDFile::removeDir( char *dirName )
{
        BOOL                            bResult;
        CLIENT_STRUCT   saveRegs;
        ALLREGS                 Registers;

        /* Save The Client State
        ------------------------ */
        Save_Client_State(&saveRegs);

        Registers.REDX = (DWORD )dirName;
        Registers.REAX = 0x713A;                                // Remove Directory

        /* Make The DOS Call
        -------------------- */
        Exec_VxD_Int( 0x21, &Registers );

        if( Registers.RFLAGS & 1 )
        {
                bResult = FALSE;                // Failure
        }
        else
        {
                bResult = TRUE;         // Success
        }

        /* Restore The Client State
        --------------------------- */
        Restore_Client_State(&saveRegs);        // restore client registers

        return( bResult );
}


BOOL VXDFile::ABSRead (unsigned char driveAIS0, void * buffer, unsigned long sectorNumber)
{
    unsigned short error;
    return R0_ReadAbsoluteDisk(driveAIS0, 1, sectorNumber, buffer, &error);
}

BOOL VXDFile::ABSWrite(unsigned char driveAIS0, void * buffer, unsigned long sectorNumber)
{
    unsigned short error;
    return R0_WriteAbsoluteDisk(driveAIS0, 1, sectorNumber, buffer, &error);

}

END VXDFILE.CPP

0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
A short tutorial showing how to set up an email signature in Outlook on the Web (previously known as OWA). For free email signatures designs, visit https://www.mail-signatures.com/articles/signature-templates/?sts=6651 If you want to manage em…

825 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question