HELP! API upgrade problems

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 :D

-----------------------------------------------
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
 
C

Cor Ligthert

Hi Grim,

Did you know there is a special newsgroup for this kind of API upgrade
questions.

microsoft.public.dotnet.languages.vb.upgrade

(I write this because Herfried says that we answer to much questions here
which can as well be done in the special newsgroups).

An answer that you would get here first will be that seeing your code I
would first change all the longs for integer, mostly that is the biggest
problem.

(A long in VB6 is an integer in VB.net)

I hope this helps?

:)

Cor
 
H

Herfried K. Wagner [MVP]

* "Cor Ligthert said:
Did you know there is a special newsgroup for this kind of API upgrade
questions.

microsoft.public.dotnet.languages.vb.upgrade

.... or mpdf.interop.
(I write this because Herfried says that we answer to much questions here
which can as well be done in the special newsgroups).

Mhm...
 
H

Herfried K. Wagner [MVP]

* "Cor Ligthert said:
Now I do exactly what you always say, what is wrong?

:)

ps I have answered the AdoNet question in that newsgroup

I don't say anything against posting replies/answers to OT questions
there. If I know an answer, I post the answer + hint for the more
appropriate group, if I don't know an answer, I post a hint for the more
appropriate group too ;-).
 
C

Cor Ligthert

Now I do exactly what you always say, what is wrong?
I don't say anything against posting replies/answers to OT questions
there. If I know an answer, I post the answer + hint for the more
appropriate group, if I don't know an answer, I post a hint for the more
appropriate group too ;-).
You know what I mean with this message I think, although it is not written
as often with me?

Cor
 
T

The Grim Reaper

Thank you Cor - I did indeed miss those 2 shorts at the top of the code.
However, they made no difference.

I posted to the vb.upgrade group about 12 hours beforehand. Got a bit
frustrated with it last night and posted here too. I'll try posting to
mpdf.interop as Herfried suggested.
_________________________________
The Grim
 
T

The Grim Reaper

Hi Herfried,

I can't find mpdf.interop ... got the full name or a clue where I might find
it?? :D
Thanks.

I tried posting to a couple of winapi groups.... and basically got told to
get lost... so I'm still stuck :(
____________________________
The Grim Reaper
 
H

Herfried K. Wagner [MVP]

* "The Grim Reaper said:
I can't find mpdf.interop ... got the full name or a clue where I might find
it?? :D

microsoft.public.dotnet.framework.interop. That's a group on the public
ms news server (likme this one).
 
T

The Grim Reaper

Sorry Herfried - I was too shortsighted to spot the abbreviation!

For anyone still interested in the subject of this thread - getting the
hardware base addresses of the serial and parallel ports - I've eventually
solved it using 3 complex WMI queries. So all that API/Marshaling is gone,
it's all in managed code now!!
If anyone else needs to know port addresses for use in VB.NET, reply to this
or drop me an email.
Thanks to all for your suggestions.
______________________________
The Grim Reaper
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top