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?
Related
While trying to create a handler using CreateFile(), even when executing the application as administrator, I get the following error message: ‘The system could not find the specified file. (Exception from HRESULT: 0x80070002)":Nothing.’
Here is a sample of the code being used for this task:
Private Enum EFileAccess As System.Int32
GENERIC_WRITE = &H40000000
End Enum
Friend Enum EFileShare
FILE_SHARE_READ = &H1
FILE_SHARE_WRITE = &H2
End Enum
Friend Enum ECreationDisposition
OPEN_EXISTING = 3
End Enum
Friend Enum EFileAttributes
FILE_FLAG_NO_BUFFERING = &H20000000
End Enum
<DllImport("kernel32.dll", SetLastError:=True, CharSet:=System.Runtime.InteropServices.CharSet.Auto)> _
Private Shared Function CreateFile(ByVal lpFileName As String, _
ByVal dwDesiredAccess As EFileAccess, _
ByVal dwShareMode As EFileShare, _
ByVal lpSecurityAttributes As IntPtr, _
ByVal dwCreationDisposition As ECreationDisposition, _
ByVal dwFlagsAndAttributes As EFileAttributes, _
ByVal hTemplateFile As IntPtr) As Microsoft.Win32.SafeHandles.SafeFileHandle
End Function
The path points to a matrix printer in a Windows Server 2003.
handle = CreateFile(\\brbhzpc001154\Epson_2180,
EFileAccess.GENERIC_WRITE,
EFileShare.FILE_SHARE_READ Or EFileShare.FILE_SHARE_WRITE,
IntPtr.Zero,
ECreationDisposition.OPEN_EXISTING,
EFileAttributes.FILE_FLAG_NO_BUFFERING,
IntPtr.Zero)
This application, when compiled works without any error in Windows XP, but when trying to execute in Windows 7, the error described above always happens.
There are solutions here suggesting that on Win7 changing OPEN_EXISTING to OPEN_ALWAYS will make it work on Win7, but with no explanation why.
I have the below code to load an icon using Shell32 dll. It works fine on my machine. But one of the systems in production environment got an exception saying "System.ArgumentException: Win32 handle that was passed to Icon is not valid or is the wrong type".
Any idea why we get this error? Thank you!
Public Function GetExecutableIcon() As Icon
Dim large As IntPtr
Dim small As IntPtr
ExtractIconEx(Application.ExecutablePath, 0, large, small, 1)
Return Icon.FromHandle(small)
End Function
<DllImport("Shell32")> _
Public Shared Function ExtractIconEx(ByVal sFile As String, ByVal iIndex As Integer,
ByRef piLargeVersion As IntPtr, ByRef piSmallVersion As IntPtr,
ByVal amountIcons As Integer) As Integer
End Function
Try this:
<DllImport("Shell32")> _
Public Shared Function ExtractIconEx(ByVal sFile As String, ByVal iIndex As Integer,
ByRef piLargeVersion As IntPtr, ByRef piSmallVersion As IntPtr,
ByVal amountIcons As Integer) As Integer
Public Function GetExecutableIcon() As Icon
Dim num As Integer = 10
Dim large(num - 1) As IntPtr
Dim small(num - 1) As IntPtr
ExtractIconEx("C:\Windows\System32\Shell32.dll", 0, large(0), small(0), num)
Return Icon.FromHandle(small(6)) 'change the index accordingly
End Function
Is your declaration correct? http://www.pinvoke.net/default.aspx/shell32.ExtractIconEx shows
<DllImport("shell32.dll", CharSet:=CharSet.Auto)> _
Shared Function ExtractIconEx(ByVal szFileName As String, _
ByVal nIconIndex As Integer, _
ByVal phiconLarge() As IntPtr, _
ByVal phiconSmall() As IntPtr, _
ByVal nIcons As UInteger) As UInteger
End Function
I'm looking for the fastest way to take a print-screen, and i found out that using Bitblt was my better choice, however, it only works for device context handle's, which means for me to retrieve a bitmap from that, i'd have to use multiple API's including CreateCompatibleBitmap, which in the end it probably takes the same time as using a managed way, like graphics.CopyFromScreen (which is a bit slow for me and also consumes alot of CPU, between 7-10% on a 2.3ghz quad-core processor...)
However, i still searched for a cleaner way of retrieving a bitmap from it, so i came up with this code:
<DllImport("user32.dll")> _
Public Shared Function GetDC(ByVal hWnd As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Public Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDC As IntPtr) As Integer
End Function
<DllImport("gdi32.dll")> _
Public Shared Function BitBlt(ByVal hdcDest As IntPtr, ByVal xDest As Integer, ByVal yDest As Integer, ByVal wDest As Integer, ByVal hDest As Integer, ByVal hdcSource As IntPtr, _
ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal rop As TernaryRasterOperations) As Boolean
End Function
Dim hwNd As IntPtr = Nothing
hwNd = GetDC(GetDesktopWindow)
picHandle = GetDC(Me.PictureBox1.Handle)
BitBlt(picHandle, 0, 0, PictureBox1.Width, PictureBox1.Height, hwNd, 0, 0, TernaryRasterOperations.SRCCOPY)
ReleaseDC(hwNd, picHandle)
I can reach ~30 fps with this... But it has two problems as i said above:
Even if displaying it on a picturebox as i'm doing it above accomplished what i want, it doesn't resize to the picturebox control, even if i change those "0" values to the picturebox x and y coordinates.
I further searched and found there's a StretchBit API for that, and it does stretch, but it also reduces quality, (Even with the necessary call to SetStretchBltMode with parameter "HALFTONE" so it doesn't "corrupt" the pixels), it also reduces performance at least in 10+ fps...
But as i need to get it as bitmap object, with the other necessary API's for that, i ended up with almost half the performance (15~ fps) which is equivalent of graphics.CopyFromScreen.
So, i'm asking, is there another way to get a bitmap from the screen using Bitblt or similar without losing performance?
If there isn't a .Net way, i kindly ask for any language-way of doing that.
If you want raw performance, you will have to get away from managed code. This is easy enough using C++ with Visual Studio. You can make calls directly to the Windows API, bypassing the .NET runtime, managed code for your application, and the overhead of p/invokes in .NET.
If you are familiar with C#, you can take your C# code, convert it to C++ (which should be straightforward, with a lot of work to replace the CLI).
Private Declare Function BitBlt Lib "GDI32" ( _
ByVal hdcDest As Integer, _
ByVal nXDest As Integer, _
ByVal nYDest As Integer, _
ByVal nWidth As Integer, _
ByVal nHeight As Integer, _
ByVal hdcSrc As Integer, _
ByVal nXSrc As Integer, _
ByVal nYSrc As Integer, _
ByVal dwRop As System.Int32) As Boolean
Declare Function QueryPerformanceCounter Lib "Kernel32" (ByRef X As Long) As Short
Declare Function QueryPerformanceFrequency Lib "Kernel32" (ByRef X As Long) As Short
Const SRCCOPY As Integer = &HCC0020
Use a form with only a picturebox and a label in it. Set the anchors of picbox accordingly. In picbox down event:
Private Sub PictureBox1_MouseDown(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown
Dim Ctr1, Ctr2, Freq As Long
Dim dbl As Double
QueryPerformanceCounter(Ctr1)
Dim desktopDC As IntPtr = Nothing
Dim picboxDC As IntPtr = Nothing
desktopDC = GetDC(New IntPtr(0))
picboxDC = GetDC(PictureBox1.Handle)
BitBlt(picboxDC, 0, 0, PictureBox1.Width, PictureBox1.Height, desktopDC, 0, 0, SRCCOPY)
QueryPerformanceCounter(Ctr2)
QueryPerformanceFrequency(Freq)
dbl = (Ctr2 - Ctr1) / Freq
dbl *= 1000000
Label1.Text = dbl.ToString 'it is in microseconds
ReleaseDC(New IntPtr(0), desktopDC)
ReleaseDC(PictureBox1.Handle, picboxDC)
End Sub
Maximize your form and click in picturebox.
I am trying to add an 'About' button to the System menu of my app, but the code that I found is throwing an error -
Unable to find an entry point named 'AppendMenu' in DLL 'user32'.
I wonder if someone could please take a look at the code and advise on how what I would need to do to fix it? Thanks.
Private Declare Function GetSystemMenu Lib "user32" (ByVal hWnd As IntPtr, ByVal bRevert As Boolean) As IntPtr
Private Declare Function AppendMenu Lib "user32" (ByVal hMenu As IntPtr, ByVal uFlags As Int32, ByVal uIDNewItem As IntPtr, ByVal lpNewItem As String) As Boolean
Private Const MF_STRING As Integer = &H0
Private Const MF_SEPARATOR As Integer = &H800
Private Sub AddSysMenuItems()
'Get the System Menus Handle.
Dim hSysMenu As IntPtr = GetSystemMenu(Me.Handle, False)
'Add a standard Separator Item.
AppendMenu(hSysMenu, MF_SEPARATOR, 1000, Nothing)
'Add an About Menu Item.
AppendMenu(hSysMenu, MF_STRING, 1001, "About")
End Sub
Well, the message is accurate, there is no entry point named "AppendMenu" in user32.dll. It actually has two versions of it. One is named AppendMenuA, the A means Ansi. The legacy version that uses 8-bit encoded strings, commonly used in old C programs. And AppendMenuW, the W means Wide. It takes a Unicode string like all winapi functions do on modern Windows versions.
Your old-style Declare statement is using the legacy function. You should use the Alias keyword to give the proper entrypoint name:
Private Declare Function AppendMenu Lib "user32.dll" Alias "AppendMenuA" (ByVal hMenu As IntPtr, ByVal uFlags As Int32, ByVal uIDNewItem As IntPtr, ByVal lpNewItem As String) As Boolean
Or just plain call it AppendMenuA. Using the legacy function isn't very pretty, although it won't have a problem converting "About" to Unicode. But do favor the modern way to declare pinvoke functions, it has many advantages beyond automatically mapping to the A or W version:
Imports System.Runtime.InteropServices
Imports System.ComponentModel
...
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function AppendMenu(ByVal hMenu As IntPtr, ByVal uFlags As Int32, ByVal uIDNewItem As IntPtr, ByVal lpNewItem As String) As Boolean
End Function
...
If Not AppendMenu(hSysMenu, MF_STRING, IntPtr.Zero, "About") Then
Throw New Win32Exception()
End If
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.