Option Strict Off
Imports System.Collections
Imports Microsoft.Win32
Imports System.Text.RegularExpressions
Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Threading
Imports System.Security
Imports System.ComponentModel
Imports Microsoft.Win32.SafeHandles
Imports System.Runtime.ConstrainedExecution
Imports System.Security.Permissions
Imports System.Collections.Generic
Imports System.Linq


Public Class Class1
    Implements GOverlayPlugin.Interfaces.IPlugin
    Public testvar As Integer = 1

    Private objHost As GOverlayPlugin.Interfaces.IHost
    Public PluginName As String = "HWiNFO"

    Public Cache As String

    ' File offset where the view is to begin.
    Public Const ViewOffset As UInt32 = 0
    Public running As Boolean = False

    Dim hMapFile As SafeFileMappingHandle = Nothing
    Public pView As IntPtr = IntPtr.Zero

    '    Private mmf As MemoryMappedFile
    Private numSensors As UInteger
    Private numReadingElements As UInteger
    Private masterSensorNames As New List(Of String)
    Public fetchmastersensornames As Boolean = True

    Private offsetSensorSection As UInteger
    Private sizeSensorElement As UInteger
    Private offsetReadingSection As UInteger
    Private sizeReadingSection As UInteger

    Public firstrun As Boolean = True

    Public LastCache As New System.Collections.Hashtable

    Public hwinfo As System.Collections.Hashtable
    Public hwinfoLegacy As System.Collections.Hashtable

    Public Const HWiNFO_SENSORS_MAP_FILE_NAME2 As String = "Global\HWiNFO_SENS_SM2"
    Public Const HWiNFO_SENSORS_SM2_MUTEX As String = "Global\HWiNFO_SM2_MUTEX"
    Public Const HWiNFO_SENSORS_STRING_LEN2 As Integer = 128
    Public Const HWiNFO_UNIT_STRING_LEN As Integer = 16
    Public HWiNFOMemory As _HWiNFO_SENSORS_SHARED_MEM2

    Public Enum SENSOR_READING_TYPE
        SENSOR_TYPE_NONE = 0
        SENSOR_TYPE_TEMP
        SENSOR_TYPE_VOLT
        SENSOR_TYPE_FAN
        SENSOR_TYPE_CURRENT
        SENSOR_TYPE_POWER
        SENSOR_TYPE_CLOCK
        SENSOR_TYPE_USAGE
        SENSOR_TYPE_OTHER
    End Enum


    <StructLayout(LayoutKind.Sequential, Pack:=1, CharSet:=CharSet.Ansi)> _
    Public Structure _HWiNFO_SENSORS_READING_ELEMENT
        Public tReading As SENSOR_READING_TYPE
        Public dwSensorIndex As UInt32
        Public dwReadingID As UInt32
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=HWiNFO_SENSORS_STRING_LEN2)> _
        Public szLabelOrig As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=HWiNFO_SENSORS_STRING_LEN2)> _
        Public szLabelUser As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=HWiNFO_UNIT_STRING_LEN)> _
        Public szUnit As String
        Public Value As Double
        Public ValueMin As Double
        Public ValueMax As Double
        Public ValueAvg As Double
    End Structure

    <StructLayout(LayoutKind.Sequential, Pack:=1, CharSet:=CharSet.Ansi)> _
    Public Structure _HWiNFO_SENSORS_SENSOR_ELEMENT
        Public dwSensorID As UInt32
        Public dwSensorInst As UInt32
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=HWiNFO_SENSORS_STRING_LEN2)> _
        Public szSensorNameOrig As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=HWiNFO_SENSORS_STRING_LEN2)> _
        Public szSensorNameUser As String
    End Structure

    <StructLayout(LayoutKind.Sequential, Pack:=1, CharSet:=CharSet.Ansi)> _
    Public Structure _HWiNFO_SENSORS_SHARED_MEM2
        Public dwSignature As UInt32
        Public dwVersion As UInt32
        Public dwRevision As UInt32
        Public poll_time As Long
        Public dwOffsetOfSensorSection As UInt32
        Public dwSizeOfSensorElement As UInt32
        Public dwNumSensorElements As UInt32
        ' descriptors for the Readings section
        Public dwOffsetOfReadingSection As UInt32
        ' Offset of the Reading section from beginning of HWiNFO_SENSORS_SHARED_MEM2
        Public dwSizeOfReadingElement As UInt32
        ' Size of each Reading element = sizeof( HWiNFO_SENSORS_READING_ELEMENT )
        Public dwNumReadingElements As UInt32
        ' Number of Reading elements
    End Structure



    Public Sub Initialize(ByVal Host As GOverlayPlugin.Interfaces.IHost) Implements GOverlayPlugin.Interfaces.IPlugin.Initialize
        objHost = Host
        hwinfo = New Hashtable
        hwinfoLegacy = New Hashtable
    End Sub

    Public ReadOnly Property Description() As String Implements GOverlayPlugin.Interfaces.IPlugin.Description
        'Return your plugin name
        Get
            Return "This plugin allows to read the sensors from HWInfo." & vbNewLine & vbNewLine & _
                "Make sure the HWInfo is running." & vbNewLine & _
                "and make sure the -MONITORING > SENSOR STATUS- window is open" & vbNewLine & vbNewLine & _
                "HWiNFO is developed by Martin Malík" & vbNewLine & vbNewLine & _
                "This plugin is developed by TheLaGmAn" & vbNewLine & vbNewLine & vbNewLine & _
                "Thanks Martin for allowing GOverlay to connect to HWiNFO"
        End Get
    End Property

    Public ReadOnly Property Name() As String Implements GOverlayPlugin.Interfaces.IPlugin.Name
        'Return your plugin name
        Get
            Return PluginName
        End Get        
    End Property

    Public ReadOnly Property Display() As String Implements GOverlayPlugin.Interfaces.IPlugin.Display
        'Return the display this plugin belongs to
        Get
            Return "lcdsys"
        End Get
    End Property

    Function CallBack(method As String) As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.CallBacks
        'Send the request to upload all the files
        'objHost.DebugMessage("ETS2 Plugin - Callback Requested")
        'objHost.DebugMessage("ETS2 Plugin - " & method)

        Dim returnHT As Hashtable = New Hashtable


        Try
            
            Dim value As Integer = 0

            If method = "willrequestvalues" Then
                'Comes here once per run (only if sensors are used thru here)
                GrabData(0)
            ElseIf method = "willrequestdisplay" Then
                'objHost.DebugMessage("wrd")
                GrabData(0)
            Else
                'objHost.DebugMessage("grabdata: " & method & " >>> " & hwinfo(method)("value"))
                If hwinfoLegacy.ContainsKey(method) Then
                    value = hwinfoLegacy(method)("value")
                ElseIf hwinfo.ContainsKey(method) Then
                    value = hwinfo(method)("value")
                Else
                    objHost.DebugMessage("Missing sensor: " & method)
                    value = 0
                End If

            End If

            returnHT("value") = value

            Return returnHT
        Catch ex As Exception
            objHost.DebugMessage("Error grabbing action : " & method & " -> " & ex.Message & " ->  " & ex.StackTrace)
        End Try

        Return returnHT

    End Function


    Function AvailableSensors(pluginOptions As Hashtable) As System.Collections.Generic.Dictionary(Of String, String) Implements GOverlayPlugin.Interfaces.IPlugin.AvailableSensors
        'Create the list of the sensors/elements this plugin has
        'You can access your pluginOptions here as pluginOptions(your_option)        
        Dim sensors As New System.Collections.Generic.Dictionary(Of String, String)

        objHost.DebugMessage("Loading sensors...")

        Dim sensorsSort As New System.Collections.Generic.Dictionary(Of String, String)
        Dim sensorsSortOut As New System.Collections.Generic.Dictionary(Of String, String)
        Try
            'objHost.DebugMessage("called as")
            GrabData(0)

            Dim sen
            For Each sen In hwinfo
                sensors.Add(sen.key, sen.value("name") & ": " & sen.value("unit"))
            Next

            For Each sen In sensors
                'Dim p = sen.Key.Split(":")
                Dim p = sen.Key.IndexOf(":")
                Dim t = sen.Key.Substring(p)
                sensorsSort(t & sen.key) = sen.key    'important to add key to mantain data for each device
            Next

            Dim sorted As System.Linq.IOrderedEnumerable(Of System.Collections.Generic.KeyValuePair(Of String, String)) = From pair In sensorsSort Order By pair.Value
            Dim sortedDictionary = sorted.ToDictionary(Function(p) p.Key, Function(p) p.Value)

            Dim senKey
            For Each senKey In sortedDictionary.Keys
                sensorsSortOut(sortedDictionary(senKey)) = sensors(sortedDictionary(senKey))
            Next

            Return sensorsSortOut

            Return sensors
        Catch ex As Exception
            objHost.DebugMessage("Error loading sensors:" & ex.Message & ": " & ex.StackTrace)
            'MsgBox(ex.Message & ":: " & ex.StackTrace)
        End Try

        Return sensors

    End Function

    Function LCDSys2_AvailableSensors(pluginOptions As Hashtable) As System.Collections.Generic.Dictionary(Of String, String) Implements GOverlayPlugin.Interfaces.IPlugin.LCDSys2_AvailableSensors
        Return AvailableSensors(pluginOptions)
    End Function

    Function SensorHasCustomDraw(sensor_name As String) As Boolean Implements GOverlayPlugin.Interfaces.IPlugin.SensorHasCustomDraw
        'All sensors are drawn with GOverlay default drawing
        Return False
    End Function

    Function ComboBoxes() As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.ComboBoxes
        'Create custom ComboBox for your configuration to use
        Dim boxes As New Hashtable
        Dim myboxOptions As New Hashtable
        'Set each one of the Combobox options as value, Display Name
        myboxOptions.Add("C", "C")
        myboxOptions.Add("F", "F")
        boxes.Add("ComboMetric", myboxOptions)
        Return boxes
    End Function

    Public Function SetDefaultOptions(sensorId As String, elementData As Hashtable) As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.SetDefaultOptions
        'Set the default values you want to have on your sensor when its created, if the user doesnt change any option, he will have this settings
        Return elementData
    End Function

    Public Function CreateOptions(sensorId As String, elementData As Hashtable) As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.CreateOptions
        'Set the options the user will have when clicking on the element
        'The available option_types are:
        'Text: Input text
        'Combo3: Combo with options (Enabled=0, Disabled=1)
        'Sensors: Combo with available sensors
        'ColorBasic: Combo with basic colors for the regular text font
        'ColorRGB: Combo with common RGB colors = 16bitinteger
        'ComboOnOff: Combo with options (Disabled=0, Enabled=1)
        'ComboYesNo: Combo with options (Yes=Yes, No=No)
        'TextSize: Combo with options (Extra Small=4, Very Small=5, Small=10, Normal=15, Big=20, Very Big=30, Extreme=40)
        'FontStyle2: Combo with options (Regular Font=0, Square Font=1, Numbers Font 1=2
        'Orientation: Combo with options (Horizontal=0, Vertical=1)
        'Here you can also load your custom comboboxes
        Return New Hashtable
    End Function

    Public Function LCDSys2_CreateOptions(sensorId As String, elementData As Hashtable) As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.LCDSys2_CreateOptions
        'Set the options the user will have when clicking on the element
        'The available option_types are:
        'Text: Input text
        'Combo3: Combo with options (Enabled=0, Disabled=1)
        'Sensors: Combo with available sensors
        'ColorRGB: Combo with common RGB colors = 16bitinteger
        'ComboOnOff: Combo with options (Disabled=0, Enabled=1)
        'ComboYesNo: Combo with options (Yes=Yes, No=No)
        'FontStyle: Combo with options of the fonts the user has installed
        'Orientation: Combo with options (Horizontal=0, Vertical=1)
        'Alignment: Left=-1,Center=0,Right=1
        'Here you can also load your custom comboboxes

        'No options because GOverlay draws instead of us
        Return New Hashtable
    End Function

    Public Function PluginOptionsDefault() As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.PluginOptionsDefault
        'Set the default values you want to have on plugin, if the user doesnt change any option, he will have this settings
        Dim options As New Hashtable
        options("metric") = "C"
        Return options
    End Function
    Public Function PluginOptions(pluginCurrentOptions As Hashtable) As Hashtable Implements GOverlayPlugin.Interfaces.IPlugin.PluginOptions
        'Set the options the user will have when going to the plugins tab and clicking on your plugin
        'The availalbe option_type are teh same as CreateOptions function
        Dim options As New Hashtable
        'Option: option_index as integer, option_data as ArrayList
        'Option_Data: option_type as string, option_label as string, option_name as string (no spaces, no _)
        'options.Add(0, New ArrayList({"TextMulti", "Temperature in C or F? (write C or F)", "metric"}))
        'options.Add(0, New ArrayList({"ComboMetric", "Temperature in C or F?", "metric"}))
        Return options
    End Function



    Private Function GetHash(strToHash As String) As String

        Dim md5Obj As New System.Security.Cryptography.MD5CryptoServiceProvider
        Dim bytesToHash() As Byte = System.Text.Encoding.ASCII.GetBytes(strToHash)

        bytesToHash = md5Obj.ComputeHash(bytesToHash)
        Dim strResult As New Text.StringBuilder

        For Each b As Byte In bytesToHash
            strResult.Append(b.ToString("x2"))
        Next

        Return strResult.ToString

    End Function



    Public Function GrabData(metric As String) As Boolean
        Try

            Dim byteBuffer As Byte()
            Dim handle As GCHandle
            Dim ReadingElement As _HWiNFO_SENSORS_READING_ELEMENT

            If hMapFile Is Nothing OrElse hMapFile.IsInvalid Then
                hMapFile = NativeMethod.OpenFileMapping(FileMapAccess.FILE_MAP_READ, False, HWiNFO_SENSORS_MAP_FILE_NAME2)
                objHost.DebugMessage("HwInfo - Connected to hMapFile")
            End If

            If (hMapFile.IsInvalid) Then
                objHost.DebugMessage("HwInfo -hMapFile is invalid")
                Return False
                Throw New Win32Exception
            End If

            If pView = IntPtr.Zero Then
                pView = NativeMethod.MapViewOfFile(hMapFile, FileMapAccess.FILE_MAP_READ, 0, ViewOffset, 0)
                objHost.DebugMessage("HwInfo - pView Inited")
            End If

            If (pView = IntPtr.Zero) Then Throw New Win32Exception

            HWiNFOMemory = Marshal.PtrToStructure(pView, GetType(_HWiNFO_SENSORS_SHARED_MEM2))
            
            numSensors = HWiNFOMemory.dwNumSensorElements
            numReadingElements = HWiNFOMemory.dwNumReadingElements
            offsetSensorSection = HWiNFOMemory.dwOffsetOfSensorSection
            sizeSensorElement = HWiNFOMemory.dwSizeOfSensorElement
            offsetReadingSection = HWiNFOMemory.dwOffsetOfReadingSection
            sizeReadingSection = HWiNFOMemory.dwSizeOfReadingElement

            If fetchmastersensornames = True Then
                For dwSensor As UInt32 = 0 To numSensors - 1
                    Dim i As Integer = 0
                    byteBuffer = New Byte(sizeSensorElement - 1) {}

                    For i = 0 To sizeSensorElement - 1
                        byteBuffer(i) = Marshal.ReadByte(New IntPtr(pView.ToInt32() + offsetSensorSection + (dwSensor * sizeSensorElement) + i))
                    Next

                    handle = GCHandle.Alloc(byteBuffer, GCHandleType.Pinned)
                    Dim SensorElement As _HWiNFO_SENSORS_SENSOR_ELEMENT = CType(Marshal.PtrToStructure(handle.AddrOfPinnedObject(), GetType(_HWiNFO_SENSORS_SENSOR_ELEMENT)), _HWiNFO_SENSORS_SENSOR_ELEMENT)
                    masterSensorNames.Add(SensorElement.szSensorNameUser)
                    handle.Free()
                Next
            End If

            For dwReading As UInt32 = 0 To numReadingElements - 1

                Try
                    'Marshal.FreeHGlobal(pView) 'test

                    'objHost.DebugMessage("a")

                    byteBuffer = New Byte(sizeReadingSection - 1) {}

                    For i As Integer = 0 To sizeReadingSection - 1
                        byteBuffer(i) = Marshal.ReadByte(New IntPtr(pView.ToInt32() + offsetReadingSection + (dwReading * sizeReadingSection) + i))
                    Next

                    'objHost.DebugMessage("b")

                    handle = GCHandle.Alloc(byteBuffer, GCHandleType.Pinned)
                    ReadingElement = CType(Marshal.PtrToStructure(handle.AddrOfPinnedObject(), GetType(_HWiNFO_SENSORS_READING_ELEMENT)), _HWiNFO_SENSORS_READING_ELEMENT)

                    Dim ouridLegacy As String = ReadingElement.szLabelUser
                    Dim ourid As String = ReadingElement.szLabelUser

                    If masterSensorNames.Count > CInt(ReadingElement.dwSensorIndex) Then
                        'Sensor Group Name Exists
                        ourid = GetHash(masterSensorNames(CInt(ReadingElement.dwSensorIndex))) & ":" & ReadingElement.szLabelOrig & ":" & ReadingElement.szUnit
                    End If


                    'objHost.DebugMessage("HwInfo Sensor - " & ourid & " -> " & ReadingElement.szLabelOrig & " / " & ReadingElement.dwSensorIndex)

                    'Create sensor data (only once, then we just update its value)
                    If Not hwinfo.ContainsKey("HW." & ourid) Or fetchmastersensornames = True Then
                        hwinfo("HW." & ourid) = New System.Collections.Hashtable
                        Dim name As String = "Unknown: " & ReadingElement.szLabelOrig

                        If masterSensorNames.Count > CInt(ReadingElement.dwSensorIndex) Then
                            'Sensor Group Name Exists
                            name = masterSensorNames(CInt(ReadingElement.dwSensorIndex)) & ": " & ReadingElement.szLabelOrig
                        Else
                            objHost.DebugMessage("HwInfo Error - Missing group name for sensor " & ReadingElement.dwSensorIndex)
                        End If

                        hwinfo("HW." & ourid)("name") = name
                        hwinfo("HW." & ourid)("unit") = ReadingElement.szUnit
                        hwinfo("HW." & ourid)("value") = 0
                    End If

                    If Not hwinfoLegacy.ContainsKey("HW." & ouridLegacy) Or fetchmastersensornames = True Then
                        hwinfoLegacy("HW." & ouridLegacy) = New System.Collections.Hashtable
                        Dim name As String = "Unknown: " & ReadingElement.szLabelOrig

                        If masterSensorNames.Count > CInt(ReadingElement.dwSensorIndex) Then
                            'Sensor Group Name Exists
                            name = masterSensorNames(CInt(ReadingElement.dwSensorIndex)) & ": " & ReadingElement.szLabelOrig
                        Else
                            objHost.DebugMessage("HwInfo Error - Missing group name for sensor " & ReadingElement.dwSensorIndex)
                        End If

                        hwinfoLegacy("HW." & ouridLegacy)("name") = name
                        hwinfoLegacy("HW." & ouridLegacy)("unit") = ReadingElement.szUnit
                        hwinfoLegacy("HW." & ouridLegacy)("value") = 0
                    End If

                    'objHost.DebugMessage("d")

                    'objHost.DebugMessage(hwinfo.Count)

                    hwinfo("HW." & ourid)("value") = ReadingElement.Value
                    hwinfoLegacy("HW." & ouridLegacy)("value") = ReadingElement.Value
                    'objHost.DebugMessage("f")
                    handle.Free()

                    'objHost.DebugMessage("g")

                Catch ex As Exception
                    objHost.DebugMessage("HwInfo Exception - " & ex.Message & ": " & ex.StackTrace)
                    If handle.IsAllocated Then
                        handle.Free()
                    End If
                End Try
            Next

            fetchmastersensornames = False

        Catch ex As Exception
            objHost.DebugMessage("HwInfo Exception2 - " & ex.Message & ": " & ex.StackTrace)
            Return False
        End Try


        Return True

    End Function
    Public Function DisplayOnLCD(sensorId As String, elementData As Hashtable, pluginOptions As Hashtable, cacheRuns As Integer) As ArrayList Implements GOverlayPlugin.Interfaces.IPlugin.DisplayOnLCD
        Return New ArrayList
    End Function

    Public Function LCDSys2_DisplayOnLCD(sensorId As String, elementData As Hashtable, pluginOptions As Hashtable, cacheRuns As Integer) As ArrayList Implements GOverlayPlugin.Interfaces.IPlugin.LCDSys2_DisplayOnLCD
        'GOverlay draws instead of us
        Return New ArrayList
    End Function


#Region "Native API Signatures and Types"

    ''' <summary>
    ''' Access rights for file mapping objects
    ''' http://msdn.microsoft.com/en-us/library/aa366559.aspx
    ''' </summary>
    ''' <remarks></remarks>
    Public Enum FileMapAccess
        FILE_MAP_COPY = 1
        FILE_MAP_WRITE = 2
        FILE_MAP_READ = 4
        FILE_MAP_ALL_ACCESS = &HF001F
    End Enum


    ''' <summary>
    ''' Represents a wrapper class for a file mapping handle. 
    ''' </summary>
    ''' <remarks></remarks>
    <SuppressUnmanagedCodeSecurity(), _
    HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort:=True)> _
    Friend NotInheritable Class SafeFileMappingHandle
        Inherits SafeHandleZeroOrMinusOneIsInvalid

        <SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode:=True)> _
        Private Sub New()
            MyBase.New(True)
        End Sub

        <SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode:=True)> _
        Public Sub New(ByVal handle As IntPtr, ByVal ownsHandle As Boolean)
            MyBase.New(ownsHandle)
            MyBase.SetHandle(handle)
        End Sub

        <ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), _
        DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
        Private Shared Function CloseHandle(ByVal handle As IntPtr) _
        As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function

        Protected Overrides Function ReleaseHandle() As Boolean
            Return SafeFileMappingHandle.CloseHandle(MyBase.handle)
        End Function

    End Class


    Friend ReadOnly INVALID_HANDLE_VALUE As New IntPtr(-1)


    ''' <summary>
    ''' The class exposes Windows APIs used in this code sample.
    ''' </summary>
    ''' <remarks></remarks>
    <SuppressUnmanagedCodeSecurity()> _
    Friend Class NativeMethod

        ''' <summary>
        ''' Opens a named file mapping object.
        ''' </summary>
        ''' <param name="dwDesiredAccess">
        ''' The access to the file mapping object. This access is checked against 
        ''' any security descriptor on the target file mapping object.
        ''' </param>
        ''' <param name="bInheritHandle">
        ''' If this parameter is TRUE, a process created by the CreateProcess 
        ''' function can inherit the handle; otherwise, the handle cannot be 
        ''' inherited.
        ''' </param>
        ''' <param name="lpName">
        ''' The name of the file mapping object to be opened.
        ''' </param>
        ''' <returns>
        ''' If the function succeeds, the return value is an open handle to the 
        ''' specified file mapping object.
        ''' </returns>
        <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
        Public Shared Function OpenFileMapping( _
            ByVal dwDesiredAccess As FileMapAccess, _
            ByVal bInheritHandle As Boolean, _
            ByVal lpName As String) _
            As SafeFileMappingHandle
        End Function


        ''' <summary>
        ''' Maps a view of a file mapping into the address space of a calling 
        ''' process.
        ''' </summary>
        ''' <param name="hFileMappingObject">
        ''' A handle to a file mapping object. The CreateFileMapping and 
        ''' OpenFileMapping functions return this handle.
        ''' </param>
        ''' <param name="dwDesiredAccess">
        ''' The type of access to a file mapping object, which determines the 
        ''' protection of the pages.
        ''' </param>
        ''' <param name="dwFileOffsetHigh">
        ''' A high-order DWORD of the file offset where the view begins.
        ''' </param>
        ''' <param name="dwFileOffsetLow">
        ''' A low-order DWORD of the file offset where the view is to begin.
        ''' </param>
        ''' <param name="dwNumberOfBytesToMap">
        ''' The number of bytes of a file mapping to map to the view. All bytes 
        ''' must be within the maximum size specified by CreateFileMapping.
        ''' </param>
        ''' <returns>
        ''' If the function succeeds, the return value is the starting address of
        ''' the mapped view.
        ''' </returns>
        <DllImport("Kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
        Public Shared Function MapViewOfFile( _
            ByVal hFileMappingObject As SafeFileMappingHandle, _
            ByVal dwDesiredAccess As FileMapAccess, _
            ByVal dwFileOffsetHigh As UInt32, _
            ByVal dwFileOffsetLow As UInt32, _
            ByVal dwNumberOfBytesToMap As UInt32) _
            As IntPtr
        End Function


        ''' <summary>
        ''' Unmaps a mapped view of a file from the calling process's address 
        ''' space.
        ''' </summary>
        ''' <param name="lpBaseAddress">
        ''' A pointer to the base address of the mapped view of a file that is to 
        ''' be unmapped.
        ''' </param>
        ''' <returns></returns>
        <DllImport("Kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
        Public Shared Function UnmapViewOfFile( _
            ByVal lpBaseAddress As IntPtr) _
            As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function

    End Class

#End Region
End Class