Posted: 18th Mar 2022 6:21
+ Code Snippet
sync on : sync rate 30 : sync

#constant WINDOW_NORMAL   13565952
#constant INTERNET_OPEN_TYPE_PRECONFIG 0 // use registry configuration
#constant INTERNET_OPEN_TYPE_DIRECT    1 // direct to net
#constant INTERNET_OPEN_TYPE_PROXY     3 // via named proxy
#constant INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 4 // prevent using java/script/INS
#constant INTERNET_DEFAULT_FTP_PORT 21 
#constant INTERNET_SERVICE_FTP 1     // FTP service.
#constant INTERNET_SERVICE_GOPHER 2    // Gopher service.
#constant INTERNET_SERVICE_HTTP 3    // HTTP service.
HttpAgent as string = "FTP Session"
NullString as string = ""

sServerName as string = "your website . com or IP address"
nServerPort as integer = INTERNET_DEFAULT_FTP_PORT  
sUsername as string = "your login id" 
sPassword as string = "your login password"
lService as integer = INTERNET_SERVICE_FTP
lFlags as integer = 0
lContext as dword = 0

wininet = find free dll()
load dll "wininet.dll", wininet
if dll exist(1)=1 
	print "dll exists and loaded ok."
else
	end
endif

`ioaexists=dll call exist(wininet,"InternetOpenA")
`print "InternetOpenA exists:" ; ioaexists
hInternetSession as dword
hInternetSession = call dll(wininet,"InternetOpenA", HttpAgent, INTERNET_OPEN_TYPE_DIRECT, "", "" , 0) 
`print "hInternetSession: ";hInternetSession

if hInternetSession > 0 
	`icaexist=dll call exist(wininet,"InternetConnectA")
	`print "InternetConnectA exists: ";icaexist
	hConnection as dword
	hConnection=call dll(wininet,"InternetConnectA", hInternetSession, sServerName, nServerPort, sUsername, sPassword, lService, lFlags, lContext ) 
	print "FTP site connection handle: ";hConnection

	checkconnected = call dll (wininet,"InternetCheckConnectionA","<your website/FTP site>",1,0)
	print checkconnected

endif
sync
wait key

if hConnection 
	r=call dll (wininet,"InternetCloseHandle", hConnection)
endif
If hInternetSession 
	r=call dll (wininet,"InternetCloseHandle", hInternetSession)
endif
delete dll wininet
end



Attached is the updated FTP dll and fixed GET FTP DIR$(). Below is example code that connects to an anonymous FTP site and displays the current ftp directory and lists the files under that directory:

+ Code Snippet
Rem Project: ftp_example_1
Rem Created: Wednesday, March 23, 2022
Rem ***** Main Source File *****
remstart
 uses fixed FTP dll containing fixed DBPro command FTP GET DIR$() 
remend
sync on : sync rate 30 : sync
//ftp.lpl.arizona.edu/pub/lpl/

url$="ftp.lpl.arizona.edu"
ftp connect url$,"anonymous","",1
success = get ftp failure()
print success 
if success = 1
 print GET FTP ERROR$() 
else 
 print "connected ok to ";url$;"."
endif

ftp set dir "pub/lpl/"
print "current ftp dir: ";get ftp dir$()
ftp find first
while get ftp file type()>-1
print "Type:";get ftp file type();
print " Name:";get ftp file name$();
   print " Size:";get ftp file size()
   ftp find next
endwhile

ftp set dir "pc_utils"
print "current ftp dir: ";get ftp dir$()
ftp find first
while get ftp file type()>-1
print "Type:";get ftp file type();
print " Name:";get ftp file name$();
   print " Size:";get ftp file size()
   ftp find next
endwhile
ftp disconnect 


wait key
end


editor keywords/help files added to dll talk post.
Posted: 19th Mar 2022 8:05
updated to connect to my website that contains files for Autowelder and list file content with attributes, this is a test only for DBPro, it's much more easier believe it or not) to do it in Visual Studio, just want to show that anything is possible in DBPro, it helps to understand some structures in VS such as the WIN32_FIND_FILES, MAX_PATH, FILETIME and loads more etc:

+ Code Snippet
sync on : sync rate 30 : sync

type _FILETIME
  dwLowDateTime as dword
  dwHighDateTime as dword
endtype 

type _WIN32_FIND_DATA
  dwFileAttributes as dword 		`0
  ftCreationTime as _FILETIME 		`4 8
  ftLastAccessTime as _FILETIME 	`12 16
  ftLastWriteTime as _FILETIME 		`20 24
  nFileSizeHigh as dword 			`28 
  nFileSizeLow as dword 			`32
  dwReserved0 as dword 				`36
  dwReserved1 as dword 				`40
  cFileName as string 				`44 - 44+260
  cAlternateFileName as string 	 	`44+260+14
  //dwFileType as dword // Obsolete. Do not use.
  //dwCreatorType as dword // Obsolete. Do not use
  //wFinderFlags as word  // Obsolete. Do not use
endtype

#constant WINDOW_NORMAL   13565952
#constant INTERNET_OPEN_TYPE_PRECONFIG 0 // use registry configuration
#constant INTERNET_OPEN_TYPE_DIRECT    1 // direct to net
#constant INTERNET_OPEN_TYPE_PROXY     3 // via named proxy
#constant INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 4 // prevent using java/script/INS
#constant INTERNET_DEFAULT_FTP_PORT 21 
#constant INTERNET_SERVICE_FTP 1     // FTP service.
#constant INTERNET_SERVICE_GOPHER 2    // Gopher service.
#constant INTERNET_SERVICE_HTTP 3    // HTTP service.
#constant INTERNET_FLAG_PASSIVE 0x08000000 // FTP PASSIVE 

`WIN32_FIND_DATA file attributes
#constant FILE_ATTRIBUTE_READONLY 1 //(0x1)	A file that is read-only. Applications can read the file, but cannot write to it or delete it. This attribute is not honored on directories. For more information, see You cannot view or change the Read-only or the System attributes of folders in Windows Server 2003, in Windows XP, in Windows Vista or in Windows 7.
#constant FILE_ATTRIBUTE_HIDDEN 2 //(0x2) The file or directory is hidden. It is not included in an ordinary directory listing.
#constant FILE_ATTRIBUTE_SYSTEM 4 //(0x4) A file or directory that the operating system uses a part of, or uses exclusively.
#constant FILE_ATTRIBUTE_DIRECTORY 16 //(0x10) The handle that identifies a directory.
#constant FILE_ATTRIBUTE_ARCHIVE 32 //(0x20) A file or directory that is an archive file or directory. Applications typically use this attribute to mark files for backup or removal .
#constant FILE_ATTRIBUTE_DEVICE 64 //(0x40) This value is reserved for system use.
#constant FILE_ATTRIBUTE_NORMAL 128 //(0x80) A file that does not have other attributes set. This attribute is valid only when used alone.
#constant FILE_ATTRIBUTE_TEMPORARY 256 //(0x100) A file that is being used for temporary storage. File systems avoid writing data back to mass storage if sufficient cache memory is available, because typically, an application deletes a temporary file after the handle is closed. In that scenario, the system can entirely avoid writing the data. Otherwise, the data is written after the handle is closed.
#constant FILE_ATTRIBUTE_SPARSE_FILE 512 //(0x200) A file that is a sparse file.
#constant FILE_ATTRIBUTE_REPARSE_POINT 1024 //(0x400) A file or directory that has an associated reparse point, or a file that is a symbolic link.
#constant FILE_ATTRIBUTE_COMPRESSED 2048 //(0x800) A file or directory that is compressed. For a file, all of the data in the file is compressed. For a directory, compression is the default for newly created files and subdirectories.
#constant FILE_ATTRIBUTE_OFFLINE 4096 //(0x1000) The data of a file is not available immediately. This attribute indicates that the file data is physically moved to offline storage. This attribute is used by Remote Storage, which is the hierarchical storage management software. Applications should not arbitrarily change this attribute.
#constant FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 8192 //(0x2000)The file or directory is not to be indexed by the content indexing service.
#constant FILE_ATTRIBUTE_ENCRYPTED 16384 // (0x4000) A file or directory that is encrypted. For a file, all data streams in the file are encrypted. For a directory, encryption is the default for newly created files and subdirectories.
#constant FILE_ATTRIBUTE_INTEGRITY_STREAM 32768 //(0x8000) The directory or user data stream is configured with integrity (only supported on ReFS volumes). It is not included in an ordinary directory listing. The integrity setting persists with the file if it's renamed. If a file is copied the destination file will have integrity set if either the source file or destination directory have integrity set.
#constant FILE_ATTRIBUTE_VIRTUAL 65536 //(0x10000) This value is reserved for system use.
#constant FILE_ATTRIBUTE_NO_SCRUB_DATA 131072 //(0x20000) The user data stream not to be read by the background data integrity scanner (AKA scrubber). When set on a directory it only provides inheritance. This flag is only supported on Storage Spaces and ReFS volumes. It is not included in an ordinary directory listing.
#constant FILE_ATTRIBUTE_RECALL_ON_OPEN 262144 //(0x40000) This attribute only appears in directory enumeration classes (FILE_DIRECTORY_INFORMATION, FILE_BOTH_DIR_INFORMATION, etc.). When this attribute is set, it means that the file or directory has no physical representation on the local system; the item is virtual. Opening the item will be more expensive than normal, e.g. it will cause at least some of it to be fetched from a remote store.
#constant FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS 4194304 //(0x400000) When this attribute is set, it means that the file or directory is not fully present locally. For a file that means that not all of its data is on local storage (e.g. it may be sparse with some data still in remote storage). For a directory it means that some of the directory contents are being virtualized from another location. Reading the file / enumerating the directory will be more expensive than normal, e.g. it will cause at least some of the file/directory content to be fetched from a remote store. Only kernel-mode callers can set this bit.

HttpAgent as string = "FTP Session"
NullString as string = ""

sServerName as string = "<your site>"
nServerPort as integer = INTERNET_DEFAULT_FTP_PORT  
sUsername as string = "<your login>" 
sPassword as string = "your password"
lService as integer = INTERNET_SERVICE_FTP
lFlags as integer = INTERNET_FLAG_PASSIVE
lContext as dword = 0

wininet = find free dll()
load dll "wininet.dll", wininet
if dll exist(1)=1 
	print "dll exists and loaded ok."
else
	end
endif

`ioaexists=dll call exist(wininet,"InternetOpenA")
`print "InternetOpenA exists:" ; ioaexists
hInternetSession as dword
hInternetSession = call dll(wininet,"InternetOpenA", HttpAgent, INTERNET_OPEN_TYPE_DIRECT, "", "" , 0) 
`print "hInternetSession: ";hInternetSession

if hInternetSession > 0 
	`icaexist=dll call exist(wininet,"InternetConnectA")
	`print "InternetConnectA exists: ";icaexist
	hConnection as dword
	hConnection=call dll(wininet,"InternetConnectA", hInternetSession, sServerName, nServerPort, sUsername, sPassword, lService, lFlags, lContext ) 
	print "FTP site connection handle: ";hConnection

	checkconnected = call dll (wininet,"InternetCheckConnectionA","<your website/FTP site>",1,0)
	print checkconnected
	
	if checkconnected = 1
	
		success=call dll (wininet,"FtpSetCurrentDirectoryA",hConnection,"AutoWelder")
		print success

		`dim fdata(320) as _WIN32_FIND_DATA
		`aryptr=get arrayptr(fdata())
		make memblock 1,320
		mptr=get memblock ptr (1)
		
		hFirstFile as dword
		hNextFile as dword
		hFirstFile = call dll (wininet,"FtpFindFirstFileA",hConnection,"",mptr ,0,0)

		`print hNextFile;" , ";mptr //.dwFileAttributes
		`print "dwFileAttributes: ";peek dword(mptr)
		`print "ftCreationTime: ";peek dword(mptr+4)
		`print "ftCreationTime: ";peek dword(mptr+8)
		`print "ftLastAccessTime: ";peek dword(mptr+12)
		`print "ftLastAccessTime: ";peek dword(mptr+16)
		`print "ftLastWriteTime: ";peek dword(mptr+20) 
		`print "ftLastWriteTime: ";peek dword(mptr+24)
		`print "nFileSizeHigh: ";peek dword(mptr+28)
		`print "nFileSizeLow: ";peek dword(mptr+32)
		`print "dwReserved0: ";peek dword(mptr+36)
		`print "dwReserved1: ";peek dword(mptr+40)
		print "cFileName: ";peek string(mptr+44,259)
		`print "cAlternateFileName: ";peek string(mptr+44+259+14)
		`print peek string(mptr+44+259+14)

		repeat
		hNextFile = call dll (wininet,"InternetFindNextFileA",hFirstFile,mptr)	
		`print hNextFile;" , ";mptr //.dwFileAttributes
		`print "dwFileAttributes: ";peek dword(mptr)
		`print "ftCreationTime: ";peek dword(mptr+4)
		`print "ftCreationTime: ";peek dword(mptr+8)
		`print "ftLastAccessTime: ";peek dword(mptr+12)
		`print "ftLastAccessTime: ";peek dword(mptr+16)
		`print "ftLastWriteTime: ";peek dword(mptr+20) 
		`print "ftLastWriteTime: ";peek dword(mptr+24)
		`print "nFileSizeHigh: ";peek dword(mptr+28)
		`print "nFileSizeLow: ";peek dword(mptr+32)
		`print "dwReserved0: ";peek dword(mptr+36)
		`print "dwReserved1: ";peek dword(mptr+40)
		print "cFileName: ";peek string(mptr+44,259)
		`print "cAlternateFileName: ";peek string(mptr+44+259+14)
		`print peek string(mptr+44+259+14)
		until hNextFile=0

		r=call dll (wininet,"InternetCloseHandle", hNextFile)
		r=call dll (wininet,"InternetCloseHandle", hFirstFile)

	endif
	
endif
sync
wait key

`r=call dll (wininet,"InternetCloseHandle", hNextFile)
`r=call dll (wininet,"InternetCloseHandle", hFirstFile)
`print r
`r=call dll (wininet,"InternetCloseHandle", hNextFile)
`print r


if hConnection 
	r=call dll (wininet,"InternetCloseHandle", hConnection)
endif
If hInternetSession 
	r=call dll (wininet,"InternetCloseHandle", hInternetSession)
endif
delete dll wininet
delete memblock 1
end




Obviously, I would put code into functions etc, this is just for demo purposes. maybe later will tidy up and add the functions.
I've used memblock here but could use Banks or ALLOC. Just need a pointer to the find_files data structure.

recursion would be good here also, remember if you want to "find first file" then you need to close the handle first and then change directory if you need to and then do a "find first file " then "find next file". This is basically the same as the DBPro commands FIND FIRST and FIND NEXT, it's just "stolen" from the wininet.dll
Posted: 19th Mar 2022 18:23
another update, this time converting a date from FILETIME format to SYSTEMTIME format, see example code which I will be expnading over the coming few days.

+ Code Snippet
sync on : sync rate 30 : sync

type _FILETIME
  dwLowDateTime as dword
  dwHighDateTime as dword
endtype 

type _SYSTEMTIME
  wYear as WORD  		`0
  wMonth as WORD 		`2
  wDayOfWeek as WORD 	`4
  wDay as WORD 			`6
  wHour as WORD 		`8
  wMinute as WORD 		`10
  wSecond as WORD 		`12
  wMilliseconds as WORD `14
endtype

type _WIN32_FIND_DATA
  dwFileAttributes as dword 		`0
  ftCreationTime as _FILETIME 		`4 8
  ftLastAccessTime as _FILETIME 	`12 16
  ftLastWriteTime as _FILETIME 		`20 24
  nFileSizeHigh as dword 			`28 
  nFileSizeLow as dword 			`32
  dwReserved0 as dword 				`36
  dwReserved1 as dword 				`40
  cFileName as string 				`44 - 44+260
  cAlternateFileName as string 	 	`44+260+14
  //dwFileType as dword // Obsolete. Do not use.
  //dwCreatorType as dword // Obsolete. Do not use
  //wFinderFlags as word  // Obsolete. Do not use
endtype

#constant WINDOW_NORMAL   13565952
#constant INTERNET_OPEN_TYPE_PRECONFIG 0 // use registry configuration
#constant INTERNET_OPEN_TYPE_DIRECT    1 // direct to net
#constant INTERNET_OPEN_TYPE_PROXY     3 // via named proxy
#constant INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 4 // prevent using java/script/INS
#constant INTERNET_DEFAULT_FTP_PORT 21 
#constant INTERNET_SERVICE_FTP 1     // FTP service.
#constant INTERNET_SERVICE_GOPHER 2    // Gopher service.
#constant INTERNET_SERVICE_HTTP 3    // HTTP service.
#constant INTERNET_FLAG_PASSIVE 0x08000000 // FTP PASSIVE 

`WIN32_FIND_DATA file attributes
#constant FILE_ATTRIBUTE_READONLY 1 //(0x1)	A file that is read-only. Applications can read the file, but cannot write to it or delete it. This attribute is not honored on directories. For more information, see You cannot view or change the Read-only or the System attributes of folders in Windows Server 2003, in Windows XP, in Windows Vista or in Windows 7.
#constant FILE_ATTRIBUTE_HIDDEN 2 //(0x2) The file or directory is hidden. It is not included in an ordinary directory listing.
#constant FILE_ATTRIBUTE_SYSTEM 4 //(0x4) A file or directory that the operating system uses a part of, or uses exclusively.
#constant FILE_ATTRIBUTE_DIRECTORY 16 //(0x10) The handle that identifies a directory.
#constant FILE_ATTRIBUTE_ARCHIVE 32 //(0x20) A file or directory that is an archive file or directory. Applications typically use this attribute to mark files for backup or removal .
#constant FILE_ATTRIBUTE_DEVICE 64 //(0x40) This value is reserved for system use.
#constant FILE_ATTRIBUTE_NORMAL 128 //(0x80) A file that does not have other attributes set. This attribute is valid only when used alone.
#constant FILE_ATTRIBUTE_TEMPORARY 256 //(0x100) A file that is being used for temporary storage. File systems avoid writing data back to mass storage if sufficient cache memory is available, because typically, an application deletes a temporary file after the handle is closed. In that scenario, the system can entirely avoid writing the data. Otherwise, the data is written after the handle is closed.
#constant FILE_ATTRIBUTE_SPARSE_FILE 512 //(0x200) A file that is a sparse file.
#constant FILE_ATTRIBUTE_REPARSE_POINT 1024 //(0x400) A file or directory that has an associated reparse point, or a file that is a symbolic link.
#constant FILE_ATTRIBUTE_COMPRESSED 2048 //(0x800) A file or directory that is compressed. For a file, all of the data in the file is compressed. For a directory, compression is the default for newly created files and subdirectories.
#constant FILE_ATTRIBUTE_OFFLINE 4096 //(0x1000) The data of a file is not available immediately. This attribute indicates that the file data is physically moved to offline storage. This attribute is used by Remote Storage, which is the hierarchical storage management software. Applications should not arbitrarily change this attribute.
#constant FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 8192 //(0x2000)The file or directory is not to be indexed by the content indexing service.
#constant FILE_ATTRIBUTE_ENCRYPTED 16384 // (0x4000) A file or directory that is encrypted. For a file, all data streams in the file are encrypted. For a directory, encryption is the default for newly created files and subdirectories.
#constant FILE_ATTRIBUTE_INTEGRITY_STREAM 32768 //(0x8000) The directory or user data stream is configured with integrity (only supported on ReFS volumes). It is not included in an ordinary directory listing. The integrity setting persists with the file if it's renamed. If a file is copied the destination file will have integrity set if either the source file or destination directory have integrity set.
#constant FILE_ATTRIBUTE_VIRTUAL 65536 //(0x10000) This value is reserved for system use.
#constant FILE_ATTRIBUTE_NO_SCRUB_DATA 131072 //(0x20000) The user data stream not to be read by the background data integrity scanner (AKA scrubber). When set on a directory it only provides inheritance. This flag is only supported on Storage Spaces and ReFS volumes. It is not included in an ordinary directory listing.
#constant FILE_ATTRIBUTE_RECALL_ON_OPEN 262144 //(0x40000) This attribute only appears in directory enumeration classes (FILE_DIRECTORY_INFORMATION, FILE_BOTH_DIR_INFORMATION, etc.). When this attribute is set, it means that the file or directory has no physical representation on the local system; the item is virtual. Opening the item will be more expensive than normal, e.g. it will cause at least some of it to be fetched from a remote store.
#constant FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS 4194304 //(0x400000) When this attribute is set, it means that the file or directory is not fully present locally. For a file that means that not all of its data is on local storage (e.g. it may be sparse with some data still in remote storage). For a directory it means that some of the directory contents are being virtualized from another location. Reading the file / enumerating the directory will be more expensive than normal, e.g. it will cause at least some of the file/directory content to be fetched from a remote store. Only kernel-mode callers can set this bit.

HttpAgent as string = "FTP Session"
NullString as string = ""

sServerName as string = "your website . com or IP address"
nServerPort as integer = INTERNET_DEFAULT_FTP_PORT  
sUsername as string = "your login id" 
sPassword as string = "your login password"
lService as integer = INTERNET_SERVICE_FTP
lFlags as integer = INTERNET_FLAG_PASSIVE
lContext as dword = 0

wininet = find free dll()
load dll "wininet.dll", wininet
if dll exist(1)=1 
	print "dll exists and loaded ok."
else
	end
endif

coredll = find free dll()
load dll "kernel32.dll", coredll
if dll exist(1)=1 
	print "dll exists and loaded ok."
else
	end
endif
fttstexists=dll call exist(coredll,"FileTimeToSystemTime")
print "FileTimeToSystemTime exists:" ; fttstexists

`ioaexists=dll call exist(wininet,"InternetOpenA")
`print "InternetOpenA exists:" ; ioaexists
hInternetSession as dword
hInternetSession = call dll(wininet,"InternetOpenA", HttpAgent, INTERNET_OPEN_TYPE_DIRECT, "", "" , 0) 
`print "hInternetSession: ";hInternetSession

if hInternetSession > 0 
	`icaexist=dll call exist(wininet,"InternetConnectA")
	`print "InternetConnectA exists: ";icaexist
	hConnection as dword
	hConnection=call dll(wininet,"InternetConnectA", hInternetSession, sServerName, nServerPort, sUsername, sPassword, lService, lFlags, lContext ) 
	print "FTP site connection handle: ";hConnection

	checkconnected = call dll (wininet,"InternetCheckConnectionA","<your website/FTP site>",1,0)
	print checkconnected
	
	if checkconnected = 1
	
		success=call dll (wininet,"FtpSetCurrentDirectoryA",hConnection,"AutoWelder")
		print success

		`dim fdata(320) as _WIN32_FIND_DATA
		`aryptr=get arrayptr(fdata())
		make memblock 1,320
		mptr=get memblock ptr (1)
		
		make memblock 2,16
		stptr = get memblock ptr (2)
		 
		hFirstFile as dword
		hNextFile as dword
		rb as boolean ` return as boolean
		hFirstFile = call dll (wininet,"FtpFindFirstFileA",hConnection,"",mptr ,0,0)

		`print hNextFile;" , ";mptr //.dwFileAttributes
		`print "dwFileAttributes: ";peek dword(mptr)
		`print "ftCreationTime: ";peek dword(mptr+4)
		`print "ftCreationTime: ";peek dword(mptr+8)
		`print "ftLastAccessTime: ";peek dword(mptr+12)
		`print "ftLastAccessTime: ";peek dword(mptr+16)
		print "ftLastWriteTime: ";peek dword(mptr+20) 
		`print "ftLastWriteTime: ";peek dword(mptr+24)
		`print "nFileSizeHigh: ";peek dword(mptr+28)
		`print "nFileSizeLow: ";peek dword(mptr+32)
		`print "dwReserved0: ";peek dword(mptr+36)
		`print "dwReserved1: ";peek dword(mptr+40)
		print "cFileName: ";peek string(mptr+44,259)
		`print "cAlternateFileName: ";peek string(mptr+44+259+14)
		`print peek string(mptr+44+259+14)
		rb = call dll (coredll,"FileTimeToSystemTime",mptr+20,stptr)
		print "rb: ";rb
		print "wYear: ";peek word(stptr+0)				`0
		print "wMonth: ";peek word(stptr+2)				`2
		print "wDayOfWeek: ";peek word(stptr+4)		 	`4
		print "wDay: ";peek word(stptr+6) 				`6
		print "wHour: ";peek word(stptr+8) 				`8
		print "wMinute: ";peek word(stptr+10)			`10
		print "wSecond: ";peek word(stptr+12)			`12
		print "wMilliseconds: ";peek word(stptr+14) 	`14

		`repeat
		hNextFile = call dll (wininet,"InternetFindNextFileA",hFirstFile,mptr)	
		`print hNextFile;" , ";mptr //.dwFileAttributes
		`print "dwFileAttributes: ";peek dword(mptr)
		`print "ftCreationTime: ";peek dword(mptr+4)
		`print "ftCreationTime: ";peek dword(mptr+8)
		`print "ftLastAccessTime: ";peek dword(mptr+12)
		`print "ftLastAccessTime: ";peek dword(mptr+16)
		print "ftLastWriteTime: ";peek dword(mptr+20) 
		`print "ftLastWriteTime: ";peek dword(mptr+24)
		`print "nFileSizeHigh: ";peek dword(mptr+28)
		`print "nFileSizeLow: ";peek dword(mptr+32)
		`print "dwReserved0: ";peek dword(mptr+36)
		`print "dwReserved1: ";peek dword(mptr+40)
		print "cFileName: ";peek string(mptr+44,259)
		`print "cAlternateFileName: ";peek string(mptr+44+259+14)
		`print peek string(mptr+44+259+14)
		`until hNextFile=0

		rb = call dll (coredll,"FileTimeToSystemTime",mptr+20,stptr)
		print "rb: ";rb
		print "wYear: ";peek word(stptr+0)				`0
		print "wMonth: ";peek word(stptr+2)				`2
		print "wDayOfWeek: ";peek word(stptr+4)		 	`4
		print "wDay: ";peek word(stptr+6) 				`6
		print "wHour: ";peek word(stptr+8) 				`8
		print "wMinute: ";peek word(stptr+10)			`10
		print "wSecond: ";peek word(stptr+12)			`12
		print "wMilliseconds: ";peek word(stptr+14) 	`14


		r=call dll (wininet,"InternetCloseHandle", hNextFile)
		r=call dll (wininet,"InternetCloseHandle", hFirstFile)

	endif
	
endif
sync
wait key

`r=call dll (wininet,"InternetCloseHandle", hNextFile)
`r=call dll (wininet,"InternetCloseHandle", hFirstFile)
`print r
`r=call dll (wininet,"InternetCloseHandle", hNextFile)
`print r


if hConnection 
	r=call dll (wininet,"InternetCloseHandle", hConnection)
endif
If hInternetSession 
	r=call dll (wininet,"InternetCloseHandle", hInternetSession)
endif
delete dll wininet
delete memblock 1
delete memblock 2
end


Again to get a pointer to the SYSTEMTIME format I have created a 2nd memblock , grabbed the pointer and the call to the "FileTimeToSystemTime" function ("kernel32.dll"), populates the 2nd memblock and peek'ing it returns the various date/time values
Posted: 20th Mar 2022 7:44
the code below, obtains the current FTP directory, the DBP command GET FTP DIR$() doesn't work, this does:
you can use the "GETLASTERROR" function from the kernel32.dll if you want to get the error code produced from any function call that returns 0 (FALSE).
Notice I have replaced memblock with ALLOC ZEROED to reduce number of code lines and is more professional / efficient. I use FREE command to delete the allocated memory at the end.

+ Code Snippet
sync on : sync rate 30 : sync
type _FILETIME
  dwLowDateTime as dword
  dwHighDateTime as dword
endtype 

type _WIN32_FIND_DATA
  dwFileAttributes as dword 	`0
  ftCreationTime as _FILETIME 	`4 8
  ftLastAccessTime as _FILETIME `12 16
  ftLastWriteTime as _FILETIME 	`20 24
  nFileSizeHigh as dword 		`28 
  nFileSizeLow as dword 		`32
  dwReserved0 as dword 			`36
  dwReserved1 as dword 			`40
  cFileName as string 			`44+MAX_PATH-1 i.e. 260-1 = 259
  cAlternateFileName as string 	`44+259+14
  //dwFileType as dword // Obsolete. Do not use.
  //dwCreatorType as dword // Obsolete. Do not use
  //wFinderFlags as word  // Obsolete. Do not use
endtype

#constant MAX_PATH 260
#constant SIZEOF_WIN32_FIND_DATA 320
#constant WINDOW_NORMAL   13565952
#constant INTERNET_OPEN_TYPE_PRECONFIG 0 // use registry configuration
#constant INTERNET_OPEN_TYPE_DIRECT    1 // direct to net
#constant INTERNET_OPEN_TYPE_PROXY     3 // via named proxy
#constant INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 4 // prevent using java/script/INS
#constant INTERNET_DEFAULT_FTP_PORT 21 
#constant INTERNET_SERVICE_FTP 1     // FTP service.

#constant INTERNET_SERVICE_GOPHER 2    // Gopher service.
#constant INTERNET_SERVICE_HTTP 3    // HTTP service.
#constant INTERNET_FLAG_PASSIVE 0x08000000 // FTP PASSIVE 
HttpAgent as string = "FTP Session"
NullString as string = ""

sServerName as string = "<your website / IP address>"
nServerPort as integer = INTERNET_DEFAULT_FTP_PORT  
sUsername as string = "<your login id>" 
sPassword as string = "<your password>"
lService as integer = INTERNET_SERVICE_FTP
lFlags as integer = INTERNET_FLAG_PASSIVE
lContext as dword = 0

wininet = find free dll()
load dll "wininet.dll", wininet
if dll exist(1)=1 
	print "dll exists and loaded ok."
else
	end
endif

coredll = find free dll()
load dll "coredll.dll", coredll
if dll exist(1)=1 
	print "dll exists and loaded ok."
else
	end
endif

kerneldll = find free dll()
load dll "kernel32.dll", kerneldll
if dll exist(1)=1 
	print "dll exists and loaded ok."
else
	end
endif

hInternetSession as dword
hInternetSession = call dll(wininet,"InternetOpenA", HttpAgent, INTERNET_OPEN_TYPE_DIRECT, "", "" , 0) 

if hInternetSession > 0 
	hConnection as dword
	hConnection=call dll(wininet,"InternetConnectA", hInternetSession, sServerName, nServerPort, sUsername, sPassword, lService, lFlags, lContext ) 
	print "FTP site connection handle: ";hConnection

	checkconnected = call dll (wininet,"InternetCheckConnectionA","<your website>",1,0)
	
	if checkconnected = 1
	
		success=call dll (wininet,"FtpSetCurrentDirectoryA",hConnection,"AutoWelder/media")

		pcdir=alloc zeroed(MAX_PATH)
		pbufflen=alloc(4)
		poke dword pbufflen,MAX_PATH
		r = call dll(wininet,"FtpGetCurrentDirectoryA",hConnection,pcdir,pbufflen)
		print "r: ";r 
		
		buflen=peek dword(pbufflen,0)
		print "Buffer length: ";buflen
		bufferstring as string
		bufferstring = peek string(pcdir,buflen) 
		print "current ftp dir: ";bufferstring
		`lasterr as dword
		`lasterr=call dll(kerneldll,"GetLastError")
		`if lasterr >0
		`	print lasterr
		`endif
		pmem = alloc(SIZEOF_WIN32_FIND_DATA)
		hFirstFile as dword
		hNextFile as dword
		hFirstFile = call dll (wininet,"FtpFindFirstFileA",hConnection,"",pmem ,0,0)	
		f$=peek string(pmem+44,MAX_PATH)
		if f$ <> "." and f$ <> ".."
			print hFirstFile;" , ";f$
		endif

		repeat
		hNextFile = call dll (wininet,"InternetFindNextFileA",hFirstFile,pmem)	
		if hNextFile >0
			f$=peek string(pmem+44,MAX_PATH)
			if f$ <> "." and f$ <> ".."
				print hNextFile;" , ";f$
			endif
		else
		endif
		until hNextFile =0
		
		r=call dll (wininet,"InternetCloseHandle", hFirstFile)
		`print r
		r=call dll (wininet,"InternetCloseHandle", hNextFile)
		`print r
	endif
endif
sync
wait key

if hConnection 
	r=call dll (wininet,"InternetCloseHandle", hConnection)
endif
If hInternetSession 
	r=call dll (wininet,"InternetCloseHandle", hInternetSession)
endif
delete dll wininet

free pcdir
free pbufflen
free pmem

end


Actually, I will probably fix some DBPro commands that don't work in the DBPRO github source code. Starting with this one.
Posted: 21st Mar 2022 5:29
Now, if like me you have the google drive ftp adaptor installed and working, you don't need filezilla to look at your files, you can connect and view your files using above code, but with following credentials as per github google drive adaptor instructions:

sServerName as string = "localhost"
nServerPort as integer = 1821
sUsername as string = "user"
sPassword as string = "user"

and then connect using:
checkconnected = call dll (wininet,"InternetCheckConnectionA","http://google.com",1,0)

https://github.com/andresoviedo/google-drive-ftp-adapter

so if you want to avoid having to login into your gdrive account and being asked every time to verify using your mobile phone, go to the github link first and follow the instructions (there is also a youtube video on how to do same).
link to you tube video:
https://www.youtube.com/watch?v=lXvfhYRPRX0
Posted: 22nd Mar 2022 6:30
the code now uses functions, you can use either ALLOC / MEMBLOCK (GET MEMBLOCK PTR) / BANK (GET BANK PTR) or DIM and then obtain the array pointer using GET ARRAYPTR. you need IanM Matrix1Util plugin for this.
Change the code if you want, make it better. I'm going to be updating the DBPRO source code to fix some of the commands that don't work. I've already noticed in the source code that the code is wrong for GET FTP DIR$(). This is easily fixed.
A few months back I updated the memblocks source code to allow more memblocks, If I recall I added 10,000 as a tester and compiles / works fine so far. There is so much that can be done with the source code. I've seen quite a lot of mistakes in places and/or inconsistencies, memory leaks etc.

I haven't put the dll calls to close the handles in yet, maybe you guys/girls can have a go. But I will add later date. Im off to do working day and then update DBPro code etc.

+ Code Snippet
sync on : sync rate 30 : sync
type _FILETIME
  dwLowDateTime as dword
  dwHighDateTime as dword
endtype 

type _WIN32_FIND_DATA
  dwFileAttributes as dword 	`0
  ftCreationTime as _FILETIME 	`4 8
  ftLastAccessTime as _FILETIME `12 16
  ftLastWriteTime as _FILETIME 	`20 24
  nFileSizeHigh as dword 		`28 
  nFileSizeLow as dword 		`32
  dwReserved0 as dword 			`36
  dwReserved1 as dword 			`40
  cFileName as string 			`44+MAX_PATH-1 i.e. 260-1 = 259
  cAlternateFileName as string 	`44+259+14
  //dwFileType as dword // Obsolete. Do not use.
  //dwCreatorType as dword // Obsolete. Do not use
  //wFinderFlags as word  // Obsolete. Do not use
endtype

#constant MAX_PATH 260
#constant SIZEOF_WIN32_FIND_DATA 320
#constant WINDOW_NORMAL   13565952
#constant INTERNET_OPEN_TYPE_PRECONFIG 0 // use registry configuration
#constant INTERNET_OPEN_TYPE_DIRECT    1 // direct to net
#constant INTERNET_OPEN_TYPE_PROXY     3 // via named proxy
#constant INTERNET_OPEN_TYPE_PRECONFIG_WITH_NO_AUTOPROXY 4 // prevent using java/script/INS
#constant INTERNET_DEFAULT_FTP_PORT 21 
#constant INTERNET_SERVICE_FTP 1     // FTP service.
#constant INTERNET_SERVICE_GOPHER 2    // Gopher service.
#constant INTERNET_SERVICE_HTTP 3    // HTTP service.
#constant INTERNET_FLAG_PASSIVE 0x08000000 // FTP PASSIVE 

`global pFindData as dword
global hNextFile as dword
global hFirstFile as dword

HttpAgent as string = "FTP Session"
NullString as string = ""

site as string = "<your site>"
sServerName as string = "<your server name>"
nServerPort as integer = INTERNET_DEFAULT_FTP_PORT  
sUsername as string = "<your user id>" 
sPassword as string = "<your password>"
`sServerName as string = "localhost" // for google drive ftp adapter
`nServerPort as integer = 1821  // for google drive ftp adapter
`sUsername as string = "user" // for google drive ftp adapter
`sPassword as string = "user" // for google drive ftp adapter
lService as integer = INTERNET_SERVICE_FTP
lFlags as integer = INTERNET_FLAG_PASSIVE
lContext as dword = 0

wininet = find free dll()
load dll "wininet.dll", wininet
if dll exist(1)=1 
	print "dll exists and loaded ok."
else
	end
endif

kerneldll = find free dll()
load dll "kernel32.dll", kerneldll
if dll exist(1)=1 
	print "dll exists and loaded ok."
else
	end
endif

hInternetSession as dword
hInternetSession = InternetOpen(wininet, HttpAgent, INTERNET_OPEN_TYPE_DIRECT, "", "" , 0) 
print "hInternetSession: ";hInternetSession
if hInternetSession > 0 
	hConnection as dword
	hConnection=SiteConnect(wininet, hInternetSession, sServerName, nServerPort, sUsername, sPassword, lService, lFlags, lContext)
	print "hConnection: ";hConnection

	checkconnected = SiteConnected(wininet,site,1,0)
	print checkconnected	
	
	if checkconnected = 1
		success=SiteSetDir(wininet,hConnection,"AutoWelder")
		print "set folder success: ";success
		curdir$=SiteGetDir(wininet, hConnection )
		print curdir$

		f$=SiteFirstFile(wininet, hConnection)
		print f$,  hFirstFile
		
		repeat
			f$=SiteNextFile(wininet, hConnection)
			print hNextFile;" , ";f$
		until hNextFile =0
		
		r=call dll (wininet,"InternetCloseHandle", hFirstFile)
		r=call dll (wininet,"InternetCloseHandle", hNextFile)
	endif
endif
sync
wait key

if hConnection 
	r=call dll (wininet,"InternetCloseHandle", hConnection)
endif
If hInternetSession 
	r=call dll (wininet,"InternetCloseHandle", hInternetSession)
endif
delete dll wininet
delete dll kerneldll
`free pFindData

end

function InternetOpen(dllid, sAgent as string , lAccessType as integer , sProxyName as string , sProxyBypass as string , lFlags as integer )
	h as dword
	h=call dll(dllid,"InternetOpenA", sAgent, lAccessType, sProxyName, sProxyBypass , lFlags)
endfunction h

function SiteConnect(dllid, hInternetSession, sServerName as string , nServerPort as integer , sUsername as string , sPassword as string , lService as integer , lFlags as integer , lContext as dword )
	h as dword
	h=call dll(dllid,"InternetConnectA", hInternetSession, sServerName, nServerPort, sUsername, sPassword, lService, lFlags, lContext )
endfunction h

function SiteConnected(dllid, lpszUrl as string , dwFlags as integer , dwReserved as integer )
	b as boolean
	b = call dll (dllid,"InternetCheckConnectionA", lpszUrl, dwFlags, dwReserved)
endfunction b

function SiteSetDir(dllid, hConnect, folder as string )
	b as boolean
	b=call dll (dllid,"FtpSetCurrentDirectoryA",hConnect,folder)
endfunction b

function SiteGetDir(dllid, hConnect )
	pCurrentDir as dword `pointer to Current Folder String
	pBuffLen as dword `pointer to string buffer maximum length
	lpszDirectory as string `buffer string containing the site current folder
	pCurrentDir=alloc zeroed(MAX_PATH)
	pbufflen=alloc(4)
	poke dword pBuffLen,MAX_PATH
	r = call dll(dllid,"FtpGetCurrentDirectoryA", hConnect, pCurrentDir, pBuffLen)
	buflen=peek dword(pBuffLen)
	lpszDirectory = peek string(pCurrentDir,buflen) 
	free pCurrentDir
	free pBuffLen
endfunction lpszDirectory

function SiteFirstFile(dllid, hConnect)
	`pFindData = alloc(SIZEOF_WIN32_FIND_DATA)
	dim FindData(SIZEOF_WIN32_FIND_DATA)
	pFindData = get arrayptr(FindData())
	searchfile as string = ""
	flags =0
	context = 0
	ff as string
	global hFirstFile as dword
	hFirstFile = call dll(dllid, "FtpFindFirstFileA", hConnect, searchfile, pFindData, flags, context)	
	if hFirstFile > 0 then ff=peek string(pFindData+44,MAX_PATH) ` +44 is the offset pointing to the filename
	undim FindData()
endfunction ff

function SiteNextFile(dllid, hConnect)
`	pFindData = alloc(SIZEOF_WIN32_FIND_DATA)
	dim FindData(SIZEOF_WIN32_FIND_DATA)
	pFindData = get arrayptr(FindData())
	ff as string
	hNextFile = call dll (dllid,"InternetFindNextFileA",hFirstFile,pFindData)	
	if hNextFile > 0 then ff=peek string(pFindData+44,MAX_PATH) ` +44 is the offset pointing to the filename
	undim FindData()
endfunction ff
Posted: 23rd Mar 2022 16:13
fixed the GET FTP DIR$() in the DBPro source code, the code was originally a copy of the GetFileName function, terrible, still glad it's fixed.
If anyone wants the updated DLL , I will place it on the 1st post when it's finalised, need to double check and add some error trapping/fail safe code.
I will put this notice on the main DBPro Professional board.
Posted: 24th Mar 2022 6:11
updated 2nd code , just to show change to another directory , return the current directory using the fixed GET FTP DIR$ command and listing the directory.
adding the updated FTP dll to the dll boards.
Posted: 25th Mar 2022 10:01
adding commands to return date stamps i.e. create, access and modification datetime stamps.
Posted: 27th Mar 2022 6:51
the FTP datetime stamp commands are now in and working. I'm keeping the format the same as Matrix1Utils (IanM) for consistency. as my website files are unix based, there won't be any valid creation/access datetime stamps as unix doesn't keep track of them so only modification timestamps will show:

The commands are:

GET FTP FILE CREATETS$();
GET FTP FILE ACCESSTS$();
GET FTP FILE MODTS$()



Looking into other commands and updates/fixes etc. Not necessarily FTP related.
Posted: 27th Mar 2022 7:19
updated FTP dll with additional datetime stamp commands - just backup your old one and copy/paste in compiler / plugins ]. see 1st post @ link : https://forum.thegamecreators.com/thread/228370
Posted: 29th Mar 2022 7:48
small update to the ftp dll made and editor keywords / help files added. see link above.
Posted: 2nd Apr 2022 6:43
a few easy wininet commands until I get them into the FTP dll.

+ Code Snippet
success=call dll (wininet,"FtpSetCurrentDirectoryA",hConnection,"<your ftp folder>")
print "changed dir ok:: ";success
		
success=call dll (wininet,"FtpCreateDirectoryA",hConnection, "test")
print "created folder test ok: ";success
		
success=call dll (wininet,"FtpRemoveDirectoryA",hConnection, "test")
print "removed folder test ok: ";success
		
success=call dll (wininet,"FtpDeleteFileA",hConnection, "testdoconly.txt")
print "removed file testdoconly.txt ok: ";success