vb .net createfile, WinUsb, must release resources? - vb.net

I have to use CreateFile imported from kernel32.dll in some VB .NET project to obtain some handle for WinUSB further functions.
The question is do I need to destroy somehow/something after CreateFile when I don't need the handle anymore?
The second question is I use WinUsb_Initialize() with CreateFile returned handle to obtain another handle for WinUSB purposes. Do I need to make some cleaning too?
Thanks in advance,
<DllImport("kernel32.dll",
SetLastError:=True,
CharSet:=CharSet.Auto)> _
Private Shared Function CreateFile(ByVal lpFileName As String,
ByVal dwDesiredAccess As Int32,
ByVal dwShareMode As UInt32,
ByVal lpSecurityAttributes As IntPtr,
ByVal dwCreationDisposition As UInt32,
ByVal dwFlagsAndAttributes As UInt32,
ByVal hTemplateFile As IntPtr) As SafeFileHandle
End Function
<DllImport("kernel32.dll",
CharSet:=CharSet.Auto,
SetLasterror:=True)>
Public Shared Function CloseHandle(ByVal Handle As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Now I read somewhere if I use safehandlers in CreateFile there is no need to CloseHandle.
This is my "Disconnect" code
Dim ErrorStatus As Integer = 0
If hWinUSBInterface <> INVALID_HANDLE_VALUE Then
WinUsb_Free(hWinUSBInterface)
hWinUSBInterface = INVALID_HANDLE_VALUE
End If
If hDevice <> INVALID_HANDLE_VALUE Then
'hDevice = INVALID_HANDLE_VALUE
'RaiseEvent Error(ErrorStatus, "Disconnect")
If CloseHandle(hDevice) Then
hDevice = INVALID_HANDLE_VALUE
RaiseEvent Disconnected()
Else
ErrorStatus = Err.LastDllError
RaiseEvent Error(ErrorStatus, "Disconnect")
End If
End If

The HANDLE you obtained from CreateFile() must be released by pinvoking CloseHandle().
The WINUSB_INTERFACE_HANDLE you obtained from WinUSB_Initialize() must be released by pinvoking WinUSB_Free().
Note that these requirements are spelled out in detail in the MSDN Library articles for these functions.

Related

'System.Runtime.InteropServices.DllImportAttribute' cannot be applied to instance method

I'm trying to use some winapi methods. how ever, when I try to use the function I get the following error:
'System.Runtime.InteropServices.DllImportAttribute' cannot be applied to instance method.
code:
Public Class Anti
<DllImport("kernel32.dll", SetLastError:=True)> _
Public Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAdress As Integer, ByRef lpBuffer As Integer, ByVal nSize As Integer, Optional ByRef lpNumberOfBytesRead As Integer = 0) As Boolean
End Function
<DllImport("kernel32.dll", SetLastError:=True)> _
Public Sub ZeroMemory(ByVal handle As IntPtr, ByVal length As UInt32)
End Sub
<DllImport("kernel32.dll", SetLastError:=True)> _
Public Function VirtualProtect(ByVal lpAddress As IntPtr, ByVal dwSize As Integer, ByVal flNewProtect As Integer, ByRef lpflOldProtect As UInteger) As Boolean
End Function
Public Sub AntiDump()
Try
Dim x(0) As Process
Well, the message is pretty clear. Methods that you apply the DllImport attribute to must be class methods (shared).

CreateFileW() handle returns -1

I am trying to create handle to Windows Phone device. But CreateFileW returns -1 and Error code is 3 ERROR_PATH_NOT_FOUND. Any help to this problem?
My code:
handle = CreateFileW("\\\\.\\NOKIA_TOUCH", GENERIC_READ Or GENERIC_WRITE, FILE_SHARE_READ Or FILE_SHARE_WRITE, IntPtr.Zero, 3, 0, IntPtr.Zero)
If handle = -1 Then
ShowMsg(Marshal.GetLastWin32Error)
Else
ShowMsg("Success!")
End If
EDIT: P/Invoke code:
<DllImport("kernelBase.dll", CharSet:=CharSet.Unicode, ExactSpelling:=False, PreserveSig:=True, SetLastError:=True)>
Public Shared Function CreateFileW(ByVal lpFileName As String, ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer, ByVal lpSecurityAttributes As IntPtr, ByVal dwCreationDisposition As Integer, ByVal dwFLagsAndAttributes As Integer, ByVal hTemplateFile As IntPtr) As IntPtr
End Function
This is unlikely to work (you probably don't have security capability to talk to the Nokia driver) and even if it does work while debugging on your device you won't be able to submit it to the Windows Store (unless you work for an OEM that needs to use this driver).
What are you trying to do with the driver that can't be done through the public API?

Enumerating native resources

This question is related to Visual Basic .NET 2010
How do I enumerate the "native" resources (such as icon, version info, etc) of a win32 executable file?
I found little to no documentation on it, and what I found simply did not work. I've tried the example provided here so far http://www.pinvoke.net/default.aspx/kernel32.EnumResourceNames. It's all I could find on the subject.
Help is much appreciated.
It isn't that clear what your hangup might be. The declarations you found at pinvoke.net are only so-so, not an uncommon problem. The probable hangup is that both the resource type and the resource name can either be a number or a string. So the pinvoke declaration should declare them as IntPtr and, if they have the right value, convert them to a string dynamically.
Another thing you have to do is to first enumerate the resource types in the file, then enumerate the resources of that type.
Some code to play with:
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Imports System.Linq
Module Module1
Sub Main()
Dim handle = LoadLibrary("user32.dll")
If handle = IntPtr.Zero Then
Throw New Win32Exception
End If
If Not EnumResourceTypes(handle, AddressOf EnumTypesCallback, IntPtr.Zero) Then
Throw New Win32Exception
End If
Console.ReadLine()
End Sub
Function EnumTypesCallback(hModule As IntPtr, lpszType As IntPtr, lParam As IntPtr) As Boolean
EnumResourceNames(hModule, lpszType, AddressOf EnumResourceCallback, IntPtr.Zero)
Return True
End Function
Function EnumResourceCallback(hModule As IntPtr, lpszType As IntPtr, ByVal lpszName As IntPtr, ByVal lParam As IntPtr) As Boolean
Dim type As String = lpszType.ToInt32().ToString()
If [Enum].GetValues(GetType(ResourceType)).Cast(Of Integer).Contains(lpszType.ToInt32()) Then
type = [Enum].GetName(GetType(ResourceType), lpszType.ToInt32())
ElseIf lpszType.ToInt32() > &HFFFF Then
type = Marshal.PtrToStringUni(lpszType)
End If
Dim name As String = lpszName.ToInt32().ToString()
If lpszName.ToInt32() > &HFFFF Then
name = Marshal.PtrToStringUni(lpszName)
End If
Console.WriteLine("Resource type={0}, id={1}", type, name)
Return True
End Function
Private Delegate Function EnumResNameProcDelegate(ByVal hModule As IntPtr, ByVal lpszType As IntPtr, ByVal lpszName As IntPtr, ByVal lParam As IntPtr) As Boolean
Private Delegate Function EnumResTypeProc(hModule As IntPtr, lpszType As IntPtr, lParam As IntPtr) As Boolean
<DllImport("kernel32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
Public Function LoadLibrary(ByVal lpFileName As String) As IntPtr
End Function
<DllImport("kernel32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
Private Function EnumResourceTypes(ByVal hModule As IntPtr, ByVal lpEnumFunc As EnumResTypeProc, ByVal lParam As IntPtr) As Boolean
End Function
<DllImport("kernel32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
Private Function EnumResourceNames(ByVal hModule As IntPtr, ByVal lpszType As IntPtr, ByVal lpEnumFunc As EnumResNameProcDelegate, ByVal lParam As IntPtr) As Boolean
End Function
Public Enum ResourceType
CURSOR = 1
BITMAP = 2
ICON = 3
MENU = 4
DIALOG = 5
[STRING] = 6
FONTDIR = 7
FONT = 8
ACCELERATOR = 9
RCDATA = 10
MESSAGETABLE = 11
GROUP_CURSOR = 12
GROUP_ICON = 14
VERSION = 16
DLGINCLUDE = 17
PLUGPLAY = 19
VXD = 20
ANICURSOR = 21
ANIICON = 22
HTML = 23
MANIFEST = 24
End Enum
End Module
Output on Windows 8.1:
Resource type=MUI, id=1
Resource type=WEVT_TEMPLATE, id=1
Resource type=CURSOR, id=92
Resource type=CURSOR, id=93
etc...
Resource type=BITMAP, id=36
Resource type=BITMAP, id=136
etc..
Resource type=ICON, id=1
Resource type=ICON, id=2
etc..
Resource type=MENU, id=1
Resource type=MENU, id=4
etc..
Resource type=DIALOG, id=9
Resource type=STRING, id=1
Resource type=STRING, id=44
etc..
Resource type=MESSAGETABLE, id=1
Resource type=GROUP_CURSOR, id=100
Resource type=GROUP_CURSOR, id=101
etc..
Resource type=GROUP_ICON, id=100
Resource type=GROUP_ICON, id=101
etc..
Resource type=VERSION, id=1
Resource type=ANICURSOR, id=32665
Resource type=ANICURSOR, id=32666
Resource type=ANICURSOR, id=32669
Compare to what you see when you use File + Open + File, select c:\windows\syswow64\user32.dll (won't work on Express).

Need help getting child windows

I am working in vb with visual studio 2010.
The app AnyOrder is no longer supported and I am trying to make an app where our users can type in info and then have the info populate into AnyOrder (and also other sites - they have to populate a lot of redundant info) but I am having no luck at all getting the child windows of any order to populate once the data is in the VB window app.
I can get the parent window handle just fine but can't seem to get a child window handle to save my life. I can't even get the first level down and the blanks that I will need to populate are great grand-children of the parent window.
It won't let me post a screencap of the spy++ since I just signed up and don't have the 10 rep but here is a link to the capture.
Thank you in advance for any assistance that you can provide.
Figured out the answer somehow.
#Region "functions"
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Int32
Public Delegate Function EnumWindowProcess(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
<DllImport("User32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Private Shared Function EnumChildWindows(ByVal WindowHandle As IntPtr, ByVal Callback As EnumWindowProcess, ByVal lParam As IntPtr) As Boolean
End Function
Private Shared Function EnumWindow(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
Dim ChildrenList As List(Of IntPtr) = CType(GCHandle.FromIntPtr(Parameter).Target, Global.System.Collections.Generic.List(Of Global.System.IntPtr))
ChildrenList = CType(GCHandle.FromIntPtr(Parameter).Target, Global.System.Collections.Generic.List(Of Global.System.IntPtr))
If ChildrenList Is Nothing Then Throw New Exception("GCHandle Target could not be cast as List(Of IntPtr)")
ChildrenList.Add(Handle)
Return True
End Function
Private Shared Function GetChildWindows(ByVal ParentHandle As IntPtr) As IntPtr()
Dim ListHandle As GCHandle = GCHandle.Alloc(ChildrenList)
Try
EnumChildWindows(ParentHandle, AddressOf EnumWindow, GCHandle.ToIntPtr(ListHandle))
Finally
If ListHandle.IsAllocated Then ListHandle.Free()
End Try
Return ChildrenList.ToArray
End Function
#End Region
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
iParentHandle = FindWindow(vbNullString, AOParentName)
GetChildWindows(FindWindow(vbNullString, AOParentName))
Dim Childlist As String = String.Join(". ", ChildrenList)
MsgBox("list of child windows: " & Childlist)
End Sub

Write text to Win32 Resources

I am trying to write text to Win32 resources, but I have failed with it.
Here it is after writing the text:
And here is how it should look like:
Here's my code:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
WriteResourceStr(Target.Text, "hello")
End Sub
#Region "Second"
<DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
Private Shared Function UpdateResource(ByVal hUpdate As IntPtr, ByVal lpType As String, ByVal lpName As String, ByVal wLanguage As UShort, ByVal lpData As IntPtr, ByVal cbData As UInteger) As Boolean
End Function
<DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
Private Shared Function BeginUpdateResource(ByVal pFileName As String, <MarshalAs(UnmanagedType.Bool)> ByVal bDeleteExistingResources As Boolean) As IntPtr
End Function
<DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
Private Shared Function EndUpdateResource(ByVal hUpdate As IntPtr, ByVal fDiscard As Boolean) As Boolean
End Function
Public Function WriteResourceStr(ByVal filename As String, ByVal bytes As String) As Boolean
Try
Dim handle As IntPtr = BeginUpdateResource(filename, False)
Dim file1 As String = bytes
Dim fileptr As IntPtr = ToPtr(file1)
Dim res As Boolean = UpdateResource(handle, "RCData", "CONFIG", 1, fileptr, System.Convert.ToUInt16(file1.Length))
EndUpdateResource(handle, False)
Catch ex As Exception
Return False
End Try
Return True
End Function
Private Function ToPtr(ByVal data As Object) As IntPtr
Dim h As GCHandle = GCHandle.Alloc(data, GCHandleType.Pinned)
Dim ptr As IntPtr
Try
ptr = h.AddrOfPinnedObject()
Finally
h.Free()
End Try
Return ptr
End Function
#End Region
So seems like it doesn't write ANSI, but in Unicode. How to change that?
Hopefully somebody replies.
The simplest way to get this is to just overload UpdateResource and let Windows make the Unicode to ANSI conversion for you:
<DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Ansi)> _
Private Shared Function UpdateResource(ByVal hUpdate As IntPtr, _
ByVal lpType As String, ByVal lpName As String, ByVal wLanguage As UShort,
ByVal lpData As String, ByVal cbData As Integer) As Boolean
End Function
Note the changed lpData type and the changed CharSet. The call now simply becomes:
Dim handle As IntPtr = BeginUpdateResource(filename, False)
If handle = IntPtr.Zero Then Throw New Win32Exception
Dim res As Boolean = UpdateResource(handle, "RCData", "CONFIG", 1, _
bytes, bytes.Length)
If Not EndUpdateResource(handle, False) Then Throw New Win32Exception
I'll have to restate the nonsensical nature of the call. RCData is a numbered resource type and not a string. Using a language ID of 1 makes little sense, that's Arabic so you wouldn't expect a Latin string in the resource. Whatever app reads this resource is unlikely to find it back.
Doing this correctly would require an overload that declares lpType as IntPtr so you can pass CType(10, IntPtr) for the RT_RCData resource type. The ToPtr() function is extremely evil, it returns a dangling pointer that will cause random data corruption. Just let the pinvoke marshaller generate the pointer by declaring the lpData argument as Byte(). You'd then use Encoding.GetBytes() to use the proper ANSI conversion. Thus:
<DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)> _
Private Shared Function UpdateResource(ByVal hUpdate As IntPtr, _
ByVal lpType As IntPtr, ByVal lpName As String, ByVal wLanguage As UShort,
ByVal lpData As Byte(), ByVal cbData As Integer) As Boolean
End Function
With an additional overload required if lpName is a numbered instead of a named resource, use IntPtr.