Sign in to follow this  
Followers 0
mestre

FTP.au3 FTPOpenFile

11 posts in this topic

I'm trying to retreive the size of a file via FTP. To do that via WinINet.dll I have to call the function "FtpOpenFile" and use that return handle with the function "FtpGetFileSize".

However I can not get FtpOpenFile to work. I have the include FTP.au3 (http://www.autoitscript.com/forum/index.php?showtopic=12473) working for uploading and downloading files.

Here is the example I am working with that I can not get to work. Any help would be appreciated! :P

#include <ftp.au3>
$ftpIP = '192.168.0.2'
$ftpUser = 'myusername'
$ftpPass = 'mypassword'


;Open FTP Session
$dllhandle = DllOpen('wininet.dll')
$Session = _FTPOpen("Testing FTP") 
if @error then 
    MsgBox(16,"Error","FTP Session Failed to open.")
    DllClose($dllhandle)
    Exit
EndIf

;Connect to FTP server
$ftpSession = _FTPConnect($Session,$ftpIP,$ftpUser,$ftpPass,1)
if @error then 
    MsgBox(16,"Error","FTP Connection Failed" & @cr & "Please check you connection and FTP Settings")
    _FTPClose($Session)
    DllClose($dllhandle)
    Exit
EndIf

;Open File to read size
$ftpOpenFile = _FtpOpenFile($ftpSession, "test.log", 1)
if @error then 
    MsgBox(16,"Error","Failed to open file for reading.")
    _FTPClose($ftpOpenFile)
    _FTPClose($ftpSession)
    DllClose($dllhandle)
    Exit
EndIf

MsgBox(0,"","Success")
_FTPClose($ftpSession)
DllClose($dllhandle)
Exit


;===============================================================================
;
; Function Name:    _FTPOpenFile()      http://msdn2.microsoft.com/en-us/library/aa384166.aspx
; Description:      Initiates access to a remote file for writing or reading.
; Parameter(s):     $l_InternetSession  - The Long from _FTPConnect()
;                   $s_RemoteFile       - The remote Location for the file.
;                   $l_Access           - Determines how the file will be accessed. This can be GENERIC_READ or GENERIC_WRITE, but not both.
;                   $l_Flags            - use the dwFlags parameter to specify 1 for transferring the file in ASCII (Type A transfer method) or 2 for transferring the file in Binary (Type I transfer method). (Default: 2)
;                   $l_Context          - lContext is used to identify the application context when using callbacks (Default: 0)
; Requirement(s):   DllCall, wininet.dll
; Return Value(s):  On Success - Returns an indentifier.
;                   On Failure - 0  and sets @ERROR
; Author(s):        
;
;===============================================================================

Func _FTPOpenFile($l_FTPSession, $s_RemoteFile, $l_Access = 0, $l_Flags = 0, $l_Context = 0)

    Local $ai_FTPOpenFile = DllCall('wininet.dll', 'long', 'FtpOpenFile', 'long', $l_FTPSession, 'str', $s_RemoteFile, 'long', $l_Access, 'long', $l_Flags, 'long', $l_Context)
    $test = DllCall('wininet.dll', 'long', 'GetLastError')
    ConsoleWrite("GetLastError = "& $test & @CR)
    ConsoleWrite("FTPOpenFile return handle = " & $ai_FTPOpenFile[0] & @CR)
    If @error OR $ai_FTPOpenFile[0] = 0 Then
        SetError(-1)
        Return 0
    EndIf

    Return $ai_FTPOpenFile[0]

EndFunc;==> _FTPOpenFile()

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

I'm trying to retreive the size of a file via FTP. To do that via WinINet.dll I have to call the function "FtpOpenFile" and use that return handle with the function "FtpGetFileSize".

However I can not get FtpOpenFile to work. I have the include FTP.au3 (http://www.autoitscript.com/forum/index.php?showtopic=12473) working for uploading and downloading files.

Here is the example I am working with that I can not get to work. Any help would be appreciated! :P

#include <ftp.au3>
$ftpIP = '192.168.0.2'
$ftpUser = 'myusername'
$ftpPass = 'mypassword'


;Open FTP Session
$dllhandle = DllOpen('wininet.dll')
$Session = _FTPOpen("Testing FTP") 
if @error then 
    MsgBox(16,"Error","FTP Session Failed to open.")
    DllClose($dllhandle)
    Exit
EndIf

;Connect to FTP server
$ftpSession = _FTPConnect($Session,$ftpIP,$ftpUser,$ftpPass,1)
if @error then 
    MsgBox(16,"Error","FTP Connection Failed" & @cr & "Please check you connection and FTP Settings")
    _FTPClose($Session)
    DllClose($dllhandle)
    Exit
EndIf

;Open File to read size
$ftpOpenFile = _FtpOpenFile($ftpSession, "test.log", 1)
if @error then 
    MsgBox(16,"Error","Failed to open file for reading.")
    _FTPClose($ftpOpenFile)
    _FTPClose($ftpSession)
    DllClose($dllhandle)
    Exit
EndIf

MsgBox(0,"","Success")
_FTPClose($ftpSession)
DllClose($dllhandle)
Exit


;===============================================================================
;
; Function Name:    _FTPOpenFile()      http://msdn2.microsoft.com/en-us/library/aa384166.aspx
; Description:      Initiates access to a remote file for writing or reading.
; Parameter(s):     $l_InternetSession  - The Long from _FTPConnect()
;                   $s_RemoteFile       - The remote Location for the file.
;                   $l_Access           - Determines how the file will be accessed. This can be GENERIC_READ or GENERIC_WRITE, but not both.
;                   $l_Flags            - use the dwFlags parameter to specify 1 for transferring the file in ASCII (Type A transfer method) or 2 for transferring the file in Binary (Type I transfer method). (Default: 2)
;                   $l_Context          - lContext is used to identify the application context when using callbacks (Default: 0)
; Requirement(s):   DllCall, wininet.dll
; Return Value(s):  On Success - Returns an indentifier.
;                   On Failure - 0  and sets @ERROR
; Author(s):        
;
;===============================================================================

Func _FTPOpenFile($l_FTPSession, $s_RemoteFile, $l_Access = 0, $l_Flags = 0, $l_Context = 0)

    Local $ai_FTPOpenFile = DllCall('wininet.dll', 'long', 'FtpOpenFile', 'long', $l_FTPSession, 'str', $s_RemoteFile, 'long', $l_Access, 'long', $l_Flags, 'long', $l_Context)
    $test = DllCall('wininet.dll', 'long', 'GetLastError')
    ConsoleWrite("GetLastError = "& $test & @CR)
    ConsoleWrite("FTPOpenFile return handle = " & $ai_FTPOpenFile[0] & @CR)
    If @error OR $ai_FTPOpenFile[0] = 0 Then
        SetError(-1)
        Return 0
    EndIf

    Return $ai_FTPOpenFile[0]

EndFunc;==> _FTPOpenFile()

Try this function

;===============================================================================
;
; Function Name:    _FTPGetFileSize()
; Description:    Gets filesize of a file on the FTP server.
; Parameter(s):  $l_FTPSession  - The Long from _FTPConnect()
;                  $s_FileName  - The file name.
; Requirement(s):   DllCall, wininet.dll
; Return Value(s):  On Success - 1
;                  On Failure - 0
; Author(s):        J.o.a.c.h.i.m. d.e. K.o.n.i.n.g.
;
;===============================================================================

Func _FTPGetFileSize($l_FTPSession, $s_FileName)

    Local $ai_FTPGetSizeHandle = DllCall('wininet.dll', 'int', 'FtpOpenFile', 'long', $l_FTPSession, 'str', $s_FileName, 'long', 0x80000000, 'long', 0x04000002, 'long', 0)
    Local $ai_FTPGetFileSize = DllCall('wininet.dll', 'int', 'FtpGetFileSize', 'long', $ai_FTPGetSizeHandle[0])
    If @error OR $ai_FTPGetFileSize[0] = 0 Then
        SetError(-1)
        Return 0
    EndIf
    DllCall('wininet.dll', 'int', 'InternetCloseHandle', 'str', $ai_FTPGetSizeHandle[0]);<--corrected 27th Nov
               ;",$ai_FTPGetSizeHandle[0])" was ",$l_FTPSession)"   

    Return $ai_FTPGetFileSize[0]
    
EndFunc;==> _FTPGetFileSize()

27th Nov EDIT: Corrected error as pointed out by Zedna in later post

Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Thank you for you fast reply. What you fixed seemed logical, but it still has the same issue on FtpOpenFile. I included a little error checking on the FtpOpenFile because the program just would hang without it. The FTP info is good for you to test on if you want. I have a file in that account called: "test.log". I've also included the FTP.au3 include as an attachment incase you didn't have it.

Thanks again

#include <ftp.au3>
$ftpIP = '72.185.209.105'
$ftpUser = 'test'
$ftpPass = '6a5d7edse1'


;Open FTP Session
$dllhandle = DllOpen('wininet.dll')
$Session = _FTPOpen("Testing FTP") 
if @error then 
    MsgBox(16,"Error","FTP Session Failed to open.")
    DllClose($dllhandle)
    Exit
EndIf

;Connect to FTP server
$ftpSession = _FTPConnect($Session,$ftpIP,$ftpUser,$ftpPass,0,1,0x08000000)
if @error then 
    MsgBox(16,"Error","FTP Connection Failed" & @cr & "Please check you connection and FTP Settings")
    _FTPClose($Session)
    DllClose($dllhandle)
    Exit
EndIf

;Open File to read size
$ftpGetSize = _FTPGetFileSize($ftpSession, "test.log")
if @error then 
    MsgBox(16,"Error","Failed to open file for reading.")
    _FTPClose($ftpSession)
    DllClose($dllhandle)
    Exit
EndIf

MsgBox(0,"",$ftpGetSize)
_FTPClose($ftpSession)
DllClose($dllhandle)
Exit


;===============================================================================
;
; Function Name:    _FTPGetFileSize()
; Description:      Gets filesize of a file on the FTP server.
; Parameter(s):     $l_FTPSession    - The Long from _FTPConnect()
;                   $s_FileName     - The file name.
; Requirement(s):   DllCall, wininet.dll
; Return Value(s):  On Success - 1
;                   On Failure - 0
; Author(s):        J.o.a.c.h.i.m. d.e. K.o.n.i.n.g.
;
;===============================================================================

Func _FTPGetFileSize($l_FTPSession, $s_FileName)

    Local $ai_FTPGetSizeHandle = DllCall('wininet.dll', 'int', 'FtpOpenFile', 'long', $l_FTPSession, 'str', $s_FileName, 'long', 0x80000000, 'long', 0x04000002, 'long', 0)
    If @error OR $ai_FTPGetSizeHandle[0] = 0 Then
        MsgBox(16,"Error", "FTPOpenFile Failed; Handle = " & $ai_FTPGetSizeHandle[0])
        SetError(-1)
        Return 0
    EndIf
    Local $ai_FTPGetFileSize = DllCall('wininet.dll', 'int', 'FtpGetFileSize', 'long', $ai_FTPGetSizeHandle[0])
    If @error OR $ai_FTPGetFileSize[0] = 0 Then
        MsgBox(16,"Error", "FTPGetFileSize Failed; Handle = " & $ai_FTPGetFileSize[0])
        SetError(-1)
        Return 0
    EndIf
    DllCall('wininet.dll', 'int', 'InternetCloseHandle', 'str', $ai_FTPGetSizeHandle)

    Return $ai_FTPGetFileSize[0]
    
EndFunc;==> _FTPGetFileSize()

FTP.au3

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Thank you Zedna. I noticed that and I have fixed that before trying. My problem is I am not getting a handle back from FTPOpenFile. Maybe my FTP server doesn't support opening of files. I can send "SIZE test.log" in a telnet session and it sends me the size of the file. Maybe I'll try another server or a different approach. Thanks again guys!

Edited by mestre

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Thank you Zedna. I noticed that and I have fixed that before trying. My problem is I am not getting a handle back from FTPOpenFile. Maybe my FTP server doesn't support opening of files. I can send "SIZE test.log" in a telnet session and it sends me the size of the file. Maybe I'll try another server or a different approach. Thanks again guys!

Ok I've got it working. My FTP server doesn't allow opening of files. Also there is another bug in the _FtpGetFileSize(): Not enough arguments. After I switched servers and was getting a handle back from _FTPGetSizeHandle the program would hang.

So I looked at this: http://msdn2.microsoft.com/en-us/library/aa384159.aspx

I changed this:

Local $ai_FTPGetFileSize = DllCall('wininet.dll', 'int', 'FtpGetFileSize', 'long', $ai_FTPGetSizeHandle[0])oÝ÷ ÚÚ-+ºÚ"µÍØØ[   ÌÍØZWÑÙ][TÚ^HHØ[
    ÌÎNÝÚ[[]    ÌÎNË ÌÎNÚ[    ÌÎNË ÌÎNÑÙ][TÚ^IÌÎNË ÌÎNÛÛÉÌÎNË  ÌÍØZWÑÙ]Ú^R[VÌK  ÌÎNÛÛÉÌÎNË
oÝ÷ Ø    ÝF;}ȶ·­º¹ÞvØ^~)^²,ÞN§Æ j)È^¶¬éi±©ò¢wǨºÑÞ­íý²Ø^3ÆzÑbä¢ÍëajجÂäx¢¹jëh×6;===============================================================================
;
; Function Name:    _FTPGetFileSize()
; Description:      Gets filesize of a file on the FTP server.
; Parameter(s):     $l_FTPSession    - The Long from _FTPConnect()
;                   $s_FileName     - The file name.
; Requirement(s):   DllCall, wininet.dll
; Return Value(s):  On Success - 1
;                   On Failure - 0
; Author(s):        J.o.a.c.h.i.m. d.e. K.o.n.i.n.g.
;
;===============================================================================

Func _FTPGetFileSize($l_FTPSession, $s_FileName)

    Local $ai_FTPGetSizeHandle = DllCall('wininet.dll', 'int', 'FtpOpenFile', 'long', $l_FTPSession, 'str', $s_FileName, 'long', 0x80000000, 'long', 0x04000002, 'long', 0)
    Local $ai_FTPGetFileSize = DllCall('wininet.dll', 'int', 'FtpGetFileSize', 'long', $ai_FTPGetSizeHandle[0], 'long', 0)
    If @error OR $ai_FTPGetFileSize[0] <= 0 Then
        SetError(-1)
        Return 0
    EndIf
    DllCall('wininet.dll', 'int', 'InternetCloseHandle', 'long', $ai_FTPGetSizeHandle[0])
    Return $ai_FTPGetFileSize[0]
    
EndFunc;==> _FTPGetFileSize()

Edit - Removed Debugging

Edited by mestre

Share this post


Link to post
Share on other sites

#7 ·  Posted (edited)

Look here and here I posted there correction for bug in function _FTPGetFileSize()

But the correction is already in the post I made isn't it?

So I looked at this: http://msdn2.microsoft.com/en-us/library/aa384159.aspx

I changed this:

CODE: AutoIt

Local $ai_FTPGetFileSize = DllCall('wininet.dll', 'int', 'FtpGetFileSize', 'long', $ai_FTPGetSizeHandle[0])

to this:

CODE: AutoIt

Local $ai_FTPGetFileSize = DllCall('wininet.dll', 'int', 'FtpGetFileSize', 'long', $ai_FTPGetSizeHandle[0], 'long', 0)

And BINGO! It returned the file size.

I followed the link and this is what it says about the function-

FtpGetFileSize Function

Retrieves the file size of the requested FTP resource.

DWORD FtpGetFileSize(

__in HINTERNET hFile,

__out LPDWORD lpdwFileSizeHigh

);

Parameters

hFile

Handle returned from a call to FtpOpenFile.

lpdwFileSizeHigh

Pointer to the high-order unsigned long integer of the file size of the requested FTP resource.

I don't see anything to say you need that extra parameter. Edited by martin

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

No. Your code hasn't this bug fixed.

Oh yes, my apologies Zedna, I was looking at the wrong thing.

Thanks for pointing this out. I'll correct my post.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

But the correction is already in the post I made isn't it?

I followed the link and this is what it says about the function-

I don't see anything to say you need that extra parameter.

FtpGetFileSize Function

Retrieves the file size of the requested FTP resource.

DWORD FtpGetFileSize(
__in HINTERNET hFile,
__out LPDWORD lpdwFileSizeHigh  <--------------------------HERE - Maybe because it is an "OUT". It doesn't work with nothing called.
);

Parameters

hFile

Handle returned from a call to FtpOpenFile.
lpdwFileSizeHigh

Pointer to the high-order unsigned long integer of the file size of the requested FTP resource.

Share this post


Link to post
Share on other sites

FtpGetFileSize Function

Retrieves the file size of the requested FTP resource.

DWORD FtpGetFileSize(
__in HINTERNET hFile,
__out LPDWORD lpdwFileSizeHigh  <--------------------------HERE - Maybe because it is an "OUT". It doesn't work with nothing called.
);

Parameters

hFile

Handle returned from a call to FtpOpenFile.
lpdwFileSizeHigh

Pointer to the high-order unsigned long integer of the file size of the requested FTP resource.

Mhhh. I seem to have had problems reading yesterday.

I see what this is now.

The file size could be larger than can be given by a 32 bit integer. But the return value is an integer. So part of the size is returned in the second parameter.

So this is what I think is needed.

Local $High  = dllstructCreate(("uint")
Local $pHigh = dllstructgetptr($High)
Local $ai_FTPGetFileSize = DllCall('wininet.dll', 'int', 'FtpGetFileSize', 'long', $ai_FTPGetSizeHandle[0], 'long_ptr', $pHigh )

$ai_FTPGetFileSize = $ai_FTPGetFileSize[0] + DllStructGetData($High,1) * (2^32)

If the file size is less than about 4Gb then it won't matter, but if it's larger then without using the second parameter correctly you will get the wrong size.


Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0