32/64bit sample code

// Updated 05/19/06: 32/64bit sample code

using System;

using System.Collections.Generic;

using System.Text;

namespace PlatformPointer

{

    class Test

    {

        static int Main(string[] args)

        {

            if (args.Length != 1)

            {

                System.Console.WriteLine("Usage : ReadFile <FileName>");

                return 1;

            }

            if (!System.IO.File.Exists(args[0]))

            {

                System.Console.WriteLine("File " + args[0] + " not found.");

                return 1;

            }

            Console.BackgroundColor = ConsoleColor.Blue;

            Console.ForegroundColor = ConsoleColor.White;

            Console.Title = "C# platform pointer sample";

            // The size of a pointer or handle on this platform, measured in bytes.

            // The value of this property is 4 on a 32-bit platform, and 8 on a 64-bit platform.

            if (System.IntPtr.Size == 4)

                Console.WriteLine("Running on a 32-bit platform");

            if (System.IntPtr.Size == 8)

                Console.WriteLine("Running on a 64-bit platform");

            Console.ResetColor();

            //

   byte[] buffer = new byte[128];

            FileReader fr = new FileReader();

            if (fr.Open(args[0]))

            {

                // Assume that an ASCII file is being read.

                System.Text.ASCIIEncoding Encoding = new System.Text.ASCIIEncoding();

                int bytesRead;

                do

                {

                    bytesRead = fr.Read(buffer, 0, buffer.Length);

                    string content = Encoding.GetString(buffer, 0, bytesRead);

                 System.Console.Write("{0}", content);

                }

                while (bytesRead > 0);

                fr.Close();

                Console.SetCursorPosition(0, 0);

                return 0;

            }

            else

            {

          System.Console.WriteLine("Failed to open requested file");

                return 1;

            }

        } // Main()

    } // class Test

    // Windows Readfile sample

    class FileReader

    {

        const uint GENERIC_READ = 0x80000000;

  const uint OPEN_EXISTING = 3;

        // Platform specific pointer or handle

        System.IntPtr handle;

        // External native windows dll call

        // Note the unsafe keyword for code that requires a pointer (a native code concept)

       [System.Runtime.InteropServices.DllImport("kernel32", SetLastError = true)]

        static extern unsafe System.IntPtr CreateFile

        (

            string FileName, // file name

            uint DesiredAccess, // access mode

           uint ShareMode, // share mode

            System.IntPtr SecurityAttributes, // Security Attributes

            uint CreationDisposition, // how to create

            uint FlagsAndAttributes, // file attributes

            System.IntPtr hTemplateFile // handle to template file

        );

        [System.Runtime.InteropServices.DllImport("kernel32", SetLastError = true)]

        static extern unsafe bool ReadFile

        (

            System.IntPtr hFile, // handle to file

         void* pBuffer, // data buffer

            int NumberOfBytesToRead, // number of bytes to read

            int* pNumberOfBytesRead, // number of bytes read

            System.IntPtr Overlapped // overlapped buffer

        );

    [System.Runtime.InteropServices.DllImport("kernel32", SetLastError = true)]

        static extern unsafe bool CloseHandle

        (

            System.IntPtr hObject // handle to object

        );

        public bool Open(string FileName)

        {

  // open the existing file for reading

            // The handle return value is an IntPtr, platform (32/64bit) agnostic

            handle = CreateFile // See extern CreateFile

            (

                FileName,

                GENERIC_READ,

                0,

                System.IntPtr.Zero,

                OPEN_EXISTING,

                0,

                System.IntPtr.Zero

            );

            if (handle != System.IntPtr.Zero)

            {

                return true;

      }

            else

            {

                return false;

            }

        } // class FileReader

        public unsafe int Read(byte[] buffer, int index, int count)

        {

            int n = 0;

            /*

             Note the fixed keyword.

             The byte array is a managed type that is passed to unmanaged code, as such the byte[]

             is subject to garbage collection by the CLR which means the memory location of the byte array

             could change and cause an unexpected behavior in the native code. The fixed keyword is used

             to get a pointer to memory and mark it so that the GC will not move it.

             * At the end of the fixed block the memory returns to a state that the GC can collect.

            */

            fixed (byte* p = buffer)

            {

                if (!ReadFile(handle, p + index, count, &n, System.IntPtr.Zero))

                {

                    return 0;

                }

            }

            return n;

       } // Read()

        public bool Close()

        {

            return CloseHandle(handle);

        } // Close()

    } // class FileReader

} // namespace PlatformPointer