OSDN Git Service

Enlarge buffers for replies on transferring files.
[ffftp/ffftp.git] / putty / iowrapper.c
1 // iowrapper.c\r
2 // Copyright (C) 2011 Suguru Kawamoto\r
3 // 標準入出力APIラッパー\r
4 \r
5 #define UNICODE\r
6 #define _UNICODE\r
7 \r
8 #include <stdio.h>\r
9 #include <windows.h>\r
10 \r
11 #define DO_NOT_REPLACE\r
12 #include "iowrapper.h"\r
13 #include "psftp.h"\r
14 \r
15 #define MAX_SFTPSTATUS 16\r
16 \r
17 SFTPSTATUS g_SFTPData[MAX_SFTPSTATUS];\r
18 HANDLE g_hStdIn;\r
19 HANDLE g_hStdOut;\r
20 HANDLE g_hStdErr;\r
21 \r
22 BOOL __stdcall DefaultIOBufferCallback(BOOL* pbAborted)\r
23 {\r
24         Sleep(1);\r
25         return *pbAborted;\r
26 }\r
27 \r
28 DWORD WINAPI SFTP_ThreadProc(LPVOID lpParameter)\r
29 {\r
30         char* p[1] = {"PSFTP"};\r
31         SFTPSTATUS* pSFTP;\r
32         psftp_main(1, p);\r
33         if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
34                 pSFTP->bExit = TRUE;\r
35         return 0;\r
36 }\r
37 \r
38 SFTPSTATUS* FindSFTPStatus(DWORD ThreadId)\r
39 {\r
40         int i;\r
41         for(i = 0; i < MAX_SFTPSTATUS; i++)\r
42         {\r
43                 if(g_SFTPData[i].ThreadId == ThreadId)\r
44                         return &g_SFTPData[i];\r
45         }\r
46         return NULL;\r
47 }\r
48 \r
49 CRITICAL_SECTION g_DummyLock;\r
50 \r
51 BOOL SFTP_InitializeIOBuffer(SFTPIOBUFFER* pIO, size_t Length)\r
52 {\r
53         memset(pIO, 0, sizeof(SFTPIOBUFFER));\r
54 //      InitializeCriticalSection(&pIO->Lock);\r
55         if(memcmp(&pIO->Lock, &g_DummyLock, sizeof(CRITICAL_SECTION)) == 0)\r
56         {\r
57                 InitializeCriticalSection(&pIO->Lock);\r
58                 EnterCriticalSection(&pIO->Lock);\r
59         }\r
60         if(!(pIO->pBuffer = (BYTE*)malloc(Length + 1)))\r
61                 return FALSE;\r
62         memset(pIO->pBuffer + Length, 0, 1);\r
63         pIO->Length = Length;\r
64         pIO->Written = 0;\r
65         pIO->Read = 0;\r
66         pIO->bAborted = FALSE;\r
67         pIO->pCallback = DefaultIOBufferCallback;\r
68         LeaveCriticalSection(&pIO->Lock);\r
69         return TRUE;\r
70 }\r
71 \r
72 void SFTP_UninitializeIOBuffer(SFTPIOBUFFER* pIO)\r
73 {\r
74 //      DeleteCriticalSection(&pIO->Lock);\r
75         EnterCriticalSection(&pIO->Lock);\r
76         free(pIO->pBuffer);\r
77 //      memset(pIO, 0, sizeof(SFTPIOBUFFER));\r
78 }\r
79 \r
80 void SFTP_AbortIOBuffer(SFTPIOBUFFER* pIO, BOOL bAborted)\r
81 {\r
82         EnterCriticalSection(&pIO->Lock);\r
83         pIO->bAborted = bAborted;\r
84         LeaveCriticalSection(&pIO->Lock);\r
85 }\r
86 \r
87 size_t SFTP_PeekIOBuffer(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size)\r
88 {\r
89         size_t Copied;\r
90         size_t Pos;\r
91         size_t Count;\r
92         size_t Read;\r
93         Copied = 0;\r
94         EnterCriticalSection(&pIO->Lock);\r
95         if(pBuffer)\r
96         {\r
97                 Read = pIO->Read;\r
98                 while(!pIO->bAborted && pIO->Written - Read > 0 && Copied < Size)\r
99                 {\r
100                         Pos = Read % pIO->Length;\r
101                         Count = min(Size - Copied, min(pIO->Written - Read, pIO->Length - Pos));\r
102                         memcpy((BYTE*)pBuffer + Copied, pIO->pBuffer + Pos, Count);\r
103                         Read += Count;\r
104                         Copied += Count;\r
105                 }\r
106         }\r
107         else\r
108                 Copied = pIO->Written - pIO->Read;\r
109         LeaveCriticalSection(&pIO->Lock);\r
110         return Copied;\r
111 }\r
112 \r
113 size_t SFTP_ReadIOBuffer(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size)\r
114 {\r
115         size_t Copied;\r
116         size_t Pos;\r
117         size_t Count;\r
118         Copied = 0;\r
119         EnterCriticalSection(&pIO->Lock);\r
120         while(!pIO->bAborted && pIO->Written - pIO->Read > 0 && Copied < Size)\r
121         {\r
122                 Pos = pIO->Read % pIO->Length;\r
123                 Count = min(Size - Copied, min(pIO->Written - pIO->Read, pIO->Length - Pos));\r
124                 memcpy((BYTE*)pBuffer + Copied, pIO->pBuffer + Pos, Count);\r
125                 pIO->Read += Count;\r
126                 Copied += Count;\r
127         }\r
128         LeaveCriticalSection(&pIO->Lock);\r
129         return Copied;\r
130 }\r
131 \r
132 size_t SFTP_WriteIOBuffer(SFTPIOBUFFER* pIO, const void* pBuffer, size_t Size)\r
133 {\r
134         size_t Copied;\r
135         size_t Pos;\r
136         size_t Count;\r
137         Copied = 0;\r
138         EnterCriticalSection(&pIO->Lock);\r
139         while(!pIO->bAborted && Copied < Size)\r
140         {\r
141                 if(pIO->Written - pIO->Read < pIO->Length)\r
142                 {\r
143                         Pos = pIO->Written % pIO->Length;\r
144                         Count = min(Size - Copied, min(pIO->Length + pIO->Read - pIO->Written, pIO->Length - Pos));\r
145                         memcpy(pIO->pBuffer + Pos, (BYTE*)pBuffer + Copied, Count);\r
146                         pIO->Written += Count;\r
147                         Copied += Count;\r
148                 }\r
149                 else\r
150                 {\r
151                         LeaveCriticalSection(&pIO->Lock);\r
152                         if(pIO->pCallback(&pIO->bAborted))\r
153                                 Size = 0;\r
154                         EnterCriticalSection(&pIO->Lock);\r
155                 }\r
156         }\r
157         LeaveCriticalSection(&pIO->Lock);\r
158         return Copied;\r
159 }\r
160 \r
161 size_t SFTP_ReadIOBufferLine(SFTPIOBUFFER* pIO, void* pBuffer, size_t Size)\r
162 {\r
163         size_t Copied;\r
164         size_t Pos;\r
165         size_t Count;\r
166         char* p;\r
167         Copied = 0;\r
168         EnterCriticalSection(&pIO->Lock);\r
169         while(!pIO->bAborted && Copied < Size)\r
170         {\r
171                 if(pIO->Written - pIO->Read > 0)\r
172                 {\r
173                         Pos = pIO->Read % pIO->Length;\r
174                         Count = min(Size - Copied, min(pIO->Written - pIO->Read, pIO->Length - Pos));\r
175                         if(p = strchr((char*)(pIO->pBuffer + Pos), '\n'))\r
176                         {\r
177                                 p++;\r
178                                 Count = min(Count, (size_t)p - (size_t)(pIO->pBuffer + Pos));\r
179                                 Size = 0;\r
180                         }\r
181                         memcpy((BYTE*)pBuffer + Copied, pIO->pBuffer + Pos, Count);\r
182                         pIO->Read += Count;\r
183                         Copied += Count;\r
184                 }\r
185                 else\r
186                 {\r
187                         LeaveCriticalSection(&pIO->Lock);\r
188                         if(pIO->pCallback(&pIO->bAborted))\r
189                                 Size = 0;\r
190                         EnterCriticalSection(&pIO->Lock);\r
191                 }\r
192         }\r
193         LeaveCriticalSection(&pIO->Lock);\r
194         return Copied;\r
195 }\r
196 \r
197 size_t SFTP_PeekThreadIO(void* pBuffer, size_t Size)\r
198 {\r
199         SFTPSTATUS* pSFTP;\r
200         if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
201                 return SFTP_PeekIOBuffer(&pSFTP->InBuffer, pBuffer, Size);\r
202         return 0;\r
203 }\r
204 \r
205 size_t SFTP_ReadThreadIO(void* pBuffer, size_t Size)\r
206 {\r
207         SFTPSTATUS* pSFTP;\r
208         if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
209                 return SFTP_ReadIOBuffer(&pSFTP->InBuffer, pBuffer, Size);\r
210         return 0;\r
211 }\r
212 \r
213 size_t SFTP_WriteThreadIO(const void* pBuffer, size_t Size)\r
214 {\r
215         SFTPSTATUS* pSFTP;\r
216         if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
217                 return SFTP_WriteIOBuffer(&pSFTP->OutBuffer, pBuffer, Size);\r
218         return 0;\r
219 }\r
220 \r
221 size_t SFTP_ReadThreadIOLine(void* pBuffer, size_t Size)\r
222 {\r
223         SFTPSTATUS* pSFTP;\r
224         if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
225                 return SFTP_ReadIOBufferLine(&pSFTP->InBuffer, pBuffer, Size);\r
226         return 0;\r
227 }\r
228 \r
229 size_t SFTP_PeekThreadDataIO(void* pBuffer, size_t Size)\r
230 {\r
231         SFTPSTATUS* pSFTP;\r
232         if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
233                 return SFTP_PeekIOBuffer(&pSFTP->DataInBuffer, pBuffer, Size);\r
234         return 0;\r
235 }\r
236 \r
237 size_t SFTP_ReadThreadDataIO(void* pBuffer, size_t Size)\r
238 {\r
239         SFTPSTATUS* pSFTP;\r
240         if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
241                 return SFTP_ReadIOBuffer(&pSFTP->DataInBuffer, pBuffer, Size);\r
242         return 0;\r
243 }\r
244 \r
245 size_t SFTP_WriteThreadDataIO(const void* pBuffer, size_t Size)\r
246 {\r
247         SFTPSTATUS* pSFTP;\r
248         if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
249                 return SFTP_WriteIOBuffer(&pSFTP->DataOutBuffer, pBuffer, Size);\r
250         return 0;\r
251 }\r
252 \r
253 BOOL SFTP_GetThreadFilePositon(DWORD* pLow, LONG* pHigh)\r
254 {\r
255         SFTPSTATUS* pSFTP;\r
256         if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
257         {\r
258                 *pLow = pSFTP->FilePosition.LowPart;\r
259                 *pHigh = pSFTP->FilePosition.HighPart;\r
260                 return TRUE;\r
261         }\r
262         return FALSE;\r
263 }\r
264 \r
265 // 以下ラッパー\r
266 \r
267 HANDLE GetStdHandleX(DWORD nStdHandle)\r
268 {\r
269         HANDLE r = INVALID_HANDLE_VALUE;\r
270         if(!g_hStdIn)\r
271                 g_hStdIn = (HANDLE)1;\r
272         if(!g_hStdOut)\r
273                 g_hStdOut = (HANDLE)2;\r
274         if(!g_hStdErr)\r
275                 g_hStdErr = (HANDLE)3;\r
276         if(nStdHandle == STD_INPUT_HANDLE)\r
277                 r = g_hStdIn;\r
278         if(nStdHandle == STD_OUTPUT_HANDLE)\r
279                 r = g_hStdOut;\r
280         if(nStdHandle == STD_ERROR_HANDLE)\r
281                 r = g_hStdErr;\r
282         return r;\r
283 }\r
284 \r
285 BOOL GetConsoleModeX(HANDLE hConsoleHandle, LPDWORD lpMode)\r
286 {\r
287         BOOL r = FALSE;\r
288         return r;\r
289 }\r
290 \r
291 BOOL SetConsoleModeX(HANDLE hConsoleHandle, DWORD dwMode)\r
292 {\r
293         BOOL r = FALSE;\r
294         return r;\r
295 }\r
296 \r
297 BOOL ReadFileX(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)\r
298 {\r
299         BOOL r = FALSE;\r
300         if(hFile == g_hStdIn)\r
301         {\r
302                 *lpNumberOfBytesRead = (DWORD)SFTP_ReadThreadIOLine(lpBuffer, nNumberOfBytesToRead);\r
303                 if(*lpNumberOfBytesRead > 0)\r
304                         r = TRUE;\r
305         }\r
306         else if(hFile == g_hStdOut)\r
307         {\r
308         }\r
309         else if(hFile == g_hStdErr)\r
310         {\r
311         }\r
312         return r;\r
313 }\r
314 \r
315 BOOL WriteFileX(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)\r
316 {\r
317         BOOL r = FALSE;\r
318         if(hFile == g_hStdIn)\r
319         {\r
320         }\r
321         else if(hFile == g_hStdOut)\r
322         {\r
323                 *lpNumberOfBytesWritten = (DWORD)SFTP_WriteThreadIO(lpBuffer, nNumberOfBytesToWrite);\r
324                 if(*lpNumberOfBytesWritten == nNumberOfBytesToWrite)\r
325                         r = TRUE;\r
326         }\r
327         else if(hFile == g_hStdErr)\r
328         {\r
329                 *lpNumberOfBytesWritten = (DWORD)SFTP_WriteThreadIO(lpBuffer, nNumberOfBytesToWrite);\r
330                 if(*lpNumberOfBytesWritten == nNumberOfBytesToWrite)\r
331                         r = TRUE;\r
332         }\r
333         return r;\r
334 }\r
335 \r
336 int printfX(const char * _Format, ...)\r
337 {\r
338         int r = 0;\r
339         va_list v;\r
340         char Temp[1024];\r
341         va_start(v, _Format);\r
342         vsprintf(Temp, _Format, v);\r
343         r = (int)SFTP_WriteThreadIO(Temp, strlen(Temp));\r
344         va_end(v);\r
345         return r;\r
346 }\r
347 \r
348 int putsX(const char * _Str)\r
349 {\r
350         int r = 0;\r
351         r = (int)SFTP_WriteThreadIO(_Str, strlen(_Str));\r
352         return r;\r
353 }\r
354 \r
355 int fprintfX(FILE * _File, const char * _Format, ...)\r
356 {\r
357         int r = 0;\r
358         va_list v;\r
359         char Temp[1024];\r
360         va_start(v, _Format);\r
361         if(_File == stdout)\r
362         {\r
363                 vsprintf(Temp, _Format, v);\r
364                 r = (int)SFTP_WriteThreadIO(Temp, strlen(Temp));\r
365         }\r
366         else if(_File == stderr)\r
367         {\r
368                 vsprintf(Temp, _Format, v);\r
369                 r = (int)SFTP_WriteThreadIO(Temp, strlen(Temp));\r
370         }\r
371         else\r
372                 r = vfprintf(_File, _Format, v);\r
373         va_end(v);\r
374         return r;\r
375 }\r
376 \r
377 char * fgetsX(char * _Buf, int _MaxCount, FILE * _File)\r
378 {\r
379         char * r = NULL;\r
380         if(_File == stdin)\r
381         {\r
382                 memset(_Buf, 0, _MaxCount);\r
383                 SFTP_ReadThreadIOLine(_Buf, _MaxCount - 1);\r
384                 r = _Buf;\r
385         }\r
386         else\r
387                 r = fgets(_Buf, _MaxCount, _File);\r
388         return r;\r
389 }\r
390 \r
391 int fputsX(const char * _Str, FILE * _File)\r
392 {\r
393         int r = 0;\r
394         if(_File == stdout)\r
395         {\r
396                 r = (int)SFTP_WriteThreadIO(_Str, strlen(_Str));\r
397         }\r
398         else if(_File == stderr)\r
399         {\r
400                 r = (int)SFTP_WriteThreadIO(_Str, strlen(_Str));\r
401         }\r
402         else\r
403                 r = fputs(_Str, _File);\r
404         return r;\r
405 }\r
406 \r
407 int fflushX(FILE * _File)\r
408 {\r
409         int r = 0;\r
410         if(_File == stdout)\r
411         {\r
412         }\r
413         else if(_File == stderr)\r
414         {\r
415         }\r
416         else\r
417                 r = fflush(_File);\r
418         return r;\r
419 }\r
420 \r
421 void exitX(int _Code)\r
422 {\r
423         SFTPSTATUS* pSFTP;\r
424         if(pSFTP = FindSFTPStatus(GetCurrentThreadId()))\r
425         {\r
426                 pSFTP->bExit = TRUE;\r
427                 SFTP_AbortIOBuffer(&pSFTP->InBuffer, TRUE);\r
428                 SFTP_AbortIOBuffer(&pSFTP->OutBuffer, TRUE);\r
429                 SFTP_AbortIOBuffer(&pSFTP->DataInBuffer, TRUE);\r
430                 SFTP_AbortIOBuffer(&pSFTP->DataOutBuffer, TRUE);\r
431         }\r
432         TerminateThread(GetCurrentThread(), (DWORD)_Code);\r
433 }\r
434 \r