Test Connection To FTP Server with WinInet VB.net - vb.net

I already searched many site and most of them using C++ or VB6.
I want to test that my code works to connect to FTP server using winInet API Vb.net.
First of all i know to declare the wininet.dll.
But i don't know how to know the connection is already connected.
Here is my code :
Imports System.Net
Imports System.IO
Imports System.Net.Sockets
Public Class Form1
Public Declare Function internetopen Lib "wininet.dll" Alias "InternetOpenA" _
(ByVal lpszAgent As String, _
ByVal dwAccessType As Long, _
ByVal lpszproxyName As String, _
ByVal lpszproxyBypass As String, _
ByVal dwflags As Long) As Long
Private Declare Function InternetCloseHandle Lib "wininet.dll" (ByVal HINet As Integer) As Integer
Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Integer, ByVal sProxyName As String, ByVal sProxyBypass As String, ByVal lFlags As Integer) As Integer
Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" (ByVal hInternetSession As Integer, ByVal sServerName As String, ByVal nServerPort As Integer, ByVal sUsername As String, ByVal sPassword As String, ByVal lService As Integer, ByVal lFlags As Integer, ByVal lContext As Integer) As Integer
Private Declare Function FtpGetFile Lib "wininet.dll" Alias "FtpGetFileA" (ByVal hFtpSession As Integer, ByVal lpszRemoteFile As String, ByVal lpszNewFile As String, ByVal fFailIfExists As Boolean, ByVal dwFlagsAndAttributes As Integer, ByVal dwFlags As Integer, ByVal dwContext As Integer) As Boolean
Private Declare Function FtpPutFile Lib "wininet.dll" Alias "FtpPutFileA" (ByVal hFtpSession As Integer, ByVal lpszLocalFile As String, ByVal lpszRemoteFile As String, ByVal dwFlags As Integer, ByVal dwContext As Integer) As Boolean
Private Declare Function FtpFindFirstFile Lib "wininet.dll" Alias "FtpFindFirstFileA" (ByVal hFtpSession As Long, ByVal lpszSearchFile As String, ByVal lpFindFileData As WIN32_FIND_DATA, ByVal dwFlags As Long, ByVal dwContent As Long) As Long
Private Declare Function InternetFindNextFile Lib "wininet.dll" Alias "InternetFindNextFileA" (ByVal hFind As Long, ByVal lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FtpSetCurrentDirectory Lib "wininet.dll" Alias "FtpSetCurrentDirectoryA" (ByVal hFtpSession As Long, ByVal lpszDirectory As String) As Boolean
Private Declare Function FtpGetCurrentDirectory Lib "wininet.dll" Alias "FtpGetCurrentDirectoryA" (ByVal hFtpSession As Long, ByVal lpszCurrentDirectory As String, ByVal lpdwCurrentDirectory As Long) As Long
Private Structure FILETIME
Dim dwLowDateTime As Long
Dim dwHighDateTime As Long
End Structure
Private Structure WIN32_FIND_DATA
Dim dwFileAttributes As Long
Dim ftCreationTime As FILETIME
Dim ftLastAccessTime As FILETIME
Dim ftLastWriteTime As FILETIME
Dim nFileSizeHigh As Long
Dim nFileSizeLow As Long
Dim dwReserved0 As Long
Dim dwReserved1 As Long
Dim cFileName As String
Dim cAlternate As String
End Structure
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim INet As Long
Dim INetConn As Long
Dim RC As Boolean
Dim FileData As WIN32_FIND_DATA
Dim FileList As String
Dim MAX_PATH As Long = 0
Try
INet = internetopen("FTP_Backup", 1, vbNullString, vbNullString, 0)
INetConn = InternetConnect(INet, "FTP_SITE", 0, "USER", "PASSWORD", 1, 0, 0)
RC = FtpGetFile(INetConn, "/public_html/install.log", "D:\", False, 0, 0, 0)
If RC Then
MsgBox("Succed")
End If
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
End Class

InternetConnect() returns a handle to the session if the connection if successful, and NULL otherwise. So to test if the connection is already connected, make the check after you have tried to connect.
Try
INet = internetopen("FTP_Backup", 1, vbNullString, vbNullString, 0)
INetConn = InternetConnect(INet, "FTP_SITE", 0, "USER", "PASSWORD", 1, 0, 0)
If (INetConn = NULL) then
'Throw an error, we have failed to connect
End If
RC = FtpGetFile(INetConn, "/public_html/install.log", "D:\", False, 0, 0, 0)
If RC Then
MsgBox("Succed")
End If
Catch ex As Exception
MsgBox(ex.ToString)
Finally
InternetCloseHandle(INet)
End Try
Also, you are not cleaning up the web calls, call InternetCloseHandle to do so.

Related

VB.NET using ReadProcessMemory API

I am trying to use basic windows API functions in VB.NET. I have the following code:
Imports System.Runtime.InteropServices
Public Class testClass
Declare Function CreateProcessA Lib "kernel32" Alias "CreateProcessA" (ByVal lpApplicationName As String,
ByVal lpCommandLine As String, ByVal lpProcessAttributes As IntPtr,
ByVal lpThreadAttributes As IntPtr,
<MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandles As Boolean,
ByVal dwCreationFlags As Integer, ByVal lpEnvironment As IntPtr,
ByVal lpCurrentDirectory As String, ByVal lpStartupInfo As Byte(),
ByVal lpProcessInformation As IntPtr()) As <MarshalAs(UnmanagedType.Bool)> Boolean
Declare Function GetThreadContext Lib "kernel32" Alias "GetThreadContext" (ByVal hThread As IntPtr,
ByVal lpContext As UInteger()) As <MarshalAs(UnmanagedType.Bool)> Boolean
Declare Function ReadProcessMemory Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As IntPtr,
ByVal lpBaseAddress As IntPtr, ByRef lpBuffer As IntPtr,
ByVal nSize As Integer,
ByRef lpNumberOfBytesRead As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
Public Sub Test()
Dim locProcess As String = "C:\Windows\notepad.exe"
Dim iPtr1 As IntPtr = IntPtr.Zero
Dim startInfo As Byte() = New Byte(67) {}
Dim procInfo As IntPtr() = New IntPtr(3) {}
Dim cpResult = CreateProcessA(locProcess, vbNullString, iPtr1, iPtr1, False, 0, iPtr1, Nothing, startInfo, procInfo)
Dim pContext As UInteger() = New UInteger(178) {}
pContext(0) = &H10002
If GetThreadContext(procInfo(1), pContext) Then
Dim pAddress As New IntPtr(pContext(&H29) + 8L)
Dim pSize As New IntPtr(4)
Dim bAddress As IntPtr = IntPtr.Zero
Dim iPtr2 As IntPtr = IntPtr.Zero
If ReadProcessMemory(procInfo(0), pAddress, bAddress, CInt(pSize), iPtr2) <> 0 Then
MessageBox.Show("Success!")
Else
MessageBox.Show("ReadProcessMemory Error code is :" & Err.LastDllError)
End If
Else
MessageBox.Show("GetThreadContext Error code is :" & Err.LastDllError)
End If
End Sub
End Class
Public Class Form1
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim tc As New testClass
tc.Test()
End Sub
End Class
I am getting an error on ReadProcessMemory. The code results in
"ReadProcessMemory Error code is : 299".
I have been struggling to find the issue seeing as the error can be vague when dealing directly with windows DLLs. Any help on the issue would be greatly appreciated. Or, is there another solution to debugging properly (other than LastDllError) that may point me in the right direction of solving this issue. Thank you!

Listen to Windows messages in control, created with WinAPI, in VBA

I had a great help with understanding how to correctly create controls (particularly, ListBox) in VBA with WinAPI.
So, according to the structure, how VBA handles windows, we have three handles:
hWin - UserForm's handle
hClient - UserForm child's handle (Server)
hList - ListBox's handle
The question is - how to listen to Windows messages, incoming from Windows and generated by ListBox?
To listen to the messages, override the function that processes messages sent to a window, which is in this case hClient.
To listen to a change of selection in UserForm1:
Option Explicit
Private hWin As LongPtr
Private hClient As LongPtr
Private hList As LongPtr
Private Sub UserForm_Initialize()
' get the top window handle '
hWin = FindWindowEx(0, 0, StrPtr("ThunderDFrame"), StrPtr(Me.Caption))
If hWin Then Else Err.Raise 5, , "Top window not found"
' get first child / client window '
hClient = FindWindowEx(hWin, 0, 0, 0)
If hClient Then Else Err.Raise 5, , "Client window not found"
' create the list box '
hList = CreateWindowEx( _
dwExStyle:=WS_EX_CLIENTEDGE, _
lpClassName:=StrPtr("LISTBOX"), _
lpWindowName:=0, _
dwStyle:=WS_CHILD Or WS_VISIBLE Or WS_VSCROLL Or WS_SIZEBOX Or LBS_NOTIFY Or LBS_HASSTRINGS, _
x:=10, _
y:=10, _
nWidth:=100, _
nHeight:=100, _
hwndParent:=hClient, _
hMenu:=0, _
hInstance:=0, _
lpParam:=0)
' add some values '
SendMessage hList, LB_ADDSTRING, 0, StrPtr("item a")
SendMessage hList, LB_ADDSTRING, 0, StrPtr("item b")
SendMessage hList, LB_ADDSTRING, 0, StrPtr("item c")
' intercept messages '
UserForm1_Register Me, hClient
End Sub
Public Sub WndProc(ByVal hwnd As LongPtr, ByVal uMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr)
Select Case uMsg
Case WM_COMMAND
Select Case (wParam \ 65536) And 65535 ' HIWORD '
Case LBN_SELCHANGE
Debug.Print "Selection changed"
End Select
End Select
End Sub
and in a module:
Option Explicit
Public Declare PtrSafe Function FindWindowEx Lib "user32.dll" Alias "FindWindowExW" ( _
ByVal hwndParent As LongPtr, _
ByVal hwndChildAfter As LongPtr, _
ByVal lpszClass As LongPtr, _
ByVal lpszWindow As LongPtr) As LongPtr
Public Declare PtrSafe Function CreateWindowEx Lib "user32.dll" Alias "CreateWindowExW" ( _
ByVal dwExStyle As Long, _
ByVal lpClassName As LongPtr, _
ByVal lpWindowName As LongPtr, _
ByVal dwStyle As Long, _
ByVal x As Long, _
ByVal y As Long, _
ByVal nWidth As Long, _
ByVal nHeight As Long, _
ByVal hwndParent As LongPtr, _
ByVal hMenu As LongPtr, _
ByVal hInstance As LongPtr, _
ByVal lpParam As LongPtr) As LongPtr
Public Declare PtrSafe Function SendMessage Lib "user32.dll" Alias "SendMessageW" ( _
ByVal hwnd As LongPtr, _
ByVal wMsg As Long, _
ByVal wParam As LongPtr, _
ByVal lParam As LongPtr) As LongPtr
Private Declare PtrSafe Function CallWindowProc Lib "user32.dll" Alias "CallWindowProcW" ( _
ByVal lpPrevWndFunc As LongPtr, _
ByVal hwnd As LongPtr, _
ByVal Msg As Long, _
ByVal wParam As LongPtr, _
ByVal lParam As LongPtr) As LongPtr
#If Win64 Then
Private Declare PtrSafe Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongPtrW" ( _
ByVal hwnd As LongPtr, _
ByVal nIndex As Long, _
ByVal dwNewLong As LongPtr) As Long
#Else
Private Declare PtrSafe Function SetWindowLong Lib "user32.dll" Alias "SetWindowLongW" ( _
ByVal hwnd As LongPtr, _
ByVal nIndex As Long, _
ByVal dwNewLong As LongPtr) As Long
#End If
Public Const WS_EX_CLIENTEDGE = &H200&
Public Const WS_CHILD = &H40000000
Public Const WS_VISIBLE = &H10000000
Public Const WS_VSCROLL = &H200000
Public Const WS_SIZEBOX = &H40000
Public Const LBS_NOTIFY = &H1&
Public Const LBS_HASSTRINGS = &H40&
Public Const LB_ADDSTRING = &H180&
Public Const GW_CHILD = &O5&
Public Const GWL_WNDPROC As Long = -4
Public Const WM_COMMAND = &H111&
Public Const LBN_SELCHANGE = 1
Private UserForm1_Form As UserForm1
Private UserForm1_Func As LongPtr
Public Sub UserForm1_Register(form As UserForm1, ByVal hwnd As LongPtr)
Set UserForm1_Form = form
UserForm1_Func = SetWindowLong(hwnd, GWL_WNDPROC, AddressOf UserForm1_WinProc)
If UserForm1_Func = 0 Then Err.Raise 1, , "Failed to register"
End Sub
Private Function UserForm1_WinProc(ByVal hwnd As LongPtr, ByVal uMsg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
UserForm1_Form.WndProc hwnd, uMsg, wParam, lParam
UserForm1_WinProc = CallWindowProc(UserForm1_Func, hwnd, uMsg, wParam, lParam)
End Function

vba PtrSafe function type mismatch [duplicate]

I should figure out problem with excel VBA code compatibility on 64bit systems. I do not use VB language and code below is not my but I have to solve that issue.
Excel VB code:
Option Explicit
Private Declare Function WideCharToMultiByte Lib "kernel32.dll" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByRef lpMultiByteStr As Byte, ByVal cchMultiByte As Long, ByVal lpDefaultChar As String, ByRef lpUsedDefaultChar As Long) As Long
Private Const CP_UTF8 As Long = 65001
Private Const ERROR_INSUFFICIENT_BUFFER As Long = 122&
Public Function ToUTF8(s As String) As Byte()
If Len(s) = 0 Then Exit Function
Dim ccb As Long
ccb = WideCharToMultiByte(CP_UTF8, 0, StrPtr(s), Len(s), ByVal 0&, 0, vbNullString, ByVal 0&)
If ccb = 0 Then
Err.Raise 5, , "Internal error."
End If
Dim b() As Byte
ReDim b(1 To ccb)
If WideCharToMultiByte(CP_UTF8, 0, StrPtr(s), Len(s), b(LBound(b)), ccb, vbNullString, ByVal 0&) = 0 Then
Err.Raise 5, , "Internal error."
Else
ToUTF8 = b
End If
End Function
I have tried to add conditions #If VBA7 and PtrSave to everywhere but worksheet still does not work.
This is the code that I tried in Office 64 Bit
Option Explicit
#If VBA7 Then
Private Declare PtrSafe Function WideCharToMultiByte Lib "kernel32" (ByVal CodePage As Integer, ByVal dwFlags As Long, ByVal lpWideCharStr As LongPtr, ByVal cchWideChar As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As LongPtr, ByVal lpDefaultChar As Long, ByVal lpUsedDefaultChar As Long) As LongPtr
#Else
Private Declare Function WideCharToMultiByte Lib "kernel32.dll" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByRef lpMultiByteStr As Byte, ByVal cchMultiByte As Long, ByVal lpDefaultChar As String, ByRef lpUsedDefaultChar As Long) As Long
#EndIf
Private Const CP_UTF8 As Long = 65001
Private Const ERROR_INSUFFICIENT_BUFFER As Long = 122&
Public Function ToUTF8(s As String) As Byte()
If Len(s) = 0 Then Exit Function
Dim ccb As LongPtr
ccb = WideCharToMultiByte(CP_UTF8, 0, StrPtr(s), Len(s), ByVal 0&, 0, vbNullString, ByVal 0&)
If ccb = 0 Then
Err.Raise 5, , "Internal error."
End If
Dim b() As Byte
ReDim b(1 To ccb) // ERROR TYPE MISMATCH on ccb
If WideCharToMultiByte(CP_UTF8, 0, StrPtr(s), Len(s), b(LBound(b)), ccb, vbNullString, ByVal 0&) = 0 Then
Err.Raise 5, , "Internal error."
Else
ToUTF8 = b
End If
End Function
Thanks for help.
(Untested)
Change
This
Private Declare PtrSafe Function WideCharToMultiByte Lib "kernel32" _
(ByVal CodePage As Integer, ByVal dwFlags As Long, ByVal lpWideCharStr _
As LongPtr, ByVal cchWideChar As Long, ByVal lpMultiByteStr As Long, _
ByVal cchMultiByte As LongPtr, ByVal lpDefaultChar As Long, _
ByVal lpUsedDefaultChar As Long) As LongPtr
To
Private Declare PtrSafe Function WideCharToMultiByte Lib "Kernel32" ( _
ByVal CodePage As LongPtr, ByVal dwflags As LongPtr, _
ByVal lpWideCharStr As LongPtr, ByVal cchWideChar As LongPtr, _
ByVal lpMultiByteStr As LongPtr, ByVal cchMultiByte As LongPtr, _
ByVal lpDefaultChar As LongPtr, ByVal lpUsedDefaultChar As LongPtr) As LongPtr
This
Private Const CP_UTF8 As Long = 65001
To
Private Const CP_UTF8 = 65001
This
Private Const ERROR_INSUFFICIENT_BUFFER As Long = 122&
To
Private Const ERROR_INSUFFICIENT_BUFFER = 122&
This
Dim ccb As LongPtr
To
Dim ccb As Variant
In the last three chnages that I suggested, we are declaring them as Variants because we don't know what the type will be on different systems. It will either be Long or LongPtr

PtrSafe no longer supported in Outlook 2007 - re-editing macro

I'm currently considering using a macro for Outlook 2007 and read somewhere that PtrSafe is no longer supported.
Any idea what I can replace it with?
Private Declare PtrSafe Function FindWindowA Lib "user32" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare PtrSafe Function SetWindowPos Lib "user32" ( _
ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal X As Long, ByVal Y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal wFlags As Long) As Long
Private Const SWP_NOSIZE = &H1
Private Const SWP_NOMOVE = &H2
Private Const FLAGS As Long = SWP_NOMOVE Or SWP_NOSIZE
Private Const HWND_TOPMOST = -1
Private Sub Application_Reminder(ByVal Item As Object)
Dim ReminderWindowHWnd As Variant
On Error Resume Next
ReminderWindowHWnd = FindWindowA(vbNullString, "1 Reminder")
SetWindowPos ReminderWindowHWnd, HWND_TOPMOST, 0, 0, 0, 0, FLAGS
End Sub
I don't know where you read that PtrSafe is no longer supported, but that is incorrect.
But you should look at http://msdn.microsoft.com/en-us/library/ee691831%28v=office.14%29.aspx
I followed that link, suggested by Charles Williams, and created this code which solves the compilation error:
#If Win64 Then
Private Declare PtrSafe Function FindWindowA Lib "user32" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare PtrSafe Function SetWindowPos Lib "user32" ( _
ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal X As Long, ByVal Y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal wFlags As Long) As Long
#Else
Private Declare Function FindWindowA Lib "user32" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function SetWindowPos Lib "user32" ( _
ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal X As Long, ByVal Y As Long, ByVal cx As Long, _
ByVal cy As Long, ByVal wFlags As Long) As Long
#End If

How to turn this VB.net declaration into the equivalent for VB6 style and what's the process?

<DllImport("ieframe.dll", EntryPoint:="IEGetProtectedModeCookie")> _
Public Function IEGetProtectedModeCookie( _
<[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal lpszURL As String, _
<[In](), MarshalAs(UnmanagedType.LPWStr)> ByVal lpszCookieName As String, _
<MarshalAs(UnmanagedType.LPWStr)> ByVal pszCookieData As StringBuilder, _
ByRef pcchCookieData As UInteger, _
ByVal dwFlags As UInteger) As Integer
End Function
Those marshalas thingy look ugly
For comparison, typical vb6 style is:
Declare Function InternetGetCookieEx Lib "wininet.dll" Alias "InternetGetCookieExA" (ByVal pchURL As String, ByVal pchCookieName As String, ByVal pchCookieData As String, ByRef pcchCookieData As System.UInt32, ByVal dwFlags As System.UInt32, ByVal lpReserved As Integer) As Boolean
No marshal this no marshal that no [in] thingy. How do I turn that?
Is this the right way?
Declare Function IEGetProtectedModeCookie Lib "ieframe.dll" (ByVal lpszURL As String, ByVal lpszCookieName As String, ByVal pszCookieData As System.Text.StringBuilder, ByRef pcchCookieData As UInteger, ByVal dwFlags As UInteger) As Integer