2

I am reading directly from a disk using C# and pinvoking the kernel32 ReadFile method.i want just read a particular sector for save time but ReadFile read from first to N sector. How can read only own sector with my choice?

    [StructLayout(LayoutKind.Sequential)]
    public struct OVERLAPPED
    {
        public uint Internal;
        public uint InternalHigh;
        public uint Offset;
        public uint OffsetHigh;
        public int hEvent;
    }

    [DllImport("kernel32", SetLastError = true)]
    static extern int CreateFile(string filename, uint desiredAccess, uint shareMode, IntPtr attributes, uint creationDisposition, uint flagsAndAttributes, IntPtr templateFile);

    [DllImport("kernel32", SetLastError = true)]
    public static extern Boolean CloseHandle(int handle);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern Boolean ReadFile(IntPtr hFile, Byte[] buffer, UInt32 BytesToRead, ref UInt32 BytedRead, OVERLAPPED OverLapped);
    static int EIGHT_K = 8192;
    static int FIVE_TWELVE_BYTES = 512;
    static uint GENERIC_READ = 0x80000000;
    static uint OPEN_EXISTING = 3;
    static uint FILE_SHARE_READ = 1;
    static uint FILE_SHARE_WRITE = 2;

    [STAThread]
    private void button1_Click(object sender, EventArgs e)
    {
        int fileHandle = 0;
        bool returnVal = true;

        try
        {
            // Open the device specified (Using the boot partition)
            string deviceName = @"\\.\f:";
            fileHandle = CreateFile(deviceName, GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE, (IntPtr)0, OPEN_EXISTING, 0,(IntPtr)0);
            if (fileHandle != -1)
            {
                Byte[] sector = new Byte[EIGHT_K];
                UInt32 bytesRead = (uint)EIGHT_K;
                OVERLAPPED ol = new OVERLAPPED();

                // Can't get a FileStream ctor to work so I am using Win32 API ReadFile
                bool worked = ReadFile((IntPtr)fileHandle, sector, (uint)EIGHT_K, ref bytesRead, ol);
                return;

            }
        }

        catch (Exception ex)
        {
            return;
        }
        finally
        {
            CloseHandle(fileHandle);
        }
        return;
    }

I want to mark the DVD till required Original DVD to run the program.

tshepang
  • 12,111
  • 21
  • 91
  • 136

1 Answers1

2

Your OVERLAPPED struct is declared poorly and is incorrect in a 64 bit process. But in any case you don't need it. You are not performing overlapped I/O. Which is just as well because the declaration of ReadFile is incorrect. That function wants a pointer to an OVERLAPPED struct. You pass it by value.

In any case, you just don't need to consider overlapped I/O. So fix this issue by deleting the OVERLAPPED struct declaration from your code. And declare ReadFile like this:

[DllImport("kernel32.dll", SetLastError = true)]
public static extern Boolean ReadFile(IntPtr hFile, Byte[] buffer, 
    UInt32 BytesToRead, out UInt32 BytedRead, IntPtr Overlapped);

Pass IntPtr.Zero as the Overlapped parameter. And do make sure that you check the return value of ReadFile for an error.

The next step is to seek to a location in the file. Use SetFilePointerEx for that.

DllImport("kernel32.dll")]
static extern bool SetFilePointerEx(IntPtr hFile, long liDistanceToMove,
   out long lpNewFilePointer, uint dwMoveMethod);

Consult the documentation for SetFilePointerEx to work out how to call this function.

Since you are using direct disk access, you will of course need to align the reads to sector boundaries.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490