在c++ / VS2012中初始化OpenSSL库会使我的应用程序崩溃:(

Initializing OpenSSL library in C++ / VS2012 crash my app :(

本文关键字:我的 应用程序 崩溃 c++ VS2012 OpenSSL 初始化      更新时间:2023-10-16

我正在尝试在c++代理中使用openSSL以打印证书。

我在VS2012中链接了openSSL库,然后我做了:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <winsock2.h>
#include <process.h>
#include <winbase.h>
#include <time.h>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <cstdlib>
#include <iostream>
#define _LP_MAIN_CPP_
#include "LP_config.h"
#include "LP_log.h"
#include "LP_cache.h"
#include "LP_socket.h"

#define CMD_SIZE        32              // max http COMMAND buf size                
#define URI_SIZE        2048            // max http URI buf size
#define VER_SIZE        32              // max http VERSION buf size
#define START_LINE_SIZE (CMD_SIZE+URI_SIZE+VER_SIZE)    // max size of start line of http protocol
#define HEAD_LINE_SIZE  2048            // max size of one line of header of http protocol
#define C_BUFSIZE       10240           // bufsize of receiving data from client
#define W_BUFSIZE       40960           // bufsize of receiving data from website
#define STKSIZE         ((C_BUFSIZE+W_BUFSIZE+START_LINE_SIZE)*2)   // stack size of every proxy thread
#define QLEN            SOMAXCONN       // maximum connection queue length
#define WSVERS          MAKEWORD(2,0)
#define PROXY_ABOUT     "Lite Proxy, ver. 0.6"
int     DoProxy(SOCKET);
/*----------------------------------------------------------
* main - main entry of concurrent Lite HTTP PROXY server
*----------------------------------------------------------*/
int
main(int argc, char *argv[])
{
    SSL_library_init();
    SSL_load_error_strings();
    ERR_load_BIO_strings();
    OpenSSL_add_all_algorithms();
    struct  sockaddr_in fsin;       // the address of a client
    int     alen;                   // length of client's address
    WSADATA wsadata;
    SOCKET  msock, ssock;           // master and slave server sockets for responding to the requests of clients
    InitLog();
    LogBegin(3);
    InitConfig();
    if (WSAStartup(WSVERS, &wsadata) != 0)
        ErrExit("WSAStartup failedn");
    if (CreatePassiveSock(msock, service, "tcp", QLEN) == SOCKET_ERROR)
        ErrExit("Proxy master listen socket can't be created.n");
    Log("-> Lite Proxy Server is running on port %s n", service);
    Log("-> To quit, just close this console window.nn");
    InitCache();
    LogEnd();
    while (1) {
        alen = sizeof(fsin);
        ssock = accept(msock, (struct sockaddr *)&fsin, &alen);
        if (ssock == INVALID_SOCKET)
            ErrExit("accept: error number %dn", GetLastError());
        if (_beginthread((void(*)(void *))DoProxy, STKSIZE, (void *)ssock) < 0)
            ErrExit("_beginthread DoProxy: %sn", strerror(errno));
    }
    return -1;  //never reach here
}
/*----------------------------------------------------------------------------------
* GetOneLine - Get one line that ends with "rn" from HTTP request or reponse
*      input - line: point to the string which will be returned;
*              input: point to the input char array;
*              len: the length of input char array;
*     return - if succeed, return the length of the line and modify input pointer
*              to point to the beginning of the next line
*              otherwise, return -1
*     notice - if return 0, it means getting one bland line which means the end of
*              http request headers
*----------------------------------------------------------------------------------*/
int
GetOneLine(char * line, char * (&input), int len)
{
    char * p;
    char * q;
    int c = 0;
    if (len < 2)
        return -1;
    p = input;
    q = line;
    while ((c<len) && ((*p != 0xd) || (*(p + 1) != 0xa))) {
        *q++ = *p++;
        c++;
    }
    if ((c + 2)>len)
        return -1;
    *q = 0;
    input = p + 2;
    return c;
}
/*---------------------------------------------------------------------------------
* FindEndOfHeaders - Find the end of the headers of http request
*            input - p: point to the char array of http headers
*                    len: the length of char array of http headers
*           return - pointer of the beginning of http request body,
*                    if can't find it, return NULL pointer
*---------------------------------------------------------------------------------*/
char *
FindEndOfHeaders(char * p, int len)
{
    int c = 0;
    while (c<len) {
        if ((*p == 0xd) && (*(p + 1) == 0xa) && (*(p + 2) == 0xd) && (*(p + 3) == 0xa))
            break;
        c++;
        p++;
    }
    if ((c + 4) <= len)
        return p + 4;
    else
        return NULL;
}
/*-----------------------------------------------------------------------------------
* MakeStartLine - Construct one new start line which is prepared to send to website
*         input - dest: point to the char array of new start line;
*                 cmd: point to the string of http commandain
*                 uri: point to the string of http uri
*                 ver: point to the string of http version
*        return - the length of new start line
*------------------------------------------------------------------------------------*/
int
MakeStartLine(char * dest, char * cmd, char * uri, char * ver)
{
    char * p;
    p = dest;
    while (*cmd)
        *p++ = *cmd++;
    *p++ = ' ';
    while (*uri)
        *p++ = *uri++;
    *p++ = ' ';
    while (*ver)
        *p++ = *ver++;
    *p++ = 0xd;
    *p++ = 0xa;
    return (p - dest);
}
/*------------------------------------------------------------------------------------------
* SendErrMsg - Constructer one 401 http reponse and send it to the client
*      input - s: the socket to which the messeage will be sent
*              err_str: point to the error string;
*              err_msg: point to the error message string;
*     return - as same as the send()
*------------------------------------------------------------------------------------------*/
char *msg_http = "HTTP/1.0 %d %srn"
"MIME-version: 1.0rnContent-type: text/htmlrnrn"
"<HTML><HEAD><TITLE>401 Infraction</TITLE></HEAD>"
"<BODY><H1>%d %s</H1><H3>%s</H3><H3>%s</H3><HR><H4>"
PROXY_ABOUT
"</H4><H5>Le temps de delegue: %s</H5>"
"</BODY></HTML>";
int
SendErrMsg(SOCKET s, char * err_str, char * err_msg)
{
    char msg[URI_SIZE + 1024];
    int c;
    time_t ltime;
    time(&ltime);
    c = sprintf(msg, msg_http, 401, "Unauthorized", 401, "Infraction", err_str, err_msg, ctime(&ltime));
    Log("[filter] %sn", err_msg);
    return send(s, msg, c + 1, 0);
}
/*------------------------------------------------------------------------------------------
* DoProxy - when get the new connection from client, start this thread to process requests.
*           It will basically follow the sequence like that:
*           get request from client -> analyse the request -> send the request to server
*           -> get the reponse from server -> send the reponse to client
*           -> get next request from client ...
*   input - csock: the socket which is connected with the client;
*  return - 0
*------------------------------------------------------------------------------------------*/
char connection_close[] = "Connection: close";
char content_length[] = "Content-Length: ";
char content_type[] = "Content-Type: text/html";
char proxy_keep_alive[] = "Proxy-Connection: Keep-Alive";
char no_cache[] = "Pragma: no-cache";
char last_modified[] = "Last-Modified: ";
char tunnel_ok[] = "HTTP/1.0 200 Connection establishedrnrn";
int
DoProxy(SOCKET csock)
{
    char    cbuf[C_BUFSIZE + 1];    // buffer of client
    char    wbuf[W_BUFSIZE + 1];    // buffer of remote site
    char    cmd[CMD_SIZE + 1];  // command string of http request
    char    uri[URI_SIZE + 1];  // URI string of http request
    char    ver[VER_SIZE + 1];  // version string of http request
    char    startline[START_LINE_SIZE + 1]; // startline string of http request or reponse
    char    headline[HEAD_LINE_SIZE + 1];       // header string of http request or reponse
    char    remote[128];        // remote site address string (include port number, if it has)
    int     cc, lcc;                // cc: counter of cbuf[], lcc: last value of cc
    int     wc, lwc;                // wc: counter of wbuf[], lwc: last value of wc
    int     slc, nslc;          // slc: length of startline, nslc: length of new startline created by proxy
    int     req_hc, req_bc, req_rc; // length of header, body and the part not be processed in http request
    int     rep_hc, rep_bc, rep_rc; // length of header, body and the part not be processed in http reponse
    int     uri_len, i;
    SOCKET  wsock;      //wsock: socket for website; csock: socket for client
    fd_set  rfds, afds; //rfds: read file/socket descriptor set; afds: active file/socket descriptor set
    char    * p, *webaddr, *path, *port, *req_rest, *req_body, *rep_body, *rep_begin;
    int     f_has_wsock, f_tunnel, f_web_close, f_type_html, f_another_req;
    int     f_req_incomplete, f_rep_incomplete;
    int     status_code;
    char    * cache_buf;
    int     cache_size, cache_count;
    char    cache_uri[URI_SIZE + 1];
    int     f_save_img;
    int     year;
    struct  linger linger_opt;
    int     tid;
    tid = GetCurrentThreadId();
    LogBegin(1);
    f_has_wsock = 0;
    f_tunnel = 0;
    f_web_close = 0;
    f_req_incomplete = 0;
    f_rep_incomplete = 0;
    f_another_req = 0;
    f_save_img = 0;
    lcc = 0;
    lwc = 0;
    // SSL TEST DEBUT
//  SSL_library_init();
    BIO              *certbio = NULL;
    BIO               *outbio = NULL;
    X509                *cert = NULL;
    X509_NAME       *certname = NULL;
    const SSL_METHOD *method;
    SSL_CTX *ctx;
    SSL *ssl;
    int server = 0;
    int ret, j;
    /* ---------------------------------------------------------- *
    * These function calls initialize openssl for correct work.  *
    * ---------------------------------------------------------- */
    //OpenSSL_add_all_algorithms();
    /*ERR_load_BIO_strings();
    ERR_load_crypto_strings();
    SSL_load_error_strings();*/

    //SSL TEST FIN

    linger_opt.l_onoff = 1;
    linger_opt.l_linger = 3;    // timeout of closing socket is 3 seconds
    setsockopt(csock, SOL_SOCKET, SO_LINGER, (char FAR *)(&linger_opt), sizeof(struct linger));
    FD_ZERO(&afds);
    FD_SET(csock, &afds);   // let select() can detect data from client
    while (1) {
        // select() will be blocked untill there are some data input from client or website
        memcpy(&rfds, &afds, sizeof(rfds));
        if (select(FD_SETSIZE, &rfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) == SOCKET_ERROR)
            ErrExit("[tid:%x] select error(%d)n", tid, GetLastError());
        // proxy works as a tunnel for HTTPS protocol
        if (f_tunnel) {
            if (FD_ISSET(wsock, &rfds)) {   // have data coming from remote site
                if ((wc = recv(wsock, wbuf, W_BUFSIZE, 0)) == SOCKET_ERROR)
                    Log("n[tid:%x] recv() from remote site error(%d)n", tid, GetLastError());
                if (wc <= 0) {              // remote site closed the socket
                    Log("n[tid:%x] remote site closed the socket in tunneln", tid);
                    break;
                }
                if ((cc = send(csock, wbuf, wc, 0)) == SOCKET_ERROR) { // copy data: remote site -> client
                    Log("n[tid:%x] send() to client error(%d)n", tid, GetLastError());
                    break;
                }
            }
            if (FD_ISSET(csock, &rfds)) {   // have data coming from client
                if ((cc = recv(csock, cbuf, C_BUFSIZE, 0)) == SOCKET_ERROR)
                    Log("n[tid:%x] recv() from client error(%d)n", tid, GetLastError());
                if (cc <= 0) {              // client closed the socket
                    Log("n[tid:%x] client closed the socket in tunneln", tid);
                    break;
                }
                if ((wc = send(wsock, cbuf, cc, 0)) == SOCKET_ERROR) { // copy data: client -> remote site
                    Log("n[tid:%x] send() to remote site error(%d)n", tid, GetLastError());
                    break;
                }
            }
            continue;
        }
        if (!FD_ISSET(csock, &rfds)) { // check whether the data is from website
            if (recv(wsock, wbuf, W_BUFSIZE, 0) <= 0) { // website want to close the socket
                Log("n[tid:%x] website closed the socket after sending one reponsen", tid);
                break;
            }
            else {
                // never reach hear. if it reach, there is something wrong.
                Log("n[tid:%x] !!!website push some data actively, it is wrongn", tid);
                break;
            }
        }
        //
        // have data coming from client
        //
    GetRequest:
        if ((cc = recv(csock, cbuf + lcc, C_BUFSIZE - lcc, 0)) == SOCKET_ERROR)
            Log("n[tid:%x] recv from client error when getting http request: %dn", tid, GetLastError());
        if (cc <= 0) {              // client closed the socket
            Log("n[tid:%x] client closed the socketn", tid);
            break;
        }
        if (f_req_incomplete)   // if the last data doesn't have complete request headers, we should merge all data
            cc = cc + lcc;
    AnalyseNextRequest:
        // check the integrity of startline and all headers
        if ((req_body = FindEndOfHeaders(cbuf, cc)) != NULL) {
            //Log("n[tid:%x] got hearders of requestn",tid);
            f_req_incomplete = 0;
            lcc = 0;
        }
        else if (cc < C_BUFSIZE) {
            Log("n[tid:%x] can't find End of Hearders of request, need more datan", tid);
            f_req_incomplete = 1;
            lcc = cc;
            goto GetRequest; // incomplete, should get more data
        }
        else {
            Log("n[tid:%x] can't find End of Hearders of request, cbuf is fulln", tid);
            break;
        }
        p = cbuf;
        while ((*p < 'A') || (*p > 'Z')) p++;   // to find the first legal letter of start line
        slc = GetOneLine(startline, p, min(cc, START_LINE_SIZE));   // get startline of http request
        if (slc < sizeof("GET http://a.com HTTP/1.x")) {        // can't find start line 
            Log("n[tid:%x] GetOneLine(StartLine) error %dn", tid, slc);
            break;
        }
        sscanf(startline, "%s %s %s", cmd, uri, ver);       // split start line 
        Log("n[tid:%x]HTTP requestnt[CMD:]t%snt[URI:]t%snt[VER:]t%sn", tid, cmd, uri, ver);
        if (strcmp(cmd, "CONNECT") == 0) {      // create a tunnel for client. for example, HTTPS 
            webaddr = uri;
            port = strstr(webaddr, ":");        // split server into address and port
            *port++ = 0;
            if (ConnectSock(wsock, webaddr, port, "tcp") == SOCKET_ERROR) // can't create socket for remote site
                break;
            FD_SET(wsock, &afds);           // let select() can detect all data from remote site
            f_tunnel = 1;                                   // set the flag of tunnel
            send(csock, tunnel_ok, sizeof(tunnel_ok) - 1, 0);   // reponse to client for indicating tunnel is OK
            // TEST ICI
            /* Connect the SSL socket */
            /*ssl = SSL_new(ctx);
            sbio = BIO_new_socket(sock, BIO_NOCLOSE);
            SSL_set_bio(ssl, sbio, sbio);
            if (SSL_connect(ssl) <= 0)
                printf("SSL connect error");
            X509 *peer;
            peer = SSL_get_peer_certificate(ssl);
            PEM_write_X509(stdout, peer);
            SSL_CTX_free(ctx);*/
            // FIN TEST
            continue;
        }
        else if (filter_post && (strcmp(cmd, "POST") == 0)) {   // if filter_post = 1, we will block POST
            SendErrMsg(csock, cmd, "Cette methode est interdite!");
            break;
        }
        else if (filter_put && (strcmp(cmd, "PUT") == 0)) { // if filter_put = 1, we will block PUT
            SendErrMsg(csock, cmd, "Cette methode est interdite!");
            break;
        }
        else if (open_cache && (strcmp(cmd, "GET") == 0)) { // if open_cache = 1, we will use cache machanism
            uri_len = strlen(uri);
            if ((strcmp(&uri[uri_len - 4], ".jpg") == 0) || (strcmp(&uri[uri_len - 4], ".gif") == 0)) {
                cache_buf = GetFromCache(uri, &cache_size);
                if (cache_buf != NULL) { // if the GET request hit the cache, send the data from cache to client
                    cache_count = send(csock, cache_buf, cache_size, 0);
                    Log("  [cache]sended bytes: %in", cache_count);
                    if (cache_count < 0)
                        Log("  [cache]can't send, error: %dn", GetLastError());
                    free(cache_buf);
                    break;
                }
                else { // if we can't find it in cache, we will prepare to save the reponse from server into cache
                    f_save_img = 1;
                    strcpy(cache_uri, uri);
                }
            }
        }
        if (strncmp(uri, "http://", 7)) {
            SendErrMsg(csock, uri, "This protocol has not been implemented. Sorry!");
            break;  // can't find correct URI
        }
        if (filter_uri) {   // if filter_uri = 1, we will block some websites which are defined in LitProxy.INI file 
            for (i = 0;i<uri_filter_max;i++) {
                uri_len = strlen(uri_filter[i]);
                if (strncmp(uri, uri_filter[i], uri_len) == 0)
                    break;
            }
            if (i<uri_filter_max) {
                SendErrMsg(csock, uri, "Ce site est blocque!");
                break;
            }
        }
        cbuf[cc] = 0;                           // truncate cbuf as a C String
                                                // build connection with website, for example: uri point to "http://www.website.com:3128/index.html
        webaddr = uri + 7;
        path = strstr(webaddr, "/");    // split website address and path
        *path++ = 0;                // now webaddr point to "www.website.com:3128", path point to "index.html"
        if ((f_has_wsock) && strcmp(remote, webaddr)) {
            // sometimes client send http request to another website by using one persistent connection 
            Log("Address of remote site has been changed!n");
            FD_CLR(wsock, &afds);
            closesocket(wsock);
            f_has_wsock = 0;
        }
        if (!f_has_wsock) {         // we need setup one connection with server
            strcpy(remote, webaddr); // keep address of remote site
            if ((port = strstr(webaddr, ":")) == NULL)
                port = "80";        // set default port of http
            else
                *port++ = 0;        // get website port, now webaddr point to "www.website.com", port point to "3128"
            if (ConnectSock(wsock, webaddr, port, "tcp") == SOCKET_ERROR) break;
            setsockopt(wsock, SOL_SOCKET, SO_LINGER, (char FAR *)(&linger_opt), sizeof(struct linger));
            //Log("wsock = %xn",wsock);
            FD_SET(wsock, &afds);
            f_has_wsock = 1;
        }
        // construct one new start line with partial URI 
        // because some websites, like news.sina.com.cn, 
        // can't support full URI.
        path--;
        *path = '/';    // now path point to "/index.html"
        nslc = MakeStartLine(startline, cmd, path, ver);
        req_rest = p;   // now p point to the beginning of http headers
        req_rc = cc - (p - cbuf);
        // analyse http request headers
        req_bc = 0;
        Log("t[HEADERS:]n");
        while ((req_hc = GetOneLine(headline, p, min(req_rc, HEAD_LINE_SIZE))) > 0) {
            // get http header one by one
            // when GetOneLine return 0, it means all headers have been processed
            Log("tt%sn", headline);
            req_rc = req_rc - req_hc - 2;
            if (strncmp(headline, content_length, sizeof(content_length) - 1) == 0) {
                // find header "Content-Length", it means the length of body after headers
                req_bc = atoi(&headline[sizeof(content_length) - 1]);
                Log("tttuploading body length = %dn", req_bc);
            }
        }
        req_rc = req_rc - 2;    // if rep_rc > 0, it means that there is one http body after http headers
                                // send new start line to remote website 
        send(wsock, startline, nslc, 0);
        // send headers to remote website
        send(wsock, req_rest, req_body - req_rest, 0);
        f_another_req = 0;
        if (req_bc) {                   // client POST or PUT some data
            if (req_bc > req_rc) {      // all the rest is a part of http request body
                req_bc = req_bc - req_rc;
                send(wsock, req_body, req_rc, 0);
                Log("tttremaining uploading body length = %dn", req_bc);
                while (req_bc > 0) {
                    if ((cc = recv(csock, cbuf, C_BUFSIZE, 0)) == SOCKET_ERROR)
                        Log("n[tid:%x] recv from client error when getting data : %dn", tid, GetLastError());
                    if (cc <= 0) {              // client closed the socket
                        Log("n[tid:%x] client closed the socket after sending datan", tid);
                        goto ExitDoProxy;
                    }
                    req_bc -= cc;
                    if (req_bc < 0) {
                        Log("n[tid:%x] upload count error, req_bc = %dn", tid, req_bc);
                        goto ExitDoProxy;
                    }
                    Log("tttremaining uploading body length = %dn", req_bc);
                    send(wsock, cbuf, cc, 0);
                }
            }
            else {
                send(wsock, req_body, req_bc, 0);
                req_rc = req_rc - req_bc;
                if (req_rc > 0) {   // if req_rc > 0, it means that there is another request after this body
                    memmove(cbuf, req_body + req_bc, req_rc);
                    cc = req_rc;
                    f_another_req = 1;
                }
            }
        }
        //
        // wait the reponse of website
        //
    GetReponse:
        if ((wc = recv(wsock, wbuf + lwc, W_BUFSIZE - lwc, 0)) == SOCKET_ERROR)
            Log("n[tid:%x] recv from website error: %dn", tid, GetLastError());
        if (wc <= 0) {              // website closed the socket
            Log("n[tid:%x] website closed the socketn", tid);
            break;
        }
        if (f_rep_incomplete)   // if the last data doesn't have complete reponse headers, we should merge all data
            wc = wc + lwc;
        if ((rep_body = FindEndOfHeaders(wbuf, wc)) != NULL) {
            //Log("n[tid:%x] got hearders of reponsen",tid);
            f_rep_incomplete = 0;
            lwc = 0;
        }
        else if (wc < W_BUFSIZE) {
            Log("n[tid:%x] can't find End of Hearders of reponse, need more datan", tid);
            f_rep_incomplete = 1;
            lwc = wc;
            goto GetReponse;
        }
        else {
            Log("n[tid:%x] can't find End of Hearders of reponse, wbuf is fulln", tid);
            break;
        }
        p = wbuf;
        while (*p != 'H') p++;  // to find the first legal letter of the first reponse line
        rep_begin = p;
        rep_rc = wc - (p - wbuf);
        // analyse reponse headers
        f_type_html = 0;
        rep_bc = 0;
        Log("n[tid:%x]HTTP reponsen", tid);
        rep_hc = GetOneLine(startline, p, 64);
        Log("tt%sn", startline);
        rep_rc = rep_rc - rep_hc - 2;
        startline[12] = 0;
        status_code = atoi(&startline[9]);
        while ((rep_hc = GetOneLine(headline, p, min(rep_rc, HEAD_LINE_SIZE))) > 0) {
            Log("tt%sn", headline);
            rep_rc = rep_rc - rep_hc - 2;
            if (strncmp(headline, connection_close, sizeof(connection_close) - 1) == 0) {
                f_web_close = 1; // website will close the socket
            }
            else if (strncmp(headline, content_type, sizeof(content_type) - 1) == 0) {
                f_type_html = 1; // after headers, there will be one html file
            }
            else if (strncmp(headline, content_length, sizeof(content_length) - 1) == 0) {
                // find header "Content-Length", it means the length of body after headers
                rep_bc = atoi(&headline[sizeof(content_length) - 1]);
                Log("tttbody length = %dn", rep_bc);
            }
            else if (filter_last_mod && strncmp(headline, last_modified, sizeof(last_modified) - 1) == 0) {
                // if filter_last_mod, we will block the file which is old than the value of "year"
                sscanf(&headline[27], "%d ", &year);
                if (year < last_mod_year) {
                    SendErrMsg(csock, headline, "Ce document est trop vieux!");
                    goto ExitDoProxy;
                }
            }
        }
        rep_rc = rep_rc - 2;            // all headers have been processed
                                        // send headers to client
        send(csock, rep_begin, rep_body - rep_begin, 0);
        cache_buf = NULL;
        if (!f_web_close && f_type_html && (status_code == 200))
            // some websites don't indicate the content-length of html file, but it will close the socket after sending data
            f_web_close = 1;
        if ((status_code != 200))
            rep_bc = 0; // the "Content-Length" has nothing to do with these status codes except code 200 
        else if (f_save_img && rep_bc) {
            // we need to save the reponse to cache, so we allocate the room for the cache buffer
            cache_count = rep_body - rep_begin;
            cache_size = cache_count + rep_bc;
            cache_buf = (char *)malloc(cache_size);
            if (cache_buf != NULL) {
                memcpy(cache_buf, rep_begin, cache_count);
            }
        }
        if (f_web_close || rep_bc) {
            // in this case, remote site has responsibility for closing socket after sending data
            if (rep_rc > 0)
                send(csock, rep_body, rep_rc, 0);
            if (rep_bc > 0) {
                rep_bc -= rep_rc;
                Log("n[tid:%x]ttremaining downloading body length = %dn", tid, rep_bc);
                if (cache_buf != NULL) {  //save data to cache buffer
                    memcpy(&cache_buf[cache_count], rep_body, rep_rc);
                    cache_count += rep_rc;
                }
                if (rep_bc <= 0) {
                    if (cache_buf != NULL) { // save cache buffer to cache file
                        PutIntoCache(cache_uri, cache_buf, cache_size);
                        free(cache_buf);
                    }
                    goto ExitDoProxy;
                }
            }
            while (1) {
                if ((wc = recv(wsock, wbuf, W_BUFSIZE, 0)) == SOCKET_ERROR)
                    Log("n[tid:%x] recv from website error: %dn", tid, GetLastError());
                if (wc <= 0) {              // website closed the socket
                    Log("n[tid:%x] website closed the socket after sending datan", tid);
                    goto ExitDoProxy;
                }
                send(csock, wbuf, wc, 0);
                if (cache_buf != NULL) {  // save data to cache buffer
                    memcpy(&cache_buf[cache_count], wbuf, wc);
                    cache_count += wc;
                }
                if (rep_bc > 0) {
                    rep_bc -= wc;
                    Log("n[tid:%x]ttremaining downloading body length = %dn", tid, rep_bc);
                    if (rep_bc <= 0) {
                        if (cache_buf != NULL) { //save cache buffer to cache file
                            PutIntoCache(cache_uri, cache_buf, cache_size);
                            free(cache_buf);
                        }
                        goto ExitDoProxy;
                    }
                }
            }
        }
        if (f_another_req) {    // in the request buffer, there is another request to process
            f_another_req = 0;
            f_save_img = 0;
            goto AnalyseNextRequest;
        }
    }
ExitDoProxy:
    // close the sockets gracefully and will end the current thread
    if (f_has_wsock) {
        shutdown(wsock, SD_SEND);
        closesocket(wsock);
    }
    shutdown(csock, SD_SEND);
    closesocket(csock);
    InsertTimeTag(2);
    LogEnd();
    return 0;
}

当我运行应用程序在X86:

"Failed to initialize application (0xc0000007).

你知道吗?

看起来你的问题与OpenSSL库无关。

根据本文档,错误码0xc0000007表示STATUS_INVALID_WORKSTATION:

用户帐户受到限制,因此不能用于从源工作站登录。

检查用于运行程序的用户的访问权限。尝试以更高的权限运行程序。