OSDN Git Service

Add test code for SFTP (still useless).
authors_kawamoto <s_kawamoto@users.sourceforge.jp>
Mon, 26 Dec 2011 12:51:51 +0000 (21:51 +0900)
committers_kawamoto <s_kawamoto@users.sourceforge.jp>
Mon, 26 Dec 2011 12:51:51 +0000 (21:51 +0900)
22 files changed:
FFFTP_Eng_Release/FFFTP.exe
Release/FFFTP.exe
connect.c
getput.c
hostman.c
main.c
mbswrapper.c
putty/PUTTY.H
putty/PuTTY.vc90.vcproj
putty/PuTTY.vcproj
putty/Release/PuTTY.dll
putty/WINDOWS/WINSFTP.C
putty/dllinterface.c [new file with mode: 0644]
putty/dllinterface.h [new file with mode: 0644]
putty/iowrapper.c [new file with mode: 0644]
putty/iowrapper.h [new file with mode: 0644]
putty/mbswrapper.c [new file with mode: 0644]
putty/mbswrapper.h [new file with mode: 0644]
remote.c
socket.c
socketwrapper.c
socketwrapper.h

index 98411a5..f8cef80 100644 (file)
Binary files a/FFFTP_Eng_Release/FFFTP.exe and b/FFFTP_Eng_Release/FFFTP.exe differ
index ac996df..40d966d 100644 (file)
Binary files a/Release/FFFTP.exe and b/Release/FFFTP.exe differ
index 92f8ef0..b679a4d 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -1699,6 +1699,61 @@ static SOCKET DoConnectCrypt(int CryptMode, HOSTDATA* HostData, char *Host, char
        }\r
        else if(CryptMode == CRYPT_SFTP)\r
        {\r
+               // TODO:\r
+               // テストコード\r
+               // ログイン成功を確認\r
+#define strrcmp(_Str1, _Str2) (strcmp(strstr(_Str1, _Str2) ? strstr(_Str1, _Str2) : "", _Str2))\r
+               size_t r;\r
+               ContSock = SFTP_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\r
+               SFTP_SetTimeoutCallback(ContSock, SSLTimeoutCallback);\r
+               while(1)\r
+               {\r
+                       r = SFTP_recv(ContSock, Reply, 1024, 0);\r
+                       if(r == SOCKET_ERROR)\r
+                               break;\r
+                       if(r <= 0)\r
+                               continue;\r
+                       Reply[r] = '\0';\r
+                       SetTaskMsg("%s", Reply);\r
+                       if(strrcmp(Reply, "psftp> ") == 0)\r
+                               break;\r
+               }\r
+               r = SFTP_send(ContSock, "open \"", strlen("open \""), 0);\r
+               r = SFTP_send(ContSock, Host, strlen(Host), 0);\r
+               r = SFTP_send(ContSock, "\"\r\n", strlen("\"\r\n"), 0);\r
+               while(1)\r
+               {\r
+                       r = SFTP_recv(ContSock, Reply, 1024, 0);\r
+                       if(r == SOCKET_ERROR)\r
+                               break;\r
+                       if(r <= 0)\r
+                               continue;\r
+                       Reply[r] = '\0';\r
+                       SetTaskMsg("%s", Reply);\r
+                       if(strrcmp(Reply, "Store key in cache? (y/n) ") == 0)\r
+                       {\r
+                               r = SFTP_send(ContSock, "n\r\n", strlen("n\r\n"), 0);\r
+                       }\r
+                       if(strrcmp(Reply, "Update cached key? (y/n, Return cancels connection) ") == 0)\r
+                       {\r
+                               r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0);\r
+                       }\r
+                       if(strrcmp(Reply, "login as: ") == 0)\r
+                       {\r
+                               r = SFTP_send(ContSock, User, strlen(User), 0);\r
+                               r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0);\r
+                       }\r
+                       if(strrcmp(Reply, "password: ") == 0)\r
+                       {\r
+                               r = SFTP_send(ContSock, Pass, strlen(Pass), 0);\r
+                               r = SFTP_send(ContSock, "\r\n", strlen("\r\n"), 0);\r
+                       }\r
+                       if(strrcmp(Reply, "psftp> ") == 0)\r
+                               break;\r
+                       Sleep(1);\r
+               }\r
+               SFTP_closesocket(ContSock);\r
+               ContSock = INVALID_SOCKET;\r
        }\r
 \r
        return(ContSock);\r
@@ -1711,12 +1766,12 @@ static SOCKET DoConnect(HOSTDATA* HostData, char *Host, char *User, char *Pass,
        SOCKET ContSock;\r
        ContSock = INVALID_SOCKET;\r
        *CancelCheckWork = NO;\r
-//     if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseSFTP == YES)\r
-//     {\r
-//             SetTaskMsg(MSGJPN317);\r
-//             if((ContSock = DoConnectCrypt(CRYPT_SFTP, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
-//                     HostData->CryptMode = CRYPT_SFTP;\r
-//     }\r
+       if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseSFTP == YES)\r
+       {\r
+               SetTaskMsg(MSGJPN317);\r
+               if((ContSock = DoConnectCrypt(CRYPT_SFTP, HostData, Host, User, Pass, Acct, Port, Fwall, SavePass, Security, CancelCheckWork)) != INVALID_SOCKET)\r
+                       HostData->CryptMode = CRYPT_SFTP;\r
+       }\r
        if(*CancelCheckWork == NO && ContSock == INVALID_SOCKET && HostData->UseFTPIS == YES)\r
        {\r
                SetTaskMsg(MSGJPN316);\r
index b5b0efb..561bc34 100644 (file)
--- a/getput.c
+++ b/getput.c
@@ -1320,7 +1320,13 @@ int DoDownLoad(SOCKET cSkt, TRANSPACKET *Pkt, int DirList, int *CancelCheckWork)
                                        DispTransFileInfo(Pkt, MSGJPN087, FALSE, NO);\r
                        }\r
 \r
-                       if(BackgrndMessageProc() == NO)\r
+                       // SFTP対応\r
+//                     if(BackgrndMessageProc() == NO)\r
+                       if(IsSFTPAttached(Pkt->ctrl_skt))\r
+                       {\r
+                               // TODO:\r
+                       }\r
+                       else if(BackgrndMessageProc() == NO)\r
                        {\r
                                if(AskPasvMode() != YES)\r
                                        iRetCode = DownLoadNonPassive(Pkt, CancelCheckWork);\r
@@ -2550,7 +2556,13 @@ static int DoUpLoad(SOCKET cSkt, TRANSPACKET *Pkt)
                                if(Pkt->hWndTrans != NULL)\r
                                        DispTransFileInfo(Pkt, MSGJPN104, TRUE, YES);\r
 \r
-                               if(BackgrndMessageProc() == NO)\r
+                               // SFTP対応\r
+//                             if(BackgrndMessageProc() == NO)\r
+                               if(IsSFTPAttached(Pkt->ctrl_skt))\r
+                               {\r
+                                       // TODO:\r
+                               }\r
+                               else if(BackgrndMessageProc() == NO)\r
                                {\r
                                        if(AskPasvMode() != YES)\r
                                                iRetCode = UpLoadNonPassive(Pkt);\r
index f95d166..31b75a2 100644 (file)
--- a/hostman.c
+++ b/hostman.c
@@ -2236,13 +2236,18 @@ static INT_PTR CALLBACK CryptSettingProc(HWND hDlg, UINT iMessage, WPARAM wParam
                                SendDlgItemMessage(hDlg, HSET_FTPIS, BM_SETCHECK, BST_UNCHECKED, 0);\r
                                EnableWindow(GetDlgItem(hDlg, HSET_FTPIS), FALSE);\r
                        }\r
-                       SendDlgItemMessage(hDlg, HSET_SFTP, BM_SETCHECK, TmpHost.UseSFTP, 0);\r
-                       SendDlgItemMessage(hDlg, HSET_PRIVATE_KEY, WM_SETTEXT, 0, (LPARAM)TmpHost.PrivateKey);\r
-                       // TODO: SFTP対応\r
-                       SendDlgItemMessage(hDlg, HSET_SFTP, BM_SETCHECK, BST_UNCHECKED, 0);\r
-                       EnableWindow(GetDlgItem(hDlg, HSET_SFTP), FALSE);\r
-                       EnableWindow(GetDlgItem(hDlg, PKEY_FILE_BR), FALSE);\r
-                       EnableWindow(GetDlgItem(hDlg, HSET_PRIVATE_KEY), FALSE);\r
+                       if(IsPuTTYLoaded())\r
+                       {\r
+                               SendDlgItemMessage(hDlg, HSET_SFTP, BM_SETCHECK, TmpHost.UseSFTP, 0);\r
+                               SendDlgItemMessage(hDlg, HSET_PRIVATE_KEY, WM_SETTEXT, 0, (LPARAM)TmpHost.PrivateKey);\r
+                       }\r
+                       else\r
+                       {\r
+                               SendDlgItemMessage(hDlg, HSET_SFTP, BM_SETCHECK, BST_UNCHECKED, 0);\r
+                               EnableWindow(GetDlgItem(hDlg, HSET_SFTP), FALSE);\r
+                               EnableWindow(GetDlgItem(hDlg, PKEY_FILE_BR), FALSE);\r
+                               EnableWindow(GetDlgItem(hDlg, HSET_PRIVATE_KEY), FALSE);\r
+                       }\r
                        return(TRUE);\r
 \r
                case WM_NOTIFY:\r
@@ -2256,9 +2261,11 @@ static INT_PTR CALLBACK CryptSettingProc(HWND hDlg, UINT iMessage, WPARAM wParam
                                                TmpHost.UseFTPES = SendDlgItemMessage(hDlg, HSET_FTPES, BM_GETCHECK, 0, 0);\r
                                                TmpHost.UseFTPIS = SendDlgItemMessage(hDlg, HSET_FTPIS, BM_GETCHECK, 0, 0);\r
                                        }\r
-                                       // TODO: SFTP対応\r
-//                                     TmpHost.UseSFTP = SendDlgItemMessage(hDlg, HSET_SFTP, BM_GETCHECK, 0, 0);\r
-                                       SendDlgItemMessage(hDlg, HSET_PRIVATE_KEY, WM_GETTEXT, PRIVATE_KEY_LEN+1, (LPARAM)TmpHost.PrivateKey);\r
+                                       if(IsPuTTYLoaded())\r
+                                       {\r
+                                               TmpHost.UseSFTP = SendDlgItemMessage(hDlg, HSET_SFTP, BM_GETCHECK, 0, 0);\r
+                                               SendDlgItemMessage(hDlg, HSET_PRIVATE_KEY, WM_GETTEXT, PRIVATE_KEY_LEN+1, (LPARAM)TmpHost.PrivateKey);\r
+                                       }\r
                                        Apply = YES;\r
                                        break;\r
 \r
diff --git a/main.c b/main.c
index d01e229..f48ce74 100644 (file)
--- a/main.c
+++ b/main.c
@@ -339,6 +339,9 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi
        LoadOpenSSL();\r
 #endif\r
 \r
+       // SFTP対応\r
+       LoadPuTTY();\r
+\r
        Ret = FALSE;\r
        hWndFtp = NULL;\r
        hInstFtp = hInstance;\r
@@ -374,6 +377,8 @@ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLi
 #ifdef USE_OPENSSL\r
        FreeOpenSSL();\r
 #endif\r
+       // SFTP対応\r
+       FreePuTTY();\r
        OleUninitialize();\r
        return(Ret);\r
 }\r
index c72577d..edef5a7 100644 (file)
@@ -1895,7 +1895,6 @@ END_ROUTINE
        return r;\r
 }\r
 \r
-\r
 BOOL AppendMenuM(HMENU hMenu, UINT uFlags, UINT_PTR uIDNewItem, LPCSTR lpNewItem)\r
 {\r
        int r = 0;\r
index e2baee8..6363105 100644 (file)
@@ -1303,4 +1303,8 @@ void timer_change_notify(long next);
 #define remove_session_from_jumplist(x) ((void)0)\r
 #endif\r
 \r
+// FFFTP\r
+#include "mbswrapper.h"\r
+#include "iowrapper.h"\r
+\r
 #endif\r
index e8982c0..481c5ed 100644 (file)
@@ -50,7 +50,7 @@
                                RuntimeLibrary="1"\r
                                UsePrecompiledHeader="0"\r
                                WarningLevel="3"\r
-                               DebugInformationFormat="4"\r
+                               DebugInformationFormat="3"\r
                        />\r
                        <Tool\r
                                Name="VCManagedResourceCompilerTool"\r
                                RuntimeLibrary="1"\r
                                UsePrecompiledHeader="0"\r
                                WarningLevel="3"\r
-                               DebugInformationFormat="4"\r
+                               DebugInformationFormat="3"\r
                        />\r
                        <Tool\r
                                Name="VCManagedResourceCompilerTool"\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\dllinterface.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\dllmain.c"\r
                                >\r
                        </File>\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\iowrapper.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\LOGGING.C"\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\mbswrapper.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\MISC.C"\r
                                >\r
                        </File>\r
index ce606a0..35f92a3 100644 (file)
@@ -49,7 +49,7 @@
                                RuntimeLibrary="1"\r
                                UsePrecompiledHeader="0"\r
                                WarningLevel="3"\r
-                               DebugInformationFormat="4"\r
+                               DebugInformationFormat="3"\r
                        />\r
                        <Tool\r
                                Name="VCManagedResourceCompilerTool"\r
                                RuntimeLibrary="1"\r
                                UsePrecompiledHeader="0"\r
                                WarningLevel="3"\r
-                               DebugInformationFormat="4"\r
+                               DebugInformationFormat="3"\r
                        />\r
                        <Tool\r
                                Name="VCManagedResourceCompilerTool"\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\dllinterface.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\dllmain.c"\r
                                >\r
                        </File>\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\iowrapper.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\LOGGING.C"\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\mbswrapper.c"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\MISC.C"\r
                                >\r
                        </File>\r
index b918a76..6a506e4 100644 (file)
Binary files a/putty/Release/PuTTY.dll and b/putty/Release/PuTTY.dll differ
index 8a36dcb..5fd5b26 100644 (file)
@@ -93,6 +93,9 @@ RFile *open_existing_file(char *name, uint64 *size,
     HANDLE h;\r
     RFile *ret;\r
 \r
+       // FFFTP\r
+       return snew(RFile);\r
+\r
     h = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL,\r
                   OPEN_EXISTING, 0, 0);\r
     if (h == INVALID_HANDLE_VALUE)\r
@@ -120,6 +123,8 @@ int read_from_file(RFile *f, void *buffer, int length)
 {\r
     int ret;\r
     DWORD read;\r
+       // FFFTP\r
+       return (int)SFTP_ReadThreadDataIO(buffer, length);\r
     ret = ReadFile(f->h, buffer, length, &read, NULL);\r
     if (!ret)\r
        return -1;                     /* error */\r
@@ -129,7 +134,8 @@ int read_from_file(RFile *f, void *buffer, int length)
 \r
 void close_rfile(RFile *f)\r
 {\r
-    CloseHandle(f->h);\r
+       // FFFTP\r
+//    CloseHandle(f->h);\r
     sfree(f);\r
 }\r
 \r
@@ -142,6 +148,9 @@ WFile *open_new_file(char *name)
     HANDLE h;\r
     WFile *ret;\r
 \r
+       // FFFTP\r
+       return snew(WFile);\r
+\r
     h = CreateFile(name, GENERIC_WRITE, 0, NULL,\r
                   CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);\r
     if (h == INVALID_HANDLE_VALUE)\r
@@ -158,6 +167,9 @@ WFile *open_existing_wfile(char *name, uint64 *size)
     HANDLE h;\r
     WFile *ret;\r
 \r
+       // FFFTP\r
+       return snew(WFile);\r
+\r
     h = CreateFile(name, GENERIC_WRITE, FILE_SHARE_READ, NULL,\r
                   OPEN_EXISTING, 0, 0);\r
     if (h == INVALID_HANDLE_VALUE)\r
@@ -176,6 +188,8 @@ int write_to_file(WFile *f, void *buffer, int length)
 {\r
     int ret;\r
     DWORD written;\r
+       // FFFTP\r
+       return (int)SFTP_WriteThreadDataIO(buffer, length);\r
     ret = WriteFile(f->h, buffer, length, &written, NULL);\r
     if (!ret)\r
        return -1;                     /* error */\r
@@ -186,6 +200,8 @@ int write_to_file(WFile *f, void *buffer, int length)
 void set_file_times(WFile *f, unsigned long mtime, unsigned long atime)\r
 {\r
     FILETIME actime, wrtime;\r
+       // FFFTP\r
+       return;\r
     TIME_POSIX_TO_WIN(atime, actime);\r
     TIME_POSIX_TO_WIN(mtime, wrtime);\r
     SetFileTime(f->h, NULL, &actime, &wrtime);\r
@@ -193,7 +209,8 @@ void set_file_times(WFile *f, unsigned long mtime, unsigned long atime)
 \r
 void close_wfile(WFile *f)\r
 {\r
-    CloseHandle(f->h);\r
+       // FFFTP\r
+//    CloseHandle(f->h);\r
     sfree(f);\r
 }\r
 \r
@@ -203,6 +220,9 @@ int seek_file(WFile *f, uint64 offset, int whence)
 {\r
     DWORD movemethod;\r
 \r
+       // FFFTP\r
+       return 0;\r
+\r
     switch (whence) {\r
     case FROM_START:\r
        movemethod = FILE_BEGIN;\r
@@ -229,6 +249,10 @@ uint64 get_file_posn(WFile *f)
 {\r
     uint64 ret;\r
 \r
+       // FFFTP\r
+       SFTP_GetThreadFilePositon((DWORD*)&ret.lo, (LONG*)&ret.hi);\r
+       return ret;\r
+\r
     ret.hi = 0L;\r
     ret.lo = SetFilePointer(f->h, 0L, &(ret.hi), FILE_CURRENT);\r
 \r
@@ -680,6 +704,9 @@ char *ssh_sftp_get_cmdline(char *prompt, int no_fds_ok)
     fputs(prompt, stdout);\r
     fflush(stdout);\r
 \r
+       // FFFTP\r
+       return fgetline(stdin);\r
+\r
     if ((sftp_ssh_socket == INVALID_SOCKET && no_fds_ok) ||\r
        p_WSAEventSelect == NULL) {\r
        return fgetline(stdin);        /* very simple */\r
diff --git a/putty/dllinterface.c b/putty/dllinterface.c
new file mode 100644 (file)
index 0000000..ee808c4
--- /dev/null
@@ -0,0 +1,90 @@
+// dllinterface.c\r
+// Copyright (C) 2011 Suguru Kawamoto\r
+// 標準入出力APIラッパー\r
+\r
+#include <stdio.h>\r
+#include <windows.h>\r
+\r
+#include "iowrapper.h"\r
+#include "dllinterface.h"\r
+\r
+__declspec(dllexport) SFTPSTATUS* SFTP_Create()\r
+{\r
+       SFTPSTATUS* p;\r
+       if(p = FindSFTPStatus(0))\r
+       {\r
+               p->ThreadId = GetCurrentThreadId();\r
+               p->bExit = FALSE;\r
+               SFTP_InitializeIOBuffer(&p->InBuffer, 65536);\r
+               SFTP_InitializeIOBuffer(&p->OutBuffer, 65536);\r
+               SFTP_InitializeIOBuffer(&p->DataInBuffer, 1048576);\r
+               SFTP_InitializeIOBuffer(&p->DataOutBuffer, 1048576);\r
+               memset(&p->FilePosition, 0, sizeof(LARGE_INTEGER));\r
+               CreateThread(NULL, 0, SFTP_ThreadProc, NULL, 0, &p->ThreadId);\r
+       }\r
+       return p;\r
+}\r
+\r
+__declspec(dllexport) void SFTP_Destroy(SFTPSTATUS* pSFTP)\r
+{\r
+       if(pSFTP)\r
+       {\r
+               SFTP_UninitializeIOBuffer(&pSFTP->InBuffer);\r
+               SFTP_UninitializeIOBuffer(&pSFTP->OutBuffer);\r
+               SFTP_UninitializeIOBuffer(&pSFTP->DataInBuffer);\r
+               SFTP_UninitializeIOBuffer(&pSFTP->DataOutBuffer);\r
+               pSFTP->ThreadId = 0;\r
+       }\r
+}\r
+\r
+__declspec(dllexport) BOOL SFTP_IsExited(SFTPSTATUS* pSFTP)\r
+{\r
+       return pSFTP->bExit;\r
+}\r
+\r
+__declspec(dllexport) BOOL SFTP_SetTimeoutCallback(SFTPSTATUS* pSFTP, LPSFTPTIMEOUTCALLBACK pCallback)\r
+{\r
+       pSFTP->pCallback = pCallback;\r
+       pSFTP->InBuffer.pCallback = pCallback;\r
+       pSFTP->OutBuffer.pCallback = pCallback;\r
+       pSFTP->DataInBuffer.pCallback = pCallback;\r
+       pSFTP->DataOutBuffer.pCallback = pCallback;\r
+       return TRUE;\r
+}\r
+\r
+__declspec(dllexport) size_t SFTP_PeekStdOut(SFTPSTATUS* pSFTP, void* pData, size_t Size)\r
+{\r
+       return SFTP_PeekIOBuffer(&pSFTP->OutBuffer, pData, Size);\r
+}\r
+\r
+__declspec(dllexport) size_t SFTP_ReadStdOut(SFTPSTATUS* pSFTP, void* pData, size_t Size)\r
+{\r
+       return SFTP_ReadIOBuffer(&pSFTP->OutBuffer, pData, Size);\r
+}\r
+\r
+__declspec(dllexport) size_t SFTP_WriteStdIn(SFTPSTATUS* pSFTP, const void* pData, size_t Size)\r
+{\r
+       return SFTP_WriteIOBuffer(&pSFTP->InBuffer, pData, Size);\r
+}\r
+\r
+__declspec(dllexport) size_t SFTP_PeekDataOut(SFTPSTATUS* pSFTP, void* pData, size_t Size)\r
+{\r
+       return SFTP_PeekIOBuffer(&pSFTP->DataOutBuffer, pData, Size);\r
+}\r
+\r
+__declspec(dllexport) size_t SFTP_ReadDataOut(SFTPSTATUS* pSFTP, void* pData, size_t Size)\r
+{\r
+       return SFTP_ReadIOBuffer(&pSFTP->DataOutBuffer, pData, Size);\r
+}\r
+\r
+__declspec(dllexport) size_t SFTP_WriteDataIn(SFTPSTATUS* pSFTP, const void* pData, size_t Size)\r
+{\r
+       return SFTP_WriteIOBuffer(&pSFTP->DataInBuffer, pData, Size);\r
+}\r
+\r
+__declspec(dllexport) BOOL SFTP_SetFilePosition(SFTPSTATUS* pSFTP, LONGLONG Position)\r
+{\r
+       pSFTP->FilePosition.QuadPart = Position;\r
+       return TRUE;\r
+}\r
+\r
diff --git a/putty/dllinterface.h b/putty/dllinterface.h
new file mode 100644 (file)
index 0000000..58facf5
--- /dev/null
@@ -0,0 +1,12 @@
+// dllinterface.h\r
+// Copyright (C) 2011 Suguru Kawamoto\r
+// 標準入出力APIラッパー\r
+\r
+#ifndef __DLLINTERFACE_H__\r
+#define __DLLINTERFACE_H__\r
+\r
+#include <stdio.h>\r
+#include <windows.h>\r
+\r
+#endif\r
+\r
diff --git a/putty/iowrapper.c b/putty/iowrapper.c
new file mode 100644 (file)
index 0000000..16a09be
--- /dev/null
@@ -0,0 +1,434 @@
+// iowrapper.c\r
+// Copyright (C) 2011 Suguru Kawamoto\r
+// 標準入出力APIラッパー\r
+\r
+#define UNICODE\r
+#define _UNICODE\r
+\r
+#include <stdio.h>\r
+#include <windows.h>\r
+\r
+#define DO_NOT_REPLACE\r
+#include "iowrapper.h"\r
+#include "psftp.h"\r
+\r
+#define MAX_SFTPSTATUS 16\r
+\r
+SFTPSTATUS g_SFTPData[MAX_SFTPSTATUS];\r
+HANDLE g_hStdIn;\r
+HANDLE g_hStdOut;\r
+HANDLE g_hStdErr;\r
+\r
+BOOL __stdcall DefaultIOBufferCallback(BOOL* pbAborted)\r
+{\r
+       Sleep(1);\r
+       return *pbAborted;\r
+}\r
+\r
+DWORD WINAPI SFTP_ThreadProc(LPVOID lpParameter)\r
+{\r
+       char* p[1] = {"PSFTP"};\r
+       SFTPSTATUS* pSFTP;\r
+       psftp_main(1, p);\r
+       if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
+               pSFTP->bExit = TRUE;\r
+       return 0;\r
+}\r
+\r
+SFTPSTATUS* FindSFTPStatus(DWORD ThreadId)\r
+{\r
+       int i;\r
+       for(i = 0; i < MAX_SFTPSTATUS; i++)\r
+       {\r
+               if(g_SFTPData[i].ThreadId == ThreadId)\r
+                       return &g_SFTPData[i];\r
+       }\r
+       return NULL;\r
+}\r
+\r
+CRITICAL_SECTION g_DummyLock;\r
+\r
+BOOL SFTP_InitializeIOBuffer(SFTPIOBUFFER* pIO, size_t Length)\r
+{\r
+       memset(pIO, 0, sizeof(SFTPIOBUFFER));\r
+//     InitializeCriticalSection(&pIO->Lock);\r
+       if(memcmp(&pIO->Lock, &g_DummyLock, sizeof(CRITICAL_SECTION)) == 0)\r
+       {\r
+               InitializeCriticalSection(&pIO->Lock);\r
+               EnterCriticalSection(&pIO->Lock);\r
+       }\r
+       if(!(pIO->pBuffer = (BYTE*)malloc(Length + 1)))\r
+               return FALSE;\r
+       memset(pIO->pBuffer + Length, 0, 1);\r
+       pIO->Length = Length;\r
+       pIO->Written = 0;\r
+       pIO->Read = 0;\r
+       pIO->bAborted = FALSE;\r
+       pIO->pCallback = DefaultIOBufferCallback;\r
+       LeaveCriticalSection(&pIO->Lock);\r
+       return TRUE;\r
+}\r
+\r
+void SFTP_UninitializeIOBuffer(SFTPIOBUFFER* pIO)\r
+{\r
+//     DeleteCriticalSection(&pIO->Lock);\r
+       EnterCriticalSection(&pIO->Lock);\r
+       free(pIO->pBuffer);\r
+//     memset(pIO, 0, sizeof(SFTPIOBUFFER));\r
+}\r
+\r
+void SFTP_AbortIOBuffer(SFTPIOBUFFER* pIO, BOOL bAborted)\r
+{\r
+       EnterCriticalSection(&pIO->Lock);\r
+       pIO->bAborted = bAborted;\r
+       LeaveCriticalSection(&pIO->Lock);\r
+}\r
+\r
+size_t SFTP_PeekIOBuffer(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size)\r
+{\r
+       size_t Copied;\r
+       size_t Pos;\r
+       size_t Count;\r
+       size_t Read;\r
+       Copied = 0;\r
+       EnterCriticalSection(&pIO->Lock);\r
+       if(pBuffer)\r
+       {\r
+               Read = pIO->Read;\r
+               while(!pIO->bAborted && pIO->Written - Read > 0 && Copied < Size)\r
+               {\r
+                       Pos = Read % pIO->Length;\r
+                       Count = min(Size - Copied, min(pIO->Written - Read, pIO->Length - Pos));\r
+                       memcpy((BYTE*)pBuffer + Copied, pIO->pBuffer + Pos, Count);\r
+                       Read += Count;\r
+                       Copied += Count;\r
+               }\r
+       }\r
+       else\r
+               Copied = pIO->Written - pIO->Read;\r
+       LeaveCriticalSection(&pIO->Lock);\r
+       return Copied;\r
+}\r
+\r
+size_t SFTP_ReadIOBuffer(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size)\r
+{\r
+       size_t Copied;\r
+       size_t Pos;\r
+       size_t Count;\r
+       Copied = 0;\r
+       EnterCriticalSection(&pIO->Lock);\r
+       while(!pIO->bAborted && pIO->Written - pIO->Read > 0 && Copied < Size)\r
+       {\r
+               Pos = pIO->Read % pIO->Length;\r
+               Count = min(Size - Copied, min(pIO->Written - pIO->Read, pIO->Length - Pos));\r
+               memcpy((BYTE*)pBuffer + Copied, pIO->pBuffer + Pos, Count);\r
+               pIO->Read += Count;\r
+               Copied += Count;\r
+       }\r
+       LeaveCriticalSection(&pIO->Lock);\r
+       return Copied;\r
+}\r
+\r
+size_t SFTP_WriteIOBuffer(SFTPIOBUFFER* pIO, const void* pBuffer, size_t Size)\r
+{\r
+       size_t Copied;\r
+       size_t Pos;\r
+       size_t Count;\r
+       Copied = 0;\r
+       EnterCriticalSection(&pIO->Lock);\r
+       while(!pIO->bAborted && Copied < Size)\r
+       {\r
+               if(pIO->Written - pIO->Read < pIO->Length)\r
+               {\r
+                       Pos = pIO->Written % pIO->Length;\r
+                       Count = min(Size - Copied, min(pIO->Length + pIO->Read - pIO->Written, pIO->Length - Pos));\r
+                       memcpy(pIO->pBuffer + Pos, (BYTE*)pBuffer + Copied, Count);\r
+                       pIO->Written += Count;\r
+                       Copied += Count;\r
+               }\r
+               else\r
+               {\r
+                       LeaveCriticalSection(&pIO->Lock);\r
+                       if(pIO->pCallback(&pIO->bAborted))\r
+                               Size = 0;\r
+                       EnterCriticalSection(&pIO->Lock);\r
+               }\r
+       }\r
+       LeaveCriticalSection(&pIO->Lock);\r
+       return Copied;\r
+}\r
+\r
+size_t SFTP_ReadIOBufferLine(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size)\r
+{\r
+       size_t Copied;\r
+       size_t Pos;\r
+       size_t Count;\r
+       char* p;\r
+       Copied = 0;\r
+       EnterCriticalSection(&pIO->Lock);\r
+       while(!pIO->bAborted && Copied < Size)\r
+       {\r
+               if(pIO->Written - pIO->Read > 0)\r
+               {\r
+                       Pos = pIO->Read % pIO->Length;\r
+                       Count = min(Size - Copied, min(pIO->Written - pIO->Read, pIO->Length - Pos));\r
+                       if(p = strchr((char*)(pIO->pBuffer + Pos), '\n'))\r
+                       {\r
+                               p++;\r
+                               Count = min(Count, (size_t)p - (size_t)(pIO->pBuffer + Pos));\r
+                               Size = 0;\r
+                       }\r
+                       memcpy((BYTE*)pBuffer + Copied, pIO->pBuffer + Pos, Count);\r
+                       pIO->Read += Count;\r
+                       Copied += Count;\r
+               }\r
+               else\r
+               {\r
+                       LeaveCriticalSection(&pIO->Lock);\r
+                       if(pIO->pCallback(&pIO->bAborted))\r
+                               Size = 0;\r
+                       EnterCriticalSection(&pIO->Lock);\r
+               }\r
+       }\r
+       LeaveCriticalSection(&pIO->Lock);\r
+       return Copied;\r
+}\r
+\r
+size_t SFTP_PeekThreadIO(void* pBuffer, size_t Size)\r
+{\r
+       SFTPSTATUS* pSFTP;\r
+       if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
+               return SFTP_PeekIOBuffer(&pSFTP->InBuffer, pBuffer, Size);\r
+       return 0;\r
+}\r
+\r
+size_t SFTP_ReadThreadIO(void* pBuffer, size_t Size)\r
+{\r
+       SFTPSTATUS* pSFTP;\r
+       if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
+               return SFTP_ReadIOBuffer(&pSFTP->InBuffer, pBuffer, Size);\r
+       return 0;\r
+}\r
+\r
+size_t SFTP_WriteThreadIO(const void* pBuffer, size_t Size)\r
+{\r
+       SFTPSTATUS* pSFTP;\r
+       if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
+               return SFTP_WriteIOBuffer(&pSFTP->OutBuffer, pBuffer, Size);\r
+       return 0;\r
+}\r
+\r
+size_t SFTP_ReadThreadIOLine(void* pBuffer, size_t Size)\r
+{\r
+       SFTPSTATUS* pSFTP;\r
+       if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
+               return SFTP_ReadIOBufferLine(&pSFTP->InBuffer, pBuffer, Size);\r
+       return 0;\r
+}\r
+\r
+size_t SFTP_PeekThreadDataIO(void* pBuffer, size_t Size)\r
+{\r
+       SFTPSTATUS* pSFTP;\r
+       if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
+               return SFTP_PeekIOBuffer(&pSFTP->DataInBuffer, pBuffer, Size);\r
+       return 0;\r
+}\r
+\r
+size_t SFTP_ReadThreadDataIO(void* pBuffer, size_t Size)\r
+{\r
+       SFTPSTATUS* pSFTP;\r
+       if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
+               return SFTP_ReadIOBuffer(&pSFTP->DataInBuffer, pBuffer, Size);\r
+       return 0;\r
+}\r
+\r
+size_t SFTP_WriteThreadDataIO(const void* pBuffer, size_t Size)\r
+{\r
+       SFTPSTATUS* pSFTP;\r
+       if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
+               return SFTP_WriteIOBuffer(&pSFTP->DataOutBuffer, pBuffer, Size);\r
+       return 0;\r
+}\r
+\r
+BOOL SFTP_GetThreadFilePositon(DWORD* pLow, LONG* pHigh)\r
+{\r
+       SFTPSTATUS* pSFTP;\r
+       if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
+       {\r
+               *pLow = pSFTP->FilePosition.LowPart;\r
+               *pHigh = pSFTP->FilePosition.HighPart;\r
+               return TRUE;\r
+       }\r
+       return FALSE;\r
+}\r
+\r
+// 以下ラッパー\r
+\r
+HANDLE GetStdHandleX(DWORD nStdHandle)\r
+{\r
+       HANDLE r = INVALID_HANDLE_VALUE;\r
+       if(!g_hStdIn)\r
+               g_hStdIn = (HANDLE)1;\r
+       if(!g_hStdOut)\r
+               g_hStdOut = (HANDLE)2;\r
+       if(!g_hStdErr)\r
+               g_hStdErr = (HANDLE)3;\r
+       if(nStdHandle == STD_INPUT_HANDLE)\r
+               r = g_hStdIn;\r
+       if(nStdHandle == STD_OUTPUT_HANDLE)\r
+               r = g_hStdOut;\r
+       if(nStdHandle == STD_ERROR_HANDLE)\r
+               r = g_hStdErr;\r
+       return r;\r
+}\r
+\r
+BOOL GetConsoleModeX(HANDLE hConsoleHandle, LPDWORD lpMode)\r
+{\r
+       BOOL r = FALSE;\r
+       return r;\r
+}\r
+\r
+BOOL SetConsoleModeX(HANDLE hConsoleHandle, DWORD dwMode)\r
+{\r
+       BOOL r = FALSE;\r
+       return r;\r
+}\r
+\r
+BOOL ReadFileX(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)\r
+{\r
+       BOOL r = FALSE;\r
+       if(hFile == g_hStdIn)\r
+       {\r
+               *lpNumberOfBytesRead = (DWORD)SFTP_ReadThreadIOLine(lpBuffer, nNumberOfBytesToRead);\r
+               if(*lpNumberOfBytesRead > 0)\r
+                       r = TRUE;\r
+       }\r
+       else if(hFile == g_hStdOut)\r
+       {\r
+       }\r
+       else if(hFile == g_hStdErr)\r
+       {\r
+       }\r
+       return r;\r
+}\r
+\r
+BOOL WriteFileX(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)\r
+{\r
+       BOOL r = FALSE;\r
+       if(hFile == g_hStdIn)\r
+       {\r
+       }\r
+       else if(hFile == g_hStdOut)\r
+       {\r
+               *lpNumberOfBytesWritten = (DWORD)SFTP_WriteThreadIO(lpBuffer, nNumberOfBytesToWrite);\r
+               if(*lpNumberOfBytesWritten == nNumberOfBytesToWrite)\r
+                       r = TRUE;\r
+       }\r
+       else if(hFile == g_hStdErr)\r
+       {\r
+               *lpNumberOfBytesWritten = (DWORD)SFTP_WriteThreadIO(lpBuffer, nNumberOfBytesToWrite);\r
+               if(*lpNumberOfBytesWritten == nNumberOfBytesToWrite)\r
+                       r = TRUE;\r
+       }\r
+       return r;\r
+}\r
+\r
+int printfX(const char * _Format, ...)\r
+{\r
+       int r = 0;\r
+       va_list v;\r
+       char Temp[1024];\r
+       va_start(v, _Format);\r
+       vsprintf(Temp, _Format, v);\r
+       r = (int)SFTP_WriteThreadIO(Temp, strlen(Temp));\r
+       va_end(v);\r
+       return r;\r
+}\r
+\r
+int putsX(const char * _Str)\r
+{\r
+       int r = 0;\r
+       r = (int)SFTP_WriteThreadIO(_Str, strlen(_Str));\r
+       return r;\r
+}\r
+\r
+int fprintfX(FILE * _File, const char * _Format, ...)\r
+{\r
+       int r = 0;\r
+       va_list v;\r
+       char Temp[1024];\r
+       va_start(v, _Format);\r
+       if(_File == stdout)\r
+       {\r
+               vsprintf(Temp, _Format, v);\r
+               r = (int)SFTP_WriteThreadIO(Temp, strlen(Temp));\r
+       }\r
+       else if(_File == stderr)\r
+       {\r
+               vsprintf(Temp, _Format, v);\r
+               r = (int)SFTP_WriteThreadIO(Temp, strlen(Temp));\r
+       }\r
+       else\r
+               r = vfprintf(_File, _Format, v);\r
+       va_end(v);\r
+       return r;\r
+}\r
+\r
+char * fgetsX(char * _Buf, int _MaxCount, FILE * _File)\r
+{\r
+       char * r = NULL;\r
+       if(_File == stdin)\r
+       {\r
+               memset(_Buf, 0, _MaxCount);\r
+               SFTP_ReadThreadIOLine(_Buf, _MaxCount - 1);\r
+               r = _Buf;\r
+       }\r
+       else\r
+               r = fgets(_Buf, _MaxCount, _File);\r
+       return r;\r
+}\r
+\r
+int fputsX(const char * _Str, FILE * _File)\r
+{\r
+       int r = 0;\r
+       if(_File == stdout)\r
+       {\r
+               r = (int)SFTP_WriteThreadIO(_Str, strlen(_Str));\r
+       }\r
+       else if(_File == stderr)\r
+       {\r
+               r = (int)SFTP_WriteThreadIO(_Str, strlen(_Str));\r
+       }\r
+       else\r
+               r = fputs(_Str, _File);\r
+       return r;\r
+}\r
+\r
+int fflushX(FILE * _File)\r
+{\r
+       int r = 0;\r
+       if(_File == stdout)\r
+       {\r
+       }\r
+       else if(_File == stderr)\r
+       {\r
+       }\r
+       else\r
+               r = fflush(_File);\r
+       return r;\r
+}\r
+\r
+void exitX(int _Code)\r
+{\r
+       SFTPSTATUS* pSFTP;\r
+       if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
+       {\r
+               pSFTP->bExit = TRUE;\r
+               SFTP_AbortIOBuffer(&pSFTP->InBuffer, TRUE);\r
+               SFTP_AbortIOBuffer(&pSFTP->OutBuffer, TRUE);\r
+               SFTP_AbortIOBuffer(&pSFTP->DataInBuffer, TRUE);\r
+               SFTP_AbortIOBuffer(&pSFTP->DataOutBuffer, TRUE);\r
+       }\r
+       TerminateThread(GetCurrentThread(), (DWORD)_Code);\r
+}\r
+\r
diff --git a/putty/iowrapper.h b/putty/iowrapper.h
new file mode 100644 (file)
index 0000000..ad80304
--- /dev/null
@@ -0,0 +1,96 @@
+// iowrapper.h\r
+// Copyright (C) 2011 Suguru Kawamoto\r
+// 標準入出力APIラッパー\r
+\r
+#ifndef __IOWRAPPER_H__\r
+#define __IOWRAPPER_H__\r
+\r
+#include <stdio.h>\r
+#include <windows.h>\r
+\r
+#ifndef DO_NOT_REPLACE\r
+\r
+#undef GetStdHandle\r
+#define GetStdHandle GetStdHandleX\r
+HANDLE GetStdHandleX(DWORD nStdHandle);\r
+#undef GetConsoleMode\r
+#define GetConsoleMode GetConsoleModeX\r
+BOOL GetConsoleModeX(HANDLE hConsoleHandle, LPDWORD lpMode);\r
+#undef SetConsoleMode\r
+#define SetConsoleMode SetConsoleModeX\r
+BOOL SetConsoleModeX(HANDLE hConsoleHandle, DWORD dwMode);\r
+#undef ReadFile\r
+#define ReadFile ReadFileX\r
+BOOL ReadFileX(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);\r
+#undef WriteFile\r
+#define WriteFile WriteFileX\r
+BOOL WriteFileX(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);\r
+#undef printf\r
+#define printf printfX\r
+int printfX(const char * _Format, ...);\r
+#undef gets\r
+#define gets getsX\r
+char * getsX(char * _Buffer);\r
+#undef puts\r
+#define puts putsX\r
+int putsX(const char * _Str);\r
+#undef fprintf\r
+#define fprintf fprintfX\r
+int fprintfX(FILE * _File, const char * _Format, ...);\r
+#undef fgets\r
+#define fgets fgetsX\r
+char * fgetsX(char * _Buf, int _MaxCount, FILE * _File);\r
+#undef fputs\r
+#define fputs fputsX\r
+int fputsX(const char * _Str, FILE * _File);\r
+#undef exit\r
+#define exit exitX\r
+void exitX(int _Code);\r
+\r
+#endif\r
+\r
+typedef BOOL (__stdcall* LPSFTPTIMEOUTCALLBACK)(BOOL*);\r
+\r
+typedef struct\r
+{\r
+       CRITICAL_SECTION Lock;\r
+       BYTE* pBuffer;\r
+       size_t Length;\r
+       size_t Written;\r
+       size_t Read;\r
+       BOOL bAborted;\r
+       LPSFTPTIMEOUTCALLBACK pCallback;\r
+} SFTPIOBUFFER;\r
+\r
+typedef struct\r
+{\r
+       DWORD ThreadId;\r
+       BOOL bExit;\r
+       LPSFTPTIMEOUTCALLBACK pCallback;\r
+       SFTPIOBUFFER InBuffer;\r
+       SFTPIOBUFFER OutBuffer;\r
+       SFTPIOBUFFER DataInBuffer;\r
+       SFTPIOBUFFER DataOutBuffer;\r
+       LARGE_INTEGER FilePosition;\r
+} SFTPSTATUS;\r
+\r
+DWORD WINAPI SFTP_ThreadProc(LPVOID lpParameter);\r
+SFTPSTATUS* FindSFTPStatus(DWORD ThreadId);\r
+BOOL SFTP_InitializeIOBuffer(SFTPIOBUFFER* pIO, size_t Length);\r
+void SFTP_UninitializeIOBuffer(SFTPIOBUFFER* pIO);\r
+void SFTP_AbortIOBuffer(SFTPIOBUFFER* pIO, BOOL bAborted);\r
+size_t SFTP_PeekIOBuffer(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size);\r
+size_t SFTP_ReadIOBuffer(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size);\r
+size_t SFTP_WriteIOBuffer(SFTPIOBUFFER* pIO, const void* pBuffer, size_t Size);\r
+size_t SFTP_ReadIOBufferLine(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size);\r
+size_t SFTP_PeekThreadIO(void* pBuffer, size_t Size);\r
+size_t SFTP_ReadThreadIO(void* pBuffer, size_t Size);\r
+size_t SFTP_WriteThreadIO(const void* pBuffer, size_t Size);\r
+size_t SFTP_ReadThreadIOLine(void* pBuffer, size_t Size);\r
+size_t SFTP_PeekThreadDataIO(void* pBuffer, size_t Size);\r
+size_t SFTP_ReadThreadDataIO(void* pBuffer, size_t Size);\r
+size_t SFTP_WriteThreadDataIO(const void* pBuffer, size_t Size);\r
+BOOL SFTP_GetThreadFilePositon(DWORD* pLow, LONG* pHigh);\r
+\r
+#endif\r
+\r
diff --git a/putty/mbswrapper.c b/putty/mbswrapper.c
new file mode 100644 (file)
index 0000000..2239f2d
--- /dev/null
@@ -0,0 +1,955 @@
+// mbswrapper.c\r
+// Copyright (C) 2011 Suguru Kawamoto\r
+// マルチバイト文字ワイド文字APIラッパー\r
+// マルチバイト文字はUTF-8、ワイド文字はUTF-16であるものとする\r
+// 全ての制御用の文字はASCIIの範囲であるため、Shift_JISとUTF-8間の変換は不要\r
+\r
+#define UNICODE\r
+#define _UNICODE\r
+\r
+#include <stdio.h>\r
+#include <tchar.h>\r
+#include <direct.h>\r
+#include <windows.h>\r
+#include <commctrl.h>\r
+#include <shlobj.h>\r
+#include <htmlhelp.h>\r
+\r
+#define DO_NOT_REPLACE\r
+#include "mbswrapper.h"\r
+\r
+// マルチバイト文字列からワイド文字列へ変換\r
+int MtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)\r
+{\r
+       if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
+               return 0;\r
+       if(pDst)\r
+               return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, pDst, size);\r
+       return MultiByteToWideChar(CP_UTF8, 0, pSrc, count, NULL, 0);\r
+}\r
+\r
+// ワイド文字列からマルチバイト文字列へ変換\r
+int WtoM(LPSTR pDst, int size, LPCWSTR pSrc, int count)\r
+{\r
+       if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
+               return 0;\r
+       if(pDst)\r
+               return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, pDst, size, NULL, NULL);\r
+       return WideCharToMultiByte(CP_UTF8, 0, pSrc, count, NULL, 0, NULL, NULL);\r
+}\r
+\r
+// Shift_JIS文字列からワイド文字列へ変換\r
+int AtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count)\r
+{\r
+       if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
+               return 0;\r
+       if(pDst)\r
+               return MultiByteToWideChar(CP_ACP, 0, pSrc, count, pDst, size);\r
+       return MultiByteToWideChar(CP_ACP, 0, pSrc, count, NULL, 0);\r
+}\r
+\r
+// ワイド文字列からShift_JIS文字列へ変換\r
+int WtoA(LPSTR pDst, int size, LPCWSTR pSrc, int count)\r
+{\r
+       if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
+               return 0;\r
+       if(pDst)\r
+               return WideCharToMultiByte(CP_ACP, 0, pSrc, count, pDst, size, NULL, NULL);\r
+       return WideCharToMultiByte(CP_ACP, 0, pSrc, count, NULL, 0, NULL, NULL);\r
+}\r
+\r
+// マルチバイト文字列バッファ終端を強制的にNULLで置換\r
+int TerminateStringM(LPSTR lpString, int size)\r
+{\r
+       int i;\r
+       if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)\r
+               return 0;\r
+       for(i = 0; i < size; i++)\r
+       {\r
+               if(lpString[i] == '\0')\r
+                       return i;\r
+       }\r
+       i--;\r
+       lpString[i] = '\0';\r
+       return i;\r
+}\r
+\r
+// ワイド文字列バッファ終端を強制的にNULLで置換\r
+int TerminateStringW(LPWSTR lpString, int size)\r
+{\r
+       int i;\r
+       if(lpString < (LPWSTR)0x00010000 || lpString == (LPWSTR)~0)\r
+               return 0;\r
+       for(i = 0; i < size; i++)\r
+       {\r
+               if(lpString[i] == L'\0')\r
+                       return i;\r
+       }\r
+       i--;\r
+       lpString[i] = L'\0';\r
+       return i;\r
+}\r
+\r
+// Shift_JIS文字列バッファ終端を強制的にNULLで置換\r
+int TerminateStringA(LPSTR lpString, int size)\r
+{\r
+       int i;\r
+       if(lpString < (LPSTR)0x00010000 || lpString == (LPSTR)~0)\r
+               return 0;\r
+       for(i = 0; i < size; i++)\r
+       {\r
+               if(lpString[i] == '\0')\r
+                       return i;\r
+       }\r
+       i--;\r
+       lpString[i] = '\0';\r
+       return i;\r
+}\r
+\r
+// NULL区切り複数マルチバイト文字列の長さを取得\r
+size_t GetMultiStringLengthM(LPCSTR lpString)\r
+{\r
+       size_t i;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return 0;\r
+       i = 0;\r
+       while(lpString[i] != '\0' || lpString[i + 1] != '\0')\r
+       {\r
+               i++;\r
+       }\r
+       i++;\r
+       return i;\r
+}\r
+\r
+// NULL区切り複数ワイド文字列の長さを取得\r
+size_t GetMultiStringLengthW(LPCWSTR lpString)\r
+{\r
+       size_t i;\r
+       if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
+               return 0;\r
+       i = 0;\r
+       while(lpString[i] != L'\0' || lpString[i + 1] != L'\0')\r
+       {\r
+               i++;\r
+       }\r
+       i++;\r
+       return i;\r
+}\r
+\r
+// NULL区切り複数Shift_JIS文字列の長さを取得\r
+size_t GetMultiStringLengthA(LPCSTR lpString)\r
+{\r
+       size_t i;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return 0;\r
+       i = 0;\r
+       while(lpString[i] != '\0' || lpString[i + 1] != '\0')\r
+       {\r
+               i++;\r
+       }\r
+       i++;\r
+       return i;\r
+}\r
+\r
+// NULL区切りマルチバイト文字列からワイド文字列へ変換\r
+int MtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)\r
+{\r
+       int i;\r
+       if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
+               return 0;\r
+       if(!pDst)\r
+               return GetMultiStringLengthM(pSrc);\r
+       i = 0;\r
+       while(*pSrc != '\0')\r
+       {\r
+               i += MultiByteToWideChar(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1);\r
+               pSrc += strlen(pSrc) + 1;\r
+       }\r
+       pDst[i] = L'\0';\r
+       return i;\r
+}\r
+\r
+// NULL区切りワイド文字列からマルチバイト文字列へ変換\r
+int WtoMMultiString(LPSTR pDst, int size, LPCWSTR pSrc)\r
+{\r
+       int i;\r
+       if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
+               return 0;\r
+       if(!pDst)\r
+               return GetMultiStringLengthW(pSrc);\r
+       i = 0;\r
+       while(*pSrc != L'\0')\r
+       {\r
+               i += WideCharToMultiByte(CP_UTF8, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);\r
+               pSrc += wcslen(pSrc) + 1;\r
+       }\r
+       pDst[i] = '\0';\r
+       return i;\r
+}\r
+\r
+// NULL区切りShift_JIS文字列からワイド文字列へ変換\r
+int AtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc)\r
+{\r
+       int i;\r
+       if(pSrc < (LPCSTR)0x00010000 || pSrc == (LPCSTR)~0)\r
+               return 0;\r
+       if(!pDst)\r
+               return GetMultiStringLengthA(pSrc);\r
+       i = 0;\r
+       while(*pSrc != '\0')\r
+       {\r
+               i += MultiByteToWideChar(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1);\r
+               pSrc += strlen(pSrc) + 1;\r
+       }\r
+       pDst[i] = L'\0';\r
+       return i;\r
+}\r
+\r
+// NULL区切りワイド文字列からShift_JIS文字列へ変換\r
+int WtoAMultiString(LPSTR pDst, int size, LPCWSTR pSrc)\r
+{\r
+       int i;\r
+       if(pSrc < (LPCWSTR)0x00010000 || pSrc == (LPCWSTR)~0)\r
+               return 0;\r
+       if(!pDst)\r
+               return GetMultiStringLengthW(pSrc);\r
+       i = 0;\r
+       while(*pSrc != L'\0')\r
+       {\r
+               i += WideCharToMultiByte(CP_ACP, 0, pSrc, -1, pDst + i, size - i - 1, NULL, NULL);\r
+               pSrc += wcslen(pSrc) + 1;\r
+       }\r
+       pDst[i] = '\0';\r
+       return i;\r
+}\r
+\r
+// マルチバイト文字列用のメモリを確保\r
+char* AllocateStringM(int size)\r
+{\r
+       char* p;\r
+       // 0が指定される場合があるため1文字分追加\r
+       p = (char*)malloc(sizeof(char) * (size + 1));\r
+       // 念のため先頭にNULL文字を代入\r
+       if(p)\r
+               *p = '\0';\r
+       return p;\r
+}\r
+\r
+// ワイド文字列用のメモリを確保\r
+wchar_t* AllocateStringW(int size)\r
+{\r
+       wchar_t* p;\r
+       // 0が指定される場合があるため1文字分追加\r
+       p = (wchar_t*)malloc(sizeof(wchar_t) * (size + 1));\r
+       // 念のため先頭にNULL文字を代入\r
+       if(p)\r
+               *p = L'\0';\r
+       return p;\r
+}\r
+\r
+// Shift_JIS文字列用のメモリを確保\r
+char* AllocateStringA(int size)\r
+{\r
+       char* p;\r
+       // 0が指定される場合があるため1文字分追加\r
+       p = (char*)malloc(sizeof(char) * (size + 1));\r
+       // 念のため先頭にNULL文字を代入\r
+       if(p)\r
+               *p = '\0';\r
+       return p;\r
+}\r
+\r
+// メモリを確保してマルチバイト文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateMtoW(LPCSTR lpString, int c)\r
+{\r
+       wchar_t* p;\r
+       int i;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return (wchar_t*)lpString;\r
+       if(c < 0)\r
+               c = strlen(lpString);\r
+       p = AllocateStringW(MtoW(NULL, 0, lpString, c) + 1);\r
+       if(p)\r
+       {\r
+               i = MtoW(p, 65535, lpString, c);\r
+               p[i] = L'\0';\r
+       }\r
+       return p;\r
+}\r
+\r
+// 指定したサイズのメモリを確保してマルチバイト文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateMtoWBuffer(LPCSTR lpString, int c, int size)\r
+{\r
+       wchar_t* p;\r
+       int i;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return (wchar_t*)lpString;\r
+       if(c < 0)\r
+               c = strlen(lpString);\r
+       p = AllocateStringW(size);\r
+       if(p)\r
+       {\r
+               i = MtoW(p, size, lpString, c);\r
+               p[i] = L'\0';\r
+       }\r
+       return p;\r
+}\r
+\r
+// メモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateMtoWMultiString(LPCSTR lpString)\r
+{\r
+       int count;\r
+       wchar_t* p;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return (wchar_t*)lpString;\r
+       count = GetMultiStringLengthM(lpString) + 1;\r
+       p = AllocateStringW(count);\r
+       if(p)\r
+               MtoW(p, count, lpString, count);\r
+       return p;\r
+}\r
+\r
+// 指定したサイズのメモリを確保してNULL区切りマルチバイト文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size)\r
+{\r
+       int count;\r
+       wchar_t* p;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return (wchar_t*)lpString;\r
+       count = GetMultiStringLengthM(lpString) + 1;\r
+       p = AllocateStringW(size);\r
+       if(p)\r
+       {\r
+               MtoW(p, size, lpString, count);\r
+               p[size - 2] = L'\0';\r
+               p[size - 1] = L'\0';\r
+       }\r
+       return p;\r
+}\r
+\r
+// メモリを確保してワイド文字列からマルチバイト文字列へ変換\r
+// リソースIDならば元の値を返す\r
+char* DuplicateWtoM(LPCWSTR lpString, int c)\r
+{\r
+       char* p;\r
+       int i;\r
+       if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
+               return (char*)lpString;\r
+       if(c < 0)\r
+               c = wcslen(lpString);\r
+       p = AllocateStringM(WtoM(NULL, 0, lpString, c) + 1);\r
+       if(p)\r
+       {\r
+               i = WtoM(p, 65535, lpString, c);\r
+               p[i] = L'\0';\r
+       }\r
+       return p;\r
+}\r
+\r
+// メモリを確保してShift_JIS文字列からワイド文字列へ変換\r
+// リソースIDならば元の値を返す\r
+wchar_t* DuplicateAtoW(LPCSTR lpString, int c)\r
+{\r
+       wchar_t* p;\r
+       int i;\r
+       if(lpString < (LPCSTR)0x00010000 || lpString == (LPCSTR)~0)\r
+               return (wchar_t*)lpString;\r
+       if(c < 0)\r
+               c = strlen(lpString);\r
+       p = AllocateStringW(AtoW(NULL, 0, lpString, c) + 1);\r
+       if(p)\r
+       {\r
+               i = AtoW(p, 65535, lpString, c);\r
+               p[i] = L'\0';\r
+       }\r
+       return p;\r
+}\r
+\r
+// メモリを確保してワイド文字列からShift_JIS文字列へ変換\r
+// リソースIDならば元の値を返す\r
+char* DuplicateWtoA(LPCWSTR lpString, int c)\r
+{\r
+       char* p;\r
+       int i;\r
+       if(lpString < (LPCWSTR)0x00010000 || lpString == (LPCWSTR)~0)\r
+               return (char*)lpString;\r
+       if(c < 0)\r
+               c = wcslen(lpString);\r
+       p = AllocateStringA(WtoA(NULL, 0, lpString, c) + 1);\r
+       if(p)\r
+       {\r
+               i = WtoA(p, 65535, lpString, c);\r
+               p[i] = L'\0';\r
+       }\r
+       return p;\r
+}\r
+\r
+// マルチバイト文字列からコードポイントと次のポインタを取得\r
+// エンコードが不正な場合は0x80000000を返す\r
+DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext)\r
+{\r
+       DWORD Code;\r
+       int i;\r
+       Code = 0;\r
+       if((*lpString & 0xfe) == 0xfc)\r
+       {\r
+               i = 5;\r
+               Code |= (DWORD)*lpString & 0x01;\r
+       }\r
+       else if((*lpString & 0xfc) == 0xf8)\r
+       {\r
+               i = 4;\r
+               Code |= (DWORD)*lpString & 0x03;\r
+       }\r
+       else if((*lpString & 0xf8) == 0xf0)\r
+       {\r
+               i = 3;\r
+               Code |= (DWORD)*lpString & 0x07;\r
+       }\r
+       else if((*lpString & 0xf0) == 0xe0)\r
+       {\r
+               i = 2;\r
+               Code |= (DWORD)*lpString & 0x0f;\r
+       }\r
+       else if((*lpString & 0xe0) == 0xc0)\r
+       {\r
+               i = 1;\r
+               Code |= (DWORD)*lpString & 0x1f;\r
+       }\r
+       else if((*lpString & 0x80) == 0x00)\r
+       {\r
+               i = 0;\r
+               Code |= (DWORD)*lpString & 0x7f;\r
+       }\r
+       else\r
+               i = -1;\r
+       lpString++;\r
+       while((*lpString & 0xc0) == 0x80)\r
+       {\r
+               i--;\r
+               Code = Code << 6;\r
+               Code |= (DWORD)*lpString & 0x3f;\r
+               lpString++;\r
+       }\r
+       if(i != 0)\r
+               Code = 0x80000000;\r
+       if(ppNext)\r
+               *ppNext = lpString;\r
+       return Code;\r
+}\r
+\r
+// マルチバイト文字列の冗長表現を修正\r
+// 修正があればTRUEを返す\r
+// 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能\r
+BOOL FixStringM(LPSTR pDst, LPCSTR pSrc)\r
+{\r
+       BOOL bResult;\r
+       char* p;\r
+       DWORD Code;\r
+       int i;\r
+       char c;\r
+       bResult = FALSE;\r
+       p = (char*)pSrc;\r
+       while(*pSrc != '\0')\r
+       {\r
+               Code = GetNextCharM(pSrc, &pSrc);\r
+               if(Code & 0x80000000)\r
+                       continue;\r
+               else if(Code & 0x7c000000)\r
+               {\r
+                       i = 5;\r
+                       c = (char)(0xfc | (Code >> (6 * i)));\r
+               }\r
+               else if(Code & 0x03e00000)\r
+               {\r
+                       i = 4;\r
+                       c = (char)(0xf8 | (Code >> (6 * i)));\r
+               }\r
+               else if(Code & 0x001f0000)\r
+               {\r
+                       i = 3;\r
+                       c = (char)(0xf0 | (Code >> (6 * i)));\r
+               }\r
+               else if(Code & 0x0000f800)\r
+               {\r
+                       i = 2;\r
+                       c = (char)(0xe0 | (Code >> (6 * i)));\r
+               }\r
+               else if(Code & 0x00000780)\r
+               {\r
+                       i = 1;\r
+                       c = (char)(0xc0 | (Code >> (6 * i)));\r
+               }\r
+               else\r
+               {\r
+                       i = 0;\r
+                       c = (char)Code;\r
+               }\r
+               if(c != *p)\r
+                       bResult = TRUE;\r
+               p++;\r
+               *pDst = c;\r
+               pDst++;\r
+               while(i > 0)\r
+               {\r
+                       i--;\r
+                       c = (char)(0x80 | ((Code >> (6 * i)) & 0x3f));\r
+                       if(c != *p)\r
+                               bResult = TRUE;\r
+                       p++;\r
+                       *pDst = c;\r
+                       pDst++;\r
+               }\r
+       }\r
+       if(*p != '\0')\r
+               bResult = TRUE;\r
+       *pDst = '\0';\r
+       return bResult;\r
+}\r
+\r
+// NULL区切りマルチバイト文字列の冗長表現を修正\r
+// 修正があればTRUEを返す\r
+// 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能\r
+BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc)\r
+{\r
+       BOOL bResult;\r
+       int Length;\r
+       bResult = FALSE;\r
+       while(*pSrc != '\0')\r
+       {\r
+               Length = strlen(pSrc) + 1;\r
+               bResult = bResult | FixStringM(pDst, pSrc);\r
+               pSrc += Length;\r
+               pDst += strlen(pDst) + 1;\r
+       }\r
+       *pDst = '\0';\r
+       return bResult;\r
+}\r
+\r
+// マルチバイト文字列の冗長表現を確認\r
+// 冗長表現があればTRUEを返す\r
+BOOL CheckStringM(LPCSTR lpString)\r
+{\r
+       BOOL bResult;\r
+       char* p;\r
+       bResult = FALSE;\r
+       p = AllocateStringM(strlen(lpString) + 1);\r
+       if(p)\r
+       {\r
+               bResult = FixStringM(p, lpString);\r
+               FreeDuplicatedString(p);\r
+       }\r
+       return bResult;\r
+}\r
+\r
+// NULL区切りマルチバイト文字列の冗長表現を確認\r
+// 冗長表現があればTRUEを返す\r
+BOOL CheckMultiStringM(LPCSTR lpString)\r
+{\r
+       BOOL bResult;\r
+       char* p;\r
+       bResult = FALSE;\r
+       p = AllocateStringM(GetMultiStringLengthM(lpString) + 1);\r
+       if(p)\r
+       {\r
+               bResult = FixMultiStringM(p, lpString);\r
+               FreeDuplicatedString(p);\r
+       }\r
+       return bResult;\r
+}\r
+\r
+// 文字列用に確保したメモリを開放\r
+// リソースIDならば何もしない\r
+void FreeDuplicatedString(void* p)\r
+{\r
+       if(p < (void*)0x00010000 || p == (void*)~0)\r
+               return;\r
+       free(p);\r
+}\r
+\r
+// 以下ラッパー\r
+// 戻り値バッファ r\r
+// ワイド文字バッファ pw%d\r
+// マルチバイト文字バッファ pm%d\r
+// 引数バッファ a%d\r
+\r
+#pragma warning(disable:4102)\r
+#define START_ROUTINE                                  do{\r
+#define END_ROUTINE                                            }while(0);end_of_routine:\r
+#define QUIT_ROUTINE                                   goto end_of_routine;\r
+\r
+HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)\r
+{\r
+       HANDLE r = INVALID_HANDLE_VALUE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpFileName, -1);\r
+       r = CreateFileW(pw0, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+HANDLE FindFirstFileM(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)\r
+{\r
+       HANDLE r = INVALID_HANDLE_VALUE;\r
+       wchar_t* pw0 = NULL;\r
+       WIN32_FIND_DATAW a0;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpFileName, -1);\r
+       r = FindFirstFileW(pw0, &a0);\r
+       if(r != INVALID_HANDLE_VALUE)\r
+       {\r
+               lpFindFileData->dwFileAttributes = a0.dwFileAttributes;\r
+               lpFindFileData->ftCreationTime = a0.ftCreationTime;\r
+               lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;\r
+               lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;\r
+               lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;\r
+               lpFindFileData->nFileSizeLow = a0.nFileSizeLow;\r
+               lpFindFileData->dwReserved0 = a0.dwReserved0;\r
+               lpFindFileData->dwReserved1 = a0.dwReserved1;\r
+               WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);\r
+               WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);\r
+       }\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+BOOL FindNextFileM(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)\r
+{\r
+       BOOL r = FALSE;\r
+       WIN32_FIND_DATAW a0;\r
+START_ROUTINE\r
+       r = FindNextFileW(hFindFile, &a0);\r
+       if(r)\r
+       {\r
+               lpFindFileData->dwFileAttributes = a0.dwFileAttributes;\r
+               lpFindFileData->ftCreationTime = a0.ftCreationTime;\r
+               lpFindFileData->ftLastAccessTime = a0.ftLastAccessTime;\r
+               lpFindFileData->ftLastWriteTime = a0.ftLastWriteTime;\r
+               lpFindFileData->nFileSizeHigh = a0.nFileSizeHigh;\r
+               lpFindFileData->nFileSizeLow = a0.nFileSizeLow;\r
+               lpFindFileData->dwReserved0 = a0.dwReserved0;\r
+               lpFindFileData->dwReserved1 = a0.dwReserved1;\r
+               WtoM(lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName), a0.cFileName, -1);\r
+               WtoM(lpFindFileData->cAlternateFileName, sizeof(lpFindFileData->cAlternateFileName), a0.cAlternateFileName, -1);\r
+       }\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+DWORD GetCurrentDirectoryM(DWORD nBufferLength, LPSTR lpBuffer)\r
+{\r
+       DWORD r = 0;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       // TODO: バッファが不十分な場合に必要なサイズを返す\r
+       pw0 = AllocateStringW(nBufferLength * 4);\r
+       GetCurrentDirectoryW(nBufferLength * 4, pw0);\r
+       WtoM(lpBuffer, nBufferLength, pw0, -1);\r
+       r = TerminateStringM(lpBuffer, nBufferLength);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+BOOL SetCurrentDirectoryM(LPCSTR lpPathName)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpPathName, -1);\r
+       r = SetCurrentDirectoryW(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+DWORD GetTempPathM(DWORD nBufferLength, LPSTR lpBuffer)\r
+{\r
+       DWORD r = 0;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = AllocateStringW(nBufferLength * 4);\r
+       GetTempPathW(nBufferLength * 4, pw0);\r
+       WtoM(lpBuffer, nBufferLength, pw0, -1);\r
+       r = TerminateStringM(lpBuffer, nBufferLength);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+DWORD GetFileAttributesM(LPCSTR lpFileName)\r
+{\r
+       DWORD r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpFileName, -1);\r
+       r = GetFileAttributesW(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+DWORD GetModuleFileNameM(HMODULE hModule, LPCH lpFilename, DWORD nSize)\r
+{\r
+       DWORD r = 0;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = AllocateStringW(nSize * 4);\r
+       GetModuleFileNameW(hModule, pw0, nSize * 4);\r
+       WtoM(lpFilename, nSize, pw0, -1);\r
+       r = TerminateStringM(lpFilename, nSize);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+BOOL CopyFileM(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, BOOL bFailIfExists)\r
+{\r
+       BOOL r = FALSE;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(lpExistingFileName, -1);\r
+       pw1 = DuplicateMtoW(lpNewFileName, -1);\r
+       r = CopyFileW(pw0, pw1, bFailIfExists);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
+int mkdirM(const char * _Path)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Path, -1);\r
+       r = _wmkdir(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int _mkdirM(const char * _Path)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Path, -1);\r
+       r = _wmkdir(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int rmdirM(const char * _Path)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Path, -1);\r
+       r = _wrmdir(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int _rmdirM(const char * _Path)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Path, -1);\r
+       r = _wrmdir(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int removeM(const char * _Filename)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Filename, -1);\r
+       r = _wremove(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int _removeM(const char * _Filename)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Filename, -1);\r
+       r = _wremove(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+int _unlinkM(const char * _Filename)\r
+{\r
+       int r = -1;\r
+       wchar_t* pw0 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Filename, -1);\r
+       r = _wunlink(pw0);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       return r;\r
+}\r
+\r
+size_t _mbslenM(const unsigned char * _Str)\r
+{\r
+       size_t r = 0;\r
+START_ROUTINE\r
+       while(GetNextCharM(_Str, &_Str) > 0)\r
+       {\r
+               r++;\r
+       }\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch)\r
+{\r
+       unsigned char* r = NULL;\r
+       unsigned int c;\r
+       unsigned char* p;\r
+START_ROUTINE\r
+       while((c = GetNextCharM(_Str, &p)) > 0)\r
+       {\r
+               if(c == _Ch)\r
+                       break;\r
+               _Str = p;\r
+       }\r
+       if(c == _Ch)\r
+               r = (unsigned char*)_Str;\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch)\r
+{\r
+       unsigned char* r = NULL;\r
+       unsigned int c;\r
+       unsigned char* p;\r
+START_ROUTINE\r
+       while((c = GetNextCharM(_Str, &p)) > 0)\r
+       {\r
+               if(c == _Ch)\r
+                       r = (unsigned char*)_Str;\r
+               _Str = p;\r
+       }\r
+       if(c == _Ch)\r
+               r = (unsigned char*)_Str;\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr)\r
+{\r
+       unsigned char* r = NULL;\r
+START_ROUTINE\r
+       r = strstr(_Str, _Substr);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
+{\r
+       int r = 0;\r
+START_ROUTINE\r
+       r = strcmp(_Str1, _Str2);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2)\r
+{\r
+       int r = 0;\r
+START_ROUTINE\r
+       r = _stricmp(_Str1, _Str2);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+int _mbsncmpM(const unsigned char * _Str1, const unsigned char * _Str2, size_t _MaxCount)\r
+{\r
+       int r = 0;\r
+       DWORD c1;\r
+       DWORD c2;\r
+START_ROUTINE\r
+       c1 = 0;\r
+       c2 = 0;\r
+       while(_MaxCount > 0)\r
+       {\r
+               c1 = GetNextCharM(_Str1, &_Str1);\r
+               c2 = GetNextCharM(_Str2, &_Str2);\r
+               if(c1 != c2)\r
+                       break;\r
+               _MaxCount--;\r
+               if(c1 == 0 || c2 == 0)\r
+                       break;\r
+       }\r
+       r = c1 - c2;\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+unsigned char * _mbslwrM(unsigned char * _String)\r
+{\r
+       unsigned char* r = NULL;\r
+START_ROUTINE\r
+       r = _strlwr(_String);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+unsigned char * _mbsuprM(unsigned char * _String)\r
+{\r
+       unsigned char* r = NULL;\r
+START_ROUTINE\r
+       r = _strupr(_String);\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count)\r
+{\r
+       unsigned char* r = NULL;\r
+START_ROUTINE\r
+       while(_Count > 0 && GetNextCharM(_Str, &_Str) > 0)\r
+       {\r
+               _Count--;\r
+       }\r
+       r = (unsigned char*)_Str;\r
+END_ROUTINE\r
+       return r;\r
+}\r
+\r
+FILE * fopenM(const char * _Filename, const char * _Mode)\r
+{\r
+       FILE* r = NULL;\r
+       wchar_t* pw0 = NULL;\r
+       wchar_t* pw1 = NULL;\r
+START_ROUTINE\r
+       pw0 = DuplicateMtoW(_Filename, -1);\r
+       pw1 = DuplicateMtoW(_Mode, -1);\r
+       r = _wfopen(pw0, pw1);\r
+END_ROUTINE\r
+       FreeDuplicatedString(pw0);\r
+       FreeDuplicatedString(pw1);\r
+       return r;\r
+}\r
+\r
diff --git a/putty/mbswrapper.h b/putty/mbswrapper.h
new file mode 100644 (file)
index 0000000..592a909
--- /dev/null
@@ -0,0 +1,130 @@
+// mbswrapper.h\r
+// Copyright (C) 2011 Suguru Kawamoto\r
+// マルチバイト文字ワイド文字APIラッパー\r
+\r
+#ifndef __MBSWRAPPER_H__\r
+#define __MBSWRAPPER_H__\r
+\r
+#include <stdio.h>\r
+#include <windows.h>\r
+#include <shlobj.h>\r
+\r
+#ifndef DO_NOT_REPLACE\r
+\r
+#undef CreateFile\r
+#define CreateFile CreateFileM\r
+HANDLE CreateFileM(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);\r
+#undef FindFirstFile\r
+#define FindFirstFile FindFirstFileM\r
+HANDLE FindFirstFileM(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData);\r
+#undef FindNextFile\r
+#define FindNextFile FindNextFileM\r
+BOOL FindNextFileM(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData);\r
+#undef GetCurrentDirectory\r
+#define GetCurrentDirectory GetCurrentDirectoryM\r
+DWORD GetCurrentDirectoryM(DWORD nBufferLength, LPSTR lpBuffer);\r
+#undef SetCurrentDirectory\r
+#define SetCurrentDirectory SetCurrentDirectoryM\r
+BOOL SetCurrentDirectoryM(LPCSTR lpPathName);\r
+#undef GetTempPath\r
+#define GetTempPath GetTempPathM\r
+DWORD GetTempPathM(DWORD nBufferLength, LPSTR lpBuffer);\r
+#undef GetFileAttributes\r
+#define GetFileAttributes GetFileAttributesM\r
+DWORD GetFileAttributesM(LPCSTR lpFileName);\r
+#undef GetModuleFileName\r
+#define GetModuleFileName GetModuleFileNameM\r
+DWORD GetModuleFileNameM(HMODULE hModule, LPCH lpFilename, DWORD nSize);\r
+#undef CopyFile\r
+#define CopyFile CopyFileM\r
+BOOL CopyFileM(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, BOOL bFailIfExists);\r
+#undef mkdir\r
+#define mkdir _mkdirM\r
+int mkdirM(const char * _Path);\r
+#undef _mkdir\r
+#define _mkdir _mkdirM\r
+int _mkdirM(const char * _Path);\r
+#undef rmdir\r
+#define rmdir rmdirM\r
+int rmdirM(const char * _Path);\r
+#undef _rmdir\r
+#define _rmdir _rmdirM\r
+int _rmdirM(const char * _Path);\r
+#undef remove\r
+#define remove removeM\r
+int removeM(const char * _Filename);\r
+#undef _remove\r
+#define _remove _removeM\r
+int _removeM(const char * _Filename);\r
+#undef _unlink\r
+#define _unlink _unlinkM\r
+int _unlinkM(const char * _Filename);\r
+#undef _mbslen\r
+#define _mbslen _mbslenM\r
+size_t _mbslenM(const unsigned char * _Str);\r
+#undef _mbschr\r
+#define _mbschr _mbschrM\r
+unsigned char * _mbschrM(const unsigned char * _Str, unsigned int _Ch);\r
+#undef _mbsrchr\r
+#define _mbsrchr _mbsrchrM\r
+unsigned char * _mbsrchrM(const unsigned char * _Str, unsigned int _Ch);\r
+#undef _mbsstr\r
+#define _mbsstr _mbsstrM\r
+unsigned char * _mbsstrM(const unsigned char * _Str, const unsigned char * _Substr);\r
+#undef _mbscmp\r
+#define _mbscmp _mbscmpM\r
+int _mbscmpM(const unsigned char * _Str1, const unsigned char * _Str2);\r
+#undef _mbsicmp\r
+#define _mbsicmp _mbsicmpM\r
+int _mbsicmpM(const unsigned char * _Str1, const unsigned char * _Str2);\r
+#undef _mbsncmp\r
+#define _mbsncmp _mbsncmpM\r
+int _mbsncmpM(const unsigned char * _Str1, const unsigned char * _Str2, size_t _MaxCount);\r
+#undef _mbslwr\r
+#define _mbslwr _mbslwrM\r
+unsigned char * _mbslwrM(unsigned char * _String);\r
+#undef _mbsupr\r
+#define _mbsupr _mbsuprM\r
+unsigned char * _mbsuprM(unsigned char * _String);\r
+#undef _mbsninc\r
+#define _mbsninc _mbsnincM\r
+unsigned char * _mbsnincM(const unsigned char * _Str, size_t _Count);\r
+#undef fopen\r
+#define fopen fopenM\r
+FILE * fopenM(const char * _Filename, const char * _Mode);\r
+\r
+#endif\r
+\r
+int MtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count);\r
+int WtoM(LPSTR pDst, int size, LPCWSTR pSrc, int count);\r
+int AtoW(LPWSTR pDst, int size, LPCSTR pSrc, int count);\r
+int WtoA(LPSTR pDst, int size, LPCWSTR pSrc, int count);\r
+int TerminateStringM(LPSTR lpString, int size);\r
+int TerminateStringW(LPWSTR lpString, int size);\r
+int TerminateStringA(LPSTR lpString, int size);\r
+size_t GetMultiStringLengthM(LPCSTR lpString);\r
+size_t GetMultiStringLengthW(LPCWSTR lpString);\r
+size_t GetMultiStringLengthA(LPCSTR lpString);\r
+int MtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc);\r
+int WtoMMultiString(LPSTR pDst, int size, LPCWSTR pSrc);\r
+int AtoWMultiString(LPWSTR pDst, int size, LPCSTR pSrc);\r
+int WtoAMultiString(LPSTR pDst, int size, LPCWSTR pSrc);\r
+char* AllocateStringM(int size);\r
+wchar_t* AllocateStringW(int size);\r
+char* AllocateStringA(int size);\r
+wchar_t* DuplicateMtoW(LPCSTR lpString, int c);\r
+wchar_t* DuplicateMtoWBuffer(LPCSTR lpString, int c, int size);\r
+wchar_t* DuplicateMtoWMultiString(LPCSTR lpString);\r
+wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size);\r
+char* DuplicateWtoM(LPCWSTR lpString, int c);\r
+wchar_t* DuplicateAtoW(LPCSTR lpString, int c);\r
+char* DuplicateWtoA(LPCWSTR lpString, int c);\r
+DWORD GetNextCharM(LPCSTR lpString, LPCSTR* ppNext);\r
+BOOL FixStringM(LPSTR pDst, LPCSTR pSrc);\r
+BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc);\r
+BOOL CheckStringM(LPCSTR lpString);\r
+BOOL CheckMultiStringM(LPCSTR lpString);\r
+void FreeDuplicatedString(void* p);\r
+\r
+#endif\r
+\r
index 6ee947c..56da76e 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -742,6 +742,93 @@ int CommandProcTrn(SOCKET cSkt, char *Reply, int* CancelCheckWork, char *fmt, ..
 //#pragma aaa\r
 //static int cntcnt = 0;\r
 \r
+// SFTP対応\r
+int ConvertFTPCommandToPuTTYSFTP(SOCKET cSkt, char *Reply, int *CancelCheckWork, char *Cmd)\r
+{\r
+       // TODO:\r
+       // 未実装\r
+       int Sts;\r
+       char NewCmd[FMAX_PATH*2];\r
+       static char RenameFrom[FMAX_PATH+1];\r
+       Sts = 429;\r
+       Reply[0] = '\0';\r
+       if(strcmp(Cmd, "QUIT") == 0)\r
+       {\r
+               sprintf(NewCmd, "ls\r\n");\r
+               SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);\r
+       }\r
+       if(strcmp(Cmd, "LIST") == 0)\r
+       {\r
+               sprintf(NewCmd, "ls\r\n");\r
+               SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);\r
+       }\r
+       else if(strncmp(Cmd, "REST ", 5) == 0)\r
+       {\r
+               SFTP_SetFilePosition(cSkt, (LONGLONG)_strtoi64(&Cmd[5], NULL, 10));\r
+       }\r
+       else if(strncmp(Cmd, "RETR ", 5) == 0)\r
+       {\r
+               sprintf(NewCmd, "get \"%s\"\r\n", &Cmd[5]);\r
+               SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);\r
+       }\r
+       else if(strncmp(Cmd, "STOR ", 5) == 0)\r
+       {\r
+               sprintf(NewCmd, "put \"%s\"\r\n", &Cmd[5]);\r
+               SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);\r
+       }\r
+       else if(strncmp(Cmd, "APPE ", 5) == 0)\r
+       {\r
+               sprintf(NewCmd, "reput \"%s\"\r\n", &Cmd[5]);\r
+               SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);\r
+       }\r
+       else if(strncmp(Cmd, "DELE ", 5) == 0)\r
+       {\r
+               sprintf(NewCmd, "rm \"%s\"\r\n", &Cmd[5]);\r
+               SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);\r
+       }\r
+       else if(strncmp(Cmd, "CWD ", 4) == 0)\r
+       {\r
+               sprintf(NewCmd, "cd \"%s\"\r\n", &Cmd[4]);\r
+               SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);\r
+       }\r
+       else if(strcmp(Cmd, "PWD") == 0)\r
+       {\r
+               sprintf(NewCmd, "pwd\r\n");\r
+               SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);\r
+       }\r
+       else if(strcmp(Cmd, "XPWD") == 0)\r
+       {\r
+               sprintf(NewCmd, "pwd\r\n");\r
+               SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);\r
+       }\r
+       else if(strncmp(Cmd, "MKD ", 4) == 0)\r
+       {\r
+               sprintf(NewCmd, "mkdir \"%s\"\r\n", &Cmd[4]);\r
+               SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);\r
+       }\r
+       else if(strncmp(Cmd, "RMD ", 4) == 0)\r
+       {\r
+               sprintf(NewCmd, "rmdir \"%s\"\r\n", &Cmd[4]);\r
+               SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);\r
+       }\r
+       else if(strncmp(Cmd, "RNFR ", 5) == 0)\r
+       {\r
+               strcpy(RenameFrom, &Cmd[5]);\r
+       }\r
+       else if(strncmp(Cmd, "RNTO ", 5) == 0)\r
+       {\r
+               sprintf(NewCmd, "mv \"%s\" \"%s\"\r\n", RenameFrom, &Cmd[5]);\r
+               SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);\r
+       }\r
+       else if(strncmp(Cmd, "SITE CHMOD ", 11) == 0)\r
+       {\r
+               Cmd[14] = '\0';\r
+               sprintf(NewCmd, "chmod %s \"%s\"\r\n", &Cmd[11], &Cmd[15]);\r
+               SFTP_send(cSkt, NewCmd, strlen(NewCmd), 0);\r
+       }\r
+       return Sts;\r
+}\r
+\r
 int command(SOCKET cSkt, char *Reply, int *CancelCheckWork, char *fmt, ...)\r
 {\r
        va_list Args;\r
@@ -755,6 +842,10 @@ int command(SOCKET cSkt, char *Reply, int *CancelCheckWork, char *fmt, ...)
                wvsprintf(Cmd, fmt, Args);\r
                va_end(Args);\r
 \r
+               // SFTP対応\r
+               if(IsSFTPAttached(cSkt))\r
+                       return ConvertFTPCommandToPuTTYSFTP(cSkt, Reply, CancelCheckWork, Cmd);\r
+\r
                if(strncmp(Cmd, "PASS ", 5) == 0)\r
                        SetTaskMsg(">PASS [xxxxxx]");\r
                else if((strncmp(Cmd, "USER ", 5) == 0) ||\r
index 0549f9c..db7b69f 100644 (file)
--- a/socket.c
+++ b/socket.c
@@ -772,7 +772,7 @@ int do_closesocket(SOCKET s)
        UnRegistAsyncTable(s);\r
        // FTPS対応\r
 //     Ret = closesocket(s);\r
-       Ret = closesocketS(s);\r
+       Ret = FTPS_closesocket(s);\r
        if(Ret == SOCKET_ERROR)\r
        {\r
                Error = 0;\r
@@ -1029,7 +1029,7 @@ int do_recv(SOCKET s, char *buf, int len, int flags, int *TimeOutErr, int *Cance
 \r
                        // FTPS対応\r
 //                     Ret = recv(s, buf, len, flags);\r
-                       Ret = recvS(s, buf, len, flags);\r
+                       Ret = FTPS_recv(s, buf, len, flags);\r
                        if(Ret != SOCKET_ERROR)\r
                                break;\r
                        Error = WSAGetLastError();\r
@@ -1139,7 +1139,7 @@ int do_send(SOCKET s, const char *buf, int len, int flags, int *TimeOutErr, int
 \r
                        // FTPS対応\r
 //                     Ret = send(s, buf, len, flags);\r
-                       Ret = sendS(s, buf, len, flags);\r
+                       Ret = FTPS_send(s, buf, len, flags);\r
                        if(Ret != SOCKET_ERROR)\r
                        {\r
 #if DBG_MSG\r
@@ -1191,10 +1191,10 @@ void RemoveReceivedData(SOCKET s)
        char buf[1024];\r
        int len;\r
        int Error;\r
-       while((len = recvS(s, buf, sizeof(buf), MSG_PEEK)) >= 0)\r
+       while((len = FTPS_recv(s, buf, sizeof(buf), MSG_PEEK)) >= 0)\r
        {\r
                AskAsyncDone(s, &Error, FD_READ);\r
-               recvS(s, buf, len, 0);\r
+               FTPS_recv(s, buf, len, 0);\r
        }\r
 }\r
 \r
index 49a5238..e5ab3f7 100644 (file)
@@ -16,6 +16,8 @@
 #include "mbswrapper.h"\r
 #include "punycode.h"\r
 \r
+// FTPS対応\r
+\r
 typedef void (__cdecl* _SSL_load_error_strings)();\r
 typedef int (__cdecl* _SSL_library_init)();\r
 typedef SSL_METHOD* (__cdecl* _SSLv23_method)();\r
@@ -556,24 +558,24 @@ BOOL IsSSLAttached(SOCKET s)
        return TRUE;\r
 }\r
 \r
-SOCKET socketS(int af, int type, int protocol)\r
+SOCKET FTPS_socket(int af, int type, int protocol)\r
 {\r
        return socket(af, type, protocol);\r
 }\r
 \r
-int bindS(SOCKET s, const struct sockaddr *addr, int namelen)\r
+int FTPS_bind(SOCKET s, const struct sockaddr *addr, int namelen)\r
 {\r
        return bind(s, addr, namelen);\r
 }\r
 \r
-int listenS(SOCKET s, int backlog)\r
+int FTPS_listen(SOCKET s, int backlog)\r
 {\r
        return listen(s, backlog);\r
 }\r
 \r
 // accept相当の関数\r
 // ただし初めからSSLのネゴシエーションを行う\r
-SOCKET acceptS(SOCKET s, struct sockaddr *addr, int *addrlen)\r
+SOCKET FTPS_accept(SOCKET s, struct sockaddr *addr, int *addrlen)\r
 {\r
        SOCKET r;\r
        BOOL bAborted;\r
@@ -589,7 +591,7 @@ SOCKET acceptS(SOCKET s, struct sockaddr *addr, int *addrlen)
 \r
 // connect相当の関数\r
 // ただし初めからSSLのネゴシエーションを行う\r
-int connectS(SOCKET s, const struct sockaddr *name, int namelen)\r
+int FTPS_connect(SOCKET s, const struct sockaddr *name, int namelen)\r
 {\r
        int r;\r
        BOOL bAborted;\r
@@ -601,14 +603,14 @@ int connectS(SOCKET s, const struct sockaddr *name, int namelen)
 }\r
 \r
 // closesocket相当の関数\r
-int closesocketS(SOCKET s)\r
+int FTPS_closesocket(SOCKET s)\r
 {\r
        DetachSSL(s);\r
        return closesocket(s);\r
 }\r
 \r
 // send相当の関数\r
-int sendS(SOCKET s, const char * buf, int len, int flags)\r
+int FTPS_send(SOCKET s, const char * buf, int len, int flags)\r
 {\r
        SSL** ppSSL;\r
        if(!g_bOpenSSLLoaded)\r
@@ -622,7 +624,7 @@ int sendS(SOCKET s, const char * buf, int len, int flags)
 }\r
 \r
 // recv相当の関数\r
-int recvS(SOCKET s, char * buf, int len, int flags)\r
+int FTPS_recv(SOCKET s, char * buf, int len, int flags)\r
 {\r
        SSL** ppSSL;\r
        if(!g_bOpenSSLLoaded)\r
@@ -989,3 +991,340 @@ HANDLE WSAAsyncGetHostByNameIPv6M(HWND hWnd, u_int wMsg, const char * name, char
        return r;\r
 }\r
 \r
+// SFTP対応\r
+\r
+typedef void* (__cdecl* _SFTP_Create)();\r
+typedef void (__cdecl* _SFTP_Destroy)(void*);\r
+typedef BOOL (__cdecl* _SFTP_IsExited)(void*);\r
+typedef BOOL (__cdecl* _SFTP_SetTimeoutCallback)(void*, void*);\r
+typedef size_t (__cdecl* _SFTP_PeekStdOut)(void*, void*, size_t);\r
+typedef size_t (__cdecl* _SFTP_ReadStdOut)(void*, void*, size_t);\r
+typedef size_t (__cdecl* _SFTP_WriteStdIn)(void*, const void*, size_t);\r
+typedef size_t (__cdecl* _SFTP_PeekDataOut)(void*, void*, size_t);\r
+typedef size_t (__cdecl* _SFTP_ReadDataOut)(void*, void*, size_t);\r
+typedef size_t (__cdecl* _SFTP_WriteDataIn)(void*, const void*, size_t);\r
+typedef BOOL (__cdecl* _SFTP_SetFilePosition)(void*, LONGLONG);\r
+\r
+_SFTP_Create p_SFTP_Create;\r
+_SFTP_Destroy p_SFTP_Destroy;\r
+_SFTP_IsExited p_SFTP_IsExited;\r
+_SFTP_SetTimeoutCallback p_SFTP_SetTimeoutCallback;\r
+_SFTP_PeekStdOut p_SFTP_PeekStdOut;\r
+_SFTP_ReadStdOut p_SFTP_ReadStdOut;\r
+_SFTP_WriteStdIn p_SFTP_WriteStdIn;\r
+_SFTP_PeekDataOut p_SFTP_PeekDataOut;\r
+_SFTP_ReadDataOut p_SFTP_ReadDataOut;\r
+_SFTP_WriteDataIn p_SFTP_WriteDataIn;\r
+_SFTP_SetFilePosition p_SFTP_SetFilePosition;\r
+\r
+typedef struct\r
+{\r
+       SOCKET Control;\r
+       SOCKET Data;\r
+       void* Handle;\r
+       char Host[1024];\r
+       int Port;\r
+       char User[1024];\r
+       char Password[1024];\r
+} SFTPDATA;\r
+\r
+#define MAX_SFTP_SOCKET 16\r
+\r
+BOOL g_bPuTTYLoaded;\r
+HMODULE g_hPuTTY;\r
+CRITICAL_SECTION g_PuTTYLock;\r
+SFTPDATA g_SFTPData[MAX_SFTP_SOCKET];\r
+\r
+// PuTTYを初期化\r
+BOOL LoadPuTTY()\r
+{\r
+       int i;\r
+       if(g_bPuTTYLoaded)\r
+               return FALSE;\r
+#ifdef ENABLE_PROCESS_PROTECTION\r
+       // ビルドしたputty.dllに合わせてSHA1ハッシュ値を変更すること\r
+       RegisterTrustedModuleSHA1Hash("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");\r
+#endif\r
+//     g_hPuTTY = LoadLibrary("putty.dll");\r
+       g_hPuTTY = LoadLibrary("C:\\SourceForge\\ffftp\\putty\\Debug\\PuTTY.dll");\r
+       if(!g_hPuTTY\r
+               || !(p_SFTP_Create = (_SFTP_Create)GetProcAddress(g_hPuTTY, "SFTP_Create"))\r
+               || !(p_SFTP_Destroy = (_SFTP_Destroy)GetProcAddress(g_hPuTTY, "SFTP_Destroy"))\r
+               || !(p_SFTP_IsExited = (_SFTP_IsExited)GetProcAddress(g_hPuTTY, "SFTP_IsExited"))\r
+               || !(p_SFTP_SetTimeoutCallback = (_SFTP_SetTimeoutCallback)GetProcAddress(g_hPuTTY, "SFTP_SetTimeoutCallback"))\r
+               || !(p_SFTP_PeekStdOut = (_SFTP_PeekStdOut)GetProcAddress(g_hPuTTY, "SFTP_PeekStdOut"))\r
+               || !(p_SFTP_ReadStdOut = (_SFTP_ReadStdOut)GetProcAddress(g_hPuTTY, "SFTP_ReadStdOut"))\r
+               || !(p_SFTP_WriteStdIn = (_SFTP_WriteStdIn)GetProcAddress(g_hPuTTY, "SFTP_WriteStdIn"))\r
+               || !(p_SFTP_PeekDataOut = (_SFTP_PeekDataOut)GetProcAddress(g_hPuTTY, "SFTP_PeekDataOut"))\r
+               || !(p_SFTP_ReadDataOut = (_SFTP_ReadDataOut)GetProcAddress(g_hPuTTY, "SFTP_ReadDataOut"))\r
+               || !(p_SFTP_WriteDataIn = (_SFTP_WriteDataIn)GetProcAddress(g_hPuTTY, "SFTP_WriteDataIn"))\r
+               || !(p_SFTP_SetFilePosition = (_SFTP_SetFilePosition)GetProcAddress(g_hPuTTY, "SFTP_SetFilePosition")))\r
+       {\r
+               if(g_hPuTTY)\r
+                       FreeLibrary(g_hPuTTY);\r
+               g_hPuTTY = NULL;\r
+               return FALSE;\r
+       }\r
+       for(i = 0; i < MAX_SFTP_SOCKET; i++)\r
+       {\r
+               g_SFTPData[i].Control = INVALID_SOCKET;\r
+               g_SFTPData[i].Data = INVALID_SOCKET;\r
+       }\r
+       InitializeCriticalSection(&g_PuTTYLock);\r
+       g_bPuTTYLoaded = TRUE;\r
+       return TRUE;\r
+}\r
+\r
+// PuTTYを解放\r
+void FreePuTTY()\r
+{\r
+       int i;\r
+       if(!g_bPuTTYLoaded)\r
+               return;\r
+       EnterCriticalSection(&g_PuTTYLock);\r
+       for(i = 0; i < MAX_SFTP_SOCKET; i++)\r
+       {\r
+               if(g_SFTPData[i].Control != INVALID_SOCKET)\r
+               {\r
+                       closesocket(g_SFTPData[i].Control);\r
+                       g_SFTPData[i].Control = INVALID_SOCKET;\r
+                       p_SFTP_Destroy(g_SFTPData[i].Handle);\r
+               }\r
+               if(g_SFTPData[i].Data != INVALID_SOCKET)\r
+               {\r
+                       closesocket(g_SFTPData[i].Data);\r
+                       g_SFTPData[i].Data = INVALID_SOCKET;\r
+               }\r
+       }\r
+       FreeLibrary(g_hPuTTY);\r
+       g_hPuTTY = NULL;\r
+       LeaveCriticalSection(&g_PuTTYLock);\r
+       DeleteCriticalSection(&g_PuTTYLock);\r
+       g_bPuTTYLoaded = FALSE;\r
+}\r
+\r
+// PuTTYが使用可能かどうか確認\r
+BOOL IsPuTTYLoaded()\r
+{\r
+       return g_bPuTTYLoaded;\r
+}\r
+\r
+SFTPDATA* GetUnusedSFTPData()\r
+{\r
+       int i;\r
+       for(i = 0; i < MAX_SFTP_SOCKET; i++)\r
+       {\r
+               if(g_SFTPData[i].Control == INVALID_SOCKET)\r
+               {\r
+                       memset(&g_SFTPData[i], 0, sizeof(SFTPDATA));\r
+                       return &g_SFTPData[i];\r
+               }\r
+       }\r
+       return NULL;\r
+}\r
+\r
+SFTPDATA* FindSFTPDataFromSocket(SOCKET s)\r
+{\r
+       int i;\r
+       for(i = 0; i < MAX_SFTP_SOCKET; i++)\r
+       {\r
+               if(g_SFTPData[i].Control == s || g_SFTPData[i].Data == s)\r
+                       return &g_SFTPData[i];\r
+       }\r
+       return NULL;\r
+}\r
+\r
+// SFTPとしてマークされているか確認\r
+// マークされていればTRUEを返す\r
+BOOL IsSFTPAttached(SOCKET s)\r
+{\r
+       SFTPDATA* pSFTPData;\r
+       if(!g_bPuTTYLoaded)\r
+               return FALSE;\r
+       EnterCriticalSection(&g_PuTTYLock);\r
+       pSFTPData = FindSFTPDataFromSocket(s);\r
+       LeaveCriticalSection(&g_PuTTYLock);\r
+       if(!pSFTPData)\r
+               return FALSE;\r
+       return TRUE;\r
+}\r
+\r
+// コントロール用の仮想的なソケットを取得\r
+// 識別子としてダミーのソケットを返す\r
+SOCKET SFTP_socket(int af, int type, int protocol)\r
+{\r
+       SOCKET r;\r
+       SFTPDATA* pSFTPData;\r
+       if(!g_bPuTTYLoaded)\r
+               return INVALID_SOCKET;\r
+       r = INVALID_SOCKET;\r
+       EnterCriticalSection(&g_PuTTYLock);\r
+       if(pSFTPData = GetUnusedSFTPData())\r
+       {\r
+               r = socket(af, type, protocol);\r
+               pSFTPData->Control = r;\r
+               pSFTPData->Data = INVALID_SOCKET;\r
+               pSFTPData->Handle = p_SFTP_Create();\r
+       }\r
+       LeaveCriticalSection(&g_PuTTYLock);\r
+       return r;\r
+}\r
+\r
+int SFTP_bind(SOCKET s, const struct sockaddr *addr, int namelen)\r
+{\r
+       return SOCKET_ERROR;\r
+}\r
+\r
+int SFTP_listen(SOCKET s, int backlog)\r
+{\r
+       return SOCKET_ERROR;\r
+}\r
+\r
+// accept相当の関数\r
+SOCKET SFTP_accept(SOCKET s, struct sockaddr *addr, int *addrlen)\r
+{\r
+       return INVALID_SOCKET;\r
+}\r
+\r
+// connect相当の関数\r
+int SFTP_connect(SOCKET s, const struct sockaddr *name, int namelen)\r
+{\r
+       SFTPDATA* pSFTPData;\r
+       if(!g_bPuTTYLoaded)\r
+               return SOCKET_ERROR;\r
+       EnterCriticalSection(&g_PuTTYLock);\r
+       pSFTPData = FindSFTPDataFromSocket(s);\r
+       LeaveCriticalSection(&g_PuTTYLock);\r
+       if(!pSFTPData)\r
+               return SOCKET_ERROR;\r
+       if(namelen == sizeof(struct sockaddr_in))\r
+       {\r
+       }\r
+       else if(namelen == sizeof(struct sockaddr_in6))\r
+       {\r
+       }\r
+       else\r
+               return SOCKET_ERROR;\r
+       return 0;\r
+}\r
+\r
+// closesocket相当の関数\r
+int SFTP_closesocket(SOCKET s)\r
+{\r
+       SFTPDATA* pSFTPData;\r
+       if(!g_bPuTTYLoaded)\r
+               return SOCKET_ERROR;\r
+       EnterCriticalSection(&g_PuTTYLock);\r
+       if(pSFTPData = FindSFTPDataFromSocket(s))\r
+       {\r
+               if(pSFTPData->Control == s)\r
+               {\r
+                       pSFTPData->Control = INVALID_SOCKET;\r
+                       p_SFTP_Destroy(pSFTPData->Handle);\r
+               }\r
+               if(pSFTPData->Data == s)\r
+                       pSFTPData->Data = INVALID_SOCKET;\r
+       }\r
+       LeaveCriticalSection(&g_PuTTYLock);\r
+       return closesocket(s);\r
+}\r
+\r
+// send相当の関数\r
+int SFTP_send(SOCKET s, const char * buf, int len, int flags)\r
+{\r
+       int r;\r
+       SFTPDATA* pSFTPData;\r
+       if(!g_bPuTTYLoaded)\r
+               return SOCKET_ERROR;\r
+       EnterCriticalSection(&g_PuTTYLock);\r
+       pSFTPData = FindSFTPDataFromSocket(s);\r
+       LeaveCriticalSection(&g_PuTTYLock);\r
+       if(!pSFTPData)\r
+               return SOCKET_ERROR;\r
+       if(p_SFTP_IsExited(pSFTPData->Handle))\r
+               return SOCKET_ERROR;\r
+       r = SOCKET_ERROR;\r
+       if(pSFTPData->Control == s)\r
+               r = (int)p_SFTP_WriteStdIn(pSFTPData->Handle, buf, len);\r
+       else if(pSFTPData->Data == s)\r
+               r = (int)p_SFTP_WriteDataIn(pSFTPData->Handle, buf, len);\r
+       return r;\r
+}\r
+\r
+// recv相当の関数\r
+int SFTP_recv(SOCKET s, char * buf, int len, int flags)\r
+{\r
+       int r;\r
+       SFTPDATA* pSFTPData;\r
+       if(!g_bPuTTYLoaded)\r
+               return SOCKET_ERROR;\r
+       EnterCriticalSection(&g_PuTTYLock);\r
+       pSFTPData = FindSFTPDataFromSocket(s);\r
+       LeaveCriticalSection(&g_PuTTYLock);\r
+       if(!pSFTPData)\r
+               return SOCKET_ERROR;\r
+       if(p_SFTP_IsExited(pSFTPData->Handle))\r
+               return SOCKET_ERROR;\r
+       r = SOCKET_ERROR;\r
+       if(pSFTPData->Control == s)\r
+       {\r
+               if(flags & MSG_PEEK)\r
+                       r = (int)p_SFTP_PeekStdOut(pSFTPData->Handle, buf, len);\r
+               else\r
+                       r = (int)p_SFTP_ReadStdOut(pSFTPData->Handle, buf, len);\r
+       }\r
+       else if(pSFTPData->Data == s)\r
+       {\r
+               if(flags & MSG_PEEK)\r
+                       r = (int)p_SFTP_PeekDataOut(pSFTPData->Handle, buf, len);\r
+               else\r
+                       r = (int)p_SFTP_ReadDataOut(pSFTPData->Handle, buf, len);\r
+       }\r
+       return r;\r
+}\r
+\r
+BOOL SFTP_SetTimeoutCallback(SOCKET s, void* pCallback)\r
+{\r
+       SFTPDATA* pSFTPData;\r
+       if(!g_bPuTTYLoaded)\r
+               return FALSE;\r
+       EnterCriticalSection(&g_PuTTYLock);\r
+       pSFTPData = FindSFTPDataFromSocket(s);\r
+       LeaveCriticalSection(&g_PuTTYLock);\r
+       if(!pSFTPData)\r
+               return FALSE;\r
+       return p_SFTP_SetTimeoutCallback(pSFTPData->Handle, pCallback);\r
+}\r
+\r
+// データ用の仮想的なソケットを取得\r
+// 識別子としてダミーのソケットを返す\r
+SOCKET SFTP_GetDataHandle(SOCKET s, int af, int type, int protocol)\r
+{\r
+       SOCKET r;\r
+       SFTPDATA* pSFTPData;\r
+       if(!g_bPuTTYLoaded)\r
+               return INVALID_SOCKET;\r
+       r = INVALID_SOCKET;\r
+       EnterCriticalSection(&g_PuTTYLock);\r
+       if(pSFTPData = FindSFTPDataFromSocket(s))\r
+       {\r
+               r = socket(af, type, protocol);\r
+               pSFTPData->Data = r;\r
+       }\r
+       LeaveCriticalSection(&g_PuTTYLock);\r
+       return r;\r
+}\r
+\r
+BOOL SFTP_SetFilePosition(SOCKET s, LONGLONG Position)\r
+{\r
+       SFTPDATA* pSFTPData;\r
+       if(!g_bPuTTYLoaded)\r
+               return FALSE;\r
+       EnterCriticalSection(&g_PuTTYLock);\r
+       pSFTPData = FindSFTPDataFromSocket(s);\r
+       LeaveCriticalSection(&g_PuTTYLock);\r
+       if(!pSFTPData)\r
+               return FALSE;\r
+       return p_SFTP_SetFilePosition(pSFTPData->Handle, Position);\r
+}\r
+\r
index ffbef2c..98b0fbb 100644 (file)
@@ -23,14 +23,14 @@ BOOL IsHostNameMatched(LPCSTR HostName, LPCSTR CommonName);
 BOOL AttachSSL(SOCKET s, SOCKET parent, BOOL* pbAborted);\r
 BOOL DetachSSL(SOCKET s);\r
 BOOL IsSSLAttached(SOCKET s);\r
-SOCKET socketS(int af, int type, int protocol);\r
-int bindS(SOCKET s, const struct sockaddr *addr, int namelen);\r
-int listenS(SOCKET s, int backlog);\r
-SOCKET acceptS(SOCKET s, struct sockaddr *addr, int *addrlen);\r
-int connectS(SOCKET s, const struct sockaddr *name, int namelen);\r
-int closesocketS(SOCKET s);\r
-int sendS(SOCKET s, const char * buf, int len, int flags);\r
-int recvS(SOCKET s, char * buf, int len, int flags);\r
+SOCKET FTPS_socket(int af, int type, int protocol);\r
+int FTPS_bind(SOCKET s, const struct sockaddr *addr, int namelen);\r
+int FTPS_listen(SOCKET s, int backlog);\r
+SOCKET FTPS_accept(SOCKET s, struct sockaddr *addr, int *addrlen);\r
+int FTPS_connect(SOCKET s, const struct sockaddr *name, int namelen);\r
+int FTPS_closesocket(SOCKET s);\r
+int FTPS_send(SOCKET s, const char * buf, int len, int flags);\r
+int FTPS_recv(SOCKET s, char * buf, int len, int flags);\r
 \r
 HANDLE WSAAsyncGetHostByNameIPv6(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen, short Family);\r
 int WSACancelAsyncRequestIPv6(HANDLE hAsyncTaskHandle);\r
@@ -40,5 +40,21 @@ struct in6_addr inet6_addr(const char* cp);
 HANDLE WSAAsyncGetHostByNameM(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen);\r
 HANDLE WSAAsyncGetHostByNameIPv6M(HWND hWnd, u_int wMsg, const char * name, char * buf, int buflen, short Family);\r
 \r
+BOOL LoadPuTTY();\r
+void FreePuTTY();\r
+BOOL IsPuTTYLoaded();\r
+BOOL IsSFTPAttached(SOCKET s);\r
+SOCKET SFTP_socket(int af, int type, int protocol);\r
+int SFTP_bind(SOCKET s, const struct sockaddr *addr, int namelen);\r
+int SFTP_listen(SOCKET s, int backlog);\r
+SOCKET SFTP_accept(SOCKET s, struct sockaddr *addr, int *addrlen);\r
+int SFTP_connect(SOCKET s, const struct sockaddr *name, int namelen);\r
+int SFTP_closesocket(SOCKET s);\r
+int SFTP_send(SOCKET s, const char * buf, int len, int flags);\r
+int SFTP_recv(SOCKET s, char * buf, int len, int flags);\r
+BOOL SFTP_SetTimeoutCallback(SOCKET s, void* pCallback);\r
+SOCKET SFTP_GetDataHandle(SOCKET s, int af, int type, int protocol);\r
+BOOL SFTP_SetFilePosition(SOCKET s, LONGLONG Position);\r
+\r
 #endif\r
 \r