mestre Posted November 26, 2007 Posted November 26, 2007 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! expandcollapse popup#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()
martin Posted November 26, 2007 Posted November 26, 2007 (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! expandcollapse popup#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 November 27, 2007 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.
Zedna Posted November 27, 2007 Posted November 27, 2007 Look here and here I posted there correction for bug in function _FTPGetFileSize() Resources UDF ResourcesEx UDF AutoIt Forum Search
mestre Posted November 27, 2007 Author Posted November 27, 2007 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 expandcollapse popup#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
mestre Posted November 27, 2007 Author Posted November 27, 2007 (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 November 27, 2007 by mestre
mestre Posted November 27, 2007 Author Posted November 27, 2007 (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 November 27, 2007 by mestre
martin Posted November 27, 2007 Posted November 27, 2007 (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 November 27, 2007 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.
Zedna Posted November 27, 2007 Posted November 27, 2007 But the correction is already in the post I made isn't it?No. Your code hasn't this bug fixed. Resources UDF ResourcesEx UDF AutoIt Forum Search
martin Posted November 27, 2007 Posted November 27, 2007 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.
mestre Posted November 27, 2007 Author Posted November 27, 2007 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.
martin Posted November 27, 2007 Posted November 27, 2007 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.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now