UWSCでDeflate圧縮する

http://zlib.net/で配布している1.2.8のDLLを埋め込んでみました。
DLLが大きいので、大きなスクリプトになっています。
174KBのスクリプトとか、、、アホかと。
なお、メモリーに乗り切らないような大きなデータは対象外です。


Zipファイル自体を扱うスクリプトはつけてませんが、zlibのDLLがあるので、やろうと思えばできそう。
(CRT依存部分が少し心配ですが)



スクリプト

Dllモジュールをさらに拡張した形としています。
今のところのDllモジュール決定版。
以下の機能となっています。

  • ネイティブスレッドの起動(Asmモジュール)
  • API呼び出しとGetLastError取得(旧Dllモジュール、I/F少し変えた)
  • DLLのスクリプト埋め込み(更新版Dllモジュール)
  • Deflate圧縮・Inflate展開(今回追加)
    • ネイティブコードのDeflate圧縮埋め込みが可能
    • DLLの圧縮埋め込みも可能
  • ファイルのメモリー読み込み(更新版Dllモジュールのおまけ)
    • DLLの圧縮Base64変換が可能

圧縮・展開が不要なら、元の方が短くて良いですね。


なお、「DFLT」で始まるデータは、Deflate圧縮されていると判定するので、そういうデータをDll.Setしたい場合には、注意が必要です。
テストコードで、ファイルの圧縮Base64変換が1MB程度を渡すと泣き言を言いますが、これは主に文字列変換のコストが高いためです。
圧縮だけであるなら、メモリーに問題なく乗る大きさであれば、なんら問題ありません。
とはいえ、問題なく乗る大きさは、意外に小さいですが、、、。
(プロセスメモリーは断片化しやすいので、まとめて取れる大きさは意外に小さい)


記事はここまで(以下はスクリプトのみ)


Dll.uws

OPTION EXPLICIT

IFB GET_UWSC_NAME = "Dll.uws" THEN

	//Dll.Debug = 2

	DIM test = INPUT("圧縮テストする長い文字列か、圧縮Base64変換するファイルをどうぞ")
	IFB FOPEN(test, F_EXISTS) THEN
		DIM tar = Dll.ReadFromFile(test)
		IFB Dll.Size(tar) > 1024 * 1024 THEN
			IFB MSGBOX("結構時間がかかりそうですが、よろしいですか?", BTN_YES OR BTN_NO) = BTN_NO THEN
				Dll.Dispose()
				EXIT
			ENDIF
		ENDIF
		DIM e = Dll.DeflateToString(tar)
		PRINT "圧縮Base64変換<#CR>" + e
		IFB Dll.Size(tar) <= 1024 * 1024 AND Dll.Size(tar) > 102400 THEN
			IFB MSGBOX("結構時間がかかりそうですが、元ファイルダンプしますか?", BTN_YES OR BTN_NO) = BTN_NO THEN
				Dll.Dispose()
				EXIT
			ENDIF
		ENDIF
		PRINT "<#CR>元ファイル<#CR>" + Dll.InflateToString(e, -1, Dll.CRYPT_STRING_HEXASCIIADDR)
		Dll.Free(tar)
	ELSE
		DIM enc = Dll.DeflateToString(test)
		MSGBOX("元の文字列:<#CR>" + test + "<#CR><#CR>変換後:<#CR>" + enc + "<#CR><#CR>圧縮率:" + LENGTH(enc) + "/" + LENGTH(test))
		DIM res = Dll.InflateToString(enc)
		IF test <> res THEN MSGBOX("Inflate error : " + res)
	ENDIF

	Dll.Dispose()
ENDIF


MODULE Dll
	PUBLIC hK32 = NULL
	PUBLIC Debug = 0

	DEF_DLL CreateThread(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD): DWORD: kernel32
	DEF_DLL WaitForSingleObject(DWORD, DWORD): DWORD: kernel32
	DEF_DLL CloseHandle(DWORD): bool: kernel32
	DEF_DLL GetExitCodeThread(DWORD, var DWORD): bool: kernel32
	DEF_DLL VirtualAlloc(DWORD, DWORD, DWORD, DWORD): DWORD: kernel32
	DEF_DLL VirtualFree(DWORD, DWORD, DWORD): bool: kernel32
	DEF_DLL GetProcAddress(DWORD, string): DWORD: kernel32
	DEF_DLL CryptStringToBinaryW(wstring,dword,dword,dword,var dword,var dword,var dword): BOOL: crypt32
	DEF_DLL LoadLibraryW(wstring): DWORD: kernel32
	DEF_DLL FreeLibrary(DWORD): BOOL: kernel32
	DEF_DLL CryptBinaryToStringW(DWORD,DWORD,DWORD,var wstring,var DWORD): BOOL: crypt32

	CONST WAIT_TIMEOUT = 258

	CONST CRYPT_STRING_BASE64HEADER        = $00000000
	CONST CRYPT_STRING_BASE64              = $00000001
	CONST CRYPT_STRING_BINARY              = $00000002
	CONST CRYPT_STRING_BASE64REQUESTHEADER = $00000003
	CONST CRYPT_STRING_HEX                 = $00000004
	CONST CRYPT_STRING_HEXASCII            = $00000005
	CONST CRYPT_STRING_BASE64_ANY          = $00000006
	CONST CRYPT_STRING_ANY                 = $00000007
	CONST CRYPT_STRING_HEX_ANY             = $00000008
	CONST CRYPT_STRING_BASE64X509CRLHEADER = $00000009
	CONST CRYPT_STRING_HEXADDR             = $0000000a
	CONST CRYPT_STRING_HEXASCIIADDR        = $0000000b
	CONST CRYPT_STRING_HEXRAW              = $0000000c
	CONST CRYPT_STRING_ASCII               = $00000010	// 勝手定義
	CONST CRYPT_STRING_HASHDATA            = $10000000
	CONST CRYPT_STRING_STRICT              = $20000000
	CONST CRYPT_STRING_NOCRLF              = $40000000
	CONST CRYPT_STRING_NOCR                = $80000000

	// Success
	CONST ELoadDLLResult_OK = 0
	// The read procedure we provided returned FALSE for a read request.
	CONST ELoadDLLResult_ReadProcError = 1
	// Bad DLL file. Wrong header or a similar error.
	CONST ELoadDLLResult_InvalidImage = 2
	// Memory allocation error.
	CONST ELoadDLLResult_MemoryAllocationError = 3
	// The DLL could not be loaded to the preferred imagebase and there is no base relocation info in the module.
	CONST ELoadDLLResult_RelocationError = 4
	// The DLL relocation data seems to be bad.
	CONST ELoadDLLResult_BadRelocationTable = 5
	// An imported DLL could not be loaded.
	CONST ELoadDLLResult_ImportModuleError = 6
	// A function was not found in an imported DLL.
	CONST ELoadDLLResult_ImportFunctionError = 6
	// Bad import table contents.
	CONST ELoadDLLResult_ImportTableError = 7
	// We do not support import directories that contain only bound import info.
	CONST ELoadDLLResult_BoundImportDirectoriesNotSupported = 8
	// Error setting the memory page protection of loaded and relocated sections.
	CONST ELoadDLLResult_ErrorSettingMemoryProtection = 9
	// The DllMain() returned FALSE or caused an exception.
	CONST ELoadDLLResult_DllMainCallError = 10
	CONST ELoadDLLResult_DLLFileNotFound = 11
	// LoadDLL() was called with wrong parameters
	CONST ELoadDLLResult_WrongFunctionParameters = -2
	CONST ELoadDLLResult_UnknownError = -1

	// Don't call the DllMain() of the loaded DLL.
	CONST ELoadDLLFlag_NoEntryCall = 1
	// Don't load the DOS/PE headers, only the data/code sections. This is useful only with LoadDLL().
	CONST ELoadDLLFlag_NoHeaders   = 2

	CONST PARA_BASE_SIZE = 84
	CONST PARA_FUNC_OFFSET = 80
	CONST PARA_LASTERR_OFFSET = 76

	CONST DEFLATE_MARK = $544c4644
	CONST DEFLATE_HEADER_SIZE = 8


	DIM _proc = NULL, _data = NULL, _hDll = NULL
	HASHTBL _allocs

	PROCEDURE Dll
		hK32 = LoadLibraryW("kernel32")
		IF _proc <> NULL THEN Free(_proc)
		_proc = Set(_dll_imp_code)
	FEND

	PROCEDURE Dispose()
		IF _hDll <> NULL THEN Unload(_hDll)
		_hDll = NULL
		IF _data <> NULL THEN Free(_data)
		_data = NULL
		IF _proc <> NULL THEN Free(_proc)
		_proc = NULL
		WHILE LENGTH(_allocs)
			DebugLog("Dispose() Free " + _allocs[0, HASH_KEY])
			Free(_allocs[0, HASH_KEY])
		WEND
	FEND


	FUNCTION Set(code)
		RESULT = SetString(0, code, CRYPT_STRING_ANY, $40)
		DIM sz = Size(RESULT)
		IFB sz > DEFLATE_HEADER_SIZE THEN
			IFB GetDword(RESULT) = DEFLATE_MARK THEN
				DIM wk = Deflate(RESULT, sz, TRUE)
				IFB wk THEN
					Free(RESULT)
					RESULT = wk
				ENDIF
			ENDIF
		ENDIF
	FEND

	// 戻りはtypeによって異なる
	//  type=0   : スレッド終了コード
	//  type=1   : スレッド終了コード取得失敗
	//  type=258 : スレッドハンドル
	//  type=他  : その他エラーコード(WaitForSingleObject)
	FUNCTION Run(addr, para, var type, timeout=$7FFFFFFF, unit=100)
		DIM hThread = CreateThread(0, 0, addr, para, 0, 0)
		RESULT = hThread
		type = WAIT_TIMEOUT
		WHILE timeout >= 0 AND type = WAIT_TIMEOUT
			type = WaitForSingleObject(hThread, unit)
			timeout = timeout - unit
		WEND
		IFB type = 0 THEN
			IF !GetExitCodeThread(hThread, RESULT) THEN type = 1
			CloseHandle(hThread)
		ENDIF
	FEND

	FUNCTION Alloc(size, ptr=NULL, pro=4)
		RESULT = VirtualAlloc(0, size, $1000, pro)
		IF RESULT THEN _allocs[RESULT] = size
		IFB ptr <> NULL THEN
			DIM ptrSize = size
			IF _allocs[ptr, HASH_EXISTS] THEN ptrSize = _allocs[ptr]
			IF size < ptrSize THEN ptrSize = size
			DEF_DLL RtlMoveMemory(DWORD, DWORD, DWORD): kernel32
			RtlMoveMemory(RESULT, ptr, ptrSize)
		ENDIF
		DebugLog("Alloc(" + size + ") " + RESULT)
	FEND
	FUNCTION Free(ptr)
		RESULT = _allocs[ptr, HASH_REMOVE]
		RESULT = VirtualFree(ptr, 0, $8000)
	FEND

	FUNCTION Size(ptr)
		RESULT = -1
		IF _allocs[ptr, HASH_EXISTS] THEN RESULT = _allocs[ptr]
	FEND

	FUNCTION SetByte(p, data[])
		DEF_DLL RtlMoveMemory(DWORD, BYTE[], DWORD): kernel32
		RESULT = LENGTH(data)
		RtlMoveMemory(p, data, RESULT)
	FEND
	FUNCTION SetDword(p, data)
		DEF_DLL RtlMoveMemory(DWORD, var DWORD, DWORD): kernel32
		RESULT = 4
		RtlMoveMemory(p, data, RESULT)
	FEND
	FUNCTION SetString(p, data, dwFlag=CRYPT_STRING_ASCII, pro=4)
		IFB dwFlag = CRYPT_STRING_ASCII THEN
			RESULT = LENGTHB(data)
			DEF_DLL RtlMoveMemory(DWORD, string, DWORD): kernel32
			RtlMoveMemory(p, data, RESULT)
		ELSE
			RESULT = 0
			DIM sz = 0
			IFB CryptStringToBinaryW(data,0,dwFlag,NULL,sz,NULL,dwFlag) THEN
				IFB p = 0 THEN
					RESULT = Alloc(sz, NULL, pro)
					p = RESULT
				ENDIF
				IF _allocs[p, HASH_EXISTS] AND Size(p) < sz THEN sz = Size(p)
				IF CryptStringToBinaryW(data,0,dwFlag,p,sz,NULL,NULL) AND !RESULT THEN RESULT = sz
			ENDIF
		ENDIF
	FEND

	FUNCTION GetDword(p)
		DEF_DLL RtlMoveMemory(var DWORD, DWORD, DWORD): kernel32
		RESULT = 0
		RtlMoveMemory(RESULT, p, 4)
	FEND
	FUNCTION GetString(addr, size=-1, dwFlag=CRYPT_STRING_ASCII)
		IF size = -1 AND _allocs[addr, HASH_EXISTS] THEN size = _allocs[addr]
		IFB dwFlag = CRYPT_STRING_ASCII THEN
			DEF_DLL RtlMoveMemory(var string, DWORD, DWORD): kernel32
			IFB size >= 0 THEN
				RESULT = FORMAT(CHR(0), size)
				RtlMoveMemory(RESULT, addr, size)
			ELSE
				size = 0
				DIM n = size
				WHILE n = size
					size = size + 1
					RESULT = FORMAT(CHR(0), size)
					RtlMoveMemory(RESULT, addr, size)
					n = LENGTH(RESULT)
				WEND
			ENDIF
			EXIT
		ENDIF
		RESULT = EMPTY
		DIM nstr = 0, str
		IFB CryptBinaryToStringW(addr,size,dwFlag,NULL,nstr) THEN
			str = FORMAT(CHR(0), nstr)
			IFB CryptBinaryToStringW(addr,size,dwFlag,str,nstr) THEN
				RESULT = str
			ENDIF
		ENDIF
	FEND

	PROCEDURE Dump(addr, size=-1, dwFlag=CRYPT_STRING_HEXASCIIADDR)
		PRINT GetString(addr, size, dwFlag)
	FEND

	FUNCTION Import(dllDataB64, funcNameLen=256-PARA_BASE_SIZE)
		DebugLog("Import(, " + funcNameLen + ") start")
		RESULT = Alloc(PARA_BASE_SIZE + funcNameLen)
		IFB RESULT THEN
			DIM dllData = Set(dllDataB64), dllSize = _allocs[dllData], i = 0
			i = i + SetDword(RESULT + i, 0)
			i = i + SetDword(RESULT + i, dllData)
			i = i + SetDword(RESULT + i, dllSize)
			i = i + SetDword(RESULT + i, ELoadDLLResult_OK)
			i = i + SetDword(RESULT + i, _proc)
			i = i + SetDword(RESULT + i, GetProcAddress(hK32, "LoadLibraryA"))
			i = i + SetDword(RESULT + i, GetProcAddress(hK32, "GetProcAddress"))
		ENDIF
		DebugLog("Import(, " + funcNameLen + ") end " + RESULT)
	FEND

	FUNCTION GetFunc(var hDll, funcName)
		DebugLog("GetFunc(" + hDll + ", " + funcName + ") start")
		RESULT = 0
		IF !_allocs[hDll, HASH_EXISTS] THEN EXIT
		DIM size = _allocs[hDll]
		IFB size < PARA_BASE_SIZE + LENGTH(funcName) + 1 THEN
			hDll = Alloc(PARA_BASE_SIZE + LENGTH(funcName) + 1, hDll)
		ENDIF
		DIM first = GetDword(hDll + 44)
		SetDword(hDll, 0)
		SetString(hDll + PARA_BASE_SIZE, funcName + CHR(0))
		DIM type, res = Run(_proc, hDll, type)
		IFB type = 0 AND res = 0 THEN
			RESULT = GetDword(hDll + PARA_FUNC_OFFSET)
			type = GetDword(hDll + 4)
			IFB RESULT > 0 AND type > 0 AND !first THEN
				Free(type)
				SetDword(hDll + 4, 0)
			ENDIF
		ENDIF
		DebugLog("GetFunc(" + hDll + ", " + funcName + ") end " + RESULT)
	FEND

	FUNCTION Call(var hDll, var e, func="", param=0, paramSize=0, dll=EMPTY)
		DebugLog("Call(" + hDll + ", " + e + ", " + func + ", " + param + ", " + paramSize + ", " + dll + ") start")
		RESULT = 0
		e = EMPTY
		DIM hMod = NULL, funcPtr
		DIM bCall = !_allocs[hDll, HASH_EXISTS]
		IFB VARTYPE(param) = VAR_BSTR THEN
			IF _data = NULL THEN _data = Alloc(LENGTHB(param) + 1)
			DIM size = Size(_data)
			IFB LENGTHB(param) + 1 > size THEN
				Free(_data)
				_data = Alloc(LENGTHB(param) + 1)
			ENDIF
			SetString(_data, param + CHR(0))
			param = _data
		ENDIF
		IFB bCall THEN
			hDll = Alloc(PARA_BASE_SIZE + 1)
			IFB !hDll THEN
				e = "Alloc fail."
				EXIT
			ENDIF
			SetDword(hDll + 16, _proc)
			IFB dll <> EMPTY THEN
				IFB VARTYPE(dll) <> VAR_BSTR THEN
					hMod = dll
				ELSE
					hMod = LoadLibraryW(dll)
					IFB !hMod THEN
						e = "LoadLibrary fail. " + dll
						EXIT
					ENDIF
				ENDIF
			ENDIF
		ELSE
			funcPtr = GetDword(hDll + PARA_FUNC_OFFSET)
			IF func <> "" AND (funcPtr = 0 OR GetString(hDll + PARA_BASE_SIZE, LENGTH(func) + 1) <> func) THEN funcPtr = GetFunc(hDll, func)
			IFB funcPtr = 0 THEN
				e = "GetFunc fail."
				EXIT
			ENDIF
		ENDIF
		IF paramSize = -1 AND _allocs[param, HASH_EXISTS] THEN paramSize = Size(param)
		DIM i = 0
		i = i + SetDword(hDll + i, 1)
		i = i + SetDword(hDll + i, param)
		i = i + SetDword(hDll + i, paramSize)
		SetDword(hDll + PARA_LASTERR_OFFSET, GetProcAddress(hK32, "GetLastError"))
		IFB bCall THEN
			IFB hMod <> NULL AND VARTYPE(func) = VAR_BSTR THEN
				i = GetProcAddress(hMod, func)
				IF !i THEN e = "GetProcAddress fail. " + func
			ELSEIF hMod = NULL AND VARTYPE(func) <> VAR_BSTR THEN
				i = func
			ELSE
				e = "Invalid func. " + func
			ENDIF
			SetDword(hDll + PARA_FUNC_OFFSET, i)
		ENDIF
		IFB e = EMPTY THEN
			RESULT = Run(_proc, hDll, i)
			e = GetDword(hDll + PARA_LASTERR_OFFSET)
		ENDIF
		IFB bCall THEN
			IF hMod <> NULL THEN FreeLibrary(hMod)
			Free(hDll)
			hDll = (i = 0)
		ENDIF
		DebugLog("Call(" + hDll + ", " + e + ", " + func + ", " + param + ", " + paramSize + ", " + dll + ") end " + RESULT)
	FEND
	FUNCTION CallEx(var hDll, var e, func=EMPTY, dll=EMPTY, num=0, p0=0, p1=0, p2=0, p3=0, p4=0, p5=0, p6=0, p7=0, p8=0, p9=0, p10=0, p11=0)
		RESULT = CallEx12(hDll, e, func, dll, num, 0, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)
	FEND
	FUNCTION CallEx12(var hDll, var e, func, dll, num, ref, var p0, var p1, var p2, var p3, var p4, var p5, var p6, var p7, var p8, var p9, var p10, var p11)
		DebugLog("CallEx12(" + hDll + ", " + e + ", " + func + ", " + dll + ", " + num + ", " + p0 + ") start")
		DIM paramSize = num * 4, i, p = SAFEARRAY(0, num - 1), f = ref
		FOR i = 0 TO num - 1
			p[i] = EVAL("p" + i)
			IF VARTYPE(p[i]) = VAR_BSTR THEN paramSize = paramSize + LENGTHB(p[i]) + 1
			IF f MOD 2 THEN paramSize = paramSize + 4
			f = INT(f / 2)
		NEXT
		DIM param = Alloc(paramSize), offset = num * 4
		f = ref
		FOR i = 0 TO num - 1
			IFB VARTYPE(p[i]) = VAR_BSTR THEN
				SetDword(param + i * 4, param + offset)
				SetString(param + offset, p[i] + CHR(0))
				offset = offset + LENGTHB(p[i]) + 1
			ELSEIF f MOD 2 THEN
				SetDword(param + i * 4, param + offset)
				SetDword(param + offset, p[i])
				offset = offset + 4
			ELSE
				SetDword(param + i * 4, p[i])
			ENDIF
			f = INT(f / 2)
		NEXT
		RESULT = Call(hDll, e, func, param, paramSize, dll)

		offset = num * 4
		f = ref
		FOR i = 0 TO num - 1
			IFB VARTYPE(p[i]) = VAR_BSTR THEN
				EVAL("p" + i + ":=<#DBL>" + GetString(param + offset) + "<#DBL>")
				offset = offset + LENGTHB(p[i]) + 1
			ELSEIF f MOD 2 THEN
				EVAL("p" + i + ":=" + GetDword(param + offset))
				offset = offset + 4
			ENDIF
			f = INT(f / 2)
		NEXT
		Free(param)
		DebugLog("CallEx12(" + hDll + ", " + e + ", " + func + ", " + dll + ", " + num + ", " + p0 + ") end " + RESULT)
	FEND
	FUNCTION CallEx6(var hDll, var e, func, dll, num, ref, var p0, var p1, var p2, var p3, var p4, var p5)
		DIM p6, p7, p8, p9, p10, p11
		RESULT = CallEx12(hDll, e, func, dll, num, ref, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)
	FEND

	FUNCTION Unload(hDll)
		DebugLog("Unload(" + hDll + ") start")
		SetDword(hDll, 2)
		DIM type
		RESULT = Run(_proc, hDll, type)
		Free(hDll)
		DebugLog("Unload(" + hDll + ") end " + RESULT)
	FEND

	FUNCTION FormatMessage(msgId, langId=0)
		DebugLog("FormatMessage(" + msgId + ", " + langId + ") start")
		RESULT = msgId
		DIM p = 256, i = p, ret, e = 0, wk = Alloc(2048)
		WHILE i >= p - 1 AND e = 0
			p = p * 2
			IFB p > Size(wk) THEN
				Free(wk)
				wk = Alloc(p)
			ENDIF
			i = CallEx(ret, e, "FormatMessageA", "kernel32", 7, $1200, 0, msgId, langId, wk, p, 0)
		WEND
		IFB wk AND e = 0 THEN
			RESULT = GetString(wk, i)
			Free(wk)
		ENDIF
		DebugLog("FormatMessage(" + msgId + ", " + langId + ") end " + RESULT)
	FEND

	FUNCTION Deflate(tar, size=-1, inflate=FALSE)
		DebugLog("Deflate(" + tar + ", " + size + ", " + inflate + ") start")
		IF _hDll = NULL THEN _hDll = Import(_zlib_dll)
		DIM tarFree = FALSE, wk
		IFB VARTYPE(tar) = VAR_BSTR THEN
			IFB inflate THEN
				RESULT = Set(tar)
				EXIT
			ENDIF
			size = LENGTHB(tar)
			wk = Alloc(size)
			SetString(wk, tar)
			tar = wk
			tarFree = TRUE
		ENDIF
		IF size = -1 THEN size = Size(tar)
		RESULT = 0
		IFB inflate THEN
			IF GetDword(tar) <> DEFLATE_MARK OR size < DEFLATE_HEADER_SIZE THEN EXIT
			wk = Alloc(GetDword(tar + 4))
		ELSE
			wk = Alloc(size + size / 16 + $200 + DEFLATE_HEADER_SIZE)
			SetDword(wk, DEFLATE_MARK)
			SetDword(wk + 4, size)
		ENDIF
		DIM pr = Alloc((14 + 4) * 4 + 8)
		DIM ret = 0, lOrigToDo = size, lOrigDone = 0
		DIM BlockSizeCompress = $8000, step = 0, i = 0
		i = i + SetDword(pr + i, pr + 4 * 4)
		IF !inflate THEN i = i + SetDword(pr + i, 9)	// Z_BEST_COMPRESSION
		i = i + SetDword(pr + i, pr + (14 + 4) * 4)	// "1.2.8"
		i = i + SetDword(pr + i, 14 * 4)
		SetString(pr + (14 + 4) * 4, "1.2.8" + CHR(0))
		DIM name = "deflate", e
		IF inflate THEN name = "inflate"
		Call(_hDll, e, name + "Init_", pr, 4 * 4)

		i = 0
		IF inflate THEN i = DEFLATE_HEADER_SIZE
		SetDword(pr + 4 * 4, tar + i)
		SetDword(pr + 7 * 4, wk + DEFLATE_HEADER_SIZE - i)
		SetDword(pr + 4, 2)	// Z_SYNC_FLUSH
		REPEAT
			i = GetDword(pr + 6 * 4)
			SetDword(pr + 5 * 4, BlockSizeCompress)
			IFB lOrigToDo <= BlockSizeCompress THEN
				SetDword(pr + 5 * 4, lOrigToDo)
				IF !inflate THEN SetDword(pr + 4, 4)	// Z_FINISH
			ENDIF
			SetDword(pr + 8 * 4, BlockSizeCompress)
			ret = Call(_hDll, e, name, pr, 4 * 2)
			i = GetDword(pr + 6 * 4) - i
			lOrigDone = lOrigDone + i
			lOrigToDo = lOrigToDo - i
			step = step + 1
		UNTIL ret <> 0
		i = GetDword(pr + 9 * 4)
		IF inflate THEN Call(_hDll, e, "inflateEnd", pr, 4) ELSE i = i + DEFLATE_HEADER_SIZE
		Free(pr)

		RESULT = Alloc(i, wk)
		Free(wk)
		IF tarFree THEN Free(tar)
		DebugLog("Deflate(" + tar + ", " + size + ", " + inflate + ") end " + RESULT)
	FEND
	FUNCTION DeflateToString(tar, size=-1, inflate=FALSE, f=CRYPT_STRING_BASE64)
		RESULT = EMPTY
		DIM wk = Deflate(tar, size, inflate)
		IF wk THEN RESULT = GetString(wk, -1, f)
		Free(wk)
	FEND
	FUNCTION InflateToString(tar, size=-1, f=CRYPT_STRING_ASCII)
		RESULT = EMPTY
		DIM wk = Deflate(tar, size, TRUE)
		IF wk THEN RESULT = GetString(wk, -1, f)
		Free(wk)
	FEND

	FUNCTION ReadFromFile(path)
		DebugLog("ReadFromFile(" + path + ") start")
		RESULT = 0
		DIM ret, e, read, size
		DIM hFile = CallEx(ret, e, "CreateFileA", "kernel32", 7, path, $80000000, 1, 0, 3, 0, 0)
		IF hFile = $FFFFFFFF THEN PRINT "CreateFile失敗:" + FormatMessage(e)
		IFB CallEx6(ret, e, "GetFileSizeEx", "kernel32", 3, 6, hFile, size, read, 0, 0, 0) AND read = 0 THEN
			RESULT = Alloc(size)
			IFB !CallEx6(ret, e, "ReadFile", "kernel32", 5, 8, hFile, RESULT, size, read, 0, 0) OR !ret THEN
				PRINT "ReadFile失敗:" + FormatMessage(e)
				Free(RESULT)
				RESULT = 0
			ENDIF
		ELSEIF read > 0 THEN
			PRINT "ファイルサイズが大きすぎます " + (read * $100000000 + size)
		ELSE
			PRINT "GetFileSize失敗:" + FormatMessage(e)
		ENDIF
		CloseHandle(hFile)
		DebugLog("ReadFromFile(" + path + ") end " + RESULT)
	FEND


	PROCEDURE DebugLog(msg)
		IF Debug THEN PRINT msg
		IF Debug > 1 THEN MSGBOX(msg)
	FEND


	TEXTBLOCK _dll_imp_code
		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
		DQAAAABfXluL5V3D
	ENDTEXTBLOCK

	TEXTBLOCK _zlib_dll
		ここに、zlib1.dllをBase64変換した結果を書く
		載せたかったけど、長すぎなのか切り捨てられてしまった
	ENDTEXTBLOCK
ENDMODULE