T
The Grim Reaper
Dear Gurus...
(Sorry to cross post... but...) I have a dire problem - been working on this
for days now. It's the undocumented API's for NTDLL.dll - namely
NtOpenSection, NtMapViewOfSection, NtUnmapViewOfSection, CloseHandle and
CopyMemory. Code listing 1 shows the existing VB6 code, which works
perfectly. However, on upgrading the code to .NET, I am getting no value
returned to vPhysicalMemory - indicating that the NtOpenSection call isn't
working. In the .NET code (listing number 2) the vReturn value is an error
code - translated through Marshal.GetLastWin32Error give 126 - anyone know
where I can find that specific error codes description?!!?
I've also found a site which suggests that NtOpenSection can be replaced by
an equivalent in kernel32.dll called OpenFileMapping (or OpenFileMappingEx)
but I've found no useful description of what these functions actually DO.
The original author of the code is an old friend who seems to have vanished
off the face of the planet, so any light anyone can shed on these functions
and how the code actually works will be very gratefully received
-----------------------------------------------
Code listing 1 - working VB6 code
(vPort As AILocalPort is just a class that holds details of the
serial/parallel/other I/O ports in use by the software)
Option Explicit
Private Const mcCaseInsensitive As Long = &H40
Private Const mcSectionMapRead = &H4
Private Const mcPageReadOnly = 2
Private Const mcViewShare = 1
Private Type mtUnicodeString
Length As Integer
MaxLength As Integer
Buffer As String
End Type
Private Type mtObjectAttributes
Length As Long
RootDirectory As Long
ObjectName As Long
Attributes As Long
SecurityDescriptor As Long
SecurityQOS As Long
End Type
Private Type mtPhysicalAddress
LowPart As Long
HighPart As Long
End Type
Private Declare Function OpenSection Lib "ntdll.dll" Alias "NtOpenSection"
(ByRef pSection As Long, ByVal pAccess As Long, ByRef pObjAttribs As
mtObjectAttributes) As Long
Private Declare Function MapSectionView Lib "ntdll.dll" Alias
"NtMapViewOfSection" (ByVal pSection As Long, ByVal pProcess As Long,
pBaseAddress As Long, ByVal pZeroBits As Long, ByVal pCommitSize As Long,
pSectionOffset As mtPhysicalAddress, pViewSize As Long, ByVal
pInheritDisposition As Long, ByVal pAllocationType As Long, ByVal pProtect
As Long) As Long
Private Declare Function UnmapSectionView Lib "ntdll.dll" Alias
"NtUnmapViewOfSection" (ByVal pProcess As Long, ByVal pBaseAddress As Long)
As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal pObject As Long)
As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
(pDestination As Any, pSource As Any, ByVal pLength As Long)
Private Sub GetSerialParallel()
Dim vMemory(0 To &HF) As Byte
Dim vIX As Integer
Dim vPhysicalMemory As Long, vVirtualAddress As Long, vMemLength As Long
Dim vBaseAddress As String, vName As String
Dim vSectionAttributes As mtObjectAttributes
Dim vDeviceName As mtUnicodeString
Dim vViewBase As mtPhysicalAddress
Dim vPort As New AILocalPort
With vDeviceName
.Buffer = "\device\physicalmemory" & Chr(0)
.MaxLength = Len(.Buffer) * 2
.Length = .MaxLength - 2
End With
With vSectionAttributes
.Length = Len(vSectionAttributes)
.ObjectName = VarPtr(vDeviceName)
.Attributes = mcCaseInsensitive
.SecurityDescriptor = 0
.RootDirectory = 0
.SecurityQOS = 0
End With
Dim vReturn As Long
vReturn = OpenSection(vPhysicalMemory, mcSectionMapRead,
vSectionAttributes)
vVirtualAddress = 0
vViewBase.HighPart = 0
vViewBase.LowPart = &H400
vMemLength = &H10
vReturn = MapSectionView(vPhysicalMemory, -1&, vVirtualAddress, 0&,
vMemLength, vViewBase, vMemLength, mcViewShare, 0&, mcPageReadOnly)
CopyMemory vMemory(0), ByVal vVirtualAddress - vViewBase.LowPart + &H400,
&H10
Rem *** Serial ports ***
For vIX = 0 To &H7 Step 2
vBaseAddress = "&H" & Hex(vMemory(vIX + 1) * 256& + vMemory(vIX))
If Val(vBaseAddress) > 0 Then
Set vPort = New AILocalPort
vName = "COM" & vIX / 2 + 1
vPort.Setup SerialCOM, vIX / 2 + 1, vName, vBaseAddress
mvPorts.Add vPort, vName
End If
Next
Rem *** Parallel ports ***
For vIX = 8 To &HD Step 2
vBaseAddress = "&H" & Hex(vMemory(vIX + 1) * 256& + vMemory(vIX))
If Val(vBaseAddress) > 0 Then
Set vPort = New AILocalPort
vName = "LPT" & vIX / 2 - 3
vPort.Setup ParallelLPT, vIX / 2 - 3, vName, vBaseAddress
mvPorts.Add vPort, vName
End If
Next
Rem *** Clean up ***
UnmapSectionView -1&, vVirtualAddress
CloseHandle vPhysicalMemory
Set vPort = Nothing
End Sub
-----------------------------------------------
Code listing 2 - non-working VB.NET code
(Yes, I know it's a mess - I've been experimenting with it for so long!!!)
Option Strict On
Option Explicit On
Imports System.Runtime.InteropServices
Friend Class AILocalPorts
Inherits CollectionBase
Private Structure mtUnicodeString
Public Length As Short
Public MaxLength As Short
Public Buffer As String
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure mtObjectAttributes
Public Length As Integer
Public RootDirectory As Integer
Public ObjectName As IntPtr
Public Attributes As Integer
Public SecurityDescriptor As Integer
Public SecurityQOS As Integer
End Structure
<StructLayout(LayoutKind.Sequential)> Private Structure mtPhysicalAddress
Public Sub New(ByVal pLowPart As Integer, ByVal pHighPart As Integer)
LowPart = pLowPart
HighPart = pHighPart
End Sub
Public LowPart As Integer
Public HighPart As Integer
End Structure
' <DllImport("ntdll.dll", EntryPoint:="NtOpenSection",
CharSet:=CharSet.Ansi, ExactSpelling:=True)> _
' Private Function OpenSection(ByRef pSection As Integer, ByVal pAccess As
Integer, ByRef pObjAttribs As mtObjectAttributes) As Integer
' End Function
'<DllImport("ntdll.dll", EntryPoint:="NtOpenSection", SetLastError:=True,
CharSet:=CharSet.Ansi, _
'ExactSpelling:=True, CallingConvention:=CallingConvention.Winapi)> _
'Public Shared Function OpenSection(ByRef pSection As Integer, _
' ByVal pAccess As Integer, ByRef pAttributes As mtObjectAttributes) As
Integer
'End Function
'<DllImport("kernel32.dll")> Public Shared Function OpenFileMapping(ByVal
dwDesiredAccess As UInt32, _
'ByVal bInheritHandle As Boolean, ByVal lpName As String) As IntPtr
'End Function
Private Declare Ansi Function OpenSection Lib "ntdll.dll" Alias
"NtOpenSection" (ByRef pSection As Integer, ByVal pAccess As Integer,
ByRef
pObjAttribs As mtObjectAttributes) As Integer
'<DllImport("kernel32.dll")> Public Shared Function MapViewOfFile(ByVal
hFileMappingObject As IntPtr, _
'ByVal dwDesiredAccess As UInt32, ByVal dwFileOffsetHigh As UInt32, ByVal
dwFileOffsetLow As UInt32, _
'ByVal dwNumberOfBytesToMap As UIntPtr) As IntPtr
'End Function
Private Declare Ansi Function MapSectionView Lib "ntdll.dll" Alias
"NtMapViewOfSection" (ByRef pSection As Integer, ByVal pProcess As
Integer,
ByRef pBaseAddress As Integer, ByVal pZeroBits As Integer, ByVal
pCommitSize As Integer, ByRef pSectionOffset As mtPhysicalAddress, ByRef
pViewSize As Integer, ByVal pInheritDisposition As Integer, ByVal
pAllocationType As Integer, ByVal pProtect As Integer) As Integer
Private Declare Ansi Function UnmapSectionView Lib "ntdll.dll" Alias
"NtUnmapViewOfSection" (ByVal pProcess As Integer, ByVal pBaseAddress As
Integer) As Integer
Private Declare Ansi Function CloseHandle Lib "kernel32" (ByVal pObject As
Integer) As Integer
Private Declare Ansi Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
(ByRef pDestination As Byte, ByRef pSource As Integer, ByVal pLength As
Integer)
Public Sub New()
MyBase.New()
Try
List.Clear()
GetSerialParallel()
Catch vException As Exception
If ASEC.QueryDebug(vException, "") Then Stop
End Try
End Sub
Private Sub GetSerialParallel()
Const cSectionMapRead As Integer = 4
Const cPageReadOnly As Integer = 2
Const cViewShare As Integer = 1
Dim vDeviceName As mtUnicodeString
With vDeviceName
.Buffer = "\device\physicalmemory" & Convert.ToChar(0)
.MaxLength = CType(.Buffer.Length * 2, Short)
.Length = CType(.MaxLength - 2, Short)
End With
Dim vPointer As IntPtr
vPointer = Marshal.AllocHGlobal(Marshal.SizeOf(vDeviceName)) ' Allocate
some unmanaged memory
Marshal.StructureToPtr(vDeviceName, vPointer, True) ' Copy the device
name structure to the pointer
Dim vSectionAttributes As mtObjectAttributes
With vSectionAttributes
.Length = Marshal.SizeOf(vSectionAttributes)
.ObjectName = vPointer
.Attributes = 64 ' Case insensitive
.SecurityDescriptor = 0
.RootDirectory = 0
.SecurityQOS = 0
End With
Dim vReturn As Integer
Dim vPhysicalMemory As Integer ' vPhysicalMemory gets set to > 0 (eg 1144)
vReturn = OpenSection(vPhysicalMemory, cSectionMapRead,
vSectionAttributes) ' equiv = openfilemapping ?
If vReturn <> 0 Then MessageBox.Show(Marshal.GetLastWin32Error.ToString)
Dim vVirtualAddress As Integer = 0
Dim vViewBase As New mtPhysicalAddress(1024, 0)
Dim vMemLength As Integer = 16
' equiv = mapviewoffile ?
vReturn = MapSectionView(vPhysicalMemory, -1, vVirtualAddress, 0,
vMemLength, vViewBase, vMemLength, cViewShare, 0, cPageReadOnly)
If vReturn <> 0 Then MessageBox.Show(Marshal.GetLastWin32Error.ToString)
Dim vMemory(15) As Byte
CopyMemory(vMemory(0), vVirtualAddress - vViewBase.LowPart + 1024, 16)
' Variables for port interation
Dim vIX As Integer
Dim vBaseAddress As String, vName As String
Dim vPort As New AILocalPort
' Serial ports
For vIX = 0 To 7 Step 2
vBaseAddress = "&H" & (vMemory(vIX + 1) * 256 +
vMemory(vIX)).ToString("X")
If CType(vBaseAddress, Integer) > 0 Then
vPort = New AILocalPort
vName = "COM" & vIX / 2 + 1
vPort.Setup(ASEC.PortTypes.SerCOM, CType(vIX / 2, Integer) + 1, vName,
vBaseAddress)
List.Add(vPort)
End If
Next
' Parallel ports
For vIX = 8 To 13 Step 2
vBaseAddress = "&H" & (vMemory(vIX + 1) * 256 +
vMemory(vIX)).ToString("X")
If CType(vBaseAddress, Integer) > 0 Then
vPort = New AILocalPort
vName = "LPT" & vIX / 2 - 3
vPort.Setup(ASEC.PortTypes.ParLPT, CType(vIX / 2, Integer) - 3, vName,
vBaseAddress)
List.Add(vPort)
End If
Next
' Clean up
UnmapSectionView(-1, vVirtualAddress)
CloseHandle(vPhysicalMemory)
Marshal.FreeHGlobal(vPointer)
End Sub
When I finally get these calls working, I will be updating the lacking code
on pinvoke.net!!
Thanks to all who read this far
_____________________
The Grim Reaper
(Sorry to cross post... but...) I have a dire problem - been working on this
for days now. It's the undocumented API's for NTDLL.dll - namely
NtOpenSection, NtMapViewOfSection, NtUnmapViewOfSection, CloseHandle and
CopyMemory. Code listing 1 shows the existing VB6 code, which works
perfectly. However, on upgrading the code to .NET, I am getting no value
returned to vPhysicalMemory - indicating that the NtOpenSection call isn't
working. In the .NET code (listing number 2) the vReturn value is an error
code - translated through Marshal.GetLastWin32Error give 126 - anyone know
where I can find that specific error codes description?!!?
I've also found a site which suggests that NtOpenSection can be replaced by
an equivalent in kernel32.dll called OpenFileMapping (or OpenFileMappingEx)
but I've found no useful description of what these functions actually DO.
The original author of the code is an old friend who seems to have vanished
off the face of the planet, so any light anyone can shed on these functions
and how the code actually works will be very gratefully received

-----------------------------------------------
Code listing 1 - working VB6 code
(vPort As AILocalPort is just a class that holds details of the
serial/parallel/other I/O ports in use by the software)
Option Explicit
Private Const mcCaseInsensitive As Long = &H40
Private Const mcSectionMapRead = &H4
Private Const mcPageReadOnly = 2
Private Const mcViewShare = 1
Private Type mtUnicodeString
Length As Integer
MaxLength As Integer
Buffer As String
End Type
Private Type mtObjectAttributes
Length As Long
RootDirectory As Long
ObjectName As Long
Attributes As Long
SecurityDescriptor As Long
SecurityQOS As Long
End Type
Private Type mtPhysicalAddress
LowPart As Long
HighPart As Long
End Type
Private Declare Function OpenSection Lib "ntdll.dll" Alias "NtOpenSection"
(ByRef pSection As Long, ByVal pAccess As Long, ByRef pObjAttribs As
mtObjectAttributes) As Long
Private Declare Function MapSectionView Lib "ntdll.dll" Alias
"NtMapViewOfSection" (ByVal pSection As Long, ByVal pProcess As Long,
pBaseAddress As Long, ByVal pZeroBits As Long, ByVal pCommitSize As Long,
pSectionOffset As mtPhysicalAddress, pViewSize As Long, ByVal
pInheritDisposition As Long, ByVal pAllocationType As Long, ByVal pProtect
As Long) As Long
Private Declare Function UnmapSectionView Lib "ntdll.dll" Alias
"NtUnmapViewOfSection" (ByVal pProcess As Long, ByVal pBaseAddress As Long)
As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal pObject As Long)
As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
(pDestination As Any, pSource As Any, ByVal pLength As Long)
Private Sub GetSerialParallel()
Dim vMemory(0 To &HF) As Byte
Dim vIX As Integer
Dim vPhysicalMemory As Long, vVirtualAddress As Long, vMemLength As Long
Dim vBaseAddress As String, vName As String
Dim vSectionAttributes As mtObjectAttributes
Dim vDeviceName As mtUnicodeString
Dim vViewBase As mtPhysicalAddress
Dim vPort As New AILocalPort
With vDeviceName
.Buffer = "\device\physicalmemory" & Chr(0)
.MaxLength = Len(.Buffer) * 2
.Length = .MaxLength - 2
End With
With vSectionAttributes
.Length = Len(vSectionAttributes)
.ObjectName = VarPtr(vDeviceName)
.Attributes = mcCaseInsensitive
.SecurityDescriptor = 0
.RootDirectory = 0
.SecurityQOS = 0
End With
Dim vReturn As Long
vReturn = OpenSection(vPhysicalMemory, mcSectionMapRead,
vSectionAttributes)
vVirtualAddress = 0
vViewBase.HighPart = 0
vViewBase.LowPart = &H400
vMemLength = &H10
vReturn = MapSectionView(vPhysicalMemory, -1&, vVirtualAddress, 0&,
vMemLength, vViewBase, vMemLength, mcViewShare, 0&, mcPageReadOnly)
CopyMemory vMemory(0), ByVal vVirtualAddress - vViewBase.LowPart + &H400,
&H10
Rem *** Serial ports ***
For vIX = 0 To &H7 Step 2
vBaseAddress = "&H" & Hex(vMemory(vIX + 1) * 256& + vMemory(vIX))
If Val(vBaseAddress) > 0 Then
Set vPort = New AILocalPort
vName = "COM" & vIX / 2 + 1
vPort.Setup SerialCOM, vIX / 2 + 1, vName, vBaseAddress
mvPorts.Add vPort, vName
End If
Next
Rem *** Parallel ports ***
For vIX = 8 To &HD Step 2
vBaseAddress = "&H" & Hex(vMemory(vIX + 1) * 256& + vMemory(vIX))
If Val(vBaseAddress) > 0 Then
Set vPort = New AILocalPort
vName = "LPT" & vIX / 2 - 3
vPort.Setup ParallelLPT, vIX / 2 - 3, vName, vBaseAddress
mvPorts.Add vPort, vName
End If
Next
Rem *** Clean up ***
UnmapSectionView -1&, vVirtualAddress
CloseHandle vPhysicalMemory
Set vPort = Nothing
End Sub
-----------------------------------------------
Code listing 2 - non-working VB.NET code
(Yes, I know it's a mess - I've been experimenting with it for so long!!!)
Option Strict On
Option Explicit On
Imports System.Runtime.InteropServices
Friend Class AILocalPorts
Inherits CollectionBase
Private Structure mtUnicodeString
Public Length As Short
Public MaxLength As Short
Public Buffer As String
End Structure
<StructLayout(LayoutKind.Sequential)> Public Structure mtObjectAttributes
Public Length As Integer
Public RootDirectory As Integer
Public ObjectName As IntPtr
Public Attributes As Integer
Public SecurityDescriptor As Integer
Public SecurityQOS As Integer
End Structure
<StructLayout(LayoutKind.Sequential)> Private Structure mtPhysicalAddress
Public Sub New(ByVal pLowPart As Integer, ByVal pHighPart As Integer)
LowPart = pLowPart
HighPart = pHighPart
End Sub
Public LowPart As Integer
Public HighPart As Integer
End Structure
' <DllImport("ntdll.dll", EntryPoint:="NtOpenSection",
CharSet:=CharSet.Ansi, ExactSpelling:=True)> _
' Private Function OpenSection(ByRef pSection As Integer, ByVal pAccess As
Integer, ByRef pObjAttribs As mtObjectAttributes) As Integer
' End Function
'<DllImport("ntdll.dll", EntryPoint:="NtOpenSection", SetLastError:=True,
CharSet:=CharSet.Ansi, _
'ExactSpelling:=True, CallingConvention:=CallingConvention.Winapi)> _
'Public Shared Function OpenSection(ByRef pSection As Integer, _
' ByVal pAccess As Integer, ByRef pAttributes As mtObjectAttributes) As
Integer
'End Function
'<DllImport("kernel32.dll")> Public Shared Function OpenFileMapping(ByVal
dwDesiredAccess As UInt32, _
'ByVal bInheritHandle As Boolean, ByVal lpName As String) As IntPtr
'End Function
Private Declare Ansi Function OpenSection Lib "ntdll.dll" Alias
"NtOpenSection" (ByRef pSection As Integer, ByVal pAccess As Integer,
ByRef
pObjAttribs As mtObjectAttributes) As Integer
'<DllImport("kernel32.dll")> Public Shared Function MapViewOfFile(ByVal
hFileMappingObject As IntPtr, _
'ByVal dwDesiredAccess As UInt32, ByVal dwFileOffsetHigh As UInt32, ByVal
dwFileOffsetLow As UInt32, _
'ByVal dwNumberOfBytesToMap As UIntPtr) As IntPtr
'End Function
Private Declare Ansi Function MapSectionView Lib "ntdll.dll" Alias
"NtMapViewOfSection" (ByRef pSection As Integer, ByVal pProcess As
Integer,
ByRef pBaseAddress As Integer, ByVal pZeroBits As Integer, ByVal
pCommitSize As Integer, ByRef pSectionOffset As mtPhysicalAddress, ByRef
pViewSize As Integer, ByVal pInheritDisposition As Integer, ByVal
pAllocationType As Integer, ByVal pProtect As Integer) As Integer
Private Declare Ansi Function UnmapSectionView Lib "ntdll.dll" Alias
"NtUnmapViewOfSection" (ByVal pProcess As Integer, ByVal pBaseAddress As
Integer) As Integer
Private Declare Ansi Function CloseHandle Lib "kernel32" (ByVal pObject As
Integer) As Integer
Private Declare Ansi Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
(ByRef pDestination As Byte, ByRef pSource As Integer, ByVal pLength As
Integer)
Public Sub New()
MyBase.New()
Try
List.Clear()
GetSerialParallel()
Catch vException As Exception
If ASEC.QueryDebug(vException, "") Then Stop
End Try
End Sub
Private Sub GetSerialParallel()
Const cSectionMapRead As Integer = 4
Const cPageReadOnly As Integer = 2
Const cViewShare As Integer = 1
Dim vDeviceName As mtUnicodeString
With vDeviceName
.Buffer = "\device\physicalmemory" & Convert.ToChar(0)
.MaxLength = CType(.Buffer.Length * 2, Short)
.Length = CType(.MaxLength - 2, Short)
End With
Dim vPointer As IntPtr
vPointer = Marshal.AllocHGlobal(Marshal.SizeOf(vDeviceName)) ' Allocate
some unmanaged memory
Marshal.StructureToPtr(vDeviceName, vPointer, True) ' Copy the device
name structure to the pointer
Dim vSectionAttributes As mtObjectAttributes
With vSectionAttributes
.Length = Marshal.SizeOf(vSectionAttributes)
.ObjectName = vPointer
.Attributes = 64 ' Case insensitive
.SecurityDescriptor = 0
.RootDirectory = 0
.SecurityQOS = 0
End With
Dim vReturn As Integer
Dim vPhysicalMemory As Integer ' vPhysicalMemory gets set to > 0 (eg 1144)
vReturn = OpenSection(vPhysicalMemory, cSectionMapRead,
vSectionAttributes) ' equiv = openfilemapping ?
If vReturn <> 0 Then MessageBox.Show(Marshal.GetLastWin32Error.ToString)
Dim vVirtualAddress As Integer = 0
Dim vViewBase As New mtPhysicalAddress(1024, 0)
Dim vMemLength As Integer = 16
' equiv = mapviewoffile ?
vReturn = MapSectionView(vPhysicalMemory, -1, vVirtualAddress, 0,
vMemLength, vViewBase, vMemLength, cViewShare, 0, cPageReadOnly)
If vReturn <> 0 Then MessageBox.Show(Marshal.GetLastWin32Error.ToString)
Dim vMemory(15) As Byte
CopyMemory(vMemory(0), vVirtualAddress - vViewBase.LowPart + 1024, 16)
' Variables for port interation
Dim vIX As Integer
Dim vBaseAddress As String, vName As String
Dim vPort As New AILocalPort
' Serial ports
For vIX = 0 To 7 Step 2
vBaseAddress = "&H" & (vMemory(vIX + 1) * 256 +
vMemory(vIX)).ToString("X")
If CType(vBaseAddress, Integer) > 0 Then
vPort = New AILocalPort
vName = "COM" & vIX / 2 + 1
vPort.Setup(ASEC.PortTypes.SerCOM, CType(vIX / 2, Integer) + 1, vName,
vBaseAddress)
List.Add(vPort)
End If
Next
' Parallel ports
For vIX = 8 To 13 Step 2
vBaseAddress = "&H" & (vMemory(vIX + 1) * 256 +
vMemory(vIX)).ToString("X")
If CType(vBaseAddress, Integer) > 0 Then
vPort = New AILocalPort
vName = "LPT" & vIX / 2 - 3
vPort.Setup(ASEC.PortTypes.ParLPT, CType(vIX / 2, Integer) - 3, vName,
vBaseAddress)
List.Add(vPort)
End If
Next
' Clean up
UnmapSectionView(-1, vVirtualAddress)
CloseHandle(vPhysicalMemory)
Marshal.FreeHGlobal(vPointer)
End Sub
When I finally get these calls working, I will be updating the lacking code
on pinvoke.net!!
Thanks to all who read this far

_____________________
The Grim Reaper