〜 ネットワーク 〜
サーバーにファイルをアップロード (要WININET.DLL)

HSP3からHSPInet.DLLが標準で同梱されており、
このDLLの命令を使うことでインターネット上のデータを取り込むことが出来ます。
便利なものですが、作成した実行ファイルと共にDLLを同梱する必要があるので、
様々な理由により「なんとかDLLナシで実現できないか」と思う人たちの為の参考Tips。
HSPInet.DLLは、Windows標準搭載のWinInet.DLLのラッパーDLLなので、
WinInet.DLLのAPI関数を直接呼び出すことで、
HSPInet.DLLを同梱することなく実現させることが可能となります。

今回はFTPサーバーのリソースとしてファイルをアップロードするftpput命令に取って代わる
WinInet.DLLのAPI関数FtpPutFileを使ったサンプルモジュールを紹介します。
API関数FtpPutFileに指定するのは第1引数から順に、「セッションハンドル」「転送ファイル」
「作成リソース」「転送フラグ」「コールバック関数に渡すアプリケーション定義値」です。
セッションハンドルはサーバーと接続した際のログインセッションハンドルを、
転送ファイルはアップロード対象のファイル名(を格納した変数ポインタ)を、
作成リソースはアップロードしたリソースの保存ファイル名(を格納した変数のポインタ)を、
転送フラグは以下の転送方法を示す定義値を、
FTP_TRANSFER_TYPE_UNKNOWN0x0000デフォルトモード(バイナリー)で転送。
FTP_TRANSFER_TYPE_ASCIIINTERNET_FLAG_TRANSFER_ASCII0x0001テキストファイル用のアスキーモードで転送。
FTP_TRANSFER_TYPE_BINARYINTERNET_FLAG_TRANSFER_BINARY0x0002データそのままのバイナリーモードで転送。
コールバックする値は0を、それぞれ指定しましょう。 既に同名リソースが存在する場合は上書きされるので、 重要なリソースが誤って上書きされてしまわないように注意してください。 カレントディレクトリ以外にアップロードするには対象ディレクトリを変更する必要があります。 コチラを参考にしてカレントディレクトリを予め変更しておいてください。 尚、API関数FtpPutFileの戻り値は成功した(=1)か否(=0)かを示す真偽値です。 この値を元に転送成功・失敗を判断すると良いでしょう。

inetinit
[パラメータなし]インターネットサービスを開始するだけである為、パラメータは必要ない。

inetend
[パラメータなし]インターネットハンドルを解放するだけの為、パラメータは必要ない。
尚、終了時に自動的に呼び出されるので命令を実行する必要はない。

inetlogin サーバー, ユーザー情報, サービス, ポート, オプション
サーバーホストサーバーアドレスまたはIPアドレス文字列を指定する。
ユーザー情報ログインユーザー名とパスワードをコロンで区切った形式で指定する。
サービス接続するサービス(1:FTP 2:Gopher 3:HTTP)を指定する。
尚、省略すればFTP接続を行う。
ポート使用するTCP/IPポートを数値指定する。
オプションFTPでパッシブモード利用する時、HTTPでHTTPS通信する時は1を指定する。
それ以外の時は0または省略する。

inetlogout
[パラメータなし]サーバーとの接続を解除するだけの為、パラメータは必要ない。
尚、終了時に自動的に呼び出されるので命令を実行する必要はない。

ftpput 転送名, 保存名, 転送モード
転送名アップロードするファイルを指定する。尚、statには失敗(=0)か成功(=1)かのフラグが返る。
保存名保存するファイル名を指定する。
転送モード転送モード(0:バイナリー 1:アスキー)を指定する。省略時はバイナリーモード。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
	ll_libload wininet, "wininet.dll"
	ll_getproc InternetOpen, "InternetOpenA", wininet
	ll_getproc InternetCloseHandle, "InternetCloseHandle", wininet
	ll_getproc InternetConnect, "InternetConnectA", wininet
	ll_getproc FtpPutFile, "FtpPutFileA", wininet

#module
#deffunc inetinit
	mref stt, 64
	prm = 0, 0, 0, 0, 0
	agent = "hspbc"
	ll_getptr agent : ll_ret prm
	ll_callfunc prm, 5, InternetOpen@
	ll_ret hinet : stt = hinet
	return

#deffunc inetend onexit
	if hinet : ll_callfunc hinet, 1, InternetCloseHandle@
	return

#deffunc inetlogin str, str, int, int
	mref server, 32 : mref info, 33 : mref service, 2 : mref option, 3
	mref stt, 64
	instr i, info, ":"
	strlen i.1, info
	strmid user, info, , i
	strmid pass, info, i + 1, i.1 - i - 1
	if hinet = 0 : inetinit
	if user = "" : i.0 = 0 : else : ll_getptr user : ll_ret i.0
	if pass = "" : i.1 = 0 : else : ll_getptr pass : ll_ret i.1
	switch service
	case 2:  i.2 = 0x0002, 0 : swbreak
	case 3:  i.2 = 0x0003, 0 : swbreak
	default: i.2 = 0x0001, option ! 0 * 0x08000000
	swend
	ll_getptr server : ll_ret i.5
	prm = hinet, i.5, 0, i.0, i.1, i.2, i.3, 0
	ll_callfunc prm, 8, InternetConnect@
	ll_ret hsess : stt = hsess
	return

#deffunc inetlogout onexit
	if hsess : ll_callfunc hsess, 1, InternetCloseHandle@
	return	

#deffunc ftpput str, str, int
	mref putname, 32 : mref savename, 33 : mref mode, 2
	mref stt, 64
	prm = hsess, 0, 0, mode, 0
	ll_getptr putname : ll_ret prm.1
	ll_getptr savename : ll_ret prm.2
	ll_callfunc prm, 5, FtpPutFile@
	ll_ret prm : stt = prm
	return
#global

	sdim v, 128, 5
	pos  10,  10 : mes "FTPサーバー"
	pos 150,  10 : input v.0, 150, 22
	pos  10,  40 : mes "ユーザー名"
	pos 150,  40 : input v.1, 150, 22
	pos  10,  70 : mes "パスワード"
	pos 150,  70 : input v.2, 150, 22
	pos  10, 100 : mes "転送ファイル名"
	pos 150, 100 : input v.3, 250, 22
	pos 400, 100 : button "参照", *refer
	pos  10, 130 : mes "保存リソース名"
	pos 150, 130 : input v.4, 150, 22
	pos 150, 160 : button "転送", *connect
	stop

*refer
	dialog "", 16, "転送元ファイル"
	if stat {
		objprm 3, refstr
		getpath s, v.3, 8 // 配列(v.4)には格納できない(バグ?)
		objprm 5, s
	}
	stop

*connect
	inetlogin v, v.1 + ":" + v.2
	if stat {
		ftpput v.3, v.4
		if stat {
			dialog "転送しました"
		} else {
			dialog "接続には成功しましたがファイル転送に失敗しました"
		}
	} else {
		dialog "接続に失敗しました"
	}
	stop

inetinit
[パラメータなし]インターネットサービスを開始するだけである為、パラメータは必要ない。

inetend
[パラメータなし]インターネットハンドルを解放するだけの為、パラメータは必要ない。
尚、終了時に自動的に呼び出されるので命令を実行する必要はない。

inetlogin サーバー, ユーザー, パスワード, サービス, オプション
サーバーホストサーバーアドレスまたはIPアドレス文字列を指定する。
ユーザーログインユーザー名を指定する。
パスワードログインパスワードを指定する。
サービス接続するサービス(1:FTP 2:Gopher 3:HTTP)を指定する。
尚、省略すればFTP接続を行う。
オプションFTPでパッシブモード利用する時、HTTPでHTTPS通信する時は1を指定する。
それ以外の時は0または省略する。

inetlogout
[パラメータなし]サーバーとの接続を解除するだけの為、パラメータは必要ない。
尚、終了時に自動的に呼び出されるので命令を実行する必要はない。

ftpput 転送名, 保存名, 転送モード
転送名アップロードするファイルを指定する。尚、statには失敗(=0)か成功(=1)かのフラグが返る。
保存名保存するファイル名を指定する。
転送モード転送モード(0:バイナリー 1:アスキー)を指定する。省略時はバイナリーモード。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#uselib "wininet.dll"
#cfunc	global InternetOpen "InternetOpenA" sptr, int, int, int, int
#func	global InternetCloseHandle "InternetCloseHandle" int
#cfunc	global InternetConnect "InternetConnectA" int, sptr, int, int, int, int, int, int
#cfunc	global FtpPutFile "FtpPutFileA" int, sptr, sptr, int, int

#module
#deffunc inetinit
	hinet = InternetOpen("hspbc")
	return hinet

#deffunc inetend onexit
	if hinet : InternetCloseHandle hinet
	return

#deffunc inetlogin str server, str user, str pass, int service, int option, local i, local s
	if hinet = 0 : inetinit
	s = user, pass
	if user = "" : i.0 = 0 : else : i.0 = varptr(s.0)
	if pass = "" : i.1 = 0 : else : i.1 = varptr(s.1)
	switch service
	case 2:  i.2 = 0x0002, 0 : swbreak
	case 3:  i.2 = 0x0003, 0 : swbreak
	default: i.2 = 0x0001, (option ! 0) * 0x08000000
	swend
	hsess = InternetConnect(hinet, server, , i.0, i.1, i.2, i.3)
	return hsess

#deffunc inetlogout onexit
	if hsess : InternetCloseHandle hsess
	return

#deffunc ftpput str putname, str savename, int mode
	return FtpPutFile(hsess, putname, savename, mode)
#global

	sdim v, 128, 5
	pos  10,  10 : mes "FTPサーバー"
	pos 150,  10 : input v.0, 150, 20
	pos  10,  40 : mes "ユーザー名"
	pos 150,  40 : input v.1, 150, 20
	pos  10,  70 : mes "パスワード"
	pos 150,  70 : input v.2, 150, 20
	pos  10, 100 : mes "転送ファイル名"
	pos 150, 100 : input v.3, 250, 20
	pos 400, 100 : button gosub "参照", *refer
	pos  10, 130 : mes "保存リソース名"
	pos 150, 130 : input v.4, 150, 20
	pos 150, 160 : button gosub "転送", *connect
	stop

*refer
	dialog "", 16, "転送元ファイル"
	if stat {
		objprm 3, refstr
		objprm 5, getpath(refstr, 8)
	}
	return

*connect
	inetlogin v, v.1, v.2
	if stat {
		ftpput v.3, v.4
		if stat {
			dialog "転送しました"
		} else {
			dialog "接続には成功しましたがファイル転送に失敗しました"
		}
	} else {
		dialog "接続に失敗しました"
	}
	return