• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

FFFTPのソースコードです。


Commit MetaInfo

Revision190e1b19f7b48bbf636b2a0a5e7b71d01929def5 (tree)
Zeit2011-12-26 21:51:51
Autors_kawamoto <s_kawamoto@user...>
Commiters_kawamoto

Log Message

Add test code for SFTP (still useless).

Ändern Zusammenfassung

Diff

Binary files a/FFFTP_Eng_Release/FFFTP.exe and b/FFFTP_Eng_Release/FFFTP.exe differ
Binary files a/Release/FFFTP.exe and b/Release/FFFTP.exe differ
--- a/connect.c
+++ b/connect.c
@@ -1699,6 +1699,61 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char
16991699 }
17001700 else if(CryptMode == CRYPT_SFTP)
17011701 {
1702+ // TODO:
1703+ // テストコード
1704+ // ログイン成功を確認
1705+#define strrcmp(_Str1, _Str2) (strcmp(strstr(_Str1, _Str2) ? strstr(_Str1, _Str2) : "", _Str2))
1706+ size_t r;
1707+ ContSock = SFTP_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
1708+ SFTP_SetTimeoutCallback(ContSock, SSLTimeoutCallback);
1709+ while(1)
1710+ {
1711+ r = SFTP_recv(ContSock, Reply, 1024, 0);
1712+ if(r == SOCKET_ERROR)
1713+ break;
1714+ if(r <= 0)
1715+ continue;
1716+ Reply[r] = '\0';
1717+ SetTaskMsg("%s", Reply);
1718+ if(strrcmp(Reply, "psftp> ") == 0)
1719+ break;
1720+ }
1721+ r = SFTP_send(ContSock, "open \"", strlen("open \""), 0);
1722+ r = SFTP_send(ContSock, Host, strlen(Host), 0);
1723+ r = SFTP_send(ContSock, "\"\r\n", strlen("\"\r\n"), 0);
1724+ while(1)
1725+ {
1726+ r = SFTP_recv(ContSock, Reply, 1024, 0);
1727+ if(r == SOCKET_ERROR)
1728+ break;
1729+ if(r <= 0)
1730+ continue;
1731+ Reply[r] = '\0';
1732+ SetTaskMsg("%s", Reply);
1733+ if(strrcmp(Reply, "Store key in cache? (y/n) ") == 0)
1734+ {
1735+ r = SFTP_send(ContSock, "n\r\n", strlen("n\r\n"), 0);
1736+ }
1737+ if(strrcmp(Reply, "Update cached key? (y/n, Return cancels connection) ") == 0)
1738+ {
1739+ r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0);
1740+ }
1741+ if(strrcmp(Reply, "login as: ") == 0)
1742+ {
1743+ r = SFTP_send(ContSock, User, strlen(User), 0);
1744+ r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0);
1745+ }
1746+ if(strrcmp(Reply, "password: ") == 0)
1747+ {
1748+ r = SFTP_send(ContSock, Pass, strlen(Pass), 0);
1749+ r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0);
1750+ }
1751+ if(strrcmp(Reply, "psftp> ") == 0)
1752+ break;
1753+ Sleep(1);
1754+ }
1755+ SFTP_closesocket(ContSock);
1756+ ContSock = INVALID_SOCKET;
17021757 }
17031758
17041759 return(ContSock);
@@ -1711,12 +1766,12 @@ static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass,
17111766 SOCKET ContSock;
17121767 ContSock = INVALID_SOCKET;
17131768 *CancelCheckWork = NO;
1714-// if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseSFTP == YES)
1715-// {
1716-// SetTaskMsg(MSGJPN317);
1717-// if((ContSock = DoConnectCrypt(CRYPT_SFTP, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)
1718-// HostData->CryptMode = CRYPT_SFTP;
1719-// }
1769+ if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseSFTP == YES)
1770+ {
1771+ SetTaskMsg(MSGJPN317);
1772+ if((ContSock = DoConnectCrypt(CRYPT_SFTP, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)
1773+ HostData->CryptMode = CRYPT_SFTP;
1774+ }
17201775 if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPIS == YES)
17211776 {
17221777 SetTaskMsg(MSGJPN316);
--- a/getput.c
+++ b/getput.c
@@ -1320,7 +1320,13 @@ int DoDownLoad(SOCKET cSkt, TRANSPACKET *Pkt, int DirList, int *CancelCheckWork)
13201320 DispTransFileInfo(Pkt, MSGJPN087, FALSE, NO);
13211321 }
13221322
1323- if(BackgrndMessageProc() == NO)
1323+ // SFTP対応
1324+// if(BackgrndMessageProc() == NO)
1325+ if(IsSFTPAttached(Pkt->ctrl_skt))
1326+ {
1327+ // TODO:
1328+ }
1329+ else if(BackgrndMessageProc() == NO)
13241330 {
13251331 if(AskPasvMode() != YES)
13261332 iRetCode = DownLoadNonPassive(Pkt, CancelCheckWork);
@@ -2550,7 +2556,13 @@ static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt)
25502556 if(Pkt->hWndTrans != NULL)
25512557 DispTransFileInfo(Pkt, MSGJPN104, TRUE, YES);
25522558
2553- if(BackgrndMessageProc() == NO)
2559+ // SFTP対応
2560+// if(BackgrndMessageProc() == NO)
2561+ if(IsSFTPAttached(Pkt->ctrl_skt))
2562+ {
2563+ // TODO:
2564+ }
2565+ else if(BackgrndMessageProc() == NO)
25542566 {
25552567 if(AskPasvMode() != YES)
25562568 iRetCode = UpLoadNonPassive(Pkt);
--- a/hostman.c
+++ b/hostman.c
@@ -2236,13 +2236,18 @@ static INT_PTR CALLBACK CryptSettingProc(HWND hDlg, UINT iMessage, WPARAM wParam
22362236 SendDlgItemMessage(hDlg, HSET_FTPIS, BM_SETCHECK, BST_UNCHECKED, 0);
22372237 EnableWindow(GetDlgItem(hDlg, HSET_FTPIS), FALSE);
22382238 }
2239- SendDlgItemMessage(hDlg, HSET_SFTP, BM_SETCHECK, TmpHost.UseSFTP, 0);
2240- SendDlgItemMessage(hDlg, HSET_PRIVATE_KEY, WM_SETTEXT, 0, (LPARAM)TmpHost.PrivateKey);
2241- // TODO: SFTP対応
2242- SendDlgItemMessage(hDlg, HSET_SFTP, BM_SETCHECK, BST_UNCHECKED, 0);
2243- EnableWindow(GetDlgItem(hDlg, HSET_SFTP), FALSE);
2244- EnableWindow(GetDlgItem(hDlg, PKEY_FILE_BR), FALSE);
2245- EnableWindow(GetDlgItem(hDlg, HSET_PRIVATE_KEY), FALSE);
2239+ if(IsPuTTYLoaded())
2240+ {
2241+ SendDlgItemMessage(hDlg, HSET_SFTP, BM_SETCHECK, TmpHost.UseSFTP, 0);
2242+ SendDlgItemMessage(hDlg, HSET_PRIVATE_KEY, WM_SETTEXT, 0, (LPARAM)TmpHost.PrivateKey);
2243+ }
2244+ else
2245+ {
2246+ SendDlgItemMessage(hDlg, HSET_SFTP, BM_SETCHECK, BST_UNCHECKED, 0);
2247+ EnableWindow(GetDlgItem(hDlg, HSET_SFTP), FALSE);
2248+ EnableWindow(GetDlgItem(hDlg, PKEY_FILE_BR), FALSE);
2249+ EnableWindow(GetDlgItem(hDlg, HSET_PRIVATE_KEY), FALSE);
2250+ }
22462251 return(TRUE);
22472252
22482253 case WM_NOTIFY:
@@ -2256,9 +2261,11 @@ static INT_PTR CALLBACK CryptSettingProc(HWND hDlg, UINT iMessage, WPARAM wParam
22562261 TmpHost.UseFTPES = SendDlgItemMessage(hDlg, HSET_FTPES, BM_GETCHECK, 0, 0);
22572262 TmpHost.UseFTPIS = SendDlgItemMessage(hDlg, HSET_FTPIS, BM_GETCHECK, 0, 0);
22582263 }
2259- // TODO: SFTP対応
2260-// TmpHost.UseSFTP = SendDlgItemMessage(hDlg, HSET_SFTP, BM_GETCHECK, 0, 0);
2261- SendDlgItemMessage(hDlg, HSET_PRIVATE_KEY, WM_GETTEXT, PRIVATE_KEY_LEN+1, (LPARAM)TmpHost.PrivateKey);
2264+ if(IsPuTTYLoaded())
2265+ {
2266+ TmpHost.UseSFTP = SendDlgItemMessage(hDlg, HSET_SFTP, BM_GETCHECK, 0, 0);
2267+ SendDlgItemMessage(hDlg, HSET_PRIVATE_KEY, WM_GETTEXT, PRIVATE_KEY_LEN+1, (LPARAM)TmpHost.PrivateKey);
2268+ }
22622269 Apply = YES;
22632270 break;
22642271
--- a/main.c
+++ b/main.c
@@ -339,6 +339,9 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi
339339 LoadOpenSSL();
340340 #endif
341341
342+ // SFTP対応
343+ LoadPuTTY();
344+
342345 Ret = FALSE;
343346 hWndFtp = NULL;
344347 hInstFtp = hInstance;
@@ -374,6 +377,8 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi
374377 #ifdef USE_OPENSSL
375378 FreeOpenSSL();
376379 #endif
380+ // SFTP対応
381+ FreePuTTY();
377382 OleUninitialize();
378383 return(Ret);
379384 }
--- a/mbswrapper.c
+++ b/mbswrapper.c
@@ -1895,7 +1895,6 @@ END_ROUTINE
18951895 return r;
18961896 }
18971897
1898-
18991898 BOOL AppendMenuM(HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem, LPCSTR lpNewItem)
19001899 {
19011900 int r = 0;
--- a/putty/PUTTY.H
+++ b/putty/PUTTY.H
@@ -1303,4 +1303,8 @@ void timer_change_notify(long next);
13031303 #define remove_session_from_jumplist(x) ((void)0)
13041304 #endif
13051305
1306+// FFFTP
1307+#include "mbswrapper.h"
1308+#include "iowrapper.h"
1309+
13061310 #endif
--- a/putty/PuTTY.vc90.vcproj
+++ b/putty/PuTTY.vc90.vcproj
@@ -50,7 +50,7 @@
5050 RuntimeLibrary="1"
5151 UsePrecompiledHeader="0"
5252 WarningLevel="3"
53- DebugInformationFormat="4"
53+ DebugInformationFormat="3"
5454 />
5555 <Tool
5656 Name="VCManagedResourceCompilerTool"
@@ -197,7 +197,7 @@
197197 RuntimeLibrary="1"
198198 UsePrecompiledHeader="0"
199199 WarningLevel="3"
200- DebugInformationFormat="4"
200+ DebugInformationFormat="3"
201201 />
202202 <Tool
203203 Name="VCManagedResourceCompilerTool"
@@ -334,6 +334,10 @@
334334 >
335335 </File>
336336 <File
337+ RelativePath=".\dllinterface.c"
338+ >
339+ </File>
340+ <File
337341 RelativePath=".\dllmain.c"
338342 >
339343 </File>
@@ -342,10 +346,18 @@
342346 >
343347 </File>
344348 <File
349+ RelativePath=".\iowrapper.c"
350+ >
351+ </File>
352+ <File
345353 RelativePath=".\LOGGING.C"
346354 >
347355 </File>
348356 <File
357+ RelativePath=".\mbswrapper.c"
358+ >
359+ </File>
360+ <File
349361 RelativePath=".\MISC.C"
350362 >
351363 </File>
--- a/putty/PuTTY.vcproj
+++ b/putty/PuTTY.vcproj
@@ -49,7 +49,7 @@
4949 RuntimeLibrary="1"
5050 UsePrecompiledHeader="0"
5151 WarningLevel="3"
52- DebugInformationFormat="4"
52+ DebugInformationFormat="3"
5353 />
5454 <Tool
5555 Name="VCManagedResourceCompilerTool"
@@ -196,7 +196,7 @@
196196 RuntimeLibrary="1"
197197 UsePrecompiledHeader="0"
198198 WarningLevel="3"
199- DebugInformationFormat="4"
199+ DebugInformationFormat="3"
200200 />
201201 <Tool
202202 Name="VCManagedResourceCompilerTool"
@@ -333,6 +333,10 @@
333333 >
334334 </File>
335335 <File
336+ RelativePath=".\dllinterface.c"
337+ >
338+ </File>
339+ <File
336340 RelativePath=".\dllmain.c"
337341 >
338342 </File>
@@ -341,10 +345,18 @@
341345 >
342346 </File>
343347 <File
348+ RelativePath=".\iowrapper.c"
349+ >
350+ </File>
351+ <File
344352 RelativePath=".\LOGGING.C"
345353 >
346354 </File>
347355 <File
356+ RelativePath=".\mbswrapper.c"
357+ >
358+ </File>
359+ <File
348360 RelativePath=".\MISC.C"
349361 >
350362 </File>
Binary files a/putty/Release/PuTTY.dll and b/putty/Release/PuTTY.dll differ
--- a/putty/WINDOWS/WINSFTP.C
+++ b/putty/WINDOWS/WINSFTP.C
@@ -93,6 +93,9 @@ RFile *open_existing_file(char *name, uint64 *size,
9393 HANDLE h;
9494 RFile *ret;
9595
96+ // FFFTP
97+ return snew(RFile);
98+
9699 h = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL,
97100 OPEN_EXISTING, 0, 0);
98101 if (h == INVALID_HANDLE_VALUE)
@@ -120,6 +123,8 @@ int read_from_file(RFile *f, void *buffer, int length)
120123 {
121124 int ret;
122125 DWORD read;
126+ // FFFTP
127+ return (int)SFTP_ReadThreadDataIO(buffer, length);
123128 ret = ReadFile(f->h, buffer, length, &read, NULL);
124129 if (!ret)
125130 return -1; /* error */
@@ -129,7 +134,8 @@ int read_from_file(RFile *f, void *buffer, int length)
129134
130135 void close_rfile(RFile *f)
131136 {
132- CloseHandle(f->h);
137+ // FFFTP
138+// CloseHandle(f->h);
133139 sfree(f);
134140 }
135141
@@ -142,6 +148,9 @@ WFile *open_new_file(char *name)
142148 HANDLE h;
143149 WFile *ret;
144150
151+ // FFFTP
152+ return snew(WFile);
153+
145154 h = CreateFile(name, GENERIC_WRITE, 0, NULL,
146155 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
147156 if (h == INVALID_HANDLE_VALUE)
@@ -158,6 +167,9 @@ WFile *open_existing_wfile(char *name, uint64 *size)
158167 HANDLE h;
159168 WFile *ret;
160169
170+ // FFFTP
171+ return snew(WFile);
172+
161173 h = CreateFile(name, GENERIC_WRITE, FILE_SHARE_READ, NULL,
162174 OPEN_EXISTING, 0, 0);
163175 if (h == INVALID_HANDLE_VALUE)
@@ -176,6 +188,8 @@ int write_to_file(WFile *f, void *buffer, int length)
176188 {
177189 int ret;
178190 DWORD written;
191+ // FFFTP
192+ return (int)SFTP_WriteThreadDataIO(buffer, length);
179193 ret = WriteFile(f->h, buffer, length, &written, NULL);
180194 if (!ret)
181195 return -1; /* error */
@@ -186,6 +200,8 @@ int write_to_file(WFile *f, void *buffer, int length)
186200 void set_file_times(WFile *f, unsigned long mtime, unsigned long atime)
187201 {
188202 FILETIME actime, wrtime;
203+ // FFFTP
204+ return;
189205 TIME_POSIX_TO_WIN(atime, actime);
190206 TIME_POSIX_TO_WIN(mtime, wrtime);
191207 SetFileTime(f->h, NULL, &actime, &wrtime);
@@ -193,7 +209,8 @@ void set_file_times(WFile *f, unsigned long mtime, unsigned long atime)
193209
194210 void close_wfile(WFile *f)
195211 {
196- CloseHandle(f->h);
212+ // FFFTP
213+// CloseHandle(f->h);
197214 sfree(f);
198215 }
199216
@@ -203,6 +220,9 @@ int seek_file(WFile *f, uint64 offset, int whence)
203220 {
204221 DWORD movemethod;
205222
223+ // FFFTP
224+ return 0;
225+
206226 switch (whence) {
207227 case FROM_START:
208228 movemethod = FILE_BEGIN;
@@ -229,6 +249,10 @@ uint64 get_file_posn(WFile *f)
229249 {
230250 uint64 ret;
231251
252+ // FFFTP
253+ SFTP_GetThreadFilePositon((DWORD*)&ret.lo, (LONG*)&ret.hi);
254+ return ret;
255+
232256 ret.hi = 0L;
233257 ret.lo = SetFilePointer(f->h, 0L, &(ret.hi), FILE_CURRENT);
234258
@@ -680,6 +704,9 @@ char *ssh_sftp_get_cmdline(char *prompt, int no_fds_ok)
680704 fputs(prompt, stdout);
681705 fflush(stdout);
682706
707+ // FFFTP
708+ return fgetline(stdin);
709+
683710 if ((sftp_ssh_socket == INVALID_SOCKET && no_fds_ok) ||
684711 p_WSAEventSelect == NULL) {
685712 return fgetline(stdin); /* very simple */
--- /dev/null
+++ b/putty/dllinterface.c
@@ -0,0 +1,90 @@
1+// dllinterface.c
2+// Copyright (C) 2011 Suguru Kawamoto
3+// 標準入出力APIラッパー
4+
5+#include <stdio.h>
6+#include <windows.h>
7+
8+#include "iowrapper.h"
9+#include "dllinterface.h"
10+
11+__declspec(dllexport) SFTPSTATUS* SFTP_Create()
12+{
13+ SFTPSTATUS* p;
14+ if(p = FindSFTPStatus(0))
15+ {
16+ p->ThreadId = GetCurrentThreadId();
17+ p->bExit = FALSE;
18+ SFTP_InitializeIOBuffer(&p->InBuffer, 65536);
19+ SFTP_InitializeIOBuffer(&p->OutBuffer, 65536);
20+ SFTP_InitializeIOBuffer(&p->DataInBuffer, 1048576);
21+ SFTP_InitializeIOBuffer(&p->DataOutBuffer, 1048576);
22+ memset(&p->FilePosition, 0, sizeof(LARGE_INTEGER));
23+ CreateThread(NULL, 0, SFTP_ThreadProc, NULL, 0, &p->ThreadId);
24+ }
25+ return p;
26+}
27+
28+__declspec(dllexport) void SFTP_Destroy(SFTPSTATUS* pSFTP)
29+{
30+ if(pSFTP)
31+ {
32+ SFTP_UninitializeIOBuffer(&pSFTP->InBuffer);
33+ SFTP_UninitializeIOBuffer(&pSFTP->OutBuffer);
34+ SFTP_UninitializeIOBuffer(&pSFTP->DataInBuffer);
35+ SFTP_UninitializeIOBuffer(&pSFTP->DataOutBuffer);
36+ pSFTP->ThreadId = 0;
37+ }
38+}
39+
40+__declspec(dllexport) BOOL SFTP_IsExited(SFTPSTATUS* pSFTP)
41+{
42+ return pSFTP->bExit;
43+}
44+
45+__declspec(dllexport) BOOL SFTP_SetTimeoutCallback(SFTPSTATUS* pSFTP, LPSFTPTIMEOUTCALLBACK pCallback)
46+{
47+ pSFTP->pCallback = pCallback;
48+ pSFTP->InBuffer.pCallback = pCallback;
49+ pSFTP->OutBuffer.pCallback = pCallback;
50+ pSFTP->DataInBuffer.pCallback = pCallback;
51+ pSFTP->DataOutBuffer.pCallback = pCallback;
52+ return TRUE;
53+}
54+
55+__declspec(dllexport) size_t SFTP_PeekStdOut(SFTPSTATUS* pSFTP, void* pData, size_t Size)
56+{
57+ return SFTP_PeekIOBuffer(&pSFTP->OutBuffer, pData, Size);
58+}
59+
60+__declspec(dllexport) size_t SFTP_ReadStdOut(SFTPSTATUS* pSFTP, void* pData, size_t Size)
61+{
62+ return SFTP_ReadIOBuffer(&pSFTP->OutBuffer, pData, Size);
63+}
64+
65+__declspec(dllexport) size_t SFTP_WriteStdIn(SFTPSTATUS* pSFTP, const void* pData, size_t Size)
66+{
67+ return SFTP_WriteIOBuffer(&pSFTP->InBuffer, pData, Size);
68+}
69+
70+__declspec(dllexport) size_t SFTP_PeekDataOut(SFTPSTATUS* pSFTP, void* pData, size_t Size)
71+{
72+ return SFTP_PeekIOBuffer(&pSFTP->DataOutBuffer, pData, Size);
73+}
74+
75+__declspec(dllexport) size_t SFTP_ReadDataOut(SFTPSTATUS* pSFTP, void* pData, size_t Size)
76+{
77+ return SFTP_ReadIOBuffer(&pSFTP->DataOutBuffer, pData, Size);
78+}
79+
80+__declspec(dllexport) size_t SFTP_WriteDataIn(SFTPSTATUS* pSFTP, const void* pData, size_t Size)
81+{
82+ return SFTP_WriteIOBuffer(&pSFTP->DataInBuffer, pData, Size);
83+}
84+
85+__declspec(dllexport) BOOL SFTP_SetFilePosition(SFTPSTATUS* pSFTP, LONGLONG Position)
86+{
87+ pSFTP->FilePosition.QuadPart = Position;
88+ return TRUE;
89+}
90+
--- /dev/null
+++ b/putty/dllinterface.h
@@ -0,0 +1,12 @@
1+// dllinterface.h
2+// Copyright (C) 2011 Suguru Kawamoto
3+// 標準入出力APIラッパー
4+
5+#ifndef __DLLINTERFACE_H__
6+#define __DLLINTERFACE_H__
7+
8+#include <stdio.h>
9+#include <windows.h>
10+
11+#endif
12+
--- /dev/null
+++ b/putty/iowrapper.c
@@ -0,0 +1,434 @@
1+// iowrapper.c
2+// Copyright (C) 2011 Suguru Kawamoto
3+// 標準入出力APIラッパー
4+
5+#define UNICODE
6+#define _UNICODE
7+
8+#include <stdio.h>
9+#include <windows.h>
10+
11+#define DO_NOT_REPLACE
12+#include "iowrapper.h"
13+#include "psftp.h"
14+
15+#define MAX_SFTPSTATUS 16
16+
17+SFTPSTATUS g_SFTPData[MAX_SFTPSTATUS];
18+HANDLE g_hStdIn;
19+HANDLE g_hStdOut;
20+HANDLE g_hStdErr;
21+
22+BOOL __stdcall DefaultIOBufferCallback(BOOL* pbAborted)
23+{
24+ Sleep(1);
25+ return *pbAborted;
26+}
27+
28+DWORD WINAPI SFTP_ThreadProc(LPVOID lpParameter)
29+{
30+ char* p[1] = {"PSFTP"};
31+ SFTPSTATUS* pSFTP;
32+ psftp_main(1, p);
33+ if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))
34+ pSFTP->bExit = TRUE;
35+ return 0;
36+}
37+
38+SFTPSTATUS* FindSFTPStatus(DWORD ThreadId)
39+{
40+ int i;
41+ for(i = 0; i < MAX_SFTPSTATUS; i++)
42+ {
43+ if(g_SFTPData[i].ThreadId == ThreadId)
44+ return &g_SFTPData[i];
45+ }
46+ return NULL;
47+}
48+
49+CRITICAL_SECTION g_DummyLock;
50+
51+BOOL SFTP_InitializeIOBuffer(SFTPIOBUFFER* pIO, size_t Length)
52+{
53+ memset(pIO, 0, sizeof(SFTPIOBUFFER));
54+// InitializeCriticalSection(&pIO->Lock);
55+ if(memcmp(&pIO->Lock, &g_DummyLock, sizeof(CRITICAL_SECTION)) == 0)
56+ {
57+ InitializeCriticalSection(&pIO->Lock);
58+ EnterCriticalSection(&pIO->Lock);
59+ }
60+ if(!(pIO->pBuffer = (BYTE*)malloc(Length + 1)))
61+ return FALSE;
62+ memset(pIO->pBuffer + Length, 0, 1);
63+ pIO->Length = Length;
64+ pIO->Written = 0;
65+ pIO->Read = 0;
66+ pIO->bAborted = FALSE;
67+ pIO->pCallback = DefaultIOBufferCallback;
68+ LeaveCriticalSection(&pIO->Lock);
69+ return TRUE;
70+}
71+
72+void SFTP_UninitializeIOBuffer(SFTPIOBUFFER* pIO)
73+{
74+// DeleteCriticalSection(&pIO->Lock);
75+ EnterCriticalSection(&pIO->Lock);
76+ free(pIO->pBuffer);
77+// memset(pIO, 0, sizeof(SFTPIOBUFFER));
78+}
79+
80+void SFTP_AbortIOBuffer(SFTPIOBUFFER* pIO, BOOL bAborted)
81+{
82+ EnterCriticalSection(&pIO->Lock);
83+ pIO->bAborted = bAborted;
84+ LeaveCriticalSection(&pIO->Lock);
85+}
86+
87+size_t SFTP_PeekIOBuffer(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size)
88+{
89+ size_t Copied;
90+ size_t Pos;
91+ size_t Count;
92+ size_t Read;
93+ Copied = 0;
94+ EnterCriticalSection(&pIO->Lock);
95+ if(pBuffer)
96+ {
97+ Read = pIO->Read;
98+ while(!pIO->bAborted && pIO->Written - Read > 0 && Copied < Size)
99+ {
100+ Pos = Read % pIO->Length;
101+ Count = min(Size - Copied, min(pIO->Written - Read, pIO->Length - Pos));
102+ memcpy((BYTE*)pBuffer + Copied, pIO->pBuffer + Pos, Count);
103+ Read += Count;
104+ Copied += Count;
105+ }
106+ }
107+ else
108+ Copied = pIO->Written - pIO->Read;
109+ LeaveCriticalSection(&pIO->Lock);
110+ return Copied;
111+}
112+
113+size_t SFTP_ReadIOBuffer(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size)
114+{
115+ size_t Copied;
116+ size_t Pos;
117+ size_t Count;
118+ Copied = 0;
119+ EnterCriticalSection(&pIO->Lock);
120+ while(!pIO->bAborted && pIO->Written - pIO->Read > 0 && Copied < Size)
121+ {
122+ Pos = pIO->Read % pIO->Length;
123+ Count = min(Size - Copied, min(pIO->Written - pIO->Read, pIO->Length - Pos));
124+ memcpy((BYTE*)pBuffer + Copied, pIO->pBuffer + Pos, Count);
125+ pIO->Read += Count;
126+ Copied += Count;
127+ }
128+ LeaveCriticalSection(&pIO->Lock);
129+ return Copied;
130+}
131+
132+size_t SFTP_WriteIOBuffer(SFTPIOBUFFER* pIO, const void* pBuffer, size_t Size)
133+{
134+ size_t Copied;
135+ size_t Pos;
136+ size_t Count;
137+ Copied = 0;
138+ EnterCriticalSection(&pIO->Lock);
139+ while(!pIO->bAborted && Copied < Size)
140+ {
141+ if(pIO->Written - pIO->Read < pIO->Length)
142+ {
143+ Pos = pIO->Written % pIO->Length;
144+ Count = min(Size - Copied, min(pIO->Length + pIO->Read - pIO->Written, pIO->Length - Pos));
145+ memcpy(pIO->pBuffer + Pos, (BYTE*)pBuffer + Copied, Count);
146+ pIO->Written += Count;
147+ Copied += Count;
148+ }
149+ else
150+ {
151+ LeaveCriticalSection(&pIO->Lock);
152+ if(pIO->pCallback(&pIO->bAborted))
153+ Size = 0;
154+ EnterCriticalSection(&pIO->Lock);
155+ }
156+ }
157+ LeaveCriticalSection(&pIO->Lock);
158+ return Copied;
159+}
160+
161+size_t SFTP_ReadIOBufferLine(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size)
162+{
163+ size_t Copied;
164+ size_t Pos;
165+ size_t Count;
166+ char* p;
167+ Copied = 0;
168+ EnterCriticalSection(&pIO->Lock);
169+ while(!pIO->bAborted && Copied < Size)
170+ {
171+ if(pIO->Written - pIO->Read > 0)
172+ {
173+ Pos = pIO->Read % pIO->Length;
174+ Count = min(Size - Copied, min(pIO->Written - pIO->Read, pIO->Length - Pos));
175+ if(p = strchr((char*)(pIO->pBuffer + Pos), '\n'))
176+ {
177+ p++;
178+ Count = min(Count, (size_t)p - (size_t)(pIO->pBuffer + Pos));
179+ Size = 0;
180+ }
181+ memcpy((BYTE*)pBuffer + Copied, pIO->pBuffer + Pos, Count);
182+ pIO->Read += Count;
183+ Copied += Count;
184+ }
185+ else
186+ {
187+ LeaveCriticalSection(&pIO->Lock);
188+ if(pIO->pCallback(&pIO->bAborted))
189+ Size = 0;
190+ EnterCriticalSection(&pIO->Lock);
191+ }
192+ }
193+ LeaveCriticalSection(&pIO->Lock);
194+ return Copied;
195+}
196+
197+size_t SFTP_PeekThreadIO(void* pBuffer, size_t Size)
198+{
199+ SFTPSTATUS* pSFTP;
200+ if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))
201+ return SFTP_PeekIOBuffer(&pSFTP->InBuffer, pBuffer, Size);
202+ return 0;
203+}
204+
205+size_t SFTP_ReadThreadIO(void* pBuffer, size_t Size)
206+{
207+ SFTPSTATUS* pSFTP;
208+ if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))
209+ return SFTP_ReadIOBuffer(&pSFTP->InBuffer, pBuffer, Size);
210+ return 0;
211+}
212+
213+size_t SFTP_WriteThreadIO(const void* pBuffer, size_t Size)
214+{
215+ SFTPSTATUS* pSFTP;
216+ if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))
217+ return SFTP_WriteIOBuffer(&pSFTP->OutBuffer, pBuffer, Size);
218+ return 0;
219+}
220+
221+size_t SFTP_ReadThreadIOLine(void* pBuffer, size_t Size)
222+{
223+ SFTPSTATUS* pSFTP;
224+ if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))
225+ return SFTP_ReadIOBufferLine(&pSFTP->InBuffer, pBuffer, Size);
226+ return 0;
227+}
228+
229+size_t SFTP_PeekThreadDataIO(void* pBuffer, size_t Size)
230+{
231+ SFTPSTATUS* pSFTP;
232+ if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))
233+ return SFTP_PeekIOBuffer(&pSFTP->DataInBuffer, pBuffer, Size);
234+ return 0;
235+}
236+
237+size_t SFTP_ReadThreadDataIO(void* pBuffer, size_t Size)
238+{
239+ SFTPSTATUS* pSFTP;
240+ if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))
241+ return SFTP_ReadIOBuffer(&pSFTP->DataInBuffer, pBuffer, Size);
242+ return 0;
243+}
244+
245+size_t SFTP_WriteThreadDataIO(const void* pBuffer, size_t Size)
246+{
247+ SFTPSTATUS* pSFTP;
248+ if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))
249+ return SFTP_WriteIOBuffer(&pSFTP->DataOutBuffer, pBuffer, Size);
250+ return 0;
251+}
252+
253+BOOL SFTP_GetThreadFilePositon(DWORD* pLow, LONG* pHigh)
254+{
255+ SFTPSTATUS* pSFTP;
256+ if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))
257+ {
258+ *pLow = pSFTP->FilePosition.LowPart;
259+ *pHigh = pSFTP->FilePosition.HighPart;
260+ return TRUE;
261+ }
262+ return FALSE;
263+}
264+
265+// 以下ラッパー
266+
267+HANDLE GetStdHandleX(DWORD nStdHandle)
268+{
269+ HANDLE r = INVALID_HANDLE_VALUE;
270+ if(!g_hStdIn)
271+ g_hStdIn = (HANDLE)1;
272+ if(!g_hStdOut)
273+ g_hStdOut = (HANDLE)2;
274+ if(!g_hStdErr)
275+ g_hStdErr = (HANDLE)3;
276+ if(nStdHandle == STD_INPUT_HANDLE)
277+ r = g_hStdIn;
278+ if(nStdHandle == STD_OUTPUT_HANDLE)
279+ r = g_hStdOut;
280+ if(nStdHandle == STD_ERROR_HANDLE)
281+ r = g_hStdErr;
282+ return r;
283+}
284+
285+BOOL GetConsoleModeX(HANDLE hConsoleHandle, LPDWORD lpMode)
286+{
287+ BOOL r = FALSE;
288+ return r;
289+}
290+
291+BOOL SetConsoleModeX(HANDLE hConsoleHandle, DWORD dwMode)
292+{
293+ BOOL r = FALSE;
294+ return r;
295+}
296+
297+BOOL ReadFileX(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
298+{
299+ BOOL r = FALSE;
300+ if(hFile == g_hStdIn)
301+ {
302+ *lpNumberOfBytesRead = (DWORD)SFTP_ReadThreadIOLine(lpBuffer, nNumberOfBytesToRead);
303+ if(*lpNumberOfBytesRead > 0)
304+ r = TRUE;
305+ }
306+ else if(hFile == g_hStdOut)
307+ {
308+ }
309+ else if(hFile == g_hStdErr)
310+ {
311+ }
312+ return r;
313+}
314+
315+BOOL WriteFileX(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
316+{
317+ BOOL r = FALSE;
318+ if(hFile == g_hStdIn)
319+ {
320+ }
321+ else if(hFile == g_hStdOut)
322+ {
323+ *lpNumberOfBytesWritten = (DWORD)SFTP_WriteThreadIO(lpBuffer, nNumberOfBytesToWrite);
324+ if(*lpNumberOfBytesWritten == nNumberOfBytesToWrite)
325+ r = TRUE;
326+ }
327+ else if(hFile == g_hStdErr)
328+ {
329+ *lpNumberOfBytesWritten = (DWORD)SFTP_WriteThreadIO(lpBuffer, nNumberOfBytesToWrite);
330+ if(*lpNumberOfBytesWritten == nNumberOfBytesToWrite)
331+ r = TRUE;
332+ }
333+ return r;
334+}
335+
336+int printfX(const char * _Format, ...)
337+{
338+ int r = 0;
339+ va_list v;
340+ char Temp[1024];
341+ va_start(v, _Format);
342+ vsprintf(Temp, _Format, v);
343+ r = (int)SFTP_WriteThreadIO(Temp, strlen(Temp));
344+ va_end(v);
345+ return r;
346+}
347+
348+int putsX(const char * _Str)
349+{
350+ int r = 0;
351+ r = (int)SFTP_WriteThreadIO(_Str, strlen(_Str));
352+ return r;
353+}
354+
355+int fprintfX(FILE * _File, const char * _Format, ...)
356+{
357+ int r = 0;
358+ va_list v;
359+ char Temp[1024];
360+ va_start(v, _Format);
361+ if(_File == stdout)
362+ {
363+ vsprintf(Temp, _Format, v);
364+ r = (int)SFTP_WriteThreadIO(Temp, strlen(Temp));
365+ }
366+ else if(_File == stderr)
367+ {
368+ vsprintf(Temp, _Format, v);
369+ r = (int)SFTP_WriteThreadIO(Temp, strlen(Temp));
370+ }
371+ else
372+ r = vfprintf(_File, _Format, v);
373+ va_end(v);
374+ return r;
375+}
376+
377+char * fgetsX(char * _Buf, int _MaxCount, FILE * _File)
378+{
379+ char * r = NULL;
380+ if(_File == stdin)
381+ {
382+ memset(_Buf, 0, _MaxCount);
383+ SFTP_ReadThreadIOLine(_Buf, _MaxCount - 1);
384+ r = _Buf;
385+ }
386+ else
387+ r = fgets(_Buf, _MaxCount, _File);
388+ return r;
389+}
390+
391+int fputsX(const char * _Str, FILE * _File)
392+{
393+ int r = 0;
394+ if(_File == stdout)
395+ {
396+ r = (int)SFTP_WriteThreadIO(_Str, strlen(_Str));
397+ }
398+ else if(_File == stderr)
399+ {
400+ r = (int)SFTP_WriteThreadIO(_Str, strlen(_Str));
401+ }
402+ else
403+ r = fputs(_Str, _File);
404+ return r;
405+}
406+
407+int fflushX(FILE * _File)
408+{
409+ int r = 0;
410+ if(_File == stdout)
411+ {
412+ }
413+ else if(_File == stderr)
414+ {
415+ }
416+ else
417+ r = fflush(_File);
418+ return r;
419+}
420+
421+void exitX(int _Code)
422+{
423+ SFTPSTATUS* pSFTP;
424+ if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))
425+ {
426+ pSFTP->bExit = TRUE;
427+ SFTP_AbortIOBuffer(&pSFTP->InBuffer, TRUE);
428+ SFTP_AbortIOBuffer(&pSFTP->OutBuffer, TRUE);
429+ SFTP_AbortIOBuffer(&pSFTP->DataInBuffer, TRUE);
430+ SFTP_AbortIOBuffer(&pSFTP->DataOutBuffer, TRUE);
431+ }
432+ TerminateThread(GetCurrentThread(), (DWORD)_Code);
433+}
434+
--- /dev/null
+++ b/putty/iowrapper.h
@@ -0,0 +1,96 @@
1+// iowrapper.h
2+// Copyright (C) 2011 Suguru Kawamoto
3+// 標準入出力APIラッパー
4+
5+#ifndef __IOWRAPPER_H__
6+#define __IOWRAPPER_H__
7+
8+#include <stdio.h>
9+#include <windows.h>
10+
11+#ifndef DO_NOT_REPLACE
12+
13+#undef GetStdHandle
14+#define GetStdHandle GetStdHandleX
15+HANDLE GetStdHandleX(DWORD nStdHandle);
16+#undef GetConsoleMode
17+#define GetConsoleMode GetConsoleModeX
18+BOOL GetConsoleModeX(HANDLE hConsoleHandle, LPDWORD lpMode);
19+#undef SetConsoleMode
20+#define SetConsoleMode SetConsoleModeX
21+BOOL SetConsoleModeX(HANDLE hConsoleHandle, DWORD dwMode);
22+#undef ReadFile
23+#define ReadFile ReadFileX
24+BOOL ReadFileX(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
25+#undef WriteFile
26+#define WriteFile WriteFileX
27+BOOL WriteFileX(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
28+#undef printf
29+#define printf printfX
30+int printfX(const char * _Format, ...);
31+#undef gets
32+#define gets getsX
33+char * getsX(char * _Buffer);
34+#undef puts
35+#define puts putsX
36+int putsX(const char * _Str);
37+#undef fprintf
38+#define fprintf fprintfX
39+int fprintfX(FILE * _File, const char * _Format, ...);
40+#undef fgets
41+#define fgets fgetsX
42+char * fgetsX(char * _Buf, int _MaxCount, FILE * _File);
43+#undef fputs
44+#define fputs fputsX
45+int fputsX(const char * _Str, FILE * _File);
46+#undef exit
47+#define exit exitX
48+void exitX(int _Code);
49+
50+#endif
51+
52+typedef BOOL (__stdcall* LPSFTPTIMEOUTCALLBACK)(BOOL*);
53+
54+typedef struct
55+{
56+ CRITICAL_SECTION Lock;
57+ BYTE* pBuffer;
58+ size_t Length;
59+ size_t Written;
60+ size_t Read;
61+ BOOL bAborted;
62+ LPSFTPTIMEOUTCALLBACK pCallback;
63+} SFTPIOBUFFER;
64+
65+typedef struct
66+{
67+ DWORD ThreadId;
68+ BOOL bExit;
69+ LPSFTPTIMEOUTCALLBACK pCallback;
70+ SFTPIOBUFFER InBuffer;
71+ SFTPIOBUFFER OutBuffer;
72+ SFTPIOBUFFER DataInBuffer;
73+ SFTPIOBUFFER DataOutBuffer;
74+ LARGE_INTEGER FilePosition;
75+} SFTPSTATUS;
76+
77+DWORD WINAPI SFTP_ThreadProc(LPVOID lpParameter);
78+SFTPSTATUS* FindSFTPStatus(DWORD ThreadId);
79+BOOL SFTP_InitializeIOBuffer(SFTPIOBUFFER* pIO, size_t Length);
80+void SFTP_UninitializeIOBuffer(SFTPIOBUFFER* pIO);
81+void SFTP_AbortIOBuffer(SFTPIOBUFFER* pIO, BOOL bAborted);
82+size_t SFTP_PeekIOBuffer(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size);
83+size_t SFTP_ReadIOBuffer(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size);
84+size_t SFTP_WriteIOBuffer(SFTPIOBUFFER* pIO, const void* pBuffer, size_t Size);
85+size_t SFTP_ReadIOBufferLine(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size);
86+size_t SFTP_PeekThreadIO(void* pBuffer, size_t Size);
87+size_t SFTP_ReadThreadIO(void* pBuffer, size_t Size);
88+size_t SFTP_WriteThreadIO(const void* pBuffer, size_t Size);
89+size_t SFTP_ReadThreadIOLine(void* pBuffer, size_t Size);
90+size_t SFTP_PeekThreadDataIO(void* pBuffer, size_t Size);
91+size_t SFTP_ReadThreadDataIO(void* pBuffer, size_t Size);
92+size_t SFTP_WriteThreadDataIO(const void* pBuffer, size_t Size);
93+BOOL SFTP_GetThreadFilePositon(DWORD* pLow, LONG* pHigh);
94+
95+#endif
96+
--- /dev/null
+++ b/putty/mbswrapper.c
@@ -0,0 +1,955 @@
1+// mbswrapper.c
2+// Copyright (C) 2011 Suguru Kawamoto
3+// マルチバイト文字ワイド文字APIラッパー
4+// マルチバイト文字はUTF-8、ワイド文字はUTF-16であるものとする
5+// 全ての制御用の文字はASCIIの範囲であるため、Shift_JISとUTF-8間の変換は不要
6+
7+#define UNICODE
8+#define _UNICODE
9+
10+#include <stdio.h>
11+#include <tchar.h>
12+#include <direct.h>
13+#include <windows.h>
14+#include <commctrl.h>
15+#include <shlobj.h>
16+#include <htmlhelp.h>
17+
18+#define DO_NOT_REPLACE
19+#include "mbswrapper.h"
20+
21+// マルチバイト文字列からワイド文字列へ変換
22+int MtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)
23+{
24+ if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)
25+ return 0;
26+ if(pDst)
27+ return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, pDst, size);
28+ return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, NULL, 0);
29+}
30+
31+// ワイド文字列からマルチバイト文字列へ変換
32+int WtoM(LPSTR pDst, int size, LPCWSTR pSrc, int count)
33+{
34+ if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)
35+ return 0;
36+ if(pDst)
37+ return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, pDst, size, NULL, NULL);
38+ return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, NULL, 0, NULL, NULL);
39+}
40+
41+// Shift_JIS文字列からワイド文字列へ変換
42+int AtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)
43+{
44+ if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)
45+ return 0;
46+ if(pDst)
47+ return MultiByteToWideChar(CP_ACP, 0, pSrc, count, pDst, size);
48+ return MultiByteToWideChar(CP_ACP, 0, pSrc, count, NULL, 0);
49+}
50+
51+// ワイド文字列からShift_JIS文字列へ変換
52+int WtoA(LPSTR pDst, int size, LPCWSTR pSrc, int count)
53+{
54+ if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)
55+ return 0;
56+ if(pDst)
57+ return WideCharToMultiByte(CP_ACP, 0, pSrc, count, pDst, size, NULL, NULL);
58+ return WideCharToMultiByte(CP_ACP, 0, pSrc, count, NULL, 0, NULL, NULL);
59+}
60+
61+// マルチバイト文字列バッファ終端を強制的にNULLで置換
62+int TerminateStringM(LPSTR lpString, int size)
63+{
64+ int i;
65+ if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)
66+ return 0;
67+ for(i = 0; i < size; i++)
68+ {
69+ if(lpString[i] == '\0')
70+ return i;
71+ }
72+ i--;
73+ lpString[i] = '\0';
74+ return i;
75+}
76+
77+// ワイド文字列バッファ終端を強制的にNULLで置換
78+int TerminateStringW(LPWSTR lpString, int size)
79+{
80+ int i;
81+ if(lpString < (LPWSTR)0x00010000 || lpString == (LPWSTR)~0)
82+ return 0;
83+ for(i = 0; i < size; i++)
84+ {
85+ if(lpString[i] == L'\0')
86+ return i;
87+ }
88+ i--;
89+ lpString[i] = L'\0';
90+ return i;
91+}
92+
93+// Shift_JIS文字列バッファ終端を強制的にNULLで置換
94+int TerminateStringA(LPSTR lpString, int size)
95+{
96+ int i;
97+ if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)
98+ return 0;
99+ for(i = 0; i < size; i++)
100+ {
101+ if(lpString[i] == '\0')
102+ return i;
103+ }
104+ i--;
105+ lpString[i] = '\0';
106+ return i;
107+}
108+
109+// NULL区切り複数マルチバイト文字列の長さを取得
110+size_t GetMultiStringLengthM(LPCSTR lpString)
111+{
112+ size_t i;
113+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
114+ return 0;
115+ i = 0;
116+ while(lpString[i] != '\0' || lpString[i + 1] != '\0')
117+ {
118+ i++;
119+ }
120+ i++;
121+ return i;
122+}
123+
124+// NULL区切り複数ワイド文字列の長さを取得
125+size_t GetMultiStringLengthW(LPCWSTR lpString)
126+{
127+ size_t i;
128+ if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)
129+ return 0;
130+ i = 0;
131+ while(lpString[i] != L'\0' || lpString[i + 1] != L'\0')
132+ {
133+ i++;
134+ }
135+ i++;
136+ return i;
137+}
138+
139+// NULL区切り複数Shift_JIS文字列の長さを取得
140+size_t GetMultiStringLengthA(LPCSTR lpString)
141+{
142+ size_t i;
143+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
144+ return 0;
145+ i = 0;
146+ while(lpString[i] != '\0' || lpString[i + 1] != '\0')
147+ {
148+ i++;
149+ }
150+ i++;
151+ return i;
152+}
153+
154+// NULL区切りマルチバイト文字列からワイド文字列へ変換
155+int MtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)
156+{
157+ int i;
158+ if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)
159+ return 0;
160+ if(!pDst)
161+ return GetMultiStringLengthM(pSrc);
162+ i = 0;
163+ while(*pSrc != '\0')
164+ {
165+ i += MultiByteToWideChar(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1);
166+ pSrc += strlen(pSrc) + 1;
167+ }
168+ pDst[i] = L'\0';
169+ return i;
170+}
171+
172+// NULL区切りワイド文字列からマルチバイト文字列へ変換
173+int WtoMMultiString(LPSTR pDst, int size, LPCWSTR pSrc)
174+{
175+ int i;
176+ if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)
177+ return 0;
178+ if(!pDst)
179+ return GetMultiStringLengthW(pSrc);
180+ i = 0;
181+ while(*pSrc != L'\0')
182+ {
183+ i += WideCharToMultiByte(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);
184+ pSrc += wcslen(pSrc) + 1;
185+ }
186+ pDst[i] = '\0';
187+ return i;
188+}
189+
190+// NULL区切りShift_JIS文字列からワイド文字列へ変換
191+int AtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)
192+{
193+ int i;
194+ if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)
195+ return 0;
196+ if(!pDst)
197+ return GetMultiStringLengthA(pSrc);
198+ i = 0;
199+ while(*pSrc != '\0')
200+ {
201+ i += MultiByteToWideChar(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1);
202+ pSrc += strlen(pSrc) + 1;
203+ }
204+ pDst[i] = L'\0';
205+ return i;
206+}
207+
208+// NULL区切りワイド文字列からShift_JIS文字列へ変換
209+int WtoAMultiString(LPSTR pDst, int size, LPCWSTR pSrc)
210+{
211+ int i;
212+ if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)
213+ return 0;
214+ if(!pDst)
215+ return GetMultiStringLengthW(pSrc);
216+ i = 0;
217+ while(*pSrc != L'\0')
218+ {
219+ i += WideCharToMultiByte(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);
220+ pSrc += wcslen(pSrc) + 1;
221+ }
222+ pDst[i] = '\0';
223+ return i;
224+}
225+
226+// マルチバイト文字列用のメモリを確保
227+char* AllocateStringM(int size)
228+{
229+ char* p;
230+ // 0が指定される場合があるため1文字分追加
231+ p = (char*)malloc(sizeof(char) * (size + 1));
232+ // 念のため先頭にNULL文字を代入
233+ if(p)
234+ *p = '\0';
235+ return p;
236+}
237+
238+// ワイド文字列用のメモリを確保
239+wchar_t* AllocateStringW(int size)
240+{
241+ wchar_t* p;
242+ // 0が指定される場合があるため1文字分追加
243+ p = (wchar_t*)malloc(sizeof(wchar_t) * (size + 1));
244+ // 念のため先頭にNULL文字を代入
245+ if(p)
246+ *p = L'\0';
247+ return p;
248+}
249+
250+// Shift_JIS文字列用のメモリを確保
251+char* AllocateStringA(int size)
252+{
253+ char* p;
254+ // 0が指定される場合があるため1文字分追加
255+ p = (char*)malloc(sizeof(char) * (size + 1));
256+ // 念のため先頭にNULL文字を代入
257+ if(p)
258+ *p = '\0';
259+ return p;
260+}
261+
262+// メモリを確保してマルチバイト文字列からワイド文字列へ変換
263+// リソースIDならば元の値を返す
264+wchar_t* DuplicateMtoW(LPCSTR lpString, int c)
265+{
266+ wchar_t* p;
267+ int i;
268+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
269+ return (wchar_t*)lpString;
270+ if(c < 0)
271+ c = strlen(lpString);
272+ p = AllocateStringW(MtoW(NULL, 0, lpString, c) + 1);
273+ if(p)
274+ {
275+ i = MtoW(p, 65535, lpString, c);
276+ p[i] = L'\0';
277+ }
278+ return p;
279+}
280+
281+// 指定したサイズのメモリを確保してマルチバイト文字列からワイド文字列へ変換
282+// リソースIDならば元の値を返す
283+wchar_t* DuplicateMtoWBuffer(LPCSTR lpString, int c, int size)
284+{
285+ wchar_t* p;
286+ int i;
287+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
288+ return (wchar_t*)lpString;
289+ if(c < 0)
290+ c = strlen(lpString);
291+ p = AllocateStringW(size);
292+ if(p)
293+ {
294+ i = MtoW(p, size, lpString, c);
295+ p[i] = L'\0';
296+ }
297+ return p;
298+}
299+
300+// メモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換
301+// リソースIDならば元の値を返す
302+wchar_t* DuplicateMtoWMultiString(LPCSTR lpString)
303+{
304+ int count;
305+ wchar_t* p;
306+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
307+ return (wchar_t*)lpString;
308+ count = GetMultiStringLengthM(lpString) + 1;
309+ p = AllocateStringW(count);
310+ if(p)
311+ MtoW(p, count, lpString, count);
312+ return p;
313+}
314+
315+// 指定したサイズのメモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換
316+// リソースIDならば元の値を返す
317+wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size)
318+{
319+ int count;
320+ wchar_t* p;
321+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
322+ return (wchar_t*)lpString;
323+ count = GetMultiStringLengthM(lpString) + 1;
324+ p = AllocateStringW(size);
325+ if(p)
326+ {
327+ MtoW(p, size, lpString, count);
328+ p[size - 2] = L'\0';
329+ p[size - 1] = L'\0';
330+ }
331+ return p;
332+}
333+
334+// メモリを確保してワイド文字列からマルチバイト文字列へ変換
335+// リソースIDならば元の値を返す
336+char* DuplicateWtoM(LPCWSTR lpString, int c)
337+{
338+ char* p;
339+ int i;
340+ if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)
341+ return (char*)lpString;
342+ if(c < 0)
343+ c = wcslen(lpString);
344+ p = AllocateStringM(WtoM(NULL, 0, lpString, c) + 1);
345+ if(p)
346+ {
347+ i = WtoM(p, 65535, lpString, c);
348+ p[i] = L'\0';
349+ }
350+ return p;
351+}
352+
353+// メモリを確保してShift_JIS文字列からワイド文字列へ変換
354+// リソースIDならば元の値を返す
355+wchar_t* DuplicateAtoW(LPCSTR lpString, int c)
356+{
357+ wchar_t* p;
358+ int i;
359+ if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)
360+ return (wchar_t*)lpString;
361+ if(c < 0)
362+ c = strlen(lpString);
363+ p = AllocateStringW(AtoW(NULL, 0, lpString, c) + 1);
364+ if(p)
365+ {
366+ i = AtoW(p, 65535, lpString, c);
367+ p[i] = L'\0';
368+ }
369+ return p;
370+}
371+
372+// メモリを確保してワイド文字列からShift_JIS文字列へ変換
373+// リソースIDならば元の値を返す
374+char* DuplicateWtoA(LPCWSTR lpString, int c)
375+{
376+ char* p;
377+ int i;
378+ if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)
379+ return (char*)lpString;
380+ if(c < 0)
381+ c = wcslen(lpString);
382+ p = AllocateStringA(WtoA(NULL, 0, lpString, c) + 1);
383+ if(p)
384+ {
385+ i = WtoA(p, 65535, lpString, c);
386+ p[i] = L'\0';
387+ }
388+ return p;
389+}
390+
391+// マルチバイト文字列からコードポイントと次のポインタを取得
392+// エンコードが不正な場合は0x80000000を返す
393+DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext)
394+{
395+ DWORD Code;
396+ int i;
397+ Code = 0;
398+ if((*lpString & 0xfe) == 0xfc)
399+ {
400+ i = 5;
401+ Code |= (DWORD)*lpString & 0x01;
402+ }
403+ else if((*lpString & 0xfc) == 0xf8)
404+ {
405+ i = 4;
406+ Code |= (DWORD)*lpString & 0x03;
407+ }
408+ else if((*lpString & 0xf8) == 0xf0)
409+ {
410+ i = 3;
411+ Code |= (DWORD)*lpString & 0x07;
412+ }
413+ else if((*lpString & 0xf0) == 0xe0)
414+ {
415+ i = 2;
416+ Code |= (DWORD)*lpString & 0x0f;
417+ }
418+ else if((*lpString & 0xe0) == 0xc0)
419+ {
420+ i = 1;
421+ Code |= (DWORD)*lpString & 0x1f;
422+ }
423+ else if((*lpString & 0x80) == 0x00)
424+ {
425+ i = 0;
426+ Code |= (DWORD)*lpString & 0x7f;
427+ }
428+ else
429+ i = -1;
430+ lpString++;
431+ while((*lpString & 0xc0) == 0x80)
432+ {
433+ i--;
434+ Code = Code << 6;
435+ Code |= (DWORD)*lpString & 0x3f;
436+ lpString++;
437+ }
438+ if(i != 0)
439+ Code = 0x80000000;
440+ if(ppNext)
441+ *ppNext = lpString;
442+ return Code;
443+}
444+
445+// マルチバイト文字列の冗長表現を修正
446+// 修正があればTRUEを返す
447+// 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能
448+BOOL FixStringM(LPSTR pDst, LPCSTR pSrc)
449+{
450+ BOOL bResult;
451+ char* p;
452+ DWORD Code;
453+ int i;
454+ char c;
455+ bResult = FALSE;
456+ p = (char*)pSrc;
457+ while(*pSrc != '\0')
458+ {
459+ Code = GetNextCharM(pSrc, &pSrc);
460+ if(Code & 0x80000000)
461+ continue;
462+ else if(Code & 0x7c000000)
463+ {
464+ i = 5;
465+ c = (char)(0xfc | (Code >> (6 * i)));
466+ }
467+ else if(Code & 0x03e00000)
468+ {
469+ i = 4;
470+ c = (char)(0xf8 | (Code >> (6 * i)));
471+ }
472+ else if(Code & 0x001f0000)
473+ {
474+ i = 3;
475+ c = (char)(0xf0 | (Code >> (6 * i)));
476+ }
477+ else if(Code & 0x0000f800)
478+ {
479+ i = 2;
480+ c = (char)(0xe0 | (Code >> (6 * i)));
481+ }
482+ else if(Code & 0x00000780)
483+ {
484+ i = 1;
485+ c = (char)(0xc0 | (Code >> (6 * i)));
486+ }
487+ else
488+ {
489+ i = 0;
490+ c = (char)Code;
491+ }
492+ if(c != *p)
493+ bResult = TRUE;
494+ p++;
495+ *pDst = c;
496+ pDst++;
497+ while(i > 0)
498+ {
499+ i--;
500+ c = (char)(0x80 | ((Code >> (6 * i)) & 0x3f));
501+ if(c != *p)
502+ bResult = TRUE;
503+ p++;
504+ *pDst = c;
505+ pDst++;
506+ }
507+ }
508+ if(*p != '\0')
509+ bResult = TRUE;
510+ *pDst = '\0';
511+ return bResult;
512+}
513+
514+// NULL区切りマルチバイト文字列の冗長表現を修正
515+// 修正があればTRUEを返す
516+// 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能
517+BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc)
518+{
519+ BOOL bResult;
520+ int Length;
521+ bResult = FALSE;
522+ while(*pSrc != '\0')
523+ {
524+ Length = strlen(pSrc) + 1;
525+ bResult = bResult | FixStringM(pDst, pSrc);
526+ pSrc += Length;
527+ pDst += strlen(pDst) + 1;
528+ }
529+ *pDst = '\0';
530+ return bResult;
531+}
532+
533+// マルチバイト文字列の冗長表現を確認
534+// 冗長表現があればTRUEを返す
535+BOOL CheckStringM(LPCSTR lpString)
536+{
537+ BOOL bResult;
538+ char* p;
539+ bResult = FALSE;
540+ p = AllocateStringM(strlen(lpString) + 1);
541+ if(p)
542+ {
543+ bResult = FixStringM(p, lpString);
544+ FreeDuplicatedString(p);
545+ }
546+ return bResult;
547+}
548+
549+// NULL区切りマルチバイト文字列の冗長表現を確認
550+// 冗長表現があればTRUEを返す
551+BOOL CheckMultiStringM(LPCSTR lpString)
552+{
553+ BOOL bResult;
554+ char* p;
555+ bResult = FALSE;
556+ p = AllocateStringM(GetMultiStringLengthM(lpString) + 1);
557+ if(p)
558+ {
559+ bResult = FixMultiStringM(p, lpString);
560+ FreeDuplicatedString(p);
561+ }
562+ return bResult;
563+}
564+
565+// 文字列用に確保したメモリを開放
566+// リソースIDならば何もしない
567+void FreeDuplicatedString(void* p)
568+{
569+ if(p < (void*)0x00010000 || p == (void*)~0)
570+ return;
571+ free(p);
572+}
573+
574+// 以下ラッパー
575+// 戻り値バッファ r
576+// ワイド文字バッファ pw%d
577+// マルチバイト文字バッファ pm%d
578+// 引数バッファ a%d
579+
580+#pragma warning(disable:4102)
581+#define START_ROUTINE do{
582+#define END_ROUTINE }while(0);end_of_routine:
583+#define QUIT_ROUTINE goto end_of_routine;
584+
585+HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
586+{
587+ HANDLE r = INVALID_HANDLE_VALUE;
588+ wchar_t* pw0 = NULL;
589+START_ROUTINE
590+ pw0 = DuplicateMtoW(lpFileName, -1);
591+ r = CreateFileW(pw0, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
592+END_ROUTINE
593+ FreeDuplicatedString(pw0);
594+ return r;
595+}
596+
597+HANDLE FindFirstFileM(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
598+{
599+ HANDLE r = INVALID_HANDLE_VALUE;
600+ wchar_t* pw0 = NULL;
601+ WIN32_FIND_DATAW a0;
602+START_ROUTINE
603+ pw0 = DuplicateMtoW(lpFileName, -1);
604+ r = FindFirstFileW(pw0, &a0);
605+ if(r != INVALID_HANDLE_VALUE)
606+ {
607+ lpFindFileData->dwFileAttributes = a0.dwFileAttributes;
608+ lpFindFileData->ftCreationTime = a0.ftCreationTime;
609+ lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;
610+ lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;
611+ lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;
612+ lpFindFileData->nFileSizeLow = a0.nFileSizeLow;
613+ lpFindFileData->dwReserved0 = a0.dwReserved0;
614+ lpFindFileData->dwReserved1 = a0.dwReserved1;
615+ WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);
616+ WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);
617+ }
618+END_ROUTINE
619+ FreeDuplicatedString(pw0);
620+ return r;
621+}
622+
623+BOOL FindNextFileM(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
624+{
625+ BOOL r = FALSE;
626+ WIN32_FIND_DATAW a0;
627+START_ROUTINE
628+ r = FindNextFileW(hFindFile, &a0);
629+ if(r)
630+ {
631+ lpFindFileData->dwFileAttributes = a0.dwFileAttributes;
632+ lpFindFileData->ftCreationTime = a0.ftCreationTime;
633+ lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;
634+ lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;
635+ lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;
636+ lpFindFileData->nFileSizeLow = a0.nFileSizeLow;
637+ lpFindFileData->dwReserved0 = a0.dwReserved0;
638+ lpFindFileData->dwReserved1 = a0.dwReserved1;
639+ WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);
640+ WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);
641+ }
642+END_ROUTINE
643+ return r;
644+}
645+
646+DWORD GetCurrentDirectoryM(DWORD nBufferLength, LPSTR lpBuffer)
647+{
648+ DWORD r = 0;
649+ wchar_t* pw0 = NULL;
650+START_ROUTINE
651+ // TODO: バッファが不十分な場合に必要なサイズを返す
652+ pw0 = AllocateStringW(nBufferLength * 4);
653+ GetCurrentDirectoryW(nBufferLength * 4, pw0);
654+ WtoM(lpBuffer, nBufferLength, pw0, -1);
655+ r = TerminateStringM(lpBuffer, nBufferLength);
656+END_ROUTINE
657+ FreeDuplicatedString(pw0);
658+ return r;
659+}
660+
661+BOOL SetCurrentDirectoryM(LPCSTR lpPathName)
662+{
663+ BOOL r = FALSE;
664+ wchar_t* pw0 = NULL;
665+START_ROUTINE
666+ pw0 = DuplicateMtoW(lpPathName, -1);
667+ r = SetCurrentDirectoryW(pw0);
668+END_ROUTINE
669+ FreeDuplicatedString(pw0);
670+ return r;
671+}
672+
673+DWORD GetTempPathM(DWORD nBufferLength, LPSTR lpBuffer)
674+{
675+ DWORD r = 0;
676+ wchar_t* pw0 = NULL;
677+START_ROUTINE
678+ pw0 = AllocateStringW(nBufferLength * 4);
679+ GetTempPathW(nBufferLength * 4, pw0);
680+ WtoM(lpBuffer, nBufferLength, pw0, -1);
681+ r = TerminateStringM(lpBuffer, nBufferLength);
682+END_ROUTINE
683+ FreeDuplicatedString(pw0);
684+ return r;
685+}
686+
687+DWORD GetFileAttributesM(LPCSTR lpFileName)
688+{
689+ DWORD r = FALSE;
690+ wchar_t* pw0 = NULL;
691+START_ROUTINE
692+ pw0 = DuplicateMtoW(lpFileName, -1);
693+ r = GetFileAttributesW(pw0);
694+END_ROUTINE
695+ FreeDuplicatedString(pw0);
696+ return r;
697+}
698+
699+DWORD GetModuleFileNameM(HMODULE hModule, LPCH lpFilename, DWORD nSize)
700+{
701+ DWORD r = 0;
702+ wchar_t* pw0 = NULL;
703+START_ROUTINE
704+ pw0 = AllocateStringW(nSize * 4);
705+ GetModuleFileNameW(hModule, pw0, nSize * 4);
706+ WtoM(lpFilename, nSize, pw0, -1);
707+ r = TerminateStringM(lpFilename, nSize);
708+END_ROUTINE
709+ FreeDuplicatedString(pw0);
710+ return r;
711+}
712+
713+BOOL CopyFileM(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, BOOL bFailIfExists)
714+{
715+ BOOL r = FALSE;
716+ wchar_t* pw0 = NULL;
717+ wchar_t* pw1 = NULL;
718+START_ROUTINE
719+ pw0 = DuplicateMtoW(lpExistingFileName, -1);
720+ pw1 = DuplicateMtoW(lpNewFileName, -1);
721+ r = CopyFileW(pw0, pw1, bFailIfExists);
722+END_ROUTINE
723+ FreeDuplicatedString(pw0);
724+ FreeDuplicatedString(pw1);
725+ return r;
726+}
727+
728+int mkdirM(const char * _Path)
729+{
730+ int r = -1;
731+ wchar_t* pw0 = NULL;
732+START_ROUTINE
733+ pw0 = DuplicateMtoW(_Path, -1);
734+ r = _wmkdir(pw0);
735+END_ROUTINE
736+ FreeDuplicatedString(pw0);
737+ return r;
738+}
739+
740+int _mkdirM(const char * _Path)
741+{
742+ int r = -1;
743+ wchar_t* pw0 = NULL;
744+START_ROUTINE
745+ pw0 = DuplicateMtoW(_Path, -1);
746+ r = _wmkdir(pw0);
747+END_ROUTINE
748+ FreeDuplicatedString(pw0);
749+ return r;
750+}
751+
752+int rmdirM(const char * _Path)
753+{
754+ int r = -1;
755+ wchar_t* pw0 = NULL;
756+START_ROUTINE
757+ pw0 = DuplicateMtoW(_Path, -1);
758+ r = _wrmdir(pw0);
759+END_ROUTINE
760+ FreeDuplicatedString(pw0);
761+ return r;
762+}
763+
764+int _rmdirM(const char * _Path)
765+{
766+ int r = -1;
767+ wchar_t* pw0 = NULL;
768+START_ROUTINE
769+ pw0 = DuplicateMtoW(_Path, -1);
770+ r = _wrmdir(pw0);
771+END_ROUTINE
772+ FreeDuplicatedString(pw0);
773+ return r;
774+}
775+
776+int removeM(const char * _Filename)
777+{
778+ int r = -1;
779+ wchar_t* pw0 = NULL;
780+START_ROUTINE
781+ pw0 = DuplicateMtoW(_Filename, -1);
782+ r = _wremove(pw0);
783+END_ROUTINE
784+ FreeDuplicatedString(pw0);
785+ return r;
786+}
787+
788+int _removeM(const char * _Filename)
789+{
790+ int r = -1;
791+ wchar_t* pw0 = NULL;
792+START_ROUTINE
793+ pw0 = DuplicateMtoW(_Filename, -1);
794+ r = _wremove(pw0);
795+END_ROUTINE
796+ FreeDuplicatedString(pw0);
797+ return r;
798+}
799+
800+int _unlinkM(const char * _Filename)
801+{
802+ int r = -1;
803+ wchar_t* pw0 = NULL;
804+START_ROUTINE
805+ pw0 = DuplicateMtoW(_Filename, -1);
806+ r = _wunlink(pw0);
807+END_ROUTINE
808+ FreeDuplicatedString(pw0);
809+ return r;
810+}
811+
812+size_t _mbslenM(const unsigned char * _Str)
813+{
814+ size_t r = 0;
815+START_ROUTINE
816+ while(GetNextCharM(_Str, &_Str) > 0)
817+ {
818+ r++;
819+ }
820+END_ROUTINE
821+ return r;
822+}
823+
824+unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch)
825+{
826+ unsigned char* r = NULL;
827+ unsigned int c;
828+ unsigned char* p;
829+START_ROUTINE
830+ while((c = GetNextCharM(_Str, &p)) > 0)
831+ {
832+ if(c == _Ch)
833+ break;
834+ _Str = p;
835+ }
836+ if(c == _Ch)
837+ r = (unsigned char*)_Str;
838+END_ROUTINE
839+ return r;
840+}
841+
842+unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch)
843+{
844+ unsigned char* r = NULL;
845+ unsigned int c;
846+ unsigned char* p;
847+START_ROUTINE
848+ while((c = GetNextCharM(_Str, &p)) > 0)
849+ {
850+ if(c == _Ch)
851+ r = (unsigned char*)_Str;
852+ _Str = p;
853+ }
854+ if(c == _Ch)
855+ r = (unsigned char*)_Str;
856+END_ROUTINE
857+ return r;
858+}
859+
860+unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr)
861+{
862+ unsigned char* r = NULL;
863+START_ROUTINE
864+ r = strstr(_Str, _Substr);
865+END_ROUTINE
866+ return r;
867+}
868+
869+int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2)
870+{
871+ int r = 0;
872+START_ROUTINE
873+ r = strcmp(_Str1, _Str2);
874+END_ROUTINE
875+ return r;
876+}
877+
878+int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2)
879+{
880+ int r = 0;
881+START_ROUTINE
882+ r = _stricmp(_Str1, _Str2);
883+END_ROUTINE
884+ return r;
885+}
886+
887+int _mbsncmpM(const unsigned char * _Str1, const unsigned char * _Str2, size_t _MaxCount)
888+{
889+ int r = 0;
890+ DWORD c1;
891+ DWORD c2;
892+START_ROUTINE
893+ c1 = 0;
894+ c2 = 0;
895+ while(_MaxCount > 0)
896+ {
897+ c1 = GetNextCharM(_Str1, &_Str1);
898+ c2 = GetNextCharM(_Str2, &_Str2);
899+ if(c1 != c2)
900+ break;
901+ _MaxCount--;
902+ if(c1 == 0 || c2 == 0)
903+ break;
904+ }
905+ r = c1 - c2;
906+END_ROUTINE
907+ return r;
908+}
909+
910+unsigned char * _mbslwrM(unsigned char * _String)
911+{
912+ unsigned char* r = NULL;
913+START_ROUTINE
914+ r = _strlwr(_String);
915+END_ROUTINE
916+ return r;
917+}
918+
919+unsigned char * _mbsuprM(unsigned char * _String)
920+{
921+ unsigned char* r = NULL;
922+START_ROUTINE
923+ r = _strupr(_String);
924+END_ROUTINE
925+ return r;
926+}
927+
928+unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count)
929+{
930+ unsigned char* r = NULL;
931+START_ROUTINE
932+ while(_Count > 0 && GetNextCharM(_Str, &_Str) > 0)
933+ {
934+ _Count--;
935+ }
936+ r = (unsigned char*)_Str;
937+END_ROUTINE
938+ return r;
939+}
940+
941+FILE * fopenM(const char * _Filename, const char * _Mode)
942+{
943+ FILE* r = NULL;
944+ wchar_t* pw0 = NULL;
945+ wchar_t* pw1 = NULL;
946+START_ROUTINE
947+ pw0 = DuplicateMtoW(_Filename, -1);
948+ pw1 = DuplicateMtoW(_Mode, -1);
949+ r = _wfopen(pw0, pw1);
950+END_ROUTINE
951+ FreeDuplicatedString(pw0);
952+ FreeDuplicatedString(pw1);
953+ return r;
954+}
955+
--- /dev/null
+++ b/putty/mbswrapper.h
@@ -0,0 +1,130 @@
1+// mbswrapper.h
2+// Copyright (C) 2011 Suguru Kawamoto
3+// マルチバイト文字ワイド文字APIラッパー
4+
5+#ifndef __MBSWRAPPER_H__
6+#define __MBSWRAPPER_H__
7+
8+#include <stdio.h>
9+#include <windows.h>
10+#include <shlobj.h>
11+
12+#ifndef DO_NOT_REPLACE
13+
14+#undef CreateFile
15+#define CreateFile CreateFileM
16+HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
17+#undef FindFirstFile
18+#define FindFirstFile FindFirstFileM
19+HANDLE FindFirstFileM(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData);
20+#undef FindNextFile
21+#define FindNextFile FindNextFileM
22+BOOL FindNextFileM(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData);
23+#undef GetCurrentDirectory
24+#define GetCurrentDirectory GetCurrentDirectoryM
25+DWORD GetCurrentDirectoryM(DWORD nBufferLength, LPSTR lpBuffer);
26+#undef SetCurrentDirectory
27+#define SetCurrentDirectory SetCurrentDirectoryM
28+BOOL SetCurrentDirectoryM(LPCSTR lpPathName);
29+#undef GetTempPath
30+#define GetTempPath GetTempPathM
31+DWORD GetTempPathM(DWORD nBufferLength, LPSTR lpBuffer);
32+#undef GetFileAttributes
33+#define GetFileAttributes GetFileAttributesM
34+DWORD GetFileAttributesM(LPCSTR lpFileName);
35+#undef GetModuleFileName
36+#define GetModuleFileName GetModuleFileNameM
37+DWORD GetModuleFileNameM(HMODULE hModule, LPCH lpFilename, DWORD nSize);
38+#undef CopyFile
39+#define CopyFile CopyFileM
40+BOOL CopyFileM(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, BOOL bFailIfExists);
41+#undef mkdir
42+#define mkdir _mkdirM
43+int mkdirM(const char * _Path);
44+#undef _mkdir
45+#define _mkdir _mkdirM
46+int _mkdirM(const char * _Path);
47+#undef rmdir
48+#define rmdir rmdirM
49+int rmdirM(const char * _Path);
50+#undef _rmdir
51+#define _rmdir _rmdirM
52+int _rmdirM(const char * _Path);
53+#undef remove
54+#define remove removeM
55+int removeM(const char * _Filename);
56+#undef _remove
57+#define _remove _removeM
58+int _removeM(const char * _Filename);
59+#undef _unlink
60+#define _unlink _unlinkM
61+int _unlinkM(const char * _Filename);
62+#undef _mbslen
63+#define _mbslen _mbslenM
64+size_t _mbslenM(const unsigned char * _Str);
65+#undef _mbschr
66+#define _mbschr _mbschrM
67+unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch);
68+#undef _mbsrchr
69+#define _mbsrchr _mbsrchrM
70+unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch);
71+#undef _mbsstr
72+#define _mbsstr _mbsstrM
73+unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr);
74+#undef _mbscmp
75+#define _mbscmp _mbscmpM
76+int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2);
77+#undef _mbsicmp
78+#define _mbsicmp _mbsicmpM
79+int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2);
80+#undef _mbsncmp
81+#define _mbsncmp _mbsncmpM
82+int _mbsncmpM(const unsigned char * _Str1, const unsigned char * _Str2, size_t _MaxCount);
83+#undef _mbslwr
84+#define _mbslwr _mbslwrM
85+unsigned char * _mbslwrM(unsigned char * _String);
86+#undef _mbsupr
87+#define _mbsupr _mbsuprM
88+unsigned char * _mbsuprM(unsigned char * _String);
89+#undef _mbsninc
90+#define _mbsninc _mbsnincM
91+unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count);
92+#undef fopen
93+#define fopen fopenM
94+FILE * fopenM(const char * _Filename, const char * _Mode);
95+
96+#endif
97+
98+int MtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count);
99+int WtoM(LPSTR pDst, int size, LPCWSTR pSrc, int count);
100+int AtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count);
101+int WtoA(LPSTR pDst, int size, LPCWSTR pSrc, int count);
102+int TerminateStringM(LPSTR lpString, int size);
103+int TerminateStringW(LPWSTR lpString, int size);
104+int TerminateStringA(LPSTR lpString, int size);
105+size_t GetMultiStringLengthM(LPCSTR lpString);
106+size_t GetMultiStringLengthW(LPCWSTR lpString);
107+size_t GetMultiStringLengthA(LPCSTR lpString);
108+int MtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc);
109+int WtoMMultiString(LPSTR pDst, int size, LPCWSTR pSrc);
110+int AtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc);
111+int WtoAMultiString(LPSTR pDst, int size, LPCWSTR pSrc);
112+char* AllocateStringM(int size);
113+wchar_t* AllocateStringW(int size);
114+char* AllocateStringA(int size);
115+wchar_t* DuplicateMtoW(LPCSTR lpString, int c);
116+wchar_t* DuplicateMtoWBuffer(LPCSTR lpString, int c, int size);
117+wchar_t* DuplicateMtoWMultiString(LPCSTR lpString);
118+wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size);
119+char* DuplicateWtoM(LPCWSTR lpString, int c);
120+wchar_t* DuplicateAtoW(LPCSTR lpString, int c);
121+char* DuplicateWtoA(LPCWSTR lpString, int c);
122+DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext);
123+BOOL FixStringM(LPSTR pDst, LPCSTR pSrc);
124+BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc);
125+BOOL CheckStringM(LPCSTR lpString);
126+BOOL CheckMultiStringM(LPCSTR lpString);
127+void FreeDuplicatedString(void* p);
128+
129+#endif
130+
--- a/remote.c
+++ b/remote.c
@@ -742,6 +742,93 @@ int CommandProcTrn(SOCKET cSkt, char *Reply, int* CancelCheckWork, char *fmt, ..
742742 //#pragma aaa
743743 //static int cntcnt = 0;
744744
745+// SFTP対応
746+int ConvertFTPCommandToPuTTYSFTP(SOCKET cSkt, char *Reply, int *CancelCheckWork, char *Cmd)
747+{
748+ // TODO:
749+ // 未実装
750+ int Sts;
751+ char NewCmd[FMAX_PATH*2];
752+ static char RenameFrom[FMAX_PATH+1];
753+ Sts = 429;
754+ Reply[0] = '\0';
755+ if(strcmp(Cmd, "QUIT") == 0)
756+ {
757+ sprintf(NewCmd, "ls\r\n");
758+ SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);
759+ }
760+ if(strcmp(Cmd, "LIST") == 0)
761+ {
762+ sprintf(NewCmd, "ls\r\n");
763+ SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);
764+ }
765+ else if(strncmp(Cmd, "REST ", 5) == 0)
766+ {
767+ SFTP_SetFilePosition(cSkt, (LONGLONG)_strtoi64(&Cmd[5], NULL, 10));
768+ }
769+ else if(strncmp(Cmd, "RETR ", 5) == 0)
770+ {
771+ sprintf(NewCmd, "get \"%s\"\r\n", &Cmd[5]);
772+ SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);
773+ }
774+ else if(strncmp(Cmd, "STOR ", 5) == 0)
775+ {
776+ sprintf(NewCmd, "put \"%s\"\r\n", &Cmd[5]);
777+ SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);
778+ }
779+ else if(strncmp(Cmd, "APPE ", 5) == 0)
780+ {
781+ sprintf(NewCmd, "reput \"%s\"\r\n", &Cmd[5]);
782+ SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);
783+ }
784+ else if(strncmp(Cmd, "DELE ", 5) == 0)
785+ {
786+ sprintf(NewCmd, "rm \"%s\"\r\n", &Cmd[5]);
787+ SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);
788+ }
789+ else if(strncmp(Cmd, "CWD ", 4) == 0)
790+ {
791+ sprintf(NewCmd, "cd \"%s\"\r\n", &Cmd[4]);
792+ SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);
793+ }
794+ else if(strcmp(Cmd, "PWD") == 0)
795+ {
796+ sprintf(NewCmd, "pwd\r\n");
797+ SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);
798+ }
799+ else if(strcmp(Cmd, "XPWD") == 0)
800+ {
801+ sprintf(NewCmd, "pwd\r\n");
802+ SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);
803+ }
804+ else if(strncmp(Cmd, "MKD ", 4) == 0)
805+ {
806+ sprintf(NewCmd, "mkdir \"%s\"\r\n", &Cmd[4]);
807+ SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);
808+ }
809+ else if(strncmp(Cmd, "RMD ", 4) == 0)
810+ {
811+ sprintf(NewCmd, "rmdir \"%s\"\r\n", &Cmd[4]);
812+ SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);
813+ }
814+ else if(strncmp(Cmd, "RNFR ", 5) == 0)
815+ {
816+ strcpy(RenameFrom, &Cmd[5]);
817+ }
818+ else if(strncmp(Cmd, "RNTO ", 5) == 0)
819+ {
820+ sprintf(NewCmd, "mv \"%s\" \"%s\"\r\n", RenameFrom, &Cmd[5]);
821+ SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);
822+ }
823+ else if(strncmp(Cmd, "SITE CHMOD ", 11) == 0)
824+ {
825+ Cmd[14] = '\0';
826+ sprintf(NewCmd, "chmod %s \"%s\"\r\n", &Cmd[11], &Cmd[15]);
827+ SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);
828+ }
829+ return Sts;
830+}
831+
745832 int command(SOCKET cSkt, char *Reply, int *CancelCheckWork, char *fmt, ...)
746833 {
747834 va_list Args;
@@ -755,6 +842,10 @@ int command(SOCKET cSkt, char *Reply, int *CancelCheckWork, char *fmt, ...)
755842 wvsprintf(Cmd, fmt, Args);
756843 va_end(Args);
757844
845+ // SFTP対応
846+ if(IsSFTPAttached(cSkt))
847+ return ConvertFTPCommandToPuTTYSFTP(cSkt, Reply, CancelCheckWork, Cmd);
848+
758849 if(strncmp(Cmd, "PASS ", 5) == 0)
759850 SetTaskMsg(">PASS [xxxxxx]");
760851 else if((strncmp(Cmd, "USER ", 5) == 0) ||
--- a/socket.c
+++ b/socket.c
@@ -772,7 +772,7 @@ int do_closesocket(SOCKET s)
772772 UnRegistAsyncTable(s);
773773 // FTPS対応
774774 // Ret = closesocket(s);
775- Ret = closesocketS(s);
775+ Ret = FTPS_closesocket(s);
776776 if(Ret == SOCKET_ERROR)
777777 {
778778 Error = 0;
@@ -1029,7 +1029,7 @@ int do_recv(SOCKET s, char *buf, int len, int flags, int *TimeOutErr, int *Cance
10291029
10301030 // FTPS対応
10311031 // Ret = recv(s, buf, len, flags);
1032- Ret = recvS(s, buf, len, flags);
1032+ Ret = FTPS_recv(s, buf, len, flags);
10331033 if(Ret != SOCKET_ERROR)
10341034 break;
10351035 Error = WSAGetLastError();
@@ -1139,7 +1139,7 @@ int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int
11391139
11401140 // FTPS対応
11411141 // Ret = send(s, buf, len, flags);
1142- Ret = sendS(s, buf, len, flags);
1142+ Ret = FTPS_send(s, buf, len, flags);
11431143 if(Ret != SOCKET_ERROR)
11441144 {
11451145 #if DBG_MSG
@@ -1191,10 +1191,10 @@ void RemoveReceivedData(SOCKET s)
11911191 char buf[1024];
11921192 int len;
11931193 int Error;
1194- while((len = recvS(s, buf, sizeof(buf), MSG_PEEK)) >= 0)
1194+ while((len = FTPS_recv(s, buf, sizeof(buf), MSG_PEEK)) >= 0)
11951195 {
11961196 AskAsyncDone(s, &Error, FD_READ);
1197- recvS(s, buf, len, 0);
1197+ FTPS_recv(s, buf, len, 0);
11981198 }
11991199 }
12001200
--- a/socketwrapper.c
+++ b/socketwrapper.c
@@ -16,6 +16,8 @@
1616 #include "mbswrapper.h"
1717 #include "punycode.h"
1818
19+// FTPS対応
20+
1921 typedef void (__cdecl* _SSL_load_error_strings)();
2022 typedef int (__cdecl* _SSL_library_init)();
2123 typedef SSL_METHOD* (__cdecl* _SSLv23_method)();
@@ -556,24 +558,24 @@ BOOL IsSSLAttached(SOCKET s)
556558 return TRUE;
557559 }
558560
559-SOCKET socketS(int af, int type, int protocol)
561+SOCKET FTPS_socket(int af, int type, int protocol)
560562 {
561563 return socket(af, type, protocol);
562564 }
563565
564-int bindS(SOCKET s, const struct sockaddr *addr, int namelen)
566+int FTPS_bind(SOCKET s, const struct sockaddr *addr, int namelen)
565567 {
566568 return bind(s, addr, namelen);
567569 }
568570
569-int listenS(SOCKET s, int backlog)
571+int FTPS_listen(SOCKET s, int backlog)
570572 {
571573 return listen(s, backlog);
572574 }
573575
574576 // accept相当の関数
575577 // ただし初めからSSLのネゴシエーションを行う
576-SOCKET acceptS(SOCKET s, struct sockaddr *addr, int *addrlen)
578+SOCKET FTPS_accept(SOCKET s, struct sockaddr *addr, int *addrlen)
577579 {
578580 SOCKET r;
579581 BOOL bAborted;
@@ -589,7 +591,7 @@ SOCKET acceptS(SOCKET s, struct sockaddr *addr, int *addrlen)
589591
590592 // connect相当の関数
591593 // ただし初めからSSLのネゴシエーションを行う
592-int connectS(SOCKET s, const struct sockaddr *name, int namelen)
594+int FTPS_connect(SOCKET s, const struct sockaddr *name, int namelen)
593595 {
594596 int r;
595597 BOOL bAborted;
@@ -601,14 +603,14 @@ int connectS(SOCKET s, const struct sockaddr *name, int namelen)
601603 }
602604
603605 // closesocket相当の関数
604-int closesocketS(SOCKET s)
606+int FTPS_closesocket(SOCKET s)
605607 {
606608 DetachSSL(s);
607609 return closesocket(s);
608610 }
609611
610612 // send相当の関数
611-int sendS(SOCKET s, const char * buf, int len, int flags)
613+int FTPS_send(SOCKET s, const char * buf, int len, int flags)
612614 {
613615 SSL** ppSSL;
614616 if(!g_bOpenSSLLoaded)
@@ -622,7 +624,7 @@ int sendS(SOCKET s, const char * buf, int len, int flags)
622624 }
623625
624626 // recv相当の関数
625-int recvS(SOCKET s, char * buf, int len, int flags)
627+int FTPS_recv(SOCKET s, char * buf, int len, int flags)
626628 {
627629 SSL** ppSSL;
628630 if(!g_bOpenSSLLoaded)
@@ -989,3 +991,340 @@ HANDLE WSAAsyncGetHostByNameIPv6M(HWND hWnd, u_int wMsg, const char * name, char
989991 return r;
990992 }
991993
994+// SFTP対応
995+
996+typedef void* (__cdecl* _SFTP_Create)();
997+typedef void (__cdecl* _SFTP_Destroy)(void*);
998+typedef BOOL (__cdecl* _SFTP_IsExited)(void*);
999+typedef BOOL (__cdecl* _SFTP_SetTimeoutCallback)(void*, void*);
1000+typedef size_t (__cdecl* _SFTP_PeekStdOut)(void*, void*, size_t);
1001+typedef size_t (__cdecl* _SFTP_ReadStdOut)(void*, void*, size_t);
1002+typedef size_t (__cdecl* _SFTP_WriteStdIn)(void*, const void*, size_t);
1003+typedef size_t (__cdecl* _SFTP_PeekDataOut)(void*, void*, size_t);
1004+typedef size_t (__cdecl* _SFTP_ReadDataOut)(void*, void*, size_t);
1005+typedef size_t (__cdecl* _SFTP_WriteDataIn)(void*, const void*, size_t);
1006+typedef BOOL (__cdecl* _SFTP_SetFilePosition)(void*, LONGLONG);
1007+
1008+_SFTP_Create p_SFTP_Create;
1009+_SFTP_Destroy p_SFTP_Destroy;
1010+_SFTP_IsExited p_SFTP_IsExited;
1011+_SFTP_SetTimeoutCallback p_SFTP_SetTimeoutCallback;
1012+_SFTP_PeekStdOut p_SFTP_PeekStdOut;
1013+_SFTP_ReadStdOut p_SFTP_ReadStdOut;
1014+_SFTP_WriteStdIn p_SFTP_WriteStdIn;
1015+_SFTP_PeekDataOut p_SFTP_PeekDataOut;
1016+_SFTP_ReadDataOut p_SFTP_ReadDataOut;
1017+_SFTP_WriteDataIn p_SFTP_WriteDataIn;
1018+_SFTP_SetFilePosition p_SFTP_SetFilePosition;
1019+
1020+typedef struct
1021+{
1022+ SOCKET Control;
1023+ SOCKET Data;
1024+ void* Handle;
1025+ char Host[1024];
1026+ int Port;
1027+ char User[1024];
1028+ char Password[1024];
1029+} SFTPDATA;
1030+
1031+#define MAX_SFTP_SOCKET 16
1032+
1033+BOOL g_bPuTTYLoaded;
1034+HMODULE g_hPuTTY;
1035+CRITICAL_SECTION g_PuTTYLock;
1036+SFTPDATA g_SFTPData[MAX_SFTP_SOCKET];
1037+
1038+// PuTTYを初期化
1039+BOOL LoadPuTTY()
1040+{
1041+ int i;
1042+ if(g_bPuTTYLoaded)
1043+ return FALSE;
1044+#ifdef ENABLE_PROCESS_PROTECTION
1045+ // ビルドしたputty.dllに合わせてSHA1ハッシュ値を変更すること
1046+ RegisterTrustedModuleSHA1Hash("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
1047+#endif
1048+// g_hPuTTY = LoadLibrary("putty.dll");
1049+ g_hPuTTY = LoadLibrary("C:\\SourceForge\\ffftp\\putty\\Debug\\PuTTY.dll");
1050+ if(!g_hPuTTY
1051+ || !(p_SFTP_Create = (_SFTP_Create)GetProcAddress(g_hPuTTY, "SFTP_Create"))
1052+ || !(p_SFTP_Destroy = (_SFTP_Destroy)GetProcAddress(g_hPuTTY, "SFTP_Destroy"))
1053+ || !(p_SFTP_IsExited = (_SFTP_IsExited)GetProcAddress(g_hPuTTY, "SFTP_IsExited"))
1054+ || !(p_SFTP_SetTimeoutCallback = (_SFTP_SetTimeoutCallback)GetProcAddress(g_hPuTTY, "SFTP_SetTimeoutCallback"))
1055+ || !(p_SFTP_PeekStdOut = (_SFTP_PeekStdOut)GetProcAddress(g_hPuTTY, "SFTP_PeekStdOut"))
1056+ || !(p_SFTP_ReadStdOut = (_SFTP_ReadStdOut)GetProcAddress(g_hPuTTY, "SFTP_ReadStdOut"))
1057+ || !(p_SFTP_WriteStdIn = (_SFTP_WriteStdIn)GetProcAddress(g_hPuTTY, "SFTP_WriteStdIn"))
1058+ || !(p_SFTP_PeekDataOut = (_SFTP_PeekDataOut)GetProcAddress(g_hPuTTY, "SFTP_PeekDataOut"))
1059+ || !(p_SFTP_ReadDataOut = (_SFTP_ReadDataOut)GetProcAddress(g_hPuTTY, "SFTP_ReadDataOut"))
1060+ || !(p_SFTP_WriteDataIn = (_SFTP_WriteDataIn)GetProcAddress(g_hPuTTY, "SFTP_WriteDataIn"))
1061+ || !(p_SFTP_SetFilePosition = (_SFTP_SetFilePosition)GetProcAddress(g_hPuTTY, "SFTP_SetFilePosition")))
1062+ {
1063+ if(g_hPuTTY)
1064+ FreeLibrary(g_hPuTTY);
1065+ g_hPuTTY = NULL;
1066+ return FALSE;
1067+ }
1068+ for(i = 0; i < MAX_SFTP_SOCKET; i++)
1069+ {
1070+ g_SFTPData[i].Control = INVALID_SOCKET;
1071+ g_SFTPData[i].Data = INVALID_SOCKET;
1072+ }
1073+ InitializeCriticalSection(&g_PuTTYLock);
1074+ g_bPuTTYLoaded = TRUE;
1075+ return TRUE;
1076+}
1077+
1078+// PuTTYを解放
1079+void FreePuTTY()
1080+{
1081+ int i;
1082+ if(!g_bPuTTYLoaded)
1083+ return;
1084+ EnterCriticalSection(&g_PuTTYLock);
1085+ for(i = 0; i < MAX_SFTP_SOCKET; i++)
1086+ {
1087+ if(g_SFTPData[i].Control != INVALID_SOCKET)
1088+ {
1089+ closesocket(g_SFTPData[i].Control);
1090+ g_SFTPData[i].Control = INVALID_SOCKET;
1091+ p_SFTP_Destroy(g_SFTPData[i].Handle);
1092+ }
1093+ if(g_SFTPData[i].Data != INVALID_SOCKET)
1094+ {
1095+ closesocket(g_SFTPData[i].Data);
1096+ g_SFTPData[i].Data = INVALID_SOCKET;
1097+ }
1098+ }
1099+ FreeLibrary(g_hPuTTY);
1100+ g_hPuTTY = NULL;
1101+ LeaveCriticalSection(&g_PuTTYLock);
1102+ DeleteCriticalSection(&g_PuTTYLock);
1103+ g_bPuTTYLoaded = FALSE;
1104+}
1105+
1106+// PuTTYが使用可能かどうか確認
1107+BOOL IsPuTTYLoaded()
1108+{
1109+ return g_bPuTTYLoaded;
1110+}
1111+
1112+SFTPDATA* GetUnusedSFTPData()
1113+{
1114+ int i;
1115+ for(i = 0; i < MAX_SFTP_SOCKET; i++)
1116+ {
1117+ if(g_SFTPData[i].Control == INVALID_SOCKET)
1118+ {
1119+ memset(&g_SFTPData[i], 0, sizeof(SFTPDATA));
1120+ return &g_SFTPData[i];
1121+ }
1122+ }
1123+ return NULL;
1124+}
1125+
1126+SFTPDATA* FindSFTPDataFromSocket(SOCKET s)
1127+{
1128+ int i;
1129+ for(i = 0; i < MAX_SFTP_SOCKET; i++)
1130+ {
1131+ if(g_SFTPData[i].Control == s || g_SFTPData[i].Data == s)
1132+ return &g_SFTPData[i];
1133+ }
1134+ return NULL;
1135+}
1136+
1137+// SFTPとしてマークされているか確認
1138+// マークされていればTRUEを返す
1139+BOOL IsSFTPAttached(SOCKET s)
1140+{
1141+ SFTPDATA* pSFTPData;
1142+ if(!g_bPuTTYLoaded)
1143+ return FALSE;
1144+ EnterCriticalSection(&g_PuTTYLock);
1145+ pSFTPData = FindSFTPDataFromSocket(s);
1146+ LeaveCriticalSection(&g_PuTTYLock);
1147+ if(!pSFTPData)
1148+ return FALSE;
1149+ return TRUE;
1150+}
1151+
1152+// コントロール用の仮想的なソケットを取得
1153+// 識別子としてダミーのソケットを返す
1154+SOCKET SFTP_socket(int af, int type, int protocol)
1155+{
1156+ SOCKET r;
1157+ SFTPDATA* pSFTPData;
1158+ if(!g_bPuTTYLoaded)
1159+ return INVALID_SOCKET;
1160+ r = INVALID_SOCKET;
1161+ EnterCriticalSection(&g_PuTTYLock);
1162+ if(pSFTPData = GetUnusedSFTPData())
1163+ {
1164+ r = socket(af, type, protocol);
1165+ pSFTPData->Control = r;
1166+ pSFTPData->Data = INVALID_SOCKET;
1167+ pSFTPData->Handle = p_SFTP_Create();
1168+ }
1169+ LeaveCriticalSection(&g_PuTTYLock);
1170+ return r;
1171+}
1172+
1173+int SFTP_bind(SOCKET s, const struct sockaddr *addr, int namelen)
1174+{
1175+ return SOCKET_ERROR;
1176+}
1177+
1178+int SFTP_listen(SOCKET s, int backlog)
1179+{
1180+ return SOCKET_ERROR;
1181+}
1182+
1183+// accept相当の関数
1184+SOCKET SFTP_accept(SOCKET s, struct sockaddr *addr, int *addrlen)
1185+{
1186+ return INVALID_SOCKET;
1187+}
1188+
1189+// connect相当の関数
1190+int SFTP_connect(SOCKET s, const struct sockaddr *name, int namelen)
1191+{
1192+ SFTPDATA* pSFTPData;
1193+ if(!g_bPuTTYLoaded)
1194+ return SOCKET_ERROR;
1195+ EnterCriticalSection(&g_PuTTYLock);
1196+ pSFTPData = FindSFTPDataFromSocket(s);
1197+ LeaveCriticalSection(&g_PuTTYLock);
1198+ if(!pSFTPData)
1199+ return SOCKET_ERROR;
1200+ if(namelen == sizeof(struct sockaddr_in))
1201+ {
1202+ }
1203+ else if(namelen == sizeof(struct sockaddr_in6))
1204+ {
1205+ }
1206+ else
1207+ return SOCKET_ERROR;
1208+ return 0;
1209+}
1210+
1211+// closesocket相当の関数
1212+int SFTP_closesocket(SOCKET s)
1213+{
1214+ SFTPDATA* pSFTPData;
1215+ if(!g_bPuTTYLoaded)
1216+ return SOCKET_ERROR;
1217+ EnterCriticalSection(&g_PuTTYLock);
1218+ if(pSFTPData = FindSFTPDataFromSocket(s))
1219+ {
1220+ if(pSFTPData->Control == s)
1221+ {
1222+ pSFTPData->Control = INVALID_SOCKET;
1223+ p_SFTP_Destroy(pSFTPData->Handle);
1224+ }
1225+ if(pSFTPData->Data == s)
1226+ pSFTPData->Data = INVALID_SOCKET;
1227+ }
1228+ LeaveCriticalSection(&g_PuTTYLock);
1229+ return closesocket(s);
1230+}
1231+
1232+// send相当の関数
1233+int SFTP_send(SOCKET s, const char * buf, int len, int flags)
1234+{
1235+ int r;
1236+ SFTPDATA* pSFTPData;
1237+ if(!g_bPuTTYLoaded)
1238+ return SOCKET_ERROR;
1239+ EnterCriticalSection(&g_PuTTYLock);
1240+ pSFTPData = FindSFTPDataFromSocket(s);
1241+ LeaveCriticalSection(&g_PuTTYLock);
1242+ if(!pSFTPData)
1243+ return SOCKET_ERROR;
1244+ if(p_SFTP_IsExited(pSFTPData->Handle))
1245+ return SOCKET_ERROR;
1246+ r = SOCKET_ERROR;
1247+ if(pSFTPData->Control == s)
1248+ r = (int)p_SFTP_WriteStdIn(pSFTPData->Handle, buf, len);
1249+ else if(pSFTPData->Data == s)
1250+ r = (int)p_SFTP_WriteDataIn(pSFTPData->Handle, buf, len);
1251+ return r;
1252+}
1253+
1254+// recv相当の関数
1255+int SFTP_recv(SOCKET s, char * buf, int len, int flags)
1256+{
1257+ int r;
1258+ SFTPDATA* pSFTPData;
1259+ if(!g_bPuTTYLoaded)
1260+ return SOCKET_ERROR;
1261+ EnterCriticalSection(&g_PuTTYLock);
1262+ pSFTPData = FindSFTPDataFromSocket(s);
1263+ LeaveCriticalSection(&g_PuTTYLock);
1264+ if(!pSFTPData)
1265+ return SOCKET_ERROR;
1266+ if(p_SFTP_IsExited(pSFTPData->Handle))
1267+ return SOCKET_ERROR;
1268+ r = SOCKET_ERROR;
1269+ if(pSFTPData->Control == s)
1270+ {
1271+ if(flags & MSG_PEEK)
1272+ r = (int)p_SFTP_PeekStdOut(pSFTPData->Handle, buf, len);
1273+ else
1274+ r = (int)p_SFTP_ReadStdOut(pSFTPData->Handle, buf, len);
1275+ }
1276+ else if(pSFTPData->Data == s)
1277+ {
1278+ if(flags & MSG_PEEK)
1279+ r = (int)p_SFTP_PeekDataOut(pSFTPData->Handle, buf, len);
1280+ else
1281+ r = (int)p_SFTP_ReadDataOut(pSFTPData->Handle, buf, len);
1282+ }
1283+ return r;
1284+}
1285+
1286+BOOL SFTP_SetTimeoutCallback(SOCKET s, void* pCallback)
1287+{
1288+ SFTPDATA* pSFTPData;
1289+ if(!g_bPuTTYLoaded)
1290+ return FALSE;
1291+ EnterCriticalSection(&g_PuTTYLock);
1292+ pSFTPData = FindSFTPDataFromSocket(s);
1293+ LeaveCriticalSection(&g_PuTTYLock);
1294+ if(!pSFTPData)
1295+ return FALSE;
1296+ return p_SFTP_SetTimeoutCallback(pSFTPData->Handle, pCallback);
1297+}
1298+
1299+// データ用の仮想的なソケットを取得
1300+// 識別子としてダミーのソケットを返す
1301+SOCKET SFTP_GetDataHandle(SOCKET s, int af, int type, int protocol)
1302+{
1303+ SOCKET r;
1304+ SFTPDATA* pSFTPData;
1305+ if(!g_bPuTTYLoaded)
1306+ return INVALID_SOCKET;
1307+ r = INVALID_SOCKET;
1308+ EnterCriticalSection(&g_PuTTYLock);
1309+ if(pSFTPData = FindSFTPDataFromSocket(s))
1310+ {
1311+ r = socket(af, type, protocol);
1312+ pSFTPData->Data = r;
1313+ }
1314+ LeaveCriticalSection(&g_PuTTYLock);
1315+ return r;
1316+}
1317+
1318+BOOL SFTP_SetFilePosition(SOCKET s, LONGLONG Position)
1319+{
1320+ SFTPDATA* pSFTPData;
1321+ if(!g_bPuTTYLoaded)
1322+ return FALSE;
1323+ EnterCriticalSection(&g_PuTTYLock);
1324+ pSFTPData = FindSFTPDataFromSocket(s);
1325+ LeaveCriticalSection(&g_PuTTYLock);
1326+ if(!pSFTPData)
1327+ return FALSE;
1328+ return p_SFTP_SetFilePosition(pSFTPData->Handle, Position);
1329+}
1330+
--- a/socketwrapper.h
+++ b/socketwrapper.h
@@ -23,14 +23,14 @@ BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName);
2323 BOOL AttachSSL(SOCKET s, SOCKET parent, BOOL* pbAborted);
2424 BOOL DetachSSL(SOCKET s);
2525 BOOL IsSSLAttached(SOCKET s);
26-SOCKET socketS(int af, int type, int protocol);
27-int bindS(SOCKET s, const struct sockaddr *addr, int namelen);
28-int listenS(SOCKET s, int backlog);
29-SOCKET acceptS(SOCKET s, struct sockaddr *addr, int *addrlen);
30-int connectS(SOCKET s, const struct sockaddr *name, int namelen);
31-int closesocketS(SOCKET s);
32-int sendS(SOCKET s, const char * buf, int len, int flags);
33-int recvS(SOCKET s, char * buf, int len, int flags);
26+SOCKET FTPS_socket(int af, int type, int protocol);
27+int FTPS_bind(SOCKET s, const struct sockaddr *addr, int namelen);
28+int FTPS_listen(SOCKET s, int backlog);
29+SOCKET FTPS_accept(SOCKET s, struct sockaddr *addr, int *addrlen);
30+int FTPS_connect(SOCKET s, const struct sockaddr *name, int namelen);
31+int FTPS_closesocket(SOCKET s);
32+int FTPS_send(SOCKET s, const char * buf, int len, int flags);
33+int FTPS_recv(SOCKET s, char * buf, int len, int flags);
3434
3535 HANDLE WSAAsyncGetHostByNameIPv6(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen, short Family);
3636 int WSACancelAsyncRequestIPv6(HANDLE hAsyncTaskHandle);
@@ -40,5 +40,21 @@ struct in6_addr inet6_addr(const char* cp);
4040 HANDLE WSAAsyncGetHostByNameM(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen);
4141 HANDLE WSAAsyncGetHostByNameIPv6M(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen, short Family);
4242
43+BOOL LoadPuTTY();
44+void FreePuTTY();
45+BOOL IsPuTTYLoaded();
46+BOOL IsSFTPAttached(SOCKET s);
47+SOCKET SFTP_socket(int af, int type, int protocol);
48+int SFTP_bind(SOCKET s, const struct sockaddr *addr, int namelen);
49+int SFTP_listen(SOCKET s, int backlog);
50+SOCKET SFTP_accept(SOCKET s, struct sockaddr *addr, int *addrlen);
51+int SFTP_connect(SOCKET s, const struct sockaddr *name, int namelen);
52+int SFTP_closesocket(SOCKET s);
53+int SFTP_send(SOCKET s, const char * buf, int len, int flags);
54+int SFTP_recv(SOCKET s, char * buf, int len, int flags);
55+BOOL SFTP_SetTimeoutCallback(SOCKET s, void* pCallback);
56+SOCKET SFTP_GetDataHandle(SOCKET s, int af, int type, int protocol);
57+BOOL SFTP_SetFilePosition(SOCKET s, LONGLONG Position);
58+
4359 #endif
4460