Guest User

Untitled

a guest
Apr 21st, 2018
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 29.21 KB | None | 0 0
  1. #include "stdafx.h"
  2.  
  3.  
  4. TOR_THREADS_METHOD *TORModFtp()
  5. {
  6.     static TOR_THREADS_METHOD method = {
  7.         "TORModFtp",
  8.         (TOR_THREADS_INIT_PROC*) TORModFtpInit,
  9.         (TOR_THREADS_DESTROY_PROC*) TORModFtpDestroy,
  10.         (TOR_THREADS_ADD_PROC*) TORModFtpAdd,
  11.         (TOR_THREADS_REMOVE_PROC*) TORModFtpRemove,
  12.         (TOR_THREADS_MAIN_PROC*) TORModFtpMain
  13.     };
  14.  
  15.     return &method;
  16. }
  17.  
  18. TOR_ERROR WINAPI TORModFtpInit(TOR_MOD_FTP **lpModule, TOR_CONF *lpConf)
  19. {
  20.     TOR_MOD_FTP     *lpRet = NULL;
  21.     TOR_CONF_SEC    *lpSec;
  22.     TOR_ERROR       rError;
  23.  
  24.  
  25.     __try {
  26.  
  27.         if ((rError = TOR_NEW(lpRet)) != ERROR_SUCCESS) {
  28.             return rError;
  29.         }
  30.  
  31.         if ((lpSec = TORConfGetSec(lpConf, "mod_ftp", NULL)) == NULL) {
  32.             return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, ERROR_INVALID_PARAMETER);
  33.         }
  34.  
  35.         lpRet->lpTrans          = NULL;
  36.         lpRet->dwCommandTimeout = atoi(TORConfGetVar(lpSec, "command_timeout", "300")) * 1000;
  37.         lpRet->dwAcceptTimeout  = atoi(TORConfGetVar(lpSec, "accept_timeout", "10")) * 1000;
  38.         lpRet->dwTransTimeout   = atoi(TORConfGetVar(lpSec, "trans_timeout", "300")) * 1000;
  39.  
  40.         if ((rError = TORTransInit(&lpRet->lpTrans, lpConf)) != ERROR_SUCCESS) {
  41.             return rError;
  42.         }
  43.  
  44.         TOR_RET_PTR(lpModule, lpRet);
  45.  
  46.     }
  47.  
  48.     __finally {
  49.  
  50.         TORModFtpDestroy(lpRet);
  51.  
  52.     }
  53.  
  54.     return ERROR_SUCCESS;
  55. }
  56.  
  57. void WINAPI TORModFtpDestroy(TOR_MOD_FTP *lpModule)
  58. {
  59.  
  60.     if (lpModule != NULL) {
  61.  
  62.         if (lpModule->lpTrans != NULL) {
  63.             TORTransDestroy(lpModule->lpTrans);
  64.         }
  65.  
  66.         TOR_FREE(lpModule);
  67.  
  68.     }
  69.  
  70.     return;
  71. }
  72.  
  73. TOR_ERROR WINAPI TORModFtpAdd(TOR_MOD_FTP *lpModule, TOR_MOD_FTP_INST **lpInst, TOR_THREADS_INST *lpThread, TOR_IO *lpIOSocket)
  74. {
  75.     TOR_MOD_FTP_INST    *lpRet = NULL;
  76.     TOR_ERROR           rError;
  77.  
  78.  
  79.     __try {
  80.  
  81.         if ((rError = TOR_NEW(lpRet)) != ERROR_SUCCESS) {
  82.  
  83.             TORIODestroy(lpIOSocket);
  84.  
  85.             return rError;
  86.         }
  87.  
  88.         lpRet->lpModule         = lpModule;
  89.         lpRet->lpThread         = lpThread;
  90.         lpRet->lpCtrlSck        = lpIOSocket;
  91.         lpRet->lpTransSck       = NULL;
  92.         lpRet->lpTransThread    = NULL;
  93.         lpRet->lpEvents         = NULL;
  94.         lpRet->lpFile           = NULL;
  95.         lpRet->lpFiles          = NULL;
  96.         lpRet->lpFSO            = NULL;
  97.         lpRet->szRenameFrom[0]  = '\0';
  98.         lpRet->qwRestOffset     = 0;
  99.         lpRet->bIsLoggedOn      = FALSE;
  100.         lpRet->szUser[0]        = '\0';
  101.  
  102.         if (TORIOGetType(lpRet->lpCtrlSck) != TOR_IO_TYPE_SOCKET) {
  103.             return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, ERROR_INVALID_PARAMETER);
  104.         }
  105.  
  106.         TORSocketSetAbortEvent(
  107.             TOR_IO_SOCKET(lpRet->lpCtrlSck),
  108.             TORThreadsGetAbortEvent(lpRet->lpThread)
  109.         );
  110.  
  111.         TORSocketSetTimeout(
  112.             TOR_IO_SOCKET(lpRet->lpCtrlSck),
  113.             TOR_SOCKET_TIMEOUT_RECV,
  114.             lpRet->lpModule->dwCommandTimeout
  115.         );
  116.  
  117.         rError = TORTransCreate(
  118.             &lpRet->lpTransSck,
  119.             lpRet->lpModule->lpTrans
  120.         );
  121.  
  122.         if (rError != ERROR_SUCCESS) {
  123.             return rError;
  124.         }
  125.  
  126.         TORPipeSetAbortEvent(
  127.             TOR_IO_PIPE(TORTransGetIO(lpRet->lpTransSck)),
  128.             TORThreadsGetAbortEvent(lpRet->lpThread)
  129.         );
  130.  
  131.         TORPipeSetTimeout(
  132.             TOR_IO_PIPE(TORTransGetIO(lpRet->lpTransSck)),
  133.             TOR_PIPE_TIMEOUT_CREATE,
  134.             lpRet->lpModule->dwAcceptTimeout
  135.         );
  136.  
  137.         TORPipeSetTimeout(
  138.             TOR_IO_PIPE(TORTransGetIO(lpRet->lpTransSck)),
  139.             TOR_PIPE_TIMEOUT_WRITE,
  140.             lpRet->lpModule->dwTransTimeout
  141.         );
  142.  
  143.         TORPipeSetTimeout(
  144.             TOR_IO_PIPE(TORTransGetIO(lpRet->lpTransSck)),
  145.             TOR_PIPE_TIMEOUT_READ,
  146.             lpRet->lpModule->dwTransTimeout
  147.         );
  148.  
  149.         if ((rError = TORThreadInit(&lpRet->lpTransThread)) != ERROR_SUCCESS) {
  150.             return rError;
  151.         }
  152.  
  153.         rError = TOREventsInit(
  154.             &lpRet->lpEvents,
  155.             lpRet->lpModule->dwCommandTimeout
  156.         );
  157.  
  158.         if (rError != ERROR_SUCCESS) {
  159.             return rError;
  160.         }
  161.  
  162.         rError = TOREventsAdd(
  163.             lpRet->lpEvents,
  164.             TOR_MOD_FTP_EVENT_ABORT,
  165.             TORThreadsGetAbortEvent(lpRet->lpThread)
  166.         );
  167.  
  168.         if (rError != ERROR_SUCCESS) {
  169.             return rError;
  170.         }
  171.  
  172.         rError = TOREventsAdd(
  173.             lpRet->lpEvents,
  174.             TOR_MOD_FTP_EVENT_CTRL_SCK,
  175.             TORIOGetEvent(lpRet->lpCtrlSck)
  176.         );
  177.  
  178.         if (rError != ERROR_SUCCESS) {
  179.             return rError;
  180.         }
  181.  
  182.         rError = TOREventsAdd(
  183.             lpRet->lpEvents,
  184.             TOR_MOD_FTP_EVENT_TRANS_DONE,
  185.             TORThreadGetFinishEvent(lpRet->lpTransThread)
  186.         );
  187.  
  188.         if (rError != ERROR_SUCCESS) {
  189.             return rError;
  190.         }
  191.  
  192.         rError = TORIOInit(
  193.             &lpRet->lpFile,
  194.             TORIOFile(),
  195.             NULL,
  196.             TOR_IO_OPT_DESTROY
  197.         );
  198.  
  199.         if (rError != ERROR_SUCCESS) {
  200.             return rError;
  201.         }
  202.  
  203.         if ((rError = TORFSOFilesInit(&lpRet->lpFiles)) != ERROR_SUCCESS) {
  204.             return rError;
  205.         }
  206.  
  207.         if ((rError = TORFSOInit(&lpRet->lpFSO)) != ERROR_SUCCESS) {
  208.             return rError;
  209.         }
  210.  
  211.         TOR_RET_PTR(lpInst, lpRet);
  212.  
  213.     }
  214.  
  215.     __finally {
  216.  
  217.         TORModFtpRemove(lpRet, rError);
  218.  
  219.     }
  220.  
  221.     return ERROR_SUCCESS;
  222. }
  223.  
  224. void WINAPI TORModFtpRemove(TOR_MOD_FTP_INST *lpInst, TOR_ERROR rError)
  225. {
  226.  
  227.     if (lpInst != NULL) {
  228.  
  229.         TORModFtpTransStop(lpInst);
  230.  
  231.         if (lpInst->lpCtrlSck != NULL) {
  232.             TORIODestroy(lpInst->lpCtrlSck);
  233.         }
  234.  
  235.         if (lpInst->lpTransSck != NULL) {
  236.             TORTransFree(lpInst->lpTransSck);
  237.         }
  238.  
  239.         if (lpInst->lpTransThread != NULL) {
  240.             TORThreadDestroy(lpInst->lpTransThread);
  241.         }
  242.  
  243.         if (lpInst->lpEvents != NULL) {
  244.             TOREventsDestroy(lpInst->lpEvents);
  245.         }
  246.  
  247.         if (lpInst->lpFile != NULL) {
  248.             TORIODestroy(lpInst->lpFile);
  249.         }
  250.  
  251.         if (lpInst->lpFiles != NULL) {
  252.             TORFSOFilesDestroy(lpInst->lpFiles);
  253.         }
  254.  
  255.         if (lpInst->lpFSO != NULL) {
  256.             TORFSODestroy(lpInst->lpFSO);
  257.         }
  258.  
  259.         TOR_FREE(lpInst);
  260.  
  261.     }
  262.  
  263.     return;
  264. }
  265.  
  266. TOR_ERROR WINAPI TORModFtpMain(TOR_MOD_FTP_INST *lpInst)
  267. {
  268.     char        *lpCmdLine;
  269.     char        szCmdLine[512];
  270.     TOR_ERROR   rError;
  271.     DWORD       dwLineLength;
  272.     DWORD       dwFactualLength;
  273.  
  274.  
  275.     if ((rError = TORSocketBeginRecv(TOR_IO_SOCKET(lpInst->lpCtrlSck))) != ERROR_SUCCESS) {
  276.         return rError;
  277.     }
  278.  
  279.     rError = TORModFtpSend(
  280.         lpInst,
  281.         "220 Welcome to TORRCServer FTP Service!"
  282.     );
  283.  
  284.     if (rError != ERROR_SUCCESS) {
  285.         return rError;
  286.     }
  287.  
  288.     do {
  289.  
  290.         if ((rError = TOREventsWait(lpInst->lpEvents, INFINITE)) != ERROR_SUCCESS) {
  291.  
  292.             switch (rError) {
  293.  
  294.                 case TOR_ERROR_OPERATION_TIMEOUT:
  295.                     TORModFtpSend(lpInst, "421 Connection timed out.");
  296.                 break;
  297.  
  298.                 default:
  299.                     TORModFtpSend(lpInst, "500 Internal server error.");
  300.                 break;
  301.  
  302.             }
  303.  
  304.             return rError;
  305.         }
  306.  
  307.         switch (TOREventsGetLastID(lpInst->lpEvents)) {
  308.  
  309.             case TOR_MOD_FTP_EVENT_ABORT:
  310.  
  311.                 TORModFtpSend(lpInst, "500 Server shutdown.");
  312.  
  313.                 return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, TOR_ERROR_OPERATION_ABORTED);
  314.  
  315.             break;
  316.  
  317.             case TOR_MOD_FTP_EVENT_CTRL_SCK:
  318.  
  319.                 rError = TORIOReadLine(
  320.                     lpInst->lpCtrlSck,
  321.                     szCmdLine,
  322.                     sizeof(szCmdLine),
  323.                     &dwLineLength,
  324.                     &dwFactualLength
  325.                 );
  326.  
  327.                 if (rError != ERROR_SUCCESS) {
  328.  
  329.                     switch (rError) {
  330.  
  331.                         case TOR_ERROR_OPERATION_ABORTED:
  332.                             TORModFtpSend(lpInst, "500 Server shutdown.");
  333.                         break;
  334.  
  335.                         case TOR_ERROR_OPERATION_TIMEOUT:
  336.                             TORModFtpSend(lpInst, "421 Connection timed out.");
  337.                         break;
  338.  
  339.                         default:
  340.  
  341.                             if (rError != TOR_ERROR_IO_END_OF_STREAM) {
  342.                                 TORModFtpSend(lpInst, "500 Internal server error.");
  343.                             }
  344.  
  345.                         break;
  346.  
  347.                     }
  348.  
  349.                     return rError;
  350.                 }
  351.  
  352.                 if (dwFactualLength > dwLineLength) {
  353.  
  354.                     TORModFtpSend(lpInst, "500 Command line too long.");
  355.  
  356.                 }
  357.                 else {
  358.  
  359.                     if (*(lpCmdLine = TORTrim(szCmdLine)) != '\0') {
  360.                         TORModFtpExecCmd(lpInst, lpCmdLine);
  361.                     }
  362.  
  363.                 }
  364.  
  365.             break;
  366.  
  367.             case TOR_MOD_FTP_EVENT_TRANS_DONE:
  368.  
  369.                 TORModFtpTransStop(lpInst);
  370.  
  371.                 if (TORThreadGetResult(lpInst->lpTransThread) == ERROR_SUCCESS) {
  372.                     TORModFtpSend(lpInst, "226 Transfer OK");
  373.                 }
  374.                 else {
  375.                     TORModFtpSend(lpInst, "426 Connection closed; transfer aborted.");
  376.                 }
  377.  
  378.             break;
  379.  
  380.         }
  381.  
  382.     } while (1);
  383.  
  384.     return ERROR_SUCCESS;
  385. }
  386.  
  387. TOR_TRANS *TORModFtpGetTrans(TOR_MOD_FTP *lpModule)
  388. {
  389.     return lpModule->lpTrans;
  390. }
  391.  
  392. TOR_ERROR TORModFtpSendFmt(TOR_MOD_FTP_INST *lpInst, const char *lpFormat, ...)
  393. {
  394.     va_list     args;
  395.     TOR_ERROR   rError;
  396.  
  397.  
  398.     __try {
  399.  
  400.         TORIOSetOpts(lpInst->lpCtrlSck, TOR_IO_OPT_WRITE_BUFFER);
  401.  
  402.         va_start(args, lpFormat);
  403.  
  404.         rError = TORVIOFormatStr(
  405.             lpInst->lpCtrlSck,
  406.             lpFormat,
  407.             args
  408.         );
  409.  
  410.         va_end(args);
  411.  
  412.         if (rError != ERROR_SUCCESS) {
  413.             return rError;
  414.         }
  415.  
  416.         if ((rError = TORIOPuts(lpInst->lpCtrlSck, "\r\n")) != ERROR_SUCCESS) {
  417.             return rError;
  418.         }
  419.  
  420.         if ((rError = TORIOFlush(lpInst->lpCtrlSck)) != ERROR_SUCCESS) {
  421.             return rError;
  422.         }
  423.  
  424.     }
  425.  
  426.     __finally {
  427.  
  428.         TORIOClearOpts(lpInst->lpCtrlSck, TOR_IO_OPT_WRITE_BUFFER);
  429.  
  430.     }
  431.  
  432.     return ERROR_SUCCESS;
  433. }
  434.  
  435. TOR_ERROR TORModFtpSend(TOR_MOD_FTP_INST *lpInst, const char *lpResp)
  436. {
  437.     return TORModFtpSendFmt(lpInst, "%s", lpResp);
  438. }
  439.  
  440. TOR_ERROR TORModFtpExecCmd(TOR_MOD_FTP_INST *lpInst, char *lpCmdLine)
  441. {
  442.     TOR_MOD_FTP_CMD     *lpCmd;
  443.     char                *lpCmdArgs;
  444.     char                *lpCmdName;
  445.     const char          *lpErrStr;
  446.     char                szAbsolutePath[MAX_PATH];
  447.     ULARGE_INTEGER      ulFileSize;
  448.     TOR_ERROR           rError;
  449.     DWORD               i;
  450.     DWORD               dwAddr;
  451.     WORD                wPort;
  452.  
  453.  
  454.     static TOR_MOD_FTP_CMD cmds[] = {
  455.         {TOR_MOD_FTP_CMD_USER, "USER", TRUE, FALSE},
  456.         {TOR_MOD_FTP_CMD_PASS, "PASS", FALSE, FALSE},
  457.         {TOR_MOD_FTP_CMD_QUIT, "QUIT", FALSE, FALSE},
  458.         {TOR_MOD_FTP_CMD_CWD, "CWD", FALSE, TRUE},
  459.         {TOR_MOD_FTP_CMD_PWD, "PWD", FALSE, TRUE},
  460.         {TOR_MOD_FTP_CMD_PORT, "PORT", TRUE, TRUE},
  461.         {TOR_MOD_FTP_CMD_PASV, "PASV", FALSE, TRUE},
  462.         {TOR_MOD_FTP_CMD_TYPE, "TYPE", TRUE, TRUE},
  463.         {TOR_MOD_FTP_CMD_LIST, "LIST", FALSE, TRUE},
  464.         {TOR_MOD_FTP_CMD_REST, "REST", TRUE, TRUE},
  465.         {TOR_MOD_FTP_CMD_CDUP, "CDUP", FALSE, TRUE},
  466.         {TOR_MOD_FTP_CMD_RETR, "RETR", TRUE, TRUE},
  467.         {TOR_MOD_FTP_CMD_STOR, "STOR", TRUE, TRUE},
  468.         {TOR_MOD_FTP_CMD_SIZE, "SIZE", TRUE, TRUE},
  469.         {TOR_MOD_FTP_CMD_DELE, "DELE", TRUE, TRUE},
  470.         {TOR_MOD_FTP_CMD_RMD, "RMD", TRUE, TRUE},
  471.         {TOR_MOD_FTP_CMD_MKD, "MKD", TRUE, TRUE},
  472.         {TOR_MOD_FTP_CMD_RNFR, "RNFR", TRUE, TRUE},
  473.         {TOR_MOD_FTP_CMD_RNTO, "RNTO", TRUE, TRUE},
  474.         {TOR_MOD_FTP_CMD_ABOR, "ABOR", FALSE, TRUE},
  475.         {TOR_MOD_FTP_CMD_SYST, "SYST", FALSE, FALSE},
  476.         {TOR_MOD_FTP_CMD_NOOP, "NOOP", FALSE, TRUE},
  477.         {TOR_MOD_FTP_CMD_APPE, "APPE", TRUE, TRUE}
  478.     };
  479.  
  480.  
  481.     lpCmd       = NULL;
  482.     lpCmdArgs   = lpCmdLine;
  483.     lpCmdName   = TORToken(&lpCmdArgs);
  484.  
  485.     for (i = 0; i < sizeof(cmds) / sizeof(TOR_MOD_FTP_CMD); i++) {
  486.  
  487.         if (stricmp(cmds[i].szCmdName, lpCmdName) == 0) {
  488.             lpCmd = &cmds[i];
  489.         }
  490.  
  491.     }
  492.  
  493.     if (lpCmd == NULL) {
  494.  
  495.         TORModFtpSend(lpInst, "500 Syntax error, command unrecognized.");
  496.  
  497.         return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, ERROR_INVALID_PARAMETER);
  498.     }
  499.  
  500.     if (lpCmd->bRequireArgs && *lpCmdArgs == '\0') {
  501.  
  502.         TORModFtpSend(lpInst, "501 Syntax error.");
  503.  
  504.         return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, ERROR_INVALID_PARAMETER);
  505.     }
  506.  
  507.     if (lpCmd->bRequireLogon && !lpInst->bIsLoggedOn) {
  508.  
  509.         TORModFtpSend(lpInst, "530 Please log in with USER and PASS first.");
  510.  
  511.         return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, TOR_ERROR_CANNOT_IN_THIS_STATE);
  512.     }
  513.  
  514.     switch (lpCmd->dwCmdID) {
  515.  
  516.         case TOR_MOD_FTP_CMD_USER:
  517.  
  518.             lpInst->bIsLoggedOn = FALSE;
  519.  
  520.             TORCopyStr(
  521.                 lpInst->szUser,
  522.                 lpCmdArgs,
  523.                 sizeof(lpInst->szUser)
  524.             );
  525.  
  526.             TORModFtpSendFmt(lpInst, "331 Password required for %s", lpInst->szUser);
  527.  
  528.         break;
  529.  
  530.         case TOR_MOD_FTP_CMD_PASS:
  531.  
  532.             lpInst->bIsLoggedOn = TRUE;
  533.  
  534.             TORModFtpSend(lpInst, "230 Logged on");
  535.  
  536.         break;
  537.  
  538.         case TOR_MOD_FTP_CMD_QUIT:
  539.  
  540.             TORModFtpSend(lpInst, "221 Goodbye");
  541.             TORThreadsExit(lpInst->lpThread, ERROR_SUCCESS);
  542.  
  543.         break;
  544.  
  545.         case TOR_MOD_FTP_CMD_CWD:
  546.  
  547.             rError = TORFSOSetCurrentDir(
  548.                 lpInst->lpFSO,
  549.                 lpCmdArgs
  550.             );
  551.  
  552.             if (rError != ERROR_SUCCESS) {
  553.  
  554.                 switch (rError) {
  555.  
  556.                     case ERROR_INVALID_NAME:
  557.                         lpErrStr = "directory name is incorrect.";
  558.                     break;
  559.  
  560.                     case ERROR_FILE_NOT_FOUND:
  561.                     case ERROR_PATH_NOT_FOUND:
  562.                     case ERROR_DIRECTORY:
  563.                         lpErrStr = "directory not found.";
  564.                     break;
  565.  
  566.                     case ERROR_ACCESS_DENIED:
  567.                         lpErrStr = "access denied.";
  568.                     break;
  569.  
  570.                     default:
  571.                         lpErrStr = "internal server error.";
  572.                     break;
  573.  
  574.                 }
  575.  
  576.                 TORModFtpSendFmt(lpInst, "550 CWD failed, %s", lpErrStr);
  577.  
  578.                 return rError;
  579.             }
  580.  
  581.             TORModFtpSendFmt(
  582.                 lpInst,
  583.                 "250 CWD successful. \"%s\" is current directory.",
  584.                 TORFSOGetCurrentDir(lpInst->lpFSO)
  585.             );
  586.  
  587.         break;
  588.  
  589.         case TOR_MOD_FTP_CMD_PWD:
  590.  
  591.             TORModFtpSendFmt(
  592.                 lpInst,
  593.                 "257 \"%s\" is current directory.",
  594.                 TORFSOGetCurrentDir(lpInst->lpFSO)
  595.             );
  596.  
  597.         break;
  598.  
  599.         case TOR_MOD_FTP_CMD_PORT:
  600.  
  601.             TORModFtpSend(lpInst, "500 Active mode not supported.");
  602.  
  603.         break;
  604.  
  605.         case TOR_MOD_FTP_CMD_PASV:
  606.  
  607.             TORModFtpTransStop(lpInst);
  608.  
  609.             if ((rError = TORTransBind(lpInst->lpTransSck)) != ERROR_SUCCESS) {
  610.            
  611.                 TORModFtpSend(lpInst, "421 Can't create socket");
  612.  
  613.                 return rError;
  614.             }
  615.  
  616.             dwAddr  = TORTransGetAddr(lpInst->lpTransSck);
  617.             wPort   = TORTransGetPort(lpInst->lpTransSck);
  618.  
  619.             TORModFtpSendFmt(
  620.                 lpInst,
  621.                 "227 Entering Passive Mode (%u,%u,%u,%u,%u,%u)",
  622.                 *(((BYTE*) &dwAddr) + 3),
  623.                 *(((BYTE*) &dwAddr) + 2),
  624.                 *(((BYTE*) &dwAddr) + 1),
  625.                 *(((BYTE*) &dwAddr) + 0),
  626.                 *(((BYTE*) &wPort) + 1),
  627.                 *(((BYTE*) &wPort) + 0)
  628.             );
  629.  
  630.         break;
  631.  
  632.         case TOR_MOD_FTP_CMD_TYPE:
  633.  
  634.             if (!(stricmp(lpCmdArgs, "I") == 0 || stricmp(lpCmdArgs, "A") == 0|| stricmp(lpCmdArgs, "L 8") == 0)) {
  635.                
  636.                 TORModFtpSend(lpInst, "501 Unsupported type. Supported types are I, A and L 8");
  637.  
  638.                 return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, ERROR_INVALID_PARAMETER);
  639.             }
  640.  
  641.             TORModFtpSendFmt(lpInst, "200 Type set to %s", lpCmdArgs);
  642.  
  643.         break;
  644.  
  645.         case TOR_MOD_FTP_CMD_LIST:
  646.  
  647.             if ((rError = TORModFtpTransReady(lpInst)) != ERROR_SUCCESS) {
  648.  
  649.                 TORModFtpSend(lpInst, "503 Bad sequence of commands.");
  650.                 TORModFtpTransStop(lpInst);
  651.  
  652.                 return rError;
  653.             }
  654.  
  655.             rError = TORFSOGetFiles(
  656.                 lpInst->lpFSO,
  657.                 lpInst->lpFiles,
  658.                 lpCmdArgs
  659.             );
  660.  
  661.             if (rError != ERROR_SUCCESS) {
  662.  
  663.                 switch (rError) {
  664.  
  665.                     case ERROR_INVALID_NAME:
  666.                         lpErrStr = "Directory name is incorrect.";
  667.                     break;
  668.  
  669.                     case ERROR_FILE_NOT_FOUND:
  670.                     case ERROR_PATH_NOT_FOUND:
  671.                     case ERROR_DIRECTORY:
  672.                         lpErrStr = "Directory not found.";
  673.                     break;
  674.  
  675.                     case ERROR_ACCESS_DENIED:
  676.                         lpErrStr = "Access denied.";
  677.                     break;
  678.  
  679.                     default:
  680.                         lpErrStr = "Internal server error.";
  681.                     break;
  682.  
  683.                 }
  684.  
  685.                 TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
  686.                 TORModFtpTransStop(lpInst);
  687.  
  688.                 return rError;
  689.             }
  690.  
  691.             rError = TORModFtpTransStart(
  692.                 lpInst,
  693.                 (TOR_THREAD_PROC*) TORModFtpSendFileList
  694.             );
  695.  
  696.             if (rError != ERROR_SUCCESS) {
  697.  
  698.                 TORModFtpSend(lpInst, "425 Can't open data connection.");
  699.                 TORModFtpTransStop(lpInst);
  700.  
  701.                 return rError;
  702.             }
  703.  
  704.             TORModFtpSend(lpInst, "150 Connection accepted");
  705.  
  706.         break;
  707.  
  708.         case TOR_MOD_FTP_CMD_REST:
  709.  
  710.             lpInst->qwRestOffset = 0;
  711.  
  712.             if (*TORTrim(lpCmdArgs) == '-' || sscanf(lpCmdArgs, "%I64u", &lpInst->qwRestOffset) != 1) {
  713.  
  714.                 TORModFtpSend(lpInst, "501 Bad parameter. Numeric value required.");
  715.  
  716.                 return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, ERROR_INVALID_PARAMETER);
  717.             }
  718.  
  719.             TORModFtpSendFmt(lpInst, "350 Rest supported. Restarting at %llu", lpInst->qwRestOffset);
  720.  
  721.         break;
  722.  
  723.         case TOR_MOD_FTP_CMD_CDUP:
  724.  
  725.             rError = TORFSOSetCurrentDir(
  726.                 lpInst->lpFSO,
  727.                 ".."
  728.             );
  729.  
  730.             if (rError != ERROR_SUCCESS) {
  731.  
  732.                 switch (rError) {
  733.  
  734.                     case ERROR_INVALID_NAME:
  735.                         lpErrStr = "directory name is incorrect.";
  736.                     break;
  737.  
  738.                     case ERROR_FILE_NOT_FOUND:
  739.                     case ERROR_PATH_NOT_FOUND:
  740.                     case ERROR_DIRECTORY:
  741.                         lpErrStr = "directory not found.";
  742.                     break;
  743.  
  744.                     case ERROR_ACCESS_DENIED:
  745.                         lpErrStr = "access denied.";
  746.                     break;
  747.  
  748.                     default:
  749.                         lpErrStr = "internal server error.";
  750.                     break;
  751.  
  752.                 }
  753.  
  754.                 TORModFtpSendFmt(lpInst, "550 CDUP failed, %s", lpErrStr);
  755.  
  756.                 return rError;
  757.             }
  758.  
  759.             TORModFtpSendFmt(
  760.                 lpInst,
  761.                 "200 CDUP successful. \"%s\" is current directory.",
  762.                 TORFSOGetCurrentDir(lpInst->lpFSO)
  763.             );
  764.  
  765.         break;
  766.  
  767.         case TOR_MOD_FTP_CMD_RETR:
  768.  
  769.             if ((rError = TORModFtpTransReady(lpInst)) != ERROR_SUCCESS) {
  770.  
  771.                 TORModFtpSend(lpInst, "503 Bad sequence of commands.");
  772.                 TORModFtpTransStop(lpInst);
  773.  
  774.                 return rError;
  775.             }
  776.  
  777.             rError = TORFSOOpenFile(
  778.                 lpInst->lpFSO,
  779.                 TOR_IO_FILE(lpInst->lpFile),
  780.                 lpCmdArgs,
  781.                 GENERIC_READ,
  782.                 FILE_SHARE_READ | FILE_SHARE_WRITE,
  783.                 NULL,
  784.                 OPEN_EXISTING,
  785.                 FILE_ATTRIBUTE_NORMAL,
  786.                 NULL
  787.             );
  788.  
  789.             if (rError != ERROR_SUCCESS) {
  790.  
  791.                 switch (rError) {
  792.  
  793.                     case ERROR_INVALID_NAME:
  794.                         lpErrStr = "File name is incorrect.";
  795.                     break;
  796.  
  797.                     case ERROR_FILE_NOT_FOUND:
  798.                         lpErrStr = "File not found.";
  799.                     break;
  800.  
  801.                     case ERROR_PATH_NOT_FOUND:
  802.                         lpErrStr = "Directory not found.";
  803.                     break;
  804.  
  805.                     case ERROR_ACCESS_DENIED:
  806.                         lpErrStr = "Access denied.";
  807.                     break;
  808.  
  809.                     default:
  810.                         lpErrStr = "Internal server error.";
  811.                     break;
  812.  
  813.                 }
  814.  
  815.                 TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
  816.                 TORModFtpTransStop(lpInst);
  817.  
  818.                 return rError;
  819.             }
  820.  
  821.             if (lpInst->qwRestOffset != 0) {
  822.  
  823.                 rError = TORFileSetPos(
  824.                     TOR_IO_FILE(lpInst->lpFile),
  825.                     lpInst->qwRestOffset,
  826.                     NULL,
  827.                     FILE_BEGIN
  828.                 );
  829.  
  830.                 if (rError != ERROR_SUCCESS) {
  831.  
  832.                     TORModFtpSendFmt(lpInst, "550 Can't restore file position %llu", lpInst->qwRestOffset);
  833.                     TORModFtpTransStop(lpInst);
  834.  
  835.                     return rError;
  836.                 }
  837.  
  838.             }
  839.  
  840.             rError = TORModFtpTransStart(
  841.                 lpInst,
  842.                 (TOR_THREAD_PROC*) TORModFtpSendFile
  843.             );
  844.  
  845.             if (rError != ERROR_SUCCESS) {
  846.  
  847.                 TORModFtpSend(lpInst, "425 Can't open data connection.");
  848.                 TORModFtpTransStop(lpInst);
  849.  
  850.                 return rError;
  851.             }
  852.  
  853.             TORModFtpSend(lpInst, "150 Connection accepted");
  854.  
  855.         break;
  856.  
  857.         case TOR_MOD_FTP_CMD_STOR:
  858.         case TOR_MOD_FTP_CMD_APPE:
  859.  
  860.             if ((rError = TORModFtpTransReady(lpInst)) != ERROR_SUCCESS) {
  861.  
  862.                 TORModFtpSend(lpInst, "503 Bad sequence of commands.");
  863.                 TORModFtpTransStop(lpInst);
  864.  
  865.                 return rError;
  866.             }
  867.  
  868.             rError = TORFSOOpenFile(
  869.                 lpInst->lpFSO,
  870.                 TOR_IO_FILE(lpInst->lpFile),
  871.                 lpCmdArgs,
  872.                 GENERIC_WRITE,
  873.                 FILE_SHARE_READ,
  874.                 NULL,
  875.                 OPEN_ALWAYS,
  876.                 FILE_ATTRIBUTE_NORMAL,
  877.                 NULL
  878.             );
  879.  
  880.             if (rError != ERROR_SUCCESS) {
  881.  
  882.                 switch (rError) {
  883.  
  884.                     case ERROR_INVALID_NAME:
  885.                         lpErrStr = "File name is incorrect.";
  886.                     break;
  887.  
  888.                     case ERROR_FILE_NOT_FOUND:
  889.                         lpErrStr = "File not found.";
  890.                     break;
  891.  
  892.                     case ERROR_PATH_NOT_FOUND:
  893.                         lpErrStr = "Directory not found.";
  894.                     break;
  895.  
  896.                     case ERROR_ACCESS_DENIED:
  897.                         lpErrStr = "Access denied.";
  898.                     break;
  899.  
  900.                     default:
  901.                         lpErrStr = "Internal server error.";
  902.                     break;
  903.  
  904.                 }
  905.  
  906.                 TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
  907.                 TORModFtpTransStop(lpInst);
  908.  
  909.                 return rError;
  910.             }
  911.  
  912.             if (lpCmd->dwCmdID == TOR_MOD_FTP_CMD_STOR) {
  913.  
  914.                 if (lpInst->qwRestOffset != 0) {
  915.  
  916.                     rError = TORFileSetPos(
  917.                         TOR_IO_FILE(lpInst->lpFile),
  918.                         lpInst->qwRestOffset,
  919.                         NULL,
  920.                         FILE_BEGIN
  921.                     );
  922.  
  923.                     if (rError != ERROR_SUCCESS) {
  924.  
  925.                         TORModFtpSendFmt(lpInst, "550 Can't restore file position %llu", lpInst->qwRestOffset);
  926.                         TORModFtpTransStop(lpInst);
  927.  
  928.                         return rError;
  929.                     }
  930.  
  931.                 }
  932.  
  933.                 if ((rError = TORFileSetEnd(TOR_IO_FILE(lpInst->lpFile))) != ERROR_SUCCESS) {
  934.  
  935.                     TORModFtpSend(lpInst, "550 Can't truncate the file.");
  936.                     TORModFtpTransStop(lpInst);
  937.  
  938.                     return rError;
  939.                 }
  940.  
  941.             }
  942.             else {
  943.  
  944.                 rError = TORFileSetPos(
  945.                     TOR_IO_FILE(lpInst->lpFile),
  946.                     0,
  947.                     NULL,
  948.                     FILE_END
  949.                 );
  950.  
  951.                 if (rError != ERROR_SUCCESS) {
  952.  
  953.                     TORModFtpSend(lpInst, "550 Can't set end of the file.");
  954.                     TORModFtpTransStop(lpInst);
  955.  
  956.                     return rError;
  957.                 }
  958.  
  959.             }
  960.  
  961.             rError = TORModFtpTransStart(
  962.                 lpInst,
  963.                 (TOR_THREAD_PROC*) TORModFtpRecvFile
  964.             );
  965.  
  966.             if (rError != ERROR_SUCCESS) {
  967.  
  968.                 TORModFtpSend(lpInst, "425 Can't open data connection.");
  969.                 TORModFtpTransStop(lpInst);
  970.  
  971.                 return rError;
  972.             }
  973.  
  974.             TORModFtpSend(lpInst, "150 Connection accepted");
  975.  
  976.         break;
  977.  
  978.         case TOR_MOD_FTP_CMD_SIZE:
  979.  
  980.             rError = TORFSOGetFileSize(
  981.                 lpInst->lpFSO,
  982.                 lpCmdArgs,
  983.                 &ulFileSize
  984.             );
  985.  
  986.             if (rError != ERROR_SUCCESS) {
  987.  
  988.                 switch (rError) {
  989.  
  990.                     case ERROR_INVALID_NAME:
  991.                         lpErrStr = "File name is incorrect.";
  992.                     break;
  993.  
  994.                     case ERROR_FILE_NOT_FOUND:
  995.                         lpErrStr = "File not found.";
  996.                     break;
  997.  
  998.                     case ERROR_PATH_NOT_FOUND:
  999.                         lpErrStr = "Directory not found.";
  1000.                     break;
  1001.  
  1002.                     case ERROR_ACCESS_DENIED:
  1003.                         lpErrStr = "Access denied.";
  1004.                     break;
  1005.  
  1006.                     default:
  1007.                         lpErrStr = "Internal server error.";
  1008.                     break;
  1009.  
  1010.                 }
  1011.  
  1012.                 TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
  1013.  
  1014.                 return rError;
  1015.             }
  1016.  
  1017.             TORModFtpSendFmt(lpInst, "213 %llu", ulFileSize.QuadPart);
  1018.  
  1019.         break;
  1020.  
  1021.         case TOR_MOD_FTP_CMD_DELE:
  1022.  
  1023.             rError = TORFSODeleteFile(
  1024.                 lpInst->lpFSO,
  1025.                 lpCmdArgs
  1026.             );
  1027.  
  1028.             if (rError != ERROR_SUCCESS) {
  1029.  
  1030.                 switch (rError) {
  1031.  
  1032.                     case ERROR_INVALID_NAME:
  1033.                         lpErrStr = "File name is incorrect.";
  1034.                     break;
  1035.  
  1036.                     case ERROR_FILE_NOT_FOUND:
  1037.                         lpErrStr = "File not found.";
  1038.                     break;
  1039.  
  1040.                     case ERROR_PATH_NOT_FOUND:
  1041.                         lpErrStr = "Directory not found.";
  1042.                     break;
  1043.  
  1044.                     case ERROR_ACCESS_DENIED:
  1045.                         lpErrStr = "Access denied.";
  1046.                     break;
  1047.  
  1048.                     default:
  1049.                         lpErrStr = "Internal server error.";
  1050.                     break;
  1051.  
  1052.                 }
  1053.  
  1054.                 TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
  1055.  
  1056.                 return rError;
  1057.             }
  1058.  
  1059.             TORModFtpSend(lpInst, "250 File deleted successfully");
  1060.  
  1061.         break;
  1062.  
  1063.         case TOR_MOD_FTP_CMD_RMD:
  1064.  
  1065.             rError = TORFSORemoveDir(
  1066.                 lpInst->lpFSO,
  1067.                 lpCmdArgs
  1068.             );
  1069.  
  1070.             if (rError != ERROR_SUCCESS) {
  1071.  
  1072.                 switch (rError) {
  1073.  
  1074.                     case ERROR_INVALID_NAME:
  1075.                         lpErrStr = "Directory name is incorrect.";
  1076.                     break;
  1077.  
  1078.                     case ERROR_FILE_NOT_FOUND:
  1079.                     case ERROR_PATH_NOT_FOUND:
  1080.                     case ERROR_DIRECTORY:
  1081.                         lpErrStr = "Directory not found.";
  1082.                     break;
  1083.  
  1084.                     case ERROR_ACCESS_DENIED:
  1085.                         lpErrStr = "Access denied.";
  1086.                     break;
  1087.  
  1088.                     case ERROR_DIR_NOT_EMPTY:
  1089.                         lpErrStr = "Directory not empty.";
  1090.                     break;
  1091.  
  1092.                     default:
  1093.                         lpErrStr = "Internal server error.";
  1094.                     break;
  1095.  
  1096.                 }
  1097.  
  1098.                 TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
  1099.  
  1100.                 return rError;
  1101.             }
  1102.  
  1103.             TORModFtpSend(lpInst, "250 Directory deleted successfully");
  1104.  
  1105.         break;
  1106.  
  1107.         case TOR_MOD_FTP_CMD_MKD:
  1108.  
  1109.             rError = TORFSOCreateDir(
  1110.                 lpInst->lpFSO,
  1111.                 lpCmdArgs
  1112.             );
  1113.  
  1114.             if (rError != ERROR_SUCCESS) {
  1115.  
  1116.                 switch (rError) {
  1117.  
  1118.                     case ERROR_INVALID_NAME:
  1119.                         lpErrStr = "Directory name is incorrect.";
  1120.                     break;
  1121.  
  1122.                     case ERROR_FILE_NOT_FOUND:
  1123.                     case ERROR_PATH_NOT_FOUND:
  1124.                         lpErrStr = "Directory not found.";
  1125.                     break;
  1126.  
  1127.                     case ERROR_ACCESS_DENIED:
  1128.                         lpErrStr = "Access denied.";
  1129.                     break;
  1130.  
  1131.                     case ERROR_ALREADY_EXISTS:
  1132.                         lpErrStr = "Directory already exists.";
  1133.                     break;
  1134.  
  1135.                     default:
  1136.                         lpErrStr = "Internal server error.";
  1137.                     break;
  1138.  
  1139.                 }
  1140.  
  1141.                 TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
  1142.  
  1143.                 return rError;
  1144.             }
  1145.  
  1146.             rError = TORFSOGetAbsolutePath(
  1147.                 lpInst->lpFSO,
  1148.                 szAbsolutePath,
  1149.                 sizeof(szAbsolutePath),
  1150.                 lpCmdArgs
  1151.             );
  1152.  
  1153.             if (rError != ERROR_SUCCESS) {
  1154.                 szAbsolutePath[0] = '\0';
  1155.             }
  1156.  
  1157.             TORModFtpSendFmt(lpInst, "257 \"%s\" created successfully", szAbsolutePath);
  1158.  
  1159.         break;
  1160.  
  1161.         case TOR_MOD_FTP_CMD_RNFR:
  1162.  
  1163.             lpInst->szRenameFrom[0] = '\0';
  1164.  
  1165.             rError = TORFSOGetFileAttributes(
  1166.                 lpInst->lpFSO,
  1167.                 lpCmdArgs,
  1168.                 &lpInst->dwFileAttributes
  1169.             );
  1170.  
  1171.             if (rError != ERROR_SUCCESS) {
  1172.  
  1173.                 switch (rError) {
  1174.  
  1175.                     case ERROR_INVALID_NAME:
  1176.                         lpErrStr = "File or directory name is incorrect.";
  1177.                     break;
  1178.  
  1179.                     case ERROR_FILE_NOT_FOUND:
  1180.                     case ERROR_PATH_NOT_FOUND:
  1181.                         lpErrStr = "File or directory not found.";
  1182.                     break;
  1183.  
  1184.                     case ERROR_ACCESS_DENIED:
  1185.                         lpErrStr = "Access denied.";
  1186.                     break;
  1187.  
  1188.                     default:
  1189.                         lpErrStr = "Internal server error.";
  1190.                     break;
  1191.  
  1192.                 }
  1193.  
  1194.                 TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
  1195.  
  1196.                 return rError;
  1197.             }
  1198.  
  1199.             TORCopyStr(
  1200.                 lpInst->szRenameFrom,
  1201.                 lpCmdArgs,
  1202.                 sizeof(lpInst->szRenameFrom)
  1203.             );
  1204.  
  1205.             if (lpInst->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  1206.                 TORModFtpSend(lpInst, "350 Directory exists, ready for destination name.");
  1207.             }
  1208.             else {
  1209.                 TORModFtpSend(lpInst, "350 File exists, ready for destination name.");
  1210.             }
  1211.  
  1212.         break;
  1213.  
  1214.         case TOR_MOD_FTP_CMD_RNTO:
  1215.  
  1216.             if (lpInst->szRenameFrom[0] == '\0') {
  1217.  
  1218.                 TORModFtpSend(lpInst, "503 Bad sequence of commands.");
  1219.  
  1220.                 return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, TOR_ERROR_CANNOT_IN_THIS_STATE);
  1221.             }
  1222.  
  1223.             rError = TORFSOMoveFile(
  1224.                 lpInst->lpFSO,
  1225.                 lpInst->szRenameFrom,
  1226.                 lpCmdArgs
  1227.             );
  1228.  
  1229.             lpInst->szRenameFrom[0] = '\0';
  1230.  
  1231.             if (rError != ERROR_SUCCESS) {
  1232.  
  1233.                 switch (rError) {
  1234.  
  1235.                     case ERROR_INVALID_NAME:
  1236.                         lpErrStr = "File or directory name is incorrect.";
  1237.                     break;
  1238.  
  1239.                     case ERROR_FILE_NOT_FOUND:
  1240.                     case ERROR_PATH_NOT_FOUND:
  1241.                         lpErrStr = "File or directory not found.";
  1242.                     break;
  1243.  
  1244.                     case ERROR_ACCESS_DENIED:
  1245.                         lpErrStr = "Access denied.";
  1246.                     break;
  1247.  
  1248.                     case ERROR_ALREADY_EXISTS:
  1249.                         lpErrStr = "File or directory already exists.";
  1250.                     break;
  1251.  
  1252.                     default:
  1253.                         lpErrStr = "Internal server error.";
  1254.                     break;
  1255.  
  1256.                 }
  1257.  
  1258.                 TORModFtpSendFmt(lpInst, "550 %s", lpErrStr);
  1259.  
  1260.                 return rError;
  1261.             }
  1262.  
  1263.             if (lpInst->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
  1264.                 TORModFtpSend(lpInst, "250 Directory renamed successfully");
  1265.             }
  1266.             else {
  1267.                 TORModFtpSend(lpInst, "250 File renamed successfully");
  1268.             }
  1269.  
  1270.         break;
  1271.  
  1272.         case TOR_MOD_FTP_CMD_SYST:
  1273.  
  1274.             TORModFtpSend(lpInst, "215 UNIX emulated by TORRCSvr");
  1275.  
  1276.         break;
  1277.  
  1278.         case TOR_MOD_FTP_CMD_NOOP:
  1279.  
  1280.             TORModFtpSend(lpInst, "200 OK");
  1281.  
  1282.         break;
  1283.  
  1284.         case TOR_MOD_FTP_CMD_ABOR:
  1285.  
  1286.             TORModFtpTransStop(lpInst);
  1287.             TORModFtpSend(lpInst, "226 ABOR command successful");
  1288.  
  1289.         break;
  1290.  
  1291.     }
  1292.    
  1293.     return ERROR_SUCCESS;
  1294. }
  1295.  
  1296. TOR_ERROR TORModFtpTransReady(TOR_MOD_FTP_INST *lpInst)
  1297. {
  1298.  
  1299.     if (TORTransGetPort(lpInst->lpTransSck) == 0 || TORThreadGetThreadID(lpInst->lpTransThread) != 0) {
  1300.         return TOR_ERROR_CREATE(TOR_ERROR_CLASS_WINAPI, TOR_ERROR_CANNOT_IN_THIS_STATE);
  1301.     }
  1302.  
  1303.     return ERROR_SUCCESS;
  1304. }
  1305.  
  1306. TOR_ERROR TORModFtpTransStart(TOR_MOD_FTP_INST *lpInst, TOR_THREAD_PROC *lpThreadFunc)
  1307. {
  1308.     TOR_ERROR rError;
  1309.  
  1310.  
  1311.     lpInst->qwRestOffset = 0;
  1312.  
  1313.     if ((rError = TORTransAccept(lpInst->lpTransSck)) != ERROR_SUCCESS) {
  1314.         return rError;
  1315.     }
  1316.  
  1317.     TORPipeSetAbortEvent(
  1318.         TOR_IO_PIPE(TORTransGetIO(lpInst->lpTransSck)),
  1319.         TORThreadGetAbortEvent(lpInst->lpTransThread)
  1320.     );
  1321.  
  1322.     TOREventsSetTimeout(
  1323.         lpInst->lpEvents,
  1324.         INFINITE
  1325.     );
  1326.  
  1327.     rError = TORThreadCreate(
  1328.         lpInst->lpTransThread,
  1329.         lpThreadFunc,
  1330.         lpInst
  1331.     );
  1332.  
  1333.     if (rError != ERROR_SUCCESS) {
  1334.         return rError;
  1335.     }
  1336.  
  1337.     return ERROR_SUCCESS;
  1338. }
  1339.  
  1340. void TORModFtpTransStop(TOR_MOD_FTP_INST *lpInst)
  1341. {
  1342.  
  1343.     TORThreadStop(lpInst->lpTransThread);
  1344.     TORTransClose(lpInst->lpTransSck);
  1345.     TORFileClose(TOR_IO_FILE(lpInst->lpFile));
  1346.  
  1347.     TORPipeSetAbortEvent(
  1348.         TOR_IO_PIPE(TORTransGetIO(lpInst->lpTransSck)),
  1349.         TORThreadsGetAbortEvent(lpInst->lpThread)
  1350.     );
  1351.  
  1352.     TOREventsSetTimeout(
  1353.         lpInst->lpEvents,
  1354.         lpInst->lpModule->dwCommandTimeout
  1355.     );
  1356.  
  1357.     return;
  1358. }
  1359.  
  1360. TOR_ERROR WINAPI TORModFtpSendFileList(TOR_THREAD *lpThread, TOR_MOD_FTP_INST *lpInst)
  1361. {
  1362.     TOR_FSO_FILE        *lpFile;
  1363.     TOR_FSO_FILE_INFO   FileInfo;
  1364.     SYSTEMTIME          stLocalTime;
  1365.     FILETIME            ftLocalTime;
  1366.     FILETIME            ftWriteTime;
  1367.     ULARGE_INTEGER      t1;
  1368.     ULARGE_INTEGER      t2;
  1369.     TOR_ERROR           rError;
  1370.  
  1371.     const char months[][4] = {
  1372.         "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  1373.     };
  1374.  
  1375.  
  1376.     GetLocalTime(&stLocalTime);
  1377.     SystemTimeToFileTime(&stLocalTime, &ftLocalTime);
  1378.  
  1379.     t1.LowPart      = ftLocalTime.dwLowDateTime;
  1380.     t1.HighPart     = ftLocalTime.dwHighDateTime;
  1381.  
  1382.     lpFile = TORFSOFilesGetFirst(lpInst->lpFiles, &FileInfo);
  1383.  
  1384.     while (lpFile) {
  1385.  
  1386.         rError = TORIOFormatStr(
  1387.             TORTransGetIO(lpInst->lpTransSck),
  1388.             "%c--------- 1 ftp ftp % 14llu %s %02u ",
  1389.             FileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? 'd' : '-',
  1390.             FileInfo.ulFileSize.QuadPart,
  1391.             months[FileInfo.stLastWriteTime.wMonth - 1],
  1392.             FileInfo.stLastWriteTime.wDay
  1393.         );
  1394.  
  1395.         if (rError != ERROR_SUCCESS) {
  1396.             return rError;
  1397.         }
  1398.  
  1399.         SystemTimeToFileTime(&FileInfo.stLastWriteTime, &ftWriteTime);
  1400.  
  1401.         t2.LowPart      = ftWriteTime.dwLowDateTime;
  1402.         t2.HighPart     = ftWriteTime.dwHighDateTime;
  1403.  
  1404.         if (t2.QuadPart > t1.QuadPart || (t1.QuadPart - t2.QuadPart) > ((ULONGLONG) 1000000 * 60 * 60 * 24 * 350)) {
  1405.  
  1406.             rError = TORIOFormatStr(
  1407.                 TORTransGetIO(lpInst->lpTransSck),
  1408.                 " %u ",
  1409.                 FileInfo.stLastWriteTime.wYear
  1410.             );
  1411.  
  1412.         }
  1413.         else {
  1414.  
  1415.             rError = TORIOFormatStr(
  1416.                 TORTransGetIO(lpInst->lpTransSck),
  1417.                 "%02u:%02u ",
  1418.                 FileInfo.stLastWriteTime.wHour,
  1419.                 FileInfo.stLastWriteTime.wMinute
  1420.             );
  1421.  
  1422.         }
  1423.  
  1424.         if (rError != ERROR_SUCCESS) {
  1425.             return rError;
  1426.         }
  1427.  
  1428.         rError = TORIOFormatStr(
  1429.             TORTransGetIO(lpInst->lpTransSck),
  1430.             "%s\r\n",
  1431.             FileInfo.szFileName
  1432.         );
  1433.  
  1434.         if (rError != ERROR_SUCCESS) {
  1435.             return rError;
  1436.         }
  1437.  
  1438.         lpFile = TORFSOFilesGetNext(lpFile, &FileInfo);
  1439.  
  1440.     }
  1441.  
  1442.     return ERROR_SUCCESS;
  1443. }
  1444.  
  1445. TOR_ERROR WINAPI TORModFtpSendFile(TOR_THREAD *lpThread, TOR_MOD_FTP_INST *lpInst)
  1446. {
  1447.     return TORIOCopyTo(lpInst->lpFile, TORTransGetIO(lpInst->lpTransSck));
  1448. }
  1449.  
  1450. TOR_ERROR WINAPI TORModFtpRecvFile(TOR_THREAD *lpThread, TOR_MOD_FTP_INST *lpInst)
  1451. {
  1452.     return TORIOCopyTo(TORTransGetIO(lpInst->lpTransSck), lpInst->lpFile);
  1453. }
Add Comment
Please, Sign In to add comment